diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000000..5b1e11ac74 --- /dev/null +++ b/.eslintignore @@ -0,0 +1,5 @@ +node_modules +dist +*.js +scripts +vitest.config.ts \ No newline at end of file diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000000..a65b910337 --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,150 @@ +{ + "env": { + "browser": true, + "es2021": true + }, + "parser": "@typescript-eslint/parser", + "plugins": [ + "@typescript-eslint", + "import", + "react", + "react-hooks", + "destructuring", + "jsx-id-attribute-enforcement" + ], + "extends": [ + "eslint:recommended", + "plugin:@typescript-eslint/eslint-recommended", + "plugin:@typescript-eslint/recommended", + "plugin:prettier/recommended", + "plugin:react/recommended" + ], + "parserOptions": { + "ecmaVersion": "latest", + "sourceType": "module", + "project": true + }, + "rules": { + "no-extra-boolean-cast": "off", + "multiline-comment-style": "error", + "arrow-spacing": "error", + "curly": ["error", "all"], + "no-else-return": "error", + "no-multiple-empty-lines": "error", + "sort-imports": [ + "error", + { + "ignoreCase": true, + "ignoreDeclarationSort": true + } + ], + "import/order": [ + "error", + { + "newlines-between": "always", + "groups": [ + "type", + "builtin", + "external", + "internal", + "parent", + "sibling", + "object", + "index" + ], + "alphabetize": { + "order": "asc", + "caseInsensitive": true + } + } + ], + "import/first": "error", + "import/no-duplicates": "error", + "import/newline-after-import": [ + "error", + { + "count": 1 + } + ], + "react-hooks/rules-of-hooks": "error", + "react/no-array-index-key": "error", + "react/jsx-no-constructed-context-values": "error", + "react/jsx-key": "error", + "react/no-unescaped-entities": "off", + "destructuring/in-params": "error", + "destructuring/in-methods-params": "error", + // These rules will be override by @typescript-eslint + "no-unused-vars": "off", + "no-throw-literal": "off", + "no-magic-numbers": "off", + "camelcase": "off", + "@typescript-eslint/no-unused-vars": [ + "error", + { + "varsIgnorePattern": "^_", + "argsIgnorePattern": "^_", + "ignoreRestSiblings": true + } + ], + "@typescript-eslint/no-throw-literal": "error", + "@typescript-eslint/no-magic-numbers": [ + "error", + { + "ignore": [-1, 0, 1, 2], + "ignoreTypeIndexes": true + } + ], + "@typescript-eslint/consistent-type-exports": "error", + "@typescript-eslint/consistent-type-imports": "error", + "@typescript-eslint/member-ordering": "error", + "@typescript-eslint/no-floating-promises": "error", + "@typescript-eslint/no-misused-promises": [ + "error", + { + "checksVoidReturn": false + } + ], + "@typescript-eslint/no-mixed-enums": "error", + "@typescript-eslint/no-unnecessary-type-assertion": "error", + "@typescript-eslint/prefer-enum-initializers": "error", + "@typescript-eslint/promise-function-async": "error", + "@typescript-eslint/switch-exhaustiveness-check": "error", + "jsx-id-attribute-enforcement/missing-ids": [ + "error", + { + "targetCustom": ["Button", "IconButton"] + } + ] + + // "@typescript-eslint/explicit-function-return-type": "error", + // "@typescript-eslint/naming-convention": [ + // "error", + // { + // "selector": "default", + // "format": ["camelCase"] + // }, + + // { + // "selector": "variable", + // "format": ["camelCase", "UPPER_CASE"] + // }, + // { + // "selector": "parameter", + // "format": ["camelCase"], + // "leadingUnderscore": "allow" + // }, + + // { + // "selector": "memberLike", + // "modifiers": ["private"], + // "format": ["camelCase"], + // "leadingUnderscore": "require" + // }, + + // { + // "selector": "typeLike", + // "format": ["PascalCase"] + // } + // ] + } +} diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000000..0f6bffcae6 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,56 @@ +# Learn how to add code owners here: +# https://help.github.com/en/articles/about-code-owners + +# Infra +/crowdin.yml @nikaaru +/lingui.config.ts @yeager-eren @nikaaru +/.github @yeager-eren @RanGojo @nikaaru +/scripts @yeager-eren @nikaaru + +# Queue manager +/queue-manager/* @yeager-eren @samobasquiat + +# Logging +/logging/* @yeager-eren + +# Wallets +/signers/* @RanGojo @mikasackermn +/wallets/* @yeager-eren +/wallets/core @yeager-eren +/wallets/react @yeager-eren +/wallets/provider-all @yeager-eren +/wallets/provider-argentx @RanGojo @RanGojo +/wallets/provider-bitget @samobasquiat +/wallets/provider-braavos @RanGojo @samobasquiat +/wallets/provider-brave @Ikari-Shinji-re +/wallets/provider-clover @RanGojo +/wallets/provider-coin98 @Ikari-Shinji-re +/wallets/provider-coinbase @yeager-eren +/wallets/provider-cosmostation @Ikari-Shinji-re +/wallets/provider-default @RanGojo +/wallets/provider-enkrypt @Ikari-Shinji-re +/wallets/provider-exodus @mikasackermn +/wallets/provider-frontier @samobasquiat +/wallets/provider-halo @samobasquiat +/wallets/provider-keplr @RanGojo +/wallets/provider-leap-cosmos @samobasquiat +/wallets/provider-math-wallet @Ikari-Shinji-re +/wallets/provider-metamask @yeager-eren +/wallets/provider-mytonwallet @Ikari-Shinji-re +/wallets/provider-okx @mikasackermn +/wallets/provider-phantom @RanGojo @mikasackermn +/wallets/provider-safe @samobasquiat +/wallets/provider-safepal @Ikari-Shinji-re +/wallets/provider-station @mikasackermn +/wallets/provider-taho @mikasackermn +/wallets/provider-tokenpocket @mikasackermn +/wallets/provider-tron-link @RanGojo +/wallets/provider-trustwallet @mikasackermn +/wallets/provider-walletconnect2 @RanGojo @yeager-eren @samobasquiat @mikasackermn +/wallets/provider-xdefi @RanGojo + +# Widget +/widget/embedded/store @yeager-eren @Ikari-Shinji-re +/widget/iframe @yeager-eren @Ikari-Shinji-re +/widget/playground @samobasquiat @mikasackermn +/widget/ui @mikasackermn @Ikari-Shinji-re \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000000..dd84ea7824 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,38 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: '' +assignees: '' + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior: +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Desktop (please complete the following information):** + - OS: [e.g. iOS] + - Browser [e.g. chrome, safari] + - Version [e.g. 22] + +**Smartphone (please complete the following information):** + - Device: [e.g. iPhone6] + - OS: [e.g. iOS8.1] + - Browser [e.g. stock browser, safari] + - Version [e.g. 22] + +**Additional context** +Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000000..bbcbbe7d61 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,20 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: '' +labels: '' +assignees: '' + +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. diff --git a/.github/PUBLISH_TEMPLATE.md b/.github/PUBLISH_TEMPLATE.md new file mode 100644 index 0000000000..5c8ee723d3 --- /dev/null +++ b/.github/PUBLISH_TEMPLATE.md @@ -0,0 +1,3 @@ +# Checklist + +TBA \ No newline at end of file diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000000..53f5242601 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,22 @@ +# Summary + +Please include a summary of the changes and the related issue. Please also include relevant motivation and context. List any dependencies that are required for this change. + +Fixes # (issue) + + +# How did you test this change? + +Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration + +- [ ] Test A +- [ ] Test B + + +# Checklist: + +- [ ] I have performed a self-review of my code +- [ ] I have commented my code, particularly in hard-to-understand areas +- [ ] I have made corresponding changes to the documentation +- [ ] I have added tests that prove my fix is effective or that my feature works +- [ ] Implemented a user interface (UI) change, referencing our Figma design to ensure pixel-perfect precision. diff --git a/.github/actions/prepare/action.yml b/.github/actions/prepare/action.yml new file mode 100644 index 0000000000..8024949dc5 --- /dev/null +++ b/.github/actions/prepare/action.yml @@ -0,0 +1,28 @@ +name: Setup Environments +description: 'Setting up Git, NodeJS and authenticate.' + +runs: + using: 'composite' + steps: + - name: Setup NodeJS + uses: actions/setup-node@v4 + with: + node-version: '20' + cache: 'yarn' + registry-url: 'https://registry.npmjs.org' + + - name: Git + run: | + git config --global user.name 'github-actions[bot]' + git config --global user.email 'github-actions[bot]@users.noreply.github.com' + shell: 'bash' + + - name: Restore cache + uses: actions/cache@v4 + with: + path: '**/node_modules' + key: ${{ runner.os }}-${{ hashFiles('**/yarn.lock') }} + + - name: Install packages + run: yarn install --frozen-lockfile + shell: 'bash' diff --git a/.github/actions/upload-build-artifacts/action.yml b/.github/actions/upload-build-artifacts/action.yml new file mode 100644 index 0000000000..1b19092414 --- /dev/null +++ b/.github/actions/upload-build-artifacts/action.yml @@ -0,0 +1,26 @@ +name: Upload Build Artifacts +description: 'Upload ESBuild build artifacts' +outputs: + hashed: + description: 'Hashed branch name' + value: ${{ steps.hash_current_branch_name.outputs.hashed }} + +runs: + using: 'composite' + steps: + - name: Hash Current Branch Name + id: hash_current_branch_name + run: | + hashed_name=$(echo -n "${GITHUB_HEAD_REF:-${GITHUB_REF#refs/heads/}}" | base64 -w 0) + echo "hashed=${hashed_name}">> $GITHUB_OUTPUT + shell: 'bash' + - name: Upload Build Information + uses: actions/upload-artifact@v4 + with: + name: ${{steps.hash_current_branch_name.outputs.hashed}} + path: | + **/**/**.build.json + !**/**/tsconfig.build.json + !**/node_modules/** + retention-days: 30 + overwrite: true diff --git a/.github/workflows/checks.yaml b/.github/workflows/checks.yaml new file mode 100644 index 0000000000..913703d681 --- /dev/null +++ b/.github/workflows/checks.yaml @@ -0,0 +1,128 @@ +name: Check PR +on: + pull_request: + types: [opened, reopened, synchronize, labeled] + +jobs: + check: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Prepare + uses: ./.github/actions/prepare + + - name: Checking Conventional Commits + run: node ./scripts/check-conventional-commits/command.mjs + env: + REF: ${{ github.ref }} + + - name: Extract new translations to check if any error exists + run: node ./scripts/lingui/command.js extract --clean + + - name: Test + run: | + node ./scripts/build-libs/command.mjs + yarn run test + + #In the test step, we build all packages, and the build meta files are generated. + #Therefore, this step should be executed after the test step. + - id: upload_artifacts + name: Upload Build Artifacts + uses: ./.github/actions/upload-build-artifacts + + # for preview deployment for specific project, add vercel project id in environment section + - name: Preview Deployment + id: deploy + run: | + yarn global add vercel + yarn run deploy + env: + REF: ${{ github.ref }} + GH_TOKEN: ${{ github.token }} + VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }} + VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }} + VERCEL_PROJECT_WIDGET_CONFIG: ${{ secrets.VERCEL_PROJECT_WIDGET_CONFIG }} # widget playground + VERCEL_PROJECT_WIDGET_APP: ${{ secrets.VERCEL_PROJECT_WIDGET_APP }} # widget app + VERCEL_PROJECT_STORYBOOK: ${{ secrets.VERCEL_PROJECT_STORYBOOK }} # storybook + + ENABLE_PREVIEW_DEPLOY: true + + outputs: + # the structure of output variable is {packageNameWithoutScope}-url like: widget-app-url + app_url: ${{ steps.deploy.outputs.widget-app-url }} + playground_url: ${{ steps.deploy.outputs.widget-playground-url }} + storybook_url: ${{ steps.deploy.outputs.storybook-url }} + + # add job for each project that you want has preview deployment + app-preview: + runs-on: ubuntu-latest + needs: check + environment: + name: app-preview + url: ${{ steps.seturl.outputs.url }} + steps: + - name: Extract Preview URL + id: seturl + run: | + echo "url=${{ needs.check.outputs.app_url }}">> $GITHUB_OUTPUT + echo "Preview URL: ${{ needs.check.outputs.app_url}}" + + playground-preview: + runs-on: ubuntu-latest + needs: check + environment: + name: playground-preview + url: ${{ steps.seturl.outputs.url }} + steps: + - name: Extract Preview URL + id: seturl + run: | + echo "url=${{ needs.check.outputs.playground_url }}">> $GITHUB_OUTPUT + echo "Preview URL: ${{ needs.check.outputs.playground_url}}" + + storybook-preview: + runs-on: ubuntu-latest + needs: check + environment: + name: storybook-preview + url: ${{ steps.seturl.outputs.url }} + steps: + - name: Extract Preview URL + id: seturl + run: | + echo "url=${{ needs.check.outputs.storybook_url }}">> $GITHUB_OUTPUT + echo "Preview URL: ${{ needs.check.outputs.storybook_url}}" + + analyze-bundle: + needs: check + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + ref: ${{ github.ref }} + + - name: Prepare + uses: ./.github/actions/prepare + + - name: Download Build Information For Current Branch + uses: actions/download-artifact@v4 + continue-on-error: true + with: + name: ${{steps.upload_artifacts.outputs.hashed}} + path: 'current-branch' + + - name: Hash Target Branch Name + id: hash_target_branch_name + run: | + hashed_name=$(printf "%s" "${{ github.base_ref }}" | base64 -w 0) + echo "hashed=${hashed_name}">> $GITHUB_OUTPUT + + - name: Analyze Bundles And Create Report + run: node ./scripts/analyze-bundle/command.mjs --currentBranchDirectory current-branch --targetBranchDirectory target-branch --targetBranchArtifactName ${{steps.hash_target_branch_name.outputs.hashed}} + env: + GH_TOKEN: ${{ github.token }} + GH_REPOSITORY: ${{ github.repository }} diff --git a/.github/workflows/crowdin.yml b/.github/workflows/crowdin.yml new file mode 100644 index 0000000000..0499cfddd1 --- /dev/null +++ b/.github/workflows/crowdin.yml @@ -0,0 +1,77 @@ +name: Sync translations using Crowdin + +on: + workflow_dispatch: + + workflow_call: + secrets: + CROWDIN_PROJECT_ID: + description: 'You need a crowdin project id to be set.' + required: true + CROWDIN_PERSONAL_TOKEN: + description: 'You need a crowdin token to be set.' + required: true + PAT: + description: 'Add a PAT to secrets.' + required: true + +jobs: + crowdin: + runs-on: ubuntu-latest + env: + CROWDIN_PROJECT_ID: ${{ secrets.CROWDIN_PROJECT_ID }} + CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_PERSONAL_TOKEN }} + GITHUB_TOKEN: ${{ secrets.PAT }} + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + token: ${{ secrets.PAT }} + + - name: Prepare + uses: ./.github/actions/prepare + + - name: Extract new source + run: yarn run i18n:extract + + - name: Crowdin push translations + uses: crowdin/github-action@v1 + with: + upload_sources: true + upload_translations: false + download_translations: false + push_sources: true + source: translations/en.po + translation: translations/%two_letters_code%.po + project_id: ${{ secrets.CROWDIN_PROJECT_ID }} + token: ${{ secrets.CROWDIN_PERSONAL_TOKEN }} + + - name: Crowdin pre-translation + run: node ./scripts/crowdin/command.mjs + + - name: Crowdin pull translations + uses: crowdin/github-action@v1 + id: crowdin-download + with: + upload_sources: false + upload_translations: false + download_translations: true + source: translations/en.po + translation: translations/%two_letters_code%.po + project_id: ${{ secrets.CROWDIN_PROJECT_ID }} + token: ${{ secrets.CROWDIN_PERSONAL_TOKEN }} + commit_message: 'chore(translation): update translations [skip ci]' + + localization_branch_name: 'l10n_crowdin_translations' + create_pull_request: true + pull_request_title: '🤖chore(translation): update translations' + pull_request_body: 'New Crowdin pull request with translations' + pull_request_base_branch_name: 'next' + env: + GITHUB_TOKEN: ${{ secrets.PAT }} + + - name: Enable auto-merge for the PR + if: steps.crowdin-download.outputs.pull_request_url + run: gh pr --repo $GITHUB_REPOSITORY merge ${{ steps.crowdin-download.outputs.pull_request_url }} --admin --rebase + env: + GITHUB_TOKEN: ${{secrets.PAT}} diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml new file mode 100644 index 0000000000..0a31ef4263 --- /dev/null +++ b/.github/workflows/deploy.yml @@ -0,0 +1,31 @@ +name: Deploy +on: + workflow_dispatch: + +jobs: + deploy-it: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + token: ${{ secrets.PAT }} + + - name: Prepare + uses: ./.github/actions/prepare + + - name: Deploy packages + run: | + yarn global add vercel + yarn run deploy + env: + REF: ${{ github.ref }} + GH_TOKEN: ${{ github.token }} + VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }} + VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }} + VERCEL_PROJECT_WIDGET_CONFIG: ${{ secrets.VERCEL_PROJECT_WIDGET_CONFIG }} + VERCEL_PROJECT_WIDGET_APP: ${{ secrets.VERCEL_PROJECT_WIDGET_APP }} + VERCEL_PROJECT_STORYBOOK: ${{ secrets.VERCEL_PROJECT_STORYBOOK }} + VERCEL_PROJECT_WALLETS: ${{ secrets.VERCEL_PROJECT_WALLETS }} + VERCEL_PROJECT_Q: ${{ secrets.VERCEL_PROJECT_Q }} + VERCEL_PROJECT_WALLET_ADAPTER: ${{ secrets.VERCEL_PROJECT_WALLET_ADAPTER }} diff --git a/.github/workflows/prerelease.yml b/.github/workflows/prerelease.yml new file mode 100644 index 0000000000..87c1837d9c --- /dev/null +++ b/.github/workflows/prerelease.yml @@ -0,0 +1,92 @@ +name: Prerelease +on: + workflow_dispatch: + +jobs: + localization: + uses: ./.github/workflows/crowdin.yml + secrets: + CROWDIN_PROJECT_ID: ${{ secrets.CROWDIN_PROJECT_ID }} + CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_PERSONAL_TOKEN }} + PAT: ${{ secrets.PAT }} + + deploy: + runs-on: ubuntu-latest + needs: + - localization + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + token: ${{ secrets.PAT }} + + - name: Checkout latest changes from 'next' branch with Crowdin updates + run: | + git fetch origin next + git checkout next + git pull origin next + + - name: Prepare + uses: ./.github/actions/prepare + + - name: Deploy packages + id: deploy-packages + run: | + yarn global add vercel + yarn run deploy + env: + REF: ${{ github.ref }} + GH_TOKEN: ${{ github.token }} + VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }} + VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }} + VERCEL_PROJECT_WIDGET_CONFIG: ${{ secrets.VERCEL_PROJECT_WIDGET_CONFIG }} # widget playground + VERCEL_PROJECT_WIDGET_APP: ${{ secrets.VERCEL_PROJECT_WIDGET_APP }} # widget app + VERCEL_PROJECT_STORYBOOK: ${{ secrets.VERCEL_PROJECT_STORYBOOK }} # storybook + + ENABLE_PREVIEW_DEPLOY: true + + outputs: + # the structure of output variable is {packageNameWithoutScope}-url like: widget-app-url + app_url: ${{ steps.deploy-packages.outputs.widget-app-url }} + playground_url: ${{ steps.deploy-packages.outputs.widget-playground-url }} + storybook_url: ${{ steps.deploy-packages.outputs.storybook-url }} + + # add job for each project that you want has preview deployment + app-preview: + runs-on: ubuntu-latest + needs: deploy + environment: + name: app-preview + url: ${{ steps.seturl.outputs.url }} + steps: + - name: Extract Preview URL + id: seturl + run: | + echo "url=${{ needs.deploy.outputs.app_url }}">> $GITHUB_OUTPUT + echo "Preview URL: ${{ needs.deploy.outputs.app_url}}" + + playground-preview: + runs-on: ubuntu-latest + needs: deploy + environment: + name: playground-preview + url: ${{ steps.seturl.outputs.url }} + steps: + - name: Extract Preview URL + id: seturl + run: | + echo "url=${{ needs.deploy.outputs.playground_url }}">> $GITHUB_OUTPUT + echo "Preview URL: ${{ needs.deploy.outputs.playground_url}}" + + storybook-preview: + runs-on: ubuntu-latest + needs: deploy + environment: + name: storybook-preview + url: ${{ steps.seturl.outputs.url }} + steps: + - name: Extract Preview URL + id: seturl + run: | + echo "url=${{ needs.deploy.outputs.storybook_url }}">> $GITHUB_OUTPUT + echo "Preview URL: ${{ needs.deploy.outputs.storybook_url}}" diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml deleted file mode 100644 index cf135065fe..0000000000 --- a/.github/workflows/publish.yaml +++ /dev/null @@ -1,47 +0,0 @@ -name: Publish -on: - push: - branches: - - 'main' - - 'next' - -jobs: - publish: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - with: - fetch-depth: 0 - - - name: Setup NodeJS - uses: actions/setup-node@v3 - with: - node-version: '14' - cache: 'yarn' - - - name: Git - run: | - git config --global user.name 'github-actions[bot]' - git config --global user.email 'github-actions[bot]@users.noreply.github.com' - - - name: Auth - run: | - echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" >> .npmrc - npm whoami - env: - NPM_TOKEN: ${{ secrets.NPM_TOKEN }} - - - name: Install packages - run: yarn install --frozen-lockfile - - - name: Build, Version & Publish packages - run: yarn run publish - env: - REF: ${{ github.ref }} - BASE_REF: ${{ github.event.pull_request.base.ref }} - VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }} - VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }} - VERCEL_PROJECT_WALLETS: ${{ secrets.VERCEL_PROJECT_WALLETS }} - VERCEL_PROJECT_Q: ${{ secrets.VERCEL_PROJECT_Q }} - VERCEL_PROJECT_WALLET_ADAPTER: ${{ secrets.VERCEL_PROJECT_WALLET_ADAPTER }} - VERCEL_PROJECT_WIDGET_CONFIG: ${{ secrets.VERCEL_PROJECT_WIDGET_CONFIG }} diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 0000000000..106ec2773e --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,28 @@ +name: Publish +on: + push: + branches: + - 'main' + - 'next' + +jobs: + publish: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + token: ${{ secrets.PAT }} + - run: git pull + + - name: Prepare + uses: ./.github/actions/prepare + + - name: Build, Version & Publish packages + run: yarn run publish + env: + REF: ${{ github.ref }} + GH_TOKEN: ${{ github.token }} + # Github will create .npmrc based on this env variable. + # https://docs.github.com/en/actions/publishing-packages/publishing-nodejs-packages#publishing-packages-to-the-npm-registry + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000000..e44b055384 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,24 @@ +name: Release +on: + workflow_dispatch: + +jobs: + release: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + token: ${{ secrets.PAT }} + + - name: Prepare + uses: ./.github/actions/prepare + + - name: Release Production + run: yarn run release-prod + env: + REF: ${{ github.ref }} + GH_TOKEN: ${{ github.token }} + # Github will create .npmrc based on this env variable. + # https://docs.github.com/en/actions/publishing-packages/publishing-nodejs-packages#publishing-packages-to-the-npm-registry + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/.github/workflows/upload-build-artifacts.yml b/.github/workflows/upload-build-artifacts.yml new file mode 100644 index 0000000000..adeeea6e9d --- /dev/null +++ b/.github/workflows/upload-build-artifacts.yml @@ -0,0 +1,23 @@ +name: Build libraries then upload build artifacts + +on: + workflow_dispatch: + +jobs: + build-and-upload: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Prepare + uses: ./.github/actions/prepare + + - name: Build Libraries + run: | + node ./scripts/build-libs/command.mjs + + - id: upload_artifacts + name: Upload Build Artifacts + uses: ./.github/actions/upload-build-artifacts diff --git a/.gitignore b/.gitignore index 56e0ae3039..f05cc31d4b 100644 --- a/.gitignore +++ b/.gitignore @@ -2,7 +2,9 @@ dist/ lerna-debug.log .vercel -.npmrc + +# i18n +translations/**/*.ts # dependencies node_modules @@ -15,7 +17,6 @@ coverage # next.js .next/ out/ -build # misc .DS_Store @@ -39,4 +40,5 @@ yarn-error.log* .parcel-cache storybook-static .yalc -yalc.lock \ No newline at end of file +yalc.lock +.nx \ No newline at end of file diff --git a/.husky/commit-msg b/.husky/commit-msg new file mode 100755 index 0000000000..2ebf085a7a --- /dev/null +++ b/.husky/commit-msg @@ -0,0 +1,4 @@ +#!/usr/bin/env sh +. "$(dirname "$0")/_/husky.sh" + +yarn commitlint $1 \ No newline at end of file diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100755 index 0000000000..25d2235737 --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1,4 @@ +#!/usr/bin/env sh +. "$(dirname "$0")/_/husky.sh" + +npx lint-staged \ No newline at end of file diff --git a/.lintstagedrc.mjs b/.lintstagedrc.mjs new file mode 100644 index 0000000000..edf3080806 --- /dev/null +++ b/.lintstagedrc.mjs @@ -0,0 +1,14 @@ +import micromatch from 'micromatch'; + +const eslintIgnoredFiles = ['**/global-wallets-env.d.ts']; + +export default { + '*.{ts,tsx}': (files) => { + const match = micromatch.not(files, eslintIgnoredFiles); + return `eslint --fix --quiet ${match.join(' ')}`; + }, + + '*.{ts,tsx,json}': (files) => { + return `prettier --write ${files.join(' ')}`; + }, +}; diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000000..b3776bf2a6 --- /dev/null +++ b/.npmrc @@ -0,0 +1,2 @@ +# Enforce to use yarn +engine-strict=true \ No newline at end of file diff --git a/.prettierrc b/.prettierrc deleted file mode 100644 index 66a9ff35f9..0000000000 --- a/.prettierrc +++ /dev/null @@ -1,8 +0,0 @@ -{ - "semi": true, - "tabWidth": 2, - "printWidth": 100, - "singleQuote": true, - "trailingComma": "all", - "jsxBracketSameLine": true -} \ No newline at end of file diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 0000000000..9908b8bb2a --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,6 @@ +{ + "semi": true, + "tabWidth": 2, + "singleQuote": true, + "jsxBracketSameLine": true +} diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000000..0dabfda416 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,19 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "node", + "request": "launch", + "name": "Debug Current Test File", + "autoAttachChildProcesses": true, + "skipFiles": ["/**", "**/node_modules/**"], + "program": "${workspaceRoot}/node_modules/vitest/vitest.mjs", + "args": ["run", "${relativeFile}"], + "smartStep": true, + "console": "integratedTerminal" + } + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000000..59f51dbc0a --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,11 @@ +{ + "editor.codeActionsOnSave": { + "source.fixAll.eslint": "explicit" + }, + "eslint.validate": [ + "javascript", + "javascriptreact", + "typescript", + "typescriptreact" + ] +} diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000000..d7208932ef --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,275 @@ +## Widget [0.25.0] (2024-12-31) + +_includes `@rango-dev/widget-embedded@0.37.0`_ + +### Bug Fixes + +- Fix ctrl wallet fail to connect problem ([f1bfedc](https://github.com/rango-exchange/rango-client/commit/f1bfedcf4e9bf4cf55c2bee7c954b83dbbb6376c)) + +### Features + +- Update ctrl wallet name and info ([fcde421](https://github.com/rango-exchange/rango-client/commit/fcde42144a995ec655388b95b606abc669a8c1a8)) + +## Widget [0.24.0] (2024-11-27) + +_includes `@rango-dev/widget-embedded@0.36.0`_ + +### Bug Fixes + +- fix error display for bad requests ([82c0381](https://github.com/rango-exchange/rango-client/commit/82c03811b64a9197680314ac4f506d8680afec0c)) + +### Features + +- Add support for MyTonWallet ([7027755](https://github.com/rango-exchange/rango-client/commit/7027755740426359f42b088b842dfd01590df5c3)) +- Add support for TonConnect ([2a2dbb7](https://github.com/rango-exchange/rango-client/commit/2a2dbb79022263f19446ced49d298e04d63f927f)) +- Accepting routing params (avoidNativeFee, maxLength) ([2a89744](https://github.com/rango-exchange/rango-client/commit/2a8974440d1269d9a12700fc7100f1f78371d277)) +- Show warning if source and destination token is same ([979cb0d](https://github.com/rango-exchange/rango-client/commit/979cb0d20c0730be9c94c2cd96d66630ea8e86ba)) + +## Widget [0.23.0] (2024-11-12) + +_includes `@rango-dev/widget-embedded@0.35.0`_ + +### Features + +- add more languages to widget ([bc37fe9](https://github.com/rango-exchange/rango-client/commit/bc37fe97586545f993d7a2675a43b64aaa743791)) + +### Bug Fixes + +- fix solana signer by migrating confirm transaction to get signature statuses ([07b2b89](https://github.com/rango-exchange/rango-client/commit/07b2b89fec1d22a09ed9215691ff296a6e77a382)) + +## Widget [0.22.0] (2024-10-12) + +_includes `@rango-dev/widget-embedded@0.34.0`_ + +### Bug Fixes + +- bump sdk and fix type issues ([d442208](https://github.com/rango-exchange/rango-client/commit/d4422083bf5dd27d5f509ce1db7f9560d05428c8)) +- resolve issues with the sign message method for certain solana providers ([cbe83a3](https://github.com/rango-exchange/rango-client/commit/cbe83a3da8b48560b206fc2a7fa7cf062cdeaa23)) +- cosmostation wallet connection error ([b3747ba](https://github.com/rango-exchange/rango-client/commit/b3747ba77d06a5c02ce670affb337771e606434b)) +- add chart icon and handle dark theme in BarChart component ([fd4f246](https://github.com/rango-exchange/rango-client/commit/fd4f24684e42deb1b47fb9a6584ac4f9a1519599)) +- add prepare data function for chart package ([a9f8c6b](https://github.com/rango-exchange/rango-client/commit/a9f8c6b092ca5343756e220238c943dbc369a62b)) +- fix issues in the tabs component ([497c387](https://github.com/rango-exchange/rango-client/commit/497c3871241f3e067682526c156014dcd8189395)) + +### Features + +- add signature to versioned transactions ([d7f374b](https://github.com/rango-exchange/rango-client/commit/d7f374b460dc6a51e761614235575eb924f8d71a)) +- introducing hub, our new wallet management ([92692fe](https://github.com/rango-exchange/rango-client/commit/92692fe7a05be72caea8b99bcc4ac5e2326f2f5a)) +- add chart package ([f5ae7e4](https://github.com/rango-exchange/rango-client/commit/f5ae7e449ec1e385188ff904e9d59862fa8ef1d2)) +- add id property to buttons ([39824e3](https://github.com/rango-exchange/rango-client/commit/39824e3ce8b1804b9944eb0faf71da7cdccf59ea)) +- add mobile menu icons ([d4358bc](https://github.com/rango-exchange/rango-client/commit/d4358bc189a61c49c508c517b2cd674d435aa3b7)) +- implement scrollable variant for tabs component ([0635f77](https://github.com/rango-exchange/rango-client/commit/0635f774af9dfd03fcc8f7adfcd32591c86efa25)) + +### Performance Improvements + +- lazy load signer packages ([7b88f18](https://github.com/rango-exchange/rango-client/commit/7b88f1834f7b29b4b81ab6c81a07bb88e8ccf55c)) +- enable code splitting in build process ([fe5a41e](https://github.com/rango-exchange/rango-client/commit/fe5a41e0e297298de11cd74ca5825544742aa03a)) + +## Widget [0.20.0] (2024-09-10) + +_includes `@rango-dev/widget-embedded@0.33.0`_ + +### Bug Fixes + +- add slippage icon to setting page ([2e29351](https://github.com/rango-exchange/rango-client/commit/2e29351d957f4e751a25f66b7cb173e5d9956378)) +- clear timeout for success modal to avoid closing upcoming modals unexpectedly ([0d54a60](https://github.com/rango-exchange/rango-client/commit/0d54a6092e6a412b1497b9a3e26af6f669eea181)) +- correct translation bugs ([0107f1d](https://github.com/rango-exchange/rango-client/commit/0107f1df7a587d9910c5376c4f99acd23b95e1a4)) +- fix wallet state issue after retrying to fetch the balance following a failed attempt ([181bac3](https://github.com/rango-exchange/rango-client/commit/181bac3f54727847f8d16ff47164cce80aa64931)) +- if state is on connecting, we should call disconnect in terminateconnectingWallets as well ([ad16056](https://github.com/rango-exchange/rango-client/commit/ad1605631df82e4d692f7e75999b2a5c51216958)) +- improve header component to center the title properly ([a9929bb](https://github.com/rango-exchange/rango-client/commit/a9929bb518ccbb2033b646fbcb5c034852b039b2)) +- reset derivation path if it's string and switching from custom mode ([c94c71a](https://github.com/rango-exchange/rango-client/commit/c94c71a94f3ac910ca13433ea616ce548559dc58)) +- ensure proper cleanup of the modal component after it is removed from the dom ([394e4f0](https://github.com/rango-exchange/rango-client/commit/394e4f017eb09ac99f90a10be94ef8a742632586)) +- fix incorrect error message on Trezor wallet transaction rejection ([3998563](https://github.com/rango-exchange/rango-client/commit/3998563fa06c694b34a61730b4f6c13f3323a407)) +- fix solfare and solfare-snap signers ([896c70b](https://github.com/rango-exchange/rango-client/commit/896c70b8cc8b5e29ec6dfcd98378ef0b3f05698f)) +- update signMessage in the default Solana signer to return a base58 string instead of base64 ([b60609b](https://github.com/rango-exchange/rango-client/commit/b60609b71d55ff205324aee87fb440d23cba5c79)) + +### Features + +- export a new hook for handling required data for connect called useStateful ([0d00a45](https://github.com/rango-exchange/rango-client/commit/0d00a45b4434e0e2b53228a1d1c0be4fa579e21b)) +- export StatefulConnect components and helpers ([c28a94b](https://github.com/rango-exchange/rango-client/commit/c28a94bd2721b4dbd16f9471f1cb0ddc45aa8904)) +- implement bordered variant for tabs component ([1de8888](https://github.com/rango-exchange/rango-client/commit/1de8888d6d4ae13a765aaee0173eebf0d49f4a11)) + +## Widget [0.19.0] (2024-08-17) + +_includes `@rango-dev/widget-embedded@0.32.1`_ + +### Features + +- add functionality to support custom tokens ([a1aa0af](https://github.com/rango-exchange/rango-client/commit/a1aa0afed98f164488a3caffaaff2fd060ab8b3d)) + +## Widget [0.18.0] (2024-08-11) + +_includes `@rango-dev/widget-embedded@0.31.0`_ + +### Bug Fixes + +- address the issue where the token list does not update when the balance changes ([d1fb4e4](https://github.com/rango-exchange/rango-client/commit/d1fb4e4bb57e97cd730cba4c33ca0b2202600c09)) +- fix bug in swap input handling empty value ([3c9b082](https://github.com/rango-exchange/rango-client/commit/3c9b082b7b548ddd3981fff100d4dc880581b98d)) +- fix flicker in playground ([6ae2d58](https://github.com/rango-exchange/rango-client/commit/6ae2d588ba36822856a43cea7cabc3618cf72c11)) +- fix missing usd value in estimated output ([a46d19a](https://github.com/rango-exchange/rango-client/commit/a46d19a80b4f6fc1ca29e289e1b6441e89aa730c)) +- fix sort logic of notifications ([ffcf4c2](https://github.com/rango-exchange/rango-client/commit/ffcf4c2d70da7887e17042f3e6fe46224cd21fe1)) +- fix wallet modal closing bug ([146f7e2](https://github.com/rango-exchange/rango-client/commit/146f7e24450be278aee53b03319399934cf84f17)) +- recalculate supported tokens even if it's empty list ([8ccda6b](https://github.com/rango-exchange/rango-client/commit/8ccda6b2e246425102e6f6ab5f0d1edd131c6794)) + +### Features + +- add derivation path modal for trezor wallet ([364422f](https://github.com/rango-exchange/rango-client/commit/364422f099b202a27a529591c5e3628bbb35508d)) +- add filter and clear to widget history ([d43b603](https://github.com/rango-exchange/rango-client/commit/d43b603462feabf297d5be389fcaa35402d667b5)) +- add functionality to update the quote inputs from outside the widget ([d9722fb](https://github.com/rango-exchange/rango-client/commit/d9722fbd5629ecb760b94a3d4a9ad7c0a07687ad)) +- add preventable event and a new ui event called CLICK_CONNECT_WALLET ([e4363bb](https://github.com/rango-exchange/rango-client/commit/e4363bb6fb98d49b22c1b608ecf6d37650ff3035)) +- add the option to define a default custom destination for each blockchain in the widget config ([7982ab6](https://github.com/rango-exchange/rango-client/commit/7982ab633dcb5b07ee5c313c9414d68baa6cbc38)) +- changing the request ID copy process ([490cdfa](https://github.com/rango-exchange/rango-client/commit/490cdfa41131eea20d8a552f8f0714b77d21ac71)) +- hide balance and max button when no wallet connected ([80b2754](https://github.com/rango-exchange/rango-client/commit/80b27547376394a3070aea7065d4bb9652f454e4)) + +### Performance Improvements + +- improve token list performance by caching target tokens on load and config change ([3cc55ff](https://github.com/rango-exchange/rango-client/commit/3cc55ff95dde1f87f53efb2496e995beeb943b00)) + +## Widget [0.17.0] (2024-07-09) + +_includes `@rango-dev/widget-embedded@0.30.0`_ + +### Bug Fixes + +- fix tx data for evm signers when transfering native tokens ([a5d9f6e](https://github.com/rango-exchange/rango-client/commit/a5d9f6e3f5bada210a05c0d1f5c57d7917bf869c)) +- import Trezor module ([cd71eb5](https://github.com/rango-exchange/rango-client/commit/cd71eb5f390f1b07974ea9e2368f35db383a8c82)) +- fix the bug where xdefi is not displayed for experimental networks ([723eb2d](https://github.com/rango-exchange/rango-client/commit/723eb2dc3bfacce8753eeee011910b595d45028d)) +- bug in updating input & output amount ([49c902b](https://github.com/rango-exchange/rango-client/commit/49c902be7adc1ba9ae7808f145ec975c724a728f)) +- fix bug displaying the same token list for blockchains with the same number of tokens ([f4dc82f](https://github.com/rango-exchange/rango-client/commit/f4dc82f5f319f9133fac7d8a68023596a773cd96)) +- improve generate colors for tokens label and price impact color ([5f2893c](https://github.com/rango-exchange/rango-client/commit/5f2893c03b17af24a8b3886e12b1631b5cc208fb)) +- refactor numeric tooltip and fix missing translations ([59f1fb9](https://github.com/rango-exchange/rango-client/commit/59f1fb96027a9b51cea5f6362b247b6cf180d809)) +- fix playground exported config bugs and slider color bug ([9505b63](https://github.com/rango-exchange/rango-client/commit/9505b6330363839aa5acc7abfdb6cd7288f946d6)) +- fix state of custom destination in playground ([ae9cd78](https://github.com/rango-exchange/rango-client/commit/ae9cd783aebc797ffa98e2cd0fb87744ae92caf8)) + +### Features + +- support new widget events ([37a9b6c](https://github.com/rango-exchange/rango-client/commit/37a9b6c023cba660c87af27bcbfceadfb8daa8d0)) +- improve solana simulation failed errors ([c7ccb97](https://github.com/rango-exchange/rango-client/commit/c7ccb97cbdc571b615ee3129a8fcadd52cb0bc9f)) +- add a modal for setting custom derivation path for ledger ([5b74ec0](https://github.com/rango-exchange/rango-client/commit/5b74ec049393ed74e3e7547edc72b68bd70b7dce)) +- add support for Trezor hardware wallet ([6edecbb](https://github.com/rango-exchange/rango-client/commit/6edecbb14fd008fc741c892bfa3e025c10160b9b)) +- integrate rabby wallet extension ([145fb8f](https://github.com/rango-exchange/rango-client/commit/145fb8ffbbf5e46e7e8386aeffcefc8f4ddb22e7)) +- integrate tomo wallet extension ([9f0f065](https://github.com/rango-exchange/rango-client/commit/9f0f0650fcd213a621dcc6ddca3e32424c1a5ada)) +- adding 'shadows' to widget config for theme ([2be1f1a](https://github.com/rango-exchange/rango-client/commit/2be1f1aa508fb642a797610471b63219cd3d2ccf)) +- display all notifications in the notification popover ([c3eda22](https://github.com/rango-exchange/rango-client/commit/c3eda22cf1f06b928fdf0c98512fd444cc46823c)) +- export useWalletList for use in dapp ([e5fb662](https://github.com/rango-exchange/rango-client/commit/e5fb662adc119fb341db2c6c68b3b9e45c0353a2)) +- make update settings optional to make it enable in playground ([c13a902](https://github.com/rango-exchange/rango-client/commit/c13a902fba9a03b111bde6fed02a1f3a081ee590)) +- add credit and disconnect icons ([b5e5357](https://github.com/rango-exchange/rango-client/commit/b5e5357cf3a5b13f602b8d5cdb829f3699ee3197)) + +### Performance Improvements + +- improve finding tokens from store ([3e890bd](https://github.com/rango-exchange/rango-client/commit/3e890bdcd47971b072f347c368c4370225cb11ff)) + +## Playground [0.17.0] (2024-07-09) + +### Bug Fixes + +- fix playground exported config bugs and slider color bug ([9505b63](https://github.com/rango-exchange/rango-client/commit/9505b6330363839aa5acc7abfdb6cd7288f946d6)) +- fix state of custom destination in playground ([ae9cd78](https://github.com/rango-exchange/rango-client/commit/ae9cd783aebc797ffa98e2cd0fb87744ae92caf8)) + +### Features + +- make update settings optional to make it enable in playground ([c13a902](https://github.com/rango-exchange/rango-client/commit/c13a902fba9a03b111bde6fed02a1f3a081ee590)) + +## Widget [0.16.0] (2024-06-01) + +_includes `@rango-dev/widget-embedded@0.29.0`_ + +### Bug Fixes + +- update design for not-selected blockchain or token ([8915101](https://github.com/rango-exchange/rango-client/commit/8915101d4e7a7092fbb5f38bbd95789e124f8ae3)) +- resolve custom slippage bug ([54bef0f](https://github.com/rango-exchange/rango-client/commit/54bef0f6d73d1078ab170e8b049a6aa311fff02d)) +- sync notifications with persisted swaps ([2ecaf38](https://github.com/rango-exchange/rango-client/commit/2ecaf38750dacc828ebaee7f8348b502a7645a88)) +- exclude ledger on mobile and fix injected wallet bug ([a6d90aa](https://github.com/rango-exchange/rango-client/commit/a6d90aa01b7b1fcea01ab46d1a74583ff6f98ff8)) +- fix init config minor bug ([7d671e3](https://github.com/rango-exchange/rango-client/commit/7d671e336050cd4d4cc0589cfd83e341421fe859)) +- fix the automatic selection of the connected wallets in the confirm wallets modal ([0b85d81](https://github.com/rango-exchange/rango-client/commit/0b85d81bc9ce6ec055e832e37eb6289a1b107d39)) + +### Features + +- update wallets page to add filter by transaction types ([0aa7c73](https://github.com/rango-exchange/rango-client/commit/0aa7c73333bd32912f7b2e90a660f3f43e64f4f7)) +- add more predefined fonts list from google fonts ([693f257](https://github.com/rango-exchange/rango-client/commit/693f25790497f6829dd74c800d3d5574d8ee0bed)) +- add custom solana rpc url to config ([8d46ebf](https://github.com/rango-exchange/rango-client/commit/8d46ebf4fcd58c7ecd180ea29c071176c0f863e9)) +- add an option to wallet connect provider to open a desktop wallet directly ([bee0a1f](https://github.com/rango-exchange/rango-client/commit/bee0a1f57ef5470564f6cdc379d00981e7d34b0a)) +- update explorer icon and add paste to custom destination ([61468a0](https://github.com/rango-exchange/rango-client/commit/61468a0e227517b91def21a85a8f7d72b7411862)) +- generate theme color tints and shades using the new method of overriding them separately ([a46b8a9](https://github.com/rango-exchange/rango-client/commit/a46b8a93bff1d8d6766c2fd636091983a8ee1baa)) + +## Widget [0.15.0] (2024-05-14) + +_includes `@rango-dev/widget-embedded@0.28.0`_ + +### Features + +- add solana to ledger ([77b6695](https://github.com/rango-exchange/rango-client/commit/77b6695758165f9258a0ba5bd3b2cf39b0b2aab5)) +- improve all routes button ([efcb61e](https://github.com/rango-exchange/rango-client/commit/efcb61ee5920b1a05c44dfa8edf23dc8d3d7f035)) +- migrate storybook components to new package ([d926ae2](https://github.com/rango-exchange/rango-client/commit/d926ae220360077ef49ee919dbb2e15f6bec0548)) +- add test to check workflow ([69a4c3e](https://github.com/rango-exchange/rango-client/commit/69a4c3e144a7e9cd1ce24c3a2f7a3d7a4b4a1eab)) +- add auto retry for fetching confirm swap ([5945d82](https://github.com/rango-exchange/rango-client/commit/5945d82030b89006f5c62c8f5ce5d492cc2ed220)) +- add a new package to deploy the storybook preview ([06aaa44](https://github.com/rango-exchange/rango-client/commit/06aaa444408f07c7a053432af081c9758f157052)) +- detect proper error related to wallet connect params ([a0d8d95](https://github.com/rango-exchange/rango-client/commit/a0d8d95ed977fffbd0244f498c81f7ce3550ee71)) +- clean solana signer simulation errors ([5d623ab](https://github.com/rango-exchange/rango-client/commit/5d623ab632945cb28581ea896fb95d7c84f92607)) + +### Bug Fixes + +- fix the entrance animation of the confirm wallets modal ([1907ad2](https://github.com/rango-exchange/rango-client/commit/1907ad25cef2a25c303e2c91194dbae2b8e6fd56)) +- fix space between of routes and swap box in expanded mode ([cbca33e](https://github.com/rango-exchange/rango-client/commit/cbca33ef31d634466b6595ee01fa337952076b89)) +- fix multiwallets config initial value check bug ([94dbf07](https://github.com/rango-exchange/rango-client/commit/94dbf074ab51f56bf1267cb668be4e58781554bf)) +- fix bugs in fetching quotes ([2b533ea](https://github.com/rango-exchange/rango-client/commit/2b533ead6fa90d2d8b3d9b8de2699072cc57d55b)) +- display the swapper's title instead of the swapper's group as their displayed name ([1142d94](https://github.com/rango-exchange/rango-client/commit/1142d9417e690bf4b0093ee84e42352dab149793)) + +## Widget (2024-05-08) + +_includes `@rango-dev/widget-embedded@0.27.3`_ + +### Bug Fixes + +- disable the confirm wallet button if all required wallets are not selected ([521883f](https://github.com/rango-exchange/rango-client/commit/521883f9e381d311bf0cdad275b234646da2a648)) + +## Widget (2024-04-27) + +_includes `@rango-dev/widget-embedded@0.27.2`_ + +### Bug Fixes + +- make sure to correctly pass validation parameters when setting up a new swap ([4f6d37e](https://github.com/rango-exchange/rango-client/commit/4f6d37ea9b59caca4d0064c1b33b05077b0b59a3)) + +## Widget (2024-04-24) + +_includes `@rango-dev/widget-embedded@0.27.1`_ + +### Features + +- add ethereum for ledger ([084aae2](https://github.com/rango-exchange/rango-client/commit/084aae28adaf0310dffe3a3100dd783252393053)) + +## Widget (2024-04-23) + +_includes `@rango-dev/widget-embedded@0.27.0`_ + +### Bug Fixes + +- address passing wallet-connect project id ([80a6b80](https://github.com/rango-exchange/rango-client/commit/80a6b8046cc93bc8e88b84a201331b2e7adc0c73)) +- fix token selector hover ui for token explorer link ([ede0fac](https://github.com/rango-exchange/rango-client/commit/ede0fac0e987b0cd6983ccd427207d78f65eeb96)) +- fix token selector infinite loader ([1122dd6](https://github.com/rango-exchange/rango-client/commit/1122dd6db1fecadd41d56f22d5dfd95fbaa645a0)) +- remove setting option from confirm swap page ([1f204c1](https://github.com/rango-exchange/rango-client/commit/1f204c1ebf544348a2969aa35c2cf8c9841ea3ff)) +- improve solana transaction sign flow ([65b7be0](https://github.com/rango-exchange/rango-client/commit/65b7be0ce02bed88c98280999b615bc405e95cb6)) +- set current state for current network in conencting multi-chain wallets ([dc62af0](https://github.com/rango-exchange/rango-client/commit/dc62af03f0edc10400394ba600c7d83e1250b4e8)) +- resolve conflicts between evm providers ([9a6734c](https://github.com/rango-exchange/rango-client/commit/9a6734cf1537bf0504cf9058d4d775313a9e8e80)) + +### Features + +- add solflare snap connect and signer ([42aa2b0](https://github.com/rango-exchange/rango-client/commit/42aa2b039dd910e8e44db473e1acd28689a8b43b)) +- add animation for switch swap button ([601af2d](https://github.com/rango-exchange/rango-client/commit/601af2dde7ed87c7aa803cb0b79a13c21ff0386d)) +- add unit test for app store ([9df49a8](https://github.com/rango-exchange/rango-client/commit/9df49a8aaf0d03fea01d9e9790953c7326e8999d)) + +--- + +You can use the following template: + +## Widget or Playground [VERSION] (DATE) + +_includes `@rango-dev/widget-embedded@VERSION`_ + +### Bug Fixes + +- commit message + +### Features + +- commit message diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 21976fc633..466535b8ff 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,28 +1,87 @@ -## Release workflow +## Overview -A release can be a lib or an app/client release. We are publishing our libs to `npm` and our apps to `vercel`. +### Queue Manager -If a package is app, you need to add the package name to `scripts/publish.config.mjs` and then after getting a `PROJECT_ID` from Vercel, you need to set it as enviroment variable as well. +The Queue Manager is a library that facilitates efficient management of swaps by creating a queue structure similar to a linked list. It provides various APIs to create and manage queues, such as blocking a queue. The Queue Manager supports the execution of multiple queues simultaneously in parallel. -### Prerelase +The folder structure is as follows: -Our publish script will do these steps: +- `/queue-manager/core`: This directory contains the JavaScript implementation of the queue. +- `/queue-manager/react`: This directory integrates the core functionality with React, unlocking features like automatic re-renders. It makes the queue available to the entire React app using context. +- `/queue-manager/rango-preset`: This directory houses a comprehensive decentralized exchange (DEX) queue with advanced features such as parallel execution and multi-chain support. It is also integrated with Rango, enabling full-cycle swap functionality, including obtaining quotes, creating transactions, and signing them using wallets -1. Get the last release (by using git tags) and calculate changes since then. -2. Bump the version and create an prerelase tag for the changed packages -3. Determine the target deplyement by using `publish.config.mjs` -4. Publish libs to `npm` and apps to `Vercel` +### Wallets -Note: -Libs will be published under `next` tag on npm, which means you need to use `yarn add @rango/test-package@next` to install the published version whenever you need. -And also all the apps published by `prerelase` workflow will be published under the Vercel's `preview` enviroment. +We have developed a unified interface for most Web3 wallets, including Bitcoin, EVM, Cosmos, Solana, TON, and more. The library provides a core module that acts as a state manager and provider for the final wallet interface. Each wallet is referred to as a provider and contains the implementation specific to that wallet. -### Production relase +To add all our providers at once, simply pass the `provider-all`. If you only require specific providers, you can add them individually to your project by passing an array of `provider` objects. -Release should be triggered manually and then it will automatically published. You only need to run this command on you local machine to release the production: +For more information about the wallets, refer to the `/wallets/` directory. -`yarn run release` +### Widget -After release (Green pipleline), make sure you will merge `main` into `next` as well. +The Widget comprises high-level packages that include a user interface (UI) and different versions of our widget, which serves as a decentralized application (dApp). -`git pull && git checkout next && git pull && git merge main && git push` \ No newline at end of file +Here is the structure: +`/widget/ui`: This directory contains our UI components and Storybook for visual development and testing. +`/widget/embedded`: Our react implementation of the widget. They are publishing as NPM packages. +`/widget/app`: This directory houses a dApp that imports the embedded widget. +`/widget/playground`: This directory offers a playground environment where you can test and obtain configurations for our widget. +`/widget/iframe`: This directory contains a JavaScript class that simplifies the process of adding our iframe-based widget to dApps. + +## Translation + +First we need to extract the message from our source code using `yarn i18n:extract` and then we should run `yarn i18n:compile` to make a wrapper arround the translation file `.po` to be used inside our app. + +### Adding a new language + +1. Add to `locales: ['en']` in `lingui.config.ts` +2. Import and add to `messages` in `widget/ui/src/components/I18nManager/I18nManager.tsx` + + +## Crowdin + +Our project uses Crowdin for managing translations. You need access to two secret keys: + +- `CROWDIN_PROJECT_ID`: This secret key represents the project ID. +- `CROWDIN_PERSONAL_TOKEN`: Use this secret key for your Crowdin account. + + + **Source and Translation Files:** + + - The source file is located at: `translations/en.po` + - Translation files are located at: `translations/%two_letters_code%.po` + + **Workflow Execution:** + + - After each pull request merge into the `main` or `next` branch, the workflow is triggered. + - The command `i18n:extract` is executed, capturing all new changes and uploading them to Crowdin. + - The workflow then interacts with Crowdin, pushing new source content and pulling updated translations. + - A pull request titled 'New Crowdin translations' is automatically created, incorporating the latest changes. + - If the Crowdin pull request is successful, an automatic merge to the base branch is performed. + +The language code standard used is ISO 639-1. For more details and a list of codes, please refer to the https://www.loc.gov/standards/iso639-2/php/code_list.php. + +Additionally, there is the option to manually trigger the crowdin workflow if needed. + + +## Technical Notes + +### How we handle urls in embedded? + +`embedded` is importing in different environments (iframe, import as react component and a separate `app`). When it's being used as a react component we let the dApp to use it inside its router and they can load the widget in a separate route (not root `/`, e.g. `/swaps`). In this context we can not use absolute paths because we don't know the basename set by user, so we need to always use relative paths. Relative paths has been defined in [URL spec](https://url.spec.whatwg.org/#urls) so we can be sure it's a long term solution and will work in future or by changing our router librart (e.g. `react-router`). + +### HMR + +We are using Parcel for our client developments, to HMR working properly, we need to point to source code (instead of dist) for Parcel to be able to detect changes on development. One approach was using `module` field, it's not standard but has meaning for some compiler/building tools, so we decided to use `source` which is a Parcel thing only. + +You can check the details on #437 PR. + +### Styles + +We use CSS-in-JS for handling styles. To avoid potential issues with conflicting styles, we don't directly write specific class names. Instead, we prefer using custom tags. If we must use HTML tags with class names, we follow this pattern: + +````html + +```` + This helps keep our styles organized, reduces the chance of conflicts, and makes it easier to manage our code. diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000000..d645695673 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/commitlint.config.js b/commitlint.config.js new file mode 100644 index 0000000000..71ae943340 --- /dev/null +++ b/commitlint.config.js @@ -0,0 +1,5 @@ +const Configuration = { + extends: ['@commitlint/config-conventional'], +}; + +module.exports = Configuration; diff --git a/docs/code-splitting.md b/docs/code-splitting.md new file mode 100644 index 0000000000..1eabce6bdc --- /dev/null +++ b/docs/code-splitting.md @@ -0,0 +1,31 @@ +# Code Splitting + +As explained in [this link](https://legacy.reactjs.org/docs/code-splitting.html), Code-Splitting is a feature supported by some bundlers that allows the creation of multiple bundles that can be loaded dynamically at runtime. This technique enables us to "lazily-load" only the necessary components for the user's current needs, significantly enhancing the performance of the application. + + +## What we did + +- Splitting Signers from initial bundle + + +## What we are going to do + +Currently, we've achieved a good initial bundle size based on analyses conducted using tools like `lighthouse`. Some potential future works that could contribute to the journey ahead are listed below: + +- Implement retry mechanisms for dynamic imports to address issues with failing to import certain chunks. +- Maintain the applied changes to prevent future modifications from undoing the achieved results. +- Identify potential areas that can be dynamically imported. +- Attempt to enhance clients that have integrated widgets (like dapp) to improve overall performance. + + +## Technical Consideration + +- Avoid small chunks, they don't add any value to user. they will have network overhead as well. +- Chunks will be built using esbuild's [splitting](https://esbuild.github.io/api/#splitting) option. +- Code splitting for libraries is off by default. To enable the option, add the "--splitting" parameter to the "build" script of that package. + + +## Notes + +The `@rango-dev/signer-solana` package is not dynamically imported because it has a major dependency ("@solana/web3.js") that is also a dependency in `@solflare-wallet/sdk`, which is used in `provider-solflare`. This dependency cannot be dynamically imported, so importing `@rango-dev/signer-solana` dynamically would only result in a very small reduction in the bundle size. + diff --git a/docs/fork.md b/docs/fork.md new file mode 100644 index 0000000000..f7e0bbe84d --- /dev/null +++ b/docs/fork.md @@ -0,0 +1,18 @@ +# Fork + +## How you can test release flow? + +You need to add your [Github Token](https://github.com/settings/tokens) and set it as `PAT` in your fork's secrets. + +for NPM: + +- Create an NPM account and an organization. (I created @yeager-dev for example) +- Get a token from NPM and set it as `NPM_TOKEN` in our repo. +- Enable Github Actions on your fork. + +_Note 1_: If you are a Rango developer, you can ask NPM token for `@yeager-dev` org. + +For Crowdin: + +After creating a Crowdin project, it has an ID (you can find it in right sidebar) and for accessing to API you will [need a token](https://crowdin.com/settings#api-key) as well. +Then, you need to set `CROWDIN_PERSONAL_TOKEN` and `CROWDIN_PROJECT_ID` in your secrets. diff --git a/docs/prerelease.md b/docs/prerelease.md new file mode 100644 index 0000000000..f0828f3444 --- /dev/null +++ b/docs/prerelease.md @@ -0,0 +1,118 @@ +# Prerelease + +## Getting started + +Before release, please ensure the following steps are taken. + +First, Send a notice to your team to let them know `next` should be locked until release process is done. Also, inform them of the result and unlock the `next` branch after the release process is done. + +After sending a notice to start release process, you should manually run `Prerelease` workflow. It will run `crowdin` workflow to extract translation keys and push them to crowdin server and pull new translations to update current translations. After that, `Prerelease` workflow will deploy the `next` branch so the latest changes can be tested along side with latest translations. + +_Note 1_: Syncing translations (crowding workflow) is an optional step which means if it fails we will deploy anyway. + +Second, To identify changes since the last release, use the following commands: + +**Get last release commit:** + +```shell +git rev-list --max-count 1 --tags +``` + +**Get commits since last release:** + +```shell +git log --oneline --no-merges main..next +``` + +**Get file names that has changed since last release:** + +```shell +git diff --name-only origin/main +``` + +For a specific path: + +```shell +git diff --name-only origin/main wallets/ +``` + +**Check the excat changes on files since last release using VSCode:** + +Ensure you've added this config to your `~/.gitconfig` + +```shell +[diff] + tool = default-difftool +[difftool "default-difftool"] + cmd = code --wait --diff $LOCAL $REMOTE +``` + +Then, open files with the following command: + +```shell +git difftool origin/main -y +``` + +For a specific path: + +```shell +git difftool origin/main -y wallets/ +``` + +Note: The `-y` flag disables the prompt in the terminal. + +## Testing + +Before each release, we are doing some manual tests on different environments to make sure critical flows working correctly. Ensure the widget works as expected on Chrome and Firefox. + +### Environments + +#### Codesandbox + +You can use the following Codesandbox template: +https://codesandbox.io/p/sandbox/sweet-wing-2jf5j3 + +#### widget-examples + +You can find it here: +https://github.com/rango-exchange/widget-examples + +Update `widget-embedded` version to latest **_next_** version using this command: + +```shell +yarn add @rango-dev/widget-embedded@next +``` + +Note: don’t commit your changes to the repo, We will doing it after release the production successfully which means we only commit `production` version to the repo. More details is on `Post Release` document. + +#### Playground + +You will need following commands on `rango-client` repo: + +```shell +git checkout next +git pull +yarn clean +yarn build:all +yarn dev:playground +``` + +#### Vercel + +TBA + +#### Wallet's Browser + +TBA + +### Testing scenarios + +First, you will need to get a list of commits since the last release and check those areas first. + +Then: + +- Doing a single and multistep swap + - USDT (Polygon) -> USDC (Polygon): That would be great to check switch network by changing your network to not be on Polygon. + - Sol (Solana)-> Atom (Cosmos) +- Check your history +- Change settings (Language, Theme) diff --git a/docs/readme.md b/docs/readme.md new file mode 100644 index 0000000000..0101e8c189 --- /dev/null +++ b/docs/readme.md @@ -0,0 +1,3 @@ +# Docs + +Here, we are documenting some of our internal processes. diff --git a/docs/release.md b/docs/release.md new file mode 100644 index 0000000000..49f939db38 --- /dev/null +++ b/docs/release.md @@ -0,0 +1,100 @@ +# Release + +## How we are releasing a new version? + +A release can be a lib or an app/client release. We are publishing our libs to `npm` and deploying our apps (client) on `vercel`. + +If a package is client, you need to add the package name to `scripts/deploy/config.mjs` and then after getting a `PROJECT_ID` from Vercel, you need to set it as environment variable as well. + +There are main commands: + +`yarn run publish` for publishing our NPM packages. +`yarn run deploy` to deploy apps on Vercel. + +### Publish flow + +#### Publish + +Our publish script will do these steps: + +1. Get the last release (by using git tags) and calculate changes since then. +2. Bump the version for changed packages. +3. Create changelog, git tags and github release, and publish them to NPM. +4. Make a publish commit and push the updated packages (version) and tags to origin. + +Note: +Libs will be published under `next` tag on npm, which means you need to use `yarn add @rango/test-package@next` to install the published version whenever you need. + +#### Production release + +There is a workflow called `Production Release`, you just need to run this workflow manually and then it will automatically published. + +### Deploy flow + +You should manually trigger the `deploy` workflow. + +By running `yarn run deploy`, it will build all the apps/clients then will try to deploy them on vercel. + +If the workflow is running on `next` branch, it will be deployed as Vercel's `preview`. If not, it's production release. + +All the apps published by `prerelease` workflow will be published under the Vercel's `preview` environment. + +## How you can release a new version? + +### Next (Staging) + +A publish will be triggered when a **Pull Request** has been merged. + +### Production + +Follow these steps for the release: + +#### 1. Run the `Production Release` workflow manually. + +For releasing production, you need to run `Production Release` workflow, it will pull the latest translation changes on `next` branch and checkout to `next` branch and pull the latest changes then it tries to merge the `next` into `main` by `--no-ff` strategy, To make sure that a new commit is made And previous commits that may have `[skips ci]` Do not prevent workflow from triggering. + +#### 2. When workflow finished running, increase `widget/app` and `widget/playground` version and update changelog. + +You should submit a pull request to the main branch from a new hotfix branch, incrementing the minor version by 1. Additionally, please remember to update the 'CHANGELOG.md' file located at the root of the repository. To do this you can follow the following steps: + +1. If widget has any updates: + +```shell +cd widget/app +yarn version --minor --no-git-tag-version +``` + +2. if playground has any changes: + +```shell +cd widget/playground +yarn version --minor --no-git-tag-version +``` + +3. Then you need to update `/CHANGELOG.md` (root) and list all the changes into widget or playground. you can use the template at the end of list. _Don't forget to use correct date and version (that you've ran before)._ + +4. Finally, you can commit your changes, run the following commands from workspace's root: + +```shell +git add CHANGELOG.md +git add widget/app/package.json +git add widget/playground/package.json + +git commit -m "chore(release): deploy" -m "[skip ci]" +``` + +#### 3. Run the `Deploy` workflow if the publish was successful. + +#### 4. Promote our clients (widget and playground) to production on Vercel (ask the team if you don't have access). + +#### 5. Create a pull request from the `main` branch to `next` to update the `next` branch. + +Please keep in mind that this PR should be merged using the `Create a merge commit` strategy instead of the default `Rebase and merge` strategy. + +**NOTE 1:** + +Ensure you send a highlight note on Telegram [like this](https://t.me/c/1797229876/15255/23609) at the end. + +**NOTE 2:** + +Ensure you update widget-examples using `yarn add @rango-dev/widget-embedded@latest`. Then open a new PR on the repo to ensure all examples are on the latest version. diff --git a/docs/test.md b/docs/test.md new file mode 100644 index 0000000000..eabc518b81 --- /dev/null +++ b/docs/test.md @@ -0,0 +1,33 @@ +# Test + + +## How to write a test + +it's essential to adhere to the following principles: + +- Test descriptions should be meaningful. +- Use only English lowercase letters for descriptions. +- Test descriptions is better to start with the verb. +- Provide specific details about the functionality being tested. +- Use descriptive names for tests to facilitate understanding. +- Organize tests logically to enhance readability and navigation. +- Use edge cases and boundary conditions to ensure comprehensive testing. +- You can use `@faker-js/faker` library to create fake data + + + +## Examples + +To clarify the topic, some examples of token sort tests are given: + +good example: + - put pinned tokens first + - put native tokens first + - should be first result when address contains searched term + +bad example: +- pinned tokens are displayed first +- put pinned tokens +- Put Pinned tokens first +- when address contains searched term, should be first + \ No newline at end of file diff --git a/examples/queue-manager-demo/CHANGELOG.md b/examples/queue-manager-demo/CHANGELOG.md new file mode 100644 index 0000000000..c7c32cd409 --- /dev/null +++ b/examples/queue-manager-demo/CHANGELOG.md @@ -0,0 +1,67 @@ +# [0.11.0](https://github.com/rango-exchange/rango-client/compare/queue-manager-demo@0.10.0...queue-manager-demo@0.11.0) (2023-08-03) + + + +# [0.10.0](https://github.com/rango-exchange/rango-client/compare/queue-manager-demo@0.9.0...queue-manager-demo@0.10.0) (2023-08-01) + + + +# [0.8.0](https://github.com/rango-exchange/rango-client/compare/queue-manager-demo@0.7.0...queue-manager-demo@0.8.0) (2023-07-31) + + +### Features + +* add project id as a external value ([0c80404](https://github.com/rango-exchange/rango-client/commit/0c80404a8cacb6c5b0338dea1e416b0b11db254b)) +* Get Wallet Connect project id from config ([9fb30b4](https://github.com/rango-exchange/rango-client/commit/9fb30b4b1a83e2005bbf42553298f24b1e278e1c)) +* Support for WalletConnect 2 ([faedef0](https://github.com/rango-exchange/rango-client/commit/faedef0b5e6fc3c5ef881cbbe4ec05334cc1c910)) + + + +# [0.7.0](https://github.com/rango-exchange/rango-client/compare/queue-manager-demo@0.6.0...queue-manager-demo@0.7.0) (2023-07-11) + + + +# [0.6.0](https://github.com/rango-exchange/rango-client/compare/queue-manager-demo@0.5.0...queue-manager-demo@0.6.0) (2023-07-11) + + +### Bug Fixes + +* network type ([cd5e489](https://github.com/rango-exchange/rango-client/commit/cd5e489a8cdee72be6a697a346b42bbd9ce6bab0)) +* update widget affiliate config ([0655dc1](https://github.com/rango-exchange/rango-client/commit/0655dc1949e6e8a9b1efacb71e3f66ac3d1e30fb)) + + +### Features + +* add widget events and refactor swap execution events ([0d76806](https://github.com/rango-exchange/rango-client/commit/0d7680693dd77439de38cd0b20f263f6ae8cceb0)) + + + +# [0.5.0](https://github.com/rango-exchange/rango-client/compare/queue-manager-demo@0.4.0...queue-manager-demo@0.5.0) (2023-05-31) + + + +# [0.4.0](https://github.com/rango-exchange/rango-client/compare/queue-manager-demo@0.3.0...queue-manager-demo@0.4.0) (2023-05-31) + + + +# [0.3.0](https://github.com/rango-exchange/rango-client/compare/queue-manager-demo@0.2.0...queue-manager-demo@0.3.0) (2023-05-30) + + + +# [0.2.0](https://github.com/rango-exchange/rango-client/compare/queue-manager-demo@0.1.17...queue-manager-demo@0.2.0) (2023-05-30) + + + +## [0.1.17](https://github.com/rango-exchange/rango-client/compare/queue-manager-demo@0.1.16...queue-manager-demo@0.1.17) (2023-05-15) + + + +## [0.1.16](https://github.com/rango-exchange/rango-client/compare/queue-manager-demo@0.1.15...queue-manager-demo@0.1.16) (2023-05-15) + + +### Bug Fixes + +* update rango-types and fix notification bugs ([993f185](https://github.com/rango-exchange/rango-client/commit/993f185e0b8c5e5e15a2c65ba2d85d1f9c8daa90)) + + + diff --git a/examples/queue-manager-demo/package.json b/examples/queue-manager-demo/package.json new file mode 100644 index 0000000000..786b360e3f --- /dev/null +++ b/examples/queue-manager-demo/package.json @@ -0,0 +1,33 @@ +{ + "name": "@rango-dev/queue-manager-demo", + "version": "0.13.1-next.14", + "license": "MIT", + "private": true, + "source": "public/index.html", + "main": "dist/index.html", + "targets": { + "main": false + }, + "browserslist": "> 0.5%, last 2 versions, not dead", + "scripts": { + "dev": "parcel -p 3000 --cache-dir=.parcel-cache", + "build": "parcel build --cache-dir=.parcel-cache", + "clean": "rimraf .parcel-cache && rimraf dist" + }, + "devDependencies": { + "process": "^0.11.10", + "rango-sdk": "^0.1.57" + }, + "dependencies": { + "@rango-dev/provider-all": "^0.40.1-next.8", + "@rango-dev/provider-xdefi": "^0.40.1-next.6", + "@rango-dev/queue-manager-rango-preset": "^0.40.1-next.6", + "@rango-dev/queue-manager-react": "^0.27.0", + "@rango-dev/wallets-react": "^0.26.1-next.9", + "@rango-dev/wallets-shared": "^0.40.1-next.6", + "bignumber.js": "^9.1.1", + "ethers": "^6.13.2", + "rango-sdk-basic": "^0.1.57", + "rango-types": "^0.1.74" + } +} \ No newline at end of file diff --git a/queue-manager/demo/public/index.html b/examples/queue-manager-demo/public/index.html similarity index 100% rename from queue-manager/demo/public/index.html rename to examples/queue-manager-demo/public/index.html diff --git a/examples/queue-manager-demo/readme.md b/examples/queue-manager-demo/readme.md new file mode 100644 index 0000000000..82ed657cea --- /dev/null +++ b/examples/queue-manager-demo/readme.md @@ -0,0 +1 @@ +# @rango-dev/queue-manager-demo diff --git a/examples/queue-manager-demo/src/App.tsx b/examples/queue-manager-demo/src/App.tsx new file mode 100644 index 0000000000..b44697c90a --- /dev/null +++ b/examples/queue-manager-demo/src/App.tsx @@ -0,0 +1,70 @@ +import type { Wallet } from './flows/rango/types'; +import type { SwapQueueContext } from '@rango-dev/queue-manager-rango-preset'; +import type { Network, WalletType } from '@rango-dev/wallets-shared'; + +import { makeQueueDefinition } from '@rango-dev/queue-manager-rango-preset'; +import { Provider as ManagerProvider } from '@rango-dev/queue-manager-react'; +import { useWallets } from '@rango-dev/wallets-react'; +import React, { useMemo } from 'react'; + +import { FlowsList } from './components/FlowsList'; +import { History } from './components/History'; +import { Wallets } from './components/Wallets'; +import { getConfig } from './configs'; +import { meta, metamaskWallet } from './flows/rango/mock'; + +const wallet: Wallet = metamaskWallet; + +interface PropTypes { + connectedWallets: WalletType[]; +} + +export function App(props: PropTypes) { + const { + providers, + getSigners, + state, + canSwitchNetworkTo, + connect, + getWalletInfo, + } = useWallets(); + + const switchNetwork = async (wallet: WalletType, network: Network) => { + if (!canSwitchNetworkTo(wallet, network)) { + return undefined; + } + return connect(wallet, network); + }; + + const isMobileWallet = (walletType: WalletType): boolean => + !!getWalletInfo(walletType).mobileWallet; + + const allProviders = providers(); + const queueContext: SwapQueueContext = { + meta, + getSigners, + wallets: wallet, + providers: allProviders, + switchNetwork, + connect, + state, + isMobileWallet, + canSwitchNetworkTo, + }; + + const swapQueueDef = useMemo(() => { + return makeQueueDefinition({ + API_KEY: getConfig('API_KEY'), + }); + }, []); + + return ( + + +

Flows

+ +

History

+ +
+ ); +} diff --git a/queue-manager/demo/src/components/FlowRunner/index.tsx b/examples/queue-manager-demo/src/components/FlowRunner/index.tsx similarity index 100% rename from queue-manager/demo/src/components/FlowRunner/index.tsx rename to examples/queue-manager-demo/src/components/FlowRunner/index.tsx diff --git a/examples/queue-manager-demo/src/components/FlowsList/index.tsx b/examples/queue-manager-demo/src/components/FlowsList/index.tsx new file mode 100644 index 0000000000..6a7d691151 --- /dev/null +++ b/examples/queue-manager-demo/src/components/FlowsList/index.tsx @@ -0,0 +1,147 @@ +import { useManager } from '@rango-dev/queue-manager-react'; +import React, { useEffect, useState } from 'react'; +import { requestSwap, urlToToken } from '../../flows/rango/helpers'; +import { FlowRunner } from '../FlowRunner'; +import { WalletType } from '@rango-dev/wallets-shared'; + +interface PropTypes { + connectedWallets: WalletType[]; +} + +function FlowsList(props: PropTypes) { + const { manager } = useManager(); + const [fromToken, setFrom] = useState( + 'FANTOM.USDC--0x04068da6c83afcfa0e13ba15a6696662335d5b75' + ); + const [toToken, setTo] = useState('COSMOS.ATOM'); + const [input, setInput] = useState('10'); + + useEffect(() => { + manager?.run(); + }, []); + + useEffect(() => { + if (props.connectedWallets.length) { + console.log('[React] run retry on `props.connectedWallets`'); + manager?.retry(); + } + }, [props.connectedWallets]); + + const flows = [ + { + title: 'Single Wallet', + description: 'Run a simple swap by metamask', + requirements: ['Use metamsk', 'Change your network to ethereum.'], + onRun: () => { + const qId = manager?.create('simpleSwap', {}); + console.debug(`[Queue] created. ID: ${qId}`, manager); + }, + }, + { + title: 'Rango Swap (On-chain)', + description: 'Run a swap using Rango flow.', + requirements: ['Please use Metamask & Keplr', 'USDC -> USDT'], + onRun: async () => { + const from = urlToToken( + 'POLYGON.USDC--0x2791bca1f2de4661ed88a30c99a7a9449aa84174' + )!; + const to = urlToToken( + 'POLYGON.USDT--0xc2132d05d31c914a87c6611c10748aeb04b58e8f' + )!; + const swap = await requestSwap('2', from, to); + // toast({ eventType: 'swap_started', swap: newSwap, step: newSwap.steps[0] }); + const qId = manager?.create('rango-swap', { + swapDetails: swap, + }); + console.debug(`[Queue] Swap created. ID: ${qId}`, manager); + }, + }, + { + title: 'Rango Swap (Cross-chain)', + description: 'Run a swap using Rango flow.', + requirements: ['Please use Metamask & Keplr (cosmos) for now.'], + children: ( +
+
+ From: + { + setFrom(e.target.value); + }} + /> +
+
+ To: + { + setTo(e.target.value); + }} + /> +
+
+ Amount: + { + setInput(e.target.value); + }} + /> +
+
+ ), + onRun: async () => { + const from = urlToToken(fromToken)!; + const to = urlToToken(toToken)!; + const swap = await requestSwap(input, from, to); + // toast({ eventType: 'swap_started', swap: newSwap, step: newSwap.steps[0] }); + const qId = manager?.create('rango-swap', { + swapDetails: swap, + }); + console.debug(`[Queue] Swap created. ID: ${qId}`, manager); + }, + }, + { + title: 'Rango Parallel Swaps', + description: 'Run multiple swaps at the same time using Rango flow.', + requirements: [ + 'Please use Metamask & Keplr (cosmos) for now.', + 'FTM -> ATOM and USDC -> USDT on polygon', + ], + onRun: async () => { + const from1 = urlToToken( + 'POLYGON.USDC--0x2791bca1f2de4661ed88a30c99a7a9449aa84174' + )!; + const to1 = urlToToken( + 'POLYGON.USDT--0xc2132d05d31c914a87c6611c10748aeb04b58e8f' + )!; + const from2 = urlToToken( + 'FANTOM.USDC--0x04068da6c83afcfa0e13ba15a6696662335d5b75' + )!; + const to2 = urlToToken('COSMOS.ATOM')!; + const swap1 = await requestSwap('2', from1, to1); + const swap2 = await requestSwap('10', from2, to2); + + // toast({ eventType: 'swap_started', swap: newSwap, step: newSwap.steps[0] }); + const qId = manager?.create('rango-swap', { swapDetails: swap1 }); + const q2Id = manager?.create('rango-swap', { swapDetails: swap2 }); + console.debug(`[Queue] Swap created. ID: ${qId}`); + console.debug(`[Queue] Swap created. ID: ${q2Id}`); + }, + }, + ]; + + return ( +
+ {flows.map((flow, i) => ( + + ))} +
+ ); +} + +export { FlowsList }; diff --git a/queue-manager/demo/src/components/History/index.tsx b/examples/queue-manager-demo/src/components/History/index.tsx similarity index 100% rename from queue-manager/demo/src/components/History/index.tsx rename to examples/queue-manager-demo/src/components/History/index.tsx diff --git a/examples/queue-manager-demo/src/components/Wallets/index.tsx b/examples/queue-manager-demo/src/components/Wallets/index.tsx new file mode 100644 index 0000000000..33282bc736 --- /dev/null +++ b/examples/queue-manager-demo/src/components/Wallets/index.tsx @@ -0,0 +1,36 @@ +import { useWallets } from '@rango-dev/wallets-react'; +import React from 'react'; + +function Wallets() { + const { connect, providers, state, disconnect } = useWallets(); + const list = Object.keys(providers()); + return ( +
+

Available Wallets

+
+ {list.map((type) => { + const wallet_type = type; + const wallet_state = state(wallet_type); + return ( +
+
{wallet_type}
+

Address: {wallet_state.accounts?.join(',')}

+ +
+ ); + })} +
+
+ ); +} + +export { Wallets }; diff --git a/examples/queue-manager-demo/src/configs.ts b/examples/queue-manager-demo/src/configs.ts new file mode 100644 index 0000000000..f6d8f26f39 --- /dev/null +++ b/examples/queue-manager-demo/src/configs.ts @@ -0,0 +1,34 @@ +export interface Configs { + API_KEY: string; +} + +/* + * this API key is limited and + * it is only for test purpose + */ +const RANGO_PUBLIC_API_KEY = 'c6381a79-2817-4602-83bf-6a641a409e32'; +export const WC_PROJECT_ID = 'e24844c5deb5193c1c14840a7af6a40b'; +export const TREZOR_MANIFEST = { + appUrl: 'https://widget.rango.exchange/', + email: 'hi+trezorwidget@rango.exchange', +}; +export const TON_CONNECT_MANIFEST_URL = + 'https://raw.githubusercontent.com/rango-exchange/assets/refs/heads/main/manifests/tonconnect/manifest.json'; +let configs: Configs = { + API_KEY: RANGO_PUBLIC_API_KEY, +}; + +export function getConfig(name: keyof Configs) { + return configs[name]; +} + +export function setConfig(name: keyof Configs, value: any) { + configs[name] = value; + + return value; +} + +export function initConfig(nextConfigs: Configs) { + configs = structuredClone(nextConfigs); + return configs; +} diff --git a/examples/queue-manager-demo/src/flows/rango/helpers.ts b/examples/queue-manager-demo/src/flows/rango/helpers.ts new file mode 100644 index 0000000000..ce31d2c9b4 --- /dev/null +++ b/examples/queue-manager-demo/src/flows/rango/helpers.ts @@ -0,0 +1,784 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ +/* eslint-disable @typescript-eslint/no-throw-literal */ +/* eslint-disable @typescript-eslint/member-ordering */ +/* eslint-disable @typescript-eslint/no-magic-numbers */ +import type { + APIErrorCode, + BestRoute, + Blockchain, + CheckTxStatusRequest, + CreateTransactionRequest, + CreateTransactionResponse, + ErrorDetail, + RawAccounts, + SwapperStatusResponse, + SwapSavedSettings, + TokenMeta, + TransactionName, + UserWalletBlockchain, + WalletTypeAndAddress, +} from './types'; +import type { + AllBlockchains, + Network, + WalletType, +} from '@rango-dev/wallets-shared'; +import type { BestRouteRequest } from 'rango-sdk'; +import type { CheckApprovalResponse } from 'rango-sdk-basic'; +import type { + EvmBlockchainMeta, + PendingSwap, + PendingSwapStep, +} from 'rango-types'; + +import { SUPPORTED_ETH_CHAINS as XDEFI_WALLET_SUPPORTED_EVM_CHAINS } from '@rango-dev/provider-xdefi'; +import { legacyReadAccountAddress as readAccountAddress } from '@rango-dev/wallets-core/legacy'; +import { + Networks, + WalletTypes, + XDEFI_WALLET_SUPPORTED_NATIVE_CHAINS, +} from '@rango-dev/wallets-shared'; +import { BigNumber } from 'bignumber.js'; +import { ethers } from 'ethers'; +import { + isCosmosBlockchain, + isEvmBlockchain, + isSolanaBlockchain, + SignerError, +} from 'rango-types'; + +import { sampleRawAccounts } from './mock'; +import { + ApiMethodName, + EXODUS_WALLET_SUPPORTED_CHAINS, + NETWORK_TO_NATIVE_SYMBOL_MAP_FOR_1INCH, + NETWORKS_FOR_1INCH, + OKX_WALLET_SUPPORTED_CHAINS, + SWAPPER_ONE_INCH_LIST, +} from './types'; + +const UNKNOWN_COIN_IMAGE = '/coins/unknown.png'; +const BRAVE_USER_AGENT_HEADER = 'X-Brave'; +const url = 'https://api.rango.exchange'; + +export const BASE_URL = url; +export const RANGO_COOKIE_HEADER = 'X-Rango-Id'; +export const RANGO_DAPP_ID_QUERY = + 'apiKey=4a624ab5-16ff-4f96-90b7-ab00ddfc342c'; + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +declare const navigator: any; + +export function calculatePendingSwap( + inputAmount: string, + bestRoute: BestRoute, + wallets: { [p: string]: WalletTypeAndAddress }, + settings: SwapSavedSettings, + validateBalanceOrFee: boolean +): PendingSwap { + const simulationResult = bestRoute.result; + if (!simulationResult) { + throw Error('Simulation result should not be null'); + } + + return { + creationTime: new Date().getTime().toString(), + finishTime: null, + requestId: bestRoute.requestId || '', + inputAmount: inputAmount, + wallets, + status: 'running', + isPaused: false, + extraMessage: null, + extraMessageSeverity: null, + extraMessageDetail: null, + extraMessageErrorCode: null, + networkStatusExtraMessage: null, + networkStatusExtraMessageDetail: null, + lastNotificationTime: null, + settings: settings, + simulationResult: simulationResult, + validateBalanceOrFee, + steps: + bestRoute.result?.swaps?.map((s, i) => ({ + id: i + 1, + fromBlockchain: s.from.blockchain, + fromSymbol: s.from.symbol, + fromSymbolAddress: + NETWORKS_FOR_1INCH.includes(s.from.blockchain as Networks) && + SWAPPER_ONE_INCH_LIST.includes(s.swapperId) && + (!s.from.address || s.from.address.length === 0) + ? null + : s.from.address, + fromDecimals: s.from.decimals, + fromAmountPrecision: s.fromAmountPrecision, + fromAmountMinValue: s.fromAmountMinValue, + fromAmountMaxValue: s.fromAmountMaxValue, + toBlockchain: s.to.blockchain, + fromLogo: s.from.logo, + toSymbol: s.to.symbol, + toSymbolAddress: + NETWORKS_FOR_1INCH.includes(s.to.blockchain as Networks) && + SWAPPER_ONE_INCH_LIST.includes(s.swapperId) && + NETWORK_TO_NATIVE_SYMBOL_MAP_FOR_1INCH.get( + s.to.blockchain as Networks + ) === s.to.symbol && + (!s.to.address || s.to.address.length === 0) + ? null + : s.to.address, + toDecimals: s.to.decimals, + toLogo: s.to.logo, + startTransactionTime: new Date().getTime(), + swapperId: s.swapperId, + expectedOutputAmountHumanReadable: s.toAmount, + outputAmount: null, + status: 'created', + networkStatus: null, + executedTransactionId: null, + externalTransactionId: null, + explorerUrl: null, + trackingCode: null, + cosmosTransaction: null, + solanaTransaction: null, + evmTransaction: null, + evmApprovalTransaction: null, + transferTransaction: null, + diagnosisUrl: null, + internalSteps: null, + })) || [], + }; +} + +export function getCookieId(): string { + const key = 'X-Rango-Id'; + const cookieId = window.localStorage.getItem(key); + if (cookieId) { + return cookieId; + } + const value = + Math.random().toString(36).substring(2, 15) + + Math.random().toString(36).substring(2, 15); + window.localStorage.setItem(key, value); + return value; +} + +export const getBestRoute = async ( + from: TokenMeta, + to: TokenMeta, + amount: BigNumber, + rawAccounts: RawAccounts, + checkPrerequisites: boolean, + signal: AbortSignal | undefined, + selectedWallets?: { [p: string]: string }, + swappersGroupsBlackList?: string[], + blockchainsWhiteList?: Network[] +): Promise => { + const connectedWallets: UserWalletBlockchain[] = ( + rawAccounts?.blockchains || [] + ).map((b) => ({ + blockchain: b.name, + addresses: Array.from(new Set(b.accounts.map((a) => a.address))), + })); + + const body: BestRouteRequest = { + from: { + blockchain: from.blockchain, + symbol: from.symbol, + address: from.address, + }, + to: { blockchain: to.blockchain, symbol: to.symbol, address: to.address }, + amount: amount.toString(), + connectedWallets, + selectedWallets: selectedWallets || {}, + checkPrerequisites: checkPrerequisites, + affiliateRef: localStorage.getItem('affiliateRef'), + swapperGroups: swappersGroupsBlackList, + ...(!!swappersGroupsBlackList && { swappersGroupsExclude: true }), + blockchains: blockchainsWhiteList, + }; + const url = `${BASE_URL}/routing/best?${RANGO_DAPP_ID_QUERY}`; + + let isBrave: boolean; + try { + isBrave = navigator.brave && (await navigator.brave.isBrave()); + } catch (error) { + isBrave = false; + } + + const response = await fetch(url, { + method: 'POST', + headers: { + 'content-type': 'application/json;charset=UTF-8', + [RANGO_COOKIE_HEADER]: getCookieId(), + ...(isBrave && { [BRAVE_USER_AGENT_HEADER]: 'true' }), + }, + body: JSON.stringify(body), + signal, + }); + const res = await response.json(); + if (res?.status === 500 || res?.error) { + throw new Error(res?.error || `Error from server, status: ${res.status}`); + } + return res; +}; + +export const urlToToken = (s: string | null): TokenMeta | null => { + if (!s) { + return null; + } + + const ps1 = s.split('--'); + const ps2 = ps1[0].split('.'); + + return { + // symbol: ps2[1], // this doesnt work for USDT.E (on avax) AVAX.WETH.E--0x49d5c2bdffac6ce2bfdb6640f4f80f226bc10bab + symbol: ps2.slice(1).join('.'), + image: UNKNOWN_COIN_IMAGE, + blockchain: ps2[0] as Networks, + address: ps1.length === 2 ? decodeURIComponent(ps1[1]) : null, + usdPrice: null, + isSecondaryCoin: false, + coinSource: null, + name: null, + coinSourceUrl: null, + decimals: 18, + }; +}; + +export async function checkApproved( + requestId: string +): Promise { + const url = `${BASE_URL}/tx/${requestId}/check-approval?${RANGO_DAPP_ID_QUERY}`; + const response = await fetch(url, { + method: 'GET', + headers: { + 'content-type': 'application/json;charset=UTF-8', + [RANGO_COOKIE_HEADER]: getCookieId(), + }, + }); + + if ( + (!!response.status && (response.status < 200 || response.status >= 400)) || + !response.ok + ) { + const apiError = ERROR_COMMUNICATING_WITH_API(ApiMethodName.CheckApproval); + throw PrettyError.BadStatusCode(apiError, response.status); + } + + return await response.json(); +} + +export async function checkSwapStatus( + requestId: string, + txId: string, + step: number +): Promise { + const url = `${BASE_URL}/tx/check-status?${RANGO_DAPP_ID_QUERY}`; + const body: CheckTxStatusRequest = { step, txId, requestId }; + + const response = await fetch(url, { + method: 'POST', + headers: { + [RANGO_COOKIE_HEADER]: getCookieId(), + 'content-type': 'application/json;charset=UTF-8', + }, + body: JSON.stringify(body), + }); + + if ( + (!!response.status && (response.status < 200 || response.status >= 400)) || + !response.ok + ) { + const apiError = ERROR_COMMUNICATING_WITH_API( + ApiMethodName.CheckingTransactionStatus + ); + throw PrettyError.BadStatusCode(apiError, response.status); + } + + const res = await response.json(); + return { + ...res, + outputAmount: res.outputAmount ? new BigNumber(res.outputAmount) : null, + }; +} + +export const ERROR_ASSERTION_FAILED = 'Assertion failed (Unexpected behaviour)'; + +export const ERROR_COMMUNICATING_WITH_API = (apiMethodName: ApiMethodName) => + `Unexpected response from API (${apiMethodName})`; + +export const ERROR_DESCRIPTION_UNSUPPORTED_TRANSACTION = ( + method: string, + walletType: WalletType +) => `method: ${method} call is unsupported for wallet ${walletType}`; + +export const ERROR_SIGNING_TRANSACTION = (transactionName: TransactionName) => + `Error sending ${transactionName}`; +export const ERROR_REJECTING_TRANSACTION = 'User rejected the message signing'; + +export const ERROR_CREATE_TRANSACTION = + 'Create transaction failed in Rango Server'; +export const ERROR_INPUT_WALLET_NOT_FOUND = 'Input wallet not found'; + +export const DEFAULT_WALLET_INJECTION_ERROR = + 'Failed to connect to wallet, if you have turned injection off (disable default wallet for xDefi), turn it on and refresh the page'; + +export class PrettyError extends Error { + private readonly detail?: string; + private readonly root?: any; + private readonly code?: APIErrorCode; + + constructor(code: APIErrorCode, m: string, root?: any, detail?: string) { + super(m); + Object.setPrototypeOf(this, PrettyError.prototype); + this.code = code; + this.detail = detail; + this.root = root; + } + + getErrorDetail(): ErrorDetail { + const rawMessage = + typeof this.root === 'object' && this.root && this.root.error + ? this.root.error + : JSON.stringify(this.root); + const rootStr = + typeof this.root === 'string' + ? this.root + : this.root instanceof Error + ? this.root.message + : rawMessage; + return { + extraMessage: this.message, + extraMessageDetail: this.detail || rootStr, + extraMessageErrorCode: this.code || null, + }; + } + + static AssertionFailed(m: string): PrettyError { + return new PrettyError( + 'CLIENT_UNEXPECTED_BEHAVIOUR', + ERROR_ASSERTION_FAILED, + m + ); + } + + static BadStatusCode( + message: string, + statusCode: number | string + ): PrettyError { + return new PrettyError( + 'TX_FAIL', + message, + null, + `status code = ${statusCode}` + ); + } + + static CreateTransaction(detail: string): PrettyError { + return new PrettyError( + 'FETCH_TX_FAILED', + ERROR_CREATE_TRANSACTION, + null, + detail + ); + } + + static WalletMissing(): PrettyError { + return new PrettyError( + 'CLIENT_UNEXPECTED_BEHAVIOUR', + ERROR_INPUT_WALLET_NOT_FOUND, + null, + 'Server requested for a blockchain or address not selected by user' + ); + } + + static BlockchainMissing(): PrettyError { + return new PrettyError( + 'CLIENT_UNEXPECTED_BEHAVIOUR', + ERROR_INPUT_WALLET_NOT_FOUND, + null, + 'Server requested for a blockchain or address not selected by user' + ); + } +} + +export function getNextStep( + swap: PendingSwap, + currentStep: PendingSwapStep +): PendingSwapStep | null { + return ( + swap.steps.find( + (step) => + step.status !== 'failed' && + step.status !== 'success' && + step.id !== currentStep.id + ) || null + ); +} + +export async function createTransaction( + request: CreateTransactionRequest +): Promise { + const url = `${BASE_URL}/tx/create?${RANGO_DAPP_ID_QUERY}`; + try { + const response = await fetch(url, { + method: 'POST', + headers: { + 'content-type': 'application/json;charset=UTF-8', + [RANGO_COOKIE_HEADER]: getCookieId(), + }, + body: JSON.stringify(request), + }); + + if ( + (!!response.status && + (response.status < 200 || response.status >= 400)) || + !response.ok + ) { + throw PrettyError.CreateTransaction( + `Error creating the transaction, status code: ${response.status}` + ); + } + + const result: CreateTransactionResponse = await response.json(); + if (!result.ok || !result.transaction) { + throw PrettyError.CreateTransaction( + result.error || 'bad response from create tx endpoint' + ); + } + + return result; + } catch (error: any) { + throw PrettyError.CreateTransaction(error.message); + } +} + +export const prettifyErrorMessage = (obj: unknown): ErrorDetail => { + if (!obj) { + return { extraMessage: '', extraMessageErrorCode: null }; + } + if (obj instanceof PrettyError) { + return obj.getErrorDetail(); + } + if (obj instanceof SignerError) { + const t = obj.getErrorDetail(); + return { + extraMessage: t.message, + extraMessageDetail: t.detail, + extraMessageErrorCode: t.code, + }; + } + if (obj instanceof Error) { + return { + extraMessage: obj.toString(), + extraMessageErrorCode: null, + }; + } + if (typeof obj !== 'string') { + return { + extraMessage: JSON.stringify(obj), + extraMessageErrorCode: null, + }; + } + return { extraMessage: obj, extraMessageErrorCode: null }; +}; + +export const getEvmApproveUrl = ( + tx: string, + network: Network, + evmBasedBlockchains: EvmBlockchainMeta[] +): string => { + const evmBlochain = evmBasedBlockchains.find( + (blockchain) => blockchain.name === network + ); + + if (!evmBlochain) { + throw Error(`unsupported network: ${network} for getting approve url.`); + } + + if (evmBlochain.info.transactionUrl) { + return evmBlochain.info.transactionUrl.replace( + '{txHash}', + tx.toLowerCase() + ); + } + + throw Error(`Explorer url for ${network} is not implemented`); +}; + +export const getCurrentBlockchainOfOrNull = ( + swap: PendingSwap, + step: PendingSwapStep +): Network | null => { + try { + return getCurrentBlockchainOf(swap, step); + } catch (e) { + return null; + } +}; + +export const getCurrentBlockchainOf = ( + swap: PendingSwap, + step: PendingSwapStep +): Network => { + const b1 = + step.evmTransaction?.blockChain || + step.evmApprovalTransaction?.blockChain || + step.cosmosTransaction?.blockChain || + step.solanaTransaction?.blockChain; + if (b1) { + return b1; + } + + const transferAddress = step.transferTransaction?.fromWalletAddress; + if (!transferAddress) { + throw PrettyError.BlockchainMissing(); + } + + const blockchain = + Object.keys(swap.wallets).find( + (b) => swap.wallets[b]?.address === transferAddress + ) || null; + if (blockchain == null) { + throw PrettyError.BlockchainMissing(); + } + + // TODO: check why it returns string + return blockchain; +}; + +export interface ConvertToFullAccountInfo { + evmBasedChainsNames: string[]; + supportedChainsByWallets: { [type in WalletType]?: Network[] } | null; +} +export function convertRawAccountToFullAccount( + wallet: WalletType, + accounts: string[], + connectedNetwork: Network | null, + info: ConvertToFullAccountInfo +): Blockchain[] { + const { evmBasedChainsNames: evmBasedChains, supportedChainsByWallets } = + info; + const result = {} as { [type in Network]: Blockchain }; + + function addAccount(network: Network, address: string) { + const isConnected = network === connectedNetwork; + const newAccount = { + address, + balances: null, + loading: true, + walletType: wallet, + isConnected, + error: false, + explorerUrl: null, + }; + + if (result[network]) { + result[network].accounts.push(newAccount); + } else { + result[network] = { + name: network, + accounts: [newAccount], + }; + } + } + + const supportedChains = supportedChainsByWallets?.[wallet] || []; + + accounts.forEach((account) => { + const { address, network } = readAccountAddress(account); + + const hasLimitation = supportedChains.length > 0; + const isSupported = supportedChains.includes(network); + const isUnknown = network === Networks.Unknown; + const notSupportedNetworkByWallet = + hasLimitation && !isSupported && !isUnknown; + + /* + * Here we check given `network` is not supported by wallet + * And also the network is known. + */ + if (notSupportedNetworkByWallet) { + return; + } + + /* + * In some cases we can handle unknown network by checking its address + * pattern and act on it. + * Example: showing our evm compatible netwrok when the uknown network is evem. + * Otherwise, we stop executing this function. + */ + const isUknownAndEvmBased = + network === Networks.Unknown && ethers.isAddress(address); + if (isUnknown && !isUknownAndEvmBased) { + return; + } + + const isEvmBasedChain = evmBasedChains.includes(network); + + // If it's an evm network, we will add the address to all the evm chains. + if (isEvmBasedChain || isUknownAndEvmBased) { + /* + * all evm chains are not supported in wallets, so we are adding + * only to those that are supported by wallet. + */ + const evmChainsSupportedByWallet = supportedChains.filter((chain) => + evmBasedChains.includes(chain) + ); + + evmChainsSupportedByWallet.forEach((network) => { + /* + * EVM addresses are not case sensetive. + * Some wallets like Binance-chain return some letters in uppercase which produces bugs in our wallet state. + */ + addAccount(network, address.toLowerCase()); + }); + } else { + addAccount(network, address); + } + }); + + return Object.values(result); +} + +export const evmBasedChainsNamesSelector = (blockchains: AllBlockchains) => + Object.entries(blockchains) + .map(([, blockchainMeta]) => blockchainMeta) + .filter(isEvmBlockchain) + .map((blockchainMeta) => blockchainMeta.name); + +export const walletsAndSupportedChainsMetaSelector = ( + blockchains: AllBlockchains +): any | null => { + // TODO WalletsAndSupportedChains can't find model for return type + if (Object.entries(blockchains).length === 0) { + return null; + } + const blockchainsArray = Object.entries(blockchains).map( + ([, blockchainMeta]) => blockchainMeta + ); + const evmBlockchains = blockchainsArray.filter(isEvmBlockchain); + const solanaBlockchain = blockchainsArray.filter(isSolanaBlockchain); + const cosmosBlockchains = blockchainsArray.filter(isCosmosBlockchain); + return { + [WalletTypes.META_MASK]: evmBlockchains, + [WalletTypes.COINBASE]: [...evmBlockchains, ...solanaBlockchain], + [WalletTypes.KEPLR]: cosmosBlockchains.filter( + (blockchainMeta) => !!blockchainMeta.info + ), + [WalletTypes.PHANTOM]: solanaBlockchain, + [WalletTypes.XDEFI]: blockchainsArray.filter((blockchainMeta) => + [ + ...XDEFI_WALLET_SUPPORTED_EVM_CHAINS, + ...XDEFI_WALLET_SUPPORTED_NATIVE_CHAINS, + Networks.SOLANA, + ].includes(blockchainMeta.name as Networks) + ), + [WalletTypes.TRUST_WALLET]: evmBlockchains, + [WalletTypes.COIN98]: [...evmBlockchains, ...solanaBlockchain], + [WalletTypes.OKX]: blockchainsArray.filter((blockchainMeta) => + OKX_WALLET_SUPPORTED_CHAINS.includes(blockchainMeta.name as Networks) + ), + + [WalletTypes.EXODUS]: blockchainsArray.filter((blockchainMeta) => + EXODUS_WALLET_SUPPORTED_CHAINS.includes(blockchainMeta.name as Networks) + ), + + [WalletTypes.TOKEN_POCKET]: evmBlockchains, + [WalletTypes.STATION]: [], + [WalletTypes.LEAP]: [], + [WalletTypes.MATH]: [...evmBlockchains, ...solanaBlockchain], + [WalletTypes.SAFEPAL]: [ + ...evmBlockchains, + ...solanaBlockchain, + /* + * ...blockchainsArray.filter((blockchainMeta) => + * SAFEPAL_SUPPORTED_NATIVE_CHAINS.includes(blockchainMeta.name), + * ), + */ + ], + [WalletTypes.CLOVER]: [...evmBlockchains, ...solanaBlockchain], + [WalletTypes.COSMOSTATION]: [ + ...evmBlockchains, + ...cosmosBlockchains.filter((blockchainMeta) => !!blockchainMeta.info), + ], + [WalletTypes.BRAVE]: [...evmBlockchains, ...solanaBlockchain], + }; +}; + +export const walletsAndSupportedChainsNamesSelector = (blockchains: any) => { + const walletsAndSupportedChainsMeta = + walletsAndSupportedChainsMetaSelector(blockchains); + if (!walletsAndSupportedChainsMeta) { + return null; + } + const walletsAndSupportedChainsNames: { + [type: WalletType]: Network[] | undefined; + } = {}; + for (const key in walletsAndSupportedChainsMeta) { + walletsAndSupportedChainsNames[key] = walletsAndSupportedChainsMeta[ + key + ].map((blockchainMeta: { name: any }) => blockchainMeta.name); + } + return walletsAndSupportedChainsNames; +}; + +export async function requestSwap( + input: string, + from: TokenMeta, + to: TokenMeta +) { + const inputAmount = input; + const amount = new BigNumber(inputAmount); + const rawAccounts = sampleRawAccounts; + const checkPrerequisites = true; + const signal = undefined; + const selectedWallets = { + BSC: '0x2702d89c1c8658b49c45dd460deebcc45faec03c', + POLYGON: '0x2702d89c1c8658b49c45dd460deebcc45faec03c', + FANTOM: '0x2702d89c1c8658b49c45dd460deebcc45faec03c', + AVAX_CCHAIN: '0x2702d89c1c8658b49c45dd460deebcc45faec03c', + COSMOS: 'cosmos1unf2rcytjxfpz8x8ar63h4qeftadptg5r5qswd', + }; + const swappersGroupsBlackList: string[] | undefined = []; + const blockchainsWhiteList: string[] | undefined = []; + + const bestRoute = await getBestRoute( + from, + to, + amount, + rawAccounts, + checkPrerequisites, + signal, + selectedWallets, + swappersGroupsBlackList, + blockchainsWhiteList + ); + + if (!bestRoute) { + throw 'No route found.'; + } + + const settings = { + slippage: '1.0', + disabledSwappersIds: [], + disabledSwappersGroups: [], + }; + const wallets: { [p: string]: WalletTypeAndAddress } = {}; + if (rawAccounts) { + rawAccounts.blockchains.forEach((item) => { + // We know there is only one account. + wallets[item.name] = item.accounts[0]; + }); + } + + const newSwap: PendingSwap = calculatePendingSwap( + inputAmount, + bestRoute, + wallets, + settings, + false + ); + + return newSwap; +} diff --git a/examples/queue-manager-demo/src/flows/rango/mock.ts b/examples/queue-manager-demo/src/flows/rango/mock.ts new file mode 100644 index 0000000000..d137402e9d --- /dev/null +++ b/examples/queue-manager-demo/src/flows/rango/mock.ts @@ -0,0 +1,6325 @@ +import { Meta, Networks, WalletTypes } from '@rango-dev/wallets-shared'; +import { RawAccounts, Wallet } from './types'; + +const evmAddress = '0x2702d89c1c8658b49c45dd460deebcc45faec03c'; +const cosmosAddress = 'cosmos1unf2rcytjxfpz8x8ar63h4qeftadptg5r5qswd'; + +export const sampleRawAccounts: RawAccounts = (() => { + const evm = [ + 'BSC', + 'POLYGON', + 'ETH', + 'AVAX_CCHAIN', + 'ARBITRUM', + 'FANTOM', + 'OPTIMISM', + 'OKC', + 'CRONOS', + 'MOONRIVER', + 'MOONBEAM', + 'HECO', + 'AURORA', + 'HARMONY', + 'EVMOS', + 'GNOSIS', + 'FUSE', + 'BOBA', + ].map((network) => { + return { + name: network, + accounts: [ + { + address: evmAddress, + walletType: WalletTypes.META_MASK, + }, + ], + }; + }); + const cosmos = [ + { + name: Networks.COSMOS, + accounts: [ + { + address: cosmosAddress, + walletType: WalletTypes.KEPLR, + }, + ], + }, + ]; + return { + blockchains: [...evm, ...cosmos], + }; +})(); + +export const metamaskWallet = { + blockchains: [ + { + name: 'BSC', + accounts: [ + { + address: '0x2702d89c1c8658b49c45dd460deebcc45faec03c', + balances: [ + { + chain: 'BSC', + symbol: 'SWAP8.IO', + ticker: 'SWAP8.IO', + address: '0xcaee79616cffeb53fdda5792742a5c084f879dec', + rawAmount: '980000000000000000000000', + decimal: 18, + amount: '980000', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'PDOT.IO', + ticker: 'PDOT.IO', + address: '0x8bd0e87273364ebbe3482efc166f7e0d34d82c25', + rawAmount: '95641000000000000000000', + decimal: 18, + amount: '95641', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'ZEPE.IO', + ticker: 'ZEPE.IO', + address: '0x119e2ad8f0c85c6f61afdf0df69693028cdc10be', + rawAmount: '750000000000000000000000', + decimal: 18, + amount: '750000', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: '0GAS.IO', + ticker: '0GAS.IO', + address: '0x2231e1c01056aebab3113d684b034b50a99a56c7', + rawAmount: '16000000000000', + decimal: 9, + amount: '16000', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'LUNA', + ticker: 'LUNA', + address: '0x030612e22610219733f3e942bb67004d6cbd796b', + rawAmount: '350000000000000000000', + decimal: 18, + amount: '350', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'FTM', + ticker: 'FTM', + address: '0xad29abb318791d579433d831ed122afeaf29dcfe', + rawAmount: '60035619283908361569', + decimal: 18, + amount: '60.035619283908361569', + logo: 'https://api.rango.exchange/i/mZqhCJ', + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'GGBOXS.COM', + ticker: 'GGBOXS.COM', + address: '0x2248ba304d2045cdc144866ce37d1435a30b29f3', + rawAmount: '60000000000000000000000', + decimal: 18, + amount: '60000', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'AGP', + ticker: 'AGP', + address: '0x1c749d5f5630cf365673bf6c0b6b0570c48da112', + rawAmount: '6300000', + decimal: 6, + amount: '6.3', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'UST', + ticker: 'UST', + address: '0x3d4350cd54aef9f9b2c29435e0fa809957b3f30a', + rawAmount: '5015300', + decimal: 6, + amount: '5.0153', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'ALPACA', + ticker: 'ALPACA', + address: '0xb926beb62d7a680406e06327c87307c1ffc4ab09', + rawAmount: '50', + decimal: 18, + amount: '0.00000000000000005', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'NUSD', + ticker: 'NUSD', + address: '0x23b891e5c62e0955ae2bd185990103928ab817b3', + rawAmount: '25863658894004353627', + decimal: 18, + amount: '25.863658894004353627', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'RENUSDT', + ticker: 'RENUSDT', + address: '0xf55941e971302c634c586416c43469f3ead5ad3e', + rawAmount: '4997500', + decimal: 6, + amount: '4.9975', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'MMDEX.IO', + ticker: 'MMDEX.IO', + address: '0xdc4cb4c3587532409a4545aa79a15d967bed1c08', + rawAmount: '250000000000000000000000', + decimal: 18, + amount: '250000', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'BOWDAO.NET', + ticker: 'BOWDAO.NET', + address: '0x3bab61ad5d103bb5b203c9092eb3a5e11677a5d0', + rawAmount: '660000000000000000000000', + decimal: 18, + amount: '660000', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'APC', + ticker: 'APC', + address: '0xda2d21872999e700a715a1bda3153eb9079770bb', + rawAmount: '124889000', + decimal: 6, + amount: '124.889', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'LINK', + ticker: 'LINK', + address: '0xf8a0bf9cf54bb92f17374d9e9a321e6a111a51bd', + rawAmount: '7095490344', + decimal: 18, + amount: '0.000000007095490344', + logo: 'https://api.rango.exchange/i/hWjRK2', + usdPrice: 5.947, + }, + { + chain: 'BSC', + symbol: 'LUNA2.APP', + ticker: 'LUNA2.APP', + address: '0x9171c79f543b298fbd39642dc29e1454e2878665', + rawAmount: '188888', + decimal: 0, + amount: '188888', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'EOS', + ticker: 'EOS', + address: '0x56b6fb708fc5732dec1afc8d8556423a2edccbd6', + rawAmount: '6521653134', + decimal: 18, + amount: '0.000000006521653134', + logo: 'https://api.rango.exchange/i/KeunI3', + usdPrice: 0.874, + }, + { + chain: 'BSC', + symbol: 'ANGELDUST', + ticker: 'ANGELDUST', + address: '0x32d3499feca3f881d779f0183d7b41d32b2498df', + rawAmount: '741825180000', + decimal: 6, + amount: '741825.18', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'ORBIT', + ticker: 'ORBIT', + address: '0xdfb8603d947ab42fb76eb3bb14d9dde4334130d2', + rawAmount: '58397000000000000000000', + decimal: 18, + amount: '58397', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'WAVAX', + ticker: 'WAVAX', + address: '0x96412902aa9aff61e13f085e70d3152c6ef2a817', + rawAmount: '8087494716', + decimal: 18, + amount: '0.000000008087494716', + logo: 'https://api.rango.exchange/i/7QDOTz', + usdPrice: 11.745, + }, + { + chain: 'BSC', + symbol: 'GASDAO.CC', + ticker: 'GASDAO.CC', + address: '0x1c0294b8a8ae3d64d8629de723cb9e44f5f12c63', + rawAmount: '9500000000000', + decimal: 8, + amount: '95000', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'MINIDOGE', + ticker: 'MINIDOGE', + address: '0x50fa1d465b2a4a13d64e9fa428ccc98ec873ae64', + rawAmount: '500000000000000000000000000000', + decimal: 18, + amount: '500000000000', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'VELO', + ticker: 'VELO', + address: '0x17d1285bc68d9085f8e4b86fc565e452b29dc48f', + rawAmount: '150000000000000000000000', + decimal: 18, + amount: '150000', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'ARTQ.ME', + ticker: 'ARTQ.ME', + address: '0xf0ef30735455d5315873cc2e2966cb20047bdb29', + rawAmount: '6000000000000000000000', + decimal: 18, + amount: '6000', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'USDCSWAP.ORG', + ticker: 'USDCSWAP.ORG', + address: '0x43217359af5f01cf82c12a7a058ba221acdaef38', + rawAmount: '500', + decimal: 0, + amount: '500', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: '1INCH', + ticker: '1INCH', + address: '0x111111111117dc0aa78b770fa6a738034120c302', + rawAmount: '271002710027100234', + decimal: 18, + amount: '0.271002710027100234', + logo: 'https://api.rango.exchange/i/9D6oXE', + usdPrice: 0.397, + }, + { + chain: 'BSC', + symbol: 'MAI', + ticker: 'MAI', + address: '0x3f56e0c36d275367b8c502090edf38289b3dea0d', + rawAmount: '19277503723092914708', + decimal: 18, + amount: '19.277503723092914708', + logo: 'https://api.rango.exchange/i/rcaHva', + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'ATOM', + ticker: 'ATOM', + address: '0x0eb3a705fc54725037cc9e008bdede697f62f335', + rawAmount: '28750711363627413', + decimal: 18, + amount: '0.028750711363627413', + logo: 'https://api.rango.exchange/i/UT9ERo', + usdPrice: 8.94, + }, + { + chain: 'BSC', + symbol: '1GAS.ORG', + ticker: '1GAS.ORG', + address: '0xd35f9ab96d04adb02fd549ef6a576ce4e2c1d935', + rawAmount: '92280000000000000000000', + decimal: 18, + amount: '92280', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'BOHM', + ticker: 'BOHM', + address: '0xbe2bac22b5f4d1126c705cb21335960531bae847', + rawAmount: '100000000000000000000', + decimal: 18, + amount: '100', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'BTCB', + ticker: 'BTCB', + address: '0x7130d2a12b9bcbfae4f2634d864a1ee1ce3ead9c', + rawAmount: '71529099712895', + decimal: 18, + amount: '0.000071529099712895', + logo: 'https://api.rango.exchange/i/MHEGHG', + usdPrice: 16863.776, + }, + { + chain: 'BSC', + symbol: 'EDG', + ticker: 'EDG', + address: '0xa2e26f5f663e18fa942db6edf3269449d75d6d85', + rawAmount: '10000000000', + decimal: 25, + amount: '0.000000000000001', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'SUSHI', + ticker: 'SUSHI', + address: '0x947950bcc74888a40ffa2593c5798f11fc9124c4', + rawAmount: '836519539228464427', + decimal: 18, + amount: '0.836519539228464427', + logo: 'https://api.rango.exchange/i/NgIT7y', + usdPrice: 0.941, + }, + { + chain: 'BSC', + symbol: 'PGAME', + ticker: 'PGAME', + address: '0x4dc90e30015af10e64a2f1ac390754cfb0454373', + rawAmount: '10952400', + decimal: 6, + amount: '10.9524', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'MATIC', + ticker: 'MATIC', + address: '0xcc42724c6683b7e57334c4e856f4c9965ed682bd', + rawAmount: '1000000008755996216', + decimal: 18, + amount: '1.000000008755996216', + logo: 'https://api.rango.exchange/i/vTlTjv', + usdPrice: 0.791, + }, + { + chain: 'BSC', + symbol: 'FISTDAO', + ticker: 'FISTDAO', + address: '0x41791dab02a1f9b2430cd46f2c6a2b33aa7fd25d', + rawAmount: '880000000000', + decimal: 9, + amount: '880', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'FF18.IO', + ticker: 'FF18.IO', + address: '0x491b25000d386cd31307580171a510d32d7e64ee', + rawAmount: '800000000000000000000000', + decimal: 18, + amount: '800000', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'RAY', + ticker: 'RAY', + address: '0x13b6a55662f6591f8b8408af1c73b017e32eedb8', + rawAmount: '4793579', + decimal: 6, + amount: '4.793579', + logo: 'https://api.rango.exchange/i/kNjVdm', + usdPrice: 0.15, + }, + { + chain: 'BSC', + symbol: 'AGEUR', + ticker: 'AGEUR', + address: '0x38c84d5bbad726d465cf6a5349e41d6d7095faf7', + rawAmount: '8242220000000000', + decimal: 18, + amount: '0.00824222', + logo: 'https://api.rango.exchange/i/d5IrO0', + usdPrice: 1.059, + }, + { + chain: 'BSC', + symbol: 'KK', + ticker: 'KK', + address: '0x482794a6efb37e3fbd51f537c7102e9ab188b818', + rawAmount: '53000000000000000000', + decimal: 18, + amount: '53', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'O3', + ticker: 'O3', + address: '0xee9801669c6138e84bd50deb500827b776777d28', + rawAmount: '1256000000000000000', + decimal: 18, + amount: '1.256', + logo: 'https://api.rango.exchange/i/lfPJOy', + usdPrice: 0.0443, + }, + { + chain: 'BSC', + symbol: 'AIR', + ticker: 'AIR', + address: '0xbc6675de91e3da8eac51293ecb87c359019621cf', + rawAmount: '1921604000000000000000000', + decimal: 18, + amount: '1921604', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'DOGGY', + ticker: 'DOGGY', + address: '0x74926b3d118a63f6958922d3dc05eb9c6e6e00c6', + rawAmount: '283511485676805491', + decimal: 18, + amount: '0.283511485676805491', + logo: 'https://api.rango.exchange/i/1lJ2Z3', + usdPrice: 0.00031, + }, + { + chain: 'BSC', + symbol: 'SEG', + ticker: 'SEG', + address: '0x2eeff21c71ae38f9c34496cd9250c0d186dcd988', + rawAmount: '100000000000000', + decimal: 18, + amount: '0.0001', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'MIM', + ticker: 'MIM', + address: '0xfe19f0b51438fd612f6fd59c1dbb3ea319f433ba', + rawAmount: '15022048536804216097', + decimal: 18, + amount: '15.022048536804216097', + logo: 'https://api.rango.exchange/i/L5wafC', + usdPrice: 0.993, + }, + { + chain: 'BSC', + symbol: 'USDSWAP.IO', + ticker: 'USDSWAP.IO', + address: '0xb2ad5142b8ccb380731866bc42b3619759f3f7b3', + rawAmount: '1286698', + decimal: 0, + amount: '1286698', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'PSG', + ticker: 'PSG', + address: '0xbc5609612b7c44bef426de600b5fd1379db2ecf1', + rawAmount: '14', + decimal: 2, + amount: '0.14', + logo: 'https://api.rango.exchange/i/OiA2jQ', + usdPrice: 5.685, + }, + { + chain: 'BSC', + symbol: 'ETH', + ticker: 'ETH', + address: '0x2170ed0880ac9a755fd29b2688956bd959f933f8', + rawAmount: '14825954098793468', + decimal: 18, + amount: '0.014825954098793468', + logo: 'https://api.rango.exchange/i/qr4L6S', + usdPrice: 1209.693, + }, + { + chain: 'BSC', + symbol: 'SAFEMOON', + ticker: 'SAFEMOON', + address: '0x2df0b14ee90671021b016dab59f2300fb08681fa', + rawAmount: '255', + decimal: 18, + amount: '0.000000000000000255', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'POODL', + ticker: 'POODL', + address: '0x4a68c250486a116dc8d6a0c5b0677de07cc09c5d', + rawAmount: '6184580930', + decimal: 9, + amount: '6.18458093', + logo: 'https://api.rango.exchange/i/ehIL4M', + usdPrice: 7.1e-9, + }, + { + chain: 'BSC', + symbol: 'AVAX', + ticker: 'AVAX', + address: '0x1ce0c2827e2ef14d5c4f29a091d735a204794041', + rawAmount: '4705457968658479', + decimal: 18, + amount: '0.004705457968658479', + logo: 'https://api.rango.exchange/i/kX4edQ', + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'MGRT', + ticker: 'MGRT', + address: '0xd08f7b01fdd26928dcdc956610a5332f17b3ea11', + rawAmount: '1119800000000000000', + decimal: 18, + amount: '1.1198', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'WBNB', + ticker: 'WBNB', + address: '0xbb4cdb9cbd36b01bd1cbaebf2de08d9173bc095c', + rawAmount: '23374035802351054', + decimal: 18, + amount: '0.023374035802351054', + logo: 'https://api.rango.exchange/i/lRTcZT', + usdPrice: 248.431, + }, + { + chain: 'BSC', + symbol: 'ANYFUSE', + ticker: 'ANYFUSE', + address: '0x43242138833e8d360e84920462a483eb9e35c8b4', + rawAmount: '32000000000000000000', + decimal: 18, + amount: '32', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'AGILESWAP.IO', + ticker: 'AGILESWAP.IO', + address: '0xcf8b4e69707e22dc5062f80576d9f069275ed1b5', + rawAmount: '12000000000000', + decimal: 9, + amount: '12000', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'BNBM', + ticker: 'BNBM', + address: '0xe8d6eccf4df7067a52d43495c11b69deeedb965e', + rawAmount: '207961000000000000000000', + decimal: 18, + amount: '207961', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'PAYOU', + ticker: 'PAYOU', + address: '0x1e8f7bfdcf6d95eea81e039234624fa6b78bd389', + rawAmount: '923000000000000000000', + decimal: 18, + amount: '923', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'AABEK', + ticker: 'AABEK', + address: '0x68d1569d1a6968f194b4d93f8d0b416c123a599f', + rawAmount: '20819314000000000', + decimal: 9, + amount: '20819314', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'TRX', + ticker: 'TRX', + address: '0x85eac5ac2f758618dfa09bdbe0cf174e7d574d5b', + rawAmount: '2425322528', + decimal: 18, + amount: '0.000000002425322528', + logo: 'https://api.rango.exchange/i/sJnSkq', + usdPrice: 0.055, + }, + { + chain: 'BSC', + symbol: 'RIFTDAO.NET', + ticker: 'RIFTDAO.NET', + address: '0x4f6a82bb5fd0996158c9ac6bd3605489cad82d8d', + rawAmount: '738097000000000000000000', + decimal: 18, + amount: '738097', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'ETH-1INCH.IO', + ticker: 'ETH-1INCH.IO', + address: '0xa83b6a470771da2d979480b2e742962088608ced', + rawAmount: '870000000000000000', + decimal: 18, + amount: '0.87', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'ODDZ', + ticker: 'ODDZ', + address: '0xcd40f2670cf58720b694968698a5514e924f742d', + rawAmount: '77970995683712403', + decimal: 18, + amount: '0.077970995683712403', + logo: 'https://api.rango.exchange/i/s6bU0A', + usdPrice: 0.0121, + }, + { + chain: 'BSC', + symbol: 'TBBT.ORG', + ticker: 'TBBT.ORG', + address: '0xbf7183b8c8e5bb2d10f63678abb5d52df72712b2', + rawAmount: '50000000000000000000000', + decimal: 18, + amount: '50000', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'DASH', + ticker: 'DASH', + address: '0x3291a9352e553740bf78ce94fad611924b640d0f', + rawAmount: '100000000000000000000', + decimal: 18, + amount: '100', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'BAKE', + ticker: 'BAKE', + address: '0xe02df9e3e622debdd69fb838bb799e3f168902c5', + rawAmount: '2896167082922666', + decimal: 18, + amount: '0.002896167082922666', + logo: 'https://api.rango.exchange/i/dQuv0N', + usdPrice: 0.141, + }, + { + chain: 'BSC', + symbol: 'USDC', + ticker: 'USDC', + address: '0x8ac76a51cc950d9822d68b83fe1ad97b32cd580d', + rawAmount: '15641472731959171181', + decimal: 18, + amount: '15.641472731959171181', + logo: 'https://api.rango.exchange/i/toXKGV', + usdPrice: 1.005, + }, + { + chain: 'BSC', + symbol: 'LTC', + ticker: 'LTC', + address: '0x4338665cbb7b2485a8855a139b75d5e34ab0db94', + rawAmount: '6918750157', + decimal: 18, + amount: '0.000000006918750157', + logo: 'https://api.rango.exchange/i/Rw2jCX', + usdPrice: 65.204, + }, + { + chain: 'BSC', + symbol: 'NEAR', + ticker: 'NEAR', + address: '0x1fa4a73a3f0133f0025378af00236f3abdee5d63', + rawAmount: '508963275751495577', + decimal: 18, + amount: '0.508963275751495577', + logo: 'https://api.rango.exchange/i/kL2qwj', + usdPrice: 1.298, + }, + { + chain: 'BSC', + symbol: 'BTG', + ticker: 'BTG', + address: '0x1385e68e3b5ea66fc50a221f8dcbabbfd3ee282b', + rawAmount: '11000000000', + decimal: 6, + amount: '11000', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'YTS', + ticker: 'YTS', + address: '0x3b4deb27a46e746776a661ecf523c42ed0400d54', + rawAmount: '9000000000000000000000000', + decimal: 18, + amount: '9000000', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'FLOKI', + ticker: 'FLOKI', + address: '0x2b3f34e9d4b127797ce6244ea341a83733ddd6e4', + rawAmount: '62088935293887', + decimal: 9, + amount: '62088.935293887', + logo: 'https://api.rango.exchange/i/UhBFxd', + usdPrice: 1.89e-7, + }, + { + chain: 'BSC', + symbol: 'SXP', + ticker: 'SXP', + address: '0x47bead2563dcbf3bf2c9407fea4dc236faba485a', + rawAmount: '7193114712', + decimal: 18, + amount: '0.000000007193114712', + logo: 'https://api.rango.exchange/i/3njEos', + usdPrice: 0.207, + }, + { + chain: 'BSC', + symbol: 'COSMICMINE', + ticker: 'COSMICMINE', + address: '0xde1e01b3ab6aa67909e41330067be7a46ec16c38', + rawAmount: '300000000000000000', + decimal: 18, + amount: '0.3', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'SPACEPI', + ticker: 'SPACEPI', + address: '0x69b14e8d3cebfdd8196bfe530954a0c226e5008e', + rawAmount: '5500000000000000', + decimal: 9, + amount: '5500000', + logo: 'https://api.rango.exchange/i/01weSc', + usdPrice: 1.02e-9, + }, + { + chain: 'BSC', + symbol: 'ALPACA', + ticker: 'ALPACA', + address: '0x373233a38ae21cf0c4f9de11570e7d5aa6824a1e', + rawAmount: '28102000000000000000000000', + decimal: 18, + amount: '28102000', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'MNEB', + ticker: 'MNEB', + address: '0xd22202d23fe7de9e3dbe11a2a88f42f4cb9507cf', + rawAmount: '15000000000000', + decimal: 8, + amount: '150000', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'DAO', + ticker: 'DAO', + address: '0x037b202ca88d2028d82936d5615ee5088cb9fd78', + rawAmount: '9970000000000000', + decimal: 18, + amount: '0.00997', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'BRISE', + ticker: 'BRISE', + address: '0x8fff93e810a2edaafc326edee51071da9d398e83', + rawAmount: '10', + decimal: 9, + amount: '0.00000001', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: '3WORLDS.IO', + ticker: '3WORLDS.IO', + address: '0xc3238c3b7b8e32588a49c751aed808368e85122d', + rawAmount: '12000000000000', + decimal: 9, + amount: '12000', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'ARKR.ORG', + ticker: 'ARKR.ORG', + address: '0x04645027122c9f152011f128c7085449b27cb6d7', + rawAmount: '800000000000000000000000', + decimal: 18, + amount: '800000', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'WADAX', + ticker: 'WADAX', + address: '0x35122d1fe8001296f61290b8ba42ef597af31fb7', + rawAmount: '1000000000000', + decimal: 6, + amount: '1000000', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'BNBW', + ticker: 'BNBW', + address: '0x5558447b06867ffebd87dd63426d61c868c45904', + rawAmount: '23752199000000000', + decimal: 9, + amount: '23752199', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'QI', + ticker: 'QI', + address: '0x8729438eb15e2c8b576fcc6aecda6a148776c0f5', + rawAmount: '208452535759624275628', + decimal: 18, + amount: '208.452535759624275628', + logo: 'https://api.rango.exchange/i/PwbKO2', + usdPrice: 0.00664, + }, + { + chain: 'BSC', + symbol: 'CAKE', + ticker: 'CAKE', + address: '0x0e09fabb73bd3ade0a17ecc321fd13a19e81ce82', + rawAmount: '132130918185825847', + decimal: 18, + amount: '0.132130918185825847', + logo: 'https://api.rango.exchange/i/UA0myt', + usdPrice: 3.433, + }, + { + chain: 'BSC', + symbol: 'LINKP.IO', + ticker: 'LINKP.IO', + address: '0xd5e3bf9045cfb1e6ded4b35d1b9c34be16d6eec3', + rawAmount: '800000000000000000000000', + decimal: 18, + amount: '800000', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'BSCTOKEN', + ticker: 'BSCTOKEN', + address: '0x569b2cf0b745ef7fad04e8ae226251814b3395f9', + rawAmount: '23752199000000000', + decimal: 9, + amount: '23752199', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'VERSE', + ticker: 'VERSE', + address: '0xbb92b9d18db99c3695bc820bf2c876d4b1527fa5', + rawAmount: '3000000000000000', + decimal: 9, + amount: '3000000', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'VERA', + ticker: 'VERA', + address: '0x0df62d2cd80591798721ddc93001afe868c367ff', + rawAmount: '800000000000000000000000', + decimal: 18, + amount: '800000', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'SQUIDV2', + ticker: 'SQUIDV2', + address: '0xd85842708252c7752f9e503f90561068433d0044', + rawAmount: '1000000000000000000', + decimal: 18, + amount: '1', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'WETH', + ticker: 'WETH', + address: '0x4db5a66e937a9f4473fa95b1caf1d1e1d62e29ea', + rawAmount: '9430724572', + decimal: 18, + amount: '0.000000009430724572', + logo: 'https://api.rango.exchange/i/wNnplE', + usdPrice: 1396.147, + }, + { + chain: 'BSC', + symbol: 'ATOM', + ticker: 'ATOM', + address: '0x725e02c7f9168f45b3699cfb7c262fb6dd355e84', + rawAmount: '99561480', + decimal: 6, + amount: '99.56148', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'FLOKI', + ticker: 'FLOKI', + address: '0xfb5b838b6cfeedc2873ab27866079ac55363d37e', + rawAmount: '62088935293887', + decimal: 9, + amount: '62088.935293887', + logo: 'https://api.rango.exchange/i/fIrbfa', + usdPrice: 0.00000913, + }, + { + chain: 'BSC', + symbol: 'AZSWAP.IO', + ticker: 'AZSWAP.IO', + address: '0xfd4c532a8c17bd326c2dc63b88d49306ce27f80b', + rawAmount: '18000000000000', + decimal: 9, + amount: '18000', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'TU7.ORG', + ticker: 'TU7.ORG', + address: '0x442b656f5a5c3dd09790951810c5a15ea5295b51', + rawAmount: '7127850000000000', + decimal: 9, + amount: '7127850', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'FLUX', + ticker: 'FLUX', + address: '0xb16600c510b0f323dee2cb212924d90e58864421', + rawAmount: '950000000000000000000000', + decimal: 18, + amount: '950000', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'XRP', + ticker: 'XRP', + address: '0x1d2f0da169ceb9fc7b3144628db156f3f6c60dbe', + rawAmount: '5688021754', + decimal: 18, + amount: '0.000000005688021754', + logo: 'https://api.rango.exchange/i/zTYnq2', + usdPrice: 0.34, + }, + { + chain: 'BSC', + symbol: 'BITTT.IO', + ticker: 'BITTT.IO', + address: '0x9603a3d3dcccf5ef1a2060a3da796ac084cc66eb', + rawAmount: '268551000000000000000000', + decimal: 18, + amount: '268551', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'AXLUSDC', + ticker: 'AXLUSDC', + address: '0x4268b8f0b87b6eae5d897996e6b845ddbd99adf3', + rawAmount: '5978049', + decimal: 6, + amount: '5.978049', + logo: 'https://api.rango.exchange/tokens/COSMOS/AXLUSDC.png', + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'SDJT', + ticker: 'SDJT', + address: '0xbb368656efa67361b0063fe0f11cb08bd460246d', + rawAmount: '100000000', + decimal: 9, + amount: '0.1', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'ONE', + ticker: 'ONE', + address: '0x03ff0ff224f904be3118461335064bb48df47938', + rawAmount: '4789152388', + decimal: 18, + amount: '0.000000004789152388', + logo: 'https://api.rango.exchange/i/5MOMsg', + usdPrice: 0.0115, + }, + { + chain: 'BSC', + symbol: 'STI', + ticker: 'STI', + address: '0x4f5f7a7dca8ba0a7983381d23dfc5eaf4be9c79a', + rawAmount: '1000', + decimal: 10, + amount: '0.0000001', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'APE', + ticker: 'APE', + address: '0xa1b99485d58d70d86e455ab8823492090c3f43c0', + rawAmount: '350000000000000000000', + decimal: 18, + amount: '350', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'COOK', + ticker: 'COOK', + address: '0x965b0df5bda0e7a0649324d78f03d5f7f2de086a', + rawAmount: '35733206194802111275189', + decimal: 18, + amount: '35733.206194802111275189', + logo: 'https://api.rango.exchange/i/owq1WS', + usdPrice: 0.000247, + }, + { + chain: 'BSC', + symbol: 'FUSE', + ticker: 'FUSE', + address: '0x5857c96dae9cf8511b08cb07f85753c472d36ea3', + rawAmount: '102000000000000000000', + decimal: 18, + amount: '102', + logo: 'https://api.rango.exchange/i/3hWqus', + usdPrice: 0.0603, + }, + { + chain: 'BSC', + symbol: 'CGB', + ticker: 'CGB', + address: '0x7e6202903275772044198d07b8a536cc064f8480', + rawAmount: '211000000', + decimal: 6, + amount: '211', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'DEF8.IO', + ticker: 'DEF8.IO', + address: '0x556798dd55db12562a6950ea8339a273539b0495', + rawAmount: '82445000000000000000000', + decimal: 18, + amount: '82445', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'WMATIC', + ticker: 'WMATIC', + address: '0xc836d8dc361e44dbe64c4862d55ba041f88ddd39', + rawAmount: '1887651939', + decimal: 18, + amount: '0.000000001887651939', + logo: 'https://api.rango.exchange/i/QpOgNr', + usdPrice: 0.791, + }, + { + chain: 'BSC', + symbol: 'BSTAKE.NET', + ticker: 'BSTAKE.NET', + address: '0x1f040f15ab15b7e0dfac935873fadbe43d015535', + rawAmount: '480000000000000000000000', + decimal: 18, + amount: '480000', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'XCH5.IO', + ticker: 'XCH5.IO', + address: '0xb3ec4e17c1c0079d977354875ab924c088325306', + rawAmount: '821112000000000', + decimal: 9, + amount: '821112', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'FS', + ticker: 'FS', + address: '0xe3a41e4dacc892ecaedfa009be5baa2d3ab4844d', + rawAmount: '1003947318555099196', + decimal: 18, + amount: '1.003947318555099196', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'BSC-COIN', + ticker: 'BSC-COIN', + address: '0xe3e1147acd39687a25ca7716227c604500f5c31a', + rawAmount: '5000000000000', + decimal: 6, + amount: '5000000', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'APEFESTPOAP.COM', + ticker: 'APEFESTPOAP.COM', + address: '0x57dac6482784a0f093483e6313804812fa177437', + rawAmount: '5555000000000000000000', + decimal: 18, + amount: '5555', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'SAFEMOON-DIVIDEND.COM', + ticker: 'SAFEMOON-DIVIDEND.COM', + address: '0xdbe3e700ab26cbf3523d850b5d892fd17e0ce343', + rawAmount: '31820000000000000000000', + decimal: 18, + amount: '31820', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'AXAX.IO', + ticker: 'AXAX.IO', + address: '0x58b5c4697dc70f3d889225260944cdd9c270c132', + rawAmount: '77000000000000', + decimal: 9, + amount: '77000', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'RRDAO.NET', + ticker: 'RRDAO.NET', + address: '0xa47b34ff31e22ef03f6054af19542bcde260cdc7', + rawAmount: '738097000000000000000000', + decimal: 18, + amount: '738097', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'ETP', + ticker: 'ETP', + address: '0x89679307c3d2e4e289da2ccd4d3c44ff39292189', + rawAmount: '100000000000000', + decimal: 18, + amount: '0.0001', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'DOT', + ticker: 'DOT', + address: '0x7083609fce4d1d8dc0c979aab8c869ea2c873402', + rawAmount: '7180274458', + decimal: 18, + amount: '0.000000007180274458', + logo: 'https://api.rango.exchange/i/suQRJx', + usdPrice: 4.528, + }, + { + chain: 'BSC', + symbol: 'AGMC.IO', + ticker: 'AGMC.IO', + address: '0xef27b9cb67aa93ec3494a60f1ea9380e86175b26', + rawAmount: '800000000000000000000000', + decimal: 18, + amount: '800000', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'RDRIP', + ticker: 'RDRIP', + address: '0xa02a0b2d67d4fa48677a79cadc483e114049916d', + rawAmount: '40214587120000', + decimal: 6, + amount: '40214587.12', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'BUSD', + ticker: 'BUSD', + address: '0xe9e7cea3dedca5984780bafc599bd69add087d56', + rawAmount: '2925825323281948117', + decimal: 18, + amount: '2.925825323281948117', + logo: 'https://api.rango.exchange/i/tY13sD', + usdPrice: 1.001, + }, + { + chain: 'BSC', + symbol: 'MKS', + ticker: 'MKS', + address: '0x64f2c2aa04755507a2ecd22ceb8c475b7a750a3a', + rawAmount: '6500000000000000000000000', + decimal: 18, + amount: '6500000', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'BITMARTEX.COM', + ticker: 'BITMARTEX.COM', + address: '0xdac0bb03158048b70abcfeb3be2607b625526f20', + rawAmount: '400000000000000000000', + decimal: 18, + amount: '400', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'APT', + ticker: 'APT', + address: '0xec811fbcd12f67874891cdbbbc95d9f73db3fbb0', + rawAmount: '40000000', + decimal: 6, + amount: '40', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'MELLO', + ticker: 'MELLO', + address: '0x0198be93b7cae38da7e2fd966946412cc36447bf', + rawAmount: '17777000000000000000000', + decimal: 18, + amount: '17777', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'ICE', + ticker: 'ICE', + address: '0xf16e81dce15b08f326220742020379b855b87df9', + rawAmount: '3071447531', + decimal: 18, + amount: '0.000000003071447531', + logo: 'https://api.rango.exchange/i/my1npH', + usdPrice: 0.121, + }, + { + chain: 'BSC', + symbol: 'ADDBNB.COM', + ticker: 'ADDBNB.COM', + address: '0x617bf230a6886accec5952385eed8bc85d1a09b2', + rawAmount: '29998899999900', + decimal: 8, + amount: '299988.999999', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'POWNFT.NET', + ticker: 'POWNFT.NET', + address: '0x893c25c46bfaa9b66cd557837d32af3fe264a07b', + rawAmount: '96816550000000000000000', + decimal: 18, + amount: '96816.55', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'MINIDOGE', + ticker: 'MINIDOGE', + address: '0x9b1ba20ae9335197c72be094d4fa300d4ef95351', + rawAmount: '500000000000000000000000000000', + decimal: 18, + amount: '500000000000', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'FIFA', + ticker: 'FIFA', + address: '0xe19417837d8e61f17dfae2e6a11b1e4810dae2a5', + rawAmount: '99000000000000', + decimal: 18, + amount: '0.000099', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'MDT', + ticker: 'MDT', + address: '0x668db7aa38eac6b40c9d13dbe61361dc4c4611d1', + rawAmount: '4965562423', + decimal: 18, + amount: '0.000000004965562423', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'ZIL', + ticker: 'ZIL', + address: '0xb86abcb37c3a4b64f74f59301aff131a1becc787', + rawAmount: '5995', + decimal: 12, + amount: '0.000000005995', + logo: 'https://api.rango.exchange/i/aiPfMq', + usdPrice: 0.0176, + }, + { + chain: 'BSC', + symbol: ' "995$ VISIT USDTREWARD.COM TO CLAIM', + ticker: ' "995$ VISIT USDTREWARD.COM TO CLAIM', + address: '0x67c4a6da86da4f45030904b143d6b00d25e366e9', + rawAmount: '6', + decimal: 0, + amount: '6', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'ADA', + ticker: 'ADA', + address: '0x3ee2200efb3400fabb9aacf31297cbdd1d435d47', + rawAmount: '6081419213', + decimal: 18, + amount: '0.000000006081419213', + logo: 'https://api.rango.exchange/i/ne4pEv', + usdPrice: 0.25, + }, + { + chain: 'BSC', + symbol: 'ZEPE.IO', + ticker: 'ZEPE.IO', + address: '0xb0557906c617f0048a700758606f64b33d0c41a6', + rawAmount: '750000000000000000000000', + decimal: 18, + amount: '750000', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'MN', + ticker: 'MN', + address: '0x1a09f518a8293d519de20700076ad9cd2125d224', + rawAmount: '454000000000000', + decimal: 18, + amount: '0.000454', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'EVER', + ticker: 'EVER', + address: '0x5190b01965b6e3d786706fd4a999978626c19880', + rawAmount: '800000000000000000000000', + decimal: 18, + amount: '800000', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'SGC', + ticker: 'SGC', + address: '0x7aa3a53360541283ffa9192972223b47a902dc0c', + rawAmount: '1450000000000', + decimal: 6, + amount: '1450000', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'BCH', + ticker: 'BCH', + address: '0x8ff795a6f4d97e7887c79bea79aba5cc76444adf', + rawAmount: '208175286', + decimal: 18, + amount: '0.000000000208175286', + logo: 'https://api.rango.exchange/i/TPdCZV', + usdPrice: 101.758, + }, + { + chain: 'BSC', + symbol: 'KK8.IO', + ticker: 'KK8.IO', + address: '0x2ba6204c23fbd5698ed90abc911de263e5f41266', + rawAmount: '166574000000000000000000', + decimal: 18, + amount: '166574', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'BCNFT', + ticker: 'BCNFT', + address: '0xe5677103191711bad85cf99e0dfc9b35449b790b', + rawAmount: '99800000000000000000', + decimal: 18, + amount: '99.8', + logo: null, + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'MNFLX', + ticker: 'MNFLX', + address: '0xa04f060077d90fe2647b61e4da4ad1f97d6649dc', + rawAmount: '18298000000000000', + decimal: 18, + amount: '0.018298', + logo: 'https://api.rango.exchange/i/66c2BP', + usdPrice: null, + }, + { + chain: 'BSC', + symbol: 'FIL', + ticker: 'FIL', + address: '0x0d8ce2a99bb6e3b7db580ed848240e4a0f9ae153', + rawAmount: '166801647873165921', + decimal: 18, + amount: '0.166801647873165921', + logo: 'https://api.rango.exchange/i/diq2au', + usdPrice: 2.925, + }, + { + chain: 'BSC', + symbol: 'DAI', + ticker: 'DAI', + address: '0x1af3f329e8be154074d8769d1ffa4ee058b1dbc3', + rawAmount: '7308178549281467169', + decimal: 18, + amount: '7.308178549281467169', + logo: 'https://api.rango.exchange/i/EcBuF8', + usdPrice: 1.002, + }, + { + chain: 'BSC', + symbol: 'BNB', + ticker: 'BNB', + address: null, + rawAmount: '64638855809280692', + decimal: 18, + amount: '0.064638855809280692', + logo: 'https://api.rango.exchange/i/Y3v1KW', + usdPrice: null, + }, + ], + loading: false, + walletType: 'metamask', + isConnected: false, + error: false, + explorerUrl: + 'https://bscscan.com/address/0x2702d89c1c8658b49c45dd460deebcc45faec03c', + }, + ], + }, + { + name: 'POLYGON', + accounts: [ + { + address: '0x2702d89c1c8658b49c45dd460deebcc45faec03c', + balances: [], + loading: false, + walletType: 'metamask', + isConnected: true, + error: true, + explorerUrl: + 'https://polygonscan.com/address/0x2702d89c1c8658b49c45dd460deebcc45faec03c', + }, + ], + }, + { + name: 'ETH', + accounts: [ + { + address: '0x2702d89c1c8658b49c45dd460deebcc45faec03c', + balances: [ + { + chain: 'ETH', + symbol: 'BAT', + ticker: 'BAT', + address: '0x0d8775f648430679a709e98d2b0cb6250d2887ef', + rawAmount: '4000000000000000000', + decimal: 18, + amount: '4', + logo: 'https://api.rango.exchange/i/fRlt4J', + usdPrice: 0.187, + }, + { + chain: 'ETH', + symbol: 'WBTC', + ticker: 'WBTC', + address: '0x2260fac5e5542a773aa44fbcfedf7c193bc2c599', + rawAmount: '4777', + decimal: 8, + amount: '0.00004777', + logo: 'https://api.rango.exchange/i/LZSo9D', + usdPrice: 16748.345, + }, + { + chain: 'ETH', + symbol: 'BUSD', + ticker: 'BUSD', + address: '0x4fabb145d64652a948d72533023f6e7a623c7c53', + rawAmount: '44533649981450616971', + decimal: 18, + amount: '44.533649981450616971', + logo: 'https://api.rango.exchange/i/sQLw6p', + usdPrice: 0.996, + }, + { + chain: 'ETH', + symbol: 'USDC', + ticker: 'USDC', + address: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', + rawAmount: '68026943', + decimal: 6, + amount: '68.026943', + logo: 'https://api.rango.exchange/i/ns0AMf', + usdPrice: 0.998, + }, + { + chain: 'ETH', + symbol: 'WETH', + ticker: 'WETH', + address: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', + rawAmount: '69476760000000000', + decimal: 18, + amount: '0.06947676', + logo: 'https://api.rango.exchange/i/yZ9N1N', + usdPrice: 1207.06, + }, + { + chain: 'ETH', + symbol: 'USDT', + ticker: 'USDT', + address: '0xdac17f958d2ee523a2206206994597c13d831ec7', + rawAmount: '458820363', + decimal: 6, + amount: '458.820363', + logo: 'https://api.rango.exchange/i/aR1yFx', + usdPrice: 0.999, + }, + { + chain: 'ETH', + symbol: 'RENBTC', + ticker: 'RENBTC', + address: '0xeb4c2781e4eba804ce9a9803c67d0893436bb27d', + rawAmount: '92825', + decimal: 8, + amount: '0.00092825', + logo: 'https://api.rango.exchange/i/kwXCDn', + usdPrice: 17122.537, + }, + { + chain: 'ETH', + symbol: 'ETH', + ticker: 'ETH', + address: null, + rawAmount: '216333389734077345', + decimal: 18, + amount: '0.216333389734077345', + logo: 'https://api.rango.exchange/i/MTyH5i', + usdPrice: null, + }, + { + chain: 'ETH', + symbol: 'MATIC', + ticker: 'MATIC', + address: '0x7d1afa7b718fb893db30a3abc0cfc608aacfebb0', + rawAmount: '31663446408882142552', + decimal: 18, + amount: '31.663446408882142552', + logo: 'https://api.rango.exchange/i/xt6ATN', + usdPrice: 0.79, + }, + { + chain: 'ETH', + symbol: 'DAI', + ticker: 'DAI', + address: '0x6b175474e89094c44da98b954eedeac495271d0f', + rawAmount: '1987151466068153485', + decimal: 18, + amount: '1.987151466068153485', + logo: 'https://api.rango.exchange/i/yJvJre', + usdPrice: 0.999, + }, + { + chain: 'ETH', + symbol: 'TUSD', + ticker: 'TUSD', + address: '0x0000000000085d4780b73119b644ae5ecd22b376', + rawAmount: '16993200000000000000', + decimal: 18, + amount: '16.9932', + logo: 'https://api.rango.exchange/i/af3mkt', + usdPrice: 0.994, + }, + { + chain: 'ETH', + symbol: 'SUSHI', + ticker: 'SUSHI', + address: '0x6b3595068778dd592e39a122f4f5a5cf09c90fe2', + rawAmount: '3943357318101926305', + decimal: 18, + amount: '3.943357318101926305', + logo: 'https://api.rango.exchange/i/2GXZEZ', + usdPrice: 0.951, + }, + { + chain: 'ETH', + symbol: 'AAVE', + ticker: 'AAVE', + address: '0x7fc66500c84a76ad7e9c93437bfc5ac33e2ddae9', + rawAmount: '25162269244382386', + decimal: 18, + amount: '0.025162269244382386', + logo: 'https://api.rango.exchange/i/ZizYhl', + usdPrice: 55.363, + }, + { + chain: 'ETH', + symbol: 'PERP', + ticker: 'PERP', + address: '0xbc396689893d065f41bc2c6ecbee5e0085233447', + rawAmount: '6774928920', + decimal: 18, + amount: '0.00000000677492892', + logo: 'https://api.rango.exchange/i/VrMbR6', + usdPrice: 0.39, + }, + { + chain: 'ETH', + symbol: 'STETH', + ticker: 'STETH', + address: '0xae7ab96520de3a18e5e111b5eaab095312d7fe84', + rawAmount: '39341623', + decimal: 18, + amount: '0.000000000039341623', + logo: null, + usdPrice: null, + }, + { + chain: 'ETH', + symbol: 'SHIB', + ticker: 'SHIB', + address: '0x95ad61b0a150d79219dcf64e1e6cc01f0b64c4ce', + rawAmount: '414477447646226736858871', + decimal: 18, + amount: '414477.447646226736858871', + logo: 'https://api.rango.exchange/i/cbCyuY', + usdPrice: 0.00000824, + }, + { + chain: 'ETH', + symbol: 'EROWAN', + ticker: 'EROWAN', + address: '0x07bac35846e5ed502aa91adf6a9e7aa210f2dcbe', + rawAmount: '17095432307032160581', + decimal: 18, + amount: '17.095432307032160581', + logo: 'https://api.rango.exchange/i/X97ibo', + usdPrice: 0.000317, + }, + { + chain: 'ETH', + symbol: 'UST', + ticker: 'UST', + address: '0xa693b19d2931d498c5b318df961919bb4aee87a5', + rawAmount: '1000000', + decimal: 6, + amount: '1', + logo: 'https://api.rango.exchange/i/IvLUkp', + usdPrice: 0.02, + }, + { + chain: 'ETH', + symbol: 'XDATA', + ticker: 'XDATA', + address: '0x0cf0ee63788a0849fe5297f3407f701e122cc023', + rawAmount: '230414265395638755692', + decimal: 18, + amount: '230.414265395638755692', + logo: null, + usdPrice: null, + }, + { + chain: 'ETH', + symbol: 'bETH', + ticker: 'bETH', + address: '0x707f9118e33a9b8998bea41dd0d46f38bb963fc8', + rawAmount: '184000000000000', + decimal: 18, + amount: '0.000184', + logo: 'https://api.rango.exchange/tokens/TERRA/BETH.png', + usdPrice: null, + }, + { + chain: 'ETH', + symbol: 'AKSWAP.IO', + ticker: 'AKSWAP.IO', + address: '0x82dfdb2ec1aa6003ed4acba663403d7c2127ff67', + rawAmount: '250000000000000000000000', + decimal: 18, + amount: '250000', + logo: null, + usdPrice: null, + }, + { + chain: 'ETH', + symbol: 'WBNB', + ticker: 'WBNB', + address: '0x418d75f65a02b3d53b2418fb8e1fe493759c7605', + rawAmount: '10000000000000000', + decimal: 18, + amount: '0.01', + logo: 'https://api.rango.exchange/i/Xzflek', + usdPrice: 248.36, + }, + { + chain: 'ETH', + symbol: 'RANGO', + ticker: 'RANGO', + address: '0x5846d81d8e4a3b9cc53ce1dcdc12b6619ae3507d', + rawAmount: '40000000', + decimal: 6, + amount: '40', + logo: null, + usdPrice: null, + }, + { + chain: 'ETH', + symbol: 'LUNAV2.IO (LUNA TOKEN)', + ticker: 'LUNAV2.IO (LUNA TOKEN)', + address: '0xaf0b2fbedd5d1fda457580fb3dabad1f5c8bbc36', + rawAmount: '258542000000000000000000', + decimal: 18, + amount: '258542', + logo: null, + usdPrice: null, + }, + { + chain: 'ETH', + symbol: 'LUNA 2.0 (LUNAV2.IO)', + ticker: 'LUNA 2.0 (LUNAV2.IO)', + address: '0x471c3a7f132bc94938516cb2bf6f02c7521d2797', + rawAmount: '250457000000000000000000', + decimal: 18, + amount: '250457', + logo: null, + usdPrice: null, + }, + { + chain: 'ETH', + symbol: 'LIDOLP.COM', + ticker: 'LIDOLP.COM', + address: '0x0332d00ae8e9baa609edc48844f48fdd94ca9547', + rawAmount: '6000', + decimal: 0, + amount: '6000', + logo: null, + usdPrice: null, + }, + { + chain: 'ETH', + symbol: 'HBOT', + ticker: 'HBOT', + address: '0xe5097d9baeafb89f9bcb78c9290d545db5f9e9cb', + rawAmount: '155042558533708582423', + decimal: 18, + amount: '155.042558533708582423', + logo: null, + usdPrice: null, + }, + { + chain: 'ETH', + symbol: '1650811245.077F', + ticker: '1650811245.077F', + address: '0xba8d75baccc4d5c4bd814fde69267213052ea663', + rawAmount: '1000000000000000000', + decimal: 18, + amount: '1', + logo: null, + usdPrice: null, + }, + { + chain: 'ETH', + symbol: 'PWING', + ticker: 'PWING', + address: '0xdb0f18081b505a7de20b18ac41856bcb4ba86a1a', + rawAmount: '498133925', + decimal: 9, + amount: '0.498133925', + logo: 'https://api.rango.exchange/i/Ba5IQF', + usdPrice: null, + }, + { + chain: 'ETH', + symbol: 'VISIT [AAVE-SR.XYZ] AND CLAIM SPECIAL REWARDS', + ticker: 'VISIT [AAVE-SR.XYZ] AND CLAIM SPECIAL REWARDS', + address: '0xd1e61fcb6e26d4deffa77f21cc5b581c3afa95e2', + rawAmount: '920816400', + decimal: 6, + amount: '920.8164', + logo: null, + usdPrice: null, + }, + { + chain: 'ETH', + symbol: 'VISIT [AUSD.SHOP] AND SUPPLY OR BORROW USDT', + ticker: 'VISIT [AUSD.SHOP] AND SUPPLY OR BORROW USDT', + address: '0x38715ab4b9d4e00890773d7338d94778b0dfc0a8', + rawAmount: '2294101815', + decimal: 6, + amount: '2294.101815', + logo: null, + usdPrice: null, + }, + { + chain: 'ETH', + symbol: '[LIDOSR.XYZ] CLAIM YOUR SPECIAL REWARDS.', + ticker: '[LIDOSR.XYZ] CLAIM YOUR SPECIAL REWARDS.', + address: '0x511b5f248269c0b90b60e33ef9df744048c84a83', + rawAmount: '149260000', + decimal: 6, + amount: '149.26', + logo: null, + usdPrice: null, + }, + { + chain: 'ETH', + symbol: 'ENJOY [HTTPS://SPINGAME.ME]', + ticker: 'ENJOY [HTTPS://SPINGAME.ME]', + address: '0xcdc94877e4164d2e915fc5e8310155d661a995f1', + rawAmount: '2294101815', + decimal: 6, + amount: '2294.101815', + logo: null, + usdPrice: null, + }, + { + chain: 'ETH', + symbol: 'WMATIC', + ticker: 'WMATIC', + address: '0x7c9f4c87d911613fe9ca58b579f737911aad2d43', + rawAmount: '100000000000000000', + decimal: 18, + amount: '0.1', + logo: 'https://api.rango.exchange/i/QpOgNr', + usdPrice: null, + }, + { + chain: 'ETH', + symbol: '$ VISIT NFTGIFTX.COM TO CLAIM', + ticker: '$ VISIT NFTGIFTX.COM TO CLAIM', + address: '0x0d3716e3e411af431a6e87e715d4b05bbcd67000', + rawAmount: '4000', + decimal: 0, + amount: '4000', + logo: null, + usdPrice: null, + }, + ], + loading: false, + walletType: 'metamask', + isConnected: false, + error: false, + explorerUrl: + 'https://etherscan.io/address/0x2702d89c1c8658b49c45dd460deebcc45faec03c', + }, + ], + }, + { + name: 'AVAX_CCHAIN', + accounts: [ + { + address: '0x2702d89c1c8658b49c45dd460deebcc45faec03c', + balances: [ + { + chain: 'AVAX_CCHAIN', + symbol: 'BNB', + ticker: 'BNB', + address: '0x264c1383ea520f73dd837f915ef3a732e204a493', + rawAmount: '7107381667', + decimal: 18, + amount: '0.000000007107381667', + logo: 'https://api.rango.exchange/i/BtRUoA', + usdPrice: 247.386, + }, + { + chain: 'AVAX_CCHAIN', + symbol: 'TUSD', + ticker: 'TUSD', + address: '0x1c20e891bab6b1727d14da358fae2984ed9b59eb', + rawAmount: '2819919094', + decimal: 18, + amount: '0.000000002819919094', + logo: 'https://api.rango.exchange/i/UBghmk', + usdPrice: 1, + }, + { + chain: 'AVAX_CCHAIN', + symbol: 'SOL', + ticker: 'SOL', + address: '0xfe6b19286885a4f7f55adad09c3cd1f906d2478f', + rawAmount: '110', + decimal: 9, + amount: '0.00000011', + logo: 'https://api.rango.exchange/i/YhJ1nK', + usdPrice: null, + }, + { + chain: 'AVAX_CCHAIN', + symbol: 'OPENDAO.IS', + ticker: 'OPENDAO.IS', + address: '0xc03f94e49c944c4f118c3f97af7cce8f01df9430', + rawAmount: '10000000000000000000', + decimal: 18, + amount: '10', + logo: null, + usdPrice: null, + }, + { + chain: 'AVAX_CCHAIN', + symbol: 'IMX.A', + ticker: 'IMX.A', + address: '0xea6887e4a9cda1b77e70129e5fba830cdb5cddef', + rawAmount: '7119477388984802736', + decimal: 18, + amount: '7.119477388984802736', + logo: 'https://api.rango.exchange/i/qhi6I3', + usdPrice: 0.000139, + }, + { + chain: 'AVAX_CCHAIN', + symbol: 'AVAXCLASSIC.COM', + ticker: 'AVAXCLASSIC.COM', + address: '0x4c4f4f4122c3a80d30c1ad6ad2828953015bd52c', + rawAmount: '74041750000000000000', + decimal: 18, + amount: '74.04175', + logo: null, + usdPrice: null, + }, + { + chain: 'AVAX_CCHAIN', + symbol: 'ORBS', + ticker: 'ORBS', + address: '0x340fe1d898eccaad394e2ba0fc1f93d27c7b717a', + rawAmount: '7336115152', + decimal: 18, + amount: '0.000000007336115152', + logo: 'https://api.rango.exchange/i/hktmCG', + usdPrice: 0.0228, + }, + { + chain: 'AVAX_CCHAIN', + symbol: 'PENDLE', + ticker: 'PENDLE', + address: '0xfb98b335551a418cd0737375a2ea0ded62ea213b', + rawAmount: '43168168325557885527', + decimal: 18, + amount: '43.168168325557885527', + logo: 'https://api.rango.exchange/i/p4dkte', + usdPrice: 0.046, + }, + { + chain: 'AVAX_CCHAIN', + symbol: 'WMATIC', + ticker: 'WMATIC', + address: '0xf2f13f0b7008ab2fa4a2418f4ccc3684e49d20eb', + rawAmount: '45499998000000000000', + decimal: 18, + amount: '45.499998', + logo: 'https://api.rango.exchange/i/QpOgNr', + usdPrice: null, + }, + { + chain: 'AVAX_CCHAIN', + symbol: 'avaxUSDC', + ticker: 'avaxUSDC', + address: '0xb97ef9ef8734c71904d8002f8b6bc66dd9c48a6e', + rawAmount: '15844946', + decimal: 6, + amount: '15.844946', + logo: 'https://api.rango.exchange/i/FHj2LZ', + usdPrice: null, + }, + { + chain: 'AVAX_CCHAIN', + symbol: 'SPELL', + ticker: 'SPELL', + address: '0xce1bffbd5374dac86a2893119683f4911a2f7814', + rawAmount: '144687727088072773130', + decimal: 18, + amount: '144.68772708807277313', + logo: 'https://api.rango.exchange/i/zW5ZK2', + usdPrice: 0.000535, + }, + { + chain: 'AVAX_CCHAIN', + symbol: 'WBNB', + ticker: 'WBNB', + address: '0x442f7f22b1ee2c842beaff52880d4573e9201158', + rawAmount: '57933890000000000', + decimal: 18, + amount: '0.05793389', + logo: 'https://api.rango.exchange/i/Xzflek', + usdPrice: null, + }, + { + chain: 'AVAX_CCHAIN', + symbol: 'GMX', + ticker: 'GMX', + address: '0x62edc0692bd897d2295872a9ffcac5425011c661', + rawAmount: '379543333707025854', + decimal: 18, + amount: '0.379543333707025854', + logo: 'https://api.rango.exchange/i/0aQTDd', + usdPrice: null, + }, + { + chain: 'AVAX_CCHAIN', + symbol: 'JOE', + ticker: 'JOE', + address: '0x6e84a6216ea6dacc71ee8e6b0a5b7322eebc0fdd', + rawAmount: '35980183723492368253', + decimal: 18, + amount: '35.980183723492368253', + logo: 'https://api.rango.exchange/i/Vw0Fv2', + usdPrice: 0.141, + }, + { + chain: 'AVAX_CCHAIN', + symbol: 'WETH.E', + ticker: 'WETH.E', + address: '0x49d5c2bdffac6ce2bfdb6640f4f80f226bc10bab', + rawAmount: '17684493183273648', + decimal: 18, + amount: '0.017684493183273648', + logo: 'https://api.rango.exchange/i/j9xgdC', + usdPrice: 1210.2, + }, + { + chain: 'AVAX_CCHAIN', + symbol: 'UST', + ticker: 'UST', + address: '0xb599c3590f42f8f995ecfa0f85d2980b76862fc1', + rawAmount: '3993', + decimal: 6, + amount: '0.003993', + logo: 'https://api.rango.exchange/i/0lk6id', + usdPrice: 0.02, + }, + { + chain: 'AVAX_CCHAIN', + symbol: 'USDT', + ticker: 'USDT', + address: '0xde3a24028580884448a5397872046a019649b084', + rawAmount: '35748023', + decimal: 6, + amount: '35.748023', + logo: null, + usdPrice: null, + }, + { + chain: 'AVAX_CCHAIN', + symbol: '24DROP.NET', + ticker: '24DROP.NET', + address: '0x2be494c06316c0d7371250419a9c659a0752ecb3', + rawAmount: '200000000000', + decimal: 8, + amount: '2000', + logo: null, + usdPrice: null, + }, + { + chain: 'AVAX_CCHAIN', + symbol: 'WETH', + ticker: 'WETH', + address: '0x8b82a291f83ca07af22120aba21632088fc92931', + rawAmount: '5200000000000000', + decimal: 18, + amount: '0.0052', + logo: 'https://api.rango.exchange/i/wNnplE', + usdPrice: null, + }, + { + chain: 'AVAX_CCHAIN', + symbol: '0006648936.E9CB', + ticker: '0006648936.E9CB', + address: '0x38dcf0532699b880e6a125f7d918380524cd60a6', + rawAmount: '10000000000000000000', + decimal: 18, + amount: '10', + logo: null, + usdPrice: null, + }, + { + chain: 'AVAX_CCHAIN', + symbol: '$ FREE CLAIM AND PLAY', + ticker: '$ FREE CLAIM AND PLAY', + address: '0xd23345e0e6340616b1cf7200762d0289547ccf87', + rawAmount: '50000000000', + decimal: 8, + amount: '500', + logo: null, + usdPrice: null, + }, + { + chain: 'AVAX_CCHAIN', + symbol: 'AMPL', + ticker: 'AMPL', + address: '0x027dbca046ca156de9622cd1e2d907d375e53aa7', + rawAmount: '8302538186', + decimal: 9, + amount: '8.302538186', + logo: 'https://api.rango.exchange/i/AiXtEj', + usdPrice: 1.078, + }, + { + chain: 'AVAX_CCHAIN', + symbol: 'USDT', + ticker: 'USDT', + address: '0x9702230a8ea53601f5cd2dc00fdbc13d4df4a8c7', + rawAmount: '35280647', + decimal: 6, + amount: '35.280647', + logo: 'https://api.rango.exchange/i/9e1hH8', + usdPrice: 1.005, + }, + { + chain: 'AVAX_CCHAIN', + symbol: 'MNEAV', + ticker: 'MNEAV', + address: '0xf9d922c055a3f1759299467dafafdf43be844f7a', + rawAmount: '30000000000000', + decimal: 8, + amount: '300000', + logo: null, + usdPrice: null, + }, + { + chain: 'AVAX_CCHAIN', + symbol: 'USDC.E', + ticker: 'USDC.E', + address: '0xa7d7079b0fead91f3e65f86e8915cb59c1a4c664', + rawAmount: '92749613', + decimal: 6, + amount: '92.749613', + logo: 'https://api.rango.exchange/i/j9eYAa', + usdPrice: 1, + }, + { + chain: 'AVAX_CCHAIN', + symbol: 'BLIZZ', + ticker: 'BLIZZ', + address: '0xb147656604217a03fe2c73c4838770df8d9d21b8', + rawAmount: '135470487277154696313', + decimal: 18, + amount: '135.470487277154696313', + logo: null, + usdPrice: null, + }, + { + chain: 'AVAX_CCHAIN', + symbol: 'USDT', + ticker: 'USDT', + address: '0xc7198437980c041c805a1edcba50c1ce5db95118', + rawAmount: '36943578', + decimal: 6, + amount: '36.943578', + logo: 'https://api.rango.exchange/i/niIihm', + usdPrice: null, + }, + { + chain: 'AVAX_CCHAIN', + symbol: 'MIM', + ticker: 'MIM', + address: '0x130966628846bfd36ff31a822705796e8cb8c18d', + rawAmount: '13661627814282704200', + decimal: 18, + amount: '13.6616278142827042', + logo: 'https://api.rango.exchange/i/RmsZZl', + usdPrice: 0.998, + }, + { + chain: 'AVAX_CCHAIN', + symbol: 'WAVAX', + ticker: 'WAVAX', + address: '0xb31f66aa3c1e785363f0875a1b74e27b85fd66c7', + rawAmount: '553221840010000000', + decimal: 18, + amount: '0.55322184001', + logo: 'https://api.rango.exchange/i/9bwFaG', + usdPrice: 11.97, + }, + { + chain: 'AVAX_CCHAIN', + symbol: 'AVAX', + ticker: 'AVAX', + address: null, + rawAmount: '3293457782165450159', + decimal: 18, + amount: '3.293457782165450159', + logo: 'https://api.rango.exchange/i/kX4edQ', + usdPrice: 11.77, + }, + ], + loading: false, + walletType: 'metamask', + isConnected: false, + error: false, + explorerUrl: + 'https://snowtrace.io/address/0x2702d89c1c8658b49c45dd460deebcc45faec03c', + }, + ], + }, + { + name: 'ARBITRUM', + accounts: [ + { + address: '0x2702d89c1c8658b49c45dd460deebcc45faec03c', + balances: [ + { + chain: 'ARBITRUM', + symbol: 'JONES', + ticker: 'JONES', + address: '0x10393c20975cf177a3513071bc110f7962cd67da', + rawAmount: '1933131668197791405', + decimal: 18, + amount: '1.933131668197791405', + logo: 'https://api.rango.exchange/i/FUexNn', + usdPrice: null, + }, + { + chain: 'ARBITRUM', + symbol: 'DAI', + ticker: 'DAI', + address: '0xda10009cbd5d07dd0cecc66161fc93d7c9000da1', + rawAmount: '19526880162738340394', + decimal: 18, + amount: '19.526880162738340394', + logo: 'https://api.rango.exchange/i/yJvJre', + usdPrice: 1, + }, + { + chain: 'ARBITRUM', + symbol: 'MAGIC', + ticker: 'MAGIC', + address: '0x539bde0d7dbd336b79148aa742883198bbf60342', + rawAmount: '9059590242', + decimal: 18, + amount: '0.000000009059590242', + logo: 'https://api.rango.exchange/i/tazAGH', + usdPrice: null, + }, + { + chain: 'ARBITRUM', + symbol: 'UNI', + ticker: 'UNI', + address: '0xfa7f8980b0f1e64a2062791cc3b0871572f1f7f0', + rawAmount: '2392264468', + decimal: 18, + amount: '0.000000002392264468', + logo: 'https://api.rango.exchange/i/n8RX8F', + usdPrice: 5.246, + }, + { + chain: 'ARBITRUM', + symbol: 'HND', + ticker: 'HND', + address: '0x10010078a54396f62c96df8532dc2b4847d47ed3', + rawAmount: '150921229948215461100', + decimal: 18, + amount: '150.9212299482154611', + logo: 'https://api.rango.exchange/i/2SsRdS', + usdPrice: null, + }, + { + chain: 'ARBITRUM', + symbol: 'GMX', + ticker: 'GMX', + address: '0xfc5a1a6eb076a2c7ad06ed22c90d7e710e35ad0a', + rawAmount: '128216748136770842', + decimal: 18, + amount: '0.128216748136770842', + logo: 'https://api.rango.exchange/i/vCEMKq', + usdPrice: 46.259, + }, + { + chain: 'ARBITRUM', + symbol: 'RIFTDAO.NET', + ticker: 'RIFTDAO.NET', + address: '0xe1cc7371f2c2b7ebb1af2b0c053ec86596e3f6d0', + rawAmount: '738097000000000000000000', + decimal: 18, + amount: '738097', + logo: null, + usdPrice: null, + }, + { + chain: 'ARBITRUM', + symbol: 'USDT', + ticker: 'USDT', + address: '0xfd086bc7cd5c481dcc9c85ebe478a1c0b69fcbb9', + rawAmount: '40064700', + decimal: 6, + amount: '40.0647', + logo: 'https://api.rango.exchange/i/aR1yFx', + usdPrice: 1, + }, + { + chain: 'ARBITRUM', + symbol: 'BADGER', + ticker: 'BADGER', + address: '0xbfa641051ba0a0ad1b0acf549a89536a0d76472e', + rawAmount: '2089136975803812618', + decimal: 18, + amount: '2.089136975803812618', + logo: 'https://api.rango.exchange/i/aaEEDq', + usdPrice: 2.26, + }, + { + chain: 'ARBITRUM', + symbol: 'USDC', + ticker: 'USDC', + address: '0xff970a61a04b1ca14834a43f5de4533ebddb5cc8', + rawAmount: '55298622', + decimal: 6, + amount: '55.298622', + logo: 'https://api.rango.exchange/i/ns0AMf', + usdPrice: 1, + }, + { + chain: 'ARBITRUM', + symbol: 'MIM', + ticker: 'MIM', + address: '0xfea7a6a0b346362bf88a9e4a88416b77a57d6c2a', + rawAmount: '10100000000000000000', + decimal: 18, + amount: '10.1', + logo: 'https://api.rango.exchange/i/JKT05f', + usdPrice: 0.998, + }, + { + chain: 'ARBITRUM', + symbol: 'AXLUSDC', + ticker: 'AXLUSDC', + address: '0xeb466342c4d449bc9f53a865d5cb90586f405215', + rawAmount: '5500000', + decimal: 6, + amount: '5.5', + logo: null, + usdPrice: null, + }, + { + chain: 'ARBITRUM', + symbol: 'ETH', + ticker: 'ETH', + address: null, + rawAmount: '82905399282605538', + decimal: 18, + amount: '0.082905399282605538', + logo: 'https://api.rango.exchange/i/MTyH5i', + usdPrice: null, + }, + ], + loading: false, + walletType: 'metamask', + isConnected: false, + error: false, + explorerUrl: + 'https://arbiscan.io/address/0x2702d89c1c8658b49c45dd460deebcc45faec03c', + }, + ], + }, + { + name: 'FANTOM', + accounts: [ + { + address: '0x2702d89c1c8658b49c45dd460deebcc45faec03c', + balances: [ + { + chain: 'FANTOM', + symbol: 'FBNB', + ticker: 'FBNB', + address: '0x27f26f00e1605903645bbabc0a73e35027dccd45', + rawAmount: '15851797577951', + decimal: 18, + amount: '0.000015851797577951', + logo: 'https://api.rango.exchange/tokens/FANTOM/FBNB.png', + usdPrice: null, + }, + { + chain: 'FANTOM', + symbol: 'WETH', + ticker: 'WETH', + address: '0x74b23882a30290451a17c44f4f05243b6b58c76d', + rawAmount: '2171678666801825', + decimal: 18, + amount: '0.002171678666801825', + logo: 'https://api.rango.exchange/tokens/FANTOM/WETH.png', + usdPrice: null, + }, + { + chain: 'FANTOM', + symbol: 'FXS', + ticker: 'FXS', + address: '0x7d016eec9c25232b01f23ef992d98ca97fc2af5a', + rawAmount: '8129029359551099', + decimal: 18, + amount: '0.008129029359551099', + logo: 'https://api.rango.exchange/i/TVDwaE', + usdPrice: null, + }, + { + chain: 'FANTOM', + symbol: 'WAVAX', + ticker: 'WAVAX', + address: '0x511d35c52a3c244e7b8bd92c0c297755fbd89212', + rawAmount: '103423419794091413', + decimal: 18, + amount: '0.103423419794091413', + logo: 'https://api.rango.exchange/tokens/FANTOM/WAVAX.png', + usdPrice: null, + }, + { + chain: 'FANTOM', + symbol: 'WOO', + ticker: 'WOO', + address: '0x6626c47c00f1d87902fc13eecfac3ed06d5e8d8a', + rawAmount: '3069453396', + decimal: 18, + amount: '0.000000003069453396', + logo: 'https://api.rango.exchange/i/UuEujP', + usdPrice: null, + }, + { + chain: 'FANTOM', + symbol: 'SWAPFTM.COM', + ticker: 'SWAPFTM.COM', + address: '0x87e377820010d818aa316f8c3f1c2b9d025eb5ee', + rawAmount: '100000000000000000000', + decimal: 18, + amount: '100', + logo: null, + usdPrice: null, + }, + { + chain: 'FANTOM', + symbol: 'BIFI', + ticker: 'BIFI', + address: '0xd6070ae98b8069de6b494332d1a1a81b6179d960', + rawAmount: '5427265333', + decimal: 18, + amount: '0.000000005427265333', + logo: 'https://api.rango.exchange/i/euTXdM', + usdPrice: null, + }, + { + chain: 'FANTOM', + symbol: 'BNB', + ticker: 'BNB', + address: '0xd67de0e0a0fd7b15dc8348bb9be742f3c5850454', + rawAmount: '4343993985', + decimal: 18, + amount: '0.000000004343993985', + logo: 'https://api.rango.exchange/i/Yj2w83', + usdPrice: null, + }, + { + chain: 'FANTOM', + symbol: 'NUSD', + ticker: 'NUSD', + address: '0xed2a7edd7413021d440b09d654f3b87712abab66', + rawAmount: '1993985245375892955', + decimal: 18, + amount: '1.993985245375892955', + logo: null, + usdPrice: null, + }, + { + chain: 'FANTOM', + symbol: 'MIM', + ticker: 'MIM', + address: '0x82f0b8b456c1a451378467398982d4834b6829c1', + rawAmount: '38400000001430563305', + decimal: 18, + amount: '38.400000001430563305', + logo: 'https://api.rango.exchange/i/ceBRSU', + usdPrice: null, + }, + { + chain: 'FANTOM', + symbol: '888CRYPTO.PRO', + ticker: '888CRYPTO.PRO', + address: '0x7082ca5058c358997063400ad78306b16a5c30d9', + rawAmount: '150000000000000', + decimal: 8, + amount: '1500000', + logo: null, + usdPrice: null, + }, + { + chain: 'FANTOM', + symbol: '2XCO', + ticker: '2XCO', + address: '0xcaef42682040a19e09eb8a6773f17da81b0604c1', + rawAmount: '9500000000000', + decimal: 8, + amount: '95000', + logo: null, + usdPrice: null, + }, + { + chain: 'FANTOM', + symbol: '$ AIRDROP IN CAKE (MULTICHAIN)', + ticker: '$ AIRDROP IN CAKE (MULTICHAIN)', + address: '0xb502b79c9ec490c4eee130a03370d490b069e59b', + rawAmount: '50000000000', + decimal: 8, + amount: '500', + logo: null, + usdPrice: null, + }, + { + chain: 'FANTOM', + symbol: 'USDC', + ticker: 'USDC', + address: '0x04068da6c83afcfa0e13ba15a6696662335d5b75', + rawAmount: '268477851', + decimal: 6, + amount: '268.477851', + logo: 'https://api.rango.exchange/i/pva3ih', + usdPrice: null, + }, + { + chain: 'FANTOM', + symbol: '0CASINO.IO', + ticker: '0CASINO.IO', + address: '0x383c5e5a05ba830579adc2fccd6403894e1caa59', + rawAmount: '150000000000000', + decimal: 8, + amount: '1500000', + logo: null, + usdPrice: null, + }, + { + chain: 'FANTOM', + symbol: 'WFTM', + ticker: 'WFTM', + address: '0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83', + rawAmount: '262664414658966373114', + decimal: 18, + amount: '262.664414658966373114', + logo: 'https://api.rango.exchange/i/auYSf8', + usdPrice: null, + }, + { + chain: 'FANTOM', + symbol: 'ETH-1INCH.IO', + ticker: 'ETH-1INCH.IO', + address: '0x5a7aad61871a39a972c11aa9cd48e8df1e10311d', + rawAmount: '870000000000000000', + decimal: 18, + amount: '0.87', + logo: null, + usdPrice: null, + }, + { + chain: 'FANTOM', + symbol: 'BUSD', + ticker: 'BUSD', + address: '0xc931f61b1534eb21d8c11b24f3f5ab2471d4ab50', + rawAmount: '996216277676653329', + decimal: 18, + amount: '0.996216277676653329', + logo: 'https://api.rango.exchange/i/zOV927', + usdPrice: null, + }, + { + chain: 'FANTOM', + symbol: 'DAI', + ticker: 'DAI', + address: '0x8d11ec38a3eb5e956b052f67da8bdc9bef8abf3e', + rawAmount: '6907579712', + decimal: 18, + amount: '0.000000006907579712', + logo: 'https://api.rango.exchange/i/iIxCAk', + usdPrice: null, + }, + { + chain: 'FANTOM', + symbol: 'RBNB', + ticker: 'RBNB', + address: '0xc3394bb9b118b3c9b5b8da297e20c08878edbed4', + rawAmount: '100000000000000', + decimal: 18, + amount: '0.0001', + logo: null, + usdPrice: null, + }, + { + chain: 'FANTOM', + symbol: 'IMX', + ticker: 'IMX', + address: '0xea38f1ccf77bf43f352636241b05dd8f6f5f52b2', + rawAmount: '116509710', + decimal: 18, + amount: '0.00000000011650971', + logo: 'https://api.rango.exchange/i/3nnwQN', + usdPrice: null, + }, + { + chain: 'FANTOM', + symbol: '24DROP.NET', + ticker: '24DROP.NET', + address: '0x67a58a20f087a600aec491d5cd329ba597b71aa7', + rawAmount: '200000000000', + decimal: 8, + amount: '2000', + logo: null, + usdPrice: null, + }, + { + chain: 'FANTOM', + symbol: 'MNEF', + ticker: 'MNEF', + address: '0xf9d922c055a3f1759299467dafafdf43be844f7a', + rawAmount: '30000000000000', + decimal: 8, + amount: '300000', + logo: null, + usdPrice: null, + }, + { + chain: 'FANTOM', + symbol: ' 0VISIT [003ERRORNOTICE.COM] TO SECURE YOUR FUNDS.', + ticker: ' 0VISIT [003ERRORNOTICE.COM] TO SECURE YOUR FUNDS.', + address: '0x98e4b3866602fc72ff766616e15146c9153b473b', + rawAmount: '2200000000000000000000', + decimal: 18, + amount: '2200', + logo: null, + usdPrice: null, + }, + { + chain: 'FANTOM', + symbol: '0CASINO.IO', + ticker: '0CASINO.IO', + address: '0xbe1b23d652580052dd8e774e0e7e92cf5cc31bb3', + rawAmount: '150000000000000', + decimal: 8, + amount: '1500000', + logo: null, + usdPrice: null, + }, + { + chain: 'FANTOM', + symbol: 'CRV', + ticker: 'CRV', + address: '0x1e4f97b9f9f913c46f1632781732927b9019c68b', + rawAmount: '2433604212107615486', + decimal: 18, + amount: '2.433604212107615486', + logo: 'https://api.rango.exchange/i/60avSg', + usdPrice: null, + }, + { + chain: 'FANTOM', + symbol: '4GAMBLING.IO', + ticker: '4GAMBLING.IO', + address: '0xe4517100ae62cbeefc363e59d0f8df5754dc7e40', + rawAmount: '300000000000000', + decimal: 8, + amount: '3000000', + logo: null, + usdPrice: null, + }, + { + chain: 'FANTOM', + symbol: 'USDT', + ticker: 'USDT', + address: '0x049d68029688eabf473097a2fc38ef61633a3c7a', + rawAmount: '63082358', + decimal: 6, + amount: '63.082358', + logo: 'https://api.rango.exchange/i/niIihm', + usdPrice: null, + }, + { + chain: 'FANTOM', + symbol: 'FTM', + ticker: 'FTM', + address: null, + rawAmount: '1346689531144440162650', + decimal: 18, + amount: '1346.68953114444016265', + logo: 'https://api.rango.exchange/i/JC2fWD', + usdPrice: null, + }, + ], + loading: false, + walletType: 'metamask', + isConnected: false, + error: false, + explorerUrl: + 'https://ftmscan.com/address/0x2702d89c1c8658b49c45dd460deebcc45faec03c', + }, + ], + }, + { + name: 'OPTIMISM', + accounts: [ + { + address: '0x2702d89c1c8658b49c45dd460deebcc45faec03c', + balances: [ + { + chain: 'OPTIMISM', + symbol: 'USDT', + ticker: 'USDT', + address: '0x94b008aa00579c1307b0ef2c499ad98a8ce58e58', + rawAmount: '22874529', + decimal: 6, + amount: '22.874529', + logo: 'https://api.rango.exchange/i/K6j5VN', + usdPrice: 1, + }, + { + chain: 'OPTIMISM', + symbol: 'USDC', + ticker: 'USDC', + address: '0x7f5c764cbc14f9669b88837ca1490cca17c31607', + rawAmount: '39610548', + decimal: 6, + amount: '39.610548', + logo: 'https://api.rango.exchange/i/e4x0s8', + usdPrice: 0.999, + }, + { + chain: 'OPTIMISM', + symbol: 'WETH', + ticker: 'WETH', + address: '0x4200000000000000000000000000000000000006', + rawAmount: '30671676019131723', + decimal: 18, + amount: '0.030671676019131723', + logo: 'https://api.rango.exchange/i/yZ9N1N', + usdPrice: 1207.06, + }, + { + chain: 'OPTIMISM', + symbol: 'DAI', + ticker: 'DAI', + address: '0xda10009cbd5d07dd0cecc66161fc93d7c9000da1', + rawAmount: '1535439265', + decimal: 18, + amount: '0.000000001535439265', + logo: 'https://api.rango.exchange/i/zyZx0X', + usdPrice: 1, + }, + { + chain: 'OPTIMISM', + symbol: 'ETH', + ticker: 'ETH', + address: null, + rawAmount: '3809903995186154', + decimal: 18, + amount: '0.003809903995186154', + logo: 'https://api.rango.exchange/i/MTyH5i', + usdPrice: null, + }, + ], + loading: false, + walletType: 'metamask', + isConnected: false, + error: false, + explorerUrl: + 'https://optimistic.etherscan.io/address/0x2702d89c1c8658b49c45dd460deebcc45faec03c', + }, + ], + }, + { + name: 'OKC', + accounts: [ + { + address: '0x2702d89c1c8658b49c45dd460deebcc45faec03c', + balances: [], + loading: false, + walletType: 'metamask', + isConnected: false, + error: true, + explorerUrl: + 'https://www.oklink.com/en/okc/address/0x2702d89c1c8658b49c45dd460deebcc45faec03c', + }, + ], + }, + { + name: 'CRONOS', + accounts: [ + { + address: '0x2702d89c1c8658b49c45dd460deebcc45faec03c', + balances: [ + { + chain: 'CRONOS', + symbol: 'WETH', + ticker: 'WETH', + address: '0xe44fd7fcb2b1581822d0c862b68222998a0c299a', + rawAmount: '4788770370', + decimal: 18, + amount: '0.00000000478877037', + logo: 'https://api.rango.exchange/i/j9xgdC', + usdPrice: 1210.2, + }, + { + chain: 'CRONOS', + symbol: 'AUTO', + ticker: 'AUTO', + address: '0x0dcb0cb0120d355cde1ce56040be57add0185baa', + rawAmount: '43013763072696143', + decimal: 18, + amount: '0.043013763072696143', + logo: 'https://api.rango.exchange/i/YxjmF0', + usdPrice: 222.98, + }, + { + chain: 'CRONOS', + symbol: 'CRONOSCLASSIC.COM', + ticker: 'CRONOSCLASSIC.COM', + address: '0x772c96ed2f99d84c2a83e67fbada9a1db4303be1', + rawAmount: '9000000000000000000000', + decimal: 18, + amount: '9000', + logo: null, + usdPrice: null, + }, + { + chain: 'CRONOS', + symbol: 'BNB', + ticker: 'BNB', + address: '0xfa9343c3897324496a05fc75abed6bac29f8a40f', + rawAmount: '86000000000000000', + decimal: 18, + amount: '0.086', + logo: 'https://api.rango.exchange/i/B4ULZJ', + usdPrice: 248.28, + }, + { + chain: 'CRONOS', + symbol: 'USDT', + ticker: 'USDT', + address: '0x66e428c3f67a68878562e79a0234c1f83c208770', + rawAmount: '1287808', + decimal: 6, + amount: '1.287808', + logo: 'https://api.rango.exchange/i/GJxbOP', + usdPrice: 1, + }, + { + chain: 'CRONOS', + symbol: 'CRONOSCLASSIC.COM', + ticker: 'CRONOSCLASSIC.COM', + address: '0x75f920403641ddbd66f8ce3ddd3a648ddb496c89', + rawAmount: '9000000000000000000000', + decimal: 18, + amount: '9000', + logo: null, + usdPrice: null, + }, + { + chain: 'CRONOS', + symbol: 'CRO', + ticker: 'CRO', + address: null, + rawAmount: '218462428966917726855', + decimal: 18, + amount: '218.462428966917726855', + logo: 'https://api.rango.exchange/i/S3tFKF', + usdPrice: 0.0579, + }, + ], + loading: false, + walletType: 'metamask', + isConnected: false, + error: false, + explorerUrl: + 'https://cronoscan.com/address/0x2702d89c1c8658b49c45dd460deebcc45faec03c', + }, + ], + }, + { + name: 'MOONRIVER', + accounts: [ + { + address: '0x2702d89c1c8658b49c45dd460deebcc45faec03c', + balances: [ + { + chain: 'MOONRIVER', + symbol: 'MOVR', + ticker: 'MOVR', + address: null, + rawAmount: '1409467396930959879', + decimal: 18, + amount: '1.409467396930959879', + logo: 'https://api.rango.exchange/i/AKXDjV', + usdPrice: null, + }, + ], + loading: false, + walletType: 'metamask', + isConnected: false, + error: false, + explorerUrl: + 'https://moonriver.moonscan.io/address/0x2702d89c1c8658b49c45dd460deebcc45faec03c', + }, + ], + }, + { + name: 'MOONBEAM', + accounts: [ + { + address: '0x2702d89c1c8658b49c45dd460deebcc45faec03c', + balances: [ + { + chain: 'MOONBEAM', + symbol: 'GLMR', + ticker: 'GLMR', + address: null, + rawAmount: '7637316155712999392', + decimal: 18, + amount: '7.637316155712999392', + logo: 'https://api.rango.exchange/i/Ra0xKh', + usdPrice: 0.343, + }, + ], + loading: false, + walletType: 'metamask', + isConnected: false, + error: false, + explorerUrl: + 'https://moonbeam.moonscan.io/address/0x2702d89c1c8658b49c45dd460deebcc45faec03c', + }, + ], + }, + { + name: 'HECO', + accounts: [ + { + address: '0x2702d89c1c8658b49c45dd460deebcc45faec03c', + balances: [ + { + chain: 'HECO', + symbol: 'HT', + ticker: 'HT', + address: null, + rawAmount: '8900958749249974840', + decimal: 18, + amount: '8.90095874924997484', + logo: 'https://api.rango.exchange/i/9uAYzf', + usdPrice: 5.361, + }, + ], + loading: false, + walletType: 'metamask', + isConnected: false, + error: false, + explorerUrl: + 'https://hecoinfo.com/address/0x2702d89c1c8658b49c45dd460deebcc45faec03c', + }, + ], + }, + { + name: 'AURORA', + accounts: [ + { + address: '0x2702d89c1c8658b49c45dd460deebcc45faec03c', + balances: [ + { + chain: 'AURORA', + symbol: 'MATIC', + ticker: 'MATIC', + address: '0x6ab6d61428fde76768d7b45d8bfeec19c6ef91a8', + rawAmount: '4963601767', + decimal: 18, + amount: '0.000000004963601767', + logo: 'https://api.rango.exchange/i/yVbC8U', + usdPrice: 0.793, + }, + { + chain: 'AURORA', + symbol: 'AVAX', + ticker: 'AVAX', + address: '0x80a16016cc4a2e6a2caca8a4a498b1699ff0f844', + rawAmount: '2088345237', + decimal: 18, + amount: '0.000000002088345237', + logo: 'https://api.rango.exchange/i/kX4edQ', + usdPrice: 11.77, + }, + { + chain: 'AURORA', + symbol: 'WETH', + ticker: 'WETH', + address: '0xc9bdeed33cd01541e1eed10f90519d2c06fe3feb', + rawAmount: '1000000328916822', + decimal: 18, + amount: '0.001000000328916822', + logo: 'https://api.rango.exchange/i/3h0NwB', + usdPrice: 1272.743, + }, + { + chain: 'AURORA', + symbol: 'USDC', + ticker: 'USDC', + address: '0xb12bfca5a55806aaf64e99521918a4bf0fc40802', + rawAmount: '25059116', + decimal: 6, + amount: '25.059116', + logo: 'https://api.rango.exchange/i/UfM0ap', + usdPrice: 0.998, + }, + { + chain: 'AURORA', + symbol: 'USDT', + ticker: 'USDT', + address: '0x4988a896b1227218e4a686fde5eabdcabd91571f', + rawAmount: '9373920', + decimal: 6, + amount: '9.37392', + logo: 'https://api.rango.exchange/i/sq7c5G', + usdPrice: 1.005, + }, + { + chain: 'AURORA', + symbol: 'ATLUNA', + ticker: 'ATLUNA', + address: '0xc4bdd27c33ec7daa6fcfd8532ddb524bf4038096', + rawAmount: '7269857397', + decimal: 18, + amount: '0.000000007269857397', + logo: 'https://api.rango.exchange/i/kIZ1fy', + usdPrice: null, + }, + { + chain: 'AURORA', + symbol: 'PICKLE', + ticker: 'PICKLE', + address: '0x291c8fceaca3342b29cc36171deb98106f712c66', + rawAmount: '3462515627985423594', + decimal: 18, + amount: '3.462515627985423594', + logo: 'https://api.rango.exchange/i/LPaa2J', + usdPrice: null, + }, + { + chain: 'AURORA', + symbol: 'PAPR', + ticker: 'PAPR', + address: '0xa5c09de3aa1cdb5cb190be66c77e033be1ca594a', + rawAmount: '163912004957041283', + decimal: 18, + amount: '0.163912004957041283', + logo: 'https://api.rango.exchange/i/sXsnQu', + usdPrice: 0.452, + }, + { + chain: 'AURORA', + symbol: 'PRNTR', + ticker: 'PRNTR', + address: '0x29daeb6a2a87b159f5fee1f19ec6ccaf4ef2acca', + rawAmount: '307884579855694445', + decimal: 18, + amount: '0.307884579855694445', + logo: 'https://api.rango.exchange/i/Uf33Cw', + usdPrice: 0.602, + }, + ], + loading: false, + walletType: 'metamask', + isConnected: false, + error: false, + explorerUrl: + 'https://explorer.mainnet.aurora.dev/address/0x2702d89c1c8658b49c45dd460deebcc45faec03c', + }, + ], + }, + { + name: 'HARMONY', + accounts: [ + { + address: '0x2702d89c1c8658b49c45dd460deebcc45faec03c', + balances: [ + { + chain: 'HARMONY', + symbol: 'ONE', + ticker: 'ONE', + address: null, + rawAmount: '48801440860746527271', + decimal: 18, + amount: '48.801440860746527271', + logo: 'https://api.rango.exchange/i/gpMxOP', + usdPrice: 0.109, + }, + { + chain: 'HARMONY', + symbol: '1DAI', + ticker: '1DAI', + address: '0xef977d2f931c1978db5f6747666fa1eacb0d0339', + rawAmount: '3951799808', + decimal: 18, + amount: '0.000000003951799808', + logo: 'https://api.rango.exchange/i/7UdDll', + usdPrice: 0.961, + }, + { + chain: 'HARMONY', + symbol: '1USDC', + ticker: '1USDC', + address: '0x985458e523db3d53125813ed68c274899e9dfab4', + rawAmount: '4480342', + decimal: 6, + amount: '4.480342', + logo: 'https://api.rango.exchange/i/4eEvKA', + usdPrice: 1.006, + }, + { + chain: 'HARMONY', + symbol: 'bscBUSD', + ticker: 'bscBUSD', + address: '0x0ab43550a6915f9f67d0c454c2e90385e6497eaa', + rawAmount: '12000000009249314069', + decimal: 18, + amount: '12.000000009249314069', + logo: 'https://api.rango.exchange/i/uZMcKl', + usdPrice: 0.946, + }, + { + chain: 'HARMONY', + symbol: 'BUSD', + ticker: 'BUSD', + address: '0xe176ebe47d621b984a73036b9da5d834411ef734', + rawAmount: '6201993388439322612', + decimal: 18, + amount: '6.201993388439322612', + logo: 'https://api.rango.exchange/i/qWxf4I', + usdPrice: 0.84, + }, + { + chain: 'HARMONY', + symbol: 'UST', + ticker: 'UST', + address: '0x224e64ec1bdce3870a6a6c777edd450454068fec', + rawAmount: '5449588252', + decimal: 18, + amount: '0.000000005449588252', + logo: 'https://api.rango.exchange/i/wmyHK9', + usdPrice: 0.194, + }, + { + chain: 'HARMONY', + symbol: 'WONE', + ticker: 'WONE', + address: '0xcf664087a5bb0237a0bad6742852ec6c8d69a27a', + rawAmount: '2000000000624440839', + decimal: 18, + amount: '2.000000000624440839', + logo: 'https://api.rango.exchange/i/u283bK', + usdPrice: 0.109, + }, + { + chain: 'HARMONY', + symbol: 'BIFI', + ticker: 'BIFI', + address: '0x6ab6d61428fde76768d7b45d8bfeec19c6ef91a8', + rawAmount: '6500000000000000', + decimal: 18, + amount: '0.0065', + logo: 'https://api.rango.exchange/i/EuFqit', + usdPrice: 325.37, + }, + { + chain: 'HARMONY', + symbol: 'JENN', + ticker: 'JENN', + address: '0x2f459dd7cbcc9d8323621f6fb430cd0555411e7b', + rawAmount: '82666600666715773', + decimal: 18, + amount: '0.082666600666715773', + logo: 'https://api.rango.exchange/i/5CYmzQ', + usdPrice: 0.00429, + }, + { + chain: 'HARMONY', + symbol: 'LMA', + ticker: 'LMA', + address: '0x7d0546dbb1dca8108d99aa389a8e9ce0c40b2370', + rawAmount: '2335555755', + decimal: 18, + amount: '0.000000002335555755', + logo: 'https://api.rango.exchange/i/A8Kw4L', + usdPrice: 33.26, + }, + ], + loading: false, + walletType: 'metamask', + isConnected: false, + error: false, + explorerUrl: + 'https://explorer.harmony.one/address/0x2702d89c1c8658b49c45dd460deebcc45faec03c', + }, + ], + }, + { + name: 'EVMOS', + accounts: [ + { + address: '0x2702d89c1c8658b49c45dd460deebcc45faec03c', + balances: [], + loading: false, + walletType: 'metamask', + isConnected: false, + error: true, + explorerUrl: + 'https://evm.evmos.org/address/0x2702d89c1c8658b49c45dd460deebcc45faec03c', + }, + ], + }, + { + name: 'GNOSIS', + accounts: [ + { + address: '0x2702d89c1c8658b49c45dd460deebcc45faec03c', + balances: [], + loading: false, + walletType: 'metamask', + isConnected: false, + error: true, + explorerUrl: + 'https://blockscout.com/xdai/mainnet/address/0x2702d89c1c8658b49c45dd460deebcc45faec03c', + }, + ], + }, + { + name: 'FUSE', + accounts: [ + { + address: '0x2702d89c1c8658b49c45dd460deebcc45faec03c', + balances: [], + loading: false, + walletType: 'metamask', + isConnected: false, + error: true, + explorerUrl: + 'https://explorer.fuse.io/address/0x2702d89c1c8658b49c45dd460deebcc45faec03c', + }, + ], + }, + { + name: 'BOBA', + accounts: [ + { + address: '0x2702d89c1c8658b49c45dd460deebcc45faec03c', + balances: [ + { + chain: 'BOBA', + symbol: 'MIM', + ticker: 'MIM', + address: '0x218c3c3d49d0e7b37aff0d8bb079de36ae61a4c0', + rawAmount: '105604450000000000', + decimal: 18, + amount: '0.10560445', + logo: 'https://api.rango.exchange/i/RmsZZl', + usdPrice: 0.998, + }, + { + chain: 'BOBA', + symbol: 'BUSD', + ticker: 'BUSD', + address: '0x461d52769884ca6235b685ef2040f47d30c94eb5', + rawAmount: '5431734874', + decimal: 18, + amount: '0.000000005431734874', + logo: 'https://api.rango.exchange/i/PsiPay', + usdPrice: 0.999, + }, + { + chain: 'BOBA', + symbol: 'UNIDX', + ticker: 'UNIDX', + address: '0x375488f097176507e39b9653b88fdc52cde736bf', + rawAmount: '23224657182604680757', + decimal: 18, + amount: '23.224657182604680757', + logo: 'https://api.rango.exchange/i/TZv5rn', + usdPrice: 2.3, + }, + { + chain: 'BOBA', + symbol: 'BANA', + ticker: 'BANA', + address: '0xc67b9b1b0557aeafa10aa1ffa1d7c87087a6149e', + rawAmount: '9067814698', + decimal: 18, + amount: '0.000000009067814698', + logo: 'https://api.rango.exchange/i/gyHe7C', + usdPrice: null, + }, + { + chain: 'BOBA', + symbol: 'BDOGE', + ticker: 'BDOGE', + address: '0x121636c43e96d97ab00b6c6994cddebef27de1c7', + rawAmount: '723068225237233960', + decimal: 18, + amount: '0.72306822523723396', + logo: 'https://api.rango.exchange/i/U6UPsb', + usdPrice: 1.64e-9, + }, + { + chain: 'BOBA', + symbol: 'SHIBUI', + ticker: 'SHIBUI', + address: '0xf08ad7c3f6b1c6843ba027ad54ed8ddb6d71169b', + rawAmount: '1827087060', + decimal: 18, + amount: '0.00000000182708706', + logo: 'https://api.rango.exchange/i/Mwv1h9', + usdPrice: 0.00631, + }, + { + chain: 'BOBA', + symbol: 'USDC', + ticker: 'USDC', + address: '0x66a2a913e447d6b4bf33efbec43aaef87890fbbc', + rawAmount: '11210692', + decimal: 6, + amount: '11.210692', + logo: 'https://api.rango.exchange/i/ahp7BS', + usdPrice: 0.993, + }, + { + chain: 'BOBA', + symbol: 'BOBA', + ticker: 'BOBA', + address: '0xa18bf3994c0cc6e3b63ac420308e5383f53120d7', + rawAmount: '1093312869', + decimal: 18, + amount: '0.000000001093312869', + logo: 'https://api.rango.exchange/i/vWYKUH', + usdPrice: 0.181, + }, + { + chain: 'BOBA', + symbol: 'WETH', + ticker: 'WETH', + address: '0xdeaddeaddeaddeaddeaddeaddeaddeaddead0000', + rawAmount: '2606189668', + decimal: 18, + amount: '0.000000002606189668', + logo: 'https://api.rango.exchange/i/fEyllw', + usdPrice: 1197.276, + }, + { + chain: 'BOBA', + symbol: 'DAI', + ticker: 'DAI', + address: '0xf74195bb8a5cf652411867c5c2c5b8c2a402be35', + rawAmount: '2131602501374765414', + decimal: 18, + amount: '2.131602501374765414', + logo: 'https://api.rango.exchange/i/U8PEdb', + usdPrice: null, + }, + { + chain: 'BOBA', + symbol: 'ETH', + ticker: 'ETH', + address: null, + rawAmount: '884271636924027', + decimal: 18, + amount: '0.000884271636924027', + logo: 'https://api.rango.exchange/i/MTyH5i', + usdPrice: 1197.276, + }, + ], + loading: false, + walletType: 'metamask', + isConnected: false, + error: false, + explorerUrl: + 'https://bobascan.com//address/0x2702d89c1c8658b49c45dd460deebcc45faec03c', + }, + ], + }, + ], +} as Wallet; + +export const meta = { + blockchains: { + BSC: { + name: 'BSC', + defaultDecimals: 18, + addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], + feeAssets: [{ blockchain: 'BSC', symbol: 'BNB', address: null }], + logo: 'https://api.rango.exchange/blockchains/binance.svg', + displayName: 'BSC', + shortName: 'BSC', + sort: 1, + color: '#F3BA2F', + enabled: true, + type: 'EVM', + chainId: '0x38', + info: { + chainName: 'Binance Smart Chain Mainnet', + nativeCurrency: { name: 'BNB', symbol: 'BNB', decimals: 18 }, + rpcUrls: ['https://bsc-dataseed1.ninicoin.io'], + blockExplorerUrls: ['https://bscscan.com'], + addressUrl: 'https://bscscan.com/address/{wallet}', + transactionUrl: 'https://bscscan.com/tx/{txHash}', + }, + }, + POLYGON: { + name: 'POLYGON', + defaultDecimals: 18, + addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], + feeAssets: [{ blockchain: 'POLYGON', symbol: 'MATIC', address: null }], + logo: 'https://api.rango.exchange/blockchains/polygon.svg', + displayName: 'Polygon', + shortName: 'Polygon', + sort: 2, + color: '#8247E5', + enabled: true, + type: 'EVM', + chainId: '0x89', + info: { + chainName: 'Polygon Mainnet', + nativeCurrency: { name: 'MATIC', symbol: 'MATIC', decimals: 18 }, + rpcUrls: ['https://polygon-rpc.com'], + blockExplorerUrls: ['https://polygonscan.com'], + addressUrl: 'https://polygonscan.com/address/{wallet}', + transactionUrl: 'https://polygonscan.com/tx/{txHash}', + }, + }, + ETH: { + name: 'ETH', + defaultDecimals: 18, + addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], + feeAssets: [{ blockchain: 'ETH', symbol: 'ETH', address: null }], + logo: 'https://api.rango.exchange/blockchains/ethereum.svg', + displayName: 'Ethereum', + shortName: 'ETH', + sort: 3, + color: '#ecf0f1', + enabled: true, + type: 'EVM', + chainId: '0x1', + info: { + chainName: 'Ethereum Mainnet', + nativeCurrency: { name: 'ETH', symbol: 'ETH', decimals: 18 }, + rpcUrls: ['https://rpc.ankr.com/eth'], + blockExplorerUrls: ['https://etherscan.io'], + addressUrl: 'https://etherscan.io/address/{wallet}', + transactionUrl: 'https://etherscan.io/tx/{txHash}', + }, + }, + OSMOSIS: { + name: 'OSMOSIS', + defaultDecimals: 6, + addressPatterns: ['^(osmo1)[0-9a-z]{38}$'], + feeAssets: [{ blockchain: 'OSMOSIS', symbol: 'OSMO', address: null }], + logo: 'https://api.rango.exchange/blockchains/osmosis.svg', + displayName: 'Osmosis', + shortName: 'Osmosis', + sort: 4, + color: '#7901B4', + enabled: true, + type: 'COSMOS', + chainId: 'osmosis-1', + info: { + experimental: false, + rpc: 'https://rpc-osmosis.keplr.app', + rest: 'https://lcd-osmosis.keplr.app', + cosmostationLcdUrl: 'https://lcd-osmosis.cosmostation.io', + cosmostationApiUrl: 'https://api-osmosis.cosmostation.io', + cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', + mintScanName: 'osmosis', + chainName: 'Osmosis', + stakeCurrency: { + coinDenom: 'OSMO', + coinMinimalDenom: 'uosmo', + coinDecimals: 6, + coinGeckoId: 'pool:uosmo', + coinImageUrl: '/tokens/blockchain/osmosis.svg', + }, + bip44: { coinType: 118 }, + bech32Config: { + bech32PrefixAccAddr: 'osmo', + bech32PrefixAccPub: 'osmopub', + bech32PrefixValAddr: 'osmovaloper', + bech32PrefixValPub: 'osmovaloperpub', + bech32PrefixConsAddr: 'osmovalcons', + bech32PrefixConsPub: 'osmovalconspub', + }, + currencies: [ + { + coinDenom: 'OSMO', + coinMinimalDenom: 'uosmo', + coinDecimals: 6, + coinGeckoId: 'pool:uosmo', + coinImageUrl: '/tokens/blockchain/osmosis.svg', + }, + { + coinDenom: 'ION', + coinMinimalDenom: 'uion', + coinDecimals: 6, + coinGeckoId: 'pool:uion', + coinImageUrl: '/tokens/blockchain/ion.png', + }, + ], + feeCurrencies: [ + { + coinDenom: 'OSMO', + coinMinimalDenom: 'uosmo', + coinDecimals: 6, + coinGeckoId: 'pool:uosmo', + coinImageUrl: '/tokens/blockchain/osmosis.svg', + }, + ], + features: ['stargate', 'ibc-transfer'], + explorerUrlToTx: 'https://www.mintscan.io/osmosis/txs/{txHash}', + gasPriceStep: { low: 0, average: 0.025, high: 0.04 }, + }, + }, + JUNO: { + name: 'JUNO', + defaultDecimals: 6, + addressPatterns: ['^(juno1)[0-9a-z]{38}$'], + feeAssets: [{ blockchain: 'JUNO', symbol: 'JUNO', address: null }], + logo: 'https://api.rango.exchange/blockchains/juno.svg', + displayName: 'Juno', + shortName: 'Juno', + sort: 5, + color: '#f0827d', + enabled: true, + type: 'COSMOS', + chainId: 'juno-1', + info: { + experimental: false, + rpc: 'https://rpc-juno.itastakers.com:443/', + rest: 'https://lcd-juno.keplr.app', + cosmostationLcdUrl: 'https://lcd-juno.cosmostation.io', + cosmostationApiUrl: 'https://api-juno.cosmostation.io', + cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', + mintScanName: 'juno', + chainName: 'Juno', + stakeCurrency: { + coinDenom: 'JUNO', + coinMinimalDenom: 'ujuno', + coinDecimals: 6, + coinGeckoId: 'juno-network', + coinImageUrl: '/tokens/blockchain/JUNO.png', + }, + bip44: { coinType: 118 }, + bech32Config: { + bech32PrefixAccAddr: 'juno', + bech32PrefixAccPub: 'junopub', + bech32PrefixValAddr: 'junovaloper', + bech32PrefixValPub: 'junovaloperpub', + bech32PrefixConsAddr: 'junovalcons', + bech32PrefixConsPub: 'junovalconspub', + }, + currencies: [ + { + coinDenom: 'JUNO', + coinMinimalDenom: 'ujuno', + coinDecimals: 6, + coinGeckoId: 'juno-network', + coinImageUrl: '/tokens/blockchain/JUNO.png', + }, + ], + feeCurrencies: [ + { + coinDenom: 'JUNO', + coinMinimalDenom: 'ujuno', + coinDecimals: 6, + coinGeckoId: 'juno-network', + coinImageUrl: '/tokens/blockchain/JUNO.png', + }, + ], + features: ['stargate', 'ibc-transfer'], + explorerUrlToTx: 'https://www.mintscan.io/juno/txs/{txHash}', + gasPriceStep: { low: 0.001, average: 0.0025, high: 0.004 }, + }, + }, + AVAX_CCHAIN: { + name: 'AVAX_CCHAIN', + defaultDecimals: 18, + addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], + feeAssets: [{ blockchain: 'AVAX_CCHAIN', symbol: 'AVAX', address: null }], + logo: 'https://api.rango.exchange/blockchains/avax_cchain.svg', + displayName: 'Avalanche', + shortName: 'Avax', + sort: 6, + color: '#e84142', + enabled: true, + type: 'EVM', + chainId: '0xa86a', + info: { + chainName: 'Avalanche C-Chain', + nativeCurrency: { name: 'AVAX', symbol: 'AVAX', decimals: 18 }, + rpcUrls: ['https://api.avax.network/ext/bc/C/rpc'], + blockExplorerUrls: ['https://snowtrace.io'], + addressUrl: 'https://snowtrace.io/address/{wallet}', + transactionUrl: 'https://snowtrace.io/tx/{txHash}', + }, + }, + ARBITRUM: { + name: 'ARBITRUM', + defaultDecimals: 18, + addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], + feeAssets: [{ blockchain: 'ARBITRUM', symbol: 'ETH', address: null }], + logo: 'https://api.rango.exchange/blockchains/arbitrum.svg', + displayName: 'Arbitrum', + shortName: 'Arbitrum', + sort: 7, + color: '#28a0f0', + enabled: true, + type: 'EVM', + chainId: '0xa4b1', + info: { + chainName: 'Arbitrum One', + nativeCurrency: { name: 'ETH', symbol: 'ETH', decimals: 18 }, + rpcUrls: ['https://arb1.arbitrum.io/rpc'], + blockExplorerUrls: ['https://arbiscan.io'], + addressUrl: 'https://arbiscan.io/address/{wallet}', + transactionUrl: 'https://arbiscan.io/tx/{txHash}', + }, + }, + COSMOS: { + name: 'COSMOS', + defaultDecimals: 6, + addressPatterns: ['^(cosmos1)[0-9a-z]{38}$'], + feeAssets: [{ blockchain: 'COSMOS', symbol: 'ATOM', address: null }], + logo: 'https://api.rango.exchange/blockchains/cosmos.svg', + displayName: 'Cosmos', + shortName: 'Cosmos', + sort: 8, + color: '#2E3148', + enabled: true, + type: 'COSMOS', + chainId: 'cosmoshub-4', + info: { + experimental: false, + rpc: 'https://cosmos-rpc.polkachu.com', + rest: 'https://lcd-cosmoshub.keplr.app', + cosmostationLcdUrl: 'https://lcd-cosmos.cosmostation.io', + cosmostationApiUrl: 'https://api-cosmos.cosmostation.io', + cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', + mintScanName: 'cosmos', + chainName: 'Cosmos', + stakeCurrency: { + coinDenom: 'ATOM', + coinMinimalDenom: 'uatom', + coinDecimals: 6, + coinGeckoId: 'cosmos', + coinImageUrl: '/tokens/blockchain/cosmos.svg', + }, + bip44: { coinType: 118 }, + bech32Config: { + bech32PrefixAccAddr: 'cosmos', + bech32PrefixAccPub: 'cosmospub', + bech32PrefixValAddr: 'cosmosvaloper', + bech32PrefixValPub: 'cosmosvaloperpub', + bech32PrefixConsAddr: 'cosmosvalcons', + bech32PrefixConsPub: 'cosmosvalconspub', + }, + currencies: [ + { + coinDenom: 'ATOM', + coinMinimalDenom: 'uatom', + coinDecimals: 6, + coinGeckoId: 'cosmos', + coinImageUrl: '/tokens/blockchain/cosmos.svg', + }, + ], + feeCurrencies: [ + { + coinDenom: 'ATOM', + coinMinimalDenom: 'uatom', + coinDecimals: 6, + coinGeckoId: 'cosmos', + coinImageUrl: '/tokens/blockchain/cosmos.svg', + }, + ], + features: ['stargate', 'ibc-transfer'], + explorerUrlToTx: 'https://www.mintscan.io/cosmos/txs/{txHash}', + gasPriceStep: { low: 0.01, average: 0.025, high: 0.04 }, + }, + }, + STARKNET: { + name: 'STARKNET', + defaultDecimals: 18, + addressPatterns: ['^(0x)[0-9A-Fa-f]{64}$'], + feeAssets: [ + { + blockchain: 'STARKNET', + symbol: 'ETH', + address: + '0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7', + }, + ], + logo: 'https://api.rango.exchange/blockchains/starknet.svg', + displayName: 'StarkNet', + shortName: 'StarkNet', + sort: 8, + color: '#28286E', + enabled: true, + type: 'ZK_ROLLUP', + chainId: 'SN_MAIN', + info: null, + }, + FANTOM: { + name: 'FANTOM', + defaultDecimals: 18, + addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], + feeAssets: [{ blockchain: 'FANTOM', symbol: 'FTM', address: null }], + logo: 'https://api.rango.exchange/blockchains/fantom.png', + displayName: 'Fantom', + shortName: 'Fantom', + sort: 9, + color: '#337afe', + enabled: true, + type: 'EVM', + chainId: '0xfa', + info: { + chainName: 'Fantom Opera', + nativeCurrency: { name: 'FTM', symbol: 'FTM', decimals: 18 }, + rpcUrls: ['https://rpc.ftm.tools'], + blockExplorerUrls: ['https://ftmscan.com'], + addressUrl: 'https://ftmscan.com/address/{wallet}', + transactionUrl: 'https://ftmscan.com/tx/{txHash}', + }, + }, + OPTIMISM: { + name: 'OPTIMISM', + defaultDecimals: 18, + addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], + feeAssets: [{ blockchain: 'OPTIMISM', symbol: 'ETH', address: null }], + logo: 'https://api.rango.exchange/blockchains/optimism.svg', + displayName: 'Optimism', + shortName: 'Optimism', + sort: 10, + color: '#FF0420', + enabled: true, + type: 'EVM', + chainId: '0xa', + info: { + chainName: 'Optimism', + nativeCurrency: { name: 'ETH', symbol: 'ETH', decimals: 18 }, + rpcUrls: ['https://mainnet.optimism.io'], + blockExplorerUrls: ['https://optimistic.etherscan.io'], + addressUrl: 'https://optimistic.etherscan.io/address/{wallet}', + transactionUrl: 'https://optimistic.etherscan.io/tx/{txHash}', + }, + }, + SOLANA: { + name: 'SOLANA', + defaultDecimals: 9, + addressPatterns: ['^[1-9A-HJ-NP-Za-km-z]{32,44}$'], + feeAssets: [{ blockchain: 'SOLANA', symbol: 'SOL', address: null }], + logo: 'https://api.rango.exchange/blockchains/solana.svg', + displayName: 'Solana', + shortName: 'Solana', + sort: 11, + color: '#708DD2', + enabled: true, + type: 'SOLANA', + chainId: 'mainnet-beta', + info: null, + }, + OKC: { + name: 'OKC', + defaultDecimals: 18, + addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], + feeAssets: [{ blockchain: 'OKC', symbol: 'OKT', address: null }], + logo: 'https://api.rango.exchange/blockchains/okx.png', + displayName: 'OKX Chain (OKC)', + shortName: 'Okx', + sort: 11, + color: '#29a0f0', + enabled: true, + type: 'EVM', + chainId: '0x42', + info: { + chainName: 'OKX Chain', + nativeCurrency: { name: 'OKT', symbol: 'OKT', decimals: 18 }, + rpcUrls: ['https://exchainrpc.okex.org'], + blockExplorerUrls: ['https://www.oklink.com/en/okc'], + addressUrl: 'https://www.oklink.com/en/okc/address/{wallet}', + transactionUrl: 'https://www.oklink.com/en/okc/tx/{txHash}', + }, + }, + CRONOS: { + name: 'CRONOS', + defaultDecimals: 18, + addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], + feeAssets: [{ blockchain: 'CRONOS', symbol: 'CRO', address: null }], + logo: 'https://api.rango.exchange/blockchains/cronos.svg', + displayName: 'Cronos', + shortName: 'Cronos', + sort: 12, + color: '#1a90ff', + enabled: true, + type: 'EVM', + chainId: '0x19', + info: { + chainName: 'Cronos Mainnet Beta', + nativeCurrency: { name: 'CRO', symbol: 'CRO', decimals: 18 }, + rpcUrls: ['https://cronosrpc-1.xstaking.sg'], + blockExplorerUrls: ['https://cronoscan.com'], + addressUrl: 'https://cronoscan.com/address/{wallet}', + transactionUrl: 'https://cronoscan.com/tx/{txHash}', + }, + }, + MOONRIVER: { + name: 'MOONRIVER', + defaultDecimals: 18, + addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], + feeAssets: [{ blockchain: 'MOONRIVER', symbol: 'MOVR', address: null }], + logo: 'https://api.rango.exchange/blockchains/moonriver.svg', + displayName: 'MoonRiver', + shortName: 'MoonRiver', + sort: 13, + color: '#F3B404', + enabled: true, + type: 'EVM', + chainId: '0x505', + info: { + chainName: 'MoonRiver', + nativeCurrency: { name: 'MOVR', symbol: 'MOVR', decimals: 18 }, + rpcUrls: ['https://rpc.moonriver.moonbeam.network'], + blockExplorerUrls: ['https://moonriver.moonscan.io'], + addressUrl: 'https://moonriver.moonscan.io/address/{wallet}', + transactionUrl: 'https://moonriver.moonscan.io/tx/{txHash}', + }, + }, + MOONBEAM: { + name: 'MOONBEAM', + defaultDecimals: 18, + addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], + feeAssets: [{ blockchain: 'MOONBEAM', symbol: 'GLMR', address: null }], + logo: 'https://api.rango.exchange/blockchains/moonbeam.png', + displayName: 'MoonBeam', + shortName: 'MoonBeam', + sort: 14, + color: '#B3206B', + enabled: true, + type: 'EVM', + chainId: '0x504', + info: { + chainName: 'MoonBeam', + nativeCurrency: { name: 'GLMR', symbol: 'GLMR', decimals: 18 }, + rpcUrls: ['https://rpc.api.moonbeam.network'], + blockExplorerUrls: ['https://moonbeam.moonscan.io'], + addressUrl: 'https://moonbeam.moonscan.io/address/{wallet}', + transactionUrl: 'https://moonbeam.moonscan.io/tx/{txHash}', + }, + }, + HECO: { + name: 'HECO', + defaultDecimals: 18, + addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], + feeAssets: [{ blockchain: 'HECO', symbol: 'HT', address: null }], + logo: 'https://api.rango.exchange/blockchains/heco.png', + displayName: 'Heco', + shortName: 'Heco', + sort: 15, + color: '#4CA852', + enabled: true, + type: 'EVM', + chainId: '0x80', + info: { + chainName: 'Huobi ECO Chain Mainnet', + nativeCurrency: { name: 'HT', symbol: 'HT', decimals: 18 }, + rpcUrls: ['https://http-mainnet.hecochain.com'], + blockExplorerUrls: ['https://hecoinfo.com'], + addressUrl: 'https://hecoinfo.com/address/{wallet}', + transactionUrl: 'https://hecoinfo.com/tx/{txHash}', + }, + }, + AURORA: { + name: 'AURORA', + defaultDecimals: 18, + addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], + feeAssets: [{ blockchain: 'AURORA', symbol: 'ETH', address: null }], + logo: 'https://api.rango.exchange/blockchains/aurora.svg', + displayName: 'Aurora', + shortName: 'Aurora', + sort: 15, + color: '#78d64b', + enabled: true, + type: 'EVM', + chainId: '0x4e454152', + info: { + chainName: 'Aurora Mainnet', + nativeCurrency: { name: 'ETH', symbol: 'ETH', decimals: 18 }, + rpcUrls: ['https://mainnet.aurora.dev'], + blockExplorerUrls: ['https://explorer.mainnet.aurora.dev'], + addressUrl: 'https://explorer.mainnet.aurora.dev/address/{wallet}', + transactionUrl: 'https://explorer.mainnet.aurora.dev/tx/{txHash}', + }, + }, + HARMONY: { + name: 'HARMONY', + defaultDecimals: 18, + addressPatterns: ['^(one1)[0-9a-z]{38}$', '^(0x)[0-9A-Fa-f]{40}$'], + feeAssets: [{ blockchain: 'HARMONY', symbol: 'ONE', address: null }], + logo: 'https://api.rango.exchange/blockchains/harmony.svg', + displayName: 'Harmony', + shortName: 'Harmony', + sort: 15, + color: '#50AEE9', + enabled: true, + type: 'EVM', + chainId: '0x63564c40', + info: { + chainName: 'Harmony Mainnet', + nativeCurrency: { name: 'ONE', symbol: 'ONE', decimals: 18 }, + rpcUrls: ['https://api.s0.t.hmny.io'], + blockExplorerUrls: ['https://explorer.harmony.one'], + addressUrl: 'https://explorer.harmony.one/address/{wallet}', + transactionUrl: 'https://explorer.harmony.one/tx/{txHash}', + }, + }, + EVMOS: { + name: 'EVMOS', + defaultDecimals: 18, + addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], + feeAssets: [{ blockchain: 'EVMOS', symbol: 'EVMOS', address: null }], + logo: 'https://api.rango.exchange/blockchains/evmos.png', + displayName: 'Evmos', + shortName: 'Evmos', + sort: 15, + color: '#2D2925', + enabled: true, + type: 'EVM', + chainId: '0x2329', + info: { + chainName: 'Evmos', + nativeCurrency: { name: 'EVMOS', symbol: 'EVMOS', decimals: 18 }, + rpcUrls: ['https://eth.bd.evmos.org:8545'], + blockExplorerUrls: ['https://evm.evmos.org'], + addressUrl: 'https://evm.evmos.org/address/{wallet}', + transactionUrl: 'https://evm.evmos.org/tx/{txHash}', + }, + }, + SIF: { + name: 'SIF', + defaultDecimals: 18, + addressPatterns: ['^(sif1)[0-9a-z]{38}$'], + feeAssets: [{ blockchain: 'SIF', symbol: 'ROWAN', address: null }], + logo: 'https://api.rango.exchange/blockchains/sif.png', + displayName: 'Sifchain', + shortName: 'Sifchain', + sort: 16, + color: '#CAAA3A', + enabled: true, + type: 'COSMOS', + chainId: 'sifchain-1', + info: { + experimental: false, + rpc: 'https://rpc.sifchain.finance', + rest: 'https://api-int.sifchain.finance', + cosmostationLcdUrl: 'https://lcd-sifchain.cosmostation.io', + cosmostationApiUrl: 'https://api-sifchain.cosmostation.io', + cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', + mintScanName: 'sifchain', + chainName: 'Sifchain', + stakeCurrency: { + coinDenom: 'ROWAN', + coinMinimalDenom: 'rowan', + coinDecimals: 18, + coinGeckoId: '', + coinImageUrl: '', + }, + bip44: { coinType: 118 }, + bech32Config: { + bech32PrefixAccAddr: 'sif', + bech32PrefixAccPub: 'sifpub', + bech32PrefixValAddr: 'sifvaloper', + bech32PrefixValPub: 'sifvaloperpub', + bech32PrefixConsAddr: 'sifvalcons', + bech32PrefixConsPub: 'sifvalconspub', + }, + currencies: [ + { + coinDenom: 'ROWAN', + coinMinimalDenom: 'rowan', + coinDecimals: 18, + coinGeckoId: '', + coinImageUrl: '', + }, + ], + feeCurrencies: [ + { + coinDenom: 'ROWAN', + coinMinimalDenom: 'rowan', + coinDecimals: 18, + coinGeckoId: '', + coinImageUrl: '', + }, + ], + features: ['stargate', 'ibc-transfer'], + explorerUrlToTx: 'https://www.mintscan.io/sifchain/txs/{txHash}', + gasPriceStep: { + low: 1000000000000, + average: 1500000000000, + high: 2000000000000, + }, + }, + }, + THOR: { + name: 'THOR', + defaultDecimals: 8, + addressPatterns: ['^(thor1)[0-9a-z]{38}$'], + feeAssets: [{ blockchain: 'THOR', symbol: 'RUNE', address: null }], + logo: 'https://api.rango.exchange/blockchains/thorchain.svg', + displayName: 'Thorchain', + shortName: 'Thorchain', + sort: 17, + color: '#1AE6CB', + enabled: true, + type: 'TRANSFER', + chainId: null, + info: null, + }, + BNB: { + name: 'BNB', + defaultDecimals: 8, + addressPatterns: ['^(bnb1)[0-9a-z]{38}$'], + feeAssets: [{ blockchain: 'BNB', symbol: 'BNB', address: null }], + logo: 'https://api.rango.exchange/blockchains/bnb.svg', + displayName: 'Binance Chain', + shortName: 'BNB', + sort: 18, + color: '#F3BA2F', + enabled: true, + type: 'COSMOS', + chainId: null, + info: null, + }, + STARGAZE: { + name: 'STARGAZE', + defaultDecimals: 6, + addressPatterns: ['^(stars1)[0-9a-z]{38}$'], + feeAssets: [{ blockchain: 'STARGAZE', symbol: 'STARS', address: null }], + logo: 'https://api.rango.exchange/blockchains/stargaze.png', + displayName: 'Stargaze', + shortName: 'Stargaze', + sort: 19, + color: '#231B60', + enabled: true, + type: 'COSMOS', + chainId: 'stargaze-1', + info: { + experimental: false, + rpc: 'https://rpc.stargaze-apis.com', + rest: 'https://rest.stargaze-apis.com', + cosmostationLcdUrl: 'https://lcd-stargaze.cosmostation.io', + cosmostationApiUrl: 'https://api-stargaze.cosmostation.io', + cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', + mintScanName: 'stargaze', + chainName: 'Stargaze', + stakeCurrency: { + coinDenom: 'STARS', + coinMinimalDenom: 'ustars', + coinDecimals: 6, + coinGeckoId: 'pool:ustars', + coinImageUrl: '/tokens/blockchain/STARS.png', + }, + bip44: { coinType: 118 }, + bech32Config: { + bech32PrefixAccAddr: 'stars', + bech32PrefixAccPub: 'starspub', + bech32PrefixValAddr: 'starsvaloper', + bech32PrefixValPub: 'starsvaloperpub', + bech32PrefixConsAddr: 'starsvalcons', + bech32PrefixConsPub: 'starsvalconspub', + }, + currencies: [ + { + coinDenom: 'STARS', + coinMinimalDenom: 'ustars', + coinDecimals: 6, + coinGeckoId: 'pool:ustars', + coinImageUrl: '/tokens/blockchain/STARS.png', + }, + ], + feeCurrencies: [ + { + coinDenom: 'STARS', + coinMinimalDenom: 'ustars', + coinDecimals: 6, + coinGeckoId: 'pool:ustars', + coinImageUrl: '/tokens/blockchain/STARS.png', + }, + ], + features: ['stargate', 'ibc-transfer', 'no-legacy-stdTx'], + explorerUrlToTx: 'https://www.mintscan.io/stargaze/txs/{txHash}', + gasPriceStep: { low: 1, average: 1, high: 1 }, + }, + }, + BTC: { + name: 'BTC', + defaultDecimals: 8, + addressPatterns: [ + '^[13][a-km-zA-HJ-NP-Z1-9]{25,34}$|^(bc1)[0-9A-Za-z]{39,59}$', + ], + feeAssets: [{ blockchain: 'BTC', symbol: 'BTC', address: null }], + logo: 'https://api.rango.exchange/blockchains/btc.svg', + displayName: 'Bitcoin', + shortName: 'BTC', + sort: 20, + color: '#F7931A', + enabled: true, + type: 'TRANSFER', + chainId: null, + info: null, + }, + CRYPTO_ORG: { + name: 'CRYPTO_ORG', + defaultDecimals: 8, + addressPatterns: ['^(cro1)[0-9a-z]{38}$'], + feeAssets: [{ blockchain: 'CRYPTO_ORG', symbol: 'CRO', address: null }], + logo: 'https://api.rango.exchange/blockchains/crypto_org.png', + displayName: 'Crypto.org', + shortName: 'Crypto.org', + sort: 21, + color: '#103F68', + enabled: true, + type: 'COSMOS', + chainId: 'crypto-org-chain-mainnet-1', + info: { + experimental: false, + rpc: 'https://rpc-crypto-org.keplr.app', + rest: 'https://lcd-crypto-org.keplr.app', + cosmostationLcdUrl: 'https://lcd-cryptocom.cosmostation.io', + cosmostationApiUrl: 'https://api-cryptocom.cosmostation.io', + cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', + mintScanName: 'crypto-org', + chainName: 'Crypto.org', + stakeCurrency: { + coinDenom: 'CRO', + coinMinimalDenom: 'basecro', + coinDecimals: 8, + coinGeckoId: 'crypto-com-chain', + coinImageUrl: '/tokens/blockchain/cro.png', + }, + bip44: { coinType: 394 }, + bech32Config: { + bech32PrefixAccAddr: 'cro', + bech32PrefixAccPub: 'cropub', + bech32PrefixValAddr: 'crovaloper', + bech32PrefixValPub: 'crovaloperpub', + bech32PrefixConsAddr: 'crovalcons', + bech32PrefixConsPub: 'crovalconspub', + }, + currencies: [ + { + coinDenom: 'CRO', + coinMinimalDenom: 'basecro', + coinDecimals: 8, + coinGeckoId: 'crypto-com-chain', + coinImageUrl: '/tokens/blockchain/cro.png', + }, + ], + feeCurrencies: [ + { + coinDenom: 'CRO', + coinMinimalDenom: 'basecro', + coinDecimals: 8, + coinGeckoId: 'crypto-com-chain', + coinImageUrl: '/tokens/blockchain/cro.png', + }, + ], + features: ['stargate', 'ibc-transfer'], + explorerUrlToTx: 'https://www.mintscan.io/crypto-org/txs/{txHash}', + gasPriceStep: { low: 0.025, average: 0.03, high: 0.04 }, + }, + }, + CHIHUAHUA: { + name: 'CHIHUAHUA', + defaultDecimals: 6, + addressPatterns: ['^(chihuahua1)[0-9a-z]{38}$'], + feeAssets: [{ blockchain: 'CHIHUAHUA', symbol: 'HUAHUA', address: null }], + logo: 'https://api.rango.exchange/blockchains/chihuahua.png', + displayName: 'Chihuahua', + shortName: 'Chihuahua', + sort: 22, + color: '#EFC92B', + enabled: true, + type: 'COSMOS', + chainId: 'chihuahua-1', + info: { + experimental: true, + rpc: 'https://rpc.chihuahua.wtf/', + rest: 'https://api.chihuahua.wtf/', + cosmostationLcdUrl: 'https://lcd-chihuahua.cosmostation.io', + cosmostationApiUrl: 'https://api-chihuahua.cosmostation.io', + cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', + mintScanName: 'chihuahua', + chainName: 'Chihuahua', + stakeCurrency: { + coinDenom: 'HUAHUA', + coinMinimalDenom: 'uhuahua', + coinDecimals: 6, + coinGeckoId: 'pool:uhuahua', + coinImageUrl: '/tokens/blockchain/HUAHUA.svg', + }, + bip44: { coinType: 118 }, + bech32Config: { + bech32PrefixAccAddr: 'chihuahua', + bech32PrefixAccPub: 'chihuahuapub', + bech32PrefixValAddr: 'chihuahuavaloper', + bech32PrefixValPub: 'chihuahuavaloperpub', + bech32PrefixConsAddr: 'chihuahuavalcons', + bech32PrefixConsPub: 'chihuahuavalconspub', + }, + currencies: [ + { + coinDenom: 'HUAHUA', + coinMinimalDenom: 'uhuahua', + coinDecimals: 6, + coinGeckoId: 'pool:uhuahua', + coinImageUrl: '/tokens/blockchain/HUAHUA.svg', + }, + ], + feeCurrencies: [ + { + coinDenom: 'HUAHUA', + coinMinimalDenom: 'uhuahua', + coinDecimals: 6, + coinGeckoId: 'pool:uhuahua', + coinImageUrl: '/tokens/blockchain/HUAHUA.svg', + }, + ], + features: ['stargate', 'ibc-transfer', 'no-legacy-stdTx'], + explorerUrlToTx: 'https://ping.pub/chihuahua/tx/{txHash}', + gasPriceStep: { low: 0.025, average: 0.03, high: 0.035 }, + }, + }, + BANDCHAIN: { + name: 'BANDCHAIN', + defaultDecimals: 6, + addressPatterns: ['^(band1)[0-9a-z]{38}$'], + feeAssets: [{ blockchain: 'BANDCHAIN', symbol: 'BAND', address: null }], + logo: 'https://api.rango.exchange/blockchains/bandchain.svg', + displayName: 'BandChain', + shortName: 'BandChain', + sort: 23, + color: '#4520E6', + enabled: true, + type: 'COSMOS', + chainId: 'laozi-mainnet', + info: { + experimental: true, + rpc: 'https://rpc.laozi3.bandchain.org/', + rest: 'https://lcd-band.cosmostation.io', + cosmostationLcdUrl: 'https://lcd-band.cosmostation.io', + cosmostationApiUrl: 'https://api-band.cosmostation.io', + cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', + mintScanName: 'band', + chainName: 'BandChain', + stakeCurrency: { + coinDenom: 'BAND', + coinMinimalDenom: 'uband', + coinDecimals: 6, + coinGeckoId: 'band-protocol', + coinImageUrl: '/tokens/blockchain/BAND.svg', + }, + bip44: { coinType: 494 }, + bech32Config: { + bech32PrefixAccAddr: 'band', + bech32PrefixAccPub: 'bandpub', + bech32PrefixValAddr: 'bandvaloper', + bech32PrefixValPub: 'bandvaloperpub', + bech32PrefixConsAddr: 'bandvalcons', + bech32PrefixConsPub: 'bandvalconspub', + }, + currencies: [ + { + coinDenom: 'BAND', + coinMinimalDenom: 'uband', + coinDecimals: 6, + coinGeckoId: 'band-protocol', + coinImageUrl: '/tokens/blockchain/BAND.svg', + }, + ], + feeCurrencies: [ + { + coinDenom: 'BAND', + coinMinimalDenom: 'uband', + coinDecimals: 6, + coinGeckoId: 'band-protocol', + coinImageUrl: '/tokens/blockchain/BAND.svg', + }, + ], + features: ['stargate', 'ibc-transfer', 'no-legacy-stdTx'], + explorerUrlToTx: 'https://cosmoscan.io/tx/{txHash}', + gasPriceStep: null, + }, + }, + COMDEX: { + name: 'COMDEX', + defaultDecimals: 6, + addressPatterns: ['^(comdex1)[0-9a-z]{38}$'], + feeAssets: [{ blockchain: 'COMDEX', symbol: 'CMDX', address: null }], + logo: 'https://api.rango.exchange/blockchains/comdex.svg', + displayName: 'Comdex', + shortName: 'Comdex', + sort: 23, + color: '#FE4350', + enabled: true, + type: 'COSMOS', + chainId: 'comdex-1', + info: { + experimental: true, + rpc: 'https://rpc.comdex.one', + rest: 'https://rest.comdex.one', + cosmostationLcdUrl: 'https://lcd-comdex.cosmostation.io', + cosmostationApiUrl: 'https://api-comdex.cosmostation.io', + cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', + mintScanName: 'comdex', + chainName: 'Comdex', + stakeCurrency: { + coinDenom: 'CMDX', + coinMinimalDenom: 'ucmdx', + coinDecimals: 6, + coinGeckoId: 'comdex', + coinImageUrl: '/tokens/blockchain/CMDX.png', + }, + bip44: { coinType: 118 }, + bech32Config: { + bech32PrefixAccAddr: 'comdex', + bech32PrefixAccPub: 'comdexpub', + bech32PrefixValAddr: 'comdexvaloper', + bech32PrefixValPub: 'comdexvaloperpub', + bech32PrefixConsAddr: 'comdexvalcons', + bech32PrefixConsPub: 'comdexvalconspub', + }, + currencies: [ + { + coinDenom: 'CMDX', + coinMinimalDenom: 'ucmdx', + coinDecimals: 6, + coinGeckoId: 'comdex', + coinImageUrl: '/tokens/blockchain/CMDX.png', + }, + ], + feeCurrencies: [ + { + coinDenom: 'CMDX', + coinMinimalDenom: 'ucmdx', + coinDecimals: 6, + coinGeckoId: 'comdex', + coinImageUrl: '/tokens/blockchain/CMDX.png', + }, + ], + features: ['stargate', 'ibc-transfer', 'no-legacy-stdTx'], + explorerUrlToTx: 'https://www.mintscan.io/comdex/txs/{txHash}', + gasPriceStep: null, + }, + }, + REGEN: { + name: 'REGEN', + defaultDecimals: 6, + addressPatterns: ['^(regen1)[0-9a-z]{38}$'], + feeAssets: [{ blockchain: 'REGEN', symbol: 'REGEN', address: null }], + logo: 'https://api.rango.exchange/blockchains/regen.png', + displayName: 'Regen Network', + shortName: 'Regen Network', + sort: 24, + color: '#4FB573', + enabled: true, + type: 'COSMOS', + chainId: 'regen-1', + info: { + experimental: false, + rpc: 'https://rpc-regen.keplr.app', + rest: 'https://lcd-regen.keplr.app', + cosmostationLcdUrl: 'https://lcd-regen.keplr.app', + cosmostationApiUrl: 'https://api-regen.cosmostation.io/', + cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', + mintScanName: 'regen', + chainName: 'Regen Network', + stakeCurrency: { + coinDenom: 'REGEN', + coinMinimalDenom: 'uregen', + coinDecimals: 6, + coinGeckoId: 'pool:uregen', + coinImageUrl: '/tokens/blockchain/regen.png', + }, + bip44: { coinType: 118 }, + bech32Config: { + bech32PrefixAccAddr: 'regen', + bech32PrefixAccPub: 'regenpub', + bech32PrefixValAddr: 'regenvaloper', + bech32PrefixValPub: 'regenvaloperpub', + bech32PrefixConsAddr: 'regenvalcons', + bech32PrefixConsPub: 'regenvalconspub', + }, + currencies: [ + { + coinDenom: 'REGEN', + coinMinimalDenom: 'uregen', + coinDecimals: 6, + coinGeckoId: 'pool:uregen', + coinImageUrl: '/tokens/blockchain/regen.png', + }, + ], + feeCurrencies: [ + { + coinDenom: 'REGEN', + coinMinimalDenom: 'uregen', + coinDecimals: 6, + coinGeckoId: 'pool:uregen', + coinImageUrl: '/tokens/blockchain/regen.png', + }, + ], + features: ['stargate', 'ibc-transfer'], + explorerUrlToTx: 'https://regen.aneka.io/txs/{txHash}', + gasPriceStep: { low: 0.015, average: 0.025, high: 0.04 }, + }, + }, + IRIS: { + name: 'IRIS', + defaultDecimals: 6, + addressPatterns: ['^(iaa1)[0-9a-z]{38}$'], + feeAssets: [{ blockchain: 'IRIS', symbol: 'IRIS', address: null }], + logo: 'https://api.rango.exchange/blockchains/iris.png', + displayName: 'IRISnet', + shortName: 'IRISnet', + sort: 25, + color: '#8A4A8E', + enabled: true, + type: 'COSMOS', + chainId: 'irishub-1', + info: { + experimental: false, + rpc: 'https://rpc-iris.keplr.app', + rest: 'https://lcd-iris.keplr.app', + cosmostationLcdUrl: 'https://lcd-iris.cosmostation.io', + cosmostationApiUrl: 'https://api-iris.cosmostation.io', + cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', + mintScanName: 'iris', + chainName: 'IRISnet', + stakeCurrency: { + coinDenom: 'IRIS', + coinMinimalDenom: 'uiris', + coinDecimals: 6, + coinGeckoId: 'iris-network', + coinImageUrl: '/tokens/blockchain/iris.svg', + }, + bip44: { coinType: 118 }, + bech32Config: { + bech32PrefixAccAddr: 'iaa', + bech32PrefixAccPub: 'iaapub', + bech32PrefixValAddr: 'iaavaloper', + bech32PrefixValPub: 'iaavaloperpub', + bech32PrefixConsAddr: 'iaavalcons', + bech32PrefixConsPub: 'iaavalconspub', + }, + currencies: [ + { + coinDenom: 'IRIS', + coinMinimalDenom: 'uiris', + coinDecimals: 6, + coinGeckoId: 'iris-network', + coinImageUrl: '/tokens/blockchain/iris.svg', + }, + ], + feeCurrencies: [ + { + coinDenom: 'IRIS', + coinMinimalDenom: 'uiris', + coinDecimals: 6, + coinGeckoId: 'iris-network', + coinImageUrl: '/tokens/blockchain/iris.svg', + }, + ], + features: ['stargate', 'ibc-transfer'], + explorerUrlToTx: 'https://www.mintscan.io/iris/txs/{txHash}', + gasPriceStep: { low: 0.2, average: 0.3, high: 0.4 }, + }, + }, + EMONEY: { + name: 'EMONEY', + defaultDecimals: 6, + addressPatterns: ['^(emoney1)[0-9a-z]{38}$'], + feeAssets: [{ blockchain: 'EMONEY', symbol: 'NGM', address: null }], + logo: 'https://api.rango.exchange/blockchains/emoney.svg', + displayName: 'e-Money', + shortName: 'e-Money', + sort: 25, + color: '#DFF5EF', + enabled: true, + type: 'COSMOS', + chainId: 'emoney-3', + info: { + experimental: true, + rpc: 'https://rpc-emoney.keplr.app', + rest: 'https://lcd-emoney.keplr.app', + cosmostationLcdUrl: 'https://lcd-emoney.cosmostation.io', + cosmostationApiUrl: 'https://api-emoney.cosmostation.io', + cosmostationDenomTracePath: + '/ibc/applications/transfer/v1beta1/denom_traces/', + mintScanName: 'emoney', + chainName: 'e-Money', + stakeCurrency: { + coinDenom: 'NGM', + coinMinimalDenom: 'ungm', + coinDecimals: 6, + coinGeckoId: 'e-money', + coinImageUrl: '/tokens/blockchain/NGM.png', + }, + bip44: { coinType: 118 }, + bech32Config: { + bech32PrefixAccAddr: 'emoney', + bech32PrefixAccPub: 'emoneypub', + bech32PrefixValAddr: 'emoneyvaloper', + bech32PrefixValPub: 'emoneyvaloperpub', + bech32PrefixConsAddr: 'emoneyvalcons', + bech32PrefixConsPub: 'emoneyvalconspub', + }, + currencies: [ + { + coinDenom: 'NGM', + coinMinimalDenom: 'ungm', + coinDecimals: 6, + coinGeckoId: 'e-money', + coinImageUrl: '/tokens/blockchain/NGM.png', + }, + { + coinDenom: 'EEUR', + coinMinimalDenom: 'eeur', + coinDecimals: 6, + coinGeckoId: 'e-money-eur', + coinImageUrl: '/tokens/blockchain/EEUR.png', + }, + ], + feeCurrencies: [ + { + coinDenom: 'NGM', + coinMinimalDenom: 'ungm', + coinDecimals: 6, + coinGeckoId: 'e-money', + coinImageUrl: '/tokens/blockchain/NGM.png', + }, + ], + features: ['stargate', 'ibc-transfer'], + explorerUrlToTx: 'https://emoney.bigdipper.live/transactions/{txHash}', + gasPriceStep: { low: 1, average: 1, high: 1 }, + }, + }, + GNOSIS: { + name: 'GNOSIS', + defaultDecimals: 18, + addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], + feeAssets: [{ blockchain: 'GNOSIS', symbol: 'XDAI', address: null }], + logo: 'https://api.rango.exchange/blockchains/gnosis.svg', + displayName: 'Gnosis', + shortName: 'Gnosis', + sort: 26, + color: '#3E6957', + enabled: true, + type: 'EVM', + chainId: '0x64', + info: { + chainName: 'Gnosis Chain', + nativeCurrency: { name: 'XDAI', symbol: 'XDAI', decimals: 18 }, + rpcUrls: ['https://rpc.gnosischain.com'], + blockExplorerUrls: ['https://blockscout.com/xdai/mainnet'], + addressUrl: 'https://blockscout.com/xdai/mainnet/address/{wallet}', + transactionUrl: 'https://blockscout.com/xdai/mainnet/tx/{txHash}', + }, + }, + LTC: { + name: 'LTC', + defaultDecimals: 8, + addressPatterns: ['^(L|M|3)[A-Za-z0-9]{33}$|^(ltc1)[0-9A-Za-z]{39}$'], + feeAssets: [{ blockchain: 'LTC', symbol: 'LTC', address: null }], + logo: 'https://api.rango.exchange/blockchains/ltc.svg', + displayName: 'LiteCoin', + shortName: 'LTC', + sort: 27, + color: '#345D9D', + enabled: true, + type: 'TRANSFER', + chainId: null, + info: null, + }, + BCH: { + name: 'BCH', + defaultDecimals: 8, + addressPatterns: [ + '^[13][a-km-zA-HJ-NP-Z1-9]{25,34}$|^[0-9A-Za-z]{42,42}$', + ], + feeAssets: [{ blockchain: 'BCH', symbol: 'BCH', address: null }], + logo: 'https://api.rango.exchange/blockchains/bch.svg', + displayName: 'Bitcoin Cash', + shortName: 'BCH', + sort: 28, + color: '#0AC18E', + enabled: true, + type: 'TRANSFER', + chainId: null, + info: null, + }, + FUSE: { + name: 'FUSE', + defaultDecimals: 18, + addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], + feeAssets: [{ blockchain: 'FUSE', symbol: 'FUSE', address: null }], + logo: 'https://api.rango.exchange/blockchains/fuse.png', + displayName: 'Fuse', + shortName: 'Fuse', + sort: 29, + color: '#C5F9AD', + enabled: true, + type: 'EVM', + chainId: '0x7a', + info: { + chainName: 'Fuse Mainnet', + nativeCurrency: { name: 'FUSE', symbol: 'FUSE', decimals: 18 }, + rpcUrls: ['https://rpc.fuse.io'], + blockExplorerUrls: ['https://explorer.fuse.io'], + addressUrl: 'https://explorer.fuse.io/address/{wallet}', + transactionUrl: 'https://explorer.fuse.io/tx/{txHash}', + }, + }, + AKASH: { + name: 'AKASH', + defaultDecimals: 6, + addressPatterns: ['^(akash1)[0-9a-z]{38}$'], + feeAssets: [{ blockchain: 'AKASH', symbol: 'AKT', address: null }], + logo: 'https://api.rango.exchange/blockchains/akash.svg', + displayName: 'Akash', + shortName: 'Akash', + sort: 30, + color: '#ED3524', + enabled: true, + type: 'COSMOS', + chainId: 'akashnet-2', + info: { + experimental: false, + rpc: 'https://rpc-akash.keplr.app', + rest: 'https://lcd-akash.keplr.app', + cosmostationLcdUrl: 'https://lcd-akash.cosmostation.io', + cosmostationApiUrl: 'https://api-akash.cosmostation.io', + cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', + mintScanName: 'akash', + chainName: 'Akash', + stakeCurrency: { + coinDenom: 'AKT', + coinMinimalDenom: 'uakt', + coinDecimals: 6, + coinGeckoId: 'akash-network', + coinImageUrl: '/tokens/blockchain/akt.svg', + }, + bip44: { coinType: 118 }, + bech32Config: { + bech32PrefixAccAddr: 'akash', + bech32PrefixAccPub: 'akashpub', + bech32PrefixValAddr: 'akashvaloper', + bech32PrefixValPub: 'akashvaloperpub', + bech32PrefixConsAddr: 'akashvalcons', + bech32PrefixConsPub: 'akashvalconspub', + }, + currencies: [ + { + coinDenom: 'AKT', + coinMinimalDenom: 'uakt', + coinDecimals: 6, + coinGeckoId: 'akash-network', + coinImageUrl: '/tokens/blockchain/akt.svg', + }, + ], + feeCurrencies: [ + { + coinDenom: 'AKT', + coinMinimalDenom: 'uakt', + coinDecimals: 6, + coinGeckoId: 'akash-network', + coinImageUrl: '/tokens/blockchain/akt.svg', + }, + ], + features: ['stargate', 'ibc-transfer'], + explorerUrlToTx: 'https://www.mintscan.io/akash/txs/{txHash}', + gasPriceStep: { low: 0.001, average: 0.0025, high: 0.004 }, + }, + }, + KI: { + name: 'KI', + defaultDecimals: 6, + addressPatterns: ['^(ki1)[0-9a-z]{38}$'], + feeAssets: [{ blockchain: 'KI', symbol: 'XKI', address: null }], + logo: 'https://api.rango.exchange/blockchains/ki.png', + displayName: 'Ki', + shortName: 'Ki', + sort: 30, + color: '#0F2B3D', + enabled: true, + type: 'COSMOS', + chainId: 'kichain-2', + info: { + experimental: true, + rpc: 'https://rpc-mainnet.blockchain.ki', + rest: 'https://api-mainnet.blockchain.ki', + cosmostationLcdUrl: 'https://lcd-kichain.cosmostation.io', + cosmostationApiUrl: 'https://api-kichain.cosmostation.io', + cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', + mintScanName: 'ki-chain', + chainName: 'Ki', + stakeCurrency: { + coinDenom: 'XKI', + coinMinimalDenom: 'uxki', + coinDecimals: 6, + coinGeckoId: 'pool:uxki', + coinImageUrl: '/tokens/blockchain/XKI.png', + }, + bip44: { coinType: 118 }, + bech32Config: { + bech32PrefixAccAddr: 'ki', + bech32PrefixAccPub: 'kipub', + bech32PrefixValAddr: 'kivaloper', + bech32PrefixValPub: 'kivaloperpub', + bech32PrefixConsAddr: 'kivalcons', + bech32PrefixConsPub: 'kivalconspub', + }, + currencies: [ + { + coinDenom: 'XKI', + coinMinimalDenom: 'uxki', + coinDecimals: 6, + coinGeckoId: 'pool:uxki', + coinImageUrl: '/tokens/blockchain/XKI.png', + }, + ], + feeCurrencies: [ + { + coinDenom: 'XKI', + coinMinimalDenom: 'uxki', + coinDecimals: 6, + coinGeckoId: 'pool:uxki', + coinImageUrl: '/tokens/blockchain/XKI.png', + }, + ], + features: ['stargate', 'ibc-transfer'], + explorerUrlToTx: 'https://www.mintscan.io/ki-chain/txs/{txHash}', + gasPriceStep: null, + }, + }, + KUJIRA: { + name: 'KUJIRA', + defaultDecimals: 6, + addressPatterns: ['^(kujira1)[0-9a-z]{38}$'], + feeAssets: [{ blockchain: 'KUJIRA', symbol: 'KUJI', address: null }], + logo: 'https://api.rango.exchange/blockchains/kuji.svg', + displayName: 'Kujira', + shortName: 'Kujira', + sort: 31, + color: '#DF3935', + enabled: true, + type: 'COSMOS', + chainId: 'kaiyo-1', + info: { + experimental: true, + rpc: 'https://rpc.kaiyo.kujira.setten.io', + rest: 'https://lcd.kaiyo.kujira.setten.io', + cosmostationLcdUrl: 'https://lcd-kujira.cosmostation.io', + cosmostationApiUrl: 'https://api-kujira.cosmostation.io', + cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', + mintScanName: 'kujira', + chainName: 'Kujira', + stakeCurrency: { + coinDenom: 'KUJI', + coinMinimalDenom: 'ukuji', + coinDecimals: 6, + coinGeckoId: 'kujira', + coinImageUrl: '/tokens/blockchain/kuji.svg', + }, + bip44: { coinType: 118 }, + bech32Config: { + bech32PrefixAccAddr: 'kujira', + bech32PrefixAccPub: 'kujirapub', + bech32PrefixValAddr: 'kujiravaloper', + bech32PrefixValPub: 'kujiravaloperpub', + bech32PrefixConsAddr: 'kujiravalcons', + bech32PrefixConsPub: 'kujiravalconspub', + }, + currencies: [ + { + coinDenom: 'KUJI', + coinMinimalDenom: 'ukuji', + coinDecimals: 6, + coinGeckoId: 'kujira', + coinImageUrl: '/tokens/blockchain/kuji.png', + }, + ], + feeCurrencies: [ + { + coinDenom: 'KUJI', + coinMinimalDenom: 'ukuji', + coinDecimals: 6, + coinGeckoId: 'kujira', + coinImageUrl: '/tokens/blockchain/kuji.png', + }, + ], + features: ['stargate', 'ibc-transfer'], + explorerUrlToTx: 'https://finder.kujira.app/kaiyo-1/tx/{txHash}', + gasPriceStep: { low: 0.01, average: 0.025, high: 0.03 }, + }, + }, + PERSISTENCE: { + name: 'PERSISTENCE', + defaultDecimals: 6, + addressPatterns: ['^(persistence1)[0-9a-z]{38}$'], + feeAssets: [{ blockchain: 'PERSISTENCE', symbol: 'XPRT', address: null }], + logo: 'https://api.rango.exchange/blockchains/persistence.png', + displayName: 'Persistence', + shortName: 'Persistence', + sort: 31, + color: '#383838', + enabled: true, + type: 'COSMOS', + chainId: 'core-1', + info: { + experimental: false, + rpc: 'https://rpc-persistence.keplr.app', + rest: 'https://lcd-persistence.keplr.app', + cosmostationLcdUrl: 'https://lcd-persistence.cosmostation.io', + cosmostationApiUrl: 'https://api-persistence.cosmostation.io', + cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', + mintScanName: 'persistence', + chainName: 'Persistence', + stakeCurrency: { + coinDenom: 'XPRT', + coinMinimalDenom: 'uxprt', + coinDecimals: 6, + coinGeckoId: 'persistence', + coinImageUrl: '/tokens/blockchain/xprt.png', + }, + bip44: { coinType: 750 }, + bech32Config: { + bech32PrefixAccAddr: 'persistence', + bech32PrefixAccPub: 'persistencepub', + bech32PrefixValAddr: 'persistencevaloper', + bech32PrefixValPub: 'persistencevaloperpub', + bech32PrefixConsAddr: 'persistencevalcons', + bech32PrefixConsPub: 'persistencevalconspub', + }, + currencies: [ + { + coinDenom: 'XPRT', + coinMinimalDenom: 'uxprt', + coinDecimals: 6, + coinGeckoId: 'persistence', + coinImageUrl: '/tokens/blockchain/xprt.png', + }, + ], + feeCurrencies: [ + { + coinDenom: 'XPRT', + coinMinimalDenom: 'uxprt', + coinDecimals: 6, + coinGeckoId: 'persistence', + coinImageUrl: '/tokens/blockchain/xprt.png', + }, + ], + features: ['stargate', 'ibc-transfer'], + explorerUrlToTx: 'https://www.mintscan.io/persistence/txs/{txHash}', + gasPriceStep: { low: 0, average: 0.025, high: 0.04 }, + }, + }, + SENTINEL: { + name: 'SENTINEL', + defaultDecimals: 6, + addressPatterns: ['^(sent1)[0-9a-z]{38}$'], + feeAssets: [{ blockchain: 'SENTINEL', symbol: 'DVPN', address: null }], + logo: 'https://api.rango.exchange/blockchains/sentinel.png', + displayName: 'Sentinel', + shortName: 'Sentinel', + sort: 32, + color: '#142E51', + enabled: true, + type: 'COSMOS', + chainId: 'sentinelhub-2', + info: { + experimental: false, + rpc: 'https://rpc-sentinel.keplr.app', + rest: 'https://lcd-sentinel.keplr.app', + cosmostationLcdUrl: 'https://lcd-sentinel.cosmostation.io', + cosmostationApiUrl: 'https://api-sentinel.cosmostation.io', + cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', + mintScanName: 'sentinel', + chainName: 'Sentinel', + stakeCurrency: { + coinDenom: 'DVPN', + coinMinimalDenom: 'udvpn', + coinDecimals: 6, + coinGeckoId: 'sentinel', + coinImageUrl: '/tokens/blockchain/dvpn.png', + }, + bip44: { coinType: 118 }, + bech32Config: { + bech32PrefixAccAddr: 'sent', + bech32PrefixAccPub: 'sentpub', + bech32PrefixValAddr: 'sentvaloper', + bech32PrefixValPub: 'sentvaloperpub', + bech32PrefixConsAddr: 'sentvalcons', + bech32PrefixConsPub: 'sentvalconspub', + }, + currencies: [ + { + coinDenom: 'DVPN', + coinMinimalDenom: 'udvpn', + coinDecimals: 6, + coinGeckoId: 'sentinel', + coinImageUrl: '/tokens/blockchain/dvpn.png', + }, + ], + feeCurrencies: [ + { + coinDenom: 'DVPN', + coinMinimalDenom: 'udvpn', + coinDecimals: 6, + coinGeckoId: 'sentinel', + coinImageUrl: '/tokens/blockchain/dvpn.png', + }, + ], + features: ['stargate', 'ibc-transfer'], + explorerUrlToTx: 'https://www.mintscan.io/sentinel/txs/{txHash}', + gasPriceStep: { low: 0.1, average: 0.25, high: 0.4 }, + }, + }, + STARNAME: { + name: 'STARNAME', + defaultDecimals: 6, + addressPatterns: ['^(star1)[0-9a-z]{38}$'], + feeAssets: [{ blockchain: 'STARNAME', symbol: 'IOV', address: null }], + logo: 'https://api.rango.exchange/blockchains/starname.png', + displayName: 'Starname', + shortName: 'Starname', + sort: 35, + color: '#BC64BB', + enabled: true, + type: 'COSMOS', + chainId: 'iov-mainnet-ibc', + info: { + experimental: false, + rpc: 'https://rpc-iov.keplr.app', + rest: 'https://lcd-iov.keplr.app', + cosmostationLcdUrl: 'https://lcd-iov.cosmostation.io', + cosmostationApiUrl: 'https://api-iov.cosmostation.io', + cosmostationDenomTracePath: + '/ibc/applications/transfer/v1beta1/denom_traces/', + mintScanName: 'starname', + chainName: 'Starname', + stakeCurrency: { + coinDenom: 'IOV', + coinMinimalDenom: 'uiov', + coinDecimals: 6, + coinGeckoId: 'starname', + coinImageUrl: '/tokens/blockchain/IOV.png', + }, + bip44: { coinType: 494 }, + bech32Config: { + bech32PrefixAccAddr: 'star', + bech32PrefixAccPub: 'starpub', + bech32PrefixValAddr: 'starvaloper', + bech32PrefixValPub: 'starvaloperpub', + bech32PrefixConsAddr: 'starvalcons', + bech32PrefixConsPub: 'starvalconspub', + }, + currencies: [ + { + coinDenom: 'IOV', + coinMinimalDenom: 'uiov', + coinDecimals: 6, + coinGeckoId: 'starname', + coinImageUrl: '/tokens/blockchain/IOV.png', + }, + ], + feeCurrencies: [ + { + coinDenom: 'IOV', + coinMinimalDenom: 'uiov', + coinDecimals: 6, + coinGeckoId: 'starname', + coinImageUrl: '/tokens/blockchain/IOV.png', + }, + ], + features: ['stargate', 'ibc-transfer'], + explorerUrlToTx: 'https://www.mintscan.io/starname/txs/{txHash}', + gasPriceStep: { low: 1, average: 2, high: 3 }, + }, + }, + UMEE: { + name: 'UMEE', + defaultDecimals: 6, + addressPatterns: ['^(umee1)[0-9a-z]{38}$'], + feeAssets: [{ blockchain: 'UMEE', symbol: 'UMEE', address: null }], + logo: 'https://api.rango.exchange/blockchains/umee.svg', + displayName: 'Umee', + shortName: 'Umee', + sort: 36, + color: '#D2B6FF', + enabled: true, + type: 'COSMOS', + chainId: 'umee-1', + info: { + experimental: false, + rpc: 'https://api.barnacle.mainnet.network.umee.cc', + rest: 'https://lcd-umee.cosmostation.io', + cosmostationLcdUrl: 'https://lcd-umee.cosmostation.io', + cosmostationApiUrl: 'https://api-umee.cosmostation.io', + cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', + mintScanName: 'umee', + chainName: 'Umee', + stakeCurrency: { + coinDenom: 'UMEE', + coinMinimalDenom: 'uumee', + coinDecimals: 6, + coinGeckoId: 'pool:uumee', + coinImageUrl: '/tokens/blockchain/UMEE.png', + }, + bip44: { coinType: 118 }, + bech32Config: { + bech32PrefixAccAddr: 'umee', + bech32PrefixAccPub: 'umeepub', + bech32PrefixValAddr: 'umeevaloper', + bech32PrefixValPub: 'umeevaloperpub', + bech32PrefixConsAddr: 'umeevalcons', + bech32PrefixConsPub: 'umeevalconspub', + }, + currencies: [ + { + coinDenom: 'UMEE', + coinMinimalDenom: 'uumee', + coinDecimals: 6, + coinGeckoId: 'pool:uumee', + coinImageUrl: '/tokens/blockchain/UMEE.png', + }, + ], + feeCurrencies: [ + { + coinDenom: 'UMEE', + coinMinimalDenom: 'uumee', + coinDecimals: 6, + coinGeckoId: 'pool:uumee', + coinImageUrl: '/tokens/blockchain/UMEE.png', + }, + ], + features: ['stargate', 'ibc-transfer', 'no-legacy-stdTx'], + explorerUrlToTx: 'https://www.mintscan.io/umee/txs/{txHash}', + gasPriceStep: { low: 0.05, average: 0.06, high: 0.1 }, + }, + }, + BITCANNA: { + name: 'BITCANNA', + defaultDecimals: 6, + addressPatterns: ['^(bcna1)[0-9a-z]{38}$'], + feeAssets: [{ blockchain: 'BITCANNA', symbol: 'BCNA', address: null }], + logo: 'https://api.rango.exchange/blockchains/bitcanna.svg', + displayName: 'BitCanna', + shortName: 'BitCanna', + sort: 36, + color: '#3CC194', + enabled: true, + type: 'COSMOS', + chainId: 'bitcanna-1', + info: { + experimental: true, + rpc: 'https://rpc.bitcanna.io', + rest: 'https://lcd.bitcanna.io', + cosmostationLcdUrl: 'https://lcd-bitcanna.cosmostation.io', + cosmostationApiUrl: 'https://api-bitcanna.cosmostation.io', + cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', + mintScanName: 'bitcanna', + chainName: 'BitCanna', + stakeCurrency: { + coinDenom: 'BCNA', + coinMinimalDenom: 'ubcna', + coinDecimals: 6, + coinGeckoId: 'bitcanna', + coinImageUrl: '/tokens/blockchain/BCNA.png', + }, + bip44: { coinType: 118 }, + bech32Config: { + bech32PrefixAccAddr: 'bcna', + bech32PrefixAccPub: 'bcnapub', + bech32PrefixValAddr: 'bcnavaloper', + bech32PrefixValPub: 'bcnavaloperpub', + bech32PrefixConsAddr: 'bcnavalcons', + bech32PrefixConsPub: 'bcnavalconspub', + }, + currencies: [ + { + coinDenom: 'BCNA', + coinMinimalDenom: 'ubcna', + coinDecimals: 6, + coinGeckoId: 'bitcanna', + coinImageUrl: '/tokens/blockchain/BCNA.png', + }, + ], + feeCurrencies: [ + { + coinDenom: 'BCNA', + coinMinimalDenom: 'ubcna', + coinDecimals: 6, + coinGeckoId: 'bitcanna', + coinImageUrl: '/tokens/blockchain/BCNA.png', + }, + ], + features: ['stargate', 'ibc-transfer', 'no-legacy-stdTx'], + explorerUrlToTx: 'https://www.mintscan.io/bitcanna/txs/{txHash}', + gasPriceStep: null, + }, + }, + DESMOS: { + name: 'DESMOS', + defaultDecimals: 6, + addressPatterns: ['^(desmos1)[0-9a-z]{38}$'], + feeAssets: [{ blockchain: 'DESMOS', symbol: 'DSM', address: null }], + logo: 'https://api.rango.exchange/blockchains/desmos.svg', + displayName: 'Desmos', + shortName: 'Desmos', + sort: 37, + color: '#DF6952', + enabled: true, + type: 'COSMOS', + chainId: 'desmos-mainnet', + info: { + experimental: true, + rpc: 'https://rpc.mainnet.desmos.network', + rest: 'https://api.mainnet.desmos.network', + cosmostationLcdUrl: 'https://lcd-desmos.cosmostation.io', + cosmostationApiUrl: 'https://api-desmos.cosmostation.io', + cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', + mintScanName: 'desmos', + chainName: 'Desmos', + stakeCurrency: { + coinDenom: 'DSM', + coinMinimalDenom: 'udsm', + coinDecimals: 6, + coinGeckoId: 'pool:udsm', + coinImageUrl: '/tokens/blockchain/DSM.png', + }, + bip44: { coinType: 852 }, + bech32Config: { + bech32PrefixAccAddr: 'desmos', + bech32PrefixAccPub: 'desmospub', + bech32PrefixValAddr: 'desmosvaloper', + bech32PrefixValPub: 'desmosvaloperpub', + bech32PrefixConsAddr: 'desmosvalcons', + bech32PrefixConsPub: 'desmosvalconspub', + }, + currencies: [ + { + coinDenom: 'DSM', + coinMinimalDenom: 'udsm', + coinDecimals: 6, + coinGeckoId: 'pool:udsm', + coinImageUrl: '/tokens/blockchain/DSM.png', + }, + ], + feeCurrencies: [ + { + coinDenom: 'DSM', + coinMinimalDenom: 'udsm', + coinDecimals: 6, + coinGeckoId: 'pool:udsm', + coinImageUrl: '/tokens/blockchain/DSM.png', + }, + ], + features: ['stargate', 'ibc-transfer', 'no-legacy-stdTx', 'ibc-go'], + explorerUrlToTx: + 'https://explorer.desmos.network/transactions/{txHash}', + gasPriceStep: null, + }, + }, + LUMNETWORK: { + name: 'LUMNETWORK', + defaultDecimals: 6, + addressPatterns: ['^(lum1)[0-9a-z]{38}$'], + feeAssets: [{ blockchain: 'LUMNETWORK', symbol: 'LUM', address: null }], + logo: 'https://api.rango.exchange/blockchains/lumnetwork.svg', + displayName: 'Lum Network', + shortName: 'Lum Network', + sort: 38, + color: '#1B42B4', + enabled: true, + type: 'COSMOS', + chainId: 'lum-network-1', + info: { + experimental: true, + rpc: 'https://node0.mainnet.lum.network/rpc', + rest: 'https://node0.mainnet.lum.network/rest', + cosmostationLcdUrl: 'https://lcd-lum.cosmostation.io', + cosmostationApiUrl: 'https://api-lum.cosmostation.io', + cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', + mintScanName: 'lum', + chainName: 'Lum Network', + stakeCurrency: { + coinDenom: 'LUM', + coinMinimalDenom: 'ulum', + coinDecimals: 6, + coinGeckoId: 'pool:ulum', + coinImageUrl: '/tokens/blockchain/LUM.png', + }, + bip44: { coinType: 118 }, + bech32Config: { + bech32PrefixAccAddr: 'lum', + bech32PrefixAccPub: 'lumpub', + bech32PrefixValAddr: 'lumvaloper', + bech32PrefixValPub: 'lumvaloperpub', + bech32PrefixConsAddr: 'lumvalcons', + bech32PrefixConsPub: 'lumvalconspub', + }, + currencies: [ + { + coinDenom: 'LUM', + coinMinimalDenom: 'ulum', + coinDecimals: 6, + coinGeckoId: 'pool:ulum', + coinImageUrl: '/tokens/blockchain/LUM.png', + }, + ], + feeCurrencies: [ + { + coinDenom: 'LUM', + coinMinimalDenom: 'ulum', + coinDecimals: 6, + coinGeckoId: 'pool:ulum', + coinImageUrl: '/tokens/blockchain/LUM.png', + }, + ], + features: ['stargate', 'ibc-transfer', 'no-legacy-stdTx', 'ibc-go'], + explorerUrlToTx: 'https://www.mintscan.io/lum/txs/{txHash}', + gasPriceStep: null, + }, + }, + BOBA: { + name: 'BOBA', + defaultDecimals: 18, + addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], + feeAssets: [{ blockchain: 'BOBA', symbol: 'ETH', address: null }], + logo: 'https://api.rango.exchange/blockchains/boba.png', + displayName: 'Boba', + shortName: 'Boba', + sort: 39, + color: '#ccff00', + enabled: true, + type: 'EVM', + chainId: '0x120', + info: { + chainName: 'Boba Network', + nativeCurrency: { name: 'ETH', symbol: 'ETH', decimals: 18 }, + rpcUrls: ['https://mainnet.boba.network'], + blockExplorerUrls: ['https://bobascan.com/'], + addressUrl: 'https://bobascan.com//address/{wallet}', + transactionUrl: 'https://bobascan.com//tx/{txHash}', + }, + }, + }, + evmNetworkChainInfo: { + BSC: { + chainName: 'Binance Smart Chain Mainnet', + chainId: '0x38', + nativeCurrency: { name: 'BNB', symbol: 'BNB', decimals: 18 }, + rpcUrls: ['https://bsc-dataseed1.ninicoin.io'], + blockExplorerUrls: ['https://bscscan.com'], + }, + POLYGON: { + chainName: 'Polygon Mainnet', + chainId: '0x89', + nativeCurrency: { name: 'MATIC', symbol: 'MATIC', decimals: 18 }, + rpcUrls: ['https://polygon-rpc.com'], + blockExplorerUrls: ['https://polygonscan.com'], + }, + ETH: { + chainName: 'Ethereum Mainnet', + chainId: '0x1', + nativeCurrency: { name: 'ETH', symbol: 'ETH', decimals: 18 }, + rpcUrls: ['https://rpc.ankr.com/eth'], + blockExplorerUrls: ['https://etherscan.io'], + }, + AVAX_CCHAIN: { + chainName: 'Avalanche C-Chain', + chainId: '0xa86a', + nativeCurrency: { name: 'AVAX', symbol: 'AVAX', decimals: 18 }, + rpcUrls: ['https://api.avax.network/ext/bc/C/rpc'], + blockExplorerUrls: ['https://snowtrace.io'], + }, + ARBITRUM: { + chainName: 'Arbitrum One', + chainId: '0xa4b1', + nativeCurrency: { name: 'ETH', symbol: 'ETH', decimals: 18 }, + rpcUrls: ['https://arb1.arbitrum.io/rpc'], + blockExplorerUrls: ['https://arbiscan.io'], + }, + FANTOM: { + chainName: 'Fantom Opera', + chainId: '0xfa', + nativeCurrency: { name: 'FTM', symbol: 'FTM', decimals: 18 }, + rpcUrls: ['https://rpc.ftm.tools'], + blockExplorerUrls: ['https://ftmscan.com'], + }, + OPTIMISM: { + chainName: 'Optimism', + chainId: '0xa', + nativeCurrency: { name: 'ETH', symbol: 'ETH', decimals: 18 }, + rpcUrls: ['https://mainnet.optimism.io'], + blockExplorerUrls: ['https://optimistic.etherscan.io'], + }, + OKC: { + chainName: 'OKX Chain', + chainId: '0x42', + nativeCurrency: { name: 'OKT', symbol: 'OKT', decimals: 18 }, + rpcUrls: ['https://exchainrpc.okex.org'], + blockExplorerUrls: ['https://www.oklink.com/en/okc'], + }, + CRONOS: { + chainName: 'Cronos Mainnet Beta', + chainId: '0x19', + nativeCurrency: { name: 'CRO', symbol: 'CRO', decimals: 18 }, + rpcUrls: ['https://cronosrpc-1.xstaking.sg'], + blockExplorerUrls: ['https://cronoscan.com'], + }, + MOONRIVER: { + chainName: 'MoonRiver', + chainId: '0x505', + nativeCurrency: { name: 'MOVR', symbol: 'MOVR', decimals: 18 }, + rpcUrls: ['https://rpc.moonriver.moonbeam.network'], + blockExplorerUrls: ['https://moonriver.moonscan.io'], + }, + MOONBEAM: { + chainName: 'MoonBeam', + chainId: '0x504', + nativeCurrency: { name: 'GLMR', symbol: 'GLMR', decimals: 18 }, + rpcUrls: ['https://rpc.api.moonbeam.network'], + blockExplorerUrls: ['https://moonbeam.moonscan.io'], + }, + HECO: { + chainName: 'Huobi ECO Chain Mainnet', + chainId: '0x80', + nativeCurrency: { name: 'HT', symbol: 'HT', decimals: 18 }, + rpcUrls: ['https://http-mainnet.hecochain.com'], + blockExplorerUrls: ['https://hecoinfo.com'], + }, + AURORA: { + chainName: 'Aurora Mainnet', + chainId: '0x4e454152', + nativeCurrency: { name: 'ETH', symbol: 'ETH', decimals: 18 }, + rpcUrls: ['https://mainnet.aurora.dev'], + blockExplorerUrls: ['https://explorer.mainnet.aurora.dev'], + }, + HARMONY: { + chainName: 'Harmony Mainnet', + chainId: '0x63564c40', + nativeCurrency: { name: 'ONE', symbol: 'ONE', decimals: 18 }, + rpcUrls: ['https://api.s0.t.hmny.io'], + blockExplorerUrls: ['https://explorer.harmony.one'], + }, + EVMOS: { + chainName: 'Evmos', + chainId: '0x2329', + nativeCurrency: { name: 'EVMOS', symbol: 'EVMOS', decimals: 18 }, + rpcUrls: ['https://eth.bd.evmos.org:8545'], + blockExplorerUrls: ['https://evm.evmos.org'], + }, + GNOSIS: { + chainName: 'Gnosis Chain', + chainId: '0x64', + nativeCurrency: { name: 'XDAI', symbol: 'XDAI', decimals: 18 }, + rpcUrls: ['https://rpc.gnosischain.com'], + blockExplorerUrls: ['https://blockscout.com/xdai/mainnet'], + }, + FUSE: { + chainName: 'Fuse Mainnet', + chainId: '0x7a', + nativeCurrency: { name: 'FUSE', symbol: 'FUSE', decimals: 18 }, + rpcUrls: ['https://rpc.fuse.io'], + blockExplorerUrls: ['https://explorer.fuse.io'], + }, + BOBA: { + chainName: 'Boba Network', + chainId: '0x120', + nativeCurrency: { name: 'ETH', symbol: 'ETH', decimals: 18 }, + rpcUrls: ['https://mainnet.boba.network'], + blockExplorerUrls: ['https://bobascan.com/'], + }, + }, + walletsAndSupportedChainsNames: { + 'binance-chain': ['BSC', 'ETH', 'BNB'], + metamask: [ + 'BSC', + 'POLYGON', + 'ETH', + 'AVAX_CCHAIN', + 'ARBITRUM', + 'FANTOM', + 'OPTIMISM', + 'OKC', + 'CRONOS', + 'MOONRIVER', + 'MOONBEAM', + 'HECO', + 'AURORA', + 'HARMONY', + 'EVMOS', + 'GNOSIS', + 'FUSE', + 'BOBA', + ], + coinbase: [ + 'BSC', + 'POLYGON', + 'ETH', + 'AVAX_CCHAIN', + 'ARBITRUM', + 'FANTOM', + 'OPTIMISM', + 'OKC', + 'CRONOS', + 'MOONRIVER', + 'MOONBEAM', + 'HECO', + 'AURORA', + 'HARMONY', + 'EVMOS', + 'GNOSIS', + 'FUSE', + 'BOBA', + 'SOLANA', + ], + keplr: [ + 'OSMOSIS', + 'JUNO', + 'COSMOS', + 'SIF', + 'STARGAZE', + 'CRYPTO_ORG', + 'CHIHUAHUA', + 'BANDCHAIN', + 'COMDEX', + 'REGEN', + 'IRIS', + 'EMONEY', + 'AKASH', + 'KI', + 'KUJIRA', + 'PERSISTENCE', + 'SENTINEL', + 'STARNAME', + 'UMEE', + 'BITCANNA', + 'DESMOS', + 'LUMNETWORK', + ], + phantom: ['SOLANA'], + xdefi: [ + 'BSC', + 'POLYGON', + 'ETH', + 'AVAX_CCHAIN', + 'ARBITRUM', + 'FANTOM', + 'SOLANA', + 'THOR', + 'BNB', + 'BTC', + 'LTC', + 'BCH', + ], + 'wallet-connect-2': [ + 'BSC', + 'POLYGON', + 'ETH', + 'AVAX_CCHAIN', + 'ARBITRUM', + 'FANTOM', + 'OPTIMISM', + 'OKC', + 'CRONOS', + 'MOONRIVER', + 'MOONBEAM', + 'HECO', + 'AURORA', + 'HARMONY', + 'EVMOS', + 'GNOSIS', + 'FUSE', + 'BOBA', + ], + 'trust-wallet': [ + 'BSC', + 'POLYGON', + 'ETH', + 'AVAX_CCHAIN', + 'ARBITRUM', + 'FANTOM', + 'OPTIMISM', + 'OKC', + 'CRONOS', + 'MOONRIVER', + 'MOONBEAM', + 'HECO', + 'AURORA', + 'HARMONY', + 'EVMOS', + 'GNOSIS', + 'FUSE', + 'BOBA', + ], + coin98: [ + 'BSC', + 'POLYGON', + 'ETH', + 'AVAX_CCHAIN', + 'ARBITRUM', + 'FANTOM', + 'OPTIMISM', + 'OKC', + 'CRONOS', + 'MOONRIVER', + 'MOONBEAM', + 'HECO', + 'AURORA', + 'HARMONY', + 'EVMOS', + 'GNOSIS', + 'FUSE', + 'BOBA', + 'SOLANA', + ], + okx: [ + 'BSC', + 'POLYGON', + 'ETH', + 'AVAX_CCHAIN', + 'ARBITRUM', + 'FANTOM', + 'OPTIMISM', + 'SOLANA', + 'CRONOS', + 'MOONRIVER', + 'MOONBEAM', + 'HARMONY', + 'BTC', + 'GNOSIS', + 'LTC', + 'BOBA', + ], + exodus: ['BSC', 'POLYGON', 'ETH', 'AVAX_CCHAIN', 'SOLANA', 'BNB'], + 'token-pocket': [ + 'BSC', + 'POLYGON', + 'ETH', + 'AVAX_CCHAIN', + 'ARBITRUM', + 'FANTOM', + 'OPTIMISM', + 'OKC', + 'CRONOS', + 'MOONRIVER', + 'MOONBEAM', + 'HECO', + 'AURORA', + 'HARMONY', + 'EVMOS', + 'GNOSIS', + 'FUSE', + 'BOBA', + ], + 'terra-station': [], + leap: [], + math: [ + 'BSC', + 'POLYGON', + 'ETH', + 'AVAX_CCHAIN', + 'ARBITRUM', + 'FANTOM', + 'OPTIMISM', + 'OKC', + 'CRONOS', + 'MOONRIVER', + 'MOONBEAM', + 'HECO', + 'AURORA', + 'HARMONY', + 'EVMOS', + 'GNOSIS', + 'FUSE', + 'BOBA', + 'SOLANA', + ], + safepal: [ + 'BSC', + 'POLYGON', + 'ETH', + 'AVAX_CCHAIN', + 'ARBITRUM', + 'FANTOM', + 'OPTIMISM', + 'OKC', + 'CRONOS', + 'MOONRIVER', + 'MOONBEAM', + 'HECO', + 'AURORA', + 'HARMONY', + 'EVMOS', + 'GNOSIS', + 'FUSE', + 'BOBA', + 'SOLANA', + ], + clover: [ + 'BSC', + 'POLYGON', + 'ETH', + 'AVAX_CCHAIN', + 'ARBITRUM', + 'FANTOM', + 'OPTIMISM', + 'OKC', + 'CRONOS', + 'MOONRIVER', + 'MOONBEAM', + 'HECO', + 'AURORA', + 'HARMONY', + 'EVMOS', + 'GNOSIS', + 'FUSE', + 'BOBA', + 'SOLANA', + ], + cosmostation: [ + 'BSC', + 'POLYGON', + 'ETH', + 'AVAX_CCHAIN', + 'ARBITRUM', + 'FANTOM', + 'OPTIMISM', + 'OKC', + 'CRONOS', + 'MOONRIVER', + 'MOONBEAM', + 'HECO', + 'AURORA', + 'HARMONY', + 'EVMOS', + 'GNOSIS', + 'FUSE', + 'BOBA', + 'OSMOSIS', + 'JUNO', + 'COSMOS', + 'SIF', + 'STARGAZE', + 'CRYPTO_ORG', + 'CHIHUAHUA', + 'BANDCHAIN', + 'COMDEX', + 'REGEN', + 'IRIS', + 'EMONEY', + 'AKASH', + 'KI', + 'KUJIRA', + 'PERSISTENCE', + 'SENTINEL', + 'STARNAME', + 'UMEE', + 'BITCANNA', + 'DESMOS', + 'LUMNETWORK', + ], + brave: [ + 'BSC', + 'POLYGON', + 'ETH', + 'AVAX_CCHAIN', + 'ARBITRUM', + 'FANTOM', + 'OPTIMISM', + 'OKC', + 'CRONOS', + 'MOONRIVER', + 'MOONBEAM', + 'HECO', + 'AURORA', + 'HARMONY', + 'EVMOS', + 'GNOSIS', + 'FUSE', + 'BOBA', + 'SOLANA', + ], + unknown: [], + }, + evmBasedChains: [ + { + name: 'BSC', + defaultDecimals: 18, + addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], + feeAssets: [{ blockchain: 'BSC', symbol: 'BNB', address: null }], + logo: 'https://api.rango.exchange/blockchains/binance.svg', + displayName: 'BSC', + shortName: 'BSC', + sort: 1, + color: '#F3BA2F', + enabled: true, + type: 'EVM', + chainId: '0x38', + info: { + chainName: 'Binance Smart Chain Mainnet', + nativeCurrency: { name: 'BNB', symbol: 'BNB', decimals: 18 }, + rpcUrls: ['https://bsc-dataseed1.ninicoin.io'], + blockExplorerUrls: ['https://bscscan.com'], + addressUrl: 'https://bscscan.com/address/{wallet}', + transactionUrl: 'https://bscscan.com/tx/{txHash}', + }, + }, + { + name: 'POLYGON', + defaultDecimals: 18, + addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], + feeAssets: [{ blockchain: 'POLYGON', symbol: 'MATIC', address: null }], + logo: 'https://api.rango.exchange/blockchains/polygon.svg', + displayName: 'Polygon', + shortName: 'Polygon', + sort: 2, + color: '#8247E5', + enabled: true, + type: 'EVM', + chainId: '0x89', + info: { + chainName: 'Polygon Mainnet', + nativeCurrency: { name: 'MATIC', symbol: 'MATIC', decimals: 18 }, + rpcUrls: ['https://polygon-rpc.com'], + blockExplorerUrls: ['https://polygonscan.com'], + addressUrl: 'https://polygonscan.com/address/{wallet}', + transactionUrl: 'https://polygonscan.com/tx/{txHash}', + }, + }, + { + name: 'ETH', + defaultDecimals: 18, + addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], + feeAssets: [{ blockchain: 'ETH', symbol: 'ETH', address: null }], + logo: 'https://api.rango.exchange/blockchains/ethereum.svg', + displayName: 'Ethereum', + shortName: 'ETH', + sort: 3, + color: '#ecf0f1', + enabled: true, + type: 'EVM', + chainId: '0x1', + info: { + chainName: 'Ethereum Mainnet', + nativeCurrency: { name: 'ETH', symbol: 'ETH', decimals: 18 }, + rpcUrls: ['https://rpc.ankr.com/eth'], + blockExplorerUrls: ['https://etherscan.io'], + addressUrl: 'https://etherscan.io/address/{wallet}', + transactionUrl: 'https://etherscan.io/tx/{txHash}', + }, + }, + { + name: 'AVAX_CCHAIN', + defaultDecimals: 18, + addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], + feeAssets: [{ blockchain: 'AVAX_CCHAIN', symbol: 'AVAX', address: null }], + logo: 'https://api.rango.exchange/blockchains/avax_cchain.svg', + displayName: 'Avalanche', + shortName: 'Avax', + sort: 6, + color: '#e84142', + enabled: true, + type: 'EVM', + chainId: '0xa86a', + info: { + chainName: 'Avalanche C-Chain', + nativeCurrency: { name: 'AVAX', symbol: 'AVAX', decimals: 18 }, + rpcUrls: ['https://api.avax.network/ext/bc/C/rpc'], + blockExplorerUrls: ['https://snowtrace.io'], + addressUrl: 'https://snowtrace.io/address/{wallet}', + transactionUrl: 'https://snowtrace.io/tx/{txHash}', + }, + }, + { + name: 'ARBITRUM', + defaultDecimals: 18, + addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], + feeAssets: [{ blockchain: 'ARBITRUM', symbol: 'ETH', address: null }], + logo: 'https://api.rango.exchange/blockchains/arbitrum.svg', + displayName: 'Arbitrum', + shortName: 'Arbitrum', + sort: 7, + color: '#28a0f0', + enabled: true, + type: 'EVM', + chainId: '0xa4b1', + info: { + chainName: 'Arbitrum One', + nativeCurrency: { name: 'ETH', symbol: 'ETH', decimals: 18 }, + rpcUrls: ['https://arb1.arbitrum.io/rpc'], + blockExplorerUrls: ['https://arbiscan.io'], + addressUrl: 'https://arbiscan.io/address/{wallet}', + transactionUrl: 'https://arbiscan.io/tx/{txHash}', + }, + }, + { + name: 'FANTOM', + defaultDecimals: 18, + addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], + feeAssets: [{ blockchain: 'FANTOM', symbol: 'FTM', address: null }], + logo: 'https://api.rango.exchange/blockchains/fantom.png', + displayName: 'Fantom', + shortName: 'Fantom', + sort: 9, + color: '#337afe', + enabled: true, + type: 'EVM', + chainId: '0xfa', + info: { + chainName: 'Fantom Opera', + nativeCurrency: { name: 'FTM', symbol: 'FTM', decimals: 18 }, + rpcUrls: ['https://rpc.ftm.tools'], + blockExplorerUrls: ['https://ftmscan.com'], + addressUrl: 'https://ftmscan.com/address/{wallet}', + transactionUrl: 'https://ftmscan.com/tx/{txHash}', + }, + }, + { + name: 'OPTIMISM', + defaultDecimals: 18, + addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], + feeAssets: [{ blockchain: 'OPTIMISM', symbol: 'ETH', address: null }], + logo: 'https://api.rango.exchange/blockchains/optimism.svg', + displayName: 'Optimism', + shortName: 'Optimism', + sort: 10, + color: '#FF0420', + enabled: true, + type: 'EVM', + chainId: '0xa', + info: { + chainName: 'Optimism', + nativeCurrency: { name: 'ETH', symbol: 'ETH', decimals: 18 }, + rpcUrls: ['https://mainnet.optimism.io'], + blockExplorerUrls: ['https://optimistic.etherscan.io'], + addressUrl: 'https://optimistic.etherscan.io/address/{wallet}', + transactionUrl: 'https://optimistic.etherscan.io/tx/{txHash}', + }, + }, + { + name: 'OKC', + defaultDecimals: 18, + addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], + feeAssets: [{ blockchain: 'OKC', symbol: 'OKT', address: null }], + logo: 'https://api.rango.exchange/blockchains/okx.png', + displayName: 'OKX Chain (OKC)', + shortName: 'Okx', + sort: 11, + color: '#29a0f0', + enabled: true, + type: 'EVM', + chainId: '0x42', + info: { + chainName: 'OKX Chain', + nativeCurrency: { name: 'OKT', symbol: 'OKT', decimals: 18 }, + rpcUrls: ['https://exchainrpc.okex.org'], + blockExplorerUrls: ['https://www.oklink.com/en/okc'], + addressUrl: 'https://www.oklink.com/en/okc/address/{wallet}', + transactionUrl: 'https://www.oklink.com/en/okc/tx/{txHash}', + }, + }, + { + name: 'CRONOS', + defaultDecimals: 18, + addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], + feeAssets: [{ blockchain: 'CRONOS', symbol: 'CRO', address: null }], + logo: 'https://api.rango.exchange/blockchains/cronos.svg', + displayName: 'Cronos', + shortName: 'Cronos', + sort: 12, + color: '#1a90ff', + enabled: true, + type: 'EVM', + chainId: '0x19', + info: { + chainName: 'Cronos Mainnet Beta', + nativeCurrency: { name: 'CRO', symbol: 'CRO', decimals: 18 }, + rpcUrls: ['https://cronosrpc-1.xstaking.sg'], + blockExplorerUrls: ['https://cronoscan.com'], + addressUrl: 'https://cronoscan.com/address/{wallet}', + transactionUrl: 'https://cronoscan.com/tx/{txHash}', + }, + }, + { + name: 'MOONRIVER', + defaultDecimals: 18, + addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], + feeAssets: [{ blockchain: 'MOONRIVER', symbol: 'MOVR', address: null }], + logo: 'https://api.rango.exchange/blockchains/moonriver.svg', + displayName: 'MoonRiver', + shortName: 'MoonRiver', + sort: 13, + color: '#F3B404', + enabled: true, + type: 'EVM', + chainId: '0x505', + info: { + chainName: 'MoonRiver', + nativeCurrency: { name: 'MOVR', symbol: 'MOVR', decimals: 18 }, + rpcUrls: ['https://rpc.moonriver.moonbeam.network'], + blockExplorerUrls: ['https://moonriver.moonscan.io'], + addressUrl: 'https://moonriver.moonscan.io/address/{wallet}', + transactionUrl: 'https://moonriver.moonscan.io/tx/{txHash}', + }, + }, + { + name: 'MOONBEAM', + defaultDecimals: 18, + addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], + feeAssets: [{ blockchain: 'MOONBEAM', symbol: 'GLMR', address: null }], + logo: 'https://api.rango.exchange/blockchains/moonbeam.png', + displayName: 'MoonBeam', + shortName: 'MoonBeam', + sort: 14, + color: '#B3206B', + enabled: true, + type: 'EVM', + chainId: '0x504', + info: { + chainName: 'MoonBeam', + nativeCurrency: { name: 'GLMR', symbol: 'GLMR', decimals: 18 }, + rpcUrls: ['https://rpc.api.moonbeam.network'], + blockExplorerUrls: ['https://moonbeam.moonscan.io'], + addressUrl: 'https://moonbeam.moonscan.io/address/{wallet}', + transactionUrl: 'https://moonbeam.moonscan.io/tx/{txHash}', + }, + }, + { + name: 'HECO', + defaultDecimals: 18, + addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], + feeAssets: [{ blockchain: 'HECO', symbol: 'HT', address: null }], + logo: 'https://api.rango.exchange/blockchains/heco.png', + displayName: 'Heco', + shortName: 'Heco', + sort: 15, + color: '#4CA852', + enabled: true, + type: 'EVM', + chainId: '0x80', + info: { + chainName: 'Huobi ECO Chain Mainnet', + nativeCurrency: { name: 'HT', symbol: 'HT', decimals: 18 }, + rpcUrls: ['https://http-mainnet.hecochain.com'], + blockExplorerUrls: ['https://hecoinfo.com'], + addressUrl: 'https://hecoinfo.com/address/{wallet}', + transactionUrl: 'https://hecoinfo.com/tx/{txHash}', + }, + }, + { + name: 'AURORA', + defaultDecimals: 18, + addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], + feeAssets: [{ blockchain: 'AURORA', symbol: 'ETH', address: null }], + logo: 'https://api.rango.exchange/blockchains/aurora.svg', + displayName: 'Aurora', + shortName: 'Aurora', + sort: 15, + color: '#78d64b', + enabled: true, + type: 'EVM', + chainId: '0x4e454152', + info: { + chainName: 'Aurora Mainnet', + nativeCurrency: { name: 'ETH', symbol: 'ETH', decimals: 18 }, + rpcUrls: ['https://mainnet.aurora.dev'], + blockExplorerUrls: ['https://explorer.mainnet.aurora.dev'], + addressUrl: 'https://explorer.mainnet.aurora.dev/address/{wallet}', + transactionUrl: 'https://explorer.mainnet.aurora.dev/tx/{txHash}', + }, + }, + { + name: 'HARMONY', + defaultDecimals: 18, + addressPatterns: ['^(one1)[0-9a-z]{38}$', '^(0x)[0-9A-Fa-f]{40}$'], + feeAssets: [{ blockchain: 'HARMONY', symbol: 'ONE', address: null }], + logo: 'https://api.rango.exchange/blockchains/harmony.svg', + displayName: 'Harmony', + shortName: 'Harmony', + sort: 15, + color: '#50AEE9', + enabled: true, + type: 'EVM', + chainId: '0x63564c40', + info: { + chainName: 'Harmony Mainnet', + nativeCurrency: { name: 'ONE', symbol: 'ONE', decimals: 18 }, + rpcUrls: ['https://api.s0.t.hmny.io'], + blockExplorerUrls: ['https://explorer.harmony.one'], + addressUrl: 'https://explorer.harmony.one/address/{wallet}', + transactionUrl: 'https://explorer.harmony.one/tx/{txHash}', + }, + }, + { + name: 'EVMOS', + defaultDecimals: 18, + addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], + feeAssets: [{ blockchain: 'EVMOS', symbol: 'EVMOS', address: null }], + logo: 'https://api.rango.exchange/blockchains/evmos.png', + displayName: 'Evmos', + shortName: 'Evmos', + sort: 15, + color: '#2D2925', + enabled: true, + type: 'EVM', + chainId: '0x2329', + info: { + chainName: 'Evmos', + nativeCurrency: { name: 'EVMOS', symbol: 'EVMOS', decimals: 18 }, + rpcUrls: ['https://eth.bd.evmos.org:8545'], + blockExplorerUrls: ['https://evm.evmos.org'], + addressUrl: 'https://evm.evmos.org/address/{wallet}', + transactionUrl: 'https://evm.evmos.org/tx/{txHash}', + }, + }, + { + name: 'GNOSIS', + defaultDecimals: 18, + addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], + feeAssets: [{ blockchain: 'GNOSIS', symbol: 'XDAI', address: null }], + logo: 'https://api.rango.exchange/blockchains/gnosis.svg', + displayName: 'Gnosis', + shortName: 'Gnosis', + sort: 26, + color: '#3E6957', + enabled: true, + type: 'EVM', + chainId: '0x64', + info: { + chainName: 'Gnosis Chain', + nativeCurrency: { name: 'XDAI', symbol: 'XDAI', decimals: 18 }, + rpcUrls: ['https://rpc.gnosischain.com'], + blockExplorerUrls: ['https://blockscout.com/xdai/mainnet'], + addressUrl: 'https://blockscout.com/xdai/mainnet/address/{wallet}', + transactionUrl: 'https://blockscout.com/xdai/mainnet/tx/{txHash}', + }, + }, + { + name: 'FUSE', + defaultDecimals: 18, + addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], + feeAssets: [{ blockchain: 'FUSE', symbol: 'FUSE', address: null }], + logo: 'https://api.rango.exchange/blockchains/fuse.png', + displayName: 'Fuse', + shortName: 'Fuse', + sort: 29, + color: '#C5F9AD', + enabled: true, + type: 'EVM', + chainId: '0x7a', + info: { + chainName: 'Fuse Mainnet', + nativeCurrency: { name: 'FUSE', symbol: 'FUSE', decimals: 18 }, + rpcUrls: ['https://rpc.fuse.io'], + blockExplorerUrls: ['https://explorer.fuse.io'], + addressUrl: 'https://explorer.fuse.io/address/{wallet}', + transactionUrl: 'https://explorer.fuse.io/tx/{txHash}', + }, + }, + { + name: 'BOBA', + defaultDecimals: 18, + addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], + feeAssets: [{ blockchain: 'BOBA', symbol: 'ETH', address: null }], + logo: 'https://api.rango.exchange/blockchains/boba.png', + displayName: 'Boba', + shortName: 'Boba', + sort: 39, + color: '#ccff00', + enabled: true, + type: 'EVM', + chainId: '0x120', + info: { + chainName: 'Boba Network', + nativeCurrency: { name: 'ETH', symbol: 'ETH', decimals: 18 }, + rpcUrls: ['https://mainnet.boba.network'], + blockExplorerUrls: ['https://bobascan.com/'], + addressUrl: 'https://bobascan.com//address/{wallet}', + transactionUrl: 'https://bobascan.com//tx/{txHash}', + }, + }, + ], +} as unknown as Meta; diff --git a/examples/queue-manager-demo/src/flows/rango/types.ts b/examples/queue-manager-demo/src/flows/rango/types.ts new file mode 100644 index 0000000000..0b5a75e760 --- /dev/null +++ b/examples/queue-manager-demo/src/flows/rango/types.ts @@ -0,0 +1,447 @@ +import type { + Asset, + CosmosTransaction, + EvmTransaction, + Network, + SolanaTransaction, + Transaction, + TransferTransaction, + WalletType, +} from '@rango-dev/wallets-shared'; +import type BigNumber from 'bignumber.js'; + +import { Networks } from '@rango-dev/wallets-shared'; + +export type WalletTypeAndAddress = { + walletType: WalletType; + address: string; +}; + +export enum MessageSeverity { + error = 'error', + warning = 'warning', + info = 'info', + success = 'success', +} + +export type SwapStatus = 'running' | 'failed' | 'success'; + +export type SwapSavedSettings = { + slippage: string; + disabledSwappersIds: string[]; + disabledSwappersGroups: string[]; +}; + +export type SwapperId = + | 'ThorChain' + | 'OneInchEth' + | 'Binance Bridge' + | 'OneInchBsc' + | 'OneInchPolygon' + | 'Terra Bridge' + | 'TerraSwap' + | 'Osmosis' + | 'Lido' + | 'PoS Bridge' + | 'Wormhole'; + +export type StepStatus = + | 'created' + | 'running' + | 'failed' + | 'success' + | 'waitingForApproval' + | 'approved'; + +export enum PendingSwapNetworkStatus { + WaitingForConnectingWallet = 'waitingForConnectingWallet', + WaitingForQueue = 'waitingForQueue', + WaitingForNetworkChange = 'waitingForNetworkChange', + NetworkChanged = 'networkChanged', +} + +export type SwapExplorerUrl = { + url: string; + description: string | null; +}; + +type InternalStepState = + | 'PENDING' + | 'CREATED' + | 'WAITING' + | 'SIGNED' + | 'SUCCESSED' + | 'FAILED'; + +export type SwapperStatusStep = { + name: string; + state: InternalStepState; + current: boolean; +}; + +export type PendingSwapStep = { + id: number; + fromBlockchain: Network; + fromSymbol: string; + fromSymbolAddress: string | null; + fromDecimals: number; + fromAmountPrecision: number | null; + fromAmountMinValue: number | null; + fromAmountMaxValue: number | null; + fromLogo: string; + toBlockchain: string; + toSymbol: string; + toSymbolAddress: string | null; + toDecimals: number; + toLogo: string; + swapperId: SwapperId; + expectedOutputAmountHumanReadable: string | null; + startTransactionTime: number; + outputAmount: string | null; + status: StepStatus; + networkStatus: PendingSwapNetworkStatus | null; + executedTransactionId: string | null; + explorerUrl: SwapExplorerUrl[] | null; + evmApprovalTransaction: EvmTransaction | null; + evmTransaction: EvmTransaction | null; + cosmosTransaction: CosmosTransaction | null; + transferTransaction: TransferTransaction | null; + solanaTransaction: SolanaTransaction | null; + diagnosisUrl: string | null; + internalSteps: SwapperStatusStep[] | null; +}; + +export type SwapResultAsset = { + symbol: string; + logo: string; + address: string | null; + blockchain: Network; + decimals: number; + usdPrice: number | null; +}; + +export type ExpenseType = 'FROM_SOURCE_WALLET' | 'DECREASE_FROM_OUTPUT'; + +export type SwapFee = { + asset: Asset; + amount: string; + expenseType: ExpenseType; +}; + +export type TimeStat = { + min: number; + avg: number; + max: number; +}; + +export type SwapNode = { + marketName: string; + marketId: string | null; + percent: number; +}; + +export type SwapSuperNode = { + nodes: SwapNode[]; + from: string; + fromLogo: string; + fromAddress: string | null; + fromBlockchain: string; + to: string; + toLogo: string; + toAddress: string | null; + toBlockchain: string; +}; + +export type SwapRoute = { + nodes: SwapSuperNode[] | null; +}; + +export type RecommendedSlippage = { + error: boolean; + slippage: string | null; +}; + +export type SwapResult = { + swapperId: SwapperId; + from: SwapResultAsset; + to: SwapResultAsset; + fromAmount: string; + fromAmountPrecision: number | null; + fromAmountRestrictionType: 'EXCLUSIVE' | 'INCLUSIVE'; + fromAmountMinValue: number | null; + fromAmountMaxValue: number | null; + toAmount: string; + fee: SwapFee[]; + estimatedTimeInSeconds: number; + timeStat: TimeStat | null; + swapChainType: string; + routes: SwapRoute[] | null; + recommendedSlippage: RecommendedSlippage | null; + includesDestinationTx: boolean | null | undefined; +}; + +export type SimulationResult = { + outputAmount: string; + swaps: SwapResult[]; +}; + +export type PendingSwap = { + creationTime: string; + finishTime: string | null; + requestId: string; + inputAmount: string; + status: SwapStatus; + isPaused: boolean; + extraMessage: string | null; + extraMessageSeverity: MessageSeverity | null; + extraMessageErrorCode: string | null; + extraMessageDetail: string | null | undefined; + networkStatusExtraMessage: string | null; + networkStatusExtraMessageDetail: string | null; + lastNotificationTime: string | null; + wallets: { [p: string]: WalletTypeAndAddress }; + settings: SwapSavedSettings; + steps: PendingSwapStep[]; + simulationResult: SimulationResult; + validateBalanceOrFee: boolean; +}; +export type Amount = { amount: string; decimals: number }; +export type WalletRequiredAssetReason = + | 'FEE' + | 'INPUT_ASSET' + | 'FEE_AND_INPUT_ASSET'; + +export type SimulationAssetAndAmount = { + asset: Asset; + requiredAmount: Amount; + currentAmount: Amount; + reason: WalletRequiredAssetReason; + ok: boolean; +}; + +export type SimulationWallet = { + address: string; + validResult: boolean; + requiredAssets: SimulationAssetAndAmount[]; + addressIsValid: boolean; +}; + +export type SimulationValidationStatus = { + blockchain: string; + wallets: SimulationWallet[]; +}; + +export type BestRoute = { + from: Asset; + to: Asset; + requestAmount: string; + result: SimulationResult | null; + validationStatus: SimulationValidationStatus[] | null; + requestId: string; + missingBlockchains: string[]; + diagnosisMessages: string[]; +}; + +export const SWAPPER_ONE_INCH_ETH = 'OneInchEth'; +export const SWAPPER_ONE_INCH_BSC = 'OneInchBsc'; +export const SWAPPER_ONE_INCH_POLYGON = 'OneInchPolygon'; +export const SWAPPER_TERRA_BRIDGE = 'Terra Bridge'; +export const SWAPPER_LIDO = 'Lido'; +export const SWAPPER_TERRA_SWAP = 'TerraSwap'; +export const SWAPPER_THORCHAIN = 'ThorChain'; +export const SWAPPER_BINANCE_BRIDGE = 'Binance Bridge'; +export const SWAPPER_OSMOSIS = 'Osmosis'; + +export const SWAPPER_ONE_INCH_LIST = [ + SWAPPER_ONE_INCH_ETH, + SWAPPER_ONE_INCH_BSC, + SWAPPER_ONE_INCH_POLYGON, +]; + +export const NETWORKS_FOR_1INCH = [ + Networks.POLYGON, + Networks.ETHEREUM, + Networks.BSC, +]; + +export const BNB_SYMBOL = 'BNB'; +export const MATIC_SYMBOL = 'MATIC'; + +export const NETWORK_TO_NATIVE_SYMBOL_MAP_FOR_1INCH = new Map([ + [Networks.ETHEREUM, Networks.ETHEREUM], + [Networks.BSC, BNB_SYMBOL], + [Networks.POLYGON, MATIC_SYMBOL], +]); + +export type TokenMeta = { + blockchain: Network; + symbol: string; + image: string; + address: string | null; + usdPrice: number | null; + isSecondaryCoin: boolean; + coinSource: string | null; + coinSourceUrl: string | null; + name: string | null; + decimals: number; +}; + +export type RawAccounts = { + blockchains: { + name: string; + accounts: { address: string; walletType: WalletType }[]; + }[]; +} | null; + +export type UserWalletBlockchain = { + blockchain: string; + addresses: string[]; +}; + +export type WalletBalance = { + chain: Network; + symbol: string; + ticker: string; + address: string | null; + rawAmount: string; + decimal: number | null; + amount: string; + logo: string | null; + usdPrice: number | null; +}; + +export type Account = { + balances: WalletBalance[] | null; + address: string; + loading: boolean; + walletType: WalletType; + error: boolean; + explorerUrl: string | null; + isConnected: boolean; +}; + +export type Blockchain = { name: Network; accounts: Account[] }; +export type Wallet = { blockchains: Blockchain[] }; + +export type EventType = + | 'swap_started' + | 'confirm_contract' + | 'confirm_transfer' + | 'task_failed' + | 'task_completed' + | 'task_canceled' + | 'task_paused' + | 'contract_confirmed' + | 'contract_rejected' + | 'transfer_confirmed' + | 'transfer_rejected' + | 'calling_smart_contract' + | 'smart_contract_called' + | 'smart_contract_call_failed' + | 'step_completed_with_output' + | 'waiting_for_network_change' + | 'waiting_for_connecting_wallet' + | 'network_changed' + | 'not_enough_balance' + | 'check_fee_failed' + | 'route_failed_to_find'; + +export type SwapperStatusResponse = { + status: 'running' | 'failed' | 'success' | null; + extraMessage: string | null; + timestamp: number; + outputAmount: BigNumber | null; + explorerUrl: SwapExplorerUrl[] | null; + trackingCode: string; + newTx: Transaction | null; + diagnosisUrl: string | null; + steps: SwapperStatusStep[] | null; +}; + +export type CheckTxStatusRequest = { + requestId: string; + txId: string; + step: number; +}; + +export enum ApiMethodName { + RequestingSwapTransaction = 'Requesting Swap Transaction', + CreatingSwap = 'Creating Swap', + CheckingTransactionStatus = 'Checking transaction status', + CreateTransaction = 'Create Transaction', + CheckApproval = 'Check TX Approval', + GettingSwapDetail = 'Getting Swap Detail', + GettingUserLimits = 'Getting user limits', +} + +export type APIErrorCode = + | 'TX_FAIL' + | 'FETCH_TX_FAILED' + | 'USER_REJECT' + | 'CALL_WALLET_FAILED' + | 'SEND_TX_FAILED' + | 'CALL_OR_SEND_FAILED' + | 'CLIENT_UNEXPECTED_BEHAVIOUR'; + +export type ErrorDetail = { + extraMessage: string; + extraMessageDetail?: string | null | undefined; + extraMessageErrorCode: string | null; +}; + +export enum TransactionName { + GenericTransaction = 'transaction', + SendingOneInchTransaction = '1inch transaction', + Approval = 'approve transaction', +} + +export type UserSettings = { + slippage: string; +}; + +export type CreateTransactionValidation = { + balance: boolean; + fee: boolean; +}; + +export type CreateTransactionRequest = { + requestId: string; + step: number; + userSettings: UserSettings; + validations: CreateTransactionValidation; +}; + +export type CreateTransactionResponse = { + ok: boolean; + error: string | null; + transaction: Transaction; +}; + +export const OKX_WALLET_SUPPORTED_CHAINS = [ + Networks.ETHEREUM, + Networks.BTC, + Networks.BSC, + Networks.TRON, + Networks.SOLANA, + Networks.POLYGON, + Networks.FANTOM, + Networks.ARBITRUM, + Networks.OPTIMISM, + Networks.CRONOS, + Networks.BOBA, + Networks.GNOSIS, + Networks.MOONBEAM, + Networks.MOONRIVER, + Networks.HARMONY, + Networks.LTC, + Networks.AVAX_CCHAIN, +]; + +export const EXODUS_WALLET_SUPPORTED_CHAINS = [ + Networks.SOLANA, + Networks.ETHEREUM, + Networks.BSC, + Networks.POLYGON, + Networks.AVAX_CCHAIN, + BNB_SYMBOL, +]; diff --git a/queue-manager/demo/src/flows/single.ts b/examples/queue-manager-demo/src/flows/single.ts similarity index 96% rename from queue-manager/demo/src/flows/single.ts rename to examples/queue-manager-demo/src/flows/single.ts index f44054c708..320dc0ff26 100644 --- a/queue-manager/demo/src/flows/single.ts +++ b/examples/queue-manager-demo/src/flows/single.ts @@ -1,6 +1,5 @@ import { RangoClient } from 'rango-sdk-basic'; import { connect, signEvmTx, switchNetwork } from '../wallet'; -import { QueueDef } from '@rango-dev/queue-manager-core'; const RANGO_API_KEY = '4a624ab5-16ff-4f96-90b7-ab00ddfc342c'; const rangoClient = new RangoClient(RANGO_API_KEY); diff --git a/examples/queue-manager-demo/src/index.tsx b/examples/queue-manager-demo/src/index.tsx new file mode 100644 index 0000000000..1a3654be5e --- /dev/null +++ b/examples/queue-manager-demo/src/index.tsx @@ -0,0 +1,72 @@ +import type { WalletType } from '@rango-dev/wallets-shared'; + +import { allProviders } from '@rango-dev/provider-all'; +import { Events, Provider } from '@rango-dev/wallets-react'; +import { RangoClient } from 'rango-sdk'; +import React, { useEffect, useState } from 'react'; +import { createRoot } from 'react-dom/client'; + +import { App } from './App'; +import { + TON_CONNECT_MANIFEST_URL, + TREZOR_MANIFEST, + WC_PROJECT_ID, +} from './configs'; + +const providers = allProviders({ + walletconnect2: { + WC_PROJECT_ID: WC_PROJECT_ID, + }, + trezorManifest: TREZOR_MANIFEST, + tonconnect: { manifestUrl: TON_CONNECT_MANIFEST_URL }, +}); + +function AppContainer() { + const [connectedWallets, setConnectedWallets] = useState([]); + const client = new RangoClient(process.env.REACT_APP_API_KEY as string); + + // Because allBlockChains didn't use the BlockchainMeta type from rango-sdk, we have to use any type + const [blockchains, setBlockChains] = useState([]); + const [, setError] = useState(''); + const [, setLoading] = useState(true); + useEffect(() => { + const getAllBlockchains = async () => { + try { + const res = await client.getAllMetadata(); + setBlockChains(res.blockchains); + } catch (e: any) { + setError(e.message); + } + setLoading(false); + }; + void getAllBlockchains(); + }, []); + + return ( + { + if (event === Events.ACCOUNTS && coreState.connected) { + if (coreState.connected) { + if (!connectedWallets.includes(type)) { + const nextState = [...connectedWallets]; + nextState.push(type); + setConnectedWallets(nextState); + } + } else { + const nextState = [...connectedWallets].filter( + (wallet) => wallet !== type + ); + setConnectedWallets(nextState); + } + } + }}> + + + ); +} + +const container = document.getElementById('app')!; +const root = createRoot(container); +root.render(); diff --git a/queue-manager/demo/src/styles.css b/examples/queue-manager-demo/src/styles.css similarity index 100% rename from queue-manager/demo/src/styles.css rename to examples/queue-manager-demo/src/styles.css diff --git a/examples/queue-manager-demo/src/wallet.js b/examples/queue-manager-demo/src/wallet.js new file mode 100644 index 0000000000..f460896bc2 --- /dev/null +++ b/examples/queue-manager-demo/src/wallet.js @@ -0,0 +1,51 @@ +import { BrowserProvider } from 'ethers'; + +const { ethereum } = window; + +let activeAccount = null; + +export async function connect() { + const accounts = await ethereum.request({ method: 'eth_requestAccounts' }); + activeAccount = accounts[0]; + console.log('connected', activeAccount); +} + +export async function switchNetwork(chainId) { + await ethereum.request({ + method: 'wallet_switchEthereumChain', + params: [{ chainId }], + }); + + console.log('network switched.'); +} + +export async function signEvmTx(evmTransaction) { + const provider = new BrowserProvider(ethereum); + const signer = await provider.getSigner(); + + let tx = {}; + if (!!evmTransaction.from) { + tx = { ...tx, from: evmTransaction.from }; + } + if (!!evmTransaction.txTo) { + tx = { ...tx, to: evmTransaction.txTo }; + } + if (!!evmTransaction.txData) { + tx = { ...tx, data: evmTransaction.txData }; + } + if (!!evmTransaction.value) { + tx = { ...tx, value: evmTransaction.value }; + } + if (!!evmTransaction.gasLimit) { + tx = { ...tx, gasLimit: evmTransaction.gasLimit }; + } + if (!!evmTransaction.gasPrice) { + tx = { ...tx, gasPrice: evmTransaction.gasPrice }; + } + if (!!evmTransaction.nonce) { + tx = { ...tx, nonce: evmTransaction.nonce }; + } + + const tr = await signer.sendTransaction(tx); + return tr.hash; +} diff --git a/examples/queue-manager-demo/tsconfig.build.json b/examples/queue-manager-demo/tsconfig.build.json new file mode 100644 index 0000000000..9e3b11c3e2 --- /dev/null +++ b/examples/queue-manager-demo/tsconfig.build.json @@ -0,0 +1,13 @@ +{ + // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs + "extends": "../../tsconfig.lib.json", + "include": ["src", "types"], + "compilerOptions": { + "outDir": "dist", + "lib": ["dom", "esnext"], + // match output dir to input dir. e.g. dist/index instead of dist/src/index + "rootDir": "./src", + // transpile JSX to React.createElement + "jsx": "react" + } +} diff --git a/examples/queue-manager-demo/tsconfig.json b/examples/queue-manager-demo/tsconfig.json new file mode 100644 index 0000000000..a3a0b0f59d --- /dev/null +++ b/examples/queue-manager-demo/tsconfig.json @@ -0,0 +1 @@ +{ "extends": "./tsconfig.build.json", "include": ["src", "tests"] } diff --git a/examples/wallets-adapter-demo/CHANGELOG.md b/examples/wallets-adapter-demo/CHANGELOG.md new file mode 100644 index 0000000000..8bea989190 --- /dev/null +++ b/examples/wallets-adapter-demo/CHANGELOG.md @@ -0,0 +1,65 @@ +# [0.12.0](https://github.com/rango-exchange/rango-client/compare/wallets-adapter-demo@0.11.0...wallets-adapter-demo@0.12.0) (2023-08-03) + + + +# [0.11.0](https://github.com/rango-exchange/rango-client/compare/wallets-adapter-demo@0.8.0...wallets-adapter-demo@0.11.0) (2023-08-01) + + +### Features + +* add project id as a external value ([0c80404](https://github.com/rango-exchange/rango-client/commit/0c80404a8cacb6c5b0338dea1e416b0b11db254b)) +* Get Wallet Connect project id from config ([9fb30b4](https://github.com/rango-exchange/rango-client/commit/9fb30b4b1a83e2005bbf42553298f24b1e278e1c)) + + + +# [0.9.0](https://github.com/rango-exchange/rango-client/compare/wallets-adapter-demo@0.8.0...wallets-adapter-demo@0.9.0) (2023-07-31) + + +### Features + +* add project id as a external value ([0c80404](https://github.com/rango-exchange/rango-client/commit/0c80404a8cacb6c5b0338dea1e416b0b11db254b)) +* Get Wallet Connect project id from config ([9fb30b4](https://github.com/rango-exchange/rango-client/commit/9fb30b4b1a83e2005bbf42553298f24b1e278e1c)) + + + +# [0.8.0](https://github.com/rango-exchange/rango-client/compare/wallets-adapter-demo@0.7.0...wallets-adapter-demo@0.8.0) (2023-07-11) + + + +# [0.7.0](https://github.com/rango-exchange/rango-client/compare/wallets-adapter-demo@0.6.0...wallets-adapter-demo@0.7.0) (2023-07-11) + + + +# [0.6.0](https://github.com/rango-exchange/rango-client/compare/wallets-adapter-demo@0.5.0...wallets-adapter-demo@0.6.0) (2023-07-11) + + + +# [0.5.0](https://github.com/rango-exchange/rango-client/compare/wallets-adapter-demo@0.4.0...wallets-adapter-demo@0.5.0) (2023-05-31) + + + +# [0.4.0](https://github.com/rango-exchange/rango-client/compare/wallets-adapter-demo@0.3.0...wallets-adapter-demo@0.4.0) (2023-05-31) + + + +# [0.3.0](https://github.com/rango-exchange/rango-client/compare/wallets-adapter-demo@0.2.0...wallets-adapter-demo@0.3.0) (2023-05-30) + + + +# [0.2.0](https://github.com/rango-exchange/rango-client/compare/wallets-adapter-demo@0.1.15...wallets-adapter-demo@0.2.0) (2023-05-30) + + + +## [0.1.15](https://github.com/rango-exchange/rango-client/compare/wallets-adapter-demo@0.1.14...wallets-adapter-demo@0.1.15) (2023-05-15) + + + +## [0.1.14](https://github.com/rango-exchange/rango-client/compare/wallets-adapter-demo@0.1.13...wallets-adapter-demo@0.1.14) (2023-05-15) + + +### Bug Fixes + +* update rango-types and fix notification bugs ([993f185](https://github.com/rango-exchange/rango-client/commit/993f185e0b8c5e5e15a2c65ba2d85d1f9c8daa90)) + + + diff --git a/examples/wallets-adapter-demo/package.json b/examples/wallets-adapter-demo/package.json new file mode 100644 index 0000000000..b2b98fd711 --- /dev/null +++ b/examples/wallets-adapter-demo/package.json @@ -0,0 +1,30 @@ +{ + "name": "@rango-dev/wallets-adapter-demo", + "version": "0.14.1-next.22", + "license": "MIT", + "private": true, + "source": "public/index.html", + "main": "dist/index.html", + "targets": { + "main": false + }, + "browserslist": "> 0.5%, last 2 versions, not dead", + "scripts": { + "dev": "parcel --cache-dir=.parcel-cache", + "build": "parcel build --cache-dir=.parcel-cache", + "clean": "rimraf .parcel-cache && rimraf dist" + }, + "dependencies": { + "@rango-dev/provider-all": "^0.40.1-next.8", + "@rango-dev/wallets-adapter": "^0.36.1-next.12", + "rango-sdk": "^0.1.57", + "react": "^18.2.0", + "react-dom": "^18.2.0" + }, + "@parcel/transformer-js": { + "inlineEnvironment": false + }, + "publishConfig": { + "access": "public" + } +} \ No newline at end of file diff --git a/wallets/wallets-adapter-demo/public/index.html b/examples/wallets-adapter-demo/public/index.html similarity index 100% rename from wallets/wallets-adapter-demo/public/index.html rename to examples/wallets-adapter-demo/public/index.html diff --git a/wallets/wallets-adapter-demo/readme.md b/examples/wallets-adapter-demo/readme.md similarity index 100% rename from wallets/wallets-adapter-demo/readme.md rename to examples/wallets-adapter-demo/readme.md diff --git a/examples/wallets-adapter-demo/src/App.tsx b/examples/wallets-adapter-demo/src/App.tsx new file mode 100644 index 0000000000..b40ec0443c --- /dev/null +++ b/examples/wallets-adapter-demo/src/App.tsx @@ -0,0 +1,44 @@ +import { allProviders } from '@rango-dev/provider-all'; +import { AdapterProvider } from '@rango-dev/wallets-adapter'; +import { RangoClient } from 'rango-sdk'; +import React, { useEffect, useState } from 'react'; + +import WalletsModal from './components/WalletsModal'; +import { + TON_CONNECT_MANIFEST_URL, + TREZOR_MANIFEST, + WC_PROJECT_ID, +} from './constants'; + +const providers = allProviders({ + walletconnect2: { + WC_PROJECT_ID: WC_PROJECT_ID, + }, + trezorManifest: TREZOR_MANIFEST, + tonconnect: { manifestUrl: TON_CONNECT_MANIFEST_URL }, +}); + +export function App() { + const client = new RangoClient(process.env.REACT_APP_API_KEY as string); + + // Because allBlockChains didn't use the BlockchainMeta type from rango-sdk, we have to use any type + const [blockchains, setBlockChains] = useState([]); + + useEffect(() => { + const getAllBlockchains = async () => { + try { + const res = await client.getAllMetadata(); + setBlockChains(res.blockchains); + } catch (e) { + console.log('failed on connect.', e); + } + }; + void getAllBlockchains(); + }, []); + + return ( + + + + ); +} diff --git a/wallets/wallets-adapter-demo/src/components/WalletsModal.tsx b/examples/wallets-adapter-demo/src/components/WalletsModal.tsx similarity index 88% rename from wallets/wallets-adapter-demo/src/components/WalletsModal.tsx rename to examples/wallets-adapter-demo/src/components/WalletsModal.tsx index 7942e5e4f1..3670de2748 100644 --- a/wallets/wallets-adapter-demo/src/components/WalletsModal.tsx +++ b/examples/wallets-adapter-demo/src/components/WalletsModal.tsx @@ -6,4 +6,4 @@ function WalletsModal() { return ; } -export default WalletsModal; \ No newline at end of file +export default WalletsModal; diff --git a/examples/wallets-adapter-demo/src/constants.ts b/examples/wallets-adapter-demo/src/constants.ts new file mode 100644 index 0000000000..02a20ef1ea --- /dev/null +++ b/examples/wallets-adapter-demo/src/constants.ts @@ -0,0 +1,7 @@ +export const WC_PROJECT_ID = 'e24844c5deb5193c1c14840a7af6a40b'; +export const TREZOR_MANIFEST = { + appUrl: 'https://widget.rango.exchange/', + email: 'hi+trezorwidget@rango.exchange', +}; +export const TON_CONNECT_MANIFEST_URL = + 'https://raw.githubusercontent.com/rango-exchange/assets/refs/heads/main/manifests/tonconnect/manifest.json'; diff --git a/examples/wallets-adapter-demo/src/index.tsx b/examples/wallets-adapter-demo/src/index.tsx new file mode 100644 index 0000000000..2417a91a17 --- /dev/null +++ b/examples/wallets-adapter-demo/src/index.tsx @@ -0,0 +1,8 @@ +import React from 'react'; +import { createRoot } from 'react-dom/client'; + +import { App } from './App'; + +const container = document.getElementById('app')!; +const root = createRoot(container); +root.render(); diff --git a/examples/wallets-adapter-demo/tsconfig.build.json b/examples/wallets-adapter-demo/tsconfig.build.json new file mode 100644 index 0000000000..9e3b11c3e2 --- /dev/null +++ b/examples/wallets-adapter-demo/tsconfig.build.json @@ -0,0 +1,13 @@ +{ + // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs + "extends": "../../tsconfig.lib.json", + "include": ["src", "types"], + "compilerOptions": { + "outDir": "dist", + "lib": ["dom", "esnext"], + // match output dir to input dir. e.g. dist/index instead of dist/src/index + "rootDir": "./src", + // transpile JSX to React.createElement + "jsx": "react" + } +} diff --git a/examples/wallets-adapter-demo/tsconfig.json b/examples/wallets-adapter-demo/tsconfig.json new file mode 100644 index 0000000000..a3a0b0f59d --- /dev/null +++ b/examples/wallets-adapter-demo/tsconfig.json @@ -0,0 +1 @@ +{ "extends": "./tsconfig.build.json", "include": ["src", "tests"] } diff --git a/examples/wallets-demo/CHANGELOG.md b/examples/wallets-demo/CHANGELOG.md new file mode 100644 index 0000000000..6d87d3b309 --- /dev/null +++ b/examples/wallets-demo/CHANGELOG.md @@ -0,0 +1,74 @@ +# [0.11.0](https://github.com/rango-exchange/rango-client/compare/wallets-demo@0.10.0...wallets-demo@0.11.0) (2023-08-03) + + + +# [0.10.0](https://github.com/rango-exchange/rango-client/compare/wallets-demo@0.8.0...wallets-demo@0.10.0) (2023-08-01) + + +### Features + +* add project id as a external value ([0c80404](https://github.com/rango-exchange/rango-client/commit/0c80404a8cacb6c5b0338dea1e416b0b11db254b)) +* Get Wallet Connect project id from config ([9fb30b4](https://github.com/rango-exchange/rango-client/commit/9fb30b4b1a83e2005bbf42553298f24b1e278e1c)) +* Support for WalletConnect 2 ([faedef0](https://github.com/rango-exchange/rango-client/commit/faedef0b5e6fc3c5ef881cbbe4ec05334cc1c910)) +* support safe wallet ([d04cbcd](https://github.com/rango-exchange/rango-client/commit/d04cbcd2a612755563512d9dff6f2312088d8b4d)) + + + +# [0.9.0](https://github.com/rango-exchange/rango-client/compare/wallets-demo@0.8.0...wallets-demo@0.9.0) (2023-07-31) + + +### Features + +* add project id as a external value ([0c80404](https://github.com/rango-exchange/rango-client/commit/0c80404a8cacb6c5b0338dea1e416b0b11db254b)) +* Get Wallet Connect project id from config ([9fb30b4](https://github.com/rango-exchange/rango-client/commit/9fb30b4b1a83e2005bbf42553298f24b1e278e1c)) +* Support for WalletConnect 2 ([faedef0](https://github.com/rango-exchange/rango-client/commit/faedef0b5e6fc3c5ef881cbbe4ec05334cc1c910)) +* support safe wallet ([d04cbcd](https://github.com/rango-exchange/rango-client/commit/d04cbcd2a612755563512d9dff6f2312088d8b4d)) + + + +# [0.8.0](https://github.com/rango-exchange/rango-client/compare/wallets-demo@0.7.0...wallets-demo@0.8.0) (2023-07-11) + + + +# [0.7.0](https://github.com/rango-exchange/rango-client/compare/wallets-demo@0.6.0...wallets-demo@0.7.0) (2023-07-11) + + + +# [0.6.0](https://github.com/rango-exchange/rango-client/compare/wallets-demo@0.5.0...wallets-demo@0.6.0) (2023-07-11) + + +### Features + +* add bitkeep wallet ([c02c3df](https://github.com/rango-exchange/rango-client/commit/c02c3dfd236070295eada74aeb97514f8dacd0ed)) + + + +# [0.5.0](https://github.com/rango-exchange/rango-client/compare/wallets-demo@0.4.0...wallets-demo@0.5.0) (2023-05-31) + + + +# [0.4.0](https://github.com/rango-exchange/rango-client/compare/wallets-demo@0.3.0...wallets-demo@0.4.0) (2023-05-31) + + + +# [0.3.0](https://github.com/rango-exchange/rango-client/compare/wallets-demo@0.2.0...wallets-demo@0.3.0) (2023-05-30) + + + +# [0.2.0](https://github.com/rango-exchange/rango-client/compare/wallets-demo@0.1.15...wallets-demo@0.2.0) (2023-05-30) + + + +## [0.1.15](https://github.com/rango-exchange/rango-client/compare/wallets-demo@0.1.14...wallets-demo@0.1.15) (2023-05-15) + + + +## [0.1.14](https://github.com/rango-exchange/rango-client/compare/wallets-demo@0.1.13...wallets-demo@0.1.14) (2023-05-15) + + +### Bug Fixes + +* update rango-types and fix notification bugs ([993f185](https://github.com/rango-exchange/rango-client/commit/993f185e0b8c5e5e15a2c65ba2d85d1f9c8daa90)) + + + diff --git a/examples/wallets-demo/package.json b/examples/wallets-demo/package.json new file mode 100644 index 0000000000..63a721ed83 --- /dev/null +++ b/examples/wallets-demo/package.json @@ -0,0 +1,26 @@ +{ + "name": "@rango-dev/wallets-demo", + "version": "0.13.1-next.22", + "license": "MIT", + "private": true, + "source": "public/index.html", + "main": "dist/index.html", + "targets": { + "main": false + }, + "browserslist": "> 0.5%, last 2 versions, not dead", + "scripts": { + "dev": "parcel -p 3000 --cache-dir=.parcel-cache", + "build": "parcel build --cache-dir=.parcel-cache --no-scope-hoist", + "clean": "rimraf .parcel-cache && rimraf dist" + }, + "dependencies": { + "@rango-dev/provider-all": "^0.40.1-next.8", + "@rango-dev/ui": "^0.42.1-next.11", + "@rango-dev/wallets-react": "^0.26.1-next.9", + "@rango-dev/wallets-shared": "^0.40.1-next.6", + "rango-sdk": "^0.1.57", + "react": "^18.2.0", + "react-dom": "^18.2.0" + } +} \ No newline at end of file diff --git a/wallets/demo/public/index.html b/examples/wallets-demo/public/index.html similarity index 100% rename from wallets/demo/public/index.html rename to examples/wallets-demo/public/index.html diff --git a/wallets/demo/readme.md b/examples/wallets-demo/readme.md similarity index 100% rename from wallets/demo/readme.md rename to examples/wallets-demo/readme.md diff --git a/examples/wallets-demo/src/App.tsx b/examples/wallets-demo/src/App.tsx new file mode 100644 index 0000000000..5aa7451649 --- /dev/null +++ b/examples/wallets-demo/src/App.tsx @@ -0,0 +1,76 @@ +import type { BlockchainMeta, Token } from 'rango-sdk'; + +import { allProviders } from '@rango-dev/provider-all'; +import { ErrorIcon, Spinner, Typography } from '@rango-dev/ui'; +import { Provider } from '@rango-dev/wallets-react'; +import { RangoClient } from 'rango-sdk'; +import React, { useEffect, useState } from 'react'; + +import List from './components/List'; +import { + TON_CONNECT_MANIFEST_URL, + TREZOR_MANIFEST, + WC_PROJECT_ID, +} from './constants'; + +const providers = allProviders({ + walletconnect2: { + WC_PROJECT_ID: WC_PROJECT_ID, + }, + trezorManifest: TREZOR_MANIFEST, + tonconnect: { manifestUrl: TON_CONNECT_MANIFEST_URL }, +}); + +export function App() { + const client = new RangoClient(process.env.REACT_APP_API_KEY as string); + const [blockchains, setBlockChains] = useState([]); + const [tokens, setTokens] = useState([]); + + const [error, setError] = useState(''); + const [loading, setLoading] = useState(true); + + useEffect(() => { + const getAllBlockchains = async () => { + try { + const res = await client.getAllMetadata(); + setBlockChains(res.blockchains); + setTokens(res.tokens); + } catch (e) { + setError(e instanceof Error ? e.message : JSON.stringify(e)); + } + setLoading(false); + }; + void getAllBlockchains(); + }, []); + + return ( + + {!process.env.REACT_APP_API_KEY && ( +

+ Please add REACT_APP_API_KEY + into .env +

+ )} +
+

Providers

+ {loading && ( +
+ + + Loading... + +
+ )} +
+ {!!error && ( +

+ Failed Get Blockchains From Server: {error} +

+ )} + +
+ ); +} diff --git a/examples/wallets-demo/src/components/List/Item.tsx b/examples/wallets-demo/src/components/List/Item.tsx new file mode 100644 index 0000000000..6faeebd2f9 --- /dev/null +++ b/examples/wallets-demo/src/components/List/Item.tsx @@ -0,0 +1,279 @@ +import type { + Network, + WalletInfo, + WalletType, +} from '@rango-dev/wallets-shared'; +import type { Token } from 'rango-sdk'; + +import { + Button, + Divider, + InfoErrorIcon, + ReverseIcon, + Spinner, + Tooltip, + Typography, +} from '@rango-dev/ui'; +import { legacyReadAccountAddress as readAccountAddress } from '@rango-dev/wallets-core/legacy'; +import { useWallets } from '@rango-dev/wallets-react'; +import { detectInstallLink, Networks } from '@rango-dev/wallets-shared'; +import React, { useState } from 'react'; +import './styles.css'; + +import { + evmBasedChainsSelector, + prepareAccounts, + walletAndSupportedChainsNames, +} from '../../helper'; + +import SignModal from './modal'; + +function Item({ + type, + info, + tokens, +}: { + type: WalletType; + info: WalletInfo; + tokens: Token[]; +}) { + const { connect, state, disconnect, canSwitchNetworkTo, getSigners } = + useWallets(); + const [open, setOpen] = useState(false); + const walletState = state(type); + const [network, setNetwork] = useState(Networks.Unknown); + const [error, setError] = useState(''); + const evmBasedChains = evmBasedChainsSelector(info.supportedChains); + const handleConnectWallet = async () => { + if (walletState.connecting) { + return; + } + try { + if (!walletState.connected) { + if (walletState.installed) { + const result = await connect(type); + setError(''); + setNetwork(result.network || Networks.Unknown); + } else { + window.open(detectInstallLink(info.installLink), '_blank'); + } + } else { + void disconnect(type); + } + } catch (err) { + if (err instanceof Error) { + setError('Error: ' + err.message); + } else { + setError('Error: Failed to connect wallet'); + } + } + }; + const canSwitchNetwork = + network !== Networks.Unknown && canSwitchNetworkTo(type, network); + const handleChangeNetwork = async () => { + if (canSwitchNetwork) { + try { + const result = await connect(type, network); + setError(''); + setNetwork(result.network || Networks.Unknown); + } catch (err) { + if (err instanceof Error) { + setError('Error: ' + err.message); + } else { + setError('Error: Failed to connect wallet'); + } + } + } + }; + const handleSigner = () => { + if (!walletState.accounts || !walletState.accounts.length) { + alert( + "You don't currently have an account or you haven't connected to wallet correctly!" + ); + } else { + const supportedChainsNames = walletAndSupportedChainsNames( + info.supportedChains + ); + const activeAccount = prepareAccounts( + walletState.accounts, + walletState.network, + evmBasedChains, + supportedChainsNames + ).find((a) => a.accounts.find((b) => b.isConnected)); + + const isMatchedNetworkWithAccount = walletState.accounts.find((account) => + account?.toLowerCase()?.includes(network?.toLowerCase()) + ); + const address = + walletState.accounts?.length > 1 && isMatchedNetworkWithAccount + ? readAccountAddress( + walletState.accounts + .find((account) => + account?.toLowerCase()?.includes(network?.toLowerCase()) + ) + ?.toLowerCase() || '' + ).address + : activeAccount?.accounts[0].address; + + const currentChain = info.supportedChains.find( + (chain) => chain.name === network + ); + const txType = currentChain?.type; + const chainId = currentChain?.chainId || null; + if (!txType) { + alert('Error in detecting tx type.'); + return; + } + + getSigners(type) + .then(async (signers) => + signers + .getSigner(txType) + .signMessage('Hello World', address || 'meow', chainId) + .then((signature) => { + alert(signature); + }) + ) + .catch((ex) => { + alert( + 'Error' + `(${info.name}): ` + (ex.message || 'Failed to sign') + ); + console.log({ ex }); + }); + } + }; + + return ( +
+
+
+ {walletState.connected ? ( +
+
+ {info.name} +
+

{info.name}

+
+ ) : ( +
+ )} +
+ {walletState.connected && !canSwitchNetwork && ( + <> + + + + + + )} +
+
+
+ + {walletState.connected ? ( + <> +

Accounts:

+
+ {walletState?.accounts?.map((account) => ( +
+ {account} +
+ ))} +
+
+

Chain:

+
{walletState?.network}
+
+ + ) : ( +
+ {info.name} +

{info.name}

+ + {!walletState.installed + ? 'The wallet is not installed' + : 'The wallet is disconnected'} + +
+ )} + + {error && ( +

+ + {error} +

+ )} +
+ +
+ +
+ + + +
+
+ + + +
+
+ {walletState.connected && ( + setOpen(false)} + type={type} + /> + )} +
+ ); +} + +export default Item; diff --git a/examples/wallets-demo/src/components/List/List.tsx b/examples/wallets-demo/src/components/List/List.tsx new file mode 100644 index 0000000000..01eb2d949d --- /dev/null +++ b/examples/wallets-demo/src/components/List/List.tsx @@ -0,0 +1,54 @@ +import type { WalletInfo } from '@rango-dev/wallets-shared'; +import type { Token } from 'rango-sdk'; + +import { allProviders } from '@rango-dev/provider-all'; +import { useWallets } from '@rango-dev/wallets-react'; +import { sortWalletsBasedOnState } from '@rango-dev/wallets-shared'; +import React from 'react'; + +import { + TON_CONNECT_MANIFEST_URL, + TREZOR_MANIFEST, + WC_PROJECT_ID, +} from '../../constants'; + +import Item from './Item'; + +import './styles.css'; + +function List({ tokens }: { tokens: Token[] }) { + const { state, getWalletInfo } = useWallets(); + const providerTypes = allProviders({ + walletconnect2: { WC_PROJECT_ID: WC_PROJECT_ID }, + trezorManifest: TREZOR_MANIFEST, + tonconnect: { manifestUrl: TON_CONNECT_MANIFEST_URL }, + }).map((p) => p.config.type); + const allWallets = sortWalletsBasedOnState( + providerTypes.map((type) => { + const walletState = state(type); + const connected = walletState.connected; + const installed = walletState.installed; + const info = getWalletInfo(type); + return { + type, + connected, + extensionAvailable: installed, + info, + }; + }) + ); + return ( +
+ {allWallets.map((wallet) => ( + + ))} +
+ ); +} + +export default List; diff --git a/examples/wallets-demo/src/components/List/index.ts b/examples/wallets-demo/src/components/List/index.ts new file mode 100644 index 0000000000..f455074564 --- /dev/null +++ b/examples/wallets-demo/src/components/List/index.ts @@ -0,0 +1 @@ +export { default } from './List'; diff --git a/examples/wallets-demo/src/components/List/modal.tsx b/examples/wallets-demo/src/components/List/modal.tsx new file mode 100644 index 0000000000..097e822027 --- /dev/null +++ b/examples/wallets-demo/src/components/List/modal.tsx @@ -0,0 +1,371 @@ +import type { WalletType } from '@rango-dev/wallets-shared'; +import type { + Asset, + BestRouteRequest, + BestRouteResponse, + Token, + TransactionType, +} from 'rango-sdk'; + +import { Button, Divider, Modal, styled, Typography } from '@rango-dev/ui'; +import { useWallets } from '@rango-dev/wallets-react'; +import { isEvmAddress, Networks } from '@rango-dev/wallets-shared'; +import { + isCosmosBlockchain, + isEvmBlockchain, + isSolanaBlockchain, + isStarknetBlockchain, + isTronBlockchain, + RangoClient, + TransactionStatus, +} from 'rango-sdk'; +import React, { useEffect, useRef, useState } from 'react'; + +import { swaps } from '../../constants'; +import { SwapComponent } from '../Swap'; +import './styles.css'; + +type Props = { + type: WalletType; + open: boolean; + onClose: () => void; + tokens: Token[]; +}; + +const SwitchButtonContainer = styled('div', { + display: 'flex', + justifyContent: 'center', + alignItems: 'center', + position: 'relative', + top: '11px', +}); +const INTERVAL_FOR_CHECK = 5_000; + +function SignModal({ type, open, onClose, tokens }: Props) { + const { getWalletInfo, state, getSigners, canSwitchNetworkTo, connect } = + useWallets(); + const client = new RangoClient(process.env.REACT_APP_API_KEY as string); + const { accounts, network } = state(type); + const { supportedChains: blockchains } = getWalletInfo(type); + const blockchain = blockchains.find((chain) => chain.name === network); + const swap = + !!blockchain && + (isEvmBlockchain(blockchain) + ? swaps.EVM + : isCosmosBlockchain(blockchain) + ? swaps.COSMOS + : isSolanaBlockchain(blockchain) + ? swaps.SOLANA + : isStarknetBlockchain(blockchain) + ? swaps.STARKNET + : isTronBlockchain(blockchain) && swaps.TRON); + + const [addresses, setAddresses] = useState([]); + const [bestRoute, setBestRoute] = useState(); + const [loadingSwap, setLoadingSwap] = useState(false); + const [error, setError] = useState(''); + const [hash, setHash] = useState(''); + const [step, setStep] = useState(1); + const signers = getSigners(type); + const timer = useRef({}); + + const resetStates = () => { + setBestRoute(null); + setLoadingSwap(false); + setStep(1); + setHash(''); + }; + + const checkStatus = async () => { + try { + const { status } = await client.checkStatus({ + requestId: bestRoute?.requestId || '', + step, + txId: hash, + }); + if (status === TransactionStatus.SUCCESS && !!bestRoute) { + clearInterval(timer.current as any); + if (step + 1 > (bestRoute.result?.swaps.length || 1)) { + resetStates(); + } else if (step <= (bestRoute.result?.swaps.length || 1)) { + setHash(''); + createTx(bestRoute, step + 1).catch((error) => console.log(error)); + setStep((prev) => prev + 1); + } + alert('Well Done, The swap was successful!'); + } else if (status === TransactionStatus.FAILED) { + setError(`Error requesting check status: faild status`); + setLoadingSwap(false); + clearInterval(timer.current as any); + } + } catch (error) { + console.log(`Error requesting check status: ${error}`); + } + }; + + const canSwitchNetwork = (network: string) => + network !== Networks.Unknown && canSwitchNetworkTo(type, network); + + const handleChangeNetwork = async (network: string) => { + if (canSwitchNetwork(network)) { + try { + await connect(type, network); + } catch (err) { + setError( + 'Error: ' + ((err as any).message || 'Failed to connect wallet') + ); + } + } + }; + const onswap = async () => { + setError(''); + setBestRoute(null); + if (!addresses) { + setError('Please connect your wallet and try again.'); + return; + } + + if (!swap) { + setError(`There is no any swap`); + return; + } + + setLoadingSwap(true); + + const fromToken = swap.from.split('.'); + const toToken = swap.to.split('.'); + + const from: Asset = { + blockchain: fromToken[0], + symbol: fromToken[1], + address: fromToken[2], + }; + const to: Asset = { + blockchain: toToken[0], + symbol: toToken[1], + address: toToken[2], + }; + const amount: string = swap.amount; + let selectedWallets = {}; + addresses.map((account) => { + const [chain, address] = account.split(':'); + selectedWallets = { ...selectedWallets, [chain]: address }; + }); + + const request: BestRouteRequest = { + amount, + from, + to, + swappersGroupsExclude: true, + connectedWallets: [], + selectedWallets, + checkPrerequisites: true, + }; + + try { + const bestRoute = await client.getBestRoute(request); + setBestRoute(bestRoute); + + if (!bestRoute || !bestRoute?.result?.resultType) { + setError( + `Invalid bestRoute response: ${bestRoute?.result?.resultType}, please try again.` + ); + setLoadingSwap(false); + } else { + createTx(bestRoute, step).catch((e) => { + console.log(e); + }); + } + } catch (error) { + setError(`Error requesting bestRoute: ${error}`); + setLoadingSwap(false); + } + }; + const createTx = async (bestRoute: BestRouteResponse, step: number) => { + if (!!bestRoute && !!accounts) { + if ( + network !== bestRoute.from.blockchain && + canSwitchNetwork(bestRoute.from.blockchain) + ) { + await handleChangeNetwork(bestRoute.from.blockchain); + } else { + try { + const { transaction } = await client.createTransaction({ + requestId: bestRoute?.requestId, + step, + userSettings: { + slippage: '1.0', + infiniteApprove: false, + }, + validations: { + balance: false, + fee: false, + }, + }); + if (!transaction) { + setError(`Error requesting create transaction: try again`); + setLoadingSwap(false); + return; + } + + let address = ''; + let chainId: string | null = null; + for (const account of addresses) { + const [chain, walletAddress] = account.split(':'); + if (chain === bestRoute.from.blockchain) { + address = walletAddress; + } + } + + blockchains.map((blockchain) => { + if (blockchain.name === bestRoute.from.blockchain) { + chainId = blockchain.chainId; + } + }); + + const { hash } = await signers + .getSigner(transaction?.type as TransactionType) + .signAndSendTx(transaction, address, chainId); + + setHash(hash); + } catch (e) { + setError( + `Error requesting create transaction: ${ + e instanceof Error ? e.message : e + }` + ); + setLoadingSwap(false); + } + } + } else { + setError('Somting wrong'); + setLoadingSwap(false); + } + }; + const cancel = async () => { + try { + await client.reportFailure({ + eventType: 'USER_CANCEL', + reason: 'Swap canceled by user.', + requestId: bestRoute?.requestId || '', + step, + tags: { wallet: type }, + }); + resetStates(); + clearInterval(timer.current as any); + } catch (e) { + setError(`Error requesting cancel: ${e}`); + } + }; + + useEffect(() => { + let allAdresses: string[] = []; + accounts?.map((account) => { + const [, address] = account.split(':'); + if (!!isEvmAddress(address)) { + allAdresses = [ + ...allAdresses, + ...blockchains.map((chain) => `${chain.name}:${address}`), + ]; + } else { + allAdresses = [...allAdresses, account]; + } + }); + setAddresses(allAdresses); + }, []); + + useEffect(() => { + if (!!hash) { + timer.current = setInterval( + async () => checkStatus(), + INTERVAL_FOR_CHECK + ); + } + }, [hash]); + + useEffect(() => { + if (loadingSwap && bestRoute) { + void createTx(bestRoute, step); + } + }, [network]); + + return ( + { + if (!loadingSwap) { + onClose(); + resetStates(); + } + }} + content={ +
+ swap.from.split('.')[0] === chain.name + ), + token: swap.from.split('.')[1], + addresse: swap.from.split('.')[2], + amount: swap.amount, + }) || + undefined + } + to={ + (!!swap && { + blockchain: blockchains.find( + (chain) => swap.to.split('.')[0] === chain.name + ), + token: swap.to.split('.')[1], + addresse: swap.to.split('.')[2], + amount: swap.amount, + }) || + undefined + } + /> + + + {/* {bestRoute && ( + + )} */} +
+ {!!error && ( + + {error} + + )} +
+ + + + + + +
+
+ } + /> + ); +} + +export default SignModal; diff --git a/wallets/demo/src/components/List/styles.css b/examples/wallets-demo/src/components/List/styles.css similarity index 100% rename from wallets/demo/src/components/List/styles.css rename to examples/wallets-demo/src/components/List/styles.css diff --git a/examples/wallets-demo/src/components/Swap.tsx b/examples/wallets-demo/src/components/Swap.tsx new file mode 100644 index 0000000000..4abde83c0e --- /dev/null +++ b/examples/wallets-demo/src/components/Swap.tsx @@ -0,0 +1,88 @@ +import type { BlockchainMeta, Token } from 'rango-sdk'; + +import { + ChevronRightIcon, + Divider, + Image, + styled, + Typography, +} from '@rango-dev/ui'; +import React from 'react'; + +interface swap { + blockchain?: BlockchainMeta; + token: string; + addresse: string; + amount: string; +} +interface PropTypes { + from?: swap; + to?: swap; + tokens: Token[]; +} + +const Box = styled('div', { + padding: '$16', + display: 'flex', + flexDirection: 'row', + textAlign: 'center', + alignItems: 'center', +}); + +const Content = styled('div', { + display: 'flex', + flexDirection: 'column', + alignItems: 'center', + margin: '0 $10', +}); + +export function SwapComponent(props: PropTypes) { + const { from, to, tokens } = props; + const fromToken = tokens + .filter((token) => token.blockchain === from?.blockchain?.name) + .find((token) => token.symbol === from?.token); + const toToken = tokens + .filter((token) => token.blockchain === to?.blockchain?.name) + .find((token) => token.symbol === to?.token); + return ( + + {!!from && ( + + + + + {from.token} + +
+ + from {from.blockchain?.name} + +
+ + {from.amount} + + + )} + + + + {!!to && ( + + + + + {to.token} + +
+ + from {to.blockchain?.name} + +
+ + - + + + )} + + ); +} diff --git a/examples/wallets-demo/src/constants.ts b/examples/wallets-demo/src/constants.ts new file mode 100644 index 0000000000..ebab30a92d --- /dev/null +++ b/examples/wallets-demo/src/constants.ts @@ -0,0 +1,35 @@ +export const WC_PROJECT_ID = 'e24844c5deb5193c1c14840a7af6a40b'; +export const TREZOR_MANIFEST = { + appUrl: 'https://widget.rango.exchange/', + email: 'hi+trezorwidget@rango.exchange', +}; +export const TON_CONNECT_MANIFEST_URL = + 'https://raw.githubusercontent.com/rango-exchange/assets/refs/heads/main/manifests/tonconnect/manifest.json'; + +export const swaps = { + EVM: { + from: 'BSC.USDC.0x8ac76a51cc950d9822d68b83fe1ad97b32cd580d', + to: 'BSC.BUSD.0xe9e7cea3dedca5984780bafc599bd69add087d56', + amount: '0.1', + }, + STARKNET: { + from: 'STARKNET.USDT.0x68f5c6a61780768455de69077e07e89787839bf8166decfbf92b645209c0fb8', + to: 'STARKNET.ETH.0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7', + amount: '0.1', + }, + SOLANA: { + from: 'SOLANA.SOL', + to: 'SOLANA.WSOL.So11111111111111111111111111111111111111112', + amount: '0.1', + }, + COSMOS: { + from: 'COSMOS.ATOM', + to: 'COSMOS.OSMO.ibc/14f9bc3e44b8a9c1be1fb08980fab87034c9905ef17cf2f5008fc085218811cc', + amount: '0.1', + }, + TRON: { + from: 'TRON.USDT.TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t', + to: 'TRON.TRX', + amount: '0.1', + }, +}; diff --git a/examples/wallets-demo/src/helper.ts b/examples/wallets-demo/src/helper.ts new file mode 100644 index 0000000000..547e33bca5 --- /dev/null +++ b/examples/wallets-demo/src/helper.ts @@ -0,0 +1,87 @@ +import type { Network } from '@rango-dev/wallets-shared'; +import type { BlockchainMeta } from 'rango-sdk'; + +import { legacyReadAccountAddress as readAccountAddress } from '@rango-dev/wallets-core/legacy'; +import { Networks } from '@rango-dev/wallets-shared'; +import { isEvmBlockchain } from 'rango-sdk'; + +export type Blockchain = { + name: Network; + accounts: { address: string; isConnected: boolean }[]; +}; + +export function prepareAccounts( + accounts: string[], + connectedNetwork: Network | null, + evmBasedChains: string[], + supportedChainNames: Network[] | null +): Blockchain[] { + const result = {} as { [type in Network]: Blockchain }; + + function addAccount(network: Network, address: string) { + const isConnected = network === connectedNetwork; + const newAccount = { + address, + isConnected, + }; + + if (result[network]) { + result[network].accounts.push(newAccount); + } else { + result[network] = { + name: network, + accounts: [newAccount], + }; + } + } + + const supportedChains = supportedChainNames || []; + + accounts.forEach((account) => { + const { address, network } = readAccountAddress(account); + + const hasLimitation = supportedChains.length > 0; + const isSupported = supportedChains.includes(network); + const isUnknown = network === Networks.Unknown; + const notSupportedNetworkByWallet = + hasLimitation && !isSupported && !isUnknown; + if (notSupportedNetworkByWallet) { + return; + } + + const isEvmBasedChain = evmBasedChains.includes(network); + + if (isEvmBasedChain) { + const evmChainsSupportedByWallet = supportedChains.filter((chain) => + evmBasedChains.includes(chain) + ); + evmChainsSupportedByWallet.forEach((network) => { + addAccount(network, address.toLowerCase()); + }); + } else { + addAccount(network, address); + } + }); + + return Object.values(result); +} + +export function walletAndSupportedChainsNames( + supportedChains: BlockchainMeta[] +): Network[] | null { + if (!supportedChains) { + return null; + } + let walletAndSupportedChainsNames: string[] = []; + walletAndSupportedChainsNames = supportedChains.map( + (blockchainMeta) => blockchainMeta.name + ); + + return walletAndSupportedChainsNames; +} + +export const evmBasedChainsSelector = (blockchains: BlockchainMeta[]) => + blockchains + .map((blockchainMeta) => blockchainMeta) + .filter(isEvmBlockchain) + .map((blockchainMeta) => blockchainMeta.name); diff --git a/wallets/demo/src/index.css b/examples/wallets-demo/src/index.css similarity index 100% rename from wallets/demo/src/index.css rename to examples/wallets-demo/src/index.css diff --git a/examples/wallets-demo/src/index.tsx b/examples/wallets-demo/src/index.tsx new file mode 100644 index 0000000000..a162909cbc --- /dev/null +++ b/examples/wallets-demo/src/index.tsx @@ -0,0 +1,9 @@ +import React from 'react'; +import { createRoot } from 'react-dom/client'; + +import { App } from './App'; +import './index.css'; + +const container = document.getElementById('app')!; +const root = createRoot(container); +root.render(); diff --git a/examples/wallets-demo/tsconfig.build.json b/examples/wallets-demo/tsconfig.build.json new file mode 100644 index 0000000000..9e3b11c3e2 --- /dev/null +++ b/examples/wallets-demo/tsconfig.build.json @@ -0,0 +1,13 @@ +{ + // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs + "extends": "../../tsconfig.lib.json", + "include": ["src", "types"], + "compilerOptions": { + "outDir": "dist", + "lib": ["dom", "esnext"], + // match output dir to input dir. e.g. dist/index instead of dist/src/index + "rootDir": "./src", + // transpile JSX to React.createElement + "jsx": "react" + } +} diff --git a/examples/wallets-demo/tsconfig.json b/examples/wallets-demo/tsconfig.json new file mode 100644 index 0000000000..a3a0b0f59d --- /dev/null +++ b/examples/wallets-demo/tsconfig.json @@ -0,0 +1 @@ +{ "extends": "./tsconfig.build.json", "include": ["src", "tests"] } diff --git a/global-wallets-env.d.ts b/global-wallets-env.d.ts index 9f826ac5ee..6b6dad9d60 100644 --- a/global-wallets-env.d.ts +++ b/global-wallets-env.d.ts @@ -2,28 +2,42 @@ export {}; declare global { interface Window { - ethereum: any; - braveSolana: any; - BinanceChain: any; - clover: any; - clover_solana: any; - cosmostation: any; - exodus: any; - solana: any; - phantom: any; - xfi: any; - coinbaseSolana: any; - coin98: any; - keplr: any; - isSafePal: any; - safepal: any; - safepalProvider: any; - trustwallet: any; - okxwallet: any; - starknet: any; - tronLink: any; - kucoin: any; - leap: any; - frontier: any; + // Some dependencies can override global environments, so maybe we needed to make some changes to make them compatible. + // This should be optional to `provider-solfare` can be compiled. see: `@solflare-wallet/metamask-sdk/lib/cjs/types.d.ts(74,18)` + ethereum?: any; + braveSolana?: any; + BinanceChain?: any; + clover?: any; + clover_solana?: any; + cosmostation?: any; + exodus?: any; + solana?: any; + phantom?: any; + xfi?: any; + coinbaseWalletExtension?: any; + coinbaseSolana?: any; + coin98?: any; + keplr?: any; + isSafePal?: any; + safepal?: any; + safepalProvider?: any; + trustwallet?: any; + okxwallet?: any; + starknet_argentX?: any; + starknet_braavos?: any; + tronLink?: any; + kucoin?: any; + leap?: any; + frontier?: any; + // This is for Station provider, `@terra-money/wallet-controller` adds this property to window automatically. + // file: node_modules/@terra-money/wallet-controller/modules/extension-router/multiChannel.d.ts + // terraWallets: any; + enkrypt?: any; + tally?: any; + bitkeep?: any; + mytonwallet?: any; + offlineSigner?: any; + tomo_evm?: any; + solflare?: any; } } diff --git a/lingui.config.ts b/lingui.config.ts new file mode 100644 index 0000000000..37c3246a92 --- /dev/null +++ b/lingui.config.ts @@ -0,0 +1,50 @@ +/** @type {import('@lingui/conf').LinguiConfig} */ +module.exports = { + locales: [ + 'af', + 'ar', + 'bn', + 'ca', + 'da', + 'de', + 'el', + 'en', + 'es', + 'fi', + 'fil', + 'fr', + 'hi', + 'hu', + 'id', + 'it', + 'ja', + 'ko', + 'lt', + 'ms', + 'nl', + 'pl', + 'pt', + 'ru', + 'sk', + 'sr', + 'sv', + 'sw', + 'th', + 'tr', + 'uk', + 'ur', + 'vi', + 'zh-CN', + 'zh-TW', + ], + sourceLocale: 'en', + format: 'po', + catalogs: [ + { + path: '/translations/{locale}', + include: ['/widget/embedded/src', '/widget/ui/src'], + exclude: ['**/node_modules/**'], + }, + ], + rootDir: '.', +}; diff --git a/logging/console/CHANGELOG.md b/logging/console/CHANGELOG.md new file mode 100644 index 0000000000..a068ffa849 --- /dev/null +++ b/logging/console/CHANGELOG.md @@ -0,0 +1,25 @@ +# [0.6.0](https://github.com/rango-exchange/rango-client/compare/logging-console@0.5.0...logging-console@0.6.0) (2024-08-11) + + + +# [0.5.0](https://github.com/rango-exchange/rango-client/compare/logging-console@0.3.0...logging-console@0.5.0) (2024-07-09) + + + +# [0.4.0](https://github.com/rango-exchange/rango-client/compare/logging-console@0.3.0...logging-console@0.4.0) (2024-06-01) + + + +# [0.3.0](https://github.com/rango-exchange/rango-client/compare/logging-console@0.2.0...logging-console@0.3.0) (2024-05-14) + + + +# 0.2.0 (2024-03-12) + + +### Features + +* logging packages to be able to create log records and capture them. ([ca9b7e9](https://github.com/rango-exchange/rango-client/commit/ca9b7e918d67bf0d93e5b8313264c5984f3adb4e)) + + + diff --git a/logging/console/package.json b/logging/console/package.json new file mode 100644 index 0000000000..f03b46a36d --- /dev/null +++ b/logging/console/package.json @@ -0,0 +1,29 @@ +{ + "name": "@rango-dev/logging-console", + "version": "0.6.0", + "license": "MIT", + "type": "module", + "source": "./src/index.ts", + "main": "./dist/index.js", + "exports": { + ".": "./dist/index.js" + }, + "typings": "dist/index.d.ts", + "files": [ + "dist", + "src" + ], + "dependencies": { + "@rango-dev/logging-types": "^0.6.0" + }, + "scripts": { + "build": "node ../../scripts/build/command.mjs --path logging/console", + "ts-check": "tsc --declaration --emitDeclarationOnly -p ./tsconfig.json", + "clean": "rimraf dist", + "format": "prettier --write '{.,src}/**/*.{ts,tsx}'", + "lint": "eslint \"**/*.{ts,tsx}\" --ignore-path ../../.eslintignore" + }, + "publishConfig": { + "access": "public" + } +} \ No newline at end of file diff --git a/logging/console/src/helpers.ts b/logging/console/src/helpers.ts new file mode 100644 index 0000000000..17fb6d5514 --- /dev/null +++ b/logging/console/src/helpers.ts @@ -0,0 +1,51 @@ +import type { EventPayload } from '@rango-dev/logging-types'; + +import { Level } from '@rango-dev/logging-types'; + +export function levelToName(level: Level) { + switch (level) { + case Level.Trace: + return 'trace'; + case Level.Debug: + return 'debug'; + case Level.Info: + return 'info'; + case Level.Warn: + return 'warn'; + case Level.Error: + return 'error'; + case Level.Off: + return 'off'; + default: + return `unknown level (${level})`; + } +} + +export function levelToConsoleStyle(level: Level) { + switch (level) { + case Level.Trace: + return 'background-color: #87d9ff; color: #000000;'; + case Level.Debug: + return 'background-color: #4fff00; color: #000000;'; + case Level.Info: + return 'background-color: #ffd800; color: #000000;'; + case Level.Warn: + return 'background-color: #0034ff; color: #000000;'; + case Level.Error: + return 'background-color: #ff0000;'; + case Level.Off: + return 'background-color: #000000;'; + default: + return 'background-color: #cccccc;'; + } +} + +export function formatMessage(payload: EventPayload) { + return [ + `%c[%s] %O %O`, + levelToConsoleStyle(payload.level), + levelToName(payload.level), + payload.message, + payload.data, + ]; +} diff --git a/logging/console/src/index.ts b/logging/console/src/index.ts new file mode 100644 index 0000000000..5c6f9e9642 --- /dev/null +++ b/logging/console/src/index.ts @@ -0,0 +1 @@ +export { layer } from './layer'; diff --git a/logging/console/src/layer.ts b/logging/console/src/layer.ts new file mode 100644 index 0000000000..f72fd7a65c --- /dev/null +++ b/logging/console/src/layer.ts @@ -0,0 +1,34 @@ +import type { Layer } from '@rango-dev/logging-types'; + +import { Level } from '@rango-dev/logging-types'; + +import { formatMessage } from './helpers'; + +export function layer(): Layer { + return { + handler(payload) { + const message = formatMessage(payload); + + switch (payload.level) { + case Level.Trace: + console.debug(...message); + break; + case Level.Debug: + console.debug(...message); + break; + case Level.Info: + console.log(...message); + break; + case Level.Warn: + console.warn(...message); + break; + case Level.Error: + console.error(...message); + break; + default: + console.log(...message); + break; + } + }, + }; +} diff --git a/logging/console/tsconfig.build.json b/logging/console/tsconfig.build.json new file mode 100644 index 0000000000..579fb407b9 --- /dev/null +++ b/logging/console/tsconfig.build.json @@ -0,0 +1,11 @@ +{ + // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs + "extends": "../../tsconfig.lib.json", + "include": ["src", "types"], + "compilerOptions": { + "outDir": "dist", + "rootDir": "./src", + "lib": ["dom", "esnext"] + // match output dir to input dir. e.g. dist/index instead of dist/src/index + } +} diff --git a/logging/console/tsconfig.json b/logging/console/tsconfig.json new file mode 100644 index 0000000000..a3a0b0f59d --- /dev/null +++ b/logging/console/tsconfig.json @@ -0,0 +1 @@ +{ "extends": "./tsconfig.build.json", "include": ["src", "tests"] } diff --git a/logging/core/CHANGELOG.md b/logging/core/CHANGELOG.md new file mode 100644 index 0000000000..a55aa65025 --- /dev/null +++ b/logging/core/CHANGELOG.md @@ -0,0 +1,25 @@ +# [0.6.0](https://github.com/rango-exchange/rango-client/compare/logging-core@0.5.0...logging-core@0.6.0) (2024-08-11) + + + +# [0.5.0](https://github.com/rango-exchange/rango-client/compare/logging-core@0.3.0...logging-core@0.5.0) (2024-07-09) + + + +# [0.4.0](https://github.com/rango-exchange/rango-client/compare/logging-core@0.3.0...logging-core@0.4.0) (2024-06-01) + + + +# [0.3.0](https://github.com/rango-exchange/rango-client/compare/logging-core@0.2.0...logging-core@0.3.0) (2024-05-14) + + + +# 0.2.0 (2024-03-12) + + +### Features + +* logging packages to be able to create log records and capture them. ([ca9b7e9](https://github.com/rango-exchange/rango-client/commit/ca9b7e918d67bf0d93e5b8313264c5984f3adb4e)) + + + diff --git a/logging/core/package.json b/logging/core/package.json new file mode 100644 index 0000000000..64a091e475 --- /dev/null +++ b/logging/core/package.json @@ -0,0 +1,29 @@ +{ + "name": "@rango-dev/logging-core", + "version": "0.6.0", + "license": "MIT", + "type": "module", + "source": "./src/index.ts", + "main": "./dist/index.js", + "exports": { + ".": "./dist/index.js" + }, + "typings": "dist/index.d.ts", + "files": [ + "dist", + "src" + ], + "dependencies": { + "@rango-dev/logging-types": "^0.6.0" + }, + "scripts": { + "build": "node ../../scripts/build/command.mjs --path logging/core", + "ts-check": "tsc --declaration --emitDeclarationOnly -p ./tsconfig.json", + "clean": "rimraf dist", + "format": "prettier --write '{.,src}/**/*.{ts,tsx}'", + "lint": "eslint \"**/*.{ts,tsx}\" --ignore-path ../../.eslintignore" + }, + "publishConfig": { + "access": "public" + } +} \ No newline at end of file diff --git a/logging/core/src/helpers.ts b/logging/core/src/helpers.ts new file mode 100644 index 0000000000..2fd42b6fcf --- /dev/null +++ b/logging/core/src/helpers.ts @@ -0,0 +1,3 @@ +export function isValidInstance(error: unknown) { + return error instanceof Error; +} diff --git a/logging/core/src/index.ts b/logging/core/src/index.ts new file mode 100644 index 0000000000..6d3d176ee3 --- /dev/null +++ b/logging/core/src/index.ts @@ -0,0 +1 @@ +export { error, warn, info, debug, trace, ev } from './logging'; diff --git a/logging/core/src/logging.ts b/logging/core/src/logging.ts new file mode 100644 index 0000000000..30c9fe798f --- /dev/null +++ b/logging/core/src/logging.ts @@ -0,0 +1,44 @@ +import type { Data, EventPayload, Message } from '@rango-dev/logging-types'; + +import { EventType, Level } from '@rango-dev/logging-types'; + +import { isValidInstance } from './helpers'; + +export function ev(level: Level, message: Message, data?: Data) { + if (!isValidInstance(message)) { + throw new Error('Your error input should be an instance of Error.'); + } + + const event = new CustomEvent(EventType, { + detail: { + level, + message, + data, + }, + }); + + if (!document) { + console.warn("document isn't available."); + } else { + document.dispatchEvent(event); + } +} + +export function error(message: Message, data?: Data) { + ev(Level.Error, message, data); +} + +export function warn(message: Message, data?: Data) { + ev(Level.Warn, message, data); +} +export function info(message: Message, data?: Data) { + ev(Level.Info, message, data); +} + +export function debug(message: Message, data?: Data) { + ev(Level.Debug, message, data); +} + +export function trace(message: Message, data?: Data) { + ev(Level.Trace, message, data); +} diff --git a/logging/core/tsconfig.build.json b/logging/core/tsconfig.build.json new file mode 100644 index 0000000000..579fb407b9 --- /dev/null +++ b/logging/core/tsconfig.build.json @@ -0,0 +1,11 @@ +{ + // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs + "extends": "../../tsconfig.lib.json", + "include": ["src", "types"], + "compilerOptions": { + "outDir": "dist", + "rootDir": "./src", + "lib": ["dom", "esnext"] + // match output dir to input dir. e.g. dist/index instead of dist/src/index + } +} diff --git a/logging/core/tsconfig.json b/logging/core/tsconfig.json new file mode 100644 index 0000000000..a3a0b0f59d --- /dev/null +++ b/logging/core/tsconfig.json @@ -0,0 +1 @@ +{ "extends": "./tsconfig.build.json", "include": ["src", "tests"] } diff --git a/logging/readme.md b/logging/readme.md new file mode 100644 index 0000000000..216fa96ddc --- /dev/null +++ b/logging/readme.md @@ -0,0 +1,30 @@ +## How it works? + +Take a look at original PR: +https://github.com/rango-exchange/rango-client/pull/601 + + +## Usage + +log your messages using: +``` +@rango-dev/logging-core +``` + +Listen to you logs (only on clients): +```json + "@rango-dev/logging-subscriber": "0.1.0", + "@rango-dev/logging-console": "0.1.0", +``` + +and + +```js +import { init, Level } from '@rango-dev/logging-subscriber'; +import { layer as consoleLayer } from '@rango-dev/logging-console'; + +init([consoleLayer()], { + baseLevel: Level.Trace, +}); + +``` \ No newline at end of file diff --git a/logging/sentry/CHANGELOG.md b/logging/sentry/CHANGELOG.md new file mode 100644 index 0000000000..75dee0fef9 --- /dev/null +++ b/logging/sentry/CHANGELOG.md @@ -0,0 +1,33 @@ +# [0.8.0](https://github.com/rango-exchange/rango-client/compare/logging-sentry@0.7.0...logging-sentry@0.8.0) (2024-11-12) + + + +# [0.7.0](https://github.com/rango-exchange/rango-client/compare/logging-sentry@0.6.0...logging-sentry@0.7.0) (2024-10-12) + + + +# [0.6.0](https://github.com/rango-exchange/rango-client/compare/logging-sentry@0.5.0...logging-sentry@0.6.0) (2024-08-11) + + + +# [0.5.0](https://github.com/rango-exchange/rango-client/compare/logging-sentry@0.3.0...logging-sentry@0.5.0) (2024-07-09) + + + +# [0.4.0](https://github.com/rango-exchange/rango-client/compare/logging-sentry@0.3.0...logging-sentry@0.4.0) (2024-06-01) + + + +# [0.3.0](https://github.com/rango-exchange/rango-client/compare/logging-sentry@0.2.0...logging-sentry@0.3.0) (2024-05-14) + + + +# 0.2.0 (2024-03-12) + + +### Features + +* logging packages to be able to create log records and capture them. ([ca9b7e9](https://github.com/rango-exchange/rango-client/commit/ca9b7e918d67bf0d93e5b8313264c5984f3adb4e)) + + + diff --git a/logging/sentry/package.json b/logging/sentry/package.json new file mode 100644 index 0000000000..fa2c79141b --- /dev/null +++ b/logging/sentry/package.json @@ -0,0 +1,32 @@ +{ + "name": "@rango-dev/logging-sentry", + "version": "0.8.0", + "license": "MIT", + "type": "module", + "source": "./src/index.ts", + "main": "./dist/index.js", + "exports": { + ".": "./dist/index.js" + }, + "typings": "dist/index.d.ts", + "files": [ + "dist", + "src" + ], + "dependencies": { + "@rango-dev/logging-types": "^0.6.0" + }, + "devDependencies": { + "@sentry/browser": "^7.119.1" + }, + "scripts": { + "build": "node ../../scripts/build/command.mjs --path logging/sentry", + "ts-check": "tsc --declaration --emitDeclarationOnly -p ./tsconfig.json", + "clean": "rimraf dist", + "format": "prettier --write '{.,src}/**/*.{ts,tsx}'", + "lint": "eslint \"**/*.{ts,tsx}\" --ignore-path ../../.eslintignore" + }, + "publishConfig": { + "access": "public" + } +} diff --git a/logging/sentry/src/helpers.ts b/logging/sentry/src/helpers.ts new file mode 100644 index 0000000000..fe6576bb3b --- /dev/null +++ b/logging/sentry/src/helpers.ts @@ -0,0 +1,24 @@ +import type { SeverityLevel } from '@sentry/browser'; + +import { Level } from '@rango-dev/logging-types'; + +const FALLBACK_LEVEL = 'log'; + +export function levelToSentryLevels(level: Level): SeverityLevel { + switch (level) { + case Level.Trace: + return 'log'; + case Level.Debug: + return 'debug'; + case Level.Info: + return 'info'; + case Level.Warn: + return 'warning'; + case Level.Error: + return 'error'; + case Level.Off: + return FALLBACK_LEVEL; + default: + return FALLBACK_LEVEL; + } +} diff --git a/logging/sentry/src/index.ts b/logging/sentry/src/index.ts new file mode 100644 index 0000000000..5c6f9e9642 --- /dev/null +++ b/logging/sentry/src/index.ts @@ -0,0 +1 @@ +export { layer } from './layer'; diff --git a/logging/sentry/src/layer.ts b/logging/sentry/src/layer.ts new file mode 100644 index 0000000000..21225190e0 --- /dev/null +++ b/logging/sentry/src/layer.ts @@ -0,0 +1,36 @@ +import type { Layer } from '@rango-dev/logging-types'; +import type { captureException, Scope, withScope } from '@sentry/browser'; + +import { levelToSentryLevels } from './helpers'; + +type Client = { + withScope: typeof withScope; + captureException: typeof captureException; +}; + +export function layer(client: Client): Layer { + return { + handler(payload) { + client.withScope((scope) => { + const level = levelToSentryLevels(payload.level); + scope.setLevel(level); + + if (payload.data?.context) { + scope.setContext('logging', payload.data.context); + } + + if (payload.data?.tags) { + // eslint-disable-next-line @typescript-eslint/no-magic-numbers + const tags = payload.data.tags as Parameters[0]; + scope.setTags(tags); + } + /* + * https://forum.sentry.io/t/error-object-details-not-showing-up-in-sentry/7081/3 + * We could use this to capture normalized error fields in sentry + */ + scope.setExtra('error', payload.message); + client.captureException(payload.message); + }); + }, + }; +} diff --git a/logging/sentry/tsconfig.build.json b/logging/sentry/tsconfig.build.json new file mode 100644 index 0000000000..579fb407b9 --- /dev/null +++ b/logging/sentry/tsconfig.build.json @@ -0,0 +1,11 @@ +{ + // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs + "extends": "../../tsconfig.lib.json", + "include": ["src", "types"], + "compilerOptions": { + "outDir": "dist", + "rootDir": "./src", + "lib": ["dom", "esnext"] + // match output dir to input dir. e.g. dist/index instead of dist/src/index + } +} diff --git a/logging/sentry/tsconfig.json b/logging/sentry/tsconfig.json new file mode 100644 index 0000000000..a3a0b0f59d --- /dev/null +++ b/logging/sentry/tsconfig.json @@ -0,0 +1 @@ +{ "extends": "./tsconfig.build.json", "include": ["src", "tests"] } diff --git a/logging/subscriber/CHANGELOG.md b/logging/subscriber/CHANGELOG.md new file mode 100644 index 0000000000..eee52cc2fa --- /dev/null +++ b/logging/subscriber/CHANGELOG.md @@ -0,0 +1,25 @@ +# [0.6.0](https://github.com/rango-exchange/rango-client/compare/logging-subscriber@0.5.0...logging-subscriber@0.6.0) (2024-08-11) + + + +# [0.5.0](https://github.com/rango-exchange/rango-client/compare/logging-subscriber@0.3.0...logging-subscriber@0.5.0) (2024-07-09) + + + +# [0.4.0](https://github.com/rango-exchange/rango-client/compare/logging-subscriber@0.3.0...logging-subscriber@0.4.0) (2024-06-01) + + + +# [0.3.0](https://github.com/rango-exchange/rango-client/compare/logging-subscriber@0.2.0...logging-subscriber@0.3.0) (2024-05-14) + + + +# 0.2.0 (2024-03-12) + + +### Features + +* logging packages to be able to create log records and capture them. ([ca9b7e9](https://github.com/rango-exchange/rango-client/commit/ca9b7e918d67bf0d93e5b8313264c5984f3adb4e)) + + + diff --git a/logging/subscriber/package.json b/logging/subscriber/package.json new file mode 100644 index 0000000000..3481f29425 --- /dev/null +++ b/logging/subscriber/package.json @@ -0,0 +1,29 @@ +{ + "name": "@rango-dev/logging-subscriber", + "version": "0.6.0", + "license": "MIT", + "type": "module", + "source": "./src/index.ts", + "main": "./dist/index.js", + "exports": { + ".": "./dist/index.js" + }, + "typings": "dist/index.d.ts", + "files": [ + "dist", + "src" + ], + "dependencies": { + "@rango-dev/logging-types": "^0.6.0" + }, + "scripts": { + "build": "node ../../scripts/build/command.mjs --path logging/subscriber", + "ts-check": "tsc --declaration --emitDeclarationOnly -p ./tsconfig.json", + "clean": "rimraf dist", + "format": "prettier --write '{.,src}/**/*.{ts,tsx}'", + "lint": "eslint \"**/*.{ts,tsx}\" --ignore-path ../../.eslintignore" + }, + "publishConfig": { + "access": "public" + } +} \ No newline at end of file diff --git a/logging/subscriber/src/helpers.ts b/logging/subscriber/src/helpers.ts new file mode 100644 index 0000000000..2c58ce0dca --- /dev/null +++ b/logging/subscriber/src/helpers.ts @@ -0,0 +1,12 @@ +import type { EventPayload, Level } from '@rango-dev/logging-types'; + +export function isEnabled(baseLevel: Level, level: Level) { + return level >= baseLevel; +} + +export function isValidEvent(payload: EventPayload) { + if (!payload.level || !payload.message) { + return false; + } + return true; +} diff --git a/logging/subscriber/src/index.ts b/logging/subscriber/src/index.ts new file mode 100644 index 0000000000..9922e4df7e --- /dev/null +++ b/logging/subscriber/src/index.ts @@ -0,0 +1,2 @@ +export { init } from './subscriber'; +export { Level } from '@rango-dev/logging-types'; diff --git a/logging/subscriber/src/subscriber.ts b/logging/subscriber/src/subscriber.ts new file mode 100644 index 0000000000..d857689ce2 --- /dev/null +++ b/logging/subscriber/src/subscriber.ts @@ -0,0 +1,37 @@ +import type { EventPayload, Layer, Level } from '@rango-dev/logging-types'; + +import { EventType } from '@rango-dev/logging-types'; + +import { isEnabled, isValidEvent } from './helpers'; + +interface Options { + baseLevel: Level; +} + +export function init(layers: Layer[], options: Options) { + const { baseLevel } = options; + + document.addEventListener(EventType, function handler(e) { + // Typescript issue: https://github.com/microsoft/TypeScript/issues/28357 + const event = e as CustomEvent; + + // Runtime check for making sure event has a valid structure. + if (!isValidEvent(event.detail)) { + return; + } + + const level = event.detail.level; + if (!isEnabled(baseLevel, level)) { + // Skipping event. + return; + } + + for (const layer of layers) { + try { + layer.handler(event.detail); + } catch { + break; + } + } + }); +} diff --git a/logging/subscriber/tsconfig.build.json b/logging/subscriber/tsconfig.build.json new file mode 100644 index 0000000000..579fb407b9 --- /dev/null +++ b/logging/subscriber/tsconfig.build.json @@ -0,0 +1,11 @@ +{ + // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs + "extends": "../../tsconfig.lib.json", + "include": ["src", "types"], + "compilerOptions": { + "outDir": "dist", + "rootDir": "./src", + "lib": ["dom", "esnext"] + // match output dir to input dir. e.g. dist/index instead of dist/src/index + } +} diff --git a/logging/subscriber/tsconfig.json b/logging/subscriber/tsconfig.json new file mode 100644 index 0000000000..a3a0b0f59d --- /dev/null +++ b/logging/subscriber/tsconfig.json @@ -0,0 +1 @@ +{ "extends": "./tsconfig.build.json", "include": ["src", "tests"] } diff --git a/logging/types/CHANGELOG.md b/logging/types/CHANGELOG.md new file mode 100644 index 0000000000..a7415b2658 --- /dev/null +++ b/logging/types/CHANGELOG.md @@ -0,0 +1,25 @@ +# [0.6.0](https://github.com/rango-exchange/rango-client/compare/logging-types@0.5.0...logging-types@0.6.0) (2024-08-11) + + + +# [0.5.0](https://github.com/rango-exchange/rango-client/compare/logging-types@0.3.0...logging-types@0.5.0) (2024-07-09) + + + +# [0.4.0](https://github.com/rango-exchange/rango-client/compare/logging-types@0.3.0...logging-types@0.4.0) (2024-06-01) + + + +# [0.3.0](https://github.com/rango-exchange/rango-client/compare/logging-types@0.2.0...logging-types@0.3.0) (2024-05-14) + + + +# 0.2.0 (2024-03-12) + + +### Features + +* logging packages to be able to create log records and capture them. ([ca9b7e9](https://github.com/rango-exchange/rango-client/commit/ca9b7e918d67bf0d93e5b8313264c5984f3adb4e)) + + + diff --git a/logging/types/package.json b/logging/types/package.json new file mode 100644 index 0000000000..7e3f3feed9 --- /dev/null +++ b/logging/types/package.json @@ -0,0 +1,26 @@ +{ + "name": "@rango-dev/logging-types", + "version": "0.6.0", + "license": "MIT", + "type": "module", + "source": "./src/index.ts", + "main": "./dist/index.js", + "exports": { + ".": "./dist/index.js" + }, + "typings": "dist/index.d.ts", + "files": [ + "dist", + "src" + ], + "scripts": { + "build": "node ../../scripts/build/command.mjs --path logging/types", + "ts-check": "tsc --declaration --emitDeclarationOnly -p ./tsconfig.json", + "clean": "rimraf dist", + "format": "prettier --write '{.,src}/**/*.{ts,tsx}'", + "lint": "eslint \"**/*.{ts,tsx}\" --ignore-path ../../.eslintignore" + }, + "publishConfig": { + "access": "public" + } +} diff --git a/logging/types/src/index.ts b/logging/types/src/index.ts new file mode 100644 index 0000000000..2a3cd91abb --- /dev/null +++ b/logging/types/src/index.ts @@ -0,0 +1,26 @@ +/* eslint-disable @typescript-eslint/no-magic-numbers */ +export enum Level { + Off = 99, + Trace = 0, + Debug = 1, + Info = 2, + Warn = 3, + Error = 4, +} + +export const EventType = 'logger-message-event'; + +export interface Layer { + handler(payload: EventPayload): void; +} + +export type Message = Error; +export type Context = Record; +export type Tags = Record; +export type Data = { tags?: Tags; context?: Context } & Record; + +export interface EventPayload { + level: Level; + message: Message; + data?: Data; +} diff --git a/logging/types/tsconfig.build.json b/logging/types/tsconfig.build.json new file mode 100644 index 0000000000..579fb407b9 --- /dev/null +++ b/logging/types/tsconfig.build.json @@ -0,0 +1,11 @@ +{ + // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs + "extends": "../../tsconfig.lib.json", + "include": ["src", "types"], + "compilerOptions": { + "outDir": "dist", + "rootDir": "./src", + "lib": ["dom", "esnext"] + // match output dir to input dir. e.g. dist/index instead of dist/src/index + } +} diff --git a/logging/types/tsconfig.json b/logging/types/tsconfig.json new file mode 100644 index 0000000000..a3a0b0f59d --- /dev/null +++ b/logging/types/tsconfig.json @@ -0,0 +1 @@ +{ "extends": "./tsconfig.build.json", "include": ["src", "tests"] } diff --git a/package.json b/package.json index 124ae2d0ad..aeeaa48112 100644 --- a/package.json +++ b/package.json @@ -3,63 +3,131 @@ "version": "1.0.0", "private": true, "engines": { - "node": ">=14" + "node": ">=20", + "npm": "please-use-yarn" + }, + "workspaces": { + "packages": [ + "examples/*", + "widget/*", + "queue-manager/*", + "wallets/*", + "signers/*", + "logging/*" + ], + "nohoist": [ + "**/@types/web" + ] }, - "workspaces": [ - "widget/*", - "queue-manager/*", - "wallets/*", - "signers/*" - ], "scripts": { - "clean": "nx clear-cache", - "prepare": "husky install", + "clean-root": "rimraf .parcel-cache && nx clear-cache", + "clean": "yarn clean-root && nx run-many --target=clean", + "prepare": "husky install && yarn i18n:compile", + "build:logging": "nx run-many --target=build --projects=@rango-dev/logging-*", "build:signers": "nx run-many --target=build --projects=@rango-dev/signer-* --parallel=5", "build:wallets": "nx run-many --target=build --projects=@rango-dev/signer-*,@rango-dev/wallets-*,@rango-dev/provider-* --exclude @rango-dev/wallets-demo --parallel=5", "build:queue-manager": "nx run-many --target=build --projects=@rango-dev/queue-manager-* --exclude=@rango-dev/queue-manager-demo", "build:widget": "nx run-many --target=build --projects=@rango-dev/widget-*", + "build:iframe": "nx run-many --target=build --projects=@rango-dev/widget-iframe", + "build:all": "nx run-many --target=build", "build": "nx affected --target=build --parallel=3", - "dev:ui": "nx run-many --target=storybook --projects=@rango-dev/ui", + "build:non-demo": "nx affected --target=build --parallel=3 --exclude=@rango-dev/queue-manager-demo,@rango-dev/wallets-demo,@rango-dev/wallets-adapter-demo,@rango-dev/widget-app,@rango-dev/widget-playground", + "dev:ui": "nx run @rango-dev/storybook:dev", "dev:wallets": "node ./scripts/dev-watch/command.mjs --project @rango-dev/wallets-demo", "dev:queue-manager": "node ./scripts/dev-watch/command.mjs --project @rango-dev/queue-manager-demo", - "dev:embedded": "node ./scripts/dev-watch/command.mjs --project @rango-dev/widget-embedded", + "dev:widget:type-checker": "node ./scripts/dev-ts-check/command.mjs --project @rango-dev/widget-app", + "dev:widget:dev-server": "yarn --cwd ./widget/app/ dev", + "dev:widget": "npm-run-all --parallel dev:widget:dev-server dev:widget:type-checker", "dev:wallets-adapter": "node ./scripts/dev-watch/command.mjs --project @rango-dev/wallets-adapter-demo", - "dev:playground": "node ./scripts/dev-watch/command.mjs --project @rango-dev/widget-playground", + "dev:playground:type-checker": "node ./scripts/dev-ts-check/command.mjs --project @rango-dev/widget-playground", + "dev:playground:dev-server": "yarn --cwd ./widget/playground/ dev", + "dev:playground": "npm-run-all --parallel dev:playground:dev-server dev:playground:type-checker", "lint": "nx run-many --target=lint", - "format": "prettier --write \"**/*.{ts,tsx,md}\"", + "format": "nx run-many --target=format", "publish": "node ./scripts/publish/command.mjs", - "release": "node ./scripts/release/command.mjs", - "upgrade-all": "node ./scripts/upgrade-all/command.mjs --project " + "deploy": "node ./scripts/deploy/command.mjs", + "release-prod": "node ./scripts/release/command.mjs", + "post-release-prod": "node ./scripts/post-release/command.mjs", + "upgrade-all": "node ./scripts/upgrade-all/command.mjs --project ", + "i18n:extract": "lingui extract --clean", + "i18n:compile": "lingui compile --typescript", + "i18n": "yarn i18n:extract && yarn i18n:compile", + "test": "vitest", + "test:coverage": "vitest run --coverage", + "commitlint": "commitlint --edit", + "postinstall": "patch-package && yarn workspace @rango-dev/signer-cosmos run patch-package" }, "dependencies": { - "@size-limit/preset-small-lib": "^8.1.0", "husky": "^8.0.3", - "size-limit": "^8.1.0", - "tsdx": "^0.14.1", "tslib": "^2.4.1", - "typescript": "^4.9.3" + "typescript": "^5.3.3" }, "devDependencies": { + "@actions/core": "^1.10.1", + "@babel/core": "^7.22.5", + "@commitlint/cli": "^18.6.1", + "@commitlint/config-conventional": "^18.6.2", + "@faker-js/faker": "^8.4.1", + "@lingui/cli": "^4.2.1", "@nrwl/workspace": "^15.9.2", "@types/react": "^18.0.26", "@types/react-dom": "^18.0.10", + "@typescript-eslint/eslint-plugin": "^5.59.7", + "@typescript-eslint/parser": "^5.59.7", + "@vercel/routing-utils": "^3.1.0", + "@vitest/coverage-v8": "^2.0.5", + "@testing-library/react": "^16.0.0", + "@testing-library/dom": "^10.1.0", + "@testing-library/react-hooks": "^8.0.1", + "happy-dom": "^14.12.0", + "react-test-renderer": "^18.3.1", "buffer": "^5.5.0", "chalk": "^5.2.0", "command-line-args": "^5.2.1", "conventional-changelog-angular": "^5.0.13", + "conventional-changelog-cli": "^2.2.2", + "conventional-commits-filter": "^2.0.7", + "conventional-commits-parser": "^3.2.4", "conventional-recommended-bump": "^6.1.0", + "crypto-browserify": "^3.12.0", + "esbuild": "^0.20.1", + "esbuild-plugins-node-modules-polyfill": "^1.6.6", + "eslint": "^8.41.0", + "eslint-config-prettier": "^8.8.0", + "eslint-plugin-destructuring": "^2.2.1", + "eslint-plugin-import": "^2.27.5", + "eslint-plugin-jsx-id-attribute-enforcement": "^1.0.2", + "eslint-plugin-prettier": "^4.2.1", + "eslint-plugin-react": "^7.32.2", + "eslint-plugin-react-hooks": "^4.6.0", "execa": "^7.1.1", - "nx": "15.9.2", + "filesize": "^10.1.2", + "lint-staged": "^13.2.2", + "npm-run-all": "^4.1.5", + "nx": "16.2.1", + "os-browserify": "^0.3.0", + "parcel": "^2.11.0", + "patch-package": "^8.0.0", + "postinstall-postinstall": "^2.1.0", "prettier": "^2.7.1", "punycode": "^1.4.1", + "querystring-es3": "^0.2.1", "react": "^18.2.0", "react-dom": "^18.2.0", + "rimraf": "^5.0.1", + "semver-parser": "^4.1.4", "stream-browserify": "^3.0.0", + "tty-browserify": "^0.0.1", "util": "^0.12.3", - "vercel": "^28.16.12", - "npm-run-all": "^4.1.5" + "vitest": "^2.0.5", + "vm-browserify": "^1.1.2" }, "resolutions": { - "react-refresh": "0.9.0" - } + "react-refresh": "0.9.0", + "protobufjs": "^6.11.4" + }, + "@parcel/resolver-default": { + "packageExports": true + }, + "packageManager": "yarn@1.22.19+sha1.4ba7fc5c6e704fce2066ecbfb0b0d8976fe62447" } diff --git a/patches/@walletconnect+modal+2.6.2.patch b/patches/@walletconnect+modal+2.6.2.patch new file mode 100644 index 0000000000..280aa8f4d8 --- /dev/null +++ b/patches/@walletconnect+modal+2.6.2.patch @@ -0,0 +1,15 @@ +diff --git a/node_modules/@walletconnect/modal/dist/_types/src/client.d.ts b/node_modules/@walletconnect/modal/dist/_types/src/client.d.ts +index fc7c092..258e47f 100644 +--- a/node_modules/@walletconnect/modal/dist/_types/src/client.d.ts ++++ b/node_modules/@walletconnect/modal/dist/_types/src/client.d.ts +@@ -9,8 +9,8 @@ export type WalletConnectModalConfig = ConfigCtrlState & ThemeCtrlState; + export declare class WalletConnectModal { + constructor(config: WalletConnectModalConfig); + private initUi; +- openModal: (options?: import("packages/modal-core/dist/_types/src/controllers/ModalCtrl").OpenOptions | undefined) => Promise; ++ openModal: (options?: import("@walletconnect/modal-core/dist/_types/src/controllers/ModalCtrl").OpenOptions | undefined) => Promise; + closeModal: () => void; +- subscribeModal: (callback: (newState: import("packages/modal-core/dist/_types/src/types/controllerTypes").ModalCtrlState) => void) => () => void; ++ subscribeModal: (callback: (newState: import("@walletconnect/modal-core/dist/_types/src/types/controllerTypes").ModalCtrlState) => void) => () => void; + setTheme: (theme: ThemeCtrlState) => void; + } diff --git a/queue-manager/core/CHANGELOG.md b/queue-manager/core/CHANGELOG.md new file mode 100644 index 0000000000..eb636e56e0 --- /dev/null +++ b/queue-manager/core/CHANGELOG.md @@ -0,0 +1,72 @@ +# [0.27.0](https://github.com/rango-exchange/rango-client/compare/queue-manager-core@0.26.0...queue-manager-core@0.27.0) (2024-08-11) + + +### Features + +* add filter and clear to widget history ([d43b603](https://github.com/rango-exchange/rango-client/commit/d43b603462feabf297d5be389fcaa35402d667b5)) + + + +# [0.26.0](https://github.com/rango-exchange/rango-client/compare/queue-manager-core@0.25.0...queue-manager-core@0.26.0) (2024-02-20) + + + +# [0.25.0](https://github.com/rango-exchange/rango-client/compare/queue-manager-core@0.23.0...queue-manager-core@0.25.0) (2023-12-24) + + +### Bug Fixes + +* fix HMR for widget and playground ([8524820](https://github.com/rango-exchange/rango-client/commit/8524820f10cf0b8921f3db0c4f620ff98daa4103)) + + + +# [0.14.0](https://github.com/rango-exchange/rango-client/compare/queue-manager-core@0.13.0...queue-manager-core@0.14.0) (2023-08-03) + + + +# [0.13.0](https://github.com/rango-exchange/rango-client/compare/queue-manager-core@0.12.0...queue-manager-core@0.13.0) (2023-08-01) + + + +# [0.9.0](https://github.com/rango-exchange/rango-client/compare/queue-manager-core@0.8.0...queue-manager-core@0.9.0) (2023-07-31) + + +### Bug Fixes + +* seems npm needs a bit time to update the cdn and return the correct version ([09168ac](https://github.com/rango-exchange/rango-client/commit/09168acdc3ca400abd2016eebc0c62103edae3a2)) + + +### Features + +* Support for WalletConnect 2 ([faedef0](https://github.com/rango-exchange/rango-client/commit/faedef0b5e6fc3c5ef881cbbe4ec05334cc1c910)) + + + +# [0.7.0](https://github.com/rango-exchange/rango-client/compare/queue-manager-core@0.6.0...queue-manager-core@0.7.0) (2023-07-11) + + + +# [0.6.0](https://github.com/rango-exchange/rango-client/compare/queue-manager-core@0.5.0...queue-manager-core@0.6.0) (2023-07-11) + + + +# [0.5.0](https://github.com/rango-exchange/rango-client/compare/queue-manager-core@0.4.0...queue-manager-core@0.5.0) (2023-05-31) + + + +# [0.4.0](https://github.com/rango-exchange/rango-client/compare/queue-manager-core@0.3.0...queue-manager-core@0.4.0) (2023-05-31) + + + +# [0.3.0](https://github.com/rango-exchange/rango-client/compare/queue-manager-core@0.2.0...queue-manager-core@0.3.0) (2023-05-30) + + + +# [0.2.0](https://github.com/rango-exchange/rango-client/compare/queue-manager-core@0.1.14...queue-manager-core@0.2.0) (2023-05-30) + + + +## [0.1.13](https://github.com/rango-exchange/rango-client/compare/queue-manager-core@0.1.12...queue-manager-core@0.1.13) (2023-05-15) + + + diff --git a/queue-manager/core/package.json b/queue-manager/core/package.json index 2d54b15883..6dc6d67b7a 100644 --- a/queue-manager/core/package.json +++ b/queue-manager/core/package.json @@ -1,43 +1,25 @@ { "name": "@rango-dev/queue-manager-core", - "version": "0.1.12-next.0", + "version": "0.27.0", "license": "MIT", - "module": "dist/queue-manager-core.esm.js", - "main": "dist/index.js", + "type": "module", + "source": "./src/index.ts", + "main": "./dist/index.js", + "exports": { + ".": "./dist/index.js" + }, "typings": "dist/index.d.ts", "files": [ "dist", "src" ], "scripts": { - "dev": "tsdx watch", - "build": "tsdx build --tsconfig ./tsconfig.json", - "test": "tsdx test", - "lint": "tsdx lint", - "size": "size-limit", - "analyze": "size-limit --why" - }, - "husky": { - "hooks": { - "pre-commit": "tsdx lint" - } + "build": "node ../../scripts/build/command.mjs --path queue-manager/core", + "ts-check": "tsc --declaration --emitDeclarationOnly -p ./tsconfig.json", + "clean": "rimraf dist", + "format": "prettier --write '{.,src}/**/*.{ts,tsx}'", + "lint": "eslint \"**/*.{ts,tsx}\" --ignore-path ../../.eslintignore" }, - "prettier": { - "printWidth": 80, - "semi": true, - "singleQuote": true, - "trailingComma": "es5" - }, - "size-limit": [ - { - "path": "dist/queue-manager-core.cjs.production.min.js", - "limit": "10 KB" - }, - { - "path": "dist/queue-manager-core.esm.js", - "limit": "10 KB" - } - ], "devDependencies": { "@types/uuid": "^8.3.4" }, diff --git a/queue-manager/core/readme.md b/queue-manager/core/readme.md index 07a4667d24..04b23683c5 100644 --- a/queue-manager/core/readme.md +++ b/queue-manager/core/readme.md @@ -1 +1,3 @@ -# @rango-dev/queue-manager-core \ No newline at end of file +# @rango-dev/queue-manager-core + +Queue Manager Core diff --git a/queue-manager/core/src/index.ts b/queue-manager/core/src/index.ts index 61f2a521ad..3afe0c8526 100644 --- a/queue-manager/core/src/index.ts +++ b/queue-manager/core/src/index.ts @@ -1,3 +1,4 @@ export * from './manager'; export { default as Persistor, DB_NAME } from './persistor'; export * from './types'; +export type { QueueContext } from './queue'; diff --git a/queue-manager/core/src/manager.ts b/queue-manager/core/src/manager.ts index 694e6d0906..a249d99016 100644 --- a/queue-manager/core/src/manager.ts +++ b/queue-manager/core/src/manager.ts @@ -1,8 +1,12 @@ -import Persistor from './persistor'; -import Queue, { QueueEventHandlers, TaskEvent } from './queue'; -import { QueueStorage, SYNC_POLLING_INTERVAL, Status } from './types'; +import type { QueueEventHandlers, TaskEvent } from './queue'; +import type { QueueStorage } from './types'; + import { v4 as uuidv4 } from 'uuid'; +import Persistor from './persistor'; +import Queue from './queue'; +import { Status, SYNC_POLLING_INTERVAL } from './types'; + export type ManagerContext = object; export type QueueName = string; export type QueueID = string; @@ -67,6 +71,7 @@ export interface Events { onUpdateTask: (queue_id: QueueID, event: TaskEvent) => void; onStorageUpdate: (queue_id: QueueID, data: QueueStorage) => void; onTaskBlock: (queue_id: QueueID) => void; + onDeleteQueue: (queue_id: QueueID) => void; onPersistedDataLoaded: (manager: Manager) => void; } @@ -96,15 +101,16 @@ class Manager { private events: Events; private persistor: Persistor; private context: ManagerContext; - private isPaused: boolean = false; + private isPaused = false; // The client won't get any update on pause, We are using a polling mode to fix this issue for now. - private syncInterval: NodeJS.Timer | null = null; + private syncInterval: number | null = null; /** * * Making an instance, initilize events, setup a persistor and try to recover the last state of the manager. * - * */ + * + */ constructor(options: ManagerOptions) { const defaultEventHandlers: Events = { onCreateQueue: () => { @@ -128,6 +134,9 @@ class Manager { onPersistedDataLoaded: () => { // .. }, + onDeleteQueue: () => { + // ... + }, }; if (options.events) { @@ -145,42 +154,51 @@ class Manager { this.context = options.context || {}; this.persistor = new Persistor(); - this.sync(); + + void this.sync(); if (options.isPaused) { this.pause(); } } + // Create a new queue /** * - * Reading persisted data from storage then brings into memory. + * Create a new queue by client. + * + * It will do the internal things to make a queue from definitions, and running using Manager. * * Notes: - * - Reset the memory, so we can call this method whenever we want and not only on the initialize process. - * - All the events will be tirggered (like onCreateQueue, onCreateTask, onBlock, ....) - * - Try to `resume` if the status is `running`. - * - Trigger `onPersistedDataLoaded` event when queues recovered from storage. + * - After creating the queue, it will be run automatically. + * + * @returns an ID for queue so it can be used to get the created queue later by client. * */ - private async sync() { - // Reading queues from storage - const queues = await this.persistor.getAll(); - - // Reset queues, if anything is exist in memory. - this.queues = new Map(); + public async create( + name: QueueName, + storage: QueueStorage, + options?: { id?: QueueID } + ) { + if (!this.queuesDefs.has(name)) { + throw new Error('You need to add a queue definition first.'); + } - // Brings them into memory - queues.forEach((q) => { + try { + const def = this.queuesDefs.get(name)!; + const queue_id: QueueID = options?.id || uuidv4(); + const createdAt = Date.now(); const list = this.createQueue({ - queue_id: q.id, - queue_name: q.name, + queue_id: queue_id, + queue_name: name, }); - this.add(q.id, { + list.setStorage(storage); + + const createdQueue = this.add(queue_id, { list, - createdAt: q.createdAt, - name: q.name, - status: q.status, + createdAt, + name, + status: Status.PENDING, actions: { run: () => { list.next({ @@ -199,18 +217,258 @@ class Manager { }, }); - list.initTasks({ - state: q.state, - tasks: q.tasks, - storage: q.storage || {}, + /* + * Persist initial queue + * Note: we need to first insert the queue, and then it can be updated by internal events. + */ + await this.persistor.insertQueue({ + id: queue_id, + createdAt, + name: createdQueue.name, + status: createdQueue.status, + tasks: list.tasks, + state: list.state, + storage: list.getStorage(), + }); + + // adding initial tasks + def.run.forEach((action) => { + list.createTask(action); }); - if (q.status === Status.RUNNING && this.shouldExecute()) { - list.resume({ + // After creating a new queue, try to run. + this.execute(); + return queue_id; + } catch (e) { + throw new Error((e as any)?.message); + } + } + /** + * + * Reading persisted data from storage then brings into memory. + * + * Notes: + * - Reset the memory, so we can call this method whenever we want and not only on the initialize process. + * - All the events will be tirggered (like onCreateQueue, onCreateTask, onBlock, ....) + * - Try to `resume` if the status is `running`. + * - Trigger `onPersistedDataLoaded` event when queues recovered from storage. + * + */ + + /** + * Get a queue by its ID. + * + * @returns An object includes queue and its state in `Manager`. + */ + public get(queue_id: QueueID) { + return this.queues.get(queue_id); + } + + /** + * Get all queues from `Manager` + * + * @returns a list of queues includes all the queues and their states. + */ + public getAll() { + return this.queues; + } + + public deleteQueue(queue_id: QueueID) { + this.queues.delete(queue_id); + void this.persistor.deleteQueue(queue_id); + } + + public async clearQueue() { + // Identify queues that are not running + this.queues.forEach((queue, queue_id) => { + if ( + queue.status !== Status.RUNNING && + queue.status !== Status.PENDING && + queue.status !== Status.BLOCKED + ) { + this.deleteQueue(queue_id); + } + }); + } + + /** + * + * Ask from manager to run pending queues. + * + * It only try to run queues with `PENDING` status and ignore all the other statuses. + * + */ + public execute() { + if (!this.shouldExecute()) { + return; + } + + for (const [, q] of Array.from(this.queues)) { + if (q.status === Status.PENDING) { + q.actions.run(); + } + } + } + + /** + * + * Try to find queues with `RUNNING` status to run them again. + * + * It's useful for recovering the queue at some certain points + * like running a currepted task (reloaded when it was running) or needs manual trigger from UI. + * + * @returns + */ + public resume() { + if (!this.shouldExecute()) { + return; + } + + for (const [, q] of Array.from(this.queues)) { + if (q.status === Status.RUNNING) { + q.list.resume({ context: this.getContext(), }); + return; } + } + + // If there is no running queue, try to run a new queue. + this.execute(); + } + + /** + * + * Run all `BLOCKED` queues once again. + * + * If a queue has `BLOCKED` status and the last task is `BLOCKED` as well, + * The task will be run one more time. + * + * Useful for scenarios like we are blocking the queue under some conditions in task, + * We can use this method to ask the queue to run the blocked task one more time and + * maybe this time condtions are met and the queue can be proceed. + * + * @returns + */ + public retry() { + if (!this.shouldExecute()) { + return; + } + + for (const [, q] of Array.from(this.queues)) { + if (q.status === Status.BLOCKED) { + q.list.checkBlock(); + } + } + + // If there is no running queue, try to run a new queue. + this.execute(); + } + + /** + * + * Run a blocked task on a specific queue with the ability to pass more data. + * + * Useful when we have a custom logic for running queue and needs to pass some specific data + * to the task and try to run it manually with the provided data. + * + */ + public forceExecute(queue_id: string, data?: object) { + const queue = this.get(queue_id); + let context = this.getContext(); + if (data) { + context = { + ...context, + ...data, + }; + } + + queue?.list.forceRun({ + context, }); + } + + /** + * Active readonly mode for manager, it means it doesn't run anythin, + * And only can be used to read the data. + */ + public pause() { + if (this.isPaused) { + return; + } + this.isPaused = true; + this.syncInterval = window.setInterval(() => { + void this.sync(); + }, SYNC_POLLING_INTERVAL); + } + + /** + * Activate normal mode which means it will be able to run the queuese as well. + */ + public run() { + // If call this method multiple times, it should be run for once. + if (this.isPaused) { + this.isPaused = false; + if (!!this.syncInterval) { + clearInterval(this.syncInterval); + this.syncInterval = null; + } + void this.sync(); + } + } + + private async sync() { + try { + // Reading queues from storage + const queues = await this.persistor.getAll(); + + // Reset queues, if anything is exist in memory. + this.queues = new Map(); + + // Brings them into memory + queues.forEach((q) => { + const list = this.createQueue({ + queue_id: q.id, + queue_name: q.name, + }); + this.add(q.id, { + list, + createdAt: q.createdAt, + name: q.name, + status: q.status, + actions: { + run: () => { + list.next({ + context: this.getContext(), + }); + }, + cancel: () => { + list.cancel(); + }, + setStorage: (...args) => { + list.setStorage(...args); + }, + getStorage: () => { + return list.getStorage(); + }, + }, + }); + + list.initTasks({ + state: q.state, + tasks: q.tasks, + storage: q.storage || {}, + }); + + if (q.status === Status.RUNNING && this.shouldExecute()) { + list.resume({ + context: this.getContext(), + }); + } + }); + } catch (e) { + console.log(`IndexDB Error: ${e}`); + } // Trigger an event to let the subscribers we are done here. this.events.onPersistedDataLoaded(this); @@ -223,13 +481,9 @@ class Manager { * @returns An instance of `Queue` with wrapped event handlers from Manager. * */ - private createQueue({ - queue_id, - queue_name, - }: { - queue_id: QueueID; - queue_name: QueueName; - }) { + private createQueue(info: { queue_id: QueueID; queue_name: QueueName }) { + const { queue_id, queue_name } = info; + // eslint-disable-next-line @typescript-eslint/no-this-alias const manager = this; const def = this.queuesDefs.get(queue_name)!; const list = new Queue({ @@ -239,13 +493,17 @@ class Manager { this.events.onCreateTask(queue_id, task); this.handleUpdate(queue_id); - if (def.events?.onCreate) def.events.onCreate(task); + if (def.events?.onCreate) { + def.events.onCreate(task); + } }, onUpdate: (task) => { this.events.onUpdateTask(queue_id, task); this.handleUpdate(queue_id); - if (def.events?.onUpdate) def.events.onUpdate(task); + if (def.events?.onUpdate) { + def.events.onUpdate(task); + } }, onUpdateListStatus: (status) => { this.queues.set(queue_id, { @@ -258,12 +516,15 @@ class Manager { // After finishing a queue, try to run other queues. this.execute(); - if (def.events?.onUpdateListStatus) + if (def.events?.onUpdateListStatus) { def.events.onUpdateListStatus(status); + } }, onStorageUpdate: (data) => { this.events.onStorageUpdate(queue_id, data); - if (def.events?.onStorageUpdate) def.events.onStorageUpdate(data); + if (def.events?.onStorageUpdate) { + def.events.onStorageUpdate(data); + } this.handleUpdate(queue_id); }, onBlock: (event) => { @@ -358,190 +619,6 @@ class Manager { return createdQueue; } - // Create a new queue - /** - * - * Create a new queue by client. - * - * It will do the internal things to make a queue from definitions, and running using Manager. - * - * Notes: - * - After creating the queue, it will be run automatically. - * - * @returns an ID for queue so it can be used to get the created queue later by client. - * - */ - public async create( - name: QueueName, - storage: QueueStorage, - options?: { id?: QueueID } - ) { - if (!this.queuesDefs.has(name)) { - throw new Error('You need to add a queue definition first.'); - } - const def = this.queuesDefs.get(name)!; - const queue_id: QueueID = options?.id || uuidv4(); - const createdAt = Date.now(); - const list = this.createQueue({ - queue_id: queue_id, - queue_name: name, - }); - list.setStorage(storage); - - const createdQueue = this.add(queue_id, { - list, - createdAt, - name, - status: Status.PENDING, - actions: { - run: () => { - list.next({ - context: this.getContext(), - }); - }, - cancel: () => { - list.cancel(); - }, - setStorage: (...args) => { - list.setStorage(...args); - }, - getStorage: () => { - return list.getStorage(); - }, - }, - }); - - // Persist initial queue - // Note: we need to first insert the queue, and then it can be updated by internal events. - await this.persistor.insertQueue({ - id: queue_id, - createdAt, - name: createdQueue.name, - status: createdQueue.status, - tasks: list.tasks, - state: list.state, - storage: list.getStorage(), - }); - - // adding initial tasks - def.run.forEach((action) => { - list.createTask(action); - }); - - // After creating a new queue, try to run. - this.execute(); - return queue_id; - } - - /** - * Get a queue by its ID. - * - * @returns An object includes queue and its state in `Manager`. - */ - public get(queue_id: QueueID) { - return this.queues.get(queue_id); - } - - /** - * Get all queues from `Manager` - * - * @returns a list of queues includes all the queues and their states. - */ - public getAll() { - return this.queues; - } - - /** - * - * Ask from manager to run pending queues. - * - * It only try to run queues with `PENDING` status and ignore all the other statuses. - * - */ - public execute() { - if (!this.shouldExecute()) return; - - for (const [, q] of Array.from(this.queues)) { - if (q.status === Status.PENDING) { - q.actions.run(); - } - } - } - - /** - * - * Try to find queues with `RUNNING` status to run them again. - * - * It's useful for recovering the queue at some certain points - * like running a currepted task (reloaded when it was running) or needs manual trigger from UI. - * - * @returns - */ - public resume() { - if (!this.shouldExecute()) return; - - for (const [, q] of Array.from(this.queues)) { - if (q.status === Status.RUNNING) { - q.list.resume({ - context: this.getContext(), - }); - return; - } - } - - // If there is no running queue, try to run a new queue. - this.execute(); - } - - /** - * - * Run all `BLOCKED` queues once again. - * - * If a queue has `BLOCKED` status and the last task is `BLOCKED` as well, - * The task will be run one more time. - * - * Useful for scenarios like we are blocking the queue under some conditions in task, - * We can use this method to ask the queue to run the blocked task one more time and - * maybe this time condtions are met and the queue can be proceed. - * - * @returns - */ - public retry() { - if (!this.shouldExecute()) return; - - for (const [, q] of Array.from(this.queues)) { - if (q.status === Status.BLOCKED) { - q.list.checkBlock(); - } - } - - // If there is no running queue, try to run a new queue. - this.execute(); - } - - /** - * - * Run a blocked task on a specific queue with the ability to pass more data. - * - * Useful when we have a custom logic for running queue and needs to pass some specific data - * to the task and try to run it manually with the provided data. - * - */ - public forceExecute(queue_id: string, data?: object) { - const queue = this.get(queue_id); - let context = this.getContext(); - if (data) { - context = { - ...context, - ...data, - }; - } - - queue?.list.forceRun({ - context, - }); - } - /** * * Sync in-memory state (of `Manager`) with storage (persist). @@ -556,7 +633,7 @@ class Manager { const status = queue.status; const state = queue.list.state; const tasks = queue.list.tasks; - this.persistor.updateQueue(queue_id, { + void this.persistor.updateQueue(queue_id, { status, state, tasks, @@ -565,35 +642,8 @@ class Manager { } } - /** - * Active readonly mode for manager, it means it doesn't run anythin, - * And only can be used to read the data. - */ - public pause() { - if (this.isPaused) return; - this.isPaused = true; - this.syncInterval = setInterval(() => { - this.sync(); - }, SYNC_POLLING_INTERVAL); - } - - /** - * Activate normal mode which means it will be able to run the queuese as well. - */ - public run() { - // If call this method multiple times, it should be run for once. - if (this.isPaused) { - this.isPaused = false; - if (!!this.syncInterval) { - clearInterval(this.syncInterval); - this.syncInterval = null; - } - this.sync(); - } - } - private getContext() { - // eslint-disable-next-line @typescript-eslint/no-explicit-any + // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/ban-ts-comment //@ts-ignore return this.context?.current || {}; } diff --git a/queue-manager/core/src/persistor.ts b/queue-manager/core/src/persistor.ts index b45a6b502d..dd555f6282 100644 --- a/queue-manager/core/src/persistor.ts +++ b/queue-manager/core/src/persistor.ts @@ -1,7 +1,6 @@ -import { openDB, DBSchema, IDBPDatabase } from 'idb'; - -import { QueueID } from './manager'; -import { PersistedQueue } from './types'; +import type { QueueID } from './manager'; +import type { PersistedQueue } from './types'; +import type { DBSchema, IDBPDatabase } from 'idb'; export const DB_NAME = 'queues-manager'; const OBJECT_STORE_NAME = 'queues'; @@ -21,12 +20,19 @@ interface Database extends DBSchema { class Persistor { db: Promise>; constructor() { - this.db = openDB(DB_NAME, VERSION, { - upgrade(db) { - db.createObjectStore(OBJECT_STORE_NAME, { keyPath: 'id' }); - }, - }); + this.db = import('idb') + .then(async (idb) => { + return idb.openDB(DB_NAME, VERSION, { + upgrade(db) { + db.createObjectStore(OBJECT_STORE_NAME, { keyPath: 'id' }); + }, + }); + }) + .catch(() => { + throw new Error("Couldn't load idb."); + }); } + async insertQueue(queue: PersistedQueue) { const db = await this.db; const queueRecord = await db.get(OBJECT_STORE_NAME, queue.id); @@ -40,7 +46,9 @@ class Persistor { const db = await this.db; const currentRecord = await db.get(OBJECT_STORE_NAME, id); - if (!currentRecord) return; + if (!currentRecord) { + return; + } const updatedRecord = { ...currentRecord, @@ -54,6 +62,14 @@ class Persistor { return results; } + async deleteQueue(id: QueueID) { + const db = await this.db; + const currentRecord = await db.get(OBJECT_STORE_NAME, id); + + if (currentRecord) { + await db.delete(OBJECT_STORE_NAME, id); + } + } } export default Persistor; diff --git a/queue-manager/core/src/types.ts b/queue-manager/core/src/types.ts index 04f24d24ed..3369092983 100644 --- a/queue-manager/core/src/types.ts +++ b/queue-manager/core/src/types.ts @@ -1,5 +1,6 @@ -import { QueueID, QueueName } from './manager'; -import Queue, { QueueState, Task } from './queue'; +import type { QueueID, QueueName } from './manager'; +import type { QueueState, Task } from './queue'; +import type Queue from './queue'; export enum Status { PENDING = 'PENDING', @@ -10,7 +11,7 @@ export enum Status { BLOCKED = 'BLOCKED', } -export const SYNC_POLLING_INTERVAL = 5_000 +export const SYNC_POLLING_INTERVAL = 5_000; export type QueueStorage = Record; diff --git a/queue-manager/core/tsconfig.build.json b/queue-manager/core/tsconfig.build.json new file mode 100644 index 0000000000..579fb407b9 --- /dev/null +++ b/queue-manager/core/tsconfig.build.json @@ -0,0 +1,11 @@ +{ + // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs + "extends": "../../tsconfig.lib.json", + "include": ["src", "types"], + "compilerOptions": { + "outDir": "dist", + "rootDir": "./src", + "lib": ["dom", "esnext"] + // match output dir to input dir. e.g. dist/index instead of dist/src/index + } +} diff --git a/queue-manager/core/tsconfig.json b/queue-manager/core/tsconfig.json index a1d99b2777..a3a0b0f59d 100644 --- a/queue-manager/core/tsconfig.json +++ b/queue-manager/core/tsconfig.json @@ -1,36 +1 @@ -{ - // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs - "extends": "../../tsconfig.base.json", - "include": ["src", "types"], - "compilerOptions": { - "module": "esnext", - "lib": ["dom", "esnext"], - "importHelpers": true, - // output .d.ts declaration files for consumers - "declaration": true, - // output .js.map sourcemap files for consumers - "sourceMap": true, - // match output dir to input dir. e.g. dist/index instead of dist/src/index - "rootDir": "./src", - // stricter type-checking for stronger correctness. Recommended by TS - "strict": true, - // linter checks for common issues - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true, - // noUnused* overlap with @typescript-eslint/no-unused-vars, can disable if duplicative - "noUnusedLocals": true, - "noUnusedParameters": true, - // use Node's module resolution algorithm, instead of the legacy TS one - "moduleResolution": "node", - // transpile JSX to React.createElement - "jsx": "react", - // interop between ESM and CJS modules. Recommended by TS - "esModuleInterop": true, - // significant perf increase by skipping checking .d.ts files, particularly those in node_modules. Recommended by TS - "skipLibCheck": true, - // error out if import and file system have a casing mismatch. Recommended by TS - "forceConsistentCasingInFileNames": true, - // `tsdx build` ignores this option, but it is commonly used when type-checking separately with `tsc` - "noEmit": true - } -} +{ "extends": "./tsconfig.build.json", "include": ["src", "tests"] } diff --git a/queue-manager/demo/package.json b/queue-manager/demo/package.json deleted file mode 100644 index c1f60cfbe3..0000000000 --- a/queue-manager/demo/package.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "name": "@rango-dev/queue-manager-demo", - "version": "0.1.13", - "license": "MIT", - "private": true, - "source": "public/index.html", - "browserslist": "> 0.5%, last 2 versions, not dead", - "scripts": { - "dev": "parcel -p 3000 --cache-dir=.parcel-cache", - "build": "parcel build --cache-dir=.parcel-cache" - }, - "devDependencies": { - "parcel": "^2.7.0", - "process": "^0.11.10" - }, - "dependencies": { - "@rango-dev/provider-all": "^0.1.12", - "@rango-dev/queue-manager-core": "^0.1.11", - "@rango-dev/queue-manager-rango-preset": "^0.1.11", - "@rango-dev/queue-manager-react": "^0.1.10", - "@rango-dev/wallets-core": "^0.1.12", - "@rango-dev/wallets-shared": "^0.1.11", - "bignumber.js": "^9.1.1", - "ethers": "^5.7.2", - "rango-sdk-basic": "^0.0.9", - "rango-types": "^0.1.23" - } -} diff --git a/queue-manager/demo/readme.md b/queue-manager/demo/readme.md deleted file mode 100644 index fab3d8047b..0000000000 --- a/queue-manager/demo/readme.md +++ /dev/null @@ -1 +0,0 @@ -# @rango-dev/queue-manager-demo \ No newline at end of file diff --git a/queue-manager/demo/src/App.tsx b/queue-manager/demo/src/App.tsx deleted file mode 100644 index d55ae944c7..0000000000 --- a/queue-manager/demo/src/App.tsx +++ /dev/null @@ -1,58 +0,0 @@ -import React, { useMemo } from 'react'; -import { Provider as ManagerProvider } from '@rango-dev/queue-manager-react'; -import { FlowsList } from './components/FlowsList'; -import { meta } from './flows/rango/mock'; -import { useWallets } from '@rango-dev/wallets-core'; -import { metamaskWallet } from './flows/rango/mock'; -import { Wallet } from './flows/rango/types'; -import { Network, WalletType } from '@rango-dev/wallets-shared'; -import { Wallets } from './components/Wallets'; -import { History } from './components/History'; -import { notifier } from './flows/swap/helpers'; -import { SwapQueueContext, makeQueueDefinition } from '@rango-dev/queue-manager-rango-preset'; -import { getConfig } from './configs'; -const wallet: Wallet = metamaskWallet; - -interface PropTypes { - connectedWallets: WalletType[]; -} - -export function App(props: PropTypes) { - const { providers, getSigners, state, canSwitchNetworkTo, connect } = useWallets(); - - const switchNetwork = (wallet: WalletType, network: Network) => { - if (!canSwitchNetworkTo(wallet, network)) { - return undefined; - } - return connect(wallet, network); - }; - - const allProviders = providers(); - const queueContext: SwapQueueContext = { - meta, - getSigners, - wallets: wallet, - providers: allProviders, - switchNetwork, - connect, - state, - notifier, - }; - - const swapQueueDef = useMemo(() => { - return makeQueueDefinition({ - API_KEY: getConfig('API_KEY'), - }); - }, []); - - return ( - // @ts-ignore - - -

Flows

- -

History

- -
- ); -} diff --git a/queue-manager/demo/src/components/FlowsList/index.tsx b/queue-manager/demo/src/components/FlowsList/index.tsx deleted file mode 100644 index a4293634d2..0000000000 --- a/queue-manager/demo/src/components/FlowsList/index.tsx +++ /dev/null @@ -1,150 +0,0 @@ -import { useManager } from "@rango-dev/queue-manager-react"; -import React, { useEffect, useState } from "react"; -import { - requestSwap, - urlToToken, -} from "../../flows/rango/helpers"; -import { FlowRunner } from "../FlowRunner"; -import { WalletType } from "@rango-dev/wallets-shared"; - -interface PropTypes { - connectedWallets: WalletType[]; -} - -function FlowsList(props: PropTypes) { - const { manager } = useManager(); - const [fromToken, setFrom] = useState( - "FANTOM.USDC--0x04068da6c83afcfa0e13ba15a6696662335d5b75" - ); - const [toToken, setTo] = useState("COSMOS.ATOM"); - const [input, setInput] = useState("10"); - - useEffect(() => { - manager?.run(); - }, []); - - useEffect(() => { - if (props.connectedWallets.length) { - console.log("[React] run retry on `props.connectedWallets`"); - manager?.retry(); - } - }, [props.connectedWallets]); - - const flows = [ - { - title: "Single Wallet", - description: "Run a simple swap by metamask", - requirements: ["Use metamsk", "Change your network to ethereum."], - onRun: () => { - const qId = manager?.create("simpleSwap", {}); - console.debug(`[Queue] created. ID: ${qId}`, manager); - }, - }, - { - title: "Rango Swap (On-chain)", - description: "Run a swap using Rango flow.", - requirements: ["Please use Metamask & Keplr", "USDC -> USDT"], - onRun: async () => { - const from = urlToToken( - "POLYGON.USDC--0x2791bca1f2de4661ed88a30c99a7a9449aa84174" - )!; - const to = urlToToken( - "POLYGON.USDT--0xc2132d05d31c914a87c6611c10748aeb04b58e8f" - )!; - const swap = await requestSwap("2", from, to); - // toast({ eventType: 'swap_started', swap: newSwap, step: newSwap.steps[0] }); - const qId = manager?.create("rango-swap", { - swapDetails: swap, - }); - console.debug(`[Queue] Swap created. ID: ${qId}`, manager); - }, - }, - { - title: "Rango Swap (Cross-chain)", - description: "Run a swap using Rango flow.", - requirements: ["Please use Metamask & Keplr (cosmos) for now."], - children: ( -
-
- From: - { - setFrom(e.target.value); - }} - /> -
-
- To: - { - setTo(e.target.value); - }} - /> -
-
- Amount: - { - setInput(e.target.value); - }} - /> -
-
- ), - onRun: async () => { - const from = urlToToken(fromToken)!; - const to = urlToToken(toToken)!; - const swap = await requestSwap(input, from, to); - // toast({ eventType: 'swap_started', swap: newSwap, step: newSwap.steps[0] }); - const qId = manager?.create("rango-swap", { - swapDetails: swap, - }); - console.debug(`[Queue] Swap created. ID: ${qId}`, manager); - }, - }, - { - title: "Rango Parallel Swaps", - description: "Run multiple swaps at the same time using Rango flow.", - requirements: [ - "Please use Metamask & Keplr (cosmos) for now.", - "FTM -> ATOM and USDC -> USDT on polygon", - ], - onRun: async () => { - const from1 = urlToToken( - "POLYGON.USDC--0x2791bca1f2de4661ed88a30c99a7a9449aa84174" - )!; - const to1 = urlToToken( - "POLYGON.USDT--0xc2132d05d31c914a87c6611c10748aeb04b58e8f" - )!; - const from2 = urlToToken( - "FANTOM.USDC--0x04068da6c83afcfa0e13ba15a6696662335d5b75" - )!; - const to2 = urlToToken("COSMOS.ATOM")!; - const swap1 = await requestSwap("2", from1, to1); - const swap2 = await requestSwap("10", from2, to2); - - // toast({ eventType: 'swap_started', swap: newSwap, step: newSwap.steps[0] }); - const qId = manager?.create("rango-swap", { swapDetails: swap1 }); - const q2Id = manager?.create("rango-swap", { swapDetails: swap2 }); - console.debug(`[Queue] Swap created. ID: ${qId}`); - console.debug(`[Queue] Swap created. ID: ${q2Id}`); - }, - }, - ]; - - return ( -
- {flows.map((flow, i) => ( - - ))} -
- ); -} - -export { FlowsList }; diff --git a/queue-manager/demo/src/components/Wallets/index.tsx b/queue-manager/demo/src/components/Wallets/index.tsx deleted file mode 100644 index 02f212aca6..0000000000 --- a/queue-manager/demo/src/components/Wallets/index.tsx +++ /dev/null @@ -1,39 +0,0 @@ -import React from "react"; -import { useWallets } from "@rango-dev/wallets-core"; -import { WalletType } from "@rango-dev/wallets-shared"; - -function Wallets() { - const { connect, providers, state, disconnect } = useWallets(); - // @ts-ignore - const list = Object.keys(providers()); - return ( -
-

Available Wallets

-
- {list.map((type) => { - const wallet_type = type as WalletType; - const wallet_state = state(wallet_type); - return ( -
-
{wallet_type}
-

Address: {wallet_state.accounts?.join(",")}

- -
- ); - })} -
-
- ); -} - -export { Wallets }; diff --git a/queue-manager/demo/src/configs.ts b/queue-manager/demo/src/configs.ts deleted file mode 100644 index 6b86455f81..0000000000 --- a/queue-manager/demo/src/configs.ts +++ /dev/null @@ -1,26 +0,0 @@ -export interface Configs { - API_KEY: string; -} - -// this API key is limited and -// it is only for test purpose -const RANGO_PUBLIC_API_KEY = 'c6381a79-2817-4602-83bf-6a641a409e32'; - -let configs: Configs = { - API_KEY: RANGO_PUBLIC_API_KEY, -}; - -export function getConfig(name: keyof Configs) { - return configs[name]; -} - -export function setConfig(name: keyof Configs, value: any) { - configs[name] = value; - - return value; -} - -export function initConfig(nextConfigs: Configs) { - configs = structuredClone(nextConfigs); - return configs; -} diff --git a/queue-manager/demo/src/flows/rango/helpers.ts b/queue-manager/demo/src/flows/rango/helpers.ts deleted file mode 100644 index b3a10187bf..0000000000 --- a/queue-manager/demo/src/flows/rango/helpers.ts +++ /dev/null @@ -1,686 +0,0 @@ -import { - AllBlockchains, - Meta, - Network, - WalletType, - XDEFI_WALLET_SUPPORTED_NATIVE_CHAINS, -} from '@rango-dev/wallets-shared'; - -import { SUPPORTED_ETH_CHAINS as XDEFI_WALLET_SUPPORTED_EVM_CHAINS } from '@rango-dev/provider-xdefi/src/constants'; -import { - APIErrorCode, - ApiMethodName, - BestRoute, - BestRouteRequest, - BINANCE_CHAIN_WALLET_SUPPORTED_CHAINS, - Blockchain, - CheckTxStatusRequest, - CreateTransactionRequest, - CreateTransactionResponse, - ErrorDetail, - EXODUS_WALLET_SUPPORTED_CHAINS, - NETWORKS_FOR_1INCH, - NETWORK_TO_NATIVE_SYMBOL_MAP_FOR_1INCH, - OKX_WALLET_SUPPORTED_CHAINS, - PendingSwap, - PendingSwapNetworkStatus, - PendingSwapStep, - RawAccounts, - SwapperStatusResponse, - SWAPPER_ONE_INCH_LIST, - SwapSavedSettings, - TokenMeta, - TransactionName, - UserWalletBlockchain, - Wallet, - WalletTypeAndAddress, -} from './types'; -import { BigNumber } from 'bignumber.js'; -import { CheckApprovalResponse } from 'rango-sdk-basic'; -import { readAccountAddress } from '@rango-dev/wallets-core'; -import { ethers } from 'ethers'; -import { sampleRawAccounts } from './mock'; -import { - EvmBlockchainMeta, - SignerError, - isCosmosBlockchain, - isEvmBlockchain, - isSolanaBlockchain, -} from 'rango-types'; - -const UNKNOWN_COIN_IMAGE = '/coins/unknown.png'; -const BRAVE_USER_AGENT_HEADER = 'X-Brave'; -const url = 'https://api.rango.exchange'; - -export const BASE_URL = url; -export const RANGO_COOKIE_HEADER = 'X-Rango-Id'; -export const RANGO_DAPP_ID_QUERY = 'apiKey=4a624ab5-16ff-4f96-90b7-ab00ddfc342c'; - -// eslint-disable-next-line @typescript-eslint/no-explicit-any -declare const navigator: any; - -export function calculatePendingSwap( - inputAmount: string, - bestRoute: BestRoute, - wallets: { [p: string]: WalletTypeAndAddress }, - settings: SwapSavedSettings, - validateBalanceOrFee: boolean, -): PendingSwap { - const simulationResult = bestRoute.result; - if (!simulationResult) throw Error('Simulation result should not be null'); - - return { - creationTime: new Date().getTime().toString(), - finishTime: null, - requestId: bestRoute.requestId || '', - inputAmount: inputAmount, - wallets, - status: 'running', - isPaused: false, - extraMessage: null, - extraMessageSeverity: null, - extraMessageDetail: null, - extraMessageErrorCode: null, - networkStatusExtraMessage: null, - networkStatusExtraMessageDetail: null, - lastNotificationTime: null, - settings: settings, - simulationResult: simulationResult, - validateBalanceOrFee, - steps: - bestRoute.result?.swaps?.map((s, i) => ({ - id: i + 1, - fromBlockchain: s.from.blockchain, - fromSymbol: s.from.symbol, - fromSymbolAddress: - NETWORKS_FOR_1INCH.includes(s.from.blockchain) && - SWAPPER_ONE_INCH_LIST.includes(s.swapperId) && - (!s.from.address || s.from.address.length === 0) - ? null - : s.from.address, - fromDecimals: s.from.decimals, - fromAmountPrecision: s.fromAmountPrecision, - fromAmountMinValue: s.fromAmountMinValue, - fromAmountMaxValue: s.fromAmountMaxValue, - toBlockchain: s.to.blockchain, - fromLogo: s.from.logo, - toSymbol: s.to.symbol, - toSymbolAddress: - NETWORKS_FOR_1INCH.includes(s.to.blockchain) && - SWAPPER_ONE_INCH_LIST.includes(s.swapperId) && - NETWORK_TO_NATIVE_SYMBOL_MAP_FOR_1INCH.get(s.to.blockchain) === s.to.symbol && - (!s.to.address || s.to.address.length === 0) - ? null - : s.to.address, - toDecimals: s.to.decimals, - toLogo: s.to.logo, - startTransactionTime: new Date().getTime(), - swapperId: s.swapperId, - expectedOutputAmountHumanReadable: s.toAmount, - outputAmount: null, - status: 'created', - networkStatus: null, - executedTransactionId: null, - externalTransactionId: null, - explorerUrl: null, - trackingCode: null, - cosmosTransaction: null, - solanaTransaction: null, - evmTransaction: null, - evmApprovalTransaction: null, - transferTransaction: null, - diagnosisUrl: null, - internalSteps: null, - })) || [], - }; -} - -export function getCookieId(): string { - const key = 'X-Rango-Id'; - const cookieId = window.localStorage.getItem(key); - if (cookieId) { - return cookieId; - } - const value = - Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15); - window.localStorage.setItem(key, value); - return value; -} - -export const getBestRoute = async ( - from: TokenMeta, - to: TokenMeta, - amount: BigNumber, - rawAccounts: RawAccounts, - checkPrerequisites: boolean, - signal: AbortSignal | undefined, - selectedWallets?: { [p: string]: string }, - swappersGroupsBlackList?: string[], - blockchainsWhiteList?: Network[], -): Promise => { - const connectedWallets: UserWalletBlockchain[] = (rawAccounts?.blockchains || []).map((b) => ({ - blockchain: b.name, - addresses: Array.from(new Set(b.accounts.map((a) => a.address))), - })); - - const body: BestRouteRequest = { - from: { - blockchain: from.blockchain, - symbol: from.symbol, - address: from.address, - }, - to: { blockchain: to.blockchain, symbol: to.symbol, address: to.address }, - amount: amount.toString(), - connectedWallets, - selectedWallets: selectedWallets || {}, - checkPrerequisites: checkPrerequisites, - affiliateRef: localStorage.getItem('affiliateRef') || null, - swapperGroups: swappersGroupsBlackList, - ...(!!swappersGroupsBlackList && { swappersGroupsExclude: true }), - blockchains: blockchainsWhiteList, - }; - const url = `${BASE_URL}/routing/best?${RANGO_DAPP_ID_QUERY}`; - - let isBrave: boolean; - try { - isBrave = navigator.brave && (await navigator.brave.isBrave()); - } catch (error) { - isBrave = false; - } - - const response = await fetch(url, { - method: 'POST', - headers: { - 'content-type': 'application/json;charset=UTF-8', - [RANGO_COOKIE_HEADER]: getCookieId(), - ...(isBrave && { [BRAVE_USER_AGENT_HEADER]: 'true' }), - }, - body: JSON.stringify(body), - signal, - }); - const res = await response.json(); - if (res?.status === 500 || res?.error) { - throw new Error(res?.error || `Error from server, status: ${res.status}`); - } - return res; -}; - -export const urlToToken = (s: string | null): TokenMeta | null => { - if (!s) return null; - - const ps1 = s.split('--'); - const ps2 = ps1[0].split('.'); - - return { - // symbol: ps2[1], // this doesnt work for USDT.E (on avax) AVAX.WETH.E--0x49d5c2bdffac6ce2bfdb6640f4f80f226bc10bab - symbol: ps2.slice(1).join('.'), - image: UNKNOWN_COIN_IMAGE, - blockchain: ps2[0] as Network, - address: ps1.length === 2 ? decodeURIComponent(ps1[1]) : null, - usdPrice: null, - isSecondaryCoin: false, - coinSource: null, - name: null, - coinSourceUrl: null, - decimals: 18, - }; -}; - -export async function checkApproved(requestId: string): Promise { - const url = `${BASE_URL}/tx/${requestId}/check-approval?${RANGO_DAPP_ID_QUERY}`; - const response = await fetch(url, { - method: 'GET', - headers: { - 'content-type': 'application/json;charset=UTF-8', - [RANGO_COOKIE_HEADER]: getCookieId(), - }, - }); - - if ((!!response.status && (response.status < 200 || response.status >= 400)) || !response.ok) { - const apiError = ERROR_COMMUNICATING_WITH_API(ApiMethodName.CheckApproval); - throw PrettyError.BadStatusCode(apiError, response.status); - } - - return await response.json(); -} - -export async function checkSwapStatus( - requestId: string, - txId: string, - step: number, -): Promise { - const url = `${BASE_URL}/tx/check-status?${RANGO_DAPP_ID_QUERY}`; - const body: CheckTxStatusRequest = { step, txId, requestId }; - - const response = await fetch(url, { - method: 'POST', - headers: { - [RANGO_COOKIE_HEADER]: getCookieId(), - 'content-type': 'application/json;charset=UTF-8', - }, - body: JSON.stringify(body), - }); - - if ((!!response.status && (response.status < 200 || response.status >= 400)) || !response.ok) { - const apiError = ERROR_COMMUNICATING_WITH_API(ApiMethodName.CheckingTransactionStatus); - throw PrettyError.BadStatusCode(apiError, response.status); - } - - const res = await response.json(); - return { - ...res, - outputAmount: res.outputAmount ? new BigNumber(res.outputAmount) : null, - }; -} - -export const ERROR_ASSERTION_FAILED = 'Assertion failed (Unexpected behaviour)'; - -export const ERROR_COMMUNICATING_WITH_API = (apiMethodName: ApiMethodName) => - `Unexpected response from API (${apiMethodName})`; - -export const ERROR_DESCRIPTION_UNSUPPORTED_TRANSACTION = (method: string, walletType: WalletType) => - `method: ${method} call is unsupported for wallet ${walletType}`; - -export const ERROR_SIGNING_TRANSACTION = (transactionName: TransactionName) => - `Error sending ${transactionName}`; -export const ERROR_REJECTING_TRANSACTION = 'User rejected the message signing'; - -export const ERROR_CREATE_TRANSACTION = 'Create transaction failed in Rango Server'; -export const ERROR_INPUT_WALLET_NOT_FOUND = 'Input wallet not found'; - -export const DEFAULT_WALLET_INJECTION_ERROR = - 'Failed to connect to wallet, if you have turned injection off (disable default wallet for xDefi), turn it on and refresh the page'; - -export class PrettyError extends Error { - private readonly detail?: string; - private readonly root?: any; - private readonly code?: APIErrorCode; - - constructor(code: APIErrorCode, m: string, root?: any, detail?: string) { - super(m); - Object.setPrototypeOf(this, PrettyError.prototype); - this.code = code; - this.detail = detail; - this.root = root; - } - - getErrorDetail(): ErrorDetail { - const rawMessage = - typeof this.root === 'object' && this.root && this.root.error - ? this.root.error - : JSON.stringify(this.root); - const rootStr = - typeof this.root === 'string' - ? this.root - : this.root instanceof Error - ? this.root.message - : rawMessage; - return { - extraMessage: this.message, - extraMessageDetail: this.detail || rootStr, - extraMessageErrorCode: this.code || null, - }; - } - - static AssertionFailed(m: string): PrettyError { - return new PrettyError('CLIENT_UNEXPECTED_BEHAVIOUR', ERROR_ASSERTION_FAILED, m); - } - - static BadStatusCode(message: string, statusCode: number | string): PrettyError { - return new PrettyError('TX_FAIL', message, null, `status code = ${statusCode}`); - } - - static CreateTransaction(detail: string): PrettyError { - return new PrettyError('FETCH_TX_FAILED', ERROR_CREATE_TRANSACTION, null, detail); - } - - static WalletMissing(): PrettyError { - return new PrettyError( - 'CLIENT_UNEXPECTED_BEHAVIOUR', - ERROR_INPUT_WALLET_NOT_FOUND, - null, - 'Server requested for a blockchain or address not selected by user', - ); - } - - static BlockchainMissing(): PrettyError { - return new PrettyError( - 'CLIENT_UNEXPECTED_BEHAVIOUR', - ERROR_INPUT_WALLET_NOT_FOUND, - null, - 'Server requested for a blockchain or address not selected by user', - ); - } -} - -export function getNextStep( - swap: PendingSwap, - currentStep: PendingSwapStep, -): PendingSwapStep | null { - return ( - swap.steps.find( - (step) => step.status !== 'failed' && step.status !== 'success' && step.id !== currentStep.id, - ) || null - ); -} - -export async function createTransaction( - request: CreateTransactionRequest, -): Promise { - const url = `${BASE_URL}/tx/create?${RANGO_DAPP_ID_QUERY}`; - try { - const response = await fetch(url, { - method: 'POST', - headers: { - 'content-type': 'application/json;charset=UTF-8', - [RANGO_COOKIE_HEADER]: getCookieId(), - }, - body: JSON.stringify(request), - }); - - if ((!!response.status && (response.status < 200 || response.status >= 400)) || !response.ok) { - throw PrettyError.CreateTransaction( - `Error creating the transaction, status code: ${response.status}`, - ); - } - - const result: CreateTransactionResponse = await response.json(); - if (!result.ok || !result.transaction) - throw PrettyError.CreateTransaction(result.error || 'bad response from create tx endpoint'); - - return result; - } catch (error: any) { - throw PrettyError.CreateTransaction(error.message); - } -} - -export const prettifyErrorMessage = (obj: unknown): ErrorDetail => { - if (!obj) return { extraMessage: '', extraMessageErrorCode: null }; - if (obj instanceof PrettyError) return obj.getErrorDetail(); - if (obj instanceof SignerError) { - const t = obj.getErrorDetail(); - return { - extraMessage: t.message, - extraMessageDetail: t.detail, - extraMessageErrorCode: t.code, - }; - } - if (obj instanceof Error) - return { - extraMessage: obj.toString(), - extraMessageErrorCode: null, - }; - if (typeof obj !== 'string') - return { - extraMessage: JSON.stringify(obj), - extraMessageErrorCode: null, - }; - return { extraMessage: obj, extraMessageErrorCode: null }; -}; - -export const getEvmApproveUrl = ( - tx: string, - network: Network, - evmBasedBlockchains: EvmBlockchainMeta[], -): string => { - const evmBlochain = evmBasedBlockchains.find((blockchain) => blockchain.name === network); - - if (!evmBlochain) { - throw Error(`unsupported network: ${network} for getting approve url.`); - } - - if (evmBlochain.info.transactionUrl) - return evmBlochain.info.transactionUrl.replace('{txHash}', tx.toLowerCase()); - - throw Error(`Explorer url for ${network} is not implemented`); -}; - -export const getCurrentBlockchainOfOrNull = ( - swap: PendingSwap, - step: PendingSwapStep, -): Network | null => { - try { - return getCurrentBlockchainOf(swap, step); - } catch (e) { - return null; - } -}; - -export const getCurrentBlockchainOf = (swap: PendingSwap, step: PendingSwapStep): Network => { - const b1 = - step.evmTransaction?.blockChain || - step.evmApprovalTransaction?.blockChain || - step.cosmosTransaction?.blockChain || - step.solanaTransaction?.blockChain; - if (!!b1) return b1 as Network; - - const transferAddress = step.transferTransaction?.fromWalletAddress; - if (!transferAddress) throw PrettyError.BlockchainMissing(); - - const blockchain = - Object.keys(swap.wallets).find((b) => swap.wallets[b]?.address === transferAddress) || null; - if (blockchain == null) throw PrettyError.BlockchainMissing(); - - // TODO: check why it returns string - return blockchain as Network; -}; - -export interface ConvertToFullAccountInfo { - evmBasedChainsNames: string[]; - supportedChainsByWallets: { [type in WalletType]?: Network[] } | null; -} -export function convertRawAccountToFullAccount( - wallet: WalletType, - accounts: string[], - connectedNetwork: Network | null, - info: ConvertToFullAccountInfo, -): Blockchain[] { - const { evmBasedChainsNames: evmBasedChains, supportedChainsByWallets } = info; - const result = {} as { [type in Network]: Blockchain }; - - function addAccount(network: Network, address: string) { - const isConnected = network === connectedNetwork; - const newAccount = { - address, - balances: null, - loading: true, - walletType: wallet, - isConnected, - error: false, - explorerUrl: null, - }; - - if (!!result[network]) { - result[network].accounts.push(newAccount); - } else { - result[network] = { - name: network, - accounts: [newAccount], - }; - } - } - - const supportedChains = supportedChainsByWallets?.[wallet] || []; - - accounts.forEach((account) => { - const { address, network } = readAccountAddress(account); - - const hasLimitation = supportedChains.length > 0; - const isSupported = supportedChains.includes(network); - const isUnknown = network === Network.Unknown; - const notSupportedNetworkByWallet = hasLimitation && !isSupported && !isUnknown; - - // Here we check given `network` is not supported by wallet - // And also the network is known. - if (notSupportedNetworkByWallet) return; - - // In some cases we can handle unknown network by checking its address - // pattern and act on it. - // Example: showing our evm compatible netwrok when the uknown network is evem. - // Otherwise, we stop executing this function. - const isUknownAndEvmBased = network === Network.Unknown && ethers.utils.isAddress(address); - if (isUnknown && !isUknownAndEvmBased) return; - - const isEvmBasedChain = evmBasedChains.includes(network); - - // If it's an evm network, we will add the address to all the evm chains. - if (isEvmBasedChain || isUknownAndEvmBased) { - // all evm chains are not supported in wallets, so we are adding - // only to those that are supported by wallet. - const evmChainsSupportedByWallet = supportedChains.filter((chain) => - evmBasedChains.includes(chain), - ); - - evmChainsSupportedByWallet.forEach((network) => { - // EVM addresses are not case sensetive. - // Some wallets like Binance-chain return some letters in uppercase which produces bugs in our wallet state. - addAccount(network, address.toLowerCase()); - }); - } else { - addAccount(network, address); - } - }); - - return Object.values(result); -} - -export const evmBasedChainsNamesSelector = (blockchains: AllBlockchains) => - Object.entries(blockchains) - .map(([, blockchainMeta]) => blockchainMeta) - .filter(isEvmBlockchain) - .map((blockchainMeta) => blockchainMeta.name); - -export const walletsAndSupportedChainsMetaSelector = (blockchains: AllBlockchains): any | null => { - // TODO WalletsAndSupportedChains can't find model for return type - if (Object.entries(blockchains).length === 0) return null; - const blockchainsArray = Object.entries(blockchains).map(([, blockchainMeta]) => blockchainMeta); - const evmBlockchains = blockchainsArray.filter(isEvmBlockchain); - const solanaBlockchain = blockchainsArray.filter(isSolanaBlockchain); - const cosmosBlockchains = blockchainsArray.filter(isCosmosBlockchain); - return { - [WalletType.BINANCE_CHAIN]: blockchainsArray.filter((blockchainMeta) => - BINANCE_CHAIN_WALLET_SUPPORTED_CHAINS.includes(blockchainMeta.name as Network), - ), - [WalletType.META_MASK]: evmBlockchains, - [WalletType.COINBASE]: [...evmBlockchains, ...solanaBlockchain], - [WalletType.KEPLR]: cosmosBlockchains.filter((blockchainMeta) => !!blockchainMeta.info), - [WalletType.PHANTOM]: solanaBlockchain, - [WalletType.XDEFI]: blockchainsArray.filter((blockchainMeta) => - [ - ...XDEFI_WALLET_SUPPORTED_EVM_CHAINS, - ...XDEFI_WALLET_SUPPORTED_NATIVE_CHAINS, - Network.SOLANA, - ].includes(blockchainMeta.name as Network), - ), - [WalletType.WALLET_CONNECT]: evmBlockchains, - [WalletType.TRUST_WALLET]: evmBlockchains, - [WalletType.COIN98]: [...evmBlockchains, ...solanaBlockchain], - [WalletType.OKX]: blockchainsArray.filter((blockchainMeta) => - OKX_WALLET_SUPPORTED_CHAINS.includes(blockchainMeta.name as Network), - ), - - [WalletType.EXODUS]: blockchainsArray.filter((blockchainMeta) => - EXODUS_WALLET_SUPPORTED_CHAINS.includes(blockchainMeta.name as Network), - ), - - [WalletType.TOKEN_POCKET]: evmBlockchains, - [WalletType.TERRA_STATION]: [], - [WalletType.LEAP]: [], - [WalletType.MATH]: [...evmBlockchains, ...solanaBlockchain], - [WalletType.SAFEPAL]: [ - ...evmBlockchains, - ...solanaBlockchain, - // ...blockchainsArray.filter((blockchainMeta) => - // SAFEPAL_SUPPORTED_NATIVE_CHAINS.includes(blockchainMeta.name), - // ), - ], - [WalletType.CLOVER]: [...evmBlockchains, ...solanaBlockchain], - [WalletType.COSMOSTATION]: [ - ...evmBlockchains, - ...cosmosBlockchains.filter((blockchainMeta) => !!blockchainMeta.info), - ], - [WalletType.BRAVE]: [...evmBlockchains, ...solanaBlockchain], - [WalletType.UNKNOWN]: [], - }; -}; - -export const walletsAndSupportedChainsNamesSelector = (blockchains) => { - const walletsAndSupportedChainsMeta = walletsAndSupportedChainsMetaSelector(blockchains); - if (!walletsAndSupportedChainsMeta) return null; - const walletsAndSupportedChainsNames: { [type in WalletType]?: Network[] } = {}; - for (const key in walletsAndSupportedChainsMeta) { - walletsAndSupportedChainsNames[key as WalletType] = walletsAndSupportedChainsMeta[ - key as WalletType - ].map((blockchainMeta) => blockchainMeta.name); - } - return walletsAndSupportedChainsNames; -}; - -export async function requestSwap(input: string, from: TokenMeta, to: TokenMeta) { - const inputAmount = input; - const amount = new BigNumber(inputAmount); - const rawAccounts = sampleRawAccounts; - const checkPrerequisites = true; - const signal = undefined; - const selectedWallets = { - BSC: '0x2702d89c1c8658b49c45dd460deebcc45faec03c', - POLYGON: '0x2702d89c1c8658b49c45dd460deebcc45faec03c', - FANTOM: '0x2702d89c1c8658b49c45dd460deebcc45faec03c', - AVAX_CCHAIN: '0x2702d89c1c8658b49c45dd460deebcc45faec03c', - COSMOS: 'cosmos1unf2rcytjxfpz8x8ar63h4qeftadptg5r5qswd', - }; - const swappersGroupsBlackList = []; - const blockchainsWhiteList = []; - - const bestRoute = await getBestRoute( - from, - to, - amount, - rawAccounts, - checkPrerequisites, - signal, - selectedWallets, - swappersGroupsBlackList, - blockchainsWhiteList, - ); - - if (!bestRoute) { - throw 'No route found.'; - } - - const settings = { - slippage: '1.0', - disabledSwappersIds: [], - disabledSwappersGroups: [], - }; - const wallets: { [p: string]: WalletTypeAndAddress } = {}; - if (!!rawAccounts) { - rawAccounts.blockchains.forEach((item) => { - // We know there is only one account. - wallets[item.name] = item.accounts[0]; - }); - } - - const newSwap: PendingSwap = calculatePendingSwap( - inputAmount, - bestRoute, - wallets, - settings, - false, - ); - - return newSwap; -} - -export function logRPCError( - error: unknown, - swap: PendingSwap, - currentStep: PendingSwapStep | undefined, - walletType: WalletType | undefined, -) { - try { - // Sending to sentry - } catch (e) { - console.log({ e }); - } -} diff --git a/queue-manager/demo/src/flows/rango/mock.ts b/queue-manager/demo/src/flows/rango/mock.ts deleted file mode 100644 index 678227ac8e..0000000000 --- a/queue-manager/demo/src/flows/rango/mock.ts +++ /dev/null @@ -1,14289 +0,0 @@ -import { WalletsAndSupportedChains } from "@rango-dev/wallets-core"; -import { Meta, Network, WalletType } from "@rango-dev/wallets-shared"; -import { RawAccounts, Wallet } from "./types"; - -const evmAddress = "0x2702d89c1c8658b49c45dd460deebcc45faec03c"; -const cosmosAddress = "cosmos1unf2rcytjxfpz8x8ar63h4qeftadptg5r5qswd"; - -export const sampleRawAccounts: RawAccounts = (() => { - const evm = [ - "BSC", - "POLYGON", - "ETH", - "AVAX_CCHAIN", - "ARBITRUM", - "FANTOM", - "OPTIMISM", - "OKC", - "CRONOS", - "MOONRIVER", - "MOONBEAM", - "HECO", - "AURORA", - "HARMONY", - "EVMOS", - "GNOSIS", - "FUSE", - "BOBA", - ].map((network) => { - return { - name: network, - accounts: [ - { - address: evmAddress, - walletType: WalletType.META_MASK, - }, - ], - }; - }); - const cosmos = [ - { - name: Network.COSMOS, - accounts: [ - { - address: cosmosAddress, - walletType: WalletType.KEPLR, - }, - ], - }, - ]; - return { - blockchains: [...evm, ...cosmos], - }; -})(); - -export const metamaskWallet = { - blockchains: [ - { - name: "BSC", - accounts: [ - { - address: "0x2702d89c1c8658b49c45dd460deebcc45faec03c", - balances: [ - { - chain: "BSC", - symbol: "SWAP8.IO", - ticker: "SWAP8.IO", - address: "0xcaee79616cffeb53fdda5792742a5c084f879dec", - rawAmount: "980000000000000000000000", - decimal: 18, - amount: "980000", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "PDOT.IO", - ticker: "PDOT.IO", - address: "0x8bd0e87273364ebbe3482efc166f7e0d34d82c25", - rawAmount: "95641000000000000000000", - decimal: 18, - amount: "95641", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "ZEPE.IO", - ticker: "ZEPE.IO", - address: "0x119e2ad8f0c85c6f61afdf0df69693028cdc10be", - rawAmount: "750000000000000000000000", - decimal: 18, - amount: "750000", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "0GAS.IO", - ticker: "0GAS.IO", - address: "0x2231e1c01056aebab3113d684b034b50a99a56c7", - rawAmount: "16000000000000", - decimal: 9, - amount: "16000", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "LUNA", - ticker: "LUNA", - address: "0x030612e22610219733f3e942bb67004d6cbd796b", - rawAmount: "350000000000000000000", - decimal: 18, - amount: "350", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "FTM", - ticker: "FTM", - address: "0xad29abb318791d579433d831ed122afeaf29dcfe", - rawAmount: "60035619283908361569", - decimal: 18, - amount: "60.035619283908361569", - logo: "https://api.rango.exchange/i/mZqhCJ", - usdPrice: null, - }, - { - chain: "BSC", - symbol: "GGBOXS.COM", - ticker: "GGBOXS.COM", - address: "0x2248ba304d2045cdc144866ce37d1435a30b29f3", - rawAmount: "60000000000000000000000", - decimal: 18, - amount: "60000", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "AGP", - ticker: "AGP", - address: "0x1c749d5f5630cf365673bf6c0b6b0570c48da112", - rawAmount: "6300000", - decimal: 6, - amount: "6.3", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "UST", - ticker: "UST", - address: "0x3d4350cd54aef9f9b2c29435e0fa809957b3f30a", - rawAmount: "5015300", - decimal: 6, - amount: "5.0153", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "ALPACA", - ticker: "ALPACA", - address: "0xb926beb62d7a680406e06327c87307c1ffc4ab09", - rawAmount: "50", - decimal: 18, - amount: "0.00000000000000005", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "NUSD", - ticker: "NUSD", - address: "0x23b891e5c62e0955ae2bd185990103928ab817b3", - rawAmount: "25863658894004353627", - decimal: 18, - amount: "25.863658894004353627", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "RENUSDT", - ticker: "RENUSDT", - address: "0xf55941e971302c634c586416c43469f3ead5ad3e", - rawAmount: "4997500", - decimal: 6, - amount: "4.9975", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "MMDEX.IO", - ticker: "MMDEX.IO", - address: "0xdc4cb4c3587532409a4545aa79a15d967bed1c08", - rawAmount: "250000000000000000000000", - decimal: 18, - amount: "250000", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "BOWDAO.NET", - ticker: "BOWDAO.NET", - address: "0x3bab61ad5d103bb5b203c9092eb3a5e11677a5d0", - rawAmount: "660000000000000000000000", - decimal: 18, - amount: "660000", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "APC", - ticker: "APC", - address: "0xda2d21872999e700a715a1bda3153eb9079770bb", - rawAmount: "124889000", - decimal: 6, - amount: "124.889", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "LINK", - ticker: "LINK", - address: "0xf8a0bf9cf54bb92f17374d9e9a321e6a111a51bd", - rawAmount: "7095490344", - decimal: 18, - amount: "0.000000007095490344", - logo: "https://api.rango.exchange/i/hWjRK2", - usdPrice: 5.947, - }, - { - chain: "BSC", - symbol: "LUNA2.APP", - ticker: "LUNA2.APP", - address: "0x9171c79f543b298fbd39642dc29e1454e2878665", - rawAmount: "188888", - decimal: 0, - amount: "188888", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "EOS", - ticker: "EOS", - address: "0x56b6fb708fc5732dec1afc8d8556423a2edccbd6", - rawAmount: "6521653134", - decimal: 18, - amount: "0.000000006521653134", - logo: "https://api.rango.exchange/i/KeunI3", - usdPrice: 0.874, - }, - { - chain: "BSC", - symbol: "ANGELDUST", - ticker: "ANGELDUST", - address: "0x32d3499feca3f881d779f0183d7b41d32b2498df", - rawAmount: "741825180000", - decimal: 6, - amount: "741825.18", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "ORBIT", - ticker: "ORBIT", - address: "0xdfb8603d947ab42fb76eb3bb14d9dde4334130d2", - rawAmount: "58397000000000000000000", - decimal: 18, - amount: "58397", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "WAVAX", - ticker: "WAVAX", - address: "0x96412902aa9aff61e13f085e70d3152c6ef2a817", - rawAmount: "8087494716", - decimal: 18, - amount: "0.000000008087494716", - logo: "https://api.rango.exchange/i/7QDOTz", - usdPrice: 11.745, - }, - { - chain: "BSC", - symbol: "GASDAO.CC", - ticker: "GASDAO.CC", - address: "0x1c0294b8a8ae3d64d8629de723cb9e44f5f12c63", - rawAmount: "9500000000000", - decimal: 8, - amount: "95000", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "MINIDOGE", - ticker: "MINIDOGE", - address: "0x50fa1d465b2a4a13d64e9fa428ccc98ec873ae64", - rawAmount: "500000000000000000000000000000", - decimal: 18, - amount: "500000000000", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "VELO", - ticker: "VELO", - address: "0x17d1285bc68d9085f8e4b86fc565e452b29dc48f", - rawAmount: "150000000000000000000000", - decimal: 18, - amount: "150000", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "ARTQ.ME", - ticker: "ARTQ.ME", - address: "0xf0ef30735455d5315873cc2e2966cb20047bdb29", - rawAmount: "6000000000000000000000", - decimal: 18, - amount: "6000", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "USDCSWAP.ORG", - ticker: "USDCSWAP.ORG", - address: "0x43217359af5f01cf82c12a7a058ba221acdaef38", - rawAmount: "500", - decimal: 0, - amount: "500", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "1INCH", - ticker: "1INCH", - address: "0x111111111117dc0aa78b770fa6a738034120c302", - rawAmount: "271002710027100234", - decimal: 18, - amount: "0.271002710027100234", - logo: "https://api.rango.exchange/i/9D6oXE", - usdPrice: 0.397, - }, - { - chain: "BSC", - symbol: "MAI", - ticker: "MAI", - address: "0x3f56e0c36d275367b8c502090edf38289b3dea0d", - rawAmount: "19277503723092914708", - decimal: 18, - amount: "19.277503723092914708", - logo: "https://api.rango.exchange/i/rcaHva", - usdPrice: null, - }, - { - chain: "BSC", - symbol: "ATOM", - ticker: "ATOM", - address: "0x0eb3a705fc54725037cc9e008bdede697f62f335", - rawAmount: "28750711363627413", - decimal: 18, - amount: "0.028750711363627413", - logo: "https://api.rango.exchange/i/UT9ERo", - usdPrice: 8.94, - }, - { - chain: "BSC", - symbol: "1GAS.ORG", - ticker: "1GAS.ORG", - address: "0xd35f9ab96d04adb02fd549ef6a576ce4e2c1d935", - rawAmount: "92280000000000000000000", - decimal: 18, - amount: "92280", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "BOHM", - ticker: "BOHM", - address: "0xbe2bac22b5f4d1126c705cb21335960531bae847", - rawAmount: "100000000000000000000", - decimal: 18, - amount: "100", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "BTCB", - ticker: "BTCB", - address: "0x7130d2a12b9bcbfae4f2634d864a1ee1ce3ead9c", - rawAmount: "71529099712895", - decimal: 18, - amount: "0.000071529099712895", - logo: "https://api.rango.exchange/i/MHEGHG", - usdPrice: 16863.776, - }, - { - chain: "BSC", - symbol: "EDG", - ticker: "EDG", - address: "0xa2e26f5f663e18fa942db6edf3269449d75d6d85", - rawAmount: "10000000000", - decimal: 25, - amount: "0.000000000000001", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "SUSHI", - ticker: "SUSHI", - address: "0x947950bcc74888a40ffa2593c5798f11fc9124c4", - rawAmount: "836519539228464427", - decimal: 18, - amount: "0.836519539228464427", - logo: "https://api.rango.exchange/i/NgIT7y", - usdPrice: 0.941, - }, - { - chain: "BSC", - symbol: "PGAME", - ticker: "PGAME", - address: "0x4dc90e30015af10e64a2f1ac390754cfb0454373", - rawAmount: "10952400", - decimal: 6, - amount: "10.9524", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "MATIC", - ticker: "MATIC", - address: "0xcc42724c6683b7e57334c4e856f4c9965ed682bd", - rawAmount: "1000000008755996216", - decimal: 18, - amount: "1.000000008755996216", - logo: "https://api.rango.exchange/i/vTlTjv", - usdPrice: 0.791, - }, - { - chain: "BSC", - symbol: "FISTDAO", - ticker: "FISTDAO", - address: "0x41791dab02a1f9b2430cd46f2c6a2b33aa7fd25d", - rawAmount: "880000000000", - decimal: 9, - amount: "880", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "FF18.IO", - ticker: "FF18.IO", - address: "0x491b25000d386cd31307580171a510d32d7e64ee", - rawAmount: "800000000000000000000000", - decimal: 18, - amount: "800000", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "RAY", - ticker: "RAY", - address: "0x13b6a55662f6591f8b8408af1c73b017e32eedb8", - rawAmount: "4793579", - decimal: 6, - amount: "4.793579", - logo: "https://api.rango.exchange/i/kNjVdm", - usdPrice: 0.15, - }, - { - chain: "BSC", - symbol: "AGEUR", - ticker: "AGEUR", - address: "0x38c84d5bbad726d465cf6a5349e41d6d7095faf7", - rawAmount: "8242220000000000", - decimal: 18, - amount: "0.00824222", - logo: "https://api.rango.exchange/i/d5IrO0", - usdPrice: 1.059, - }, - { - chain: "BSC", - symbol: "KK", - ticker: "KK", - address: "0x482794a6efb37e3fbd51f537c7102e9ab188b818", - rawAmount: "53000000000000000000", - decimal: 18, - amount: "53", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "O3", - ticker: "O3", - address: "0xee9801669c6138e84bd50deb500827b776777d28", - rawAmount: "1256000000000000000", - decimal: 18, - amount: "1.256", - logo: "https://api.rango.exchange/i/lfPJOy", - usdPrice: 0.0443, - }, - { - chain: "BSC", - symbol: "AIR", - ticker: "AIR", - address: "0xbc6675de91e3da8eac51293ecb87c359019621cf", - rawAmount: "1921604000000000000000000", - decimal: 18, - amount: "1921604", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "DOGGY", - ticker: "DOGGY", - address: "0x74926b3d118a63f6958922d3dc05eb9c6e6e00c6", - rawAmount: "283511485676805491", - decimal: 18, - amount: "0.283511485676805491", - logo: "https://api.rango.exchange/i/1lJ2Z3", - usdPrice: 0.00031, - }, - { - chain: "BSC", - symbol: "SEG", - ticker: "SEG", - address: "0x2eeff21c71ae38f9c34496cd9250c0d186dcd988", - rawAmount: "100000000000000", - decimal: 18, - amount: "0.0001", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "MIM", - ticker: "MIM", - address: "0xfe19f0b51438fd612f6fd59c1dbb3ea319f433ba", - rawAmount: "15022048536804216097", - decimal: 18, - amount: "15.022048536804216097", - logo: "https://api.rango.exchange/i/L5wafC", - usdPrice: 0.993, - }, - { - chain: "BSC", - symbol: "USDSWAP.IO", - ticker: "USDSWAP.IO", - address: "0xb2ad5142b8ccb380731866bc42b3619759f3f7b3", - rawAmount: "1286698", - decimal: 0, - amount: "1286698", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "PSG", - ticker: "PSG", - address: "0xbc5609612b7c44bef426de600b5fd1379db2ecf1", - rawAmount: "14", - decimal: 2, - amount: "0.14", - logo: "https://api.rango.exchange/i/OiA2jQ", - usdPrice: 5.685, - }, - { - chain: "BSC", - symbol: "ETH", - ticker: "ETH", - address: "0x2170ed0880ac9a755fd29b2688956bd959f933f8", - rawAmount: "14825954098793468", - decimal: 18, - amount: "0.014825954098793468", - logo: "https://api.rango.exchange/i/qr4L6S", - usdPrice: 1209.693, - }, - { - chain: "BSC", - symbol: "SAFEMOON", - ticker: "SAFEMOON", - address: "0x2df0b14ee90671021b016dab59f2300fb08681fa", - rawAmount: "255", - decimal: 18, - amount: "0.000000000000000255", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "POODL", - ticker: "POODL", - address: "0x4a68c250486a116dc8d6a0c5b0677de07cc09c5d", - rawAmount: "6184580930", - decimal: 9, - amount: "6.18458093", - logo: "https://api.rango.exchange/i/ehIL4M", - usdPrice: 7.1e-9, - }, - { - chain: "BSC", - symbol: "AVAX", - ticker: "AVAX", - address: "0x1ce0c2827e2ef14d5c4f29a091d735a204794041", - rawAmount: "4705457968658479", - decimal: 18, - amount: "0.004705457968658479", - logo: "https://api.rango.exchange/i/kX4edQ", - usdPrice: null, - }, - { - chain: "BSC", - symbol: "MGRT", - ticker: "MGRT", - address: "0xd08f7b01fdd26928dcdc956610a5332f17b3ea11", - rawAmount: "1119800000000000000", - decimal: 18, - amount: "1.1198", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "WBNB", - ticker: "WBNB", - address: "0xbb4cdb9cbd36b01bd1cbaebf2de08d9173bc095c", - rawAmount: "23374035802351054", - decimal: 18, - amount: "0.023374035802351054", - logo: "https://api.rango.exchange/i/lRTcZT", - usdPrice: 248.431, - }, - { - chain: "BSC", - symbol: "ANYFUSE", - ticker: "ANYFUSE", - address: "0x43242138833e8d360e84920462a483eb9e35c8b4", - rawAmount: "32000000000000000000", - decimal: 18, - amount: "32", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "AGILESWAP.IO", - ticker: "AGILESWAP.IO", - address: "0xcf8b4e69707e22dc5062f80576d9f069275ed1b5", - rawAmount: "12000000000000", - decimal: 9, - amount: "12000", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "BNBM", - ticker: "BNBM", - address: "0xe8d6eccf4df7067a52d43495c11b69deeedb965e", - rawAmount: "207961000000000000000000", - decimal: 18, - amount: "207961", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "PAYOU", - ticker: "PAYOU", - address: "0x1e8f7bfdcf6d95eea81e039234624fa6b78bd389", - rawAmount: "923000000000000000000", - decimal: 18, - amount: "923", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "AABEK", - ticker: "AABEK", - address: "0x68d1569d1a6968f194b4d93f8d0b416c123a599f", - rawAmount: "20819314000000000", - decimal: 9, - amount: "20819314", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "TRX", - ticker: "TRX", - address: "0x85eac5ac2f758618dfa09bdbe0cf174e7d574d5b", - rawAmount: "2425322528", - decimal: 18, - amount: "0.000000002425322528", - logo: "https://api.rango.exchange/i/sJnSkq", - usdPrice: 0.055, - }, - { - chain: "BSC", - symbol: "RIFTDAO.NET", - ticker: "RIFTDAO.NET", - address: "0x4f6a82bb5fd0996158c9ac6bd3605489cad82d8d", - rawAmount: "738097000000000000000000", - decimal: 18, - amount: "738097", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "ETH-1INCH.IO", - ticker: "ETH-1INCH.IO", - address: "0xa83b6a470771da2d979480b2e742962088608ced", - rawAmount: "870000000000000000", - decimal: 18, - amount: "0.87", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "ODDZ", - ticker: "ODDZ", - address: "0xcd40f2670cf58720b694968698a5514e924f742d", - rawAmount: "77970995683712403", - decimal: 18, - amount: "0.077970995683712403", - logo: "https://api.rango.exchange/i/s6bU0A", - usdPrice: 0.0121, - }, - { - chain: "BSC", - symbol: "TBBT.ORG", - ticker: "TBBT.ORG", - address: "0xbf7183b8c8e5bb2d10f63678abb5d52df72712b2", - rawAmount: "50000000000000000000000", - decimal: 18, - amount: "50000", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "DASH", - ticker: "DASH", - address: "0x3291a9352e553740bf78ce94fad611924b640d0f", - rawAmount: "100000000000000000000", - decimal: 18, - amount: "100", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "BAKE", - ticker: "BAKE", - address: "0xe02df9e3e622debdd69fb838bb799e3f168902c5", - rawAmount: "2896167082922666", - decimal: 18, - amount: "0.002896167082922666", - logo: "https://api.rango.exchange/i/dQuv0N", - usdPrice: 0.141, - }, - { - chain: "BSC", - symbol: "USDC", - ticker: "USDC", - address: "0x8ac76a51cc950d9822d68b83fe1ad97b32cd580d", - rawAmount: "15641472731959171181", - decimal: 18, - amount: "15.641472731959171181", - logo: "https://api.rango.exchange/i/toXKGV", - usdPrice: 1.005, - }, - { - chain: "BSC", - symbol: "LTC", - ticker: "LTC", - address: "0x4338665cbb7b2485a8855a139b75d5e34ab0db94", - rawAmount: "6918750157", - decimal: 18, - amount: "0.000000006918750157", - logo: "https://api.rango.exchange/i/Rw2jCX", - usdPrice: 65.204, - }, - { - chain: "BSC", - symbol: "NEAR", - ticker: "NEAR", - address: "0x1fa4a73a3f0133f0025378af00236f3abdee5d63", - rawAmount: "508963275751495577", - decimal: 18, - amount: "0.508963275751495577", - logo: "https://api.rango.exchange/i/kL2qwj", - usdPrice: 1.298, - }, - { - chain: "BSC", - symbol: "BTG", - ticker: "BTG", - address: "0x1385e68e3b5ea66fc50a221f8dcbabbfd3ee282b", - rawAmount: "11000000000", - decimal: 6, - amount: "11000", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "YTS", - ticker: "YTS", - address: "0x3b4deb27a46e746776a661ecf523c42ed0400d54", - rawAmount: "9000000000000000000000000", - decimal: 18, - amount: "9000000", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "FLOKI", - ticker: "FLOKI", - address: "0x2b3f34e9d4b127797ce6244ea341a83733ddd6e4", - rawAmount: "62088935293887", - decimal: 9, - amount: "62088.935293887", - logo: "https://api.rango.exchange/i/UhBFxd", - usdPrice: 1.89e-7, - }, - { - chain: "BSC", - symbol: "SXP", - ticker: "SXP", - address: "0x47bead2563dcbf3bf2c9407fea4dc236faba485a", - rawAmount: "7193114712", - decimal: 18, - amount: "0.000000007193114712", - logo: "https://api.rango.exchange/i/3njEos", - usdPrice: 0.207, - }, - { - chain: "BSC", - symbol: "COSMICMINE", - ticker: "COSMICMINE", - address: "0xde1e01b3ab6aa67909e41330067be7a46ec16c38", - rawAmount: "300000000000000000", - decimal: 18, - amount: "0.3", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "SPACEPI", - ticker: "SPACEPI", - address: "0x69b14e8d3cebfdd8196bfe530954a0c226e5008e", - rawAmount: "5500000000000000", - decimal: 9, - amount: "5500000", - logo: "https://api.rango.exchange/i/01weSc", - usdPrice: 1.02e-9, - }, - { - chain: "BSC", - symbol: "ALPACA", - ticker: "ALPACA", - address: "0x373233a38ae21cf0c4f9de11570e7d5aa6824a1e", - rawAmount: "28102000000000000000000000", - decimal: 18, - amount: "28102000", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "MNEB", - ticker: "MNEB", - address: "0xd22202d23fe7de9e3dbe11a2a88f42f4cb9507cf", - rawAmount: "15000000000000", - decimal: 8, - amount: "150000", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "DAO", - ticker: "DAO", - address: "0x037b202ca88d2028d82936d5615ee5088cb9fd78", - rawAmount: "9970000000000000", - decimal: 18, - amount: "0.00997", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "BRISE", - ticker: "BRISE", - address: "0x8fff93e810a2edaafc326edee51071da9d398e83", - rawAmount: "10", - decimal: 9, - amount: "0.00000001", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "3WORLDS.IO", - ticker: "3WORLDS.IO", - address: "0xc3238c3b7b8e32588a49c751aed808368e85122d", - rawAmount: "12000000000000", - decimal: 9, - amount: "12000", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "ARKR.ORG", - ticker: "ARKR.ORG", - address: "0x04645027122c9f152011f128c7085449b27cb6d7", - rawAmount: "800000000000000000000000", - decimal: 18, - amount: "800000", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "WADAX", - ticker: "WADAX", - address: "0x35122d1fe8001296f61290b8ba42ef597af31fb7", - rawAmount: "1000000000000", - decimal: 6, - amount: "1000000", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "BNBW", - ticker: "BNBW", - address: "0x5558447b06867ffebd87dd63426d61c868c45904", - rawAmount: "23752199000000000", - decimal: 9, - amount: "23752199", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "QI", - ticker: "QI", - address: "0x8729438eb15e2c8b576fcc6aecda6a148776c0f5", - rawAmount: "208452535759624275628", - decimal: 18, - amount: "208.452535759624275628", - logo: "https://api.rango.exchange/i/PwbKO2", - usdPrice: 0.00664, - }, - { - chain: "BSC", - symbol: "CAKE", - ticker: "CAKE", - address: "0x0e09fabb73bd3ade0a17ecc321fd13a19e81ce82", - rawAmount: "132130918185825847", - decimal: 18, - amount: "0.132130918185825847", - logo: "https://api.rango.exchange/i/UA0myt", - usdPrice: 3.433, - }, - { - chain: "BSC", - symbol: "LINKP.IO", - ticker: "LINKP.IO", - address: "0xd5e3bf9045cfb1e6ded4b35d1b9c34be16d6eec3", - rawAmount: "800000000000000000000000", - decimal: 18, - amount: "800000", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "BSCTOKEN", - ticker: "BSCTOKEN", - address: "0x569b2cf0b745ef7fad04e8ae226251814b3395f9", - rawAmount: "23752199000000000", - decimal: 9, - amount: "23752199", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "VERSE", - ticker: "VERSE", - address: "0xbb92b9d18db99c3695bc820bf2c876d4b1527fa5", - rawAmount: "3000000000000000", - decimal: 9, - amount: "3000000", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "VERA", - ticker: "VERA", - address: "0x0df62d2cd80591798721ddc93001afe868c367ff", - rawAmount: "800000000000000000000000", - decimal: 18, - amount: "800000", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "SQUIDV2", - ticker: "SQUIDV2", - address: "0xd85842708252c7752f9e503f90561068433d0044", - rawAmount: "1000000000000000000", - decimal: 18, - amount: "1", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "WETH", - ticker: "WETH", - address: "0x4db5a66e937a9f4473fa95b1caf1d1e1d62e29ea", - rawAmount: "9430724572", - decimal: 18, - amount: "0.000000009430724572", - logo: "https://api.rango.exchange/i/wNnplE", - usdPrice: 1396.147, - }, - { - chain: "BSC", - symbol: "ATOM", - ticker: "ATOM", - address: "0x725e02c7f9168f45b3699cfb7c262fb6dd355e84", - rawAmount: "99561480", - decimal: 6, - amount: "99.56148", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "FLOKI", - ticker: "FLOKI", - address: "0xfb5b838b6cfeedc2873ab27866079ac55363d37e", - rawAmount: "62088935293887", - decimal: 9, - amount: "62088.935293887", - logo: "https://api.rango.exchange/i/fIrbfa", - usdPrice: 0.00000913, - }, - { - chain: "BSC", - symbol: "AZSWAP.IO", - ticker: "AZSWAP.IO", - address: "0xfd4c532a8c17bd326c2dc63b88d49306ce27f80b", - rawAmount: "18000000000000", - decimal: 9, - amount: "18000", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "TU7.ORG", - ticker: "TU7.ORG", - address: "0x442b656f5a5c3dd09790951810c5a15ea5295b51", - rawAmount: "7127850000000000", - decimal: 9, - amount: "7127850", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "FLUX", - ticker: "FLUX", - address: "0xb16600c510b0f323dee2cb212924d90e58864421", - rawAmount: "950000000000000000000000", - decimal: 18, - amount: "950000", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "XRP", - ticker: "XRP", - address: "0x1d2f0da169ceb9fc7b3144628db156f3f6c60dbe", - rawAmount: "5688021754", - decimal: 18, - amount: "0.000000005688021754", - logo: "https://api.rango.exchange/i/zTYnq2", - usdPrice: 0.34, - }, - { - chain: "BSC", - symbol: "BITTT.IO", - ticker: "BITTT.IO", - address: "0x9603a3d3dcccf5ef1a2060a3da796ac084cc66eb", - rawAmount: "268551000000000000000000", - decimal: 18, - amount: "268551", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "AXLUSDC", - ticker: "AXLUSDC", - address: "0x4268b8f0b87b6eae5d897996e6b845ddbd99adf3", - rawAmount: "5978049", - decimal: 6, - amount: "5.978049", - logo: "https://api.rango.exchange/tokens/COSMOS/AXLUSDC.png", - usdPrice: null, - }, - { - chain: "BSC", - symbol: "SDJT", - ticker: "SDJT", - address: "0xbb368656efa67361b0063fe0f11cb08bd460246d", - rawAmount: "100000000", - decimal: 9, - amount: "0.1", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "ONE", - ticker: "ONE", - address: "0x03ff0ff224f904be3118461335064bb48df47938", - rawAmount: "4789152388", - decimal: 18, - amount: "0.000000004789152388", - logo: "https://api.rango.exchange/i/5MOMsg", - usdPrice: 0.0115, - }, - { - chain: "BSC", - symbol: "STI", - ticker: "STI", - address: "0x4f5f7a7dca8ba0a7983381d23dfc5eaf4be9c79a", - rawAmount: "1000", - decimal: 10, - amount: "0.0000001", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "APE", - ticker: "APE", - address: "0xa1b99485d58d70d86e455ab8823492090c3f43c0", - rawAmount: "350000000000000000000", - decimal: 18, - amount: "350", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "COOK", - ticker: "COOK", - address: "0x965b0df5bda0e7a0649324d78f03d5f7f2de086a", - rawAmount: "35733206194802111275189", - decimal: 18, - amount: "35733.206194802111275189", - logo: "https://api.rango.exchange/i/owq1WS", - usdPrice: 0.000247, - }, - { - chain: "BSC", - symbol: "FUSE", - ticker: "FUSE", - address: "0x5857c96dae9cf8511b08cb07f85753c472d36ea3", - rawAmount: "102000000000000000000", - decimal: 18, - amount: "102", - logo: "https://api.rango.exchange/i/3hWqus", - usdPrice: 0.0603, - }, - { - chain: "BSC", - symbol: "CGB", - ticker: "CGB", - address: "0x7e6202903275772044198d07b8a536cc064f8480", - rawAmount: "211000000", - decimal: 6, - amount: "211", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "DEF8.IO", - ticker: "DEF8.IO", - address: "0x556798dd55db12562a6950ea8339a273539b0495", - rawAmount: "82445000000000000000000", - decimal: 18, - amount: "82445", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "WMATIC", - ticker: "WMATIC", - address: "0xc836d8dc361e44dbe64c4862d55ba041f88ddd39", - rawAmount: "1887651939", - decimal: 18, - amount: "0.000000001887651939", - logo: "https://api.rango.exchange/i/QpOgNr", - usdPrice: 0.791, - }, - { - chain: "BSC", - symbol: "BSTAKE.NET", - ticker: "BSTAKE.NET", - address: "0x1f040f15ab15b7e0dfac935873fadbe43d015535", - rawAmount: "480000000000000000000000", - decimal: 18, - amount: "480000", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "XCH5.IO", - ticker: "XCH5.IO", - address: "0xb3ec4e17c1c0079d977354875ab924c088325306", - rawAmount: "821112000000000", - decimal: 9, - amount: "821112", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "FS", - ticker: "FS", - address: "0xe3a41e4dacc892ecaedfa009be5baa2d3ab4844d", - rawAmount: "1003947318555099196", - decimal: 18, - amount: "1.003947318555099196", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "BSC-COIN", - ticker: "BSC-COIN", - address: "0xe3e1147acd39687a25ca7716227c604500f5c31a", - rawAmount: "5000000000000", - decimal: 6, - amount: "5000000", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "APEFESTPOAP.COM", - ticker: "APEFESTPOAP.COM", - address: "0x57dac6482784a0f093483e6313804812fa177437", - rawAmount: "5555000000000000000000", - decimal: 18, - amount: "5555", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "SAFEMOON-DIVIDEND.COM", - ticker: "SAFEMOON-DIVIDEND.COM", - address: "0xdbe3e700ab26cbf3523d850b5d892fd17e0ce343", - rawAmount: "31820000000000000000000", - decimal: 18, - amount: "31820", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "AXAX.IO", - ticker: "AXAX.IO", - address: "0x58b5c4697dc70f3d889225260944cdd9c270c132", - rawAmount: "77000000000000", - decimal: 9, - amount: "77000", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "RRDAO.NET", - ticker: "RRDAO.NET", - address: "0xa47b34ff31e22ef03f6054af19542bcde260cdc7", - rawAmount: "738097000000000000000000", - decimal: 18, - amount: "738097", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "ETP", - ticker: "ETP", - address: "0x89679307c3d2e4e289da2ccd4d3c44ff39292189", - rawAmount: "100000000000000", - decimal: 18, - amount: "0.0001", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "DOT", - ticker: "DOT", - address: "0x7083609fce4d1d8dc0c979aab8c869ea2c873402", - rawAmount: "7180274458", - decimal: 18, - amount: "0.000000007180274458", - logo: "https://api.rango.exchange/i/suQRJx", - usdPrice: 4.528, - }, - { - chain: "BSC", - symbol: "AGMC.IO", - ticker: "AGMC.IO", - address: "0xef27b9cb67aa93ec3494a60f1ea9380e86175b26", - rawAmount: "800000000000000000000000", - decimal: 18, - amount: "800000", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "RDRIP", - ticker: "RDRIP", - address: "0xa02a0b2d67d4fa48677a79cadc483e114049916d", - rawAmount: "40214587120000", - decimal: 6, - amount: "40214587.12", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "BUSD", - ticker: "BUSD", - address: "0xe9e7cea3dedca5984780bafc599bd69add087d56", - rawAmount: "2925825323281948117", - decimal: 18, - amount: "2.925825323281948117", - logo: "https://api.rango.exchange/i/tY13sD", - usdPrice: 1.001, - }, - { - chain: "BSC", - symbol: "MKS", - ticker: "MKS", - address: "0x64f2c2aa04755507a2ecd22ceb8c475b7a750a3a", - rawAmount: "6500000000000000000000000", - decimal: 18, - amount: "6500000", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "BITMARTEX.COM", - ticker: "BITMARTEX.COM", - address: "0xdac0bb03158048b70abcfeb3be2607b625526f20", - rawAmount: "400000000000000000000", - decimal: 18, - amount: "400", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "APT", - ticker: "APT", - address: "0xec811fbcd12f67874891cdbbbc95d9f73db3fbb0", - rawAmount: "40000000", - decimal: 6, - amount: "40", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "MELLO", - ticker: "MELLO", - address: "0x0198be93b7cae38da7e2fd966946412cc36447bf", - rawAmount: "17777000000000000000000", - decimal: 18, - amount: "17777", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "ICE", - ticker: "ICE", - address: "0xf16e81dce15b08f326220742020379b855b87df9", - rawAmount: "3071447531", - decimal: 18, - amount: "0.000000003071447531", - logo: "https://api.rango.exchange/i/my1npH", - usdPrice: 0.121, - }, - { - chain: "BSC", - symbol: "ADDBNB.COM", - ticker: "ADDBNB.COM", - address: "0x617bf230a6886accec5952385eed8bc85d1a09b2", - rawAmount: "29998899999900", - decimal: 8, - amount: "299988.999999", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "POWNFT.NET", - ticker: "POWNFT.NET", - address: "0x893c25c46bfaa9b66cd557837d32af3fe264a07b", - rawAmount: "96816550000000000000000", - decimal: 18, - amount: "96816.55", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "MINIDOGE", - ticker: "MINIDOGE", - address: "0x9b1ba20ae9335197c72be094d4fa300d4ef95351", - rawAmount: "500000000000000000000000000000", - decimal: 18, - amount: "500000000000", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "FIFA", - ticker: "FIFA", - address: "0xe19417837d8e61f17dfae2e6a11b1e4810dae2a5", - rawAmount: "99000000000000", - decimal: 18, - amount: "0.000099", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "MDT", - ticker: "MDT", - address: "0x668db7aa38eac6b40c9d13dbe61361dc4c4611d1", - rawAmount: "4965562423", - decimal: 18, - amount: "0.000000004965562423", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "ZIL", - ticker: "ZIL", - address: "0xb86abcb37c3a4b64f74f59301aff131a1becc787", - rawAmount: "5995", - decimal: 12, - amount: "0.000000005995", - logo: "https://api.rango.exchange/i/aiPfMq", - usdPrice: 0.0176, - }, - { - chain: "BSC", - symbol: ' "995$ VISIT USDTREWARD.COM TO CLAIM', - ticker: ' "995$ VISIT USDTREWARD.COM TO CLAIM', - address: "0x67c4a6da86da4f45030904b143d6b00d25e366e9", - rawAmount: "6", - decimal: 0, - amount: "6", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "ADA", - ticker: "ADA", - address: "0x3ee2200efb3400fabb9aacf31297cbdd1d435d47", - rawAmount: "6081419213", - decimal: 18, - amount: "0.000000006081419213", - logo: "https://api.rango.exchange/i/ne4pEv", - usdPrice: 0.25, - }, - { - chain: "BSC", - symbol: "ZEPE.IO", - ticker: "ZEPE.IO", - address: "0xb0557906c617f0048a700758606f64b33d0c41a6", - rawAmount: "750000000000000000000000", - decimal: 18, - amount: "750000", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "MN", - ticker: "MN", - address: "0x1a09f518a8293d519de20700076ad9cd2125d224", - rawAmount: "454000000000000", - decimal: 18, - amount: "0.000454", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "EVER", - ticker: "EVER", - address: "0x5190b01965b6e3d786706fd4a999978626c19880", - rawAmount: "800000000000000000000000", - decimal: 18, - amount: "800000", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "SGC", - ticker: "SGC", - address: "0x7aa3a53360541283ffa9192972223b47a902dc0c", - rawAmount: "1450000000000", - decimal: 6, - amount: "1450000", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "BCH", - ticker: "BCH", - address: "0x8ff795a6f4d97e7887c79bea79aba5cc76444adf", - rawAmount: "208175286", - decimal: 18, - amount: "0.000000000208175286", - logo: "https://api.rango.exchange/i/TPdCZV", - usdPrice: 101.758, - }, - { - chain: "BSC", - symbol: "KK8.IO", - ticker: "KK8.IO", - address: "0x2ba6204c23fbd5698ed90abc911de263e5f41266", - rawAmount: "166574000000000000000000", - decimal: 18, - amount: "166574", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "BCNFT", - ticker: "BCNFT", - address: "0xe5677103191711bad85cf99e0dfc9b35449b790b", - rawAmount: "99800000000000000000", - decimal: 18, - amount: "99.8", - logo: null, - usdPrice: null, - }, - { - chain: "BSC", - symbol: "MNFLX", - ticker: "MNFLX", - address: "0xa04f060077d90fe2647b61e4da4ad1f97d6649dc", - rawAmount: "18298000000000000", - decimal: 18, - amount: "0.018298", - logo: "https://api.rango.exchange/i/66c2BP", - usdPrice: null, - }, - { - chain: "BSC", - symbol: "FIL", - ticker: "FIL", - address: "0x0d8ce2a99bb6e3b7db580ed848240e4a0f9ae153", - rawAmount: "166801647873165921", - decimal: 18, - amount: "0.166801647873165921", - logo: "https://api.rango.exchange/i/diq2au", - usdPrice: 2.925, - }, - { - chain: "BSC", - symbol: "DAI", - ticker: "DAI", - address: "0x1af3f329e8be154074d8769d1ffa4ee058b1dbc3", - rawAmount: "7308178549281467169", - decimal: 18, - amount: "7.308178549281467169", - logo: "https://api.rango.exchange/i/EcBuF8", - usdPrice: 1.002, - }, - { - chain: "BSC", - symbol: "BNB", - ticker: "BNB", - address: null, - rawAmount: "64638855809280692", - decimal: 18, - amount: "0.064638855809280692", - logo: "https://api.rango.exchange/i/Y3v1KW", - usdPrice: null, - }, - ], - loading: false, - walletType: "metamask", - isConnected: false, - error: false, - explorerUrl: - "https://bscscan.com/address/0x2702d89c1c8658b49c45dd460deebcc45faec03c", - }, - ], - }, - { - name: "POLYGON", - accounts: [ - { - address: "0x2702d89c1c8658b49c45dd460deebcc45faec03c", - balances: [], - loading: false, - walletType: "metamask", - isConnected: true, - error: true, - explorerUrl: - "https://polygonscan.com/address/0x2702d89c1c8658b49c45dd460deebcc45faec03c", - }, - ], - }, - { - name: "ETH", - accounts: [ - { - address: "0x2702d89c1c8658b49c45dd460deebcc45faec03c", - balances: [ - { - chain: "ETH", - symbol: "BAT", - ticker: "BAT", - address: "0x0d8775f648430679a709e98d2b0cb6250d2887ef", - rawAmount: "4000000000000000000", - decimal: 18, - amount: "4", - logo: "https://api.rango.exchange/i/fRlt4J", - usdPrice: 0.187, - }, - { - chain: "ETH", - symbol: "WBTC", - ticker: "WBTC", - address: "0x2260fac5e5542a773aa44fbcfedf7c193bc2c599", - rawAmount: "4777", - decimal: 8, - amount: "0.00004777", - logo: "https://api.rango.exchange/i/LZSo9D", - usdPrice: 16748.345, - }, - { - chain: "ETH", - symbol: "BUSD", - ticker: "BUSD", - address: "0x4fabb145d64652a948d72533023f6e7a623c7c53", - rawAmount: "44533649981450616971", - decimal: 18, - amount: "44.533649981450616971", - logo: "https://api.rango.exchange/i/sQLw6p", - usdPrice: 0.996, - }, - { - chain: "ETH", - symbol: "USDC", - ticker: "USDC", - address: "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", - rawAmount: "68026943", - decimal: 6, - amount: "68.026943", - logo: "https://api.rango.exchange/i/ns0AMf", - usdPrice: 0.998, - }, - { - chain: "ETH", - symbol: "WETH", - ticker: "WETH", - address: "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", - rawAmount: "69476760000000000", - decimal: 18, - amount: "0.06947676", - logo: "https://api.rango.exchange/i/yZ9N1N", - usdPrice: 1207.06, - }, - { - chain: "ETH", - symbol: "USDT", - ticker: "USDT", - address: "0xdac17f958d2ee523a2206206994597c13d831ec7", - rawAmount: "458820363", - decimal: 6, - amount: "458.820363", - logo: "https://api.rango.exchange/i/aR1yFx", - usdPrice: 0.999, - }, - { - chain: "ETH", - symbol: "RENBTC", - ticker: "RENBTC", - address: "0xeb4c2781e4eba804ce9a9803c67d0893436bb27d", - rawAmount: "92825", - decimal: 8, - amount: "0.00092825", - logo: "https://api.rango.exchange/i/kwXCDn", - usdPrice: 17122.537, - }, - { - chain: "ETH", - symbol: "ETH", - ticker: "ETH", - address: null, - rawAmount: "216333389734077345", - decimal: 18, - amount: "0.216333389734077345", - logo: "https://api.rango.exchange/i/MTyH5i", - usdPrice: null, - }, - { - chain: "ETH", - symbol: "MATIC", - ticker: "MATIC", - address: "0x7d1afa7b718fb893db30a3abc0cfc608aacfebb0", - rawAmount: "31663446408882142552", - decimal: 18, - amount: "31.663446408882142552", - logo: "https://api.rango.exchange/i/xt6ATN", - usdPrice: 0.79, - }, - { - chain: "ETH", - symbol: "DAI", - ticker: "DAI", - address: "0x6b175474e89094c44da98b954eedeac495271d0f", - rawAmount: "1987151466068153485", - decimal: 18, - amount: "1.987151466068153485", - logo: "https://api.rango.exchange/i/yJvJre", - usdPrice: 0.999, - }, - { - chain: "ETH", - symbol: "TUSD", - ticker: "TUSD", - address: "0x0000000000085d4780b73119b644ae5ecd22b376", - rawAmount: "16993200000000000000", - decimal: 18, - amount: "16.9932", - logo: "https://api.rango.exchange/i/af3mkt", - usdPrice: 0.994, - }, - { - chain: "ETH", - symbol: "SUSHI", - ticker: "SUSHI", - address: "0x6b3595068778dd592e39a122f4f5a5cf09c90fe2", - rawAmount: "3943357318101926305", - decimal: 18, - amount: "3.943357318101926305", - logo: "https://api.rango.exchange/i/2GXZEZ", - usdPrice: 0.951, - }, - { - chain: "ETH", - symbol: "AAVE", - ticker: "AAVE", - address: "0x7fc66500c84a76ad7e9c93437bfc5ac33e2ddae9", - rawAmount: "25162269244382386", - decimal: 18, - amount: "0.025162269244382386", - logo: "https://api.rango.exchange/i/ZizYhl", - usdPrice: 55.363, - }, - { - chain: "ETH", - symbol: "PERP", - ticker: "PERP", - address: "0xbc396689893d065f41bc2c6ecbee5e0085233447", - rawAmount: "6774928920", - decimal: 18, - amount: "0.00000000677492892", - logo: "https://api.rango.exchange/i/VrMbR6", - usdPrice: 0.39, - }, - { - chain: "ETH", - symbol: "STETH", - ticker: "STETH", - address: "0xae7ab96520de3a18e5e111b5eaab095312d7fe84", - rawAmount: "39341623", - decimal: 18, - amount: "0.000000000039341623", - logo: null, - usdPrice: null, - }, - { - chain: "ETH", - symbol: "SHIB", - ticker: "SHIB", - address: "0x95ad61b0a150d79219dcf64e1e6cc01f0b64c4ce", - rawAmount: "414477447646226736858871", - decimal: 18, - amount: "414477.447646226736858871", - logo: "https://api.rango.exchange/i/cbCyuY", - usdPrice: 0.00000824, - }, - { - chain: "ETH", - symbol: "EROWAN", - ticker: "EROWAN", - address: "0x07bac35846e5ed502aa91adf6a9e7aa210f2dcbe", - rawAmount: "17095432307032160581", - decimal: 18, - amount: "17.095432307032160581", - logo: "https://api.rango.exchange/i/X97ibo", - usdPrice: 0.000317, - }, - { - chain: "ETH", - symbol: "UST", - ticker: "UST", - address: "0xa693b19d2931d498c5b318df961919bb4aee87a5", - rawAmount: "1000000", - decimal: 6, - amount: "1", - logo: "https://api.rango.exchange/i/IvLUkp", - usdPrice: 0.02, - }, - { - chain: "ETH", - symbol: "XDATA", - ticker: "XDATA", - address: "0x0cf0ee63788a0849fe5297f3407f701e122cc023", - rawAmount: "230414265395638755692", - decimal: 18, - amount: "230.414265395638755692", - logo: null, - usdPrice: null, - }, - { - chain: "ETH", - symbol: "bETH", - ticker: "bETH", - address: "0x707f9118e33a9b8998bea41dd0d46f38bb963fc8", - rawAmount: "184000000000000", - decimal: 18, - amount: "0.000184", - logo: "https://api.rango.exchange/tokens/TERRA/BETH.png", - usdPrice: null, - }, - { - chain: "ETH", - symbol: "AKSWAP.IO", - ticker: "AKSWAP.IO", - address: "0x82dfdb2ec1aa6003ed4acba663403d7c2127ff67", - rawAmount: "250000000000000000000000", - decimal: 18, - amount: "250000", - logo: null, - usdPrice: null, - }, - { - chain: "ETH", - symbol: "WBNB", - ticker: "WBNB", - address: "0x418d75f65a02b3d53b2418fb8e1fe493759c7605", - rawAmount: "10000000000000000", - decimal: 18, - amount: "0.01", - logo: "https://api.rango.exchange/i/Xzflek", - usdPrice: 248.36, - }, - { - chain: "ETH", - symbol: "RANGO", - ticker: "RANGO", - address: "0x5846d81d8e4a3b9cc53ce1dcdc12b6619ae3507d", - rawAmount: "40000000", - decimal: 6, - amount: "40", - logo: null, - usdPrice: null, - }, - { - chain: "ETH", - symbol: "LUNAV2.IO (LUNA TOKEN)", - ticker: "LUNAV2.IO (LUNA TOKEN)", - address: "0xaf0b2fbedd5d1fda457580fb3dabad1f5c8bbc36", - rawAmount: "258542000000000000000000", - decimal: 18, - amount: "258542", - logo: null, - usdPrice: null, - }, - { - chain: "ETH", - symbol: "LUNA 2.0 (LUNAV2.IO)", - ticker: "LUNA 2.0 (LUNAV2.IO)", - address: "0x471c3a7f132bc94938516cb2bf6f02c7521d2797", - rawAmount: "250457000000000000000000", - decimal: 18, - amount: "250457", - logo: null, - usdPrice: null, - }, - { - chain: "ETH", - symbol: "LIDOLP.COM", - ticker: "LIDOLP.COM", - address: "0x0332d00ae8e9baa609edc48844f48fdd94ca9547", - rawAmount: "6000", - decimal: 0, - amount: "6000", - logo: null, - usdPrice: null, - }, - { - chain: "ETH", - symbol: "HBOT", - ticker: "HBOT", - address: "0xe5097d9baeafb89f9bcb78c9290d545db5f9e9cb", - rawAmount: "155042558533708582423", - decimal: 18, - amount: "155.042558533708582423", - logo: null, - usdPrice: null, - }, - { - chain: "ETH", - symbol: "1650811245.077F", - ticker: "1650811245.077F", - address: "0xba8d75baccc4d5c4bd814fde69267213052ea663", - rawAmount: "1000000000000000000", - decimal: 18, - amount: "1", - logo: null, - usdPrice: null, - }, - { - chain: "ETH", - symbol: "PWING", - ticker: "PWING", - address: "0xdb0f18081b505a7de20b18ac41856bcb4ba86a1a", - rawAmount: "498133925", - decimal: 9, - amount: "0.498133925", - logo: "https://api.rango.exchange/i/Ba5IQF", - usdPrice: null, - }, - { - chain: "ETH", - symbol: "VISIT [AAVE-SR.XYZ] AND CLAIM SPECIAL REWARDS", - ticker: "VISIT [AAVE-SR.XYZ] AND CLAIM SPECIAL REWARDS", - address: "0xd1e61fcb6e26d4deffa77f21cc5b581c3afa95e2", - rawAmount: "920816400", - decimal: 6, - amount: "920.8164", - logo: null, - usdPrice: null, - }, - { - chain: "ETH", - symbol: "VISIT [AUSD.SHOP] AND SUPPLY OR BORROW USDT", - ticker: "VISIT [AUSD.SHOP] AND SUPPLY OR BORROW USDT", - address: "0x38715ab4b9d4e00890773d7338d94778b0dfc0a8", - rawAmount: "2294101815", - decimal: 6, - amount: "2294.101815", - logo: null, - usdPrice: null, - }, - { - chain: "ETH", - symbol: "[LIDOSR.XYZ] CLAIM YOUR SPECIAL REWARDS.", - ticker: "[LIDOSR.XYZ] CLAIM YOUR SPECIAL REWARDS.", - address: "0x511b5f248269c0b90b60e33ef9df744048c84a83", - rawAmount: "149260000", - decimal: 6, - amount: "149.26", - logo: null, - usdPrice: null, - }, - { - chain: "ETH", - symbol: "ENJOY [HTTPS://SPINGAME.ME]", - ticker: "ENJOY [HTTPS://SPINGAME.ME]", - address: "0xcdc94877e4164d2e915fc5e8310155d661a995f1", - rawAmount: "2294101815", - decimal: 6, - amount: "2294.101815", - logo: null, - usdPrice: null, - }, - { - chain: "ETH", - symbol: "WMATIC", - ticker: "WMATIC", - address: "0x7c9f4c87d911613fe9ca58b579f737911aad2d43", - rawAmount: "100000000000000000", - decimal: 18, - amount: "0.1", - logo: "https://api.rango.exchange/i/QpOgNr", - usdPrice: null, - }, - { - chain: "ETH", - symbol: "$ VISIT NFTGIFTX.COM TO CLAIM", - ticker: "$ VISIT NFTGIFTX.COM TO CLAIM", - address: "0x0d3716e3e411af431a6e87e715d4b05bbcd67000", - rawAmount: "4000", - decimal: 0, - amount: "4000", - logo: null, - usdPrice: null, - }, - ], - loading: false, - walletType: "metamask", - isConnected: false, - error: false, - explorerUrl: - "https://etherscan.io/address/0x2702d89c1c8658b49c45dd460deebcc45faec03c", - }, - ], - }, - { - name: "AVAX_CCHAIN", - accounts: [ - { - address: "0x2702d89c1c8658b49c45dd460deebcc45faec03c", - balances: [ - { - chain: "AVAX_CCHAIN", - symbol: "BNB", - ticker: "BNB", - address: "0x264c1383ea520f73dd837f915ef3a732e204a493", - rawAmount: "7107381667", - decimal: 18, - amount: "0.000000007107381667", - logo: "https://api.rango.exchange/i/BtRUoA", - usdPrice: 247.386, - }, - { - chain: "AVAX_CCHAIN", - symbol: "TUSD", - ticker: "TUSD", - address: "0x1c20e891bab6b1727d14da358fae2984ed9b59eb", - rawAmount: "2819919094", - decimal: 18, - amount: "0.000000002819919094", - logo: "https://api.rango.exchange/i/UBghmk", - usdPrice: 1, - }, - { - chain: "AVAX_CCHAIN", - symbol: "SOL", - ticker: "SOL", - address: "0xfe6b19286885a4f7f55adad09c3cd1f906d2478f", - rawAmount: "110", - decimal: 9, - amount: "0.00000011", - logo: "https://api.rango.exchange/i/YhJ1nK", - usdPrice: null, - }, - { - chain: "AVAX_CCHAIN", - symbol: "OPENDAO.IS", - ticker: "OPENDAO.IS", - address: "0xc03f94e49c944c4f118c3f97af7cce8f01df9430", - rawAmount: "10000000000000000000", - decimal: 18, - amount: "10", - logo: null, - usdPrice: null, - }, - { - chain: "AVAX_CCHAIN", - symbol: "IMX.A", - ticker: "IMX.A", - address: "0xea6887e4a9cda1b77e70129e5fba830cdb5cddef", - rawAmount: "7119477388984802736", - decimal: 18, - amount: "7.119477388984802736", - logo: "https://api.rango.exchange/i/qhi6I3", - usdPrice: 0.000139, - }, - { - chain: "AVAX_CCHAIN", - symbol: "AVAXCLASSIC.COM", - ticker: "AVAXCLASSIC.COM", - address: "0x4c4f4f4122c3a80d30c1ad6ad2828953015bd52c", - rawAmount: "74041750000000000000", - decimal: 18, - amount: "74.04175", - logo: null, - usdPrice: null, - }, - { - chain: "AVAX_CCHAIN", - symbol: "ORBS", - ticker: "ORBS", - address: "0x340fe1d898eccaad394e2ba0fc1f93d27c7b717a", - rawAmount: "7336115152", - decimal: 18, - amount: "0.000000007336115152", - logo: "https://api.rango.exchange/i/hktmCG", - usdPrice: 0.0228, - }, - { - chain: "AVAX_CCHAIN", - symbol: "PENDLE", - ticker: "PENDLE", - address: "0xfb98b335551a418cd0737375a2ea0ded62ea213b", - rawAmount: "43168168325557885527", - decimal: 18, - amount: "43.168168325557885527", - logo: "https://api.rango.exchange/i/p4dkte", - usdPrice: 0.046, - }, - { - chain: "AVAX_CCHAIN", - symbol: "WMATIC", - ticker: "WMATIC", - address: "0xf2f13f0b7008ab2fa4a2418f4ccc3684e49d20eb", - rawAmount: "45499998000000000000", - decimal: 18, - amount: "45.499998", - logo: "https://api.rango.exchange/i/QpOgNr", - usdPrice: null, - }, - { - chain: "AVAX_CCHAIN", - symbol: "avaxUSDC", - ticker: "avaxUSDC", - address: "0xb97ef9ef8734c71904d8002f8b6bc66dd9c48a6e", - rawAmount: "15844946", - decimal: 6, - amount: "15.844946", - logo: "https://api.rango.exchange/i/FHj2LZ", - usdPrice: null, - }, - { - chain: "AVAX_CCHAIN", - symbol: "SPELL", - ticker: "SPELL", - address: "0xce1bffbd5374dac86a2893119683f4911a2f7814", - rawAmount: "144687727088072773130", - decimal: 18, - amount: "144.68772708807277313", - logo: "https://api.rango.exchange/i/zW5ZK2", - usdPrice: 0.000535, - }, - { - chain: "AVAX_CCHAIN", - symbol: "WBNB", - ticker: "WBNB", - address: "0x442f7f22b1ee2c842beaff52880d4573e9201158", - rawAmount: "57933890000000000", - decimal: 18, - amount: "0.05793389", - logo: "https://api.rango.exchange/i/Xzflek", - usdPrice: null, - }, - { - chain: "AVAX_CCHAIN", - symbol: "GMX", - ticker: "GMX", - address: "0x62edc0692bd897d2295872a9ffcac5425011c661", - rawAmount: "379543333707025854", - decimal: 18, - amount: "0.379543333707025854", - logo: "https://api.rango.exchange/i/0aQTDd", - usdPrice: null, - }, - { - chain: "AVAX_CCHAIN", - symbol: "JOE", - ticker: "JOE", - address: "0x6e84a6216ea6dacc71ee8e6b0a5b7322eebc0fdd", - rawAmount: "35980183723492368253", - decimal: 18, - amount: "35.980183723492368253", - logo: "https://api.rango.exchange/i/Vw0Fv2", - usdPrice: 0.141, - }, - { - chain: "AVAX_CCHAIN", - symbol: "WETH.E", - ticker: "WETH.E", - address: "0x49d5c2bdffac6ce2bfdb6640f4f80f226bc10bab", - rawAmount: "17684493183273648", - decimal: 18, - amount: "0.017684493183273648", - logo: "https://api.rango.exchange/i/j9xgdC", - usdPrice: 1210.2, - }, - { - chain: "AVAX_CCHAIN", - symbol: "UST", - ticker: "UST", - address: "0xb599c3590f42f8f995ecfa0f85d2980b76862fc1", - rawAmount: "3993", - decimal: 6, - amount: "0.003993", - logo: "https://api.rango.exchange/i/0lk6id", - usdPrice: 0.02, - }, - { - chain: "AVAX_CCHAIN", - symbol: "USDT", - ticker: "USDT", - address: "0xde3a24028580884448a5397872046a019649b084", - rawAmount: "35748023", - decimal: 6, - amount: "35.748023", - logo: null, - usdPrice: null, - }, - { - chain: "AVAX_CCHAIN", - symbol: "24DROP.NET", - ticker: "24DROP.NET", - address: "0x2be494c06316c0d7371250419a9c659a0752ecb3", - rawAmount: "200000000000", - decimal: 8, - amount: "2000", - logo: null, - usdPrice: null, - }, - { - chain: "AVAX_CCHAIN", - symbol: "WETH", - ticker: "WETH", - address: "0x8b82a291f83ca07af22120aba21632088fc92931", - rawAmount: "5200000000000000", - decimal: 18, - amount: "0.0052", - logo: "https://api.rango.exchange/i/wNnplE", - usdPrice: null, - }, - { - chain: "AVAX_CCHAIN", - symbol: "0006648936.E9CB", - ticker: "0006648936.E9CB", - address: "0x38dcf0532699b880e6a125f7d918380524cd60a6", - rawAmount: "10000000000000000000", - decimal: 18, - amount: "10", - logo: null, - usdPrice: null, - }, - { - chain: "AVAX_CCHAIN", - symbol: "$ FREE CLAIM AND PLAY", - ticker: "$ FREE CLAIM AND PLAY", - address: "0xd23345e0e6340616b1cf7200762d0289547ccf87", - rawAmount: "50000000000", - decimal: 8, - amount: "500", - logo: null, - usdPrice: null, - }, - { - chain: "AVAX_CCHAIN", - symbol: "AMPL", - ticker: "AMPL", - address: "0x027dbca046ca156de9622cd1e2d907d375e53aa7", - rawAmount: "8302538186", - decimal: 9, - amount: "8.302538186", - logo: "https://api.rango.exchange/i/AiXtEj", - usdPrice: 1.078, - }, - { - chain: "AVAX_CCHAIN", - symbol: "USDT", - ticker: "USDT", - address: "0x9702230a8ea53601f5cd2dc00fdbc13d4df4a8c7", - rawAmount: "35280647", - decimal: 6, - amount: "35.280647", - logo: "https://api.rango.exchange/i/9e1hH8", - usdPrice: 1.005, - }, - { - chain: "AVAX_CCHAIN", - symbol: "MNEAV", - ticker: "MNEAV", - address: "0xf9d922c055a3f1759299467dafafdf43be844f7a", - rawAmount: "30000000000000", - decimal: 8, - amount: "300000", - logo: null, - usdPrice: null, - }, - { - chain: "AVAX_CCHAIN", - symbol: "USDC.E", - ticker: "USDC.E", - address: "0xa7d7079b0fead91f3e65f86e8915cb59c1a4c664", - rawAmount: "92749613", - decimal: 6, - amount: "92.749613", - logo: "https://api.rango.exchange/i/j9eYAa", - usdPrice: 1, - }, - { - chain: "AVAX_CCHAIN", - symbol: "BLIZZ", - ticker: "BLIZZ", - address: "0xb147656604217a03fe2c73c4838770df8d9d21b8", - rawAmount: "135470487277154696313", - decimal: 18, - amount: "135.470487277154696313", - logo: null, - usdPrice: null, - }, - { - chain: "AVAX_CCHAIN", - symbol: "USDT", - ticker: "USDT", - address: "0xc7198437980c041c805a1edcba50c1ce5db95118", - rawAmount: "36943578", - decimal: 6, - amount: "36.943578", - logo: "https://api.rango.exchange/i/niIihm", - usdPrice: null, - }, - { - chain: "AVAX_CCHAIN", - symbol: "MIM", - ticker: "MIM", - address: "0x130966628846bfd36ff31a822705796e8cb8c18d", - rawAmount: "13661627814282704200", - decimal: 18, - amount: "13.6616278142827042", - logo: "https://api.rango.exchange/i/RmsZZl", - usdPrice: 0.998, - }, - { - chain: "AVAX_CCHAIN", - symbol: "WAVAX", - ticker: "WAVAX", - address: "0xb31f66aa3c1e785363f0875a1b74e27b85fd66c7", - rawAmount: "553221840010000000", - decimal: 18, - amount: "0.55322184001", - logo: "https://api.rango.exchange/i/9bwFaG", - usdPrice: 11.97, - }, - { - chain: "AVAX_CCHAIN", - symbol: "AVAX", - ticker: "AVAX", - address: null, - rawAmount: "3293457782165450159", - decimal: 18, - amount: "3.293457782165450159", - logo: "https://api.rango.exchange/i/kX4edQ", - usdPrice: 11.77, - }, - ], - loading: false, - walletType: "metamask", - isConnected: false, - error: false, - explorerUrl: - "https://snowtrace.io/address/0x2702d89c1c8658b49c45dd460deebcc45faec03c", - }, - ], - }, - { - name: "ARBITRUM", - accounts: [ - { - address: "0x2702d89c1c8658b49c45dd460deebcc45faec03c", - balances: [ - { - chain: "ARBITRUM", - symbol: "JONES", - ticker: "JONES", - address: "0x10393c20975cf177a3513071bc110f7962cd67da", - rawAmount: "1933131668197791405", - decimal: 18, - amount: "1.933131668197791405", - logo: "https://api.rango.exchange/i/FUexNn", - usdPrice: null, - }, - { - chain: "ARBITRUM", - symbol: "DAI", - ticker: "DAI", - address: "0xda10009cbd5d07dd0cecc66161fc93d7c9000da1", - rawAmount: "19526880162738340394", - decimal: 18, - amount: "19.526880162738340394", - logo: "https://api.rango.exchange/i/yJvJre", - usdPrice: 1, - }, - { - chain: "ARBITRUM", - symbol: "MAGIC", - ticker: "MAGIC", - address: "0x539bde0d7dbd336b79148aa742883198bbf60342", - rawAmount: "9059590242", - decimal: 18, - amount: "0.000000009059590242", - logo: "https://api.rango.exchange/i/tazAGH", - usdPrice: null, - }, - { - chain: "ARBITRUM", - symbol: "UNI", - ticker: "UNI", - address: "0xfa7f8980b0f1e64a2062791cc3b0871572f1f7f0", - rawAmount: "2392264468", - decimal: 18, - amount: "0.000000002392264468", - logo: "https://api.rango.exchange/i/n8RX8F", - usdPrice: 5.246, - }, - { - chain: "ARBITRUM", - symbol: "HND", - ticker: "HND", - address: "0x10010078a54396f62c96df8532dc2b4847d47ed3", - rawAmount: "150921229948215461100", - decimal: 18, - amount: "150.9212299482154611", - logo: "https://api.rango.exchange/i/2SsRdS", - usdPrice: null, - }, - { - chain: "ARBITRUM", - symbol: "GMX", - ticker: "GMX", - address: "0xfc5a1a6eb076a2c7ad06ed22c90d7e710e35ad0a", - rawAmount: "128216748136770842", - decimal: 18, - amount: "0.128216748136770842", - logo: "https://api.rango.exchange/i/vCEMKq", - usdPrice: 46.259, - }, - { - chain: "ARBITRUM", - symbol: "RIFTDAO.NET", - ticker: "RIFTDAO.NET", - address: "0xe1cc7371f2c2b7ebb1af2b0c053ec86596e3f6d0", - rawAmount: "738097000000000000000000", - decimal: 18, - amount: "738097", - logo: null, - usdPrice: null, - }, - { - chain: "ARBITRUM", - symbol: "USDT", - ticker: "USDT", - address: "0xfd086bc7cd5c481dcc9c85ebe478a1c0b69fcbb9", - rawAmount: "40064700", - decimal: 6, - amount: "40.0647", - logo: "https://api.rango.exchange/i/aR1yFx", - usdPrice: 1, - }, - { - chain: "ARBITRUM", - symbol: "BADGER", - ticker: "BADGER", - address: "0xbfa641051ba0a0ad1b0acf549a89536a0d76472e", - rawAmount: "2089136975803812618", - decimal: 18, - amount: "2.089136975803812618", - logo: "https://api.rango.exchange/i/aaEEDq", - usdPrice: 2.26, - }, - { - chain: "ARBITRUM", - symbol: "USDC", - ticker: "USDC", - address: "0xff970a61a04b1ca14834a43f5de4533ebddb5cc8", - rawAmount: "55298622", - decimal: 6, - amount: "55.298622", - logo: "https://api.rango.exchange/i/ns0AMf", - usdPrice: 1, - }, - { - chain: "ARBITRUM", - symbol: "MIM", - ticker: "MIM", - address: "0xfea7a6a0b346362bf88a9e4a88416b77a57d6c2a", - rawAmount: "10100000000000000000", - decimal: 18, - amount: "10.1", - logo: "https://api.rango.exchange/i/JKT05f", - usdPrice: 0.998, - }, - { - chain: "ARBITRUM", - symbol: "AXLUSDC", - ticker: "AXLUSDC", - address: "0xeb466342c4d449bc9f53a865d5cb90586f405215", - rawAmount: "5500000", - decimal: 6, - amount: "5.5", - logo: null, - usdPrice: null, - }, - { - chain: "ARBITRUM", - symbol: "ETH", - ticker: "ETH", - address: null, - rawAmount: "82905399282605538", - decimal: 18, - amount: "0.082905399282605538", - logo: "https://api.rango.exchange/i/MTyH5i", - usdPrice: null, - }, - ], - loading: false, - walletType: "metamask", - isConnected: false, - error: false, - explorerUrl: - "https://arbiscan.io/address/0x2702d89c1c8658b49c45dd460deebcc45faec03c", - }, - ], - }, - { - name: "FANTOM", - accounts: [ - { - address: "0x2702d89c1c8658b49c45dd460deebcc45faec03c", - balances: [ - { - chain: "FANTOM", - symbol: "FBNB", - ticker: "FBNB", - address: "0x27f26f00e1605903645bbabc0a73e35027dccd45", - rawAmount: "15851797577951", - decimal: 18, - amount: "0.000015851797577951", - logo: "https://api.rango.exchange/tokens/FANTOM/FBNB.png", - usdPrice: null, - }, - { - chain: "FANTOM", - symbol: "WETH", - ticker: "WETH", - address: "0x74b23882a30290451a17c44f4f05243b6b58c76d", - rawAmount: "2171678666801825", - decimal: 18, - amount: "0.002171678666801825", - logo: "https://api.rango.exchange/tokens/FANTOM/WETH.png", - usdPrice: null, - }, - { - chain: "FANTOM", - symbol: "FXS", - ticker: "FXS", - address: "0x7d016eec9c25232b01f23ef992d98ca97fc2af5a", - rawAmount: "8129029359551099", - decimal: 18, - amount: "0.008129029359551099", - logo: "https://api.rango.exchange/i/TVDwaE", - usdPrice: null, - }, - { - chain: "FANTOM", - symbol: "WAVAX", - ticker: "WAVAX", - address: "0x511d35c52a3c244e7b8bd92c0c297755fbd89212", - rawAmount: "103423419794091413", - decimal: 18, - amount: "0.103423419794091413", - logo: "https://api.rango.exchange/tokens/FANTOM/WAVAX.png", - usdPrice: null, - }, - { - chain: "FANTOM", - symbol: "WOO", - ticker: "WOO", - address: "0x6626c47c00f1d87902fc13eecfac3ed06d5e8d8a", - rawAmount: "3069453396", - decimal: 18, - amount: "0.000000003069453396", - logo: "https://api.rango.exchange/i/UuEujP", - usdPrice: null, - }, - { - chain: "FANTOM", - symbol: "SWAPFTM.COM", - ticker: "SWAPFTM.COM", - address: "0x87e377820010d818aa316f8c3f1c2b9d025eb5ee", - rawAmount: "100000000000000000000", - decimal: 18, - amount: "100", - logo: null, - usdPrice: null, - }, - { - chain: "FANTOM", - symbol: "BIFI", - ticker: "BIFI", - address: "0xd6070ae98b8069de6b494332d1a1a81b6179d960", - rawAmount: "5427265333", - decimal: 18, - amount: "0.000000005427265333", - logo: "https://api.rango.exchange/i/euTXdM", - usdPrice: null, - }, - { - chain: "FANTOM", - symbol: "BNB", - ticker: "BNB", - address: "0xd67de0e0a0fd7b15dc8348bb9be742f3c5850454", - rawAmount: "4343993985", - decimal: 18, - amount: "0.000000004343993985", - logo: "https://api.rango.exchange/i/Yj2w83", - usdPrice: null, - }, - { - chain: "FANTOM", - symbol: "NUSD", - ticker: "NUSD", - address: "0xed2a7edd7413021d440b09d654f3b87712abab66", - rawAmount: "1993985245375892955", - decimal: 18, - amount: "1.993985245375892955", - logo: null, - usdPrice: null, - }, - { - chain: "FANTOM", - symbol: "MIM", - ticker: "MIM", - address: "0x82f0b8b456c1a451378467398982d4834b6829c1", - rawAmount: "38400000001430563305", - decimal: 18, - amount: "38.400000001430563305", - logo: "https://api.rango.exchange/i/ceBRSU", - usdPrice: null, - }, - { - chain: "FANTOM", - symbol: "888CRYPTO.PRO", - ticker: "888CRYPTO.PRO", - address: "0x7082ca5058c358997063400ad78306b16a5c30d9", - rawAmount: "150000000000000", - decimal: 8, - amount: "1500000", - logo: null, - usdPrice: null, - }, - { - chain: "FANTOM", - symbol: "2XCO", - ticker: "2XCO", - address: "0xcaef42682040a19e09eb8a6773f17da81b0604c1", - rawAmount: "9500000000000", - decimal: 8, - amount: "95000", - logo: null, - usdPrice: null, - }, - { - chain: "FANTOM", - symbol: "$ AIRDROP IN CAKE (MULTICHAIN)", - ticker: "$ AIRDROP IN CAKE (MULTICHAIN)", - address: "0xb502b79c9ec490c4eee130a03370d490b069e59b", - rawAmount: "50000000000", - decimal: 8, - amount: "500", - logo: null, - usdPrice: null, - }, - { - chain: "FANTOM", - symbol: "USDC", - ticker: "USDC", - address: "0x04068da6c83afcfa0e13ba15a6696662335d5b75", - rawAmount: "268477851", - decimal: 6, - amount: "268.477851", - logo: "https://api.rango.exchange/i/pva3ih", - usdPrice: null, - }, - { - chain: "FANTOM", - symbol: "0CASINO.IO", - ticker: "0CASINO.IO", - address: "0x383c5e5a05ba830579adc2fccd6403894e1caa59", - rawAmount: "150000000000000", - decimal: 8, - amount: "1500000", - logo: null, - usdPrice: null, - }, - { - chain: "FANTOM", - symbol: "WFTM", - ticker: "WFTM", - address: "0x21be370d5312f44cb42ce377bc9b8a0cef1a4c83", - rawAmount: "262664414658966373114", - decimal: 18, - amount: "262.664414658966373114", - logo: "https://api.rango.exchange/i/auYSf8", - usdPrice: null, - }, - { - chain: "FANTOM", - symbol: "ETH-1INCH.IO", - ticker: "ETH-1INCH.IO", - address: "0x5a7aad61871a39a972c11aa9cd48e8df1e10311d", - rawAmount: "870000000000000000", - decimal: 18, - amount: "0.87", - logo: null, - usdPrice: null, - }, - { - chain: "FANTOM", - symbol: "BUSD", - ticker: "BUSD", - address: "0xc931f61b1534eb21d8c11b24f3f5ab2471d4ab50", - rawAmount: "996216277676653329", - decimal: 18, - amount: "0.996216277676653329", - logo: "https://api.rango.exchange/i/zOV927", - usdPrice: null, - }, - { - chain: "FANTOM", - symbol: "DAI", - ticker: "DAI", - address: "0x8d11ec38a3eb5e956b052f67da8bdc9bef8abf3e", - rawAmount: "6907579712", - decimal: 18, - amount: "0.000000006907579712", - logo: "https://api.rango.exchange/i/iIxCAk", - usdPrice: null, - }, - { - chain: "FANTOM", - symbol: "RBNB", - ticker: "RBNB", - address: "0xc3394bb9b118b3c9b5b8da297e20c08878edbed4", - rawAmount: "100000000000000", - decimal: 18, - amount: "0.0001", - logo: null, - usdPrice: null, - }, - { - chain: "FANTOM", - symbol: "IMX", - ticker: "IMX", - address: "0xea38f1ccf77bf43f352636241b05dd8f6f5f52b2", - rawAmount: "116509710", - decimal: 18, - amount: "0.00000000011650971", - logo: "https://api.rango.exchange/i/3nnwQN", - usdPrice: null, - }, - { - chain: "FANTOM", - symbol: "24DROP.NET", - ticker: "24DROP.NET", - address: "0x67a58a20f087a600aec491d5cd329ba597b71aa7", - rawAmount: "200000000000", - decimal: 8, - amount: "2000", - logo: null, - usdPrice: null, - }, - { - chain: "FANTOM", - symbol: "MNEF", - ticker: "MNEF", - address: "0xf9d922c055a3f1759299467dafafdf43be844f7a", - rawAmount: "30000000000000", - decimal: 8, - amount: "300000", - logo: null, - usdPrice: null, - }, - { - chain: "FANTOM", - symbol: " 0VISIT [003ERRORNOTICE.COM] TO SECURE YOUR FUNDS.", - ticker: " 0VISIT [003ERRORNOTICE.COM] TO SECURE YOUR FUNDS.", - address: "0x98e4b3866602fc72ff766616e15146c9153b473b", - rawAmount: "2200000000000000000000", - decimal: 18, - amount: "2200", - logo: null, - usdPrice: null, - }, - { - chain: "FANTOM", - symbol: "0CASINO.IO", - ticker: "0CASINO.IO", - address: "0xbe1b23d652580052dd8e774e0e7e92cf5cc31bb3", - rawAmount: "150000000000000", - decimal: 8, - amount: "1500000", - logo: null, - usdPrice: null, - }, - { - chain: "FANTOM", - symbol: "CRV", - ticker: "CRV", - address: "0x1e4f97b9f9f913c46f1632781732927b9019c68b", - rawAmount: "2433604212107615486", - decimal: 18, - amount: "2.433604212107615486", - logo: "https://api.rango.exchange/i/60avSg", - usdPrice: null, - }, - { - chain: "FANTOM", - symbol: "4GAMBLING.IO", - ticker: "4GAMBLING.IO", - address: "0xe4517100ae62cbeefc363e59d0f8df5754dc7e40", - rawAmount: "300000000000000", - decimal: 8, - amount: "3000000", - logo: null, - usdPrice: null, - }, - { - chain: "FANTOM", - symbol: "USDT", - ticker: "USDT", - address: "0x049d68029688eabf473097a2fc38ef61633a3c7a", - rawAmount: "63082358", - decimal: 6, - amount: "63.082358", - logo: "https://api.rango.exchange/i/niIihm", - usdPrice: null, - }, - { - chain: "FANTOM", - symbol: "FTM", - ticker: "FTM", - address: null, - rawAmount: "1346689531144440162650", - decimal: 18, - amount: "1346.68953114444016265", - logo: "https://api.rango.exchange/i/JC2fWD", - usdPrice: null, - }, - ], - loading: false, - walletType: "metamask", - isConnected: false, - error: false, - explorerUrl: - "https://ftmscan.com/address/0x2702d89c1c8658b49c45dd460deebcc45faec03c", - }, - ], - }, - { - name: "OPTIMISM", - accounts: [ - { - address: "0x2702d89c1c8658b49c45dd460deebcc45faec03c", - balances: [ - { - chain: "OPTIMISM", - symbol: "USDT", - ticker: "USDT", - address: "0x94b008aa00579c1307b0ef2c499ad98a8ce58e58", - rawAmount: "22874529", - decimal: 6, - amount: "22.874529", - logo: "https://api.rango.exchange/i/K6j5VN", - usdPrice: 1, - }, - { - chain: "OPTIMISM", - symbol: "USDC", - ticker: "USDC", - address: "0x7f5c764cbc14f9669b88837ca1490cca17c31607", - rawAmount: "39610548", - decimal: 6, - amount: "39.610548", - logo: "https://api.rango.exchange/i/e4x0s8", - usdPrice: 0.999, - }, - { - chain: "OPTIMISM", - symbol: "WETH", - ticker: "WETH", - address: "0x4200000000000000000000000000000000000006", - rawAmount: "30671676019131723", - decimal: 18, - amount: "0.030671676019131723", - logo: "https://api.rango.exchange/i/yZ9N1N", - usdPrice: 1207.06, - }, - { - chain: "OPTIMISM", - symbol: "DAI", - ticker: "DAI", - address: "0xda10009cbd5d07dd0cecc66161fc93d7c9000da1", - rawAmount: "1535439265", - decimal: 18, - amount: "0.000000001535439265", - logo: "https://api.rango.exchange/i/zyZx0X", - usdPrice: 1, - }, - { - chain: "OPTIMISM", - symbol: "ETH", - ticker: "ETH", - address: null, - rawAmount: "3809903995186154", - decimal: 18, - amount: "0.003809903995186154", - logo: "https://api.rango.exchange/i/MTyH5i", - usdPrice: null, - }, - ], - loading: false, - walletType: "metamask", - isConnected: false, - error: false, - explorerUrl: - "https://optimistic.etherscan.io/address/0x2702d89c1c8658b49c45dd460deebcc45faec03c", - }, - ], - }, - { - name: "OKC", - accounts: [ - { - address: "0x2702d89c1c8658b49c45dd460deebcc45faec03c", - balances: [], - loading: false, - walletType: "metamask", - isConnected: false, - error: true, - explorerUrl: - "https://www.oklink.com/en/okc/address/0x2702d89c1c8658b49c45dd460deebcc45faec03c", - }, - ], - }, - { - name: "CRONOS", - accounts: [ - { - address: "0x2702d89c1c8658b49c45dd460deebcc45faec03c", - balances: [ - { - chain: "CRONOS", - symbol: "WETH", - ticker: "WETH", - address: "0xe44fd7fcb2b1581822d0c862b68222998a0c299a", - rawAmount: "4788770370", - decimal: 18, - amount: "0.00000000478877037", - logo: "https://api.rango.exchange/i/j9xgdC", - usdPrice: 1210.2, - }, - { - chain: "CRONOS", - symbol: "AUTO", - ticker: "AUTO", - address: "0x0dcb0cb0120d355cde1ce56040be57add0185baa", - rawAmount: "43013763072696143", - decimal: 18, - amount: "0.043013763072696143", - logo: "https://api.rango.exchange/i/YxjmF0", - usdPrice: 222.98, - }, - { - chain: "CRONOS", - symbol: "CRONOSCLASSIC.COM", - ticker: "CRONOSCLASSIC.COM", - address: "0x772c96ed2f99d84c2a83e67fbada9a1db4303be1", - rawAmount: "9000000000000000000000", - decimal: 18, - amount: "9000", - logo: null, - usdPrice: null, - }, - { - chain: "CRONOS", - symbol: "BNB", - ticker: "BNB", - address: "0xfa9343c3897324496a05fc75abed6bac29f8a40f", - rawAmount: "86000000000000000", - decimal: 18, - amount: "0.086", - logo: "https://api.rango.exchange/i/B4ULZJ", - usdPrice: 248.28, - }, - { - chain: "CRONOS", - symbol: "USDT", - ticker: "USDT", - address: "0x66e428c3f67a68878562e79a0234c1f83c208770", - rawAmount: "1287808", - decimal: 6, - amount: "1.287808", - logo: "https://api.rango.exchange/i/GJxbOP", - usdPrice: 1, - }, - { - chain: "CRONOS", - symbol: "CRONOSCLASSIC.COM", - ticker: "CRONOSCLASSIC.COM", - address: "0x75f920403641ddbd66f8ce3ddd3a648ddb496c89", - rawAmount: "9000000000000000000000", - decimal: 18, - amount: "9000", - logo: null, - usdPrice: null, - }, - { - chain: "CRONOS", - symbol: "CRO", - ticker: "CRO", - address: null, - rawAmount: "218462428966917726855", - decimal: 18, - amount: "218.462428966917726855", - logo: "https://api.rango.exchange/i/S3tFKF", - usdPrice: 0.0579, - }, - ], - loading: false, - walletType: "metamask", - isConnected: false, - error: false, - explorerUrl: - "https://cronoscan.com/address/0x2702d89c1c8658b49c45dd460deebcc45faec03c", - }, - ], - }, - { - name: "MOONRIVER", - accounts: [ - { - address: "0x2702d89c1c8658b49c45dd460deebcc45faec03c", - balances: [ - { - chain: "MOONRIVER", - symbol: "MOVR", - ticker: "MOVR", - address: null, - rawAmount: "1409467396930959879", - decimal: 18, - amount: "1.409467396930959879", - logo: "https://api.rango.exchange/i/AKXDjV", - usdPrice: null, - }, - ], - loading: false, - walletType: "metamask", - isConnected: false, - error: false, - explorerUrl: - "https://moonriver.moonscan.io/address/0x2702d89c1c8658b49c45dd460deebcc45faec03c", - }, - ], - }, - { - name: "MOONBEAM", - accounts: [ - { - address: "0x2702d89c1c8658b49c45dd460deebcc45faec03c", - balances: [ - { - chain: "MOONBEAM", - symbol: "GLMR", - ticker: "GLMR", - address: null, - rawAmount: "7637316155712999392", - decimal: 18, - amount: "7.637316155712999392", - logo: "https://api.rango.exchange/i/Ra0xKh", - usdPrice: 0.343, - }, - ], - loading: false, - walletType: "metamask", - isConnected: false, - error: false, - explorerUrl: - "https://moonbeam.moonscan.io/address/0x2702d89c1c8658b49c45dd460deebcc45faec03c", - }, - ], - }, - { - name: "HECO", - accounts: [ - { - address: "0x2702d89c1c8658b49c45dd460deebcc45faec03c", - balances: [ - { - chain: "HECO", - symbol: "HT", - ticker: "HT", - address: null, - rawAmount: "8900958749249974840", - decimal: 18, - amount: "8.90095874924997484", - logo: "https://api.rango.exchange/i/9uAYzf", - usdPrice: 5.361, - }, - ], - loading: false, - walletType: "metamask", - isConnected: false, - error: false, - explorerUrl: - "https://hecoinfo.com/address/0x2702d89c1c8658b49c45dd460deebcc45faec03c", - }, - ], - }, - { - name: "AURORA", - accounts: [ - { - address: "0x2702d89c1c8658b49c45dd460deebcc45faec03c", - balances: [ - { - chain: "AURORA", - symbol: "MATIC", - ticker: "MATIC", - address: "0x6ab6d61428fde76768d7b45d8bfeec19c6ef91a8", - rawAmount: "4963601767", - decimal: 18, - amount: "0.000000004963601767", - logo: "https://api.rango.exchange/i/yVbC8U", - usdPrice: 0.793, - }, - { - chain: "AURORA", - symbol: "AVAX", - ticker: "AVAX", - address: "0x80a16016cc4a2e6a2caca8a4a498b1699ff0f844", - rawAmount: "2088345237", - decimal: 18, - amount: "0.000000002088345237", - logo: "https://api.rango.exchange/i/kX4edQ", - usdPrice: 11.77, - }, - { - chain: "AURORA", - symbol: "WETH", - ticker: "WETH", - address: "0xc9bdeed33cd01541e1eed10f90519d2c06fe3feb", - rawAmount: "1000000328916822", - decimal: 18, - amount: "0.001000000328916822", - logo: "https://api.rango.exchange/i/3h0NwB", - usdPrice: 1272.743, - }, - { - chain: "AURORA", - symbol: "USDC", - ticker: "USDC", - address: "0xb12bfca5a55806aaf64e99521918a4bf0fc40802", - rawAmount: "25059116", - decimal: 6, - amount: "25.059116", - logo: "https://api.rango.exchange/i/UfM0ap", - usdPrice: 0.998, - }, - { - chain: "AURORA", - symbol: "USDT", - ticker: "USDT", - address: "0x4988a896b1227218e4a686fde5eabdcabd91571f", - rawAmount: "9373920", - decimal: 6, - amount: "9.37392", - logo: "https://api.rango.exchange/i/sq7c5G", - usdPrice: 1.005, - }, - { - chain: "AURORA", - symbol: "ATLUNA", - ticker: "ATLUNA", - address: "0xc4bdd27c33ec7daa6fcfd8532ddb524bf4038096", - rawAmount: "7269857397", - decimal: 18, - amount: "0.000000007269857397", - logo: "https://api.rango.exchange/i/kIZ1fy", - usdPrice: null, - }, - { - chain: "AURORA", - symbol: "PICKLE", - ticker: "PICKLE", - address: "0x291c8fceaca3342b29cc36171deb98106f712c66", - rawAmount: "3462515627985423594", - decimal: 18, - amount: "3.462515627985423594", - logo: "https://api.rango.exchange/i/LPaa2J", - usdPrice: null, - }, - { - chain: "AURORA", - symbol: "PAPR", - ticker: "PAPR", - address: "0xa5c09de3aa1cdb5cb190be66c77e033be1ca594a", - rawAmount: "163912004957041283", - decimal: 18, - amount: "0.163912004957041283", - logo: "https://api.rango.exchange/i/sXsnQu", - usdPrice: 0.452, - }, - { - chain: "AURORA", - symbol: "PRNTR", - ticker: "PRNTR", - address: "0x29daeb6a2a87b159f5fee1f19ec6ccaf4ef2acca", - rawAmount: "307884579855694445", - decimal: 18, - amount: "0.307884579855694445", - logo: "https://api.rango.exchange/i/Uf33Cw", - usdPrice: 0.602, - }, - ], - loading: false, - walletType: "metamask", - isConnected: false, - error: false, - explorerUrl: - "https://explorer.mainnet.aurora.dev/address/0x2702d89c1c8658b49c45dd460deebcc45faec03c", - }, - ], - }, - { - name: "HARMONY", - accounts: [ - { - address: "0x2702d89c1c8658b49c45dd460deebcc45faec03c", - balances: [ - { - chain: "HARMONY", - symbol: "ONE", - ticker: "ONE", - address: null, - rawAmount: "48801440860746527271", - decimal: 18, - amount: "48.801440860746527271", - logo: "https://api.rango.exchange/i/gpMxOP", - usdPrice: 0.109, - }, - { - chain: "HARMONY", - symbol: "1DAI", - ticker: "1DAI", - address: "0xef977d2f931c1978db5f6747666fa1eacb0d0339", - rawAmount: "3951799808", - decimal: 18, - amount: "0.000000003951799808", - logo: "https://api.rango.exchange/i/7UdDll", - usdPrice: 0.961, - }, - { - chain: "HARMONY", - symbol: "1USDC", - ticker: "1USDC", - address: "0x985458e523db3d53125813ed68c274899e9dfab4", - rawAmount: "4480342", - decimal: 6, - amount: "4.480342", - logo: "https://api.rango.exchange/i/4eEvKA", - usdPrice: 1.006, - }, - { - chain: "HARMONY", - symbol: "bscBUSD", - ticker: "bscBUSD", - address: "0x0ab43550a6915f9f67d0c454c2e90385e6497eaa", - rawAmount: "12000000009249314069", - decimal: 18, - amount: "12.000000009249314069", - logo: "https://api.rango.exchange/i/uZMcKl", - usdPrice: 0.946, - }, - { - chain: "HARMONY", - symbol: "BUSD", - ticker: "BUSD", - address: "0xe176ebe47d621b984a73036b9da5d834411ef734", - rawAmount: "6201993388439322612", - decimal: 18, - amount: "6.201993388439322612", - logo: "https://api.rango.exchange/i/qWxf4I", - usdPrice: 0.84, - }, - { - chain: "HARMONY", - symbol: "UST", - ticker: "UST", - address: "0x224e64ec1bdce3870a6a6c777edd450454068fec", - rawAmount: "5449588252", - decimal: 18, - amount: "0.000000005449588252", - logo: "https://api.rango.exchange/i/wmyHK9", - usdPrice: 0.194, - }, - { - chain: "HARMONY", - symbol: "WONE", - ticker: "WONE", - address: "0xcf664087a5bb0237a0bad6742852ec6c8d69a27a", - rawAmount: "2000000000624440839", - decimal: 18, - amount: "2.000000000624440839", - logo: "https://api.rango.exchange/i/u283bK", - usdPrice: 0.109, - }, - { - chain: "HARMONY", - symbol: "BIFI", - ticker: "BIFI", - address: "0x6ab6d61428fde76768d7b45d8bfeec19c6ef91a8", - rawAmount: "6500000000000000", - decimal: 18, - amount: "0.0065", - logo: "https://api.rango.exchange/i/EuFqit", - usdPrice: 325.37, - }, - { - chain: "HARMONY", - symbol: "JENN", - ticker: "JENN", - address: "0x2f459dd7cbcc9d8323621f6fb430cd0555411e7b", - rawAmount: "82666600666715773", - decimal: 18, - amount: "0.082666600666715773", - logo: "https://api.rango.exchange/i/5CYmzQ", - usdPrice: 0.00429, - }, - { - chain: "HARMONY", - symbol: "LMA", - ticker: "LMA", - address: "0x7d0546dbb1dca8108d99aa389a8e9ce0c40b2370", - rawAmount: "2335555755", - decimal: 18, - amount: "0.000000002335555755", - logo: "https://api.rango.exchange/i/A8Kw4L", - usdPrice: 33.26, - }, - ], - loading: false, - walletType: "metamask", - isConnected: false, - error: false, - explorerUrl: - "https://explorer.harmony.one/address/0x2702d89c1c8658b49c45dd460deebcc45faec03c", - }, - ], - }, - { - name: "EVMOS", - accounts: [ - { - address: "0x2702d89c1c8658b49c45dd460deebcc45faec03c", - balances: [], - loading: false, - walletType: "metamask", - isConnected: false, - error: true, - explorerUrl: - "https://evm.evmos.org/address/0x2702d89c1c8658b49c45dd460deebcc45faec03c", - }, - ], - }, - { - name: "GNOSIS", - accounts: [ - { - address: "0x2702d89c1c8658b49c45dd460deebcc45faec03c", - balances: [], - loading: false, - walletType: "metamask", - isConnected: false, - error: true, - explorerUrl: - "https://blockscout.com/xdai/mainnet/address/0x2702d89c1c8658b49c45dd460deebcc45faec03c", - }, - ], - }, - { - name: "FUSE", - accounts: [ - { - address: "0x2702d89c1c8658b49c45dd460deebcc45faec03c", - balances: [], - loading: false, - walletType: "metamask", - isConnected: false, - error: true, - explorerUrl: - "https://explorer.fuse.io/address/0x2702d89c1c8658b49c45dd460deebcc45faec03c", - }, - ], - }, - { - name: "BOBA", - accounts: [ - { - address: "0x2702d89c1c8658b49c45dd460deebcc45faec03c", - balances: [ - { - chain: "BOBA", - symbol: "MIM", - ticker: "MIM", - address: "0x218c3c3d49d0e7b37aff0d8bb079de36ae61a4c0", - rawAmount: "105604450000000000", - decimal: 18, - amount: "0.10560445", - logo: "https://api.rango.exchange/i/RmsZZl", - usdPrice: 0.998, - }, - { - chain: "BOBA", - symbol: "BUSD", - ticker: "BUSD", - address: "0x461d52769884ca6235b685ef2040f47d30c94eb5", - rawAmount: "5431734874", - decimal: 18, - amount: "0.000000005431734874", - logo: "https://api.rango.exchange/i/PsiPay", - usdPrice: 0.999, - }, - { - chain: "BOBA", - symbol: "UNIDX", - ticker: "UNIDX", - address: "0x375488f097176507e39b9653b88fdc52cde736bf", - rawAmount: "23224657182604680757", - decimal: 18, - amount: "23.224657182604680757", - logo: "https://api.rango.exchange/i/TZv5rn", - usdPrice: 2.3, - }, - { - chain: "BOBA", - symbol: "BANA", - ticker: "BANA", - address: "0xc67b9b1b0557aeafa10aa1ffa1d7c87087a6149e", - rawAmount: "9067814698", - decimal: 18, - amount: "0.000000009067814698", - logo: "https://api.rango.exchange/i/gyHe7C", - usdPrice: null, - }, - { - chain: "BOBA", - symbol: "BDOGE", - ticker: "BDOGE", - address: "0x121636c43e96d97ab00b6c6994cddebef27de1c7", - rawAmount: "723068225237233960", - decimal: 18, - amount: "0.72306822523723396", - logo: "https://api.rango.exchange/i/U6UPsb", - usdPrice: 1.64e-9, - }, - { - chain: "BOBA", - symbol: "SHIBUI", - ticker: "SHIBUI", - address: "0xf08ad7c3f6b1c6843ba027ad54ed8ddb6d71169b", - rawAmount: "1827087060", - decimal: 18, - amount: "0.00000000182708706", - logo: "https://api.rango.exchange/i/Mwv1h9", - usdPrice: 0.00631, - }, - { - chain: "BOBA", - symbol: "USDC", - ticker: "USDC", - address: "0x66a2a913e447d6b4bf33efbec43aaef87890fbbc", - rawAmount: "11210692", - decimal: 6, - amount: "11.210692", - logo: "https://api.rango.exchange/i/ahp7BS", - usdPrice: 0.993, - }, - { - chain: "BOBA", - symbol: "BOBA", - ticker: "BOBA", - address: "0xa18bf3994c0cc6e3b63ac420308e5383f53120d7", - rawAmount: "1093312869", - decimal: 18, - amount: "0.000000001093312869", - logo: "https://api.rango.exchange/i/vWYKUH", - usdPrice: 0.181, - }, - { - chain: "BOBA", - symbol: "WETH", - ticker: "WETH", - address: "0xdeaddeaddeaddeaddeaddeaddeaddeaddead0000", - rawAmount: "2606189668", - decimal: 18, - amount: "0.000000002606189668", - logo: "https://api.rango.exchange/i/fEyllw", - usdPrice: 1197.276, - }, - { - chain: "BOBA", - symbol: "DAI", - ticker: "DAI", - address: "0xf74195bb8a5cf652411867c5c2c5b8c2a402be35", - rawAmount: "2131602501374765414", - decimal: 18, - amount: "2.131602501374765414", - logo: "https://api.rango.exchange/i/U8PEdb", - usdPrice: null, - }, - { - chain: "BOBA", - symbol: "ETH", - ticker: "ETH", - address: null, - rawAmount: "884271636924027", - decimal: 18, - amount: "0.000884271636924027", - logo: "https://api.rango.exchange/i/MTyH5i", - usdPrice: 1197.276, - }, - ], - loading: false, - walletType: "metamask", - isConnected: false, - error: false, - explorerUrl: - "https://bobascan.com//address/0x2702d89c1c8658b49c45dd460deebcc45faec03c", - }, - ], - }, - ], -} as Wallet; - -export const walletsAndSupportedChains = { - "binance-chain": [ - { - name: "BSC", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "BSC", symbol: "BNB", address: null }], - logo: "https://api.rango.exchange/blockchains/binance.svg", - displayName: "BSC", - shortName: "BSC", - sort: 1, - color: "#F3BA2F", - enabled: true, - type: "EVM", - chainId: "0x38", - info: { - chainName: "Binance Smart Chain Mainnet", - nativeCurrency: { name: "BNB", symbol: "BNB", decimals: 18 }, - rpcUrls: ["https://bsc-dataseed1.ninicoin.io"], - blockExplorerUrls: ["https://bscscan.com"], - addressUrl: "https://bscscan.com/address/{wallet}", - transactionUrl: "https://bscscan.com/tx/{txHash}", - }, - }, - { - name: "ETH", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "ETH", symbol: "ETH", address: null }], - logo: "https://api.rango.exchange/blockchains/ethereum.svg", - displayName: "Ethereum", - shortName: "ETH", - sort: 3, - color: "#ecf0f1", - enabled: true, - type: "EVM", - chainId: "0x1", - info: { - chainName: "Ethereum Mainnet", - nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 }, - rpcUrls: ["https://rpc.ankr.com/eth"], - blockExplorerUrls: ["https://etherscan.io"], - addressUrl: "https://etherscan.io/address/{wallet}", - transactionUrl: "https://etherscan.io/tx/{txHash}", - }, - }, - { - name: "BNB", - defaultDecimals: 8, - addressPatterns: ["^(bnb1)[0-9a-z]{38}$"], - feeAssets: [{ blockchain: "BNB", symbol: "BNB", address: null }], - logo: "https://api.rango.exchange/blockchains/bnb.svg", - displayName: "Binance Chain", - shortName: "BNB", - sort: 18, - color: "#F3BA2F", - enabled: true, - type: "COSMOS", - chainId: null, - info: null, - }, - ], - metamask: [ - { - name: "BSC", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "BSC", symbol: "BNB", address: null }], - logo: "https://api.rango.exchange/blockchains/binance.svg", - displayName: "BSC", - shortName: "BSC", - sort: 1, - color: "#F3BA2F", - enabled: true, - type: "EVM", - chainId: "0x38", - info: { - chainName: "Binance Smart Chain Mainnet", - nativeCurrency: { name: "BNB", symbol: "BNB", decimals: 18 }, - rpcUrls: ["https://bsc-dataseed1.ninicoin.io"], - blockExplorerUrls: ["https://bscscan.com"], - addressUrl: "https://bscscan.com/address/{wallet}", - transactionUrl: "https://bscscan.com/tx/{txHash}", - }, - }, - { - name: "POLYGON", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "POLYGON", symbol: "MATIC", address: null }], - logo: "https://api.rango.exchange/blockchains/polygon.svg", - displayName: "Polygon", - shortName: "Polygon", - sort: 2, - color: "#8247E5", - enabled: true, - type: "EVM", - chainId: "0x89", - info: { - chainName: "Polygon Mainnet", - nativeCurrency: { name: "MATIC", symbol: "MATIC", decimals: 18 }, - rpcUrls: ["https://polygon-rpc.com"], - blockExplorerUrls: ["https://polygonscan.com"], - addressUrl: "https://polygonscan.com/address/{wallet}", - transactionUrl: "https://polygonscan.com/tx/{txHash}", - }, - }, - { - name: "ETH", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "ETH", symbol: "ETH", address: null }], - logo: "https://api.rango.exchange/blockchains/ethereum.svg", - displayName: "Ethereum", - shortName: "ETH", - sort: 3, - color: "#ecf0f1", - enabled: true, - type: "EVM", - chainId: "0x1", - info: { - chainName: "Ethereum Mainnet", - nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 }, - rpcUrls: ["https://rpc.ankr.com/eth"], - blockExplorerUrls: ["https://etherscan.io"], - addressUrl: "https://etherscan.io/address/{wallet}", - transactionUrl: "https://etherscan.io/tx/{txHash}", - }, - }, - { - name: "AVAX_CCHAIN", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "AVAX_CCHAIN", symbol: "AVAX", address: null }], - logo: "https://api.rango.exchange/blockchains/avax_cchain.svg", - displayName: "Avalanche", - shortName: "Avax", - sort: 6, - color: "#e84142", - enabled: true, - type: "EVM", - chainId: "0xa86a", - info: { - chainName: "Avalanche C-Chain", - nativeCurrency: { name: "AVAX", symbol: "AVAX", decimals: 18 }, - rpcUrls: ["https://api.avax.network/ext/bc/C/rpc"], - blockExplorerUrls: ["https://snowtrace.io"], - addressUrl: "https://snowtrace.io/address/{wallet}", - transactionUrl: "https://snowtrace.io/tx/{txHash}", - }, - }, - { - name: "ARBITRUM", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "ARBITRUM", symbol: "ETH", address: null }], - logo: "https://api.rango.exchange/blockchains/arbitrum.svg", - displayName: "Arbitrum", - shortName: "Arbitrum", - sort: 7, - color: "#28a0f0", - enabled: true, - type: "EVM", - chainId: "0xa4b1", - info: { - chainName: "Arbitrum One", - nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 }, - rpcUrls: ["https://arb1.arbitrum.io/rpc"], - blockExplorerUrls: ["https://arbiscan.io"], - addressUrl: "https://arbiscan.io/address/{wallet}", - transactionUrl: "https://arbiscan.io/tx/{txHash}", - }, - }, - { - name: "FANTOM", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "FANTOM", symbol: "FTM", address: null }], - logo: "https://api.rango.exchange/blockchains/fantom.png", - displayName: "Fantom", - shortName: "Fantom", - sort: 9, - color: "#337afe", - enabled: true, - type: "EVM", - chainId: "0xfa", - info: { - chainName: "Fantom Opera", - nativeCurrency: { name: "FTM", symbol: "FTM", decimals: 18 }, - rpcUrls: ["https://rpc.ftm.tools"], - blockExplorerUrls: ["https://ftmscan.com"], - addressUrl: "https://ftmscan.com/address/{wallet}", - transactionUrl: "https://ftmscan.com/tx/{txHash}", - }, - }, - { - name: "OPTIMISM", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "OPTIMISM", symbol: "ETH", address: null }], - logo: "https://api.rango.exchange/blockchains/optimism.svg", - displayName: "Optimism", - shortName: "Optimism", - sort: 10, - color: "#FF0420", - enabled: true, - type: "EVM", - chainId: "0xa", - info: { - chainName: "Optimism", - nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 }, - rpcUrls: ["https://mainnet.optimism.io"], - blockExplorerUrls: ["https://optimistic.etherscan.io"], - addressUrl: "https://optimistic.etherscan.io/address/{wallet}", - transactionUrl: "https://optimistic.etherscan.io/tx/{txHash}", - }, - }, - { - name: "OKC", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "OKC", symbol: "OKT", address: null }], - logo: "https://api.rango.exchange/blockchains/okx.png", - displayName: "OKX Chain (OKC)", - shortName: "Okx", - sort: 11, - color: "#29a0f0", - enabled: true, - type: "EVM", - chainId: "0x42", - info: { - chainName: "OKX Chain", - nativeCurrency: { name: "OKT", symbol: "OKT", decimals: 18 }, - rpcUrls: ["https://exchainrpc.okex.org"], - blockExplorerUrls: ["https://www.oklink.com/en/okc"], - addressUrl: "https://www.oklink.com/en/okc/address/{wallet}", - transactionUrl: "https://www.oklink.com/en/okc/tx/{txHash}", - }, - }, - { - name: "CRONOS", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "CRONOS", symbol: "CRO", address: null }], - logo: "https://api.rango.exchange/blockchains/cronos.svg", - displayName: "Cronos", - shortName: "Cronos", - sort: 12, - color: "#1a90ff", - enabled: true, - type: "EVM", - chainId: "0x19", - info: { - chainName: "Cronos Mainnet Beta", - nativeCurrency: { name: "CRO", symbol: "CRO", decimals: 18 }, - rpcUrls: ["https://cronosrpc-1.xstaking.sg"], - blockExplorerUrls: ["https://cronoscan.com"], - addressUrl: "https://cronoscan.com/address/{wallet}", - transactionUrl: "https://cronoscan.com/tx/{txHash}", - }, - }, - { - name: "MOONRIVER", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "MOONRIVER", symbol: "MOVR", address: null }], - logo: "https://api.rango.exchange/blockchains/moonriver.svg", - displayName: "MoonRiver", - shortName: "MoonRiver", - sort: 13, - color: "#F3B404", - enabled: true, - type: "EVM", - chainId: "0x505", - info: { - chainName: "MoonRiver", - nativeCurrency: { name: "MOVR", symbol: "MOVR", decimals: 18 }, - rpcUrls: ["https://rpc.moonriver.moonbeam.network"], - blockExplorerUrls: ["https://moonriver.moonscan.io"], - addressUrl: "https://moonriver.moonscan.io/address/{wallet}", - transactionUrl: "https://moonriver.moonscan.io/tx/{txHash}", - }, - }, - { - name: "MOONBEAM", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "MOONBEAM", symbol: "GLMR", address: null }], - logo: "https://api.rango.exchange/blockchains/moonbeam.png", - displayName: "MoonBeam", - shortName: "MoonBeam", - sort: 14, - color: "#B3206B", - enabled: true, - type: "EVM", - chainId: "0x504", - info: { - chainName: "MoonBeam", - nativeCurrency: { name: "GLMR", symbol: "GLMR", decimals: 18 }, - rpcUrls: ["https://rpc.api.moonbeam.network"], - blockExplorerUrls: ["https://moonbeam.moonscan.io"], - addressUrl: "https://moonbeam.moonscan.io/address/{wallet}", - transactionUrl: "https://moonbeam.moonscan.io/tx/{txHash}", - }, - }, - { - name: "HECO", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "HECO", symbol: "HT", address: null }], - logo: "https://api.rango.exchange/blockchains/heco.png", - displayName: "Heco", - shortName: "Heco", - sort: 15, - color: "#4CA852", - enabled: true, - type: "EVM", - chainId: "0x80", - info: { - chainName: "Huobi ECO Chain Mainnet", - nativeCurrency: { name: "HT", symbol: "HT", decimals: 18 }, - rpcUrls: ["https://http-mainnet.hecochain.com"], - blockExplorerUrls: ["https://hecoinfo.com"], - addressUrl: "https://hecoinfo.com/address/{wallet}", - transactionUrl: "https://hecoinfo.com/tx/{txHash}", - }, - }, - { - name: "AURORA", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "AURORA", symbol: "ETH", address: null }], - logo: "https://api.rango.exchange/blockchains/aurora.svg", - displayName: "Aurora", - shortName: "Aurora", - sort: 15, - color: "#78d64b", - enabled: true, - type: "EVM", - chainId: "0x4e454152", - info: { - chainName: "Aurora Mainnet", - nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 }, - rpcUrls: ["https://mainnet.aurora.dev"], - blockExplorerUrls: ["https://explorer.mainnet.aurora.dev"], - addressUrl: "https://explorer.mainnet.aurora.dev/address/{wallet}", - transactionUrl: "https://explorer.mainnet.aurora.dev/tx/{txHash}", - }, - }, - { - name: "HARMONY", - defaultDecimals: 18, - addressPatterns: ["^(one1)[0-9a-z]{38}$", "^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "HARMONY", symbol: "ONE", address: null }], - logo: "https://api.rango.exchange/blockchains/harmony.svg", - displayName: "Harmony", - shortName: "Harmony", - sort: 15, - color: "#50AEE9", - enabled: true, - type: "EVM", - chainId: "0x63564c40", - info: { - chainName: "Harmony Mainnet", - nativeCurrency: { name: "ONE", symbol: "ONE", decimals: 18 }, - rpcUrls: ["https://api.s0.t.hmny.io"], - blockExplorerUrls: ["https://explorer.harmony.one"], - addressUrl: "https://explorer.harmony.one/address/{wallet}", - transactionUrl: "https://explorer.harmony.one/tx/{txHash}", - }, - }, - { - name: "EVMOS", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "EVMOS", symbol: "EVMOS", address: null }], - logo: "https://api.rango.exchange/blockchains/evmos.png", - displayName: "Evmos", - shortName: "Evmos", - sort: 15, - color: "#2D2925", - enabled: true, - type: "EVM", - chainId: "0x2329", - info: { - chainName: "Evmos", - nativeCurrency: { name: "EVMOS", symbol: "EVMOS", decimals: 18 }, - rpcUrls: ["https://eth.bd.evmos.org:8545"], - blockExplorerUrls: ["https://evm.evmos.org"], - addressUrl: "https://evm.evmos.org/address/{wallet}", - transactionUrl: "https://evm.evmos.org/tx/{txHash}", - }, - }, - { - name: "GNOSIS", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "GNOSIS", symbol: "XDAI", address: null }], - logo: "https://api.rango.exchange/blockchains/gnosis.svg", - displayName: "Gnosis", - shortName: "Gnosis", - sort: 26, - color: "#3E6957", - enabled: true, - type: "EVM", - chainId: "0x64", - info: { - chainName: "Gnosis Chain", - nativeCurrency: { name: "XDAI", symbol: "XDAI", decimals: 18 }, - rpcUrls: ["https://rpc.gnosischain.com"], - blockExplorerUrls: ["https://blockscout.com/xdai/mainnet"], - addressUrl: "https://blockscout.com/xdai/mainnet/address/{wallet}", - transactionUrl: "https://blockscout.com/xdai/mainnet/tx/{txHash}", - }, - }, - { - name: "FUSE", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "FUSE", symbol: "FUSE", address: null }], - logo: "https://api.rango.exchange/blockchains/fuse.png", - displayName: "Fuse", - shortName: "Fuse", - sort: 29, - color: "#C5F9AD", - enabled: true, - type: "EVM", - chainId: "0x7a", - info: { - chainName: "Fuse Mainnet", - nativeCurrency: { name: "FUSE", symbol: "FUSE", decimals: 18 }, - rpcUrls: ["https://rpc.fuse.io"], - blockExplorerUrls: ["https://explorer.fuse.io"], - addressUrl: "https://explorer.fuse.io/address/{wallet}", - transactionUrl: "https://explorer.fuse.io/tx/{txHash}", - }, - }, - { - name: "BOBA", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "BOBA", symbol: "ETH", address: null }], - logo: "https://api.rango.exchange/blockchains/boba.png", - displayName: "Boba", - shortName: "Boba", - sort: 39, - color: "#ccff00", - enabled: true, - type: "EVM", - chainId: "0x120", - info: { - chainName: "Boba Network", - nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 }, - rpcUrls: ["https://mainnet.boba.network"], - blockExplorerUrls: ["https://bobascan.com/"], - addressUrl: "https://bobascan.com//address/{wallet}", - transactionUrl: "https://bobascan.com//tx/{txHash}", - }, - }, - ], - coinbase: [ - { - name: "BSC", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "BSC", symbol: "BNB", address: null }], - logo: "https://api.rango.exchange/blockchains/binance.svg", - displayName: "BSC", - shortName: "BSC", - sort: 1, - color: "#F3BA2F", - enabled: true, - type: "EVM", - chainId: "0x38", - info: { - chainName: "Binance Smart Chain Mainnet", - nativeCurrency: { name: "BNB", symbol: "BNB", decimals: 18 }, - rpcUrls: ["https://bsc-dataseed1.ninicoin.io"], - blockExplorerUrls: ["https://bscscan.com"], - addressUrl: "https://bscscan.com/address/{wallet}", - transactionUrl: "https://bscscan.com/tx/{txHash}", - }, - }, - { - name: "POLYGON", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "POLYGON", symbol: "MATIC", address: null }], - logo: "https://api.rango.exchange/blockchains/polygon.svg", - displayName: "Polygon", - shortName: "Polygon", - sort: 2, - color: "#8247E5", - enabled: true, - type: "EVM", - chainId: "0x89", - info: { - chainName: "Polygon Mainnet", - nativeCurrency: { name: "MATIC", symbol: "MATIC", decimals: 18 }, - rpcUrls: ["https://polygon-rpc.com"], - blockExplorerUrls: ["https://polygonscan.com"], - addressUrl: "https://polygonscan.com/address/{wallet}", - transactionUrl: "https://polygonscan.com/tx/{txHash}", - }, - }, - { - name: "ETH", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "ETH", symbol: "ETH", address: null }], - logo: "https://api.rango.exchange/blockchains/ethereum.svg", - displayName: "Ethereum", - shortName: "ETH", - sort: 3, - color: "#ecf0f1", - enabled: true, - type: "EVM", - chainId: "0x1", - info: { - chainName: "Ethereum Mainnet", - nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 }, - rpcUrls: ["https://rpc.ankr.com/eth"], - blockExplorerUrls: ["https://etherscan.io"], - addressUrl: "https://etherscan.io/address/{wallet}", - transactionUrl: "https://etherscan.io/tx/{txHash}", - }, - }, - { - name: "AVAX_CCHAIN", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "AVAX_CCHAIN", symbol: "AVAX", address: null }], - logo: "https://api.rango.exchange/blockchains/avax_cchain.svg", - displayName: "Avalanche", - shortName: "Avax", - sort: 6, - color: "#e84142", - enabled: true, - type: "EVM", - chainId: "0xa86a", - info: { - chainName: "Avalanche C-Chain", - nativeCurrency: { name: "AVAX", symbol: "AVAX", decimals: 18 }, - rpcUrls: ["https://api.avax.network/ext/bc/C/rpc"], - blockExplorerUrls: ["https://snowtrace.io"], - addressUrl: "https://snowtrace.io/address/{wallet}", - transactionUrl: "https://snowtrace.io/tx/{txHash}", - }, - }, - { - name: "ARBITRUM", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "ARBITRUM", symbol: "ETH", address: null }], - logo: "https://api.rango.exchange/blockchains/arbitrum.svg", - displayName: "Arbitrum", - shortName: "Arbitrum", - sort: 7, - color: "#28a0f0", - enabled: true, - type: "EVM", - chainId: "0xa4b1", - info: { - chainName: "Arbitrum One", - nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 }, - rpcUrls: ["https://arb1.arbitrum.io/rpc"], - blockExplorerUrls: ["https://arbiscan.io"], - addressUrl: "https://arbiscan.io/address/{wallet}", - transactionUrl: "https://arbiscan.io/tx/{txHash}", - }, - }, - { - name: "FANTOM", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "FANTOM", symbol: "FTM", address: null }], - logo: "https://api.rango.exchange/blockchains/fantom.png", - displayName: "Fantom", - shortName: "Fantom", - sort: 9, - color: "#337afe", - enabled: true, - type: "EVM", - chainId: "0xfa", - info: { - chainName: "Fantom Opera", - nativeCurrency: { name: "FTM", symbol: "FTM", decimals: 18 }, - rpcUrls: ["https://rpc.ftm.tools"], - blockExplorerUrls: ["https://ftmscan.com"], - addressUrl: "https://ftmscan.com/address/{wallet}", - transactionUrl: "https://ftmscan.com/tx/{txHash}", - }, - }, - { - name: "OPTIMISM", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "OPTIMISM", symbol: "ETH", address: null }], - logo: "https://api.rango.exchange/blockchains/optimism.svg", - displayName: "Optimism", - shortName: "Optimism", - sort: 10, - color: "#FF0420", - enabled: true, - type: "EVM", - chainId: "0xa", - info: { - chainName: "Optimism", - nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 }, - rpcUrls: ["https://mainnet.optimism.io"], - blockExplorerUrls: ["https://optimistic.etherscan.io"], - addressUrl: "https://optimistic.etherscan.io/address/{wallet}", - transactionUrl: "https://optimistic.etherscan.io/tx/{txHash}", - }, - }, - { - name: "OKC", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "OKC", symbol: "OKT", address: null }], - logo: "https://api.rango.exchange/blockchains/okx.png", - displayName: "OKX Chain (OKC)", - shortName: "Okx", - sort: 11, - color: "#29a0f0", - enabled: true, - type: "EVM", - chainId: "0x42", - info: { - chainName: "OKX Chain", - nativeCurrency: { name: "OKT", symbol: "OKT", decimals: 18 }, - rpcUrls: ["https://exchainrpc.okex.org"], - blockExplorerUrls: ["https://www.oklink.com/en/okc"], - addressUrl: "https://www.oklink.com/en/okc/address/{wallet}", - transactionUrl: "https://www.oklink.com/en/okc/tx/{txHash}", - }, - }, - { - name: "CRONOS", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "CRONOS", symbol: "CRO", address: null }], - logo: "https://api.rango.exchange/blockchains/cronos.svg", - displayName: "Cronos", - shortName: "Cronos", - sort: 12, - color: "#1a90ff", - enabled: true, - type: "EVM", - chainId: "0x19", - info: { - chainName: "Cronos Mainnet Beta", - nativeCurrency: { name: "CRO", symbol: "CRO", decimals: 18 }, - rpcUrls: ["https://cronosrpc-1.xstaking.sg"], - blockExplorerUrls: ["https://cronoscan.com"], - addressUrl: "https://cronoscan.com/address/{wallet}", - transactionUrl: "https://cronoscan.com/tx/{txHash}", - }, - }, - { - name: "MOONRIVER", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "MOONRIVER", symbol: "MOVR", address: null }], - logo: "https://api.rango.exchange/blockchains/moonriver.svg", - displayName: "MoonRiver", - shortName: "MoonRiver", - sort: 13, - color: "#F3B404", - enabled: true, - type: "EVM", - chainId: "0x505", - info: { - chainName: "MoonRiver", - nativeCurrency: { name: "MOVR", symbol: "MOVR", decimals: 18 }, - rpcUrls: ["https://rpc.moonriver.moonbeam.network"], - blockExplorerUrls: ["https://moonriver.moonscan.io"], - addressUrl: "https://moonriver.moonscan.io/address/{wallet}", - transactionUrl: "https://moonriver.moonscan.io/tx/{txHash}", - }, - }, - { - name: "MOONBEAM", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "MOONBEAM", symbol: "GLMR", address: null }], - logo: "https://api.rango.exchange/blockchains/moonbeam.png", - displayName: "MoonBeam", - shortName: "MoonBeam", - sort: 14, - color: "#B3206B", - enabled: true, - type: "EVM", - chainId: "0x504", - info: { - chainName: "MoonBeam", - nativeCurrency: { name: "GLMR", symbol: "GLMR", decimals: 18 }, - rpcUrls: ["https://rpc.api.moonbeam.network"], - blockExplorerUrls: ["https://moonbeam.moonscan.io"], - addressUrl: "https://moonbeam.moonscan.io/address/{wallet}", - transactionUrl: "https://moonbeam.moonscan.io/tx/{txHash}", - }, - }, - { - name: "HECO", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "HECO", symbol: "HT", address: null }], - logo: "https://api.rango.exchange/blockchains/heco.png", - displayName: "Heco", - shortName: "Heco", - sort: 15, - color: "#4CA852", - enabled: true, - type: "EVM", - chainId: "0x80", - info: { - chainName: "Huobi ECO Chain Mainnet", - nativeCurrency: { name: "HT", symbol: "HT", decimals: 18 }, - rpcUrls: ["https://http-mainnet.hecochain.com"], - blockExplorerUrls: ["https://hecoinfo.com"], - addressUrl: "https://hecoinfo.com/address/{wallet}", - transactionUrl: "https://hecoinfo.com/tx/{txHash}", - }, - }, - { - name: "AURORA", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "AURORA", symbol: "ETH", address: null }], - logo: "https://api.rango.exchange/blockchains/aurora.svg", - displayName: "Aurora", - shortName: "Aurora", - sort: 15, - color: "#78d64b", - enabled: true, - type: "EVM", - chainId: "0x4e454152", - info: { - chainName: "Aurora Mainnet", - nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 }, - rpcUrls: ["https://mainnet.aurora.dev"], - blockExplorerUrls: ["https://explorer.mainnet.aurora.dev"], - addressUrl: "https://explorer.mainnet.aurora.dev/address/{wallet}", - transactionUrl: "https://explorer.mainnet.aurora.dev/tx/{txHash}", - }, - }, - { - name: "HARMONY", - defaultDecimals: 18, - addressPatterns: ["^(one1)[0-9a-z]{38}$", "^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "HARMONY", symbol: "ONE", address: null }], - logo: "https://api.rango.exchange/blockchains/harmony.svg", - displayName: "Harmony", - shortName: "Harmony", - sort: 15, - color: "#50AEE9", - enabled: true, - type: "EVM", - chainId: "0x63564c40", - info: { - chainName: "Harmony Mainnet", - nativeCurrency: { name: "ONE", symbol: "ONE", decimals: 18 }, - rpcUrls: ["https://api.s0.t.hmny.io"], - blockExplorerUrls: ["https://explorer.harmony.one"], - addressUrl: "https://explorer.harmony.one/address/{wallet}", - transactionUrl: "https://explorer.harmony.one/tx/{txHash}", - }, - }, - { - name: "EVMOS", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "EVMOS", symbol: "EVMOS", address: null }], - logo: "https://api.rango.exchange/blockchains/evmos.png", - displayName: "Evmos", - shortName: "Evmos", - sort: 15, - color: "#2D2925", - enabled: true, - type: "EVM", - chainId: "0x2329", - info: { - chainName: "Evmos", - nativeCurrency: { name: "EVMOS", symbol: "EVMOS", decimals: 18 }, - rpcUrls: ["https://eth.bd.evmos.org:8545"], - blockExplorerUrls: ["https://evm.evmos.org"], - addressUrl: "https://evm.evmos.org/address/{wallet}", - transactionUrl: "https://evm.evmos.org/tx/{txHash}", - }, - }, - { - name: "GNOSIS", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "GNOSIS", symbol: "XDAI", address: null }], - logo: "https://api.rango.exchange/blockchains/gnosis.svg", - displayName: "Gnosis", - shortName: "Gnosis", - sort: 26, - color: "#3E6957", - enabled: true, - type: "EVM", - chainId: "0x64", - info: { - chainName: "Gnosis Chain", - nativeCurrency: { name: "XDAI", symbol: "XDAI", decimals: 18 }, - rpcUrls: ["https://rpc.gnosischain.com"], - blockExplorerUrls: ["https://blockscout.com/xdai/mainnet"], - addressUrl: "https://blockscout.com/xdai/mainnet/address/{wallet}", - transactionUrl: "https://blockscout.com/xdai/mainnet/tx/{txHash}", - }, - }, - { - name: "FUSE", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "FUSE", symbol: "FUSE", address: null }], - logo: "https://api.rango.exchange/blockchains/fuse.png", - displayName: "Fuse", - shortName: "Fuse", - sort: 29, - color: "#C5F9AD", - enabled: true, - type: "EVM", - chainId: "0x7a", - info: { - chainName: "Fuse Mainnet", - nativeCurrency: { name: "FUSE", symbol: "FUSE", decimals: 18 }, - rpcUrls: ["https://rpc.fuse.io"], - blockExplorerUrls: ["https://explorer.fuse.io"], - addressUrl: "https://explorer.fuse.io/address/{wallet}", - transactionUrl: "https://explorer.fuse.io/tx/{txHash}", - }, - }, - { - name: "BOBA", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "BOBA", symbol: "ETH", address: null }], - logo: "https://api.rango.exchange/blockchains/boba.png", - displayName: "Boba", - shortName: "Boba", - sort: 39, - color: "#ccff00", - enabled: true, - type: "EVM", - chainId: "0x120", - info: { - chainName: "Boba Network", - nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 }, - rpcUrls: ["https://mainnet.boba.network"], - blockExplorerUrls: ["https://bobascan.com/"], - addressUrl: "https://bobascan.com//address/{wallet}", - transactionUrl: "https://bobascan.com//tx/{txHash}", - }, - }, - { - name: "SOLANA", - defaultDecimals: 9, - addressPatterns: ["^[1-9A-HJ-NP-Za-km-z]{32,44}$"], - feeAssets: [{ blockchain: "SOLANA", symbol: "SOL", address: null }], - logo: "https://api.rango.exchange/blockchains/solana.svg", - displayName: "Solana", - shortName: "Solana", - sort: 11, - color: "#708DD2", - enabled: true, - type: "SOLANA", - chainId: "mainnet-beta", - info: null, - }, - ], - keplr: [ - { - name: "OSMOSIS", - defaultDecimals: 6, - addressPatterns: ["^(osmo1)[0-9a-z]{38}$"], - feeAssets: [{ blockchain: "OSMOSIS", symbol: "OSMO", address: null }], - logo: "https://api.rango.exchange/blockchains/osmosis.svg", - displayName: "Osmosis", - shortName: "Osmosis", - sort: 4, - color: "#7901B4", - enabled: true, - type: "COSMOS", - chainId: "osmosis-1", - info: { - experimental: false, - rpc: "https://rpc-osmosis.keplr.app", - rest: "https://lcd-osmosis.keplr.app", - cosmostationLcdUrl: "https://lcd-osmosis.cosmostation.io", - cosmostationApiUrl: "https://api-osmosis.cosmostation.io", - cosmostationDenomTracePath: "/ibc/apps/transfer/v1/denom_traces/", - mintScanName: "osmosis", - chainName: "Osmosis", - stakeCurrency: { - coinDenom: "OSMO", - coinMinimalDenom: "uosmo", - coinDecimals: 6, - coinGeckoId: "pool:uosmo", - coinImageUrl: "/tokens/blockchain/osmosis.svg", - }, - bip44: { coinType: 118 }, - bech32Config: { - bech32PrefixAccAddr: "osmo", - bech32PrefixAccPub: "osmopub", - bech32PrefixValAddr: "osmovaloper", - bech32PrefixValPub: "osmovaloperpub", - bech32PrefixConsAddr: "osmovalcons", - bech32PrefixConsPub: "osmovalconspub", - }, - currencies: [ - { - coinDenom: "OSMO", - coinMinimalDenom: "uosmo", - coinDecimals: 6, - coinGeckoId: "pool:uosmo", - coinImageUrl: "/tokens/blockchain/osmosis.svg", - }, - { - coinDenom: "ION", - coinMinimalDenom: "uion", - coinDecimals: 6, - coinGeckoId: "pool:uion", - coinImageUrl: "/tokens/blockchain/ion.png", - }, - ], - feeCurrencies: [ - { - coinDenom: "OSMO", - coinMinimalDenom: "uosmo", - coinDecimals: 6, - coinGeckoId: "pool:uosmo", - coinImageUrl: "/tokens/blockchain/osmosis.svg", - }, - ], - features: ["stargate", "ibc-transfer"], - explorerUrlToTx: "https://www.mintscan.io/osmosis/txs/{txHash}", - gasPriceStep: { low: 0, average: 0.025, high: 0.04 }, - }, - }, - { - name: "JUNO", - defaultDecimals: 6, - addressPatterns: ["^(juno1)[0-9a-z]{38}$"], - feeAssets: [{ blockchain: "JUNO", symbol: "JUNO", address: null }], - logo: "https://api.rango.exchange/blockchains/juno.svg", - displayName: "Juno", - shortName: "Juno", - sort: 5, - color: "#f0827d", - enabled: true, - type: "COSMOS", - chainId: "juno-1", - info: { - experimental: false, - rpc: "https://rpc-juno.itastakers.com:443/", - rest: "https://lcd-juno.keplr.app", - cosmostationLcdUrl: "https://lcd-juno.cosmostation.io", - cosmostationApiUrl: "https://api-juno.cosmostation.io", - cosmostationDenomTracePath: "/ibc/apps/transfer/v1/denom_traces/", - mintScanName: "juno", - chainName: "Juno", - stakeCurrency: { - coinDenom: "JUNO", - coinMinimalDenom: "ujuno", - coinDecimals: 6, - coinGeckoId: "juno-network", - coinImageUrl: "/tokens/blockchain/JUNO.png", - }, - bip44: { coinType: 118 }, - bech32Config: { - bech32PrefixAccAddr: "juno", - bech32PrefixAccPub: "junopub", - bech32PrefixValAddr: "junovaloper", - bech32PrefixValPub: "junovaloperpub", - bech32PrefixConsAddr: "junovalcons", - bech32PrefixConsPub: "junovalconspub", - }, - currencies: [ - { - coinDenom: "JUNO", - coinMinimalDenom: "ujuno", - coinDecimals: 6, - coinGeckoId: "juno-network", - coinImageUrl: "/tokens/blockchain/JUNO.png", - }, - ], - feeCurrencies: [ - { - coinDenom: "JUNO", - coinMinimalDenom: "ujuno", - coinDecimals: 6, - coinGeckoId: "juno-network", - coinImageUrl: "/tokens/blockchain/JUNO.png", - }, - ], - features: ["stargate", "ibc-transfer"], - explorerUrlToTx: "https://www.mintscan.io/juno/txs/{txHash}", - gasPriceStep: { low: 0.001, average: 0.0025, high: 0.004 }, - }, - }, - { - name: "COSMOS", - defaultDecimals: 6, - addressPatterns: ["^(cosmos1)[0-9a-z]{38}$"], - feeAssets: [{ blockchain: "COSMOS", symbol: "ATOM", address: null }], - logo: "https://api.rango.exchange/blockchains/cosmos.svg", - displayName: "Cosmos", - shortName: "Cosmos", - sort: 8, - color: "#2E3148", - enabled: true, - type: "COSMOS", - chainId: "cosmoshub-4", - info: { - experimental: false, - rpc: "https://cosmos-rpc.polkachu.com", - rest: "https://lcd-cosmoshub.keplr.app", - cosmostationLcdUrl: "https://lcd-cosmos.cosmostation.io", - cosmostationApiUrl: "https://api-cosmos.cosmostation.io", - cosmostationDenomTracePath: "/ibc/apps/transfer/v1/denom_traces/", - mintScanName: "cosmos", - chainName: "Cosmos", - stakeCurrency: { - coinDenom: "ATOM", - coinMinimalDenom: "uatom", - coinDecimals: 6, - coinGeckoId: "cosmos", - coinImageUrl: "/tokens/blockchain/cosmos.svg", - }, - bip44: { coinType: 118 }, - bech32Config: { - bech32PrefixAccAddr: "cosmos", - bech32PrefixAccPub: "cosmospub", - bech32PrefixValAddr: "cosmosvaloper", - bech32PrefixValPub: "cosmosvaloperpub", - bech32PrefixConsAddr: "cosmosvalcons", - bech32PrefixConsPub: "cosmosvalconspub", - }, - currencies: [ - { - coinDenom: "ATOM", - coinMinimalDenom: "uatom", - coinDecimals: 6, - coinGeckoId: "cosmos", - coinImageUrl: "/tokens/blockchain/cosmos.svg", - }, - ], - feeCurrencies: [ - { - coinDenom: "ATOM", - coinMinimalDenom: "uatom", - coinDecimals: 6, - coinGeckoId: "cosmos", - coinImageUrl: "/tokens/blockchain/cosmos.svg", - }, - ], - features: ["stargate", "ibc-transfer"], - explorerUrlToTx: "https://www.mintscan.io/cosmos/txs/{txHash}", - gasPriceStep: { low: 0.01, average: 0.025, high: 0.04 }, - }, - }, - { - name: "SIF", - defaultDecimals: 18, - addressPatterns: ["^(sif1)[0-9a-z]{38}$"], - feeAssets: [{ blockchain: "SIF", symbol: "ROWAN", address: null }], - logo: "https://api.rango.exchange/blockchains/sif.png", - displayName: "Sifchain", - shortName: "Sifchain", - sort: 16, - color: "#CAAA3A", - enabled: true, - type: "COSMOS", - chainId: "sifchain-1", - info: { - experimental: false, - rpc: "https://rpc.sifchain.finance", - rest: "https://api-int.sifchain.finance", - cosmostationLcdUrl: "https://lcd-sifchain.cosmostation.io", - cosmostationApiUrl: "https://api-sifchain.cosmostation.io", - cosmostationDenomTracePath: "/ibc/apps/transfer/v1/denom_traces/", - mintScanName: "sifchain", - chainName: "Sifchain", - stakeCurrency: { - coinDenom: "ROWAN", - coinMinimalDenom: "rowan", - coinDecimals: 18, - coinGeckoId: "", - coinImageUrl: "", - }, - bip44: { coinType: 118 }, - bech32Config: { - bech32PrefixAccAddr: "sif", - bech32PrefixAccPub: "sifpub", - bech32PrefixValAddr: "sifvaloper", - bech32PrefixValPub: "sifvaloperpub", - bech32PrefixConsAddr: "sifvalcons", - bech32PrefixConsPub: "sifvalconspub", - }, - currencies: [ - { - coinDenom: "ROWAN", - coinMinimalDenom: "rowan", - coinDecimals: 18, - coinGeckoId: "", - coinImageUrl: "", - }, - ], - feeCurrencies: [ - { - coinDenom: "ROWAN", - coinMinimalDenom: "rowan", - coinDecimals: 18, - coinGeckoId: "", - coinImageUrl: "", - }, - ], - features: ["stargate", "ibc-transfer"], - explorerUrlToTx: "https://www.mintscan.io/sifchain/txs/{txHash}", - gasPriceStep: { - low: 1000000000000, - average: 1500000000000, - high: 2000000000000, - }, - }, - }, - { - name: "STARGAZE", - defaultDecimals: 6, - addressPatterns: ["^(stars1)[0-9a-z]{38}$"], - feeAssets: [{ blockchain: "STARGAZE", symbol: "STARS", address: null }], - logo: "https://api.rango.exchange/blockchains/stargaze.png", - displayName: "Stargaze", - shortName: "Stargaze", - sort: 19, - color: "#231B60", - enabled: true, - type: "COSMOS", - chainId: "stargaze-1", - info: { - experimental: false, - rpc: "https://rpc.stargaze-apis.com", - rest: "https://rest.stargaze-apis.com", - cosmostationLcdUrl: "https://lcd-stargaze.cosmostation.io", - cosmostationApiUrl: "https://api-stargaze.cosmostation.io", - cosmostationDenomTracePath: "/ibc/apps/transfer/v1/denom_traces/", - mintScanName: "stargaze", - chainName: "Stargaze", - stakeCurrency: { - coinDenom: "STARS", - coinMinimalDenom: "ustars", - coinDecimals: 6, - coinGeckoId: "pool:ustars", - coinImageUrl: "/tokens/blockchain/STARS.png", - }, - bip44: { coinType: 118 }, - bech32Config: { - bech32PrefixAccAddr: "stars", - bech32PrefixAccPub: "starspub", - bech32PrefixValAddr: "starsvaloper", - bech32PrefixValPub: "starsvaloperpub", - bech32PrefixConsAddr: "starsvalcons", - bech32PrefixConsPub: "starsvalconspub", - }, - currencies: [ - { - coinDenom: "STARS", - coinMinimalDenom: "ustars", - coinDecimals: 6, - coinGeckoId: "pool:ustars", - coinImageUrl: "/tokens/blockchain/STARS.png", - }, - ], - feeCurrencies: [ - { - coinDenom: "STARS", - coinMinimalDenom: "ustars", - coinDecimals: 6, - coinGeckoId: "pool:ustars", - coinImageUrl: "/tokens/blockchain/STARS.png", - }, - ], - features: ["stargate", "ibc-transfer", "no-legacy-stdTx"], - explorerUrlToTx: "https://www.mintscan.io/stargaze/txs/{txHash}", - gasPriceStep: { low: 1, average: 1, high: 1 }, - }, - }, - { - name: "CRYPTO_ORG", - defaultDecimals: 8, - addressPatterns: ["^(cro1)[0-9a-z]{38}$"], - feeAssets: [{ blockchain: "CRYPTO_ORG", symbol: "CRO", address: null }], - logo: "https://api.rango.exchange/blockchains/crypto_org.png", - displayName: "Crypto.org", - shortName: "Crypto.org", - sort: 21, - color: "#103F68", - enabled: true, - type: "COSMOS", - chainId: "crypto-org-chain-mainnet-1", - info: { - experimental: false, - rpc: "https://rpc-crypto-org.keplr.app", - rest: "https://lcd-crypto-org.keplr.app", - cosmostationLcdUrl: "https://lcd-cryptocom.cosmostation.io", - cosmostationApiUrl: "https://api-cryptocom.cosmostation.io", - cosmostationDenomTracePath: "/ibc/apps/transfer/v1/denom_traces/", - mintScanName: "crypto-org", - chainName: "Crypto.org", - stakeCurrency: { - coinDenom: "CRO", - coinMinimalDenom: "basecro", - coinDecimals: 8, - coinGeckoId: "crypto-com-chain", - coinImageUrl: "/tokens/blockchain/cro.png", - }, - bip44: { coinType: 394 }, - bech32Config: { - bech32PrefixAccAddr: "cro", - bech32PrefixAccPub: "cropub", - bech32PrefixValAddr: "crovaloper", - bech32PrefixValPub: "crovaloperpub", - bech32PrefixConsAddr: "crovalcons", - bech32PrefixConsPub: "crovalconspub", - }, - currencies: [ - { - coinDenom: "CRO", - coinMinimalDenom: "basecro", - coinDecimals: 8, - coinGeckoId: "crypto-com-chain", - coinImageUrl: "/tokens/blockchain/cro.png", - }, - ], - feeCurrencies: [ - { - coinDenom: "CRO", - coinMinimalDenom: "basecro", - coinDecimals: 8, - coinGeckoId: "crypto-com-chain", - coinImageUrl: "/tokens/blockchain/cro.png", - }, - ], - features: ["stargate", "ibc-transfer"], - explorerUrlToTx: "https://www.mintscan.io/crypto-org/txs/{txHash}", - gasPriceStep: { low: 0.025, average: 0.03, high: 0.04 }, - }, - }, - { - name: "CHIHUAHUA", - defaultDecimals: 6, - addressPatterns: ["^(chihuahua1)[0-9a-z]{38}$"], - feeAssets: [{ blockchain: "CHIHUAHUA", symbol: "HUAHUA", address: null }], - logo: "https://api.rango.exchange/blockchains/chihuahua.png", - displayName: "Chihuahua", - shortName: "Chihuahua", - sort: 22, - color: "#EFC92B", - enabled: true, - type: "COSMOS", - chainId: "chihuahua-1", - info: { - experimental: true, - rpc: "https://rpc.chihuahua.wtf/", - rest: "https://api.chihuahua.wtf/", - cosmostationLcdUrl: "https://lcd-chihuahua.cosmostation.io", - cosmostationApiUrl: "https://api-chihuahua.cosmostation.io", - cosmostationDenomTracePath: "/ibc/apps/transfer/v1/denom_traces/", - mintScanName: "chihuahua", - chainName: "Chihuahua", - stakeCurrency: { - coinDenom: "HUAHUA", - coinMinimalDenom: "uhuahua", - coinDecimals: 6, - coinGeckoId: "pool:uhuahua", - coinImageUrl: "/tokens/blockchain/HUAHUA.svg", - }, - bip44: { coinType: 118 }, - bech32Config: { - bech32PrefixAccAddr: "chihuahua", - bech32PrefixAccPub: "chihuahuapub", - bech32PrefixValAddr: "chihuahuavaloper", - bech32PrefixValPub: "chihuahuavaloperpub", - bech32PrefixConsAddr: "chihuahuavalcons", - bech32PrefixConsPub: "chihuahuavalconspub", - }, - currencies: [ - { - coinDenom: "HUAHUA", - coinMinimalDenom: "uhuahua", - coinDecimals: 6, - coinGeckoId: "pool:uhuahua", - coinImageUrl: "/tokens/blockchain/HUAHUA.svg", - }, - ], - feeCurrencies: [ - { - coinDenom: "HUAHUA", - coinMinimalDenom: "uhuahua", - coinDecimals: 6, - coinGeckoId: "pool:uhuahua", - coinImageUrl: "/tokens/blockchain/HUAHUA.svg", - }, - ], - features: ["stargate", "ibc-transfer", "no-legacy-stdTx"], - explorerUrlToTx: "https://ping.pub/chihuahua/tx/{txHash}", - gasPriceStep: { low: 0.025, average: 0.03, high: 0.035 }, - }, - }, - { - name: "BANDCHAIN", - defaultDecimals: 6, - addressPatterns: ["^(band1)[0-9a-z]{38}$"], - feeAssets: [{ blockchain: "BANDCHAIN", symbol: "BAND", address: null }], - logo: "https://api.rango.exchange/blockchains/bandchain.svg", - displayName: "BandChain", - shortName: "BandChain", - sort: 23, - color: "#4520E6", - enabled: true, - type: "COSMOS", - chainId: "laozi-mainnet", - info: { - experimental: true, - rpc: "https://rpc.laozi3.bandchain.org/", - rest: "https://lcd-band.cosmostation.io", - cosmostationLcdUrl: "https://lcd-band.cosmostation.io", - cosmostationApiUrl: "https://api-band.cosmostation.io", - cosmostationDenomTracePath: "/ibc/apps/transfer/v1/denom_traces/", - mintScanName: "band", - chainName: "BandChain", - stakeCurrency: { - coinDenom: "BAND", - coinMinimalDenom: "uband", - coinDecimals: 6, - coinGeckoId: "band-protocol", - coinImageUrl: "/tokens/blockchain/BAND.svg", - }, - bip44: { coinType: 494 }, - bech32Config: { - bech32PrefixAccAddr: "band", - bech32PrefixAccPub: "bandpub", - bech32PrefixValAddr: "bandvaloper", - bech32PrefixValPub: "bandvaloperpub", - bech32PrefixConsAddr: "bandvalcons", - bech32PrefixConsPub: "bandvalconspub", - }, - currencies: [ - { - coinDenom: "BAND", - coinMinimalDenom: "uband", - coinDecimals: 6, - coinGeckoId: "band-protocol", - coinImageUrl: "/tokens/blockchain/BAND.svg", - }, - ], - feeCurrencies: [ - { - coinDenom: "BAND", - coinMinimalDenom: "uband", - coinDecimals: 6, - coinGeckoId: "band-protocol", - coinImageUrl: "/tokens/blockchain/BAND.svg", - }, - ], - features: ["stargate", "ibc-transfer", "no-legacy-stdTx"], - explorerUrlToTx: "https://cosmoscan.io/tx/{txHash}", - gasPriceStep: null, - }, - }, - { - name: "COMDEX", - defaultDecimals: 6, - addressPatterns: ["^(comdex1)[0-9a-z]{38}$"], - feeAssets: [{ blockchain: "COMDEX", symbol: "CMDX", address: null }], - logo: "https://api.rango.exchange/blockchains/comdex.svg", - displayName: "Comdex", - shortName: "Comdex", - sort: 23, - color: "#FE4350", - enabled: true, - type: "COSMOS", - chainId: "comdex-1", - info: { - experimental: true, - rpc: "https://rpc.comdex.one", - rest: "https://rest.comdex.one", - cosmostationLcdUrl: "https://lcd-comdex.cosmostation.io", - cosmostationApiUrl: "https://api-comdex.cosmostation.io", - cosmostationDenomTracePath: "/ibc/apps/transfer/v1/denom_traces/", - mintScanName: "comdex", - chainName: "Comdex", - stakeCurrency: { - coinDenom: "CMDX", - coinMinimalDenom: "ucmdx", - coinDecimals: 6, - coinGeckoId: "comdex", - coinImageUrl: "/tokens/blockchain/CMDX.png", - }, - bip44: { coinType: 118 }, - bech32Config: { - bech32PrefixAccAddr: "comdex", - bech32PrefixAccPub: "comdexpub", - bech32PrefixValAddr: "comdexvaloper", - bech32PrefixValPub: "comdexvaloperpub", - bech32PrefixConsAddr: "comdexvalcons", - bech32PrefixConsPub: "comdexvalconspub", - }, - currencies: [ - { - coinDenom: "CMDX", - coinMinimalDenom: "ucmdx", - coinDecimals: 6, - coinGeckoId: "comdex", - coinImageUrl: "/tokens/blockchain/CMDX.png", - }, - ], - feeCurrencies: [ - { - coinDenom: "CMDX", - coinMinimalDenom: "ucmdx", - coinDecimals: 6, - coinGeckoId: "comdex", - coinImageUrl: "/tokens/blockchain/CMDX.png", - }, - ], - features: ["stargate", "ibc-transfer", "no-legacy-stdTx"], - explorerUrlToTx: "https://www.mintscan.io/comdex/txs/{txHash}", - gasPriceStep: null, - }, - }, - { - name: "REGEN", - defaultDecimals: 6, - addressPatterns: ["^(regen1)[0-9a-z]{38}$"], - feeAssets: [{ blockchain: "REGEN", symbol: "REGEN", address: null }], - logo: "https://api.rango.exchange/blockchains/regen.png", - displayName: "Regen Network", - shortName: "Regen Network", - sort: 24, - color: "#4FB573", - enabled: true, - type: "COSMOS", - chainId: "regen-1", - info: { - experimental: false, - rpc: "https://rpc-regen.keplr.app", - rest: "https://lcd-regen.keplr.app", - cosmostationLcdUrl: "https://lcd-regen.keplr.app", - cosmostationApiUrl: "https://api-regen.cosmostation.io/", - cosmostationDenomTracePath: "/ibc/apps/transfer/v1/denom_traces/", - mintScanName: "regen", - chainName: "Regen Network", - stakeCurrency: { - coinDenom: "REGEN", - coinMinimalDenom: "uregen", - coinDecimals: 6, - coinGeckoId: "pool:uregen", - coinImageUrl: "/tokens/blockchain/regen.png", - }, - bip44: { coinType: 118 }, - bech32Config: { - bech32PrefixAccAddr: "regen", - bech32PrefixAccPub: "regenpub", - bech32PrefixValAddr: "regenvaloper", - bech32PrefixValPub: "regenvaloperpub", - bech32PrefixConsAddr: "regenvalcons", - bech32PrefixConsPub: "regenvalconspub", - }, - currencies: [ - { - coinDenom: "REGEN", - coinMinimalDenom: "uregen", - coinDecimals: 6, - coinGeckoId: "pool:uregen", - coinImageUrl: "/tokens/blockchain/regen.png", - }, - ], - feeCurrencies: [ - { - coinDenom: "REGEN", - coinMinimalDenom: "uregen", - coinDecimals: 6, - coinGeckoId: "pool:uregen", - coinImageUrl: "/tokens/blockchain/regen.png", - }, - ], - features: ["stargate", "ibc-transfer"], - explorerUrlToTx: "https://regen.aneka.io/txs/{txHash}", - gasPriceStep: { low: 0.015, average: 0.025, high: 0.04 }, - }, - }, - { - name: "IRIS", - defaultDecimals: 6, - addressPatterns: ["^(iaa1)[0-9a-z]{38}$"], - feeAssets: [{ blockchain: "IRIS", symbol: "IRIS", address: null }], - logo: "https://api.rango.exchange/blockchains/iris.png", - displayName: "IRISnet", - shortName: "IRISnet", - sort: 25, - color: "#8A4A8E", - enabled: true, - type: "COSMOS", - chainId: "irishub-1", - info: { - experimental: false, - rpc: "https://rpc-iris.keplr.app", - rest: "https://lcd-iris.keplr.app", - cosmostationLcdUrl: "https://lcd-iris.cosmostation.io", - cosmostationApiUrl: "https://api-iris.cosmostation.io", - cosmostationDenomTracePath: "/ibc/apps/transfer/v1/denom_traces/", - mintScanName: "iris", - chainName: "IRISnet", - stakeCurrency: { - coinDenom: "IRIS", - coinMinimalDenom: "uiris", - coinDecimals: 6, - coinGeckoId: "iris-network", - coinImageUrl: "/tokens/blockchain/iris.svg", - }, - bip44: { coinType: 118 }, - bech32Config: { - bech32PrefixAccAddr: "iaa", - bech32PrefixAccPub: "iaapub", - bech32PrefixValAddr: "iaavaloper", - bech32PrefixValPub: "iaavaloperpub", - bech32PrefixConsAddr: "iaavalcons", - bech32PrefixConsPub: "iaavalconspub", - }, - currencies: [ - { - coinDenom: "IRIS", - coinMinimalDenom: "uiris", - coinDecimals: 6, - coinGeckoId: "iris-network", - coinImageUrl: "/tokens/blockchain/iris.svg", - }, - ], - feeCurrencies: [ - { - coinDenom: "IRIS", - coinMinimalDenom: "uiris", - coinDecimals: 6, - coinGeckoId: "iris-network", - coinImageUrl: "/tokens/blockchain/iris.svg", - }, - ], - features: ["stargate", "ibc-transfer"], - explorerUrlToTx: "https://www.mintscan.io/iris/txs/{txHash}", - gasPriceStep: { low: 0.2, average: 0.3, high: 0.4 }, - }, - }, - { - name: "EMONEY", - defaultDecimals: 6, - addressPatterns: ["^(emoney1)[0-9a-z]{38}$"], - feeAssets: [{ blockchain: "EMONEY", symbol: "NGM", address: null }], - logo: "https://api.rango.exchange/blockchains/emoney.svg", - displayName: "e-Money", - shortName: "e-Money", - sort: 25, - color: "#DFF5EF", - enabled: true, - type: "COSMOS", - chainId: "emoney-3", - info: { - experimental: true, - rpc: "https://rpc-emoney.keplr.app", - rest: "https://lcd-emoney.keplr.app", - cosmostationLcdUrl: "https://lcd-emoney.cosmostation.io", - cosmostationApiUrl: "https://api-emoney.cosmostation.io", - cosmostationDenomTracePath: - "/ibc/applications/transfer/v1beta1/denom_traces/", - mintScanName: "emoney", - chainName: "e-Money", - stakeCurrency: { - coinDenom: "NGM", - coinMinimalDenom: "ungm", - coinDecimals: 6, - coinGeckoId: "e-money", - coinImageUrl: "/tokens/blockchain/NGM.png", - }, - bip44: { coinType: 118 }, - bech32Config: { - bech32PrefixAccAddr: "emoney", - bech32PrefixAccPub: "emoneypub", - bech32PrefixValAddr: "emoneyvaloper", - bech32PrefixValPub: "emoneyvaloperpub", - bech32PrefixConsAddr: "emoneyvalcons", - bech32PrefixConsPub: "emoneyvalconspub", - }, - currencies: [ - { - coinDenom: "NGM", - coinMinimalDenom: "ungm", - coinDecimals: 6, - coinGeckoId: "e-money", - coinImageUrl: "/tokens/blockchain/NGM.png", - }, - { - coinDenom: "EEUR", - coinMinimalDenom: "eeur", - coinDecimals: 6, - coinGeckoId: "e-money-eur", - coinImageUrl: "/tokens/blockchain/EEUR.png", - }, - ], - feeCurrencies: [ - { - coinDenom: "NGM", - coinMinimalDenom: "ungm", - coinDecimals: 6, - coinGeckoId: "e-money", - coinImageUrl: "/tokens/blockchain/NGM.png", - }, - ], - features: ["stargate", "ibc-transfer"], - explorerUrlToTx: "https://emoney.bigdipper.live/transactions/{txHash}", - gasPriceStep: { low: 1, average: 1, high: 1 }, - }, - }, - { - name: "AKASH", - defaultDecimals: 6, - addressPatterns: ["^(akash1)[0-9a-z]{38}$"], - feeAssets: [{ blockchain: "AKASH", symbol: "AKT", address: null }], - logo: "https://api.rango.exchange/blockchains/akash.svg", - displayName: "Akash", - shortName: "Akash", - sort: 30, - color: "#ED3524", - enabled: true, - type: "COSMOS", - chainId: "akashnet-2", - info: { - experimental: false, - rpc: "https://rpc-akash.keplr.app", - rest: "https://lcd-akash.keplr.app", - cosmostationLcdUrl: "https://lcd-akash.cosmostation.io", - cosmostationApiUrl: "https://api-akash.cosmostation.io", - cosmostationDenomTracePath: "/ibc/apps/transfer/v1/denom_traces/", - mintScanName: "akash", - chainName: "Akash", - stakeCurrency: { - coinDenom: "AKT", - coinMinimalDenom: "uakt", - coinDecimals: 6, - coinGeckoId: "akash-network", - coinImageUrl: "/tokens/blockchain/akt.svg", - }, - bip44: { coinType: 118 }, - bech32Config: { - bech32PrefixAccAddr: "akash", - bech32PrefixAccPub: "akashpub", - bech32PrefixValAddr: "akashvaloper", - bech32PrefixValPub: "akashvaloperpub", - bech32PrefixConsAddr: "akashvalcons", - bech32PrefixConsPub: "akashvalconspub", - }, - currencies: [ - { - coinDenom: "AKT", - coinMinimalDenom: "uakt", - coinDecimals: 6, - coinGeckoId: "akash-network", - coinImageUrl: "/tokens/blockchain/akt.svg", - }, - ], - feeCurrencies: [ - { - coinDenom: "AKT", - coinMinimalDenom: "uakt", - coinDecimals: 6, - coinGeckoId: "akash-network", - coinImageUrl: "/tokens/blockchain/akt.svg", - }, - ], - features: ["stargate", "ibc-transfer"], - explorerUrlToTx: "https://www.mintscan.io/akash/txs/{txHash}", - gasPriceStep: { low: 0.001, average: 0.0025, high: 0.004 }, - }, - }, - { - name: "KI", - defaultDecimals: 6, - addressPatterns: ["^(ki1)[0-9a-z]{38}$"], - feeAssets: [{ blockchain: "KI", symbol: "XKI", address: null }], - logo: "https://api.rango.exchange/blockchains/ki.png", - displayName: "Ki", - shortName: "Ki", - sort: 30, - color: "#0F2B3D", - enabled: true, - type: "COSMOS", - chainId: "kichain-2", - info: { - experimental: true, - rpc: "https://rpc-mainnet.blockchain.ki", - rest: "https://api-mainnet.blockchain.ki", - cosmostationLcdUrl: "https://lcd-kichain.cosmostation.io", - cosmostationApiUrl: "https://api-kichain.cosmostation.io", - cosmostationDenomTracePath: "/ibc/apps/transfer/v1/denom_traces/", - mintScanName: "ki-chain", - chainName: "Ki", - stakeCurrency: { - coinDenom: "XKI", - coinMinimalDenom: "uxki", - coinDecimals: 6, - coinGeckoId: "pool:uxki", - coinImageUrl: "/tokens/blockchain/XKI.png", - }, - bip44: { coinType: 118 }, - bech32Config: { - bech32PrefixAccAddr: "ki", - bech32PrefixAccPub: "kipub", - bech32PrefixValAddr: "kivaloper", - bech32PrefixValPub: "kivaloperpub", - bech32PrefixConsAddr: "kivalcons", - bech32PrefixConsPub: "kivalconspub", - }, - currencies: [ - { - coinDenom: "XKI", - coinMinimalDenom: "uxki", - coinDecimals: 6, - coinGeckoId: "pool:uxki", - coinImageUrl: "/tokens/blockchain/XKI.png", - }, - ], - feeCurrencies: [ - { - coinDenom: "XKI", - coinMinimalDenom: "uxki", - coinDecimals: 6, - coinGeckoId: "pool:uxki", - coinImageUrl: "/tokens/blockchain/XKI.png", - }, - ], - features: ["stargate", "ibc-transfer"], - explorerUrlToTx: "https://www.mintscan.io/ki-chain/txs/{txHash}", - gasPriceStep: null, - }, - }, - { - name: "KUJIRA", - defaultDecimals: 6, - addressPatterns: ["^(kujira1)[0-9a-z]{38}$"], - feeAssets: [{ blockchain: "KUJIRA", symbol: "KUJI", address: null }], - logo: "https://api.rango.exchange/blockchains/kuji.svg", - displayName: "Kujira", - shortName: "Kujira", - sort: 31, - color: "#DF3935", - enabled: true, - type: "COSMOS", - chainId: "kaiyo-1", - info: { - experimental: true, - rpc: "https://rpc.kaiyo.kujira.setten.io", - rest: "https://lcd.kaiyo.kujira.setten.io", - cosmostationLcdUrl: "https://lcd-kujira.cosmostation.io", - cosmostationApiUrl: "https://api-kujira.cosmostation.io", - cosmostationDenomTracePath: "/ibc/apps/transfer/v1/denom_traces/", - mintScanName: "kujira", - chainName: "Kujira", - stakeCurrency: { - coinDenom: "KUJI", - coinMinimalDenom: "ukuji", - coinDecimals: 6, - coinGeckoId: "kujira", - coinImageUrl: "/tokens/blockchain/kuji.svg", - }, - bip44: { coinType: 118 }, - bech32Config: { - bech32PrefixAccAddr: "kujira", - bech32PrefixAccPub: "kujirapub", - bech32PrefixValAddr: "kujiravaloper", - bech32PrefixValPub: "kujiravaloperpub", - bech32PrefixConsAddr: "kujiravalcons", - bech32PrefixConsPub: "kujiravalconspub", - }, - currencies: [ - { - coinDenom: "KUJI", - coinMinimalDenom: "ukuji", - coinDecimals: 6, - coinGeckoId: "kujira", - coinImageUrl: "/tokens/blockchain/kuji.png", - }, - ], - feeCurrencies: [ - { - coinDenom: "KUJI", - coinMinimalDenom: "ukuji", - coinDecimals: 6, - coinGeckoId: "kujira", - coinImageUrl: "/tokens/blockchain/kuji.png", - }, - ], - features: ["stargate", "ibc-transfer"], - explorerUrlToTx: "https://finder.kujira.app/kaiyo-1/tx/{txHash}", - gasPriceStep: { low: 0.01, average: 0.025, high: 0.03 }, - }, - }, - { - name: "PERSISTENCE", - defaultDecimals: 6, - addressPatterns: ["^(persistence1)[0-9a-z]{38}$"], - feeAssets: [{ blockchain: "PERSISTENCE", symbol: "XPRT", address: null }], - logo: "https://api.rango.exchange/blockchains/persistence.png", - displayName: "Persistence", - shortName: "Persistence", - sort: 31, - color: "#383838", - enabled: true, - type: "COSMOS", - chainId: "core-1", - info: { - experimental: false, - rpc: "https://rpc-persistence.keplr.app", - rest: "https://lcd-persistence.keplr.app", - cosmostationLcdUrl: "https://lcd-persistence.cosmostation.io", - cosmostationApiUrl: "https://api-persistence.cosmostation.io", - cosmostationDenomTracePath: "/ibc/apps/transfer/v1/denom_traces/", - mintScanName: "persistence", - chainName: "Persistence", - stakeCurrency: { - coinDenom: "XPRT", - coinMinimalDenom: "uxprt", - coinDecimals: 6, - coinGeckoId: "persistence", - coinImageUrl: "/tokens/blockchain/xprt.png", - }, - bip44: { coinType: 750 }, - bech32Config: { - bech32PrefixAccAddr: "persistence", - bech32PrefixAccPub: "persistencepub", - bech32PrefixValAddr: "persistencevaloper", - bech32PrefixValPub: "persistencevaloperpub", - bech32PrefixConsAddr: "persistencevalcons", - bech32PrefixConsPub: "persistencevalconspub", - }, - currencies: [ - { - coinDenom: "XPRT", - coinMinimalDenom: "uxprt", - coinDecimals: 6, - coinGeckoId: "persistence", - coinImageUrl: "/tokens/blockchain/xprt.png", - }, - ], - feeCurrencies: [ - { - coinDenom: "XPRT", - coinMinimalDenom: "uxprt", - coinDecimals: 6, - coinGeckoId: "persistence", - coinImageUrl: "/tokens/blockchain/xprt.png", - }, - ], - features: ["stargate", "ibc-transfer"], - explorerUrlToTx: "https://www.mintscan.io/persistence/txs/{txHash}", - gasPriceStep: { low: 0, average: 0.025, high: 0.04 }, - }, - }, - { - name: "SENTINEL", - defaultDecimals: 6, - addressPatterns: ["^(sent1)[0-9a-z]{38}$"], - feeAssets: [{ blockchain: "SENTINEL", symbol: "DVPN", address: null }], - logo: "https://api.rango.exchange/blockchains/sentinel.png", - displayName: "Sentinel", - shortName: "Sentinel", - sort: 32, - color: "#142E51", - enabled: true, - type: "COSMOS", - chainId: "sentinelhub-2", - info: { - experimental: false, - rpc: "https://rpc-sentinel.keplr.app", - rest: "https://lcd-sentinel.keplr.app", - cosmostationLcdUrl: "https://lcd-sentinel.cosmostation.io", - cosmostationApiUrl: "https://api-sentinel.cosmostation.io", - cosmostationDenomTracePath: "/ibc/apps/transfer/v1/denom_traces/", - mintScanName: "sentinel", - chainName: "Sentinel", - stakeCurrency: { - coinDenom: "DVPN", - coinMinimalDenom: "udvpn", - coinDecimals: 6, - coinGeckoId: "sentinel", - coinImageUrl: "/tokens/blockchain/dvpn.png", - }, - bip44: { coinType: 118 }, - bech32Config: { - bech32PrefixAccAddr: "sent", - bech32PrefixAccPub: "sentpub", - bech32PrefixValAddr: "sentvaloper", - bech32PrefixValPub: "sentvaloperpub", - bech32PrefixConsAddr: "sentvalcons", - bech32PrefixConsPub: "sentvalconspub", - }, - currencies: [ - { - coinDenom: "DVPN", - coinMinimalDenom: "udvpn", - coinDecimals: 6, - coinGeckoId: "sentinel", - coinImageUrl: "/tokens/blockchain/dvpn.png", - }, - ], - feeCurrencies: [ - { - coinDenom: "DVPN", - coinMinimalDenom: "udvpn", - coinDecimals: 6, - coinGeckoId: "sentinel", - coinImageUrl: "/tokens/blockchain/dvpn.png", - }, - ], - features: ["stargate", "ibc-transfer"], - explorerUrlToTx: "https://www.mintscan.io/sentinel/txs/{txHash}", - gasPriceStep: { low: 0.1, average: 0.25, high: 0.4 }, - }, - }, - { - name: "STARNAME", - defaultDecimals: 6, - addressPatterns: ["^(star1)[0-9a-z]{38}$"], - feeAssets: [{ blockchain: "STARNAME", symbol: "IOV", address: null }], - logo: "https://api.rango.exchange/blockchains/starname.png", - displayName: "Starname", - shortName: "Starname", - sort: 35, - color: "#BC64BB", - enabled: true, - type: "COSMOS", - chainId: "iov-mainnet-ibc", - info: { - experimental: false, - rpc: "https://rpc-iov.keplr.app", - rest: "https://lcd-iov.keplr.app", - cosmostationLcdUrl: "https://lcd-iov.cosmostation.io", - cosmostationApiUrl: "https://api-iov.cosmostation.io", - cosmostationDenomTracePath: - "/ibc/applications/transfer/v1beta1/denom_traces/", - mintScanName: "starname", - chainName: "Starname", - stakeCurrency: { - coinDenom: "IOV", - coinMinimalDenom: "uiov", - coinDecimals: 6, - coinGeckoId: "starname", - coinImageUrl: "/tokens/blockchain/IOV.png", - }, - bip44: { coinType: 494 }, - bech32Config: { - bech32PrefixAccAddr: "star", - bech32PrefixAccPub: "starpub", - bech32PrefixValAddr: "starvaloper", - bech32PrefixValPub: "starvaloperpub", - bech32PrefixConsAddr: "starvalcons", - bech32PrefixConsPub: "starvalconspub", - }, - currencies: [ - { - coinDenom: "IOV", - coinMinimalDenom: "uiov", - coinDecimals: 6, - coinGeckoId: "starname", - coinImageUrl: "/tokens/blockchain/IOV.png", - }, - ], - feeCurrencies: [ - { - coinDenom: "IOV", - coinMinimalDenom: "uiov", - coinDecimals: 6, - coinGeckoId: "starname", - coinImageUrl: "/tokens/blockchain/IOV.png", - }, - ], - features: ["stargate", "ibc-transfer"], - explorerUrlToTx: "https://www.mintscan.io/starname/txs/{txHash}", - gasPriceStep: { low: 1, average: 2, high: 3 }, - }, - }, - { - name: "UMEE", - defaultDecimals: 6, - addressPatterns: ["^(umee1)[0-9a-z]{38}$"], - feeAssets: [{ blockchain: "UMEE", symbol: "UMEE", address: null }], - logo: "https://api.rango.exchange/blockchains/umee.svg", - displayName: "Umee", - shortName: "Umee", - sort: 36, - color: "#D2B6FF", - enabled: true, - type: "COSMOS", - chainId: "umee-1", - info: { - experimental: false, - rpc: "https://api.barnacle.mainnet.network.umee.cc", - rest: "https://lcd-umee.cosmostation.io", - cosmostationLcdUrl: "https://lcd-umee.cosmostation.io", - cosmostationApiUrl: "https://api-umee.cosmostation.io", - cosmostationDenomTracePath: "/ibc/apps/transfer/v1/denom_traces/", - mintScanName: "umee", - chainName: "Umee", - stakeCurrency: { - coinDenom: "UMEE", - coinMinimalDenom: "uumee", - coinDecimals: 6, - coinGeckoId: "pool:uumee", - coinImageUrl: "/tokens/blockchain/UMEE.png", - }, - bip44: { coinType: 118 }, - bech32Config: { - bech32PrefixAccAddr: "umee", - bech32PrefixAccPub: "umeepub", - bech32PrefixValAddr: "umeevaloper", - bech32PrefixValPub: "umeevaloperpub", - bech32PrefixConsAddr: "umeevalcons", - bech32PrefixConsPub: "umeevalconspub", - }, - currencies: [ - { - coinDenom: "UMEE", - coinMinimalDenom: "uumee", - coinDecimals: 6, - coinGeckoId: "pool:uumee", - coinImageUrl: "/tokens/blockchain/UMEE.png", - }, - ], - feeCurrencies: [ - { - coinDenom: "UMEE", - coinMinimalDenom: "uumee", - coinDecimals: 6, - coinGeckoId: "pool:uumee", - coinImageUrl: "/tokens/blockchain/UMEE.png", - }, - ], - features: ["stargate", "ibc-transfer", "no-legacy-stdTx"], - explorerUrlToTx: "https://www.mintscan.io/umee/txs/{txHash}", - gasPriceStep: { low: 0.05, average: 0.06, high: 0.1 }, - }, - }, - { - name: "BITCANNA", - defaultDecimals: 6, - addressPatterns: ["^(bcna1)[0-9a-z]{38}$"], - feeAssets: [{ blockchain: "BITCANNA", symbol: "BCNA", address: null }], - logo: "https://api.rango.exchange/blockchains/bitcanna.svg", - displayName: "BitCanna", - shortName: "BitCanna", - sort: 36, - color: "#3CC194", - enabled: true, - type: "COSMOS", - chainId: "bitcanna-1", - info: { - experimental: true, - rpc: "https://rpc.bitcanna.io", - rest: "https://lcd.bitcanna.io", - cosmostationLcdUrl: "https://lcd-bitcanna.cosmostation.io", - cosmostationApiUrl: "https://api-bitcanna.cosmostation.io", - cosmostationDenomTracePath: "/ibc/apps/transfer/v1/denom_traces/", - mintScanName: "bitcanna", - chainName: "BitCanna", - stakeCurrency: { - coinDenom: "BCNA", - coinMinimalDenom: "ubcna", - coinDecimals: 6, - coinGeckoId: "bitcanna", - coinImageUrl: "/tokens/blockchain/BCNA.png", - }, - bip44: { coinType: 118 }, - bech32Config: { - bech32PrefixAccAddr: "bcna", - bech32PrefixAccPub: "bcnapub", - bech32PrefixValAddr: "bcnavaloper", - bech32PrefixValPub: "bcnavaloperpub", - bech32PrefixConsAddr: "bcnavalcons", - bech32PrefixConsPub: "bcnavalconspub", - }, - currencies: [ - { - coinDenom: "BCNA", - coinMinimalDenom: "ubcna", - coinDecimals: 6, - coinGeckoId: "bitcanna", - coinImageUrl: "/tokens/blockchain/BCNA.png", - }, - ], - feeCurrencies: [ - { - coinDenom: "BCNA", - coinMinimalDenom: "ubcna", - coinDecimals: 6, - coinGeckoId: "bitcanna", - coinImageUrl: "/tokens/blockchain/BCNA.png", - }, - ], - features: ["stargate", "ibc-transfer", "no-legacy-stdTx"], - explorerUrlToTx: "https://www.mintscan.io/bitcanna/txs/{txHash}", - gasPriceStep: null, - }, - }, - { - name: "DESMOS", - defaultDecimals: 6, - addressPatterns: ["^(desmos1)[0-9a-z]{38}$"], - feeAssets: [{ blockchain: "DESMOS", symbol: "DSM", address: null }], - logo: "https://api.rango.exchange/blockchains/desmos.svg", - displayName: "Desmos", - shortName: "Desmos", - sort: 37, - color: "#DF6952", - enabled: true, - type: "COSMOS", - chainId: "desmos-mainnet", - info: { - experimental: true, - rpc: "https://rpc.mainnet.desmos.network", - rest: "https://api.mainnet.desmos.network", - cosmostationLcdUrl: "https://lcd-desmos.cosmostation.io", - cosmostationApiUrl: "https://api-desmos.cosmostation.io", - cosmostationDenomTracePath: "/ibc/apps/transfer/v1/denom_traces/", - mintScanName: "desmos", - chainName: "Desmos", - stakeCurrency: { - coinDenom: "DSM", - coinMinimalDenom: "udsm", - coinDecimals: 6, - coinGeckoId: "pool:udsm", - coinImageUrl: "/tokens/blockchain/DSM.png", - }, - bip44: { coinType: 852 }, - bech32Config: { - bech32PrefixAccAddr: "desmos", - bech32PrefixAccPub: "desmospub", - bech32PrefixValAddr: "desmosvaloper", - bech32PrefixValPub: "desmosvaloperpub", - bech32PrefixConsAddr: "desmosvalcons", - bech32PrefixConsPub: "desmosvalconspub", - }, - currencies: [ - { - coinDenom: "DSM", - coinMinimalDenom: "udsm", - coinDecimals: 6, - coinGeckoId: "pool:udsm", - coinImageUrl: "/tokens/blockchain/DSM.png", - }, - ], - feeCurrencies: [ - { - coinDenom: "DSM", - coinMinimalDenom: "udsm", - coinDecimals: 6, - coinGeckoId: "pool:udsm", - coinImageUrl: "/tokens/blockchain/DSM.png", - }, - ], - features: ["stargate", "ibc-transfer", "no-legacy-stdTx", "ibc-go"], - explorerUrlToTx: - "https://explorer.desmos.network/transactions/{txHash}", - gasPriceStep: null, - }, - }, - { - name: "LUMNETWORK", - defaultDecimals: 6, - addressPatterns: ["^(lum1)[0-9a-z]{38}$"], - feeAssets: [{ blockchain: "LUMNETWORK", symbol: "LUM", address: null }], - logo: "https://api.rango.exchange/blockchains/lumnetwork.svg", - displayName: "Lum Network", - shortName: "Lum Network", - sort: 38, - color: "#1B42B4", - enabled: true, - type: "COSMOS", - chainId: "lum-network-1", - info: { - experimental: true, - rpc: "https://node0.mainnet.lum.network/rpc", - rest: "https://node0.mainnet.lum.network/rest", - cosmostationLcdUrl: "https://lcd-lum.cosmostation.io", - cosmostationApiUrl: "https://api-lum.cosmostation.io", - cosmostationDenomTracePath: "/ibc/apps/transfer/v1/denom_traces/", - mintScanName: "lum", - chainName: "Lum Network", - stakeCurrency: { - coinDenom: "LUM", - coinMinimalDenom: "ulum", - coinDecimals: 6, - coinGeckoId: "pool:ulum", - coinImageUrl: "/tokens/blockchain/LUM.png", - }, - bip44: { coinType: 118 }, - bech32Config: { - bech32PrefixAccAddr: "lum", - bech32PrefixAccPub: "lumpub", - bech32PrefixValAddr: "lumvaloper", - bech32PrefixValPub: "lumvaloperpub", - bech32PrefixConsAddr: "lumvalcons", - bech32PrefixConsPub: "lumvalconspub", - }, - currencies: [ - { - coinDenom: "LUM", - coinMinimalDenom: "ulum", - coinDecimals: 6, - coinGeckoId: "pool:ulum", - coinImageUrl: "/tokens/blockchain/LUM.png", - }, - ], - feeCurrencies: [ - { - coinDenom: "LUM", - coinMinimalDenom: "ulum", - coinDecimals: 6, - coinGeckoId: "pool:ulum", - coinImageUrl: "/tokens/blockchain/LUM.png", - }, - ], - features: ["stargate", "ibc-transfer", "no-legacy-stdTx", "ibc-go"], - explorerUrlToTx: "https://www.mintscan.io/lum/txs/{txHash}", - gasPriceStep: null, - }, - }, - ], - phantom: [ - { - name: "SOLANA", - defaultDecimals: 9, - addressPatterns: ["^[1-9A-HJ-NP-Za-km-z]{32,44}$"], - feeAssets: [{ blockchain: "SOLANA", symbol: "SOL", address: null }], - logo: "https://api.rango.exchange/blockchains/solana.svg", - displayName: "Solana", - shortName: "Solana", - sort: 11, - color: "#708DD2", - enabled: true, - type: "SOLANA", - chainId: "mainnet-beta", - info: null, - }, - ], - xdefi: [ - { - name: "BSC", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "BSC", symbol: "BNB", address: null }], - logo: "https://api.rango.exchange/blockchains/binance.svg", - displayName: "BSC", - shortName: "BSC", - sort: 1, - color: "#F3BA2F", - enabled: true, - type: "EVM", - chainId: "0x38", - info: { - chainName: "Binance Smart Chain Mainnet", - nativeCurrency: { name: "BNB", symbol: "BNB", decimals: 18 }, - rpcUrls: ["https://bsc-dataseed1.ninicoin.io"], - blockExplorerUrls: ["https://bscscan.com"], - addressUrl: "https://bscscan.com/address/{wallet}", - transactionUrl: "https://bscscan.com/tx/{txHash}", - }, - }, - { - name: "POLYGON", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "POLYGON", symbol: "MATIC", address: null }], - logo: "https://api.rango.exchange/blockchains/polygon.svg", - displayName: "Polygon", - shortName: "Polygon", - sort: 2, - color: "#8247E5", - enabled: true, - type: "EVM", - chainId: "0x89", - info: { - chainName: "Polygon Mainnet", - nativeCurrency: { name: "MATIC", symbol: "MATIC", decimals: 18 }, - rpcUrls: ["https://polygon-rpc.com"], - blockExplorerUrls: ["https://polygonscan.com"], - addressUrl: "https://polygonscan.com/address/{wallet}", - transactionUrl: "https://polygonscan.com/tx/{txHash}", - }, - }, - { - name: "ETH", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "ETH", symbol: "ETH", address: null }], - logo: "https://api.rango.exchange/blockchains/ethereum.svg", - displayName: "Ethereum", - shortName: "ETH", - sort: 3, - color: "#ecf0f1", - enabled: true, - type: "EVM", - chainId: "0x1", - info: { - chainName: "Ethereum Mainnet", - nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 }, - rpcUrls: ["https://rpc.ankr.com/eth"], - blockExplorerUrls: ["https://etherscan.io"], - addressUrl: "https://etherscan.io/address/{wallet}", - transactionUrl: "https://etherscan.io/tx/{txHash}", - }, - }, - { - name: "AVAX_CCHAIN", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "AVAX_CCHAIN", symbol: "AVAX", address: null }], - logo: "https://api.rango.exchange/blockchains/avax_cchain.svg", - displayName: "Avalanche", - shortName: "Avax", - sort: 6, - color: "#e84142", - enabled: true, - type: "EVM", - chainId: "0xa86a", - info: { - chainName: "Avalanche C-Chain", - nativeCurrency: { name: "AVAX", symbol: "AVAX", decimals: 18 }, - rpcUrls: ["https://api.avax.network/ext/bc/C/rpc"], - blockExplorerUrls: ["https://snowtrace.io"], - addressUrl: "https://snowtrace.io/address/{wallet}", - transactionUrl: "https://snowtrace.io/tx/{txHash}", - }, - }, - { - name: "ARBITRUM", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "ARBITRUM", symbol: "ETH", address: null }], - logo: "https://api.rango.exchange/blockchains/arbitrum.svg", - displayName: "Arbitrum", - shortName: "Arbitrum", - sort: 7, - color: "#28a0f0", - enabled: true, - type: "EVM", - chainId: "0xa4b1", - info: { - chainName: "Arbitrum One", - nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 }, - rpcUrls: ["https://arb1.arbitrum.io/rpc"], - blockExplorerUrls: ["https://arbiscan.io"], - addressUrl: "https://arbiscan.io/address/{wallet}", - transactionUrl: "https://arbiscan.io/tx/{txHash}", - }, - }, - { - name: "FANTOM", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "FANTOM", symbol: "FTM", address: null }], - logo: "https://api.rango.exchange/blockchains/fantom.png", - displayName: "Fantom", - shortName: "Fantom", - sort: 9, - color: "#337afe", - enabled: true, - type: "EVM", - chainId: "0xfa", - info: { - chainName: "Fantom Opera", - nativeCurrency: { name: "FTM", symbol: "FTM", decimals: 18 }, - rpcUrls: ["https://rpc.ftm.tools"], - blockExplorerUrls: ["https://ftmscan.com"], - addressUrl: "https://ftmscan.com/address/{wallet}", - transactionUrl: "https://ftmscan.com/tx/{txHash}", - }, - }, - { - name: "SOLANA", - defaultDecimals: 9, - addressPatterns: ["^[1-9A-HJ-NP-Za-km-z]{32,44}$"], - feeAssets: [{ blockchain: "SOLANA", symbol: "SOL", address: null }], - logo: "https://api.rango.exchange/blockchains/solana.svg", - displayName: "Solana", - shortName: "Solana", - sort: 11, - color: "#708DD2", - enabled: true, - type: "SOLANA", - chainId: "mainnet-beta", - info: null, - }, - { - name: "THOR", - defaultDecimals: 8, - addressPatterns: ["^(thor1)[0-9a-z]{38}$"], - feeAssets: [{ blockchain: "THOR", symbol: "RUNE", address: null }], - logo: "https://api.rango.exchange/blockchains/thorchain.svg", - displayName: "Thorchain", - shortName: "Thorchain", - sort: 17, - color: "#1AE6CB", - enabled: true, - type: "TRANSFER", - chainId: null, - info: null, - }, - { - name: "BNB", - defaultDecimals: 8, - addressPatterns: ["^(bnb1)[0-9a-z]{38}$"], - feeAssets: [{ blockchain: "BNB", symbol: "BNB", address: null }], - logo: "https://api.rango.exchange/blockchains/bnb.svg", - displayName: "Binance Chain", - shortName: "BNB", - sort: 18, - color: "#F3BA2F", - enabled: true, - type: "COSMOS", - chainId: null, - info: null, - }, - { - name: "BTC", - defaultDecimals: 8, - addressPatterns: [ - "^[13][a-km-zA-HJ-NP-Z1-9]{25,34}$|^(bc1)[0-9A-Za-z]{39,59}$", - ], - feeAssets: [{ blockchain: "BTC", symbol: "BTC", address: null }], - logo: "https://api.rango.exchange/blockchains/btc.svg", - displayName: "Bitcoin", - shortName: "BTC", - sort: 20, - color: "#F7931A", - enabled: true, - type: "TRANSFER", - chainId: null, - info: null, - }, - { - name: "LTC", - defaultDecimals: 8, - addressPatterns: ["^(L|M|3)[A-Za-z0-9]{33}$|^(ltc1)[0-9A-Za-z]{39}$"], - feeAssets: [{ blockchain: "LTC", symbol: "LTC", address: null }], - logo: "https://api.rango.exchange/blockchains/ltc.svg", - displayName: "LiteCoin", - shortName: "LTC", - sort: 27, - color: "#345D9D", - enabled: true, - type: "TRANSFER", - chainId: null, - info: null, - }, - { - name: "BCH", - defaultDecimals: 8, - addressPatterns: [ - "^[13][a-km-zA-HJ-NP-Z1-9]{25,34}$|^[0-9A-Za-z]{42,42}$", - ], - feeAssets: [{ blockchain: "BCH", symbol: "BCH", address: null }], - logo: "https://api.rango.exchange/blockchains/bch.svg", - displayName: "Bitcoin Cash", - shortName: "BCH", - sort: 28, - color: "#0AC18E", - enabled: true, - type: "TRANSFER", - chainId: null, - info: null, - }, - ], - "wallet-connect": [ - { - name: "BSC", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "BSC", symbol: "BNB", address: null }], - logo: "https://api.rango.exchange/blockchains/binance.svg", - displayName: "BSC", - shortName: "BSC", - sort: 1, - color: "#F3BA2F", - enabled: true, - type: "EVM", - chainId: "0x38", - info: { - chainName: "Binance Smart Chain Mainnet", - nativeCurrency: { name: "BNB", symbol: "BNB", decimals: 18 }, - rpcUrls: ["https://bsc-dataseed1.ninicoin.io"], - blockExplorerUrls: ["https://bscscan.com"], - addressUrl: "https://bscscan.com/address/{wallet}", - transactionUrl: "https://bscscan.com/tx/{txHash}", - }, - }, - { - name: "POLYGON", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "POLYGON", symbol: "MATIC", address: null }], - logo: "https://api.rango.exchange/blockchains/polygon.svg", - displayName: "Polygon", - shortName: "Polygon", - sort: 2, - color: "#8247E5", - enabled: true, - type: "EVM", - chainId: "0x89", - info: { - chainName: "Polygon Mainnet", - nativeCurrency: { name: "MATIC", symbol: "MATIC", decimals: 18 }, - rpcUrls: ["https://polygon-rpc.com"], - blockExplorerUrls: ["https://polygonscan.com"], - addressUrl: "https://polygonscan.com/address/{wallet}", - transactionUrl: "https://polygonscan.com/tx/{txHash}", - }, - }, - { - name: "ETH", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "ETH", symbol: "ETH", address: null }], - logo: "https://api.rango.exchange/blockchains/ethereum.svg", - displayName: "Ethereum", - shortName: "ETH", - sort: 3, - color: "#ecf0f1", - enabled: true, - type: "EVM", - chainId: "0x1", - info: { - chainName: "Ethereum Mainnet", - nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 }, - rpcUrls: ["https://rpc.ankr.com/eth"], - blockExplorerUrls: ["https://etherscan.io"], - addressUrl: "https://etherscan.io/address/{wallet}", - transactionUrl: "https://etherscan.io/tx/{txHash}", - }, - }, - { - name: "AVAX_CCHAIN", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "AVAX_CCHAIN", symbol: "AVAX", address: null }], - logo: "https://api.rango.exchange/blockchains/avax_cchain.svg", - displayName: "Avalanche", - shortName: "Avax", - sort: 6, - color: "#e84142", - enabled: true, - type: "EVM", - chainId: "0xa86a", - info: { - chainName: "Avalanche C-Chain", - nativeCurrency: { name: "AVAX", symbol: "AVAX", decimals: 18 }, - rpcUrls: ["https://api.avax.network/ext/bc/C/rpc"], - blockExplorerUrls: ["https://snowtrace.io"], - addressUrl: "https://snowtrace.io/address/{wallet}", - transactionUrl: "https://snowtrace.io/tx/{txHash}", - }, - }, - { - name: "ARBITRUM", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "ARBITRUM", symbol: "ETH", address: null }], - logo: "https://api.rango.exchange/blockchains/arbitrum.svg", - displayName: "Arbitrum", - shortName: "Arbitrum", - sort: 7, - color: "#28a0f0", - enabled: true, - type: "EVM", - chainId: "0xa4b1", - info: { - chainName: "Arbitrum One", - nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 }, - rpcUrls: ["https://arb1.arbitrum.io/rpc"], - blockExplorerUrls: ["https://arbiscan.io"], - addressUrl: "https://arbiscan.io/address/{wallet}", - transactionUrl: "https://arbiscan.io/tx/{txHash}", - }, - }, - { - name: "FANTOM", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "FANTOM", symbol: "FTM", address: null }], - logo: "https://api.rango.exchange/blockchains/fantom.png", - displayName: "Fantom", - shortName: "Fantom", - sort: 9, - color: "#337afe", - enabled: true, - type: "EVM", - chainId: "0xfa", - info: { - chainName: "Fantom Opera", - nativeCurrency: { name: "FTM", symbol: "FTM", decimals: 18 }, - rpcUrls: ["https://rpc.ftm.tools"], - blockExplorerUrls: ["https://ftmscan.com"], - addressUrl: "https://ftmscan.com/address/{wallet}", - transactionUrl: "https://ftmscan.com/tx/{txHash}", - }, - }, - { - name: "OPTIMISM", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "OPTIMISM", symbol: "ETH", address: null }], - logo: "https://api.rango.exchange/blockchains/optimism.svg", - displayName: "Optimism", - shortName: "Optimism", - sort: 10, - color: "#FF0420", - enabled: true, - type: "EVM", - chainId: "0xa", - info: { - chainName: "Optimism", - nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 }, - rpcUrls: ["https://mainnet.optimism.io"], - blockExplorerUrls: ["https://optimistic.etherscan.io"], - addressUrl: "https://optimistic.etherscan.io/address/{wallet}", - transactionUrl: "https://optimistic.etherscan.io/tx/{txHash}", - }, - }, - { - name: "OKC", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "OKC", symbol: "OKT", address: null }], - logo: "https://api.rango.exchange/blockchains/okx.png", - displayName: "OKX Chain (OKC)", - shortName: "Okx", - sort: 11, - color: "#29a0f0", - enabled: true, - type: "EVM", - chainId: "0x42", - info: { - chainName: "OKX Chain", - nativeCurrency: { name: "OKT", symbol: "OKT", decimals: 18 }, - rpcUrls: ["https://exchainrpc.okex.org"], - blockExplorerUrls: ["https://www.oklink.com/en/okc"], - addressUrl: "https://www.oklink.com/en/okc/address/{wallet}", - transactionUrl: "https://www.oklink.com/en/okc/tx/{txHash}", - }, - }, - { - name: "CRONOS", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "CRONOS", symbol: "CRO", address: null }], - logo: "https://api.rango.exchange/blockchains/cronos.svg", - displayName: "Cronos", - shortName: "Cronos", - sort: 12, - color: "#1a90ff", - enabled: true, - type: "EVM", - chainId: "0x19", - info: { - chainName: "Cronos Mainnet Beta", - nativeCurrency: { name: "CRO", symbol: "CRO", decimals: 18 }, - rpcUrls: ["https://cronosrpc-1.xstaking.sg"], - blockExplorerUrls: ["https://cronoscan.com"], - addressUrl: "https://cronoscan.com/address/{wallet}", - transactionUrl: "https://cronoscan.com/tx/{txHash}", - }, - }, - { - name: "MOONRIVER", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "MOONRIVER", symbol: "MOVR", address: null }], - logo: "https://api.rango.exchange/blockchains/moonriver.svg", - displayName: "MoonRiver", - shortName: "MoonRiver", - sort: 13, - color: "#F3B404", - enabled: true, - type: "EVM", - chainId: "0x505", - info: { - chainName: "MoonRiver", - nativeCurrency: { name: "MOVR", symbol: "MOVR", decimals: 18 }, - rpcUrls: ["https://rpc.moonriver.moonbeam.network"], - blockExplorerUrls: ["https://moonriver.moonscan.io"], - addressUrl: "https://moonriver.moonscan.io/address/{wallet}", - transactionUrl: "https://moonriver.moonscan.io/tx/{txHash}", - }, - }, - { - name: "MOONBEAM", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "MOONBEAM", symbol: "GLMR", address: null }], - logo: "https://api.rango.exchange/blockchains/moonbeam.png", - displayName: "MoonBeam", - shortName: "MoonBeam", - sort: 14, - color: "#B3206B", - enabled: true, - type: "EVM", - chainId: "0x504", - info: { - chainName: "MoonBeam", - nativeCurrency: { name: "GLMR", symbol: "GLMR", decimals: 18 }, - rpcUrls: ["https://rpc.api.moonbeam.network"], - blockExplorerUrls: ["https://moonbeam.moonscan.io"], - addressUrl: "https://moonbeam.moonscan.io/address/{wallet}", - transactionUrl: "https://moonbeam.moonscan.io/tx/{txHash}", - }, - }, - { - name: "HECO", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "HECO", symbol: "HT", address: null }], - logo: "https://api.rango.exchange/blockchains/heco.png", - displayName: "Heco", - shortName: "Heco", - sort: 15, - color: "#4CA852", - enabled: true, - type: "EVM", - chainId: "0x80", - info: { - chainName: "Huobi ECO Chain Mainnet", - nativeCurrency: { name: "HT", symbol: "HT", decimals: 18 }, - rpcUrls: ["https://http-mainnet.hecochain.com"], - blockExplorerUrls: ["https://hecoinfo.com"], - addressUrl: "https://hecoinfo.com/address/{wallet}", - transactionUrl: "https://hecoinfo.com/tx/{txHash}", - }, - }, - { - name: "AURORA", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "AURORA", symbol: "ETH", address: null }], - logo: "https://api.rango.exchange/blockchains/aurora.svg", - displayName: "Aurora", - shortName: "Aurora", - sort: 15, - color: "#78d64b", - enabled: true, - type: "EVM", - chainId: "0x4e454152", - info: { - chainName: "Aurora Mainnet", - nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 }, - rpcUrls: ["https://mainnet.aurora.dev"], - blockExplorerUrls: ["https://explorer.mainnet.aurora.dev"], - addressUrl: "https://explorer.mainnet.aurora.dev/address/{wallet}", - transactionUrl: "https://explorer.mainnet.aurora.dev/tx/{txHash}", - }, - }, - { - name: "HARMONY", - defaultDecimals: 18, - addressPatterns: ["^(one1)[0-9a-z]{38}$", "^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "HARMONY", symbol: "ONE", address: null }], - logo: "https://api.rango.exchange/blockchains/harmony.svg", - displayName: "Harmony", - shortName: "Harmony", - sort: 15, - color: "#50AEE9", - enabled: true, - type: "EVM", - chainId: "0x63564c40", - info: { - chainName: "Harmony Mainnet", - nativeCurrency: { name: "ONE", symbol: "ONE", decimals: 18 }, - rpcUrls: ["https://api.s0.t.hmny.io"], - blockExplorerUrls: ["https://explorer.harmony.one"], - addressUrl: "https://explorer.harmony.one/address/{wallet}", - transactionUrl: "https://explorer.harmony.one/tx/{txHash}", - }, - }, - { - name: "EVMOS", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "EVMOS", symbol: "EVMOS", address: null }], - logo: "https://api.rango.exchange/blockchains/evmos.png", - displayName: "Evmos", - shortName: "Evmos", - sort: 15, - color: "#2D2925", - enabled: true, - type: "EVM", - chainId: "0x2329", - info: { - chainName: "Evmos", - nativeCurrency: { name: "EVMOS", symbol: "EVMOS", decimals: 18 }, - rpcUrls: ["https://eth.bd.evmos.org:8545"], - blockExplorerUrls: ["https://evm.evmos.org"], - addressUrl: "https://evm.evmos.org/address/{wallet}", - transactionUrl: "https://evm.evmos.org/tx/{txHash}", - }, - }, - { - name: "GNOSIS", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "GNOSIS", symbol: "XDAI", address: null }], - logo: "https://api.rango.exchange/blockchains/gnosis.svg", - displayName: "Gnosis", - shortName: "Gnosis", - sort: 26, - color: "#3E6957", - enabled: true, - type: "EVM", - chainId: "0x64", - info: { - chainName: "Gnosis Chain", - nativeCurrency: { name: "XDAI", symbol: "XDAI", decimals: 18 }, - rpcUrls: ["https://rpc.gnosischain.com"], - blockExplorerUrls: ["https://blockscout.com/xdai/mainnet"], - addressUrl: "https://blockscout.com/xdai/mainnet/address/{wallet}", - transactionUrl: "https://blockscout.com/xdai/mainnet/tx/{txHash}", - }, - }, - { - name: "FUSE", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "FUSE", symbol: "FUSE", address: null }], - logo: "https://api.rango.exchange/blockchains/fuse.png", - displayName: "Fuse", - shortName: "Fuse", - sort: 29, - color: "#C5F9AD", - enabled: true, - type: "EVM", - chainId: "0x7a", - info: { - chainName: "Fuse Mainnet", - nativeCurrency: { name: "FUSE", symbol: "FUSE", decimals: 18 }, - rpcUrls: ["https://rpc.fuse.io"], - blockExplorerUrls: ["https://explorer.fuse.io"], - addressUrl: "https://explorer.fuse.io/address/{wallet}", - transactionUrl: "https://explorer.fuse.io/tx/{txHash}", - }, - }, - { - name: "BOBA", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "BOBA", symbol: "ETH", address: null }], - logo: "https://api.rango.exchange/blockchains/boba.png", - displayName: "Boba", - shortName: "Boba", - sort: 39, - color: "#ccff00", - enabled: true, - type: "EVM", - chainId: "0x120", - info: { - chainName: "Boba Network", - nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 }, - rpcUrls: ["https://mainnet.boba.network"], - blockExplorerUrls: ["https://bobascan.com/"], - addressUrl: "https://bobascan.com//address/{wallet}", - transactionUrl: "https://bobascan.com//tx/{txHash}", - }, - }, - ], - "trust-wallet": [ - { - name: "BSC", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "BSC", symbol: "BNB", address: null }], - logo: "https://api.rango.exchange/blockchains/binance.svg", - displayName: "BSC", - shortName: "BSC", - sort: 1, - color: "#F3BA2F", - enabled: true, - type: "EVM", - chainId: "0x38", - info: { - chainName: "Binance Smart Chain Mainnet", - nativeCurrency: { name: "BNB", symbol: "BNB", decimals: 18 }, - rpcUrls: ["https://bsc-dataseed1.ninicoin.io"], - blockExplorerUrls: ["https://bscscan.com"], - addressUrl: "https://bscscan.com/address/{wallet}", - transactionUrl: "https://bscscan.com/tx/{txHash}", - }, - }, - { - name: "POLYGON", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "POLYGON", symbol: "MATIC", address: null }], - logo: "https://api.rango.exchange/blockchains/polygon.svg", - displayName: "Polygon", - shortName: "Polygon", - sort: 2, - color: "#8247E5", - enabled: true, - type: "EVM", - chainId: "0x89", - info: { - chainName: "Polygon Mainnet", - nativeCurrency: { name: "MATIC", symbol: "MATIC", decimals: 18 }, - rpcUrls: ["https://polygon-rpc.com"], - blockExplorerUrls: ["https://polygonscan.com"], - addressUrl: "https://polygonscan.com/address/{wallet}", - transactionUrl: "https://polygonscan.com/tx/{txHash}", - }, - }, - { - name: "ETH", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "ETH", symbol: "ETH", address: null }], - logo: "https://api.rango.exchange/blockchains/ethereum.svg", - displayName: "Ethereum", - shortName: "ETH", - sort: 3, - color: "#ecf0f1", - enabled: true, - type: "EVM", - chainId: "0x1", - info: { - chainName: "Ethereum Mainnet", - nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 }, - rpcUrls: ["https://rpc.ankr.com/eth"], - blockExplorerUrls: ["https://etherscan.io"], - addressUrl: "https://etherscan.io/address/{wallet}", - transactionUrl: "https://etherscan.io/tx/{txHash}", - }, - }, - { - name: "AVAX_CCHAIN", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "AVAX_CCHAIN", symbol: "AVAX", address: null }], - logo: "https://api.rango.exchange/blockchains/avax_cchain.svg", - displayName: "Avalanche", - shortName: "Avax", - sort: 6, - color: "#e84142", - enabled: true, - type: "EVM", - chainId: "0xa86a", - info: { - chainName: "Avalanche C-Chain", - nativeCurrency: { name: "AVAX", symbol: "AVAX", decimals: 18 }, - rpcUrls: ["https://api.avax.network/ext/bc/C/rpc"], - blockExplorerUrls: ["https://snowtrace.io"], - addressUrl: "https://snowtrace.io/address/{wallet}", - transactionUrl: "https://snowtrace.io/tx/{txHash}", - }, - }, - { - name: "ARBITRUM", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "ARBITRUM", symbol: "ETH", address: null }], - logo: "https://api.rango.exchange/blockchains/arbitrum.svg", - displayName: "Arbitrum", - shortName: "Arbitrum", - sort: 7, - color: "#28a0f0", - enabled: true, - type: "EVM", - chainId: "0xa4b1", - info: { - chainName: "Arbitrum One", - nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 }, - rpcUrls: ["https://arb1.arbitrum.io/rpc"], - blockExplorerUrls: ["https://arbiscan.io"], - addressUrl: "https://arbiscan.io/address/{wallet}", - transactionUrl: "https://arbiscan.io/tx/{txHash}", - }, - }, - { - name: "FANTOM", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "FANTOM", symbol: "FTM", address: null }], - logo: "https://api.rango.exchange/blockchains/fantom.png", - displayName: "Fantom", - shortName: "Fantom", - sort: 9, - color: "#337afe", - enabled: true, - type: "EVM", - chainId: "0xfa", - info: { - chainName: "Fantom Opera", - nativeCurrency: { name: "FTM", symbol: "FTM", decimals: 18 }, - rpcUrls: ["https://rpc.ftm.tools"], - blockExplorerUrls: ["https://ftmscan.com"], - addressUrl: "https://ftmscan.com/address/{wallet}", - transactionUrl: "https://ftmscan.com/tx/{txHash}", - }, - }, - { - name: "OPTIMISM", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "OPTIMISM", symbol: "ETH", address: null }], - logo: "https://api.rango.exchange/blockchains/optimism.svg", - displayName: "Optimism", - shortName: "Optimism", - sort: 10, - color: "#FF0420", - enabled: true, - type: "EVM", - chainId: "0xa", - info: { - chainName: "Optimism", - nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 }, - rpcUrls: ["https://mainnet.optimism.io"], - blockExplorerUrls: ["https://optimistic.etherscan.io"], - addressUrl: "https://optimistic.etherscan.io/address/{wallet}", - transactionUrl: "https://optimistic.etherscan.io/tx/{txHash}", - }, - }, - { - name: "OKC", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "OKC", symbol: "OKT", address: null }], - logo: "https://api.rango.exchange/blockchains/okx.png", - displayName: "OKX Chain (OKC)", - shortName: "Okx", - sort: 11, - color: "#29a0f0", - enabled: true, - type: "EVM", - chainId: "0x42", - info: { - chainName: "OKX Chain", - nativeCurrency: { name: "OKT", symbol: "OKT", decimals: 18 }, - rpcUrls: ["https://exchainrpc.okex.org"], - blockExplorerUrls: ["https://www.oklink.com/en/okc"], - addressUrl: "https://www.oklink.com/en/okc/address/{wallet}", - transactionUrl: "https://www.oklink.com/en/okc/tx/{txHash}", - }, - }, - { - name: "CRONOS", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "CRONOS", symbol: "CRO", address: null }], - logo: "https://api.rango.exchange/blockchains/cronos.svg", - displayName: "Cronos", - shortName: "Cronos", - sort: 12, - color: "#1a90ff", - enabled: true, - type: "EVM", - chainId: "0x19", - info: { - chainName: "Cronos Mainnet Beta", - nativeCurrency: { name: "CRO", symbol: "CRO", decimals: 18 }, - rpcUrls: ["https://cronosrpc-1.xstaking.sg"], - blockExplorerUrls: ["https://cronoscan.com"], - addressUrl: "https://cronoscan.com/address/{wallet}", - transactionUrl: "https://cronoscan.com/tx/{txHash}", - }, - }, - { - name: "MOONRIVER", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "MOONRIVER", symbol: "MOVR", address: null }], - logo: "https://api.rango.exchange/blockchains/moonriver.svg", - displayName: "MoonRiver", - shortName: "MoonRiver", - sort: 13, - color: "#F3B404", - enabled: true, - type: "EVM", - chainId: "0x505", - info: { - chainName: "MoonRiver", - nativeCurrency: { name: "MOVR", symbol: "MOVR", decimals: 18 }, - rpcUrls: ["https://rpc.moonriver.moonbeam.network"], - blockExplorerUrls: ["https://moonriver.moonscan.io"], - addressUrl: "https://moonriver.moonscan.io/address/{wallet}", - transactionUrl: "https://moonriver.moonscan.io/tx/{txHash}", - }, - }, - { - name: "MOONBEAM", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "MOONBEAM", symbol: "GLMR", address: null }], - logo: "https://api.rango.exchange/blockchains/moonbeam.png", - displayName: "MoonBeam", - shortName: "MoonBeam", - sort: 14, - color: "#B3206B", - enabled: true, - type: "EVM", - chainId: "0x504", - info: { - chainName: "MoonBeam", - nativeCurrency: { name: "GLMR", symbol: "GLMR", decimals: 18 }, - rpcUrls: ["https://rpc.api.moonbeam.network"], - blockExplorerUrls: ["https://moonbeam.moonscan.io"], - addressUrl: "https://moonbeam.moonscan.io/address/{wallet}", - transactionUrl: "https://moonbeam.moonscan.io/tx/{txHash}", - }, - }, - { - name: "HECO", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "HECO", symbol: "HT", address: null }], - logo: "https://api.rango.exchange/blockchains/heco.png", - displayName: "Heco", - shortName: "Heco", - sort: 15, - color: "#4CA852", - enabled: true, - type: "EVM", - chainId: "0x80", - info: { - chainName: "Huobi ECO Chain Mainnet", - nativeCurrency: { name: "HT", symbol: "HT", decimals: 18 }, - rpcUrls: ["https://http-mainnet.hecochain.com"], - blockExplorerUrls: ["https://hecoinfo.com"], - addressUrl: "https://hecoinfo.com/address/{wallet}", - transactionUrl: "https://hecoinfo.com/tx/{txHash}", - }, - }, - { - name: "AURORA", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "AURORA", symbol: "ETH", address: null }], - logo: "https://api.rango.exchange/blockchains/aurora.svg", - displayName: "Aurora", - shortName: "Aurora", - sort: 15, - color: "#78d64b", - enabled: true, - type: "EVM", - chainId: "0x4e454152", - info: { - chainName: "Aurora Mainnet", - nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 }, - rpcUrls: ["https://mainnet.aurora.dev"], - blockExplorerUrls: ["https://explorer.mainnet.aurora.dev"], - addressUrl: "https://explorer.mainnet.aurora.dev/address/{wallet}", - transactionUrl: "https://explorer.mainnet.aurora.dev/tx/{txHash}", - }, - }, - { - name: "HARMONY", - defaultDecimals: 18, - addressPatterns: ["^(one1)[0-9a-z]{38}$", "^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "HARMONY", symbol: "ONE", address: null }], - logo: "https://api.rango.exchange/blockchains/harmony.svg", - displayName: "Harmony", - shortName: "Harmony", - sort: 15, - color: "#50AEE9", - enabled: true, - type: "EVM", - chainId: "0x63564c40", - info: { - chainName: "Harmony Mainnet", - nativeCurrency: { name: "ONE", symbol: "ONE", decimals: 18 }, - rpcUrls: ["https://api.s0.t.hmny.io"], - blockExplorerUrls: ["https://explorer.harmony.one"], - addressUrl: "https://explorer.harmony.one/address/{wallet}", - transactionUrl: "https://explorer.harmony.one/tx/{txHash}", - }, - }, - { - name: "EVMOS", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "EVMOS", symbol: "EVMOS", address: null }], - logo: "https://api.rango.exchange/blockchains/evmos.png", - displayName: "Evmos", - shortName: "Evmos", - sort: 15, - color: "#2D2925", - enabled: true, - type: "EVM", - chainId: "0x2329", - info: { - chainName: "Evmos", - nativeCurrency: { name: "EVMOS", symbol: "EVMOS", decimals: 18 }, - rpcUrls: ["https://eth.bd.evmos.org:8545"], - blockExplorerUrls: ["https://evm.evmos.org"], - addressUrl: "https://evm.evmos.org/address/{wallet}", - transactionUrl: "https://evm.evmos.org/tx/{txHash}", - }, - }, - { - name: "GNOSIS", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "GNOSIS", symbol: "XDAI", address: null }], - logo: "https://api.rango.exchange/blockchains/gnosis.svg", - displayName: "Gnosis", - shortName: "Gnosis", - sort: 26, - color: "#3E6957", - enabled: true, - type: "EVM", - chainId: "0x64", - info: { - chainName: "Gnosis Chain", - nativeCurrency: { name: "XDAI", symbol: "XDAI", decimals: 18 }, - rpcUrls: ["https://rpc.gnosischain.com"], - blockExplorerUrls: ["https://blockscout.com/xdai/mainnet"], - addressUrl: "https://blockscout.com/xdai/mainnet/address/{wallet}", - transactionUrl: "https://blockscout.com/xdai/mainnet/tx/{txHash}", - }, - }, - { - name: "FUSE", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "FUSE", symbol: "FUSE", address: null }], - logo: "https://api.rango.exchange/blockchains/fuse.png", - displayName: "Fuse", - shortName: "Fuse", - sort: 29, - color: "#C5F9AD", - enabled: true, - type: "EVM", - chainId: "0x7a", - info: { - chainName: "Fuse Mainnet", - nativeCurrency: { name: "FUSE", symbol: "FUSE", decimals: 18 }, - rpcUrls: ["https://rpc.fuse.io"], - blockExplorerUrls: ["https://explorer.fuse.io"], - addressUrl: "https://explorer.fuse.io/address/{wallet}", - transactionUrl: "https://explorer.fuse.io/tx/{txHash}", - }, - }, - { - name: "BOBA", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "BOBA", symbol: "ETH", address: null }], - logo: "https://api.rango.exchange/blockchains/boba.png", - displayName: "Boba", - shortName: "Boba", - sort: 39, - color: "#ccff00", - enabled: true, - type: "EVM", - chainId: "0x120", - info: { - chainName: "Boba Network", - nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 }, - rpcUrls: ["https://mainnet.boba.network"], - blockExplorerUrls: ["https://bobascan.com/"], - addressUrl: "https://bobascan.com//address/{wallet}", - transactionUrl: "https://bobascan.com//tx/{txHash}", - }, - }, - ], - coin98: [ - { - name: "BSC", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "BSC", symbol: "BNB", address: null }], - logo: "https://api.rango.exchange/blockchains/binance.svg", - displayName: "BSC", - shortName: "BSC", - sort: 1, - color: "#F3BA2F", - enabled: true, - type: "EVM", - chainId: "0x38", - info: { - chainName: "Binance Smart Chain Mainnet", - nativeCurrency: { name: "BNB", symbol: "BNB", decimals: 18 }, - rpcUrls: ["https://bsc-dataseed1.ninicoin.io"], - blockExplorerUrls: ["https://bscscan.com"], - addressUrl: "https://bscscan.com/address/{wallet}", - transactionUrl: "https://bscscan.com/tx/{txHash}", - }, - }, - { - name: "POLYGON", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "POLYGON", symbol: "MATIC", address: null }], - logo: "https://api.rango.exchange/blockchains/polygon.svg", - displayName: "Polygon", - shortName: "Polygon", - sort: 2, - color: "#8247E5", - enabled: true, - type: "EVM", - chainId: "0x89", - info: { - chainName: "Polygon Mainnet", - nativeCurrency: { name: "MATIC", symbol: "MATIC", decimals: 18 }, - rpcUrls: ["https://polygon-rpc.com"], - blockExplorerUrls: ["https://polygonscan.com"], - addressUrl: "https://polygonscan.com/address/{wallet}", - transactionUrl: "https://polygonscan.com/tx/{txHash}", - }, - }, - { - name: "ETH", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "ETH", symbol: "ETH", address: null }], - logo: "https://api.rango.exchange/blockchains/ethereum.svg", - displayName: "Ethereum", - shortName: "ETH", - sort: 3, - color: "#ecf0f1", - enabled: true, - type: "EVM", - chainId: "0x1", - info: { - chainName: "Ethereum Mainnet", - nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 }, - rpcUrls: ["https://rpc.ankr.com/eth"], - blockExplorerUrls: ["https://etherscan.io"], - addressUrl: "https://etherscan.io/address/{wallet}", - transactionUrl: "https://etherscan.io/tx/{txHash}", - }, - }, - { - name: "AVAX_CCHAIN", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "AVAX_CCHAIN", symbol: "AVAX", address: null }], - logo: "https://api.rango.exchange/blockchains/avax_cchain.svg", - displayName: "Avalanche", - shortName: "Avax", - sort: 6, - color: "#e84142", - enabled: true, - type: "EVM", - chainId: "0xa86a", - info: { - chainName: "Avalanche C-Chain", - nativeCurrency: { name: "AVAX", symbol: "AVAX", decimals: 18 }, - rpcUrls: ["https://api.avax.network/ext/bc/C/rpc"], - blockExplorerUrls: ["https://snowtrace.io"], - addressUrl: "https://snowtrace.io/address/{wallet}", - transactionUrl: "https://snowtrace.io/tx/{txHash}", - }, - }, - { - name: "ARBITRUM", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "ARBITRUM", symbol: "ETH", address: null }], - logo: "https://api.rango.exchange/blockchains/arbitrum.svg", - displayName: "Arbitrum", - shortName: "Arbitrum", - sort: 7, - color: "#28a0f0", - enabled: true, - type: "EVM", - chainId: "0xa4b1", - info: { - chainName: "Arbitrum One", - nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 }, - rpcUrls: ["https://arb1.arbitrum.io/rpc"], - blockExplorerUrls: ["https://arbiscan.io"], - addressUrl: "https://arbiscan.io/address/{wallet}", - transactionUrl: "https://arbiscan.io/tx/{txHash}", - }, - }, - { - name: "FANTOM", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "FANTOM", symbol: "FTM", address: null }], - logo: "https://api.rango.exchange/blockchains/fantom.png", - displayName: "Fantom", - shortName: "Fantom", - sort: 9, - color: "#337afe", - enabled: true, - type: "EVM", - chainId: "0xfa", - info: { - chainName: "Fantom Opera", - nativeCurrency: { name: "FTM", symbol: "FTM", decimals: 18 }, - rpcUrls: ["https://rpc.ftm.tools"], - blockExplorerUrls: ["https://ftmscan.com"], - addressUrl: "https://ftmscan.com/address/{wallet}", - transactionUrl: "https://ftmscan.com/tx/{txHash}", - }, - }, - { - name: "OPTIMISM", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "OPTIMISM", symbol: "ETH", address: null }], - logo: "https://api.rango.exchange/blockchains/optimism.svg", - displayName: "Optimism", - shortName: "Optimism", - sort: 10, - color: "#FF0420", - enabled: true, - type: "EVM", - chainId: "0xa", - info: { - chainName: "Optimism", - nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 }, - rpcUrls: ["https://mainnet.optimism.io"], - blockExplorerUrls: ["https://optimistic.etherscan.io"], - addressUrl: "https://optimistic.etherscan.io/address/{wallet}", - transactionUrl: "https://optimistic.etherscan.io/tx/{txHash}", - }, - }, - { - name: "OKC", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "OKC", symbol: "OKT", address: null }], - logo: "https://api.rango.exchange/blockchains/okx.png", - displayName: "OKX Chain (OKC)", - shortName: "Okx", - sort: 11, - color: "#29a0f0", - enabled: true, - type: "EVM", - chainId: "0x42", - info: { - chainName: "OKX Chain", - nativeCurrency: { name: "OKT", symbol: "OKT", decimals: 18 }, - rpcUrls: ["https://exchainrpc.okex.org"], - blockExplorerUrls: ["https://www.oklink.com/en/okc"], - addressUrl: "https://www.oklink.com/en/okc/address/{wallet}", - transactionUrl: "https://www.oklink.com/en/okc/tx/{txHash}", - }, - }, - { - name: "CRONOS", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "CRONOS", symbol: "CRO", address: null }], - logo: "https://api.rango.exchange/blockchains/cronos.svg", - displayName: "Cronos", - shortName: "Cronos", - sort: 12, - color: "#1a90ff", - enabled: true, - type: "EVM", - chainId: "0x19", - info: { - chainName: "Cronos Mainnet Beta", - nativeCurrency: { name: "CRO", symbol: "CRO", decimals: 18 }, - rpcUrls: ["https://cronosrpc-1.xstaking.sg"], - blockExplorerUrls: ["https://cronoscan.com"], - addressUrl: "https://cronoscan.com/address/{wallet}", - transactionUrl: "https://cronoscan.com/tx/{txHash}", - }, - }, - { - name: "MOONRIVER", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "MOONRIVER", symbol: "MOVR", address: null }], - logo: "https://api.rango.exchange/blockchains/moonriver.svg", - displayName: "MoonRiver", - shortName: "MoonRiver", - sort: 13, - color: "#F3B404", - enabled: true, - type: "EVM", - chainId: "0x505", - info: { - chainName: "MoonRiver", - nativeCurrency: { name: "MOVR", symbol: "MOVR", decimals: 18 }, - rpcUrls: ["https://rpc.moonriver.moonbeam.network"], - blockExplorerUrls: ["https://moonriver.moonscan.io"], - addressUrl: "https://moonriver.moonscan.io/address/{wallet}", - transactionUrl: "https://moonriver.moonscan.io/tx/{txHash}", - }, - }, - { - name: "MOONBEAM", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "MOONBEAM", symbol: "GLMR", address: null }], - logo: "https://api.rango.exchange/blockchains/moonbeam.png", - displayName: "MoonBeam", - shortName: "MoonBeam", - sort: 14, - color: "#B3206B", - enabled: true, - type: "EVM", - chainId: "0x504", - info: { - chainName: "MoonBeam", - nativeCurrency: { name: "GLMR", symbol: "GLMR", decimals: 18 }, - rpcUrls: ["https://rpc.api.moonbeam.network"], - blockExplorerUrls: ["https://moonbeam.moonscan.io"], - addressUrl: "https://moonbeam.moonscan.io/address/{wallet}", - transactionUrl: "https://moonbeam.moonscan.io/tx/{txHash}", - }, - }, - { - name: "HECO", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "HECO", symbol: "HT", address: null }], - logo: "https://api.rango.exchange/blockchains/heco.png", - displayName: "Heco", - shortName: "Heco", - sort: 15, - color: "#4CA852", - enabled: true, - type: "EVM", - chainId: "0x80", - info: { - chainName: "Huobi ECO Chain Mainnet", - nativeCurrency: { name: "HT", symbol: "HT", decimals: 18 }, - rpcUrls: ["https://http-mainnet.hecochain.com"], - blockExplorerUrls: ["https://hecoinfo.com"], - addressUrl: "https://hecoinfo.com/address/{wallet}", - transactionUrl: "https://hecoinfo.com/tx/{txHash}", - }, - }, - { - name: "AURORA", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "AURORA", symbol: "ETH", address: null }], - logo: "https://api.rango.exchange/blockchains/aurora.svg", - displayName: "Aurora", - shortName: "Aurora", - sort: 15, - color: "#78d64b", - enabled: true, - type: "EVM", - chainId: "0x4e454152", - info: { - chainName: "Aurora Mainnet", - nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 }, - rpcUrls: ["https://mainnet.aurora.dev"], - blockExplorerUrls: ["https://explorer.mainnet.aurora.dev"], - addressUrl: "https://explorer.mainnet.aurora.dev/address/{wallet}", - transactionUrl: "https://explorer.mainnet.aurora.dev/tx/{txHash}", - }, - }, - { - name: "HARMONY", - defaultDecimals: 18, - addressPatterns: ["^(one1)[0-9a-z]{38}$", "^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "HARMONY", symbol: "ONE", address: null }], - logo: "https://api.rango.exchange/blockchains/harmony.svg", - displayName: "Harmony", - shortName: "Harmony", - sort: 15, - color: "#50AEE9", - enabled: true, - type: "EVM", - chainId: "0x63564c40", - info: { - chainName: "Harmony Mainnet", - nativeCurrency: { name: "ONE", symbol: "ONE", decimals: 18 }, - rpcUrls: ["https://api.s0.t.hmny.io"], - blockExplorerUrls: ["https://explorer.harmony.one"], - addressUrl: "https://explorer.harmony.one/address/{wallet}", - transactionUrl: "https://explorer.harmony.one/tx/{txHash}", - }, - }, - { - name: "EVMOS", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "EVMOS", symbol: "EVMOS", address: null }], - logo: "https://api.rango.exchange/blockchains/evmos.png", - displayName: "Evmos", - shortName: "Evmos", - sort: 15, - color: "#2D2925", - enabled: true, - type: "EVM", - chainId: "0x2329", - info: { - chainName: "Evmos", - nativeCurrency: { name: "EVMOS", symbol: "EVMOS", decimals: 18 }, - rpcUrls: ["https://eth.bd.evmos.org:8545"], - blockExplorerUrls: ["https://evm.evmos.org"], - addressUrl: "https://evm.evmos.org/address/{wallet}", - transactionUrl: "https://evm.evmos.org/tx/{txHash}", - }, - }, - { - name: "GNOSIS", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "GNOSIS", symbol: "XDAI", address: null }], - logo: "https://api.rango.exchange/blockchains/gnosis.svg", - displayName: "Gnosis", - shortName: "Gnosis", - sort: 26, - color: "#3E6957", - enabled: true, - type: "EVM", - chainId: "0x64", - info: { - chainName: "Gnosis Chain", - nativeCurrency: { name: "XDAI", symbol: "XDAI", decimals: 18 }, - rpcUrls: ["https://rpc.gnosischain.com"], - blockExplorerUrls: ["https://blockscout.com/xdai/mainnet"], - addressUrl: "https://blockscout.com/xdai/mainnet/address/{wallet}", - transactionUrl: "https://blockscout.com/xdai/mainnet/tx/{txHash}", - }, - }, - { - name: "FUSE", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "FUSE", symbol: "FUSE", address: null }], - logo: "https://api.rango.exchange/blockchains/fuse.png", - displayName: "Fuse", - shortName: "Fuse", - sort: 29, - color: "#C5F9AD", - enabled: true, - type: "EVM", - chainId: "0x7a", - info: { - chainName: "Fuse Mainnet", - nativeCurrency: { name: "FUSE", symbol: "FUSE", decimals: 18 }, - rpcUrls: ["https://rpc.fuse.io"], - blockExplorerUrls: ["https://explorer.fuse.io"], - addressUrl: "https://explorer.fuse.io/address/{wallet}", - transactionUrl: "https://explorer.fuse.io/tx/{txHash}", - }, - }, - { - name: "BOBA", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "BOBA", symbol: "ETH", address: null }], - logo: "https://api.rango.exchange/blockchains/boba.png", - displayName: "Boba", - shortName: "Boba", - sort: 39, - color: "#ccff00", - enabled: true, - type: "EVM", - chainId: "0x120", - info: { - chainName: "Boba Network", - nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 }, - rpcUrls: ["https://mainnet.boba.network"], - blockExplorerUrls: ["https://bobascan.com/"], - addressUrl: "https://bobascan.com//address/{wallet}", - transactionUrl: "https://bobascan.com//tx/{txHash}", - }, - }, - { - name: "SOLANA", - defaultDecimals: 9, - addressPatterns: ["^[1-9A-HJ-NP-Za-km-z]{32,44}$"], - feeAssets: [{ blockchain: "SOLANA", symbol: "SOL", address: null }], - logo: "https://api.rango.exchange/blockchains/solana.svg", - displayName: "Solana", - shortName: "Solana", - sort: 11, - color: "#708DD2", - enabled: true, - type: "SOLANA", - chainId: "mainnet-beta", - info: null, - }, - ], - okx: [ - { - name: "BSC", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "BSC", symbol: "BNB", address: null }], - logo: "https://api.rango.exchange/blockchains/binance.svg", - displayName: "BSC", - shortName: "BSC", - sort: 1, - color: "#F3BA2F", - enabled: true, - type: "EVM", - chainId: "0x38", - info: { - chainName: "Binance Smart Chain Mainnet", - nativeCurrency: { name: "BNB", symbol: "BNB", decimals: 18 }, - rpcUrls: ["https://bsc-dataseed1.ninicoin.io"], - blockExplorerUrls: ["https://bscscan.com"], - addressUrl: "https://bscscan.com/address/{wallet}", - transactionUrl: "https://bscscan.com/tx/{txHash}", - }, - }, - { - name: "POLYGON", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "POLYGON", symbol: "MATIC", address: null }], - logo: "https://api.rango.exchange/blockchains/polygon.svg", - displayName: "Polygon", - shortName: "Polygon", - sort: 2, - color: "#8247E5", - enabled: true, - type: "EVM", - chainId: "0x89", - info: { - chainName: "Polygon Mainnet", - nativeCurrency: { name: "MATIC", symbol: "MATIC", decimals: 18 }, - rpcUrls: ["https://polygon-rpc.com"], - blockExplorerUrls: ["https://polygonscan.com"], - addressUrl: "https://polygonscan.com/address/{wallet}", - transactionUrl: "https://polygonscan.com/tx/{txHash}", - }, - }, - { - name: "ETH", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "ETH", symbol: "ETH", address: null }], - logo: "https://api.rango.exchange/blockchains/ethereum.svg", - displayName: "Ethereum", - shortName: "ETH", - sort: 3, - color: "#ecf0f1", - enabled: true, - type: "EVM", - chainId: "0x1", - info: { - chainName: "Ethereum Mainnet", - nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 }, - rpcUrls: ["https://rpc.ankr.com/eth"], - blockExplorerUrls: ["https://etherscan.io"], - addressUrl: "https://etherscan.io/address/{wallet}", - transactionUrl: "https://etherscan.io/tx/{txHash}", - }, - }, - { - name: "AVAX_CCHAIN", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "AVAX_CCHAIN", symbol: "AVAX", address: null }], - logo: "https://api.rango.exchange/blockchains/avax_cchain.svg", - displayName: "Avalanche", - shortName: "Avax", - sort: 6, - color: "#e84142", - enabled: true, - type: "EVM", - chainId: "0xa86a", - info: { - chainName: "Avalanche C-Chain", - nativeCurrency: { name: "AVAX", symbol: "AVAX", decimals: 18 }, - rpcUrls: ["https://api.avax.network/ext/bc/C/rpc"], - blockExplorerUrls: ["https://snowtrace.io"], - addressUrl: "https://snowtrace.io/address/{wallet}", - transactionUrl: "https://snowtrace.io/tx/{txHash}", - }, - }, - { - name: "ARBITRUM", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "ARBITRUM", symbol: "ETH", address: null }], - logo: "https://api.rango.exchange/blockchains/arbitrum.svg", - displayName: "Arbitrum", - shortName: "Arbitrum", - sort: 7, - color: "#28a0f0", - enabled: true, - type: "EVM", - chainId: "0xa4b1", - info: { - chainName: "Arbitrum One", - nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 }, - rpcUrls: ["https://arb1.arbitrum.io/rpc"], - blockExplorerUrls: ["https://arbiscan.io"], - addressUrl: "https://arbiscan.io/address/{wallet}", - transactionUrl: "https://arbiscan.io/tx/{txHash}", - }, - }, - { - name: "FANTOM", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "FANTOM", symbol: "FTM", address: null }], - logo: "https://api.rango.exchange/blockchains/fantom.png", - displayName: "Fantom", - shortName: "Fantom", - sort: 9, - color: "#337afe", - enabled: true, - type: "EVM", - chainId: "0xfa", - info: { - chainName: "Fantom Opera", - nativeCurrency: { name: "FTM", symbol: "FTM", decimals: 18 }, - rpcUrls: ["https://rpc.ftm.tools"], - blockExplorerUrls: ["https://ftmscan.com"], - addressUrl: "https://ftmscan.com/address/{wallet}", - transactionUrl: "https://ftmscan.com/tx/{txHash}", - }, - }, - { - name: "OPTIMISM", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "OPTIMISM", symbol: "ETH", address: null }], - logo: "https://api.rango.exchange/blockchains/optimism.svg", - displayName: "Optimism", - shortName: "Optimism", - sort: 10, - color: "#FF0420", - enabled: true, - type: "EVM", - chainId: "0xa", - info: { - chainName: "Optimism", - nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 }, - rpcUrls: ["https://mainnet.optimism.io"], - blockExplorerUrls: ["https://optimistic.etherscan.io"], - addressUrl: "https://optimistic.etherscan.io/address/{wallet}", - transactionUrl: "https://optimistic.etherscan.io/tx/{txHash}", - }, - }, - { - name: "SOLANA", - defaultDecimals: 9, - addressPatterns: ["^[1-9A-HJ-NP-Za-km-z]{32,44}$"], - feeAssets: [{ blockchain: "SOLANA", symbol: "SOL", address: null }], - logo: "https://api.rango.exchange/blockchains/solana.svg", - displayName: "Solana", - shortName: "Solana", - sort: 11, - color: "#708DD2", - enabled: true, - type: "SOLANA", - chainId: "mainnet-beta", - info: null, - }, - { - name: "CRONOS", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "CRONOS", symbol: "CRO", address: null }], - logo: "https://api.rango.exchange/blockchains/cronos.svg", - displayName: "Cronos", - shortName: "Cronos", - sort: 12, - color: "#1a90ff", - enabled: true, - type: "EVM", - chainId: "0x19", - info: { - chainName: "Cronos Mainnet Beta", - nativeCurrency: { name: "CRO", symbol: "CRO", decimals: 18 }, - rpcUrls: ["https://cronosrpc-1.xstaking.sg"], - blockExplorerUrls: ["https://cronoscan.com"], - addressUrl: "https://cronoscan.com/address/{wallet}", - transactionUrl: "https://cronoscan.com/tx/{txHash}", - }, - }, - { - name: "MOONRIVER", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "MOONRIVER", symbol: "MOVR", address: null }], - logo: "https://api.rango.exchange/blockchains/moonriver.svg", - displayName: "MoonRiver", - shortName: "MoonRiver", - sort: 13, - color: "#F3B404", - enabled: true, - type: "EVM", - chainId: "0x505", - info: { - chainName: "MoonRiver", - nativeCurrency: { name: "MOVR", symbol: "MOVR", decimals: 18 }, - rpcUrls: ["https://rpc.moonriver.moonbeam.network"], - blockExplorerUrls: ["https://moonriver.moonscan.io"], - addressUrl: "https://moonriver.moonscan.io/address/{wallet}", - transactionUrl: "https://moonriver.moonscan.io/tx/{txHash}", - }, - }, - { - name: "MOONBEAM", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "MOONBEAM", symbol: "GLMR", address: null }], - logo: "https://api.rango.exchange/blockchains/moonbeam.png", - displayName: "MoonBeam", - shortName: "MoonBeam", - sort: 14, - color: "#B3206B", - enabled: true, - type: "EVM", - chainId: "0x504", - info: { - chainName: "MoonBeam", - nativeCurrency: { name: "GLMR", symbol: "GLMR", decimals: 18 }, - rpcUrls: ["https://rpc.api.moonbeam.network"], - blockExplorerUrls: ["https://moonbeam.moonscan.io"], - addressUrl: "https://moonbeam.moonscan.io/address/{wallet}", - transactionUrl: "https://moonbeam.moonscan.io/tx/{txHash}", - }, - }, - { - name: "HARMONY", - defaultDecimals: 18, - addressPatterns: ["^(one1)[0-9a-z]{38}$", "^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "HARMONY", symbol: "ONE", address: null }], - logo: "https://api.rango.exchange/blockchains/harmony.svg", - displayName: "Harmony", - shortName: "Harmony", - sort: 15, - color: "#50AEE9", - enabled: true, - type: "EVM", - chainId: "0x63564c40", - info: { - chainName: "Harmony Mainnet", - nativeCurrency: { name: "ONE", symbol: "ONE", decimals: 18 }, - rpcUrls: ["https://api.s0.t.hmny.io"], - blockExplorerUrls: ["https://explorer.harmony.one"], - addressUrl: "https://explorer.harmony.one/address/{wallet}", - transactionUrl: "https://explorer.harmony.one/tx/{txHash}", - }, - }, - { - name: "BTC", - defaultDecimals: 8, - addressPatterns: [ - "^[13][a-km-zA-HJ-NP-Z1-9]{25,34}$|^(bc1)[0-9A-Za-z]{39,59}$", - ], - feeAssets: [{ blockchain: "BTC", symbol: "BTC", address: null }], - logo: "https://api.rango.exchange/blockchains/btc.svg", - displayName: "Bitcoin", - shortName: "BTC", - sort: 20, - color: "#F7931A", - enabled: true, - type: "TRANSFER", - chainId: null, - info: null, - }, - { - name: "GNOSIS", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "GNOSIS", symbol: "XDAI", address: null }], - logo: "https://api.rango.exchange/blockchains/gnosis.svg", - displayName: "Gnosis", - shortName: "Gnosis", - sort: 26, - color: "#3E6957", - enabled: true, - type: "EVM", - chainId: "0x64", - info: { - chainName: "Gnosis Chain", - nativeCurrency: { name: "XDAI", symbol: "XDAI", decimals: 18 }, - rpcUrls: ["https://rpc.gnosischain.com"], - blockExplorerUrls: ["https://blockscout.com/xdai/mainnet"], - addressUrl: "https://blockscout.com/xdai/mainnet/address/{wallet}", - transactionUrl: "https://blockscout.com/xdai/mainnet/tx/{txHash}", - }, - }, - { - name: "LTC", - defaultDecimals: 8, - addressPatterns: ["^(L|M|3)[A-Za-z0-9]{33}$|^(ltc1)[0-9A-Za-z]{39}$"], - feeAssets: [{ blockchain: "LTC", symbol: "LTC", address: null }], - logo: "https://api.rango.exchange/blockchains/ltc.svg", - displayName: "LiteCoin", - shortName: "LTC", - sort: 27, - color: "#345D9D", - enabled: true, - type: "TRANSFER", - chainId: null, - info: null, - }, - { - name: "BOBA", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "BOBA", symbol: "ETH", address: null }], - logo: "https://api.rango.exchange/blockchains/boba.png", - displayName: "Boba", - shortName: "Boba", - sort: 39, - color: "#ccff00", - enabled: true, - type: "EVM", - chainId: "0x120", - info: { - chainName: "Boba Network", - nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 }, - rpcUrls: ["https://mainnet.boba.network"], - blockExplorerUrls: ["https://bobascan.com/"], - addressUrl: "https://bobascan.com//address/{wallet}", - transactionUrl: "https://bobascan.com//tx/{txHash}", - }, - }, - ], - exodus: [ - { - name: "BSC", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "BSC", symbol: "BNB", address: null }], - logo: "https://api.rango.exchange/blockchains/binance.svg", - displayName: "BSC", - shortName: "BSC", - sort: 1, - color: "#F3BA2F", - enabled: true, - type: "EVM", - chainId: "0x38", - info: { - chainName: "Binance Smart Chain Mainnet", - nativeCurrency: { name: "BNB", symbol: "BNB", decimals: 18 }, - rpcUrls: ["https://bsc-dataseed1.ninicoin.io"], - blockExplorerUrls: ["https://bscscan.com"], - addressUrl: "https://bscscan.com/address/{wallet}", - transactionUrl: "https://bscscan.com/tx/{txHash}", - }, - }, - { - name: "POLYGON", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "POLYGON", symbol: "MATIC", address: null }], - logo: "https://api.rango.exchange/blockchains/polygon.svg", - displayName: "Polygon", - shortName: "Polygon", - sort: 2, - color: "#8247E5", - enabled: true, - type: "EVM", - chainId: "0x89", - info: { - chainName: "Polygon Mainnet", - nativeCurrency: { name: "MATIC", symbol: "MATIC", decimals: 18 }, - rpcUrls: ["https://polygon-rpc.com"], - blockExplorerUrls: ["https://polygonscan.com"], - addressUrl: "https://polygonscan.com/address/{wallet}", - transactionUrl: "https://polygonscan.com/tx/{txHash}", - }, - }, - { - name: "ETH", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "ETH", symbol: "ETH", address: null }], - logo: "https://api.rango.exchange/blockchains/ethereum.svg", - displayName: "Ethereum", - shortName: "ETH", - sort: 3, - color: "#ecf0f1", - enabled: true, - type: "EVM", - chainId: "0x1", - info: { - chainName: "Ethereum Mainnet", - nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 }, - rpcUrls: ["https://rpc.ankr.com/eth"], - blockExplorerUrls: ["https://etherscan.io"], - addressUrl: "https://etherscan.io/address/{wallet}", - transactionUrl: "https://etherscan.io/tx/{txHash}", - }, - }, - { - name: "AVAX_CCHAIN", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "AVAX_CCHAIN", symbol: "AVAX", address: null }], - logo: "https://api.rango.exchange/blockchains/avax_cchain.svg", - displayName: "Avalanche", - shortName: "Avax", - sort: 6, - color: "#e84142", - enabled: true, - type: "EVM", - chainId: "0xa86a", - info: { - chainName: "Avalanche C-Chain", - nativeCurrency: { name: "AVAX", symbol: "AVAX", decimals: 18 }, - rpcUrls: ["https://api.avax.network/ext/bc/C/rpc"], - blockExplorerUrls: ["https://snowtrace.io"], - addressUrl: "https://snowtrace.io/address/{wallet}", - transactionUrl: "https://snowtrace.io/tx/{txHash}", - }, - }, - { - name: "SOLANA", - defaultDecimals: 9, - addressPatterns: ["^[1-9A-HJ-NP-Za-km-z]{32,44}$"], - feeAssets: [{ blockchain: "SOLANA", symbol: "SOL", address: null }], - logo: "https://api.rango.exchange/blockchains/solana.svg", - displayName: "Solana", - shortName: "Solana", - sort: 11, - color: "#708DD2", - enabled: true, - type: "SOLANA", - chainId: "mainnet-beta", - info: null, - }, - { - name: "BNB", - defaultDecimals: 8, - addressPatterns: ["^(bnb1)[0-9a-z]{38}$"], - feeAssets: [{ blockchain: "BNB", symbol: "BNB", address: null }], - logo: "https://api.rango.exchange/blockchains/bnb.svg", - displayName: "Binance Chain", - shortName: "BNB", - sort: 18, - color: "#F3BA2F", - enabled: true, - type: "COSMOS", - chainId: null, - info: null, - }, - ], - "token-pocket": [ - { - name: "BSC", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "BSC", symbol: "BNB", address: null }], - logo: "https://api.rango.exchange/blockchains/binance.svg", - displayName: "BSC", - shortName: "BSC", - sort: 1, - color: "#F3BA2F", - enabled: true, - type: "EVM", - chainId: "0x38", - info: { - chainName: "Binance Smart Chain Mainnet", - nativeCurrency: { name: "BNB", symbol: "BNB", decimals: 18 }, - rpcUrls: ["https://bsc-dataseed1.ninicoin.io"], - blockExplorerUrls: ["https://bscscan.com"], - addressUrl: "https://bscscan.com/address/{wallet}", - transactionUrl: "https://bscscan.com/tx/{txHash}", - }, - }, - { - name: "POLYGON", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "POLYGON", symbol: "MATIC", address: null }], - logo: "https://api.rango.exchange/blockchains/polygon.svg", - displayName: "Polygon", - shortName: "Polygon", - sort: 2, - color: "#8247E5", - enabled: true, - type: "EVM", - chainId: "0x89", - info: { - chainName: "Polygon Mainnet", - nativeCurrency: { name: "MATIC", symbol: "MATIC", decimals: 18 }, - rpcUrls: ["https://polygon-rpc.com"], - blockExplorerUrls: ["https://polygonscan.com"], - addressUrl: "https://polygonscan.com/address/{wallet}", - transactionUrl: "https://polygonscan.com/tx/{txHash}", - }, - }, - { - name: "ETH", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "ETH", symbol: "ETH", address: null }], - logo: "https://api.rango.exchange/blockchains/ethereum.svg", - displayName: "Ethereum", - shortName: "ETH", - sort: 3, - color: "#ecf0f1", - enabled: true, - type: "EVM", - chainId: "0x1", - info: { - chainName: "Ethereum Mainnet", - nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 }, - rpcUrls: ["https://rpc.ankr.com/eth"], - blockExplorerUrls: ["https://etherscan.io"], - addressUrl: "https://etherscan.io/address/{wallet}", - transactionUrl: "https://etherscan.io/tx/{txHash}", - }, - }, - { - name: "AVAX_CCHAIN", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "AVAX_CCHAIN", symbol: "AVAX", address: null }], - logo: "https://api.rango.exchange/blockchains/avax_cchain.svg", - displayName: "Avalanche", - shortName: "Avax", - sort: 6, - color: "#e84142", - enabled: true, - type: "EVM", - chainId: "0xa86a", - info: { - chainName: "Avalanche C-Chain", - nativeCurrency: { name: "AVAX", symbol: "AVAX", decimals: 18 }, - rpcUrls: ["https://api.avax.network/ext/bc/C/rpc"], - blockExplorerUrls: ["https://snowtrace.io"], - addressUrl: "https://snowtrace.io/address/{wallet}", - transactionUrl: "https://snowtrace.io/tx/{txHash}", - }, - }, - { - name: "ARBITRUM", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "ARBITRUM", symbol: "ETH", address: null }], - logo: "https://api.rango.exchange/blockchains/arbitrum.svg", - displayName: "Arbitrum", - shortName: "Arbitrum", - sort: 7, - color: "#28a0f0", - enabled: true, - type: "EVM", - chainId: "0xa4b1", - info: { - chainName: "Arbitrum One", - nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 }, - rpcUrls: ["https://arb1.arbitrum.io/rpc"], - blockExplorerUrls: ["https://arbiscan.io"], - addressUrl: "https://arbiscan.io/address/{wallet}", - transactionUrl: "https://arbiscan.io/tx/{txHash}", - }, - }, - { - name: "FANTOM", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "FANTOM", symbol: "FTM", address: null }], - logo: "https://api.rango.exchange/blockchains/fantom.png", - displayName: "Fantom", - shortName: "Fantom", - sort: 9, - color: "#337afe", - enabled: true, - type: "EVM", - chainId: "0xfa", - info: { - chainName: "Fantom Opera", - nativeCurrency: { name: "FTM", symbol: "FTM", decimals: 18 }, - rpcUrls: ["https://rpc.ftm.tools"], - blockExplorerUrls: ["https://ftmscan.com"], - addressUrl: "https://ftmscan.com/address/{wallet}", - transactionUrl: "https://ftmscan.com/tx/{txHash}", - }, - }, - { - name: "OPTIMISM", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "OPTIMISM", symbol: "ETH", address: null }], - logo: "https://api.rango.exchange/blockchains/optimism.svg", - displayName: "Optimism", - shortName: "Optimism", - sort: 10, - color: "#FF0420", - enabled: true, - type: "EVM", - chainId: "0xa", - info: { - chainName: "Optimism", - nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 }, - rpcUrls: ["https://mainnet.optimism.io"], - blockExplorerUrls: ["https://optimistic.etherscan.io"], - addressUrl: "https://optimistic.etherscan.io/address/{wallet}", - transactionUrl: "https://optimistic.etherscan.io/tx/{txHash}", - }, - }, - { - name: "OKC", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "OKC", symbol: "OKT", address: null }], - logo: "https://api.rango.exchange/blockchains/okx.png", - displayName: "OKX Chain (OKC)", - shortName: "Okx", - sort: 11, - color: "#29a0f0", - enabled: true, - type: "EVM", - chainId: "0x42", - info: { - chainName: "OKX Chain", - nativeCurrency: { name: "OKT", symbol: "OKT", decimals: 18 }, - rpcUrls: ["https://exchainrpc.okex.org"], - blockExplorerUrls: ["https://www.oklink.com/en/okc"], - addressUrl: "https://www.oklink.com/en/okc/address/{wallet}", - transactionUrl: "https://www.oklink.com/en/okc/tx/{txHash}", - }, - }, - { - name: "CRONOS", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "CRONOS", symbol: "CRO", address: null }], - logo: "https://api.rango.exchange/blockchains/cronos.svg", - displayName: "Cronos", - shortName: "Cronos", - sort: 12, - color: "#1a90ff", - enabled: true, - type: "EVM", - chainId: "0x19", - info: { - chainName: "Cronos Mainnet Beta", - nativeCurrency: { name: "CRO", symbol: "CRO", decimals: 18 }, - rpcUrls: ["https://cronosrpc-1.xstaking.sg"], - blockExplorerUrls: ["https://cronoscan.com"], - addressUrl: "https://cronoscan.com/address/{wallet}", - transactionUrl: "https://cronoscan.com/tx/{txHash}", - }, - }, - { - name: "MOONRIVER", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "MOONRIVER", symbol: "MOVR", address: null }], - logo: "https://api.rango.exchange/blockchains/moonriver.svg", - displayName: "MoonRiver", - shortName: "MoonRiver", - sort: 13, - color: "#F3B404", - enabled: true, - type: "EVM", - chainId: "0x505", - info: { - chainName: "MoonRiver", - nativeCurrency: { name: "MOVR", symbol: "MOVR", decimals: 18 }, - rpcUrls: ["https://rpc.moonriver.moonbeam.network"], - blockExplorerUrls: ["https://moonriver.moonscan.io"], - addressUrl: "https://moonriver.moonscan.io/address/{wallet}", - transactionUrl: "https://moonriver.moonscan.io/tx/{txHash}", - }, - }, - { - name: "MOONBEAM", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "MOONBEAM", symbol: "GLMR", address: null }], - logo: "https://api.rango.exchange/blockchains/moonbeam.png", - displayName: "MoonBeam", - shortName: "MoonBeam", - sort: 14, - color: "#B3206B", - enabled: true, - type: "EVM", - chainId: "0x504", - info: { - chainName: "MoonBeam", - nativeCurrency: { name: "GLMR", symbol: "GLMR", decimals: 18 }, - rpcUrls: ["https://rpc.api.moonbeam.network"], - blockExplorerUrls: ["https://moonbeam.moonscan.io"], - addressUrl: "https://moonbeam.moonscan.io/address/{wallet}", - transactionUrl: "https://moonbeam.moonscan.io/tx/{txHash}", - }, - }, - { - name: "HECO", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "HECO", symbol: "HT", address: null }], - logo: "https://api.rango.exchange/blockchains/heco.png", - displayName: "Heco", - shortName: "Heco", - sort: 15, - color: "#4CA852", - enabled: true, - type: "EVM", - chainId: "0x80", - info: { - chainName: "Huobi ECO Chain Mainnet", - nativeCurrency: { name: "HT", symbol: "HT", decimals: 18 }, - rpcUrls: ["https://http-mainnet.hecochain.com"], - blockExplorerUrls: ["https://hecoinfo.com"], - addressUrl: "https://hecoinfo.com/address/{wallet}", - transactionUrl: "https://hecoinfo.com/tx/{txHash}", - }, - }, - { - name: "AURORA", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "AURORA", symbol: "ETH", address: null }], - logo: "https://api.rango.exchange/blockchains/aurora.svg", - displayName: "Aurora", - shortName: "Aurora", - sort: 15, - color: "#78d64b", - enabled: true, - type: "EVM", - chainId: "0x4e454152", - info: { - chainName: "Aurora Mainnet", - nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 }, - rpcUrls: ["https://mainnet.aurora.dev"], - blockExplorerUrls: ["https://explorer.mainnet.aurora.dev"], - addressUrl: "https://explorer.mainnet.aurora.dev/address/{wallet}", - transactionUrl: "https://explorer.mainnet.aurora.dev/tx/{txHash}", - }, - }, - { - name: "HARMONY", - defaultDecimals: 18, - addressPatterns: ["^(one1)[0-9a-z]{38}$", "^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "HARMONY", symbol: "ONE", address: null }], - logo: "https://api.rango.exchange/blockchains/harmony.svg", - displayName: "Harmony", - shortName: "Harmony", - sort: 15, - color: "#50AEE9", - enabled: true, - type: "EVM", - chainId: "0x63564c40", - info: { - chainName: "Harmony Mainnet", - nativeCurrency: { name: "ONE", symbol: "ONE", decimals: 18 }, - rpcUrls: ["https://api.s0.t.hmny.io"], - blockExplorerUrls: ["https://explorer.harmony.one"], - addressUrl: "https://explorer.harmony.one/address/{wallet}", - transactionUrl: "https://explorer.harmony.one/tx/{txHash}", - }, - }, - { - name: "EVMOS", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "EVMOS", symbol: "EVMOS", address: null }], - logo: "https://api.rango.exchange/blockchains/evmos.png", - displayName: "Evmos", - shortName: "Evmos", - sort: 15, - color: "#2D2925", - enabled: true, - type: "EVM", - chainId: "0x2329", - info: { - chainName: "Evmos", - nativeCurrency: { name: "EVMOS", symbol: "EVMOS", decimals: 18 }, - rpcUrls: ["https://eth.bd.evmos.org:8545"], - blockExplorerUrls: ["https://evm.evmos.org"], - addressUrl: "https://evm.evmos.org/address/{wallet}", - transactionUrl: "https://evm.evmos.org/tx/{txHash}", - }, - }, - { - name: "GNOSIS", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "GNOSIS", symbol: "XDAI", address: null }], - logo: "https://api.rango.exchange/blockchains/gnosis.svg", - displayName: "Gnosis", - shortName: "Gnosis", - sort: 26, - color: "#3E6957", - enabled: true, - type: "EVM", - chainId: "0x64", - info: { - chainName: "Gnosis Chain", - nativeCurrency: { name: "XDAI", symbol: "XDAI", decimals: 18 }, - rpcUrls: ["https://rpc.gnosischain.com"], - blockExplorerUrls: ["https://blockscout.com/xdai/mainnet"], - addressUrl: "https://blockscout.com/xdai/mainnet/address/{wallet}", - transactionUrl: "https://blockscout.com/xdai/mainnet/tx/{txHash}", - }, - }, - { - name: "FUSE", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "FUSE", symbol: "FUSE", address: null }], - logo: "https://api.rango.exchange/blockchains/fuse.png", - displayName: "Fuse", - shortName: "Fuse", - sort: 29, - color: "#C5F9AD", - enabled: true, - type: "EVM", - chainId: "0x7a", - info: { - chainName: "Fuse Mainnet", - nativeCurrency: { name: "FUSE", symbol: "FUSE", decimals: 18 }, - rpcUrls: ["https://rpc.fuse.io"], - blockExplorerUrls: ["https://explorer.fuse.io"], - addressUrl: "https://explorer.fuse.io/address/{wallet}", - transactionUrl: "https://explorer.fuse.io/tx/{txHash}", - }, - }, - { - name: "BOBA", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "BOBA", symbol: "ETH", address: null }], - logo: "https://api.rango.exchange/blockchains/boba.png", - displayName: "Boba", - shortName: "Boba", - sort: 39, - color: "#ccff00", - enabled: true, - type: "EVM", - chainId: "0x120", - info: { - chainName: "Boba Network", - nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 }, - rpcUrls: ["https://mainnet.boba.network"], - blockExplorerUrls: ["https://bobascan.com/"], - addressUrl: "https://bobascan.com//address/{wallet}", - transactionUrl: "https://bobascan.com//tx/{txHash}", - }, - }, - ], - "terra-station": [], - leap: [], - math: [ - { - name: "BSC", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "BSC", symbol: "BNB", address: null }], - logo: "https://api.rango.exchange/blockchains/binance.svg", - displayName: "BSC", - shortName: "BSC", - sort: 1, - color: "#F3BA2F", - enabled: true, - type: "EVM", - chainId: "0x38", - info: { - chainName: "Binance Smart Chain Mainnet", - nativeCurrency: { name: "BNB", symbol: "BNB", decimals: 18 }, - rpcUrls: ["https://bsc-dataseed1.ninicoin.io"], - blockExplorerUrls: ["https://bscscan.com"], - addressUrl: "https://bscscan.com/address/{wallet}", - transactionUrl: "https://bscscan.com/tx/{txHash}", - }, - }, - { - name: "POLYGON", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "POLYGON", symbol: "MATIC", address: null }], - logo: "https://api.rango.exchange/blockchains/polygon.svg", - displayName: "Polygon", - shortName: "Polygon", - sort: 2, - color: "#8247E5", - enabled: true, - type: "EVM", - chainId: "0x89", - info: { - chainName: "Polygon Mainnet", - nativeCurrency: { name: "MATIC", symbol: "MATIC", decimals: 18 }, - rpcUrls: ["https://polygon-rpc.com"], - blockExplorerUrls: ["https://polygonscan.com"], - addressUrl: "https://polygonscan.com/address/{wallet}", - transactionUrl: "https://polygonscan.com/tx/{txHash}", - }, - }, - { - name: "ETH", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "ETH", symbol: "ETH", address: null }], - logo: "https://api.rango.exchange/blockchains/ethereum.svg", - displayName: "Ethereum", - shortName: "ETH", - sort: 3, - color: "#ecf0f1", - enabled: true, - type: "EVM", - chainId: "0x1", - info: { - chainName: "Ethereum Mainnet", - nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 }, - rpcUrls: ["https://rpc.ankr.com/eth"], - blockExplorerUrls: ["https://etherscan.io"], - addressUrl: "https://etherscan.io/address/{wallet}", - transactionUrl: "https://etherscan.io/tx/{txHash}", - }, - }, - { - name: "AVAX_CCHAIN", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "AVAX_CCHAIN", symbol: "AVAX", address: null }], - logo: "https://api.rango.exchange/blockchains/avax_cchain.svg", - displayName: "Avalanche", - shortName: "Avax", - sort: 6, - color: "#e84142", - enabled: true, - type: "EVM", - chainId: "0xa86a", - info: { - chainName: "Avalanche C-Chain", - nativeCurrency: { name: "AVAX", symbol: "AVAX", decimals: 18 }, - rpcUrls: ["https://api.avax.network/ext/bc/C/rpc"], - blockExplorerUrls: ["https://snowtrace.io"], - addressUrl: "https://snowtrace.io/address/{wallet}", - transactionUrl: "https://snowtrace.io/tx/{txHash}", - }, - }, - { - name: "ARBITRUM", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "ARBITRUM", symbol: "ETH", address: null }], - logo: "https://api.rango.exchange/blockchains/arbitrum.svg", - displayName: "Arbitrum", - shortName: "Arbitrum", - sort: 7, - color: "#28a0f0", - enabled: true, - type: "EVM", - chainId: "0xa4b1", - info: { - chainName: "Arbitrum One", - nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 }, - rpcUrls: ["https://arb1.arbitrum.io/rpc"], - blockExplorerUrls: ["https://arbiscan.io"], - addressUrl: "https://arbiscan.io/address/{wallet}", - transactionUrl: "https://arbiscan.io/tx/{txHash}", - }, - }, - { - name: "FANTOM", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "FANTOM", symbol: "FTM", address: null }], - logo: "https://api.rango.exchange/blockchains/fantom.png", - displayName: "Fantom", - shortName: "Fantom", - sort: 9, - color: "#337afe", - enabled: true, - type: "EVM", - chainId: "0xfa", - info: { - chainName: "Fantom Opera", - nativeCurrency: { name: "FTM", symbol: "FTM", decimals: 18 }, - rpcUrls: ["https://rpc.ftm.tools"], - blockExplorerUrls: ["https://ftmscan.com"], - addressUrl: "https://ftmscan.com/address/{wallet}", - transactionUrl: "https://ftmscan.com/tx/{txHash}", - }, - }, - { - name: "OPTIMISM", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "OPTIMISM", symbol: "ETH", address: null }], - logo: "https://api.rango.exchange/blockchains/optimism.svg", - displayName: "Optimism", - shortName: "Optimism", - sort: 10, - color: "#FF0420", - enabled: true, - type: "EVM", - chainId: "0xa", - info: { - chainName: "Optimism", - nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 }, - rpcUrls: ["https://mainnet.optimism.io"], - blockExplorerUrls: ["https://optimistic.etherscan.io"], - addressUrl: "https://optimistic.etherscan.io/address/{wallet}", - transactionUrl: "https://optimistic.etherscan.io/tx/{txHash}", - }, - }, - { - name: "OKC", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "OKC", symbol: "OKT", address: null }], - logo: "https://api.rango.exchange/blockchains/okx.png", - displayName: "OKX Chain (OKC)", - shortName: "Okx", - sort: 11, - color: "#29a0f0", - enabled: true, - type: "EVM", - chainId: "0x42", - info: { - chainName: "OKX Chain", - nativeCurrency: { name: "OKT", symbol: "OKT", decimals: 18 }, - rpcUrls: ["https://exchainrpc.okex.org"], - blockExplorerUrls: ["https://www.oklink.com/en/okc"], - addressUrl: "https://www.oklink.com/en/okc/address/{wallet}", - transactionUrl: "https://www.oklink.com/en/okc/tx/{txHash}", - }, - }, - { - name: "CRONOS", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "CRONOS", symbol: "CRO", address: null }], - logo: "https://api.rango.exchange/blockchains/cronos.svg", - displayName: "Cronos", - shortName: "Cronos", - sort: 12, - color: "#1a90ff", - enabled: true, - type: "EVM", - chainId: "0x19", - info: { - chainName: "Cronos Mainnet Beta", - nativeCurrency: { name: "CRO", symbol: "CRO", decimals: 18 }, - rpcUrls: ["https://cronosrpc-1.xstaking.sg"], - blockExplorerUrls: ["https://cronoscan.com"], - addressUrl: "https://cronoscan.com/address/{wallet}", - transactionUrl: "https://cronoscan.com/tx/{txHash}", - }, - }, - { - name: "MOONRIVER", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "MOONRIVER", symbol: "MOVR", address: null }], - logo: "https://api.rango.exchange/blockchains/moonriver.svg", - displayName: "MoonRiver", - shortName: "MoonRiver", - sort: 13, - color: "#F3B404", - enabled: true, - type: "EVM", - chainId: "0x505", - info: { - chainName: "MoonRiver", - nativeCurrency: { name: "MOVR", symbol: "MOVR", decimals: 18 }, - rpcUrls: ["https://rpc.moonriver.moonbeam.network"], - blockExplorerUrls: ["https://moonriver.moonscan.io"], - addressUrl: "https://moonriver.moonscan.io/address/{wallet}", - transactionUrl: "https://moonriver.moonscan.io/tx/{txHash}", - }, - }, - { - name: "MOONBEAM", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "MOONBEAM", symbol: "GLMR", address: null }], - logo: "https://api.rango.exchange/blockchains/moonbeam.png", - displayName: "MoonBeam", - shortName: "MoonBeam", - sort: 14, - color: "#B3206B", - enabled: true, - type: "EVM", - chainId: "0x504", - info: { - chainName: "MoonBeam", - nativeCurrency: { name: "GLMR", symbol: "GLMR", decimals: 18 }, - rpcUrls: ["https://rpc.api.moonbeam.network"], - blockExplorerUrls: ["https://moonbeam.moonscan.io"], - addressUrl: "https://moonbeam.moonscan.io/address/{wallet}", - transactionUrl: "https://moonbeam.moonscan.io/tx/{txHash}", - }, - }, - { - name: "HECO", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "HECO", symbol: "HT", address: null }], - logo: "https://api.rango.exchange/blockchains/heco.png", - displayName: "Heco", - shortName: "Heco", - sort: 15, - color: "#4CA852", - enabled: true, - type: "EVM", - chainId: "0x80", - info: { - chainName: "Huobi ECO Chain Mainnet", - nativeCurrency: { name: "HT", symbol: "HT", decimals: 18 }, - rpcUrls: ["https://http-mainnet.hecochain.com"], - blockExplorerUrls: ["https://hecoinfo.com"], - addressUrl: "https://hecoinfo.com/address/{wallet}", - transactionUrl: "https://hecoinfo.com/tx/{txHash}", - }, - }, - { - name: "AURORA", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "AURORA", symbol: "ETH", address: null }], - logo: "https://api.rango.exchange/blockchains/aurora.svg", - displayName: "Aurora", - shortName: "Aurora", - sort: 15, - color: "#78d64b", - enabled: true, - type: "EVM", - chainId: "0x4e454152", - info: { - chainName: "Aurora Mainnet", - nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 }, - rpcUrls: ["https://mainnet.aurora.dev"], - blockExplorerUrls: ["https://explorer.mainnet.aurora.dev"], - addressUrl: "https://explorer.mainnet.aurora.dev/address/{wallet}", - transactionUrl: "https://explorer.mainnet.aurora.dev/tx/{txHash}", - }, - }, - { - name: "HARMONY", - defaultDecimals: 18, - addressPatterns: ["^(one1)[0-9a-z]{38}$", "^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "HARMONY", symbol: "ONE", address: null }], - logo: "https://api.rango.exchange/blockchains/harmony.svg", - displayName: "Harmony", - shortName: "Harmony", - sort: 15, - color: "#50AEE9", - enabled: true, - type: "EVM", - chainId: "0x63564c40", - info: { - chainName: "Harmony Mainnet", - nativeCurrency: { name: "ONE", symbol: "ONE", decimals: 18 }, - rpcUrls: ["https://api.s0.t.hmny.io"], - blockExplorerUrls: ["https://explorer.harmony.one"], - addressUrl: "https://explorer.harmony.one/address/{wallet}", - transactionUrl: "https://explorer.harmony.one/tx/{txHash}", - }, - }, - { - name: "EVMOS", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "EVMOS", symbol: "EVMOS", address: null }], - logo: "https://api.rango.exchange/blockchains/evmos.png", - displayName: "Evmos", - shortName: "Evmos", - sort: 15, - color: "#2D2925", - enabled: true, - type: "EVM", - chainId: "0x2329", - info: { - chainName: "Evmos", - nativeCurrency: { name: "EVMOS", symbol: "EVMOS", decimals: 18 }, - rpcUrls: ["https://eth.bd.evmos.org:8545"], - blockExplorerUrls: ["https://evm.evmos.org"], - addressUrl: "https://evm.evmos.org/address/{wallet}", - transactionUrl: "https://evm.evmos.org/tx/{txHash}", - }, - }, - { - name: "GNOSIS", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "GNOSIS", symbol: "XDAI", address: null }], - logo: "https://api.rango.exchange/blockchains/gnosis.svg", - displayName: "Gnosis", - shortName: "Gnosis", - sort: 26, - color: "#3E6957", - enabled: true, - type: "EVM", - chainId: "0x64", - info: { - chainName: "Gnosis Chain", - nativeCurrency: { name: "XDAI", symbol: "XDAI", decimals: 18 }, - rpcUrls: ["https://rpc.gnosischain.com"], - blockExplorerUrls: ["https://blockscout.com/xdai/mainnet"], - addressUrl: "https://blockscout.com/xdai/mainnet/address/{wallet}", - transactionUrl: "https://blockscout.com/xdai/mainnet/tx/{txHash}", - }, - }, - { - name: "FUSE", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "FUSE", symbol: "FUSE", address: null }], - logo: "https://api.rango.exchange/blockchains/fuse.png", - displayName: "Fuse", - shortName: "Fuse", - sort: 29, - color: "#C5F9AD", - enabled: true, - type: "EVM", - chainId: "0x7a", - info: { - chainName: "Fuse Mainnet", - nativeCurrency: { name: "FUSE", symbol: "FUSE", decimals: 18 }, - rpcUrls: ["https://rpc.fuse.io"], - blockExplorerUrls: ["https://explorer.fuse.io"], - addressUrl: "https://explorer.fuse.io/address/{wallet}", - transactionUrl: "https://explorer.fuse.io/tx/{txHash}", - }, - }, - { - name: "BOBA", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "BOBA", symbol: "ETH", address: null }], - logo: "https://api.rango.exchange/blockchains/boba.png", - displayName: "Boba", - shortName: "Boba", - sort: 39, - color: "#ccff00", - enabled: true, - type: "EVM", - chainId: "0x120", - info: { - chainName: "Boba Network", - nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 }, - rpcUrls: ["https://mainnet.boba.network"], - blockExplorerUrls: ["https://bobascan.com/"], - addressUrl: "https://bobascan.com//address/{wallet}", - transactionUrl: "https://bobascan.com//tx/{txHash}", - }, - }, - { - name: "SOLANA", - defaultDecimals: 9, - addressPatterns: ["^[1-9A-HJ-NP-Za-km-z]{32,44}$"], - feeAssets: [{ blockchain: "SOLANA", symbol: "SOL", address: null }], - logo: "https://api.rango.exchange/blockchains/solana.svg", - displayName: "Solana", - shortName: "Solana", - sort: 11, - color: "#708DD2", - enabled: true, - type: "SOLANA", - chainId: "mainnet-beta", - info: null, - }, - ], - safepal: [ - { - name: "BSC", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "BSC", symbol: "BNB", address: null }], - logo: "https://api.rango.exchange/blockchains/binance.svg", - displayName: "BSC", - shortName: "BSC", - sort: 1, - color: "#F3BA2F", - enabled: true, - type: "EVM", - chainId: "0x38", - info: { - chainName: "Binance Smart Chain Mainnet", - nativeCurrency: { name: "BNB", symbol: "BNB", decimals: 18 }, - rpcUrls: ["https://bsc-dataseed1.ninicoin.io"], - blockExplorerUrls: ["https://bscscan.com"], - addressUrl: "https://bscscan.com/address/{wallet}", - transactionUrl: "https://bscscan.com/tx/{txHash}", - }, - }, - { - name: "POLYGON", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "POLYGON", symbol: "MATIC", address: null }], - logo: "https://api.rango.exchange/blockchains/polygon.svg", - displayName: "Polygon", - shortName: "Polygon", - sort: 2, - color: "#8247E5", - enabled: true, - type: "EVM", - chainId: "0x89", - info: { - chainName: "Polygon Mainnet", - nativeCurrency: { name: "MATIC", symbol: "MATIC", decimals: 18 }, - rpcUrls: ["https://polygon-rpc.com"], - blockExplorerUrls: ["https://polygonscan.com"], - addressUrl: "https://polygonscan.com/address/{wallet}", - transactionUrl: "https://polygonscan.com/tx/{txHash}", - }, - }, - { - name: "ETH", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "ETH", symbol: "ETH", address: null }], - logo: "https://api.rango.exchange/blockchains/ethereum.svg", - displayName: "Ethereum", - shortName: "ETH", - sort: 3, - color: "#ecf0f1", - enabled: true, - type: "EVM", - chainId: "0x1", - info: { - chainName: "Ethereum Mainnet", - nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 }, - rpcUrls: ["https://rpc.ankr.com/eth"], - blockExplorerUrls: ["https://etherscan.io"], - addressUrl: "https://etherscan.io/address/{wallet}", - transactionUrl: "https://etherscan.io/tx/{txHash}", - }, - }, - { - name: "AVAX_CCHAIN", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "AVAX_CCHAIN", symbol: "AVAX", address: null }], - logo: "https://api.rango.exchange/blockchains/avax_cchain.svg", - displayName: "Avalanche", - shortName: "Avax", - sort: 6, - color: "#e84142", - enabled: true, - type: "EVM", - chainId: "0xa86a", - info: { - chainName: "Avalanche C-Chain", - nativeCurrency: { name: "AVAX", symbol: "AVAX", decimals: 18 }, - rpcUrls: ["https://api.avax.network/ext/bc/C/rpc"], - blockExplorerUrls: ["https://snowtrace.io"], - addressUrl: "https://snowtrace.io/address/{wallet}", - transactionUrl: "https://snowtrace.io/tx/{txHash}", - }, - }, - { - name: "ARBITRUM", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "ARBITRUM", symbol: "ETH", address: null }], - logo: "https://api.rango.exchange/blockchains/arbitrum.svg", - displayName: "Arbitrum", - shortName: "Arbitrum", - sort: 7, - color: "#28a0f0", - enabled: true, - type: "EVM", - chainId: "0xa4b1", - info: { - chainName: "Arbitrum One", - nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 }, - rpcUrls: ["https://arb1.arbitrum.io/rpc"], - blockExplorerUrls: ["https://arbiscan.io"], - addressUrl: "https://arbiscan.io/address/{wallet}", - transactionUrl: "https://arbiscan.io/tx/{txHash}", - }, - }, - { - name: "FANTOM", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "FANTOM", symbol: "FTM", address: null }], - logo: "https://api.rango.exchange/blockchains/fantom.png", - displayName: "Fantom", - shortName: "Fantom", - sort: 9, - color: "#337afe", - enabled: true, - type: "EVM", - chainId: "0xfa", - info: { - chainName: "Fantom Opera", - nativeCurrency: { name: "FTM", symbol: "FTM", decimals: 18 }, - rpcUrls: ["https://rpc.ftm.tools"], - blockExplorerUrls: ["https://ftmscan.com"], - addressUrl: "https://ftmscan.com/address/{wallet}", - transactionUrl: "https://ftmscan.com/tx/{txHash}", - }, - }, - { - name: "OPTIMISM", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "OPTIMISM", symbol: "ETH", address: null }], - logo: "https://api.rango.exchange/blockchains/optimism.svg", - displayName: "Optimism", - shortName: "Optimism", - sort: 10, - color: "#FF0420", - enabled: true, - type: "EVM", - chainId: "0xa", - info: { - chainName: "Optimism", - nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 }, - rpcUrls: ["https://mainnet.optimism.io"], - blockExplorerUrls: ["https://optimistic.etherscan.io"], - addressUrl: "https://optimistic.etherscan.io/address/{wallet}", - transactionUrl: "https://optimistic.etherscan.io/tx/{txHash}", - }, - }, - { - name: "OKC", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "OKC", symbol: "OKT", address: null }], - logo: "https://api.rango.exchange/blockchains/okx.png", - displayName: "OKX Chain (OKC)", - shortName: "Okx", - sort: 11, - color: "#29a0f0", - enabled: true, - type: "EVM", - chainId: "0x42", - info: { - chainName: "OKX Chain", - nativeCurrency: { name: "OKT", symbol: "OKT", decimals: 18 }, - rpcUrls: ["https://exchainrpc.okex.org"], - blockExplorerUrls: ["https://www.oklink.com/en/okc"], - addressUrl: "https://www.oklink.com/en/okc/address/{wallet}", - transactionUrl: "https://www.oklink.com/en/okc/tx/{txHash}", - }, - }, - { - name: "CRONOS", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "CRONOS", symbol: "CRO", address: null }], - logo: "https://api.rango.exchange/blockchains/cronos.svg", - displayName: "Cronos", - shortName: "Cronos", - sort: 12, - color: "#1a90ff", - enabled: true, - type: "EVM", - chainId: "0x19", - info: { - chainName: "Cronos Mainnet Beta", - nativeCurrency: { name: "CRO", symbol: "CRO", decimals: 18 }, - rpcUrls: ["https://cronosrpc-1.xstaking.sg"], - blockExplorerUrls: ["https://cronoscan.com"], - addressUrl: "https://cronoscan.com/address/{wallet}", - transactionUrl: "https://cronoscan.com/tx/{txHash}", - }, - }, - { - name: "MOONRIVER", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "MOONRIVER", symbol: "MOVR", address: null }], - logo: "https://api.rango.exchange/blockchains/moonriver.svg", - displayName: "MoonRiver", - shortName: "MoonRiver", - sort: 13, - color: "#F3B404", - enabled: true, - type: "EVM", - chainId: "0x505", - info: { - chainName: "MoonRiver", - nativeCurrency: { name: "MOVR", symbol: "MOVR", decimals: 18 }, - rpcUrls: ["https://rpc.moonriver.moonbeam.network"], - blockExplorerUrls: ["https://moonriver.moonscan.io"], - addressUrl: "https://moonriver.moonscan.io/address/{wallet}", - transactionUrl: "https://moonriver.moonscan.io/tx/{txHash}", - }, - }, - { - name: "MOONBEAM", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "MOONBEAM", symbol: "GLMR", address: null }], - logo: "https://api.rango.exchange/blockchains/moonbeam.png", - displayName: "MoonBeam", - shortName: "MoonBeam", - sort: 14, - color: "#B3206B", - enabled: true, - type: "EVM", - chainId: "0x504", - info: { - chainName: "MoonBeam", - nativeCurrency: { name: "GLMR", symbol: "GLMR", decimals: 18 }, - rpcUrls: ["https://rpc.api.moonbeam.network"], - blockExplorerUrls: ["https://moonbeam.moonscan.io"], - addressUrl: "https://moonbeam.moonscan.io/address/{wallet}", - transactionUrl: "https://moonbeam.moonscan.io/tx/{txHash}", - }, - }, - { - name: "HECO", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "HECO", symbol: "HT", address: null }], - logo: "https://api.rango.exchange/blockchains/heco.png", - displayName: "Heco", - shortName: "Heco", - sort: 15, - color: "#4CA852", - enabled: true, - type: "EVM", - chainId: "0x80", - info: { - chainName: "Huobi ECO Chain Mainnet", - nativeCurrency: { name: "HT", symbol: "HT", decimals: 18 }, - rpcUrls: ["https://http-mainnet.hecochain.com"], - blockExplorerUrls: ["https://hecoinfo.com"], - addressUrl: "https://hecoinfo.com/address/{wallet}", - transactionUrl: "https://hecoinfo.com/tx/{txHash}", - }, - }, - { - name: "AURORA", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "AURORA", symbol: "ETH", address: null }], - logo: "https://api.rango.exchange/blockchains/aurora.svg", - displayName: "Aurora", - shortName: "Aurora", - sort: 15, - color: "#78d64b", - enabled: true, - type: "EVM", - chainId: "0x4e454152", - info: { - chainName: "Aurora Mainnet", - nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 }, - rpcUrls: ["https://mainnet.aurora.dev"], - blockExplorerUrls: ["https://explorer.mainnet.aurora.dev"], - addressUrl: "https://explorer.mainnet.aurora.dev/address/{wallet}", - transactionUrl: "https://explorer.mainnet.aurora.dev/tx/{txHash}", - }, - }, - { - name: "HARMONY", - defaultDecimals: 18, - addressPatterns: ["^(one1)[0-9a-z]{38}$", "^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "HARMONY", symbol: "ONE", address: null }], - logo: "https://api.rango.exchange/blockchains/harmony.svg", - displayName: "Harmony", - shortName: "Harmony", - sort: 15, - color: "#50AEE9", - enabled: true, - type: "EVM", - chainId: "0x63564c40", - info: { - chainName: "Harmony Mainnet", - nativeCurrency: { name: "ONE", symbol: "ONE", decimals: 18 }, - rpcUrls: ["https://api.s0.t.hmny.io"], - blockExplorerUrls: ["https://explorer.harmony.one"], - addressUrl: "https://explorer.harmony.one/address/{wallet}", - transactionUrl: "https://explorer.harmony.one/tx/{txHash}", - }, - }, - { - name: "EVMOS", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "EVMOS", symbol: "EVMOS", address: null }], - logo: "https://api.rango.exchange/blockchains/evmos.png", - displayName: "Evmos", - shortName: "Evmos", - sort: 15, - color: "#2D2925", - enabled: true, - type: "EVM", - chainId: "0x2329", - info: { - chainName: "Evmos", - nativeCurrency: { name: "EVMOS", symbol: "EVMOS", decimals: 18 }, - rpcUrls: ["https://eth.bd.evmos.org:8545"], - blockExplorerUrls: ["https://evm.evmos.org"], - addressUrl: "https://evm.evmos.org/address/{wallet}", - transactionUrl: "https://evm.evmos.org/tx/{txHash}", - }, - }, - { - name: "GNOSIS", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "GNOSIS", symbol: "XDAI", address: null }], - logo: "https://api.rango.exchange/blockchains/gnosis.svg", - displayName: "Gnosis", - shortName: "Gnosis", - sort: 26, - color: "#3E6957", - enabled: true, - type: "EVM", - chainId: "0x64", - info: { - chainName: "Gnosis Chain", - nativeCurrency: { name: "XDAI", symbol: "XDAI", decimals: 18 }, - rpcUrls: ["https://rpc.gnosischain.com"], - blockExplorerUrls: ["https://blockscout.com/xdai/mainnet"], - addressUrl: "https://blockscout.com/xdai/mainnet/address/{wallet}", - transactionUrl: "https://blockscout.com/xdai/mainnet/tx/{txHash}", - }, - }, - { - name: "FUSE", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "FUSE", symbol: "FUSE", address: null }], - logo: "https://api.rango.exchange/blockchains/fuse.png", - displayName: "Fuse", - shortName: "Fuse", - sort: 29, - color: "#C5F9AD", - enabled: true, - type: "EVM", - chainId: "0x7a", - info: { - chainName: "Fuse Mainnet", - nativeCurrency: { name: "FUSE", symbol: "FUSE", decimals: 18 }, - rpcUrls: ["https://rpc.fuse.io"], - blockExplorerUrls: ["https://explorer.fuse.io"], - addressUrl: "https://explorer.fuse.io/address/{wallet}", - transactionUrl: "https://explorer.fuse.io/tx/{txHash}", - }, - }, - { - name: "BOBA", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "BOBA", symbol: "ETH", address: null }], - logo: "https://api.rango.exchange/blockchains/boba.png", - displayName: "Boba", - shortName: "Boba", - sort: 39, - color: "#ccff00", - enabled: true, - type: "EVM", - chainId: "0x120", - info: { - chainName: "Boba Network", - nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 }, - rpcUrls: ["https://mainnet.boba.network"], - blockExplorerUrls: ["https://bobascan.com/"], - addressUrl: "https://bobascan.com//address/{wallet}", - transactionUrl: "https://bobascan.com//tx/{txHash}", - }, - }, - { - name: "SOLANA", - defaultDecimals: 9, - addressPatterns: ["^[1-9A-HJ-NP-Za-km-z]{32,44}$"], - feeAssets: [{ blockchain: "SOLANA", symbol: "SOL", address: null }], - logo: "https://api.rango.exchange/blockchains/solana.svg", - displayName: "Solana", - shortName: "Solana", - sort: 11, - color: "#708DD2", - enabled: true, - type: "SOLANA", - chainId: "mainnet-beta", - info: null, - }, - ], - clover: [ - { - name: "BSC", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "BSC", symbol: "BNB", address: null }], - logo: "https://api.rango.exchange/blockchains/binance.svg", - displayName: "BSC", - shortName: "BSC", - sort: 1, - color: "#F3BA2F", - enabled: true, - type: "EVM", - chainId: "0x38", - info: { - chainName: "Binance Smart Chain Mainnet", - nativeCurrency: { name: "BNB", symbol: "BNB", decimals: 18 }, - rpcUrls: ["https://bsc-dataseed1.ninicoin.io"], - blockExplorerUrls: ["https://bscscan.com"], - addressUrl: "https://bscscan.com/address/{wallet}", - transactionUrl: "https://bscscan.com/tx/{txHash}", - }, - }, - { - name: "POLYGON", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "POLYGON", symbol: "MATIC", address: null }], - logo: "https://api.rango.exchange/blockchains/polygon.svg", - displayName: "Polygon", - shortName: "Polygon", - sort: 2, - color: "#8247E5", - enabled: true, - type: "EVM", - chainId: "0x89", - info: { - chainName: "Polygon Mainnet", - nativeCurrency: { name: "MATIC", symbol: "MATIC", decimals: 18 }, - rpcUrls: ["https://polygon-rpc.com"], - blockExplorerUrls: ["https://polygonscan.com"], - addressUrl: "https://polygonscan.com/address/{wallet}", - transactionUrl: "https://polygonscan.com/tx/{txHash}", - }, - }, - { - name: "ETH", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "ETH", symbol: "ETH", address: null }], - logo: "https://api.rango.exchange/blockchains/ethereum.svg", - displayName: "Ethereum", - shortName: "ETH", - sort: 3, - color: "#ecf0f1", - enabled: true, - type: "EVM", - chainId: "0x1", - info: { - chainName: "Ethereum Mainnet", - nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 }, - rpcUrls: ["https://rpc.ankr.com/eth"], - blockExplorerUrls: ["https://etherscan.io"], - addressUrl: "https://etherscan.io/address/{wallet}", - transactionUrl: "https://etherscan.io/tx/{txHash}", - }, - }, - { - name: "AVAX_CCHAIN", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "AVAX_CCHAIN", symbol: "AVAX", address: null }], - logo: "https://api.rango.exchange/blockchains/avax_cchain.svg", - displayName: "Avalanche", - shortName: "Avax", - sort: 6, - color: "#e84142", - enabled: true, - type: "EVM", - chainId: "0xa86a", - info: { - chainName: "Avalanche C-Chain", - nativeCurrency: { name: "AVAX", symbol: "AVAX", decimals: 18 }, - rpcUrls: ["https://api.avax.network/ext/bc/C/rpc"], - blockExplorerUrls: ["https://snowtrace.io"], - addressUrl: "https://snowtrace.io/address/{wallet}", - transactionUrl: "https://snowtrace.io/tx/{txHash}", - }, - }, - { - name: "ARBITRUM", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "ARBITRUM", symbol: "ETH", address: null }], - logo: "https://api.rango.exchange/blockchains/arbitrum.svg", - displayName: "Arbitrum", - shortName: "Arbitrum", - sort: 7, - color: "#28a0f0", - enabled: true, - type: "EVM", - chainId: "0xa4b1", - info: { - chainName: "Arbitrum One", - nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 }, - rpcUrls: ["https://arb1.arbitrum.io/rpc"], - blockExplorerUrls: ["https://arbiscan.io"], - addressUrl: "https://arbiscan.io/address/{wallet}", - transactionUrl: "https://arbiscan.io/tx/{txHash}", - }, - }, - { - name: "FANTOM", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "FANTOM", symbol: "FTM", address: null }], - logo: "https://api.rango.exchange/blockchains/fantom.png", - displayName: "Fantom", - shortName: "Fantom", - sort: 9, - color: "#337afe", - enabled: true, - type: "EVM", - chainId: "0xfa", - info: { - chainName: "Fantom Opera", - nativeCurrency: { name: "FTM", symbol: "FTM", decimals: 18 }, - rpcUrls: ["https://rpc.ftm.tools"], - blockExplorerUrls: ["https://ftmscan.com"], - addressUrl: "https://ftmscan.com/address/{wallet}", - transactionUrl: "https://ftmscan.com/tx/{txHash}", - }, - }, - { - name: "OPTIMISM", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "OPTIMISM", symbol: "ETH", address: null }], - logo: "https://api.rango.exchange/blockchains/optimism.svg", - displayName: "Optimism", - shortName: "Optimism", - sort: 10, - color: "#FF0420", - enabled: true, - type: "EVM", - chainId: "0xa", - info: { - chainName: "Optimism", - nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 }, - rpcUrls: ["https://mainnet.optimism.io"], - blockExplorerUrls: ["https://optimistic.etherscan.io"], - addressUrl: "https://optimistic.etherscan.io/address/{wallet}", - transactionUrl: "https://optimistic.etherscan.io/tx/{txHash}", - }, - }, - { - name: "OKC", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "OKC", symbol: "OKT", address: null }], - logo: "https://api.rango.exchange/blockchains/okx.png", - displayName: "OKX Chain (OKC)", - shortName: "Okx", - sort: 11, - color: "#29a0f0", - enabled: true, - type: "EVM", - chainId: "0x42", - info: { - chainName: "OKX Chain", - nativeCurrency: { name: "OKT", symbol: "OKT", decimals: 18 }, - rpcUrls: ["https://exchainrpc.okex.org"], - blockExplorerUrls: ["https://www.oklink.com/en/okc"], - addressUrl: "https://www.oklink.com/en/okc/address/{wallet}", - transactionUrl: "https://www.oklink.com/en/okc/tx/{txHash}", - }, - }, - { - name: "CRONOS", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "CRONOS", symbol: "CRO", address: null }], - logo: "https://api.rango.exchange/blockchains/cronos.svg", - displayName: "Cronos", - shortName: "Cronos", - sort: 12, - color: "#1a90ff", - enabled: true, - type: "EVM", - chainId: "0x19", - info: { - chainName: "Cronos Mainnet Beta", - nativeCurrency: { name: "CRO", symbol: "CRO", decimals: 18 }, - rpcUrls: ["https://cronosrpc-1.xstaking.sg"], - blockExplorerUrls: ["https://cronoscan.com"], - addressUrl: "https://cronoscan.com/address/{wallet}", - transactionUrl: "https://cronoscan.com/tx/{txHash}", - }, - }, - { - name: "MOONRIVER", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "MOONRIVER", symbol: "MOVR", address: null }], - logo: "https://api.rango.exchange/blockchains/moonriver.svg", - displayName: "MoonRiver", - shortName: "MoonRiver", - sort: 13, - color: "#F3B404", - enabled: true, - type: "EVM", - chainId: "0x505", - info: { - chainName: "MoonRiver", - nativeCurrency: { name: "MOVR", symbol: "MOVR", decimals: 18 }, - rpcUrls: ["https://rpc.moonriver.moonbeam.network"], - blockExplorerUrls: ["https://moonriver.moonscan.io"], - addressUrl: "https://moonriver.moonscan.io/address/{wallet}", - transactionUrl: "https://moonriver.moonscan.io/tx/{txHash}", - }, - }, - { - name: "MOONBEAM", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "MOONBEAM", symbol: "GLMR", address: null }], - logo: "https://api.rango.exchange/blockchains/moonbeam.png", - displayName: "MoonBeam", - shortName: "MoonBeam", - sort: 14, - color: "#B3206B", - enabled: true, - type: "EVM", - chainId: "0x504", - info: { - chainName: "MoonBeam", - nativeCurrency: { name: "GLMR", symbol: "GLMR", decimals: 18 }, - rpcUrls: ["https://rpc.api.moonbeam.network"], - blockExplorerUrls: ["https://moonbeam.moonscan.io"], - addressUrl: "https://moonbeam.moonscan.io/address/{wallet}", - transactionUrl: "https://moonbeam.moonscan.io/tx/{txHash}", - }, - }, - { - name: "HECO", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "HECO", symbol: "HT", address: null }], - logo: "https://api.rango.exchange/blockchains/heco.png", - displayName: "Heco", - shortName: "Heco", - sort: 15, - color: "#4CA852", - enabled: true, - type: "EVM", - chainId: "0x80", - info: { - chainName: "Huobi ECO Chain Mainnet", - nativeCurrency: { name: "HT", symbol: "HT", decimals: 18 }, - rpcUrls: ["https://http-mainnet.hecochain.com"], - blockExplorerUrls: ["https://hecoinfo.com"], - addressUrl: "https://hecoinfo.com/address/{wallet}", - transactionUrl: "https://hecoinfo.com/tx/{txHash}", - }, - }, - { - name: "AURORA", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "AURORA", symbol: "ETH", address: null }], - logo: "https://api.rango.exchange/blockchains/aurora.svg", - displayName: "Aurora", - shortName: "Aurora", - sort: 15, - color: "#78d64b", - enabled: true, - type: "EVM", - chainId: "0x4e454152", - info: { - chainName: "Aurora Mainnet", - nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 }, - rpcUrls: ["https://mainnet.aurora.dev"], - blockExplorerUrls: ["https://explorer.mainnet.aurora.dev"], - addressUrl: "https://explorer.mainnet.aurora.dev/address/{wallet}", - transactionUrl: "https://explorer.mainnet.aurora.dev/tx/{txHash}", - }, - }, - { - name: "HARMONY", - defaultDecimals: 18, - addressPatterns: ["^(one1)[0-9a-z]{38}$", "^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "HARMONY", symbol: "ONE", address: null }], - logo: "https://api.rango.exchange/blockchains/harmony.svg", - displayName: "Harmony", - shortName: "Harmony", - sort: 15, - color: "#50AEE9", - enabled: true, - type: "EVM", - chainId: "0x63564c40", - info: { - chainName: "Harmony Mainnet", - nativeCurrency: { name: "ONE", symbol: "ONE", decimals: 18 }, - rpcUrls: ["https://api.s0.t.hmny.io"], - blockExplorerUrls: ["https://explorer.harmony.one"], - addressUrl: "https://explorer.harmony.one/address/{wallet}", - transactionUrl: "https://explorer.harmony.one/tx/{txHash}", - }, - }, - { - name: "EVMOS", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "EVMOS", symbol: "EVMOS", address: null }], - logo: "https://api.rango.exchange/blockchains/evmos.png", - displayName: "Evmos", - shortName: "Evmos", - sort: 15, - color: "#2D2925", - enabled: true, - type: "EVM", - chainId: "0x2329", - info: { - chainName: "Evmos", - nativeCurrency: { name: "EVMOS", symbol: "EVMOS", decimals: 18 }, - rpcUrls: ["https://eth.bd.evmos.org:8545"], - blockExplorerUrls: ["https://evm.evmos.org"], - addressUrl: "https://evm.evmos.org/address/{wallet}", - transactionUrl: "https://evm.evmos.org/tx/{txHash}", - }, - }, - { - name: "GNOSIS", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "GNOSIS", symbol: "XDAI", address: null }], - logo: "https://api.rango.exchange/blockchains/gnosis.svg", - displayName: "Gnosis", - shortName: "Gnosis", - sort: 26, - color: "#3E6957", - enabled: true, - type: "EVM", - chainId: "0x64", - info: { - chainName: "Gnosis Chain", - nativeCurrency: { name: "XDAI", symbol: "XDAI", decimals: 18 }, - rpcUrls: ["https://rpc.gnosischain.com"], - blockExplorerUrls: ["https://blockscout.com/xdai/mainnet"], - addressUrl: "https://blockscout.com/xdai/mainnet/address/{wallet}", - transactionUrl: "https://blockscout.com/xdai/mainnet/tx/{txHash}", - }, - }, - { - name: "FUSE", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "FUSE", symbol: "FUSE", address: null }], - logo: "https://api.rango.exchange/blockchains/fuse.png", - displayName: "Fuse", - shortName: "Fuse", - sort: 29, - color: "#C5F9AD", - enabled: true, - type: "EVM", - chainId: "0x7a", - info: { - chainName: "Fuse Mainnet", - nativeCurrency: { name: "FUSE", symbol: "FUSE", decimals: 18 }, - rpcUrls: ["https://rpc.fuse.io"], - blockExplorerUrls: ["https://explorer.fuse.io"], - addressUrl: "https://explorer.fuse.io/address/{wallet}", - transactionUrl: "https://explorer.fuse.io/tx/{txHash}", - }, - }, - { - name: "BOBA", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "BOBA", symbol: "ETH", address: null }], - logo: "https://api.rango.exchange/blockchains/boba.png", - displayName: "Boba", - shortName: "Boba", - sort: 39, - color: "#ccff00", - enabled: true, - type: "EVM", - chainId: "0x120", - info: { - chainName: "Boba Network", - nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 }, - rpcUrls: ["https://mainnet.boba.network"], - blockExplorerUrls: ["https://bobascan.com/"], - addressUrl: "https://bobascan.com//address/{wallet}", - transactionUrl: "https://bobascan.com//tx/{txHash}", - }, - }, - { - name: "SOLANA", - defaultDecimals: 9, - addressPatterns: ["^[1-9A-HJ-NP-Za-km-z]{32,44}$"], - feeAssets: [{ blockchain: "SOLANA", symbol: "SOL", address: null }], - logo: "https://api.rango.exchange/blockchains/solana.svg", - displayName: "Solana", - shortName: "Solana", - sort: 11, - color: "#708DD2", - enabled: true, - type: "SOLANA", - chainId: "mainnet-beta", - info: null, - }, - ], - cosmostation: [ - { - name: "BSC", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "BSC", symbol: "BNB", address: null }], - logo: "https://api.rango.exchange/blockchains/binance.svg", - displayName: "BSC", - shortName: "BSC", - sort: 1, - color: "#F3BA2F", - enabled: true, - type: "EVM", - chainId: "0x38", - info: { - chainName: "Binance Smart Chain Mainnet", - nativeCurrency: { name: "BNB", symbol: "BNB", decimals: 18 }, - rpcUrls: ["https://bsc-dataseed1.ninicoin.io"], - blockExplorerUrls: ["https://bscscan.com"], - addressUrl: "https://bscscan.com/address/{wallet}", - transactionUrl: "https://bscscan.com/tx/{txHash}", - }, - }, - { - name: "POLYGON", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "POLYGON", symbol: "MATIC", address: null }], - logo: "https://api.rango.exchange/blockchains/polygon.svg", - displayName: "Polygon", - shortName: "Polygon", - sort: 2, - color: "#8247E5", - enabled: true, - type: "EVM", - chainId: "0x89", - info: { - chainName: "Polygon Mainnet", - nativeCurrency: { name: "MATIC", symbol: "MATIC", decimals: 18 }, - rpcUrls: ["https://polygon-rpc.com"], - blockExplorerUrls: ["https://polygonscan.com"], - addressUrl: "https://polygonscan.com/address/{wallet}", - transactionUrl: "https://polygonscan.com/tx/{txHash}", - }, - }, - { - name: "ETH", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "ETH", symbol: "ETH", address: null }], - logo: "https://api.rango.exchange/blockchains/ethereum.svg", - displayName: "Ethereum", - shortName: "ETH", - sort: 3, - color: "#ecf0f1", - enabled: true, - type: "EVM", - chainId: "0x1", - info: { - chainName: "Ethereum Mainnet", - nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 }, - rpcUrls: ["https://rpc.ankr.com/eth"], - blockExplorerUrls: ["https://etherscan.io"], - addressUrl: "https://etherscan.io/address/{wallet}", - transactionUrl: "https://etherscan.io/tx/{txHash}", - }, - }, - { - name: "AVAX_CCHAIN", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "AVAX_CCHAIN", symbol: "AVAX", address: null }], - logo: "https://api.rango.exchange/blockchains/avax_cchain.svg", - displayName: "Avalanche", - shortName: "Avax", - sort: 6, - color: "#e84142", - enabled: true, - type: "EVM", - chainId: "0xa86a", - info: { - chainName: "Avalanche C-Chain", - nativeCurrency: { name: "AVAX", symbol: "AVAX", decimals: 18 }, - rpcUrls: ["https://api.avax.network/ext/bc/C/rpc"], - blockExplorerUrls: ["https://snowtrace.io"], - addressUrl: "https://snowtrace.io/address/{wallet}", - transactionUrl: "https://snowtrace.io/tx/{txHash}", - }, - }, - { - name: "ARBITRUM", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "ARBITRUM", symbol: "ETH", address: null }], - logo: "https://api.rango.exchange/blockchains/arbitrum.svg", - displayName: "Arbitrum", - shortName: "Arbitrum", - sort: 7, - color: "#28a0f0", - enabled: true, - type: "EVM", - chainId: "0xa4b1", - info: { - chainName: "Arbitrum One", - nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 }, - rpcUrls: ["https://arb1.arbitrum.io/rpc"], - blockExplorerUrls: ["https://arbiscan.io"], - addressUrl: "https://arbiscan.io/address/{wallet}", - transactionUrl: "https://arbiscan.io/tx/{txHash}", - }, - }, - { - name: "FANTOM", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "FANTOM", symbol: "FTM", address: null }], - logo: "https://api.rango.exchange/blockchains/fantom.png", - displayName: "Fantom", - shortName: "Fantom", - sort: 9, - color: "#337afe", - enabled: true, - type: "EVM", - chainId: "0xfa", - info: { - chainName: "Fantom Opera", - nativeCurrency: { name: "FTM", symbol: "FTM", decimals: 18 }, - rpcUrls: ["https://rpc.ftm.tools"], - blockExplorerUrls: ["https://ftmscan.com"], - addressUrl: "https://ftmscan.com/address/{wallet}", - transactionUrl: "https://ftmscan.com/tx/{txHash}", - }, - }, - { - name: "OPTIMISM", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "OPTIMISM", symbol: "ETH", address: null }], - logo: "https://api.rango.exchange/blockchains/optimism.svg", - displayName: "Optimism", - shortName: "Optimism", - sort: 10, - color: "#FF0420", - enabled: true, - type: "EVM", - chainId: "0xa", - info: { - chainName: "Optimism", - nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 }, - rpcUrls: ["https://mainnet.optimism.io"], - blockExplorerUrls: ["https://optimistic.etherscan.io"], - addressUrl: "https://optimistic.etherscan.io/address/{wallet}", - transactionUrl: "https://optimistic.etherscan.io/tx/{txHash}", - }, - }, - { - name: "OKC", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "OKC", symbol: "OKT", address: null }], - logo: "https://api.rango.exchange/blockchains/okx.png", - displayName: "OKX Chain (OKC)", - shortName: "Okx", - sort: 11, - color: "#29a0f0", - enabled: true, - type: "EVM", - chainId: "0x42", - info: { - chainName: "OKX Chain", - nativeCurrency: { name: "OKT", symbol: "OKT", decimals: 18 }, - rpcUrls: ["https://exchainrpc.okex.org"], - blockExplorerUrls: ["https://www.oklink.com/en/okc"], - addressUrl: "https://www.oklink.com/en/okc/address/{wallet}", - transactionUrl: "https://www.oklink.com/en/okc/tx/{txHash}", - }, - }, - { - name: "CRONOS", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "CRONOS", symbol: "CRO", address: null }], - logo: "https://api.rango.exchange/blockchains/cronos.svg", - displayName: "Cronos", - shortName: "Cronos", - sort: 12, - color: "#1a90ff", - enabled: true, - type: "EVM", - chainId: "0x19", - info: { - chainName: "Cronos Mainnet Beta", - nativeCurrency: { name: "CRO", symbol: "CRO", decimals: 18 }, - rpcUrls: ["https://cronosrpc-1.xstaking.sg"], - blockExplorerUrls: ["https://cronoscan.com"], - addressUrl: "https://cronoscan.com/address/{wallet}", - transactionUrl: "https://cronoscan.com/tx/{txHash}", - }, - }, - { - name: "MOONRIVER", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "MOONRIVER", symbol: "MOVR", address: null }], - logo: "https://api.rango.exchange/blockchains/moonriver.svg", - displayName: "MoonRiver", - shortName: "MoonRiver", - sort: 13, - color: "#F3B404", - enabled: true, - type: "EVM", - chainId: "0x505", - info: { - chainName: "MoonRiver", - nativeCurrency: { name: "MOVR", symbol: "MOVR", decimals: 18 }, - rpcUrls: ["https://rpc.moonriver.moonbeam.network"], - blockExplorerUrls: ["https://moonriver.moonscan.io"], - addressUrl: "https://moonriver.moonscan.io/address/{wallet}", - transactionUrl: "https://moonriver.moonscan.io/tx/{txHash}", - }, - }, - { - name: "MOONBEAM", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "MOONBEAM", symbol: "GLMR", address: null }], - logo: "https://api.rango.exchange/blockchains/moonbeam.png", - displayName: "MoonBeam", - shortName: "MoonBeam", - sort: 14, - color: "#B3206B", - enabled: true, - type: "EVM", - chainId: "0x504", - info: { - chainName: "MoonBeam", - nativeCurrency: { name: "GLMR", symbol: "GLMR", decimals: 18 }, - rpcUrls: ["https://rpc.api.moonbeam.network"], - blockExplorerUrls: ["https://moonbeam.moonscan.io"], - addressUrl: "https://moonbeam.moonscan.io/address/{wallet}", - transactionUrl: "https://moonbeam.moonscan.io/tx/{txHash}", - }, - }, - { - name: "HECO", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "HECO", symbol: "HT", address: null }], - logo: "https://api.rango.exchange/blockchains/heco.png", - displayName: "Heco", - shortName: "Heco", - sort: 15, - color: "#4CA852", - enabled: true, - type: "EVM", - chainId: "0x80", - info: { - chainName: "Huobi ECO Chain Mainnet", - nativeCurrency: { name: "HT", symbol: "HT", decimals: 18 }, - rpcUrls: ["https://http-mainnet.hecochain.com"], - blockExplorerUrls: ["https://hecoinfo.com"], - addressUrl: "https://hecoinfo.com/address/{wallet}", - transactionUrl: "https://hecoinfo.com/tx/{txHash}", - }, - }, - { - name: "AURORA", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "AURORA", symbol: "ETH", address: null }], - logo: "https://api.rango.exchange/blockchains/aurora.svg", - displayName: "Aurora", - shortName: "Aurora", - sort: 15, - color: "#78d64b", - enabled: true, - type: "EVM", - chainId: "0x4e454152", - info: { - chainName: "Aurora Mainnet", - nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 }, - rpcUrls: ["https://mainnet.aurora.dev"], - blockExplorerUrls: ["https://explorer.mainnet.aurora.dev"], - addressUrl: "https://explorer.mainnet.aurora.dev/address/{wallet}", - transactionUrl: "https://explorer.mainnet.aurora.dev/tx/{txHash}", - }, - }, - { - name: "HARMONY", - defaultDecimals: 18, - addressPatterns: ["^(one1)[0-9a-z]{38}$", "^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "HARMONY", symbol: "ONE", address: null }], - logo: "https://api.rango.exchange/blockchains/harmony.svg", - displayName: "Harmony", - shortName: "Harmony", - sort: 15, - color: "#50AEE9", - enabled: true, - type: "EVM", - chainId: "0x63564c40", - info: { - chainName: "Harmony Mainnet", - nativeCurrency: { name: "ONE", symbol: "ONE", decimals: 18 }, - rpcUrls: ["https://api.s0.t.hmny.io"], - blockExplorerUrls: ["https://explorer.harmony.one"], - addressUrl: "https://explorer.harmony.one/address/{wallet}", - transactionUrl: "https://explorer.harmony.one/tx/{txHash}", - }, - }, - { - name: "EVMOS", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "EVMOS", symbol: "EVMOS", address: null }], - logo: "https://api.rango.exchange/blockchains/evmos.png", - displayName: "Evmos", - shortName: "Evmos", - sort: 15, - color: "#2D2925", - enabled: true, - type: "EVM", - chainId: "0x2329", - info: { - chainName: "Evmos", - nativeCurrency: { name: "EVMOS", symbol: "EVMOS", decimals: 18 }, - rpcUrls: ["https://eth.bd.evmos.org:8545"], - blockExplorerUrls: ["https://evm.evmos.org"], - addressUrl: "https://evm.evmos.org/address/{wallet}", - transactionUrl: "https://evm.evmos.org/tx/{txHash}", - }, - }, - { - name: "GNOSIS", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "GNOSIS", symbol: "XDAI", address: null }], - logo: "https://api.rango.exchange/blockchains/gnosis.svg", - displayName: "Gnosis", - shortName: "Gnosis", - sort: 26, - color: "#3E6957", - enabled: true, - type: "EVM", - chainId: "0x64", - info: { - chainName: "Gnosis Chain", - nativeCurrency: { name: "XDAI", symbol: "XDAI", decimals: 18 }, - rpcUrls: ["https://rpc.gnosischain.com"], - blockExplorerUrls: ["https://blockscout.com/xdai/mainnet"], - addressUrl: "https://blockscout.com/xdai/mainnet/address/{wallet}", - transactionUrl: "https://blockscout.com/xdai/mainnet/tx/{txHash}", - }, - }, - { - name: "FUSE", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "FUSE", symbol: "FUSE", address: null }], - logo: "https://api.rango.exchange/blockchains/fuse.png", - displayName: "Fuse", - shortName: "Fuse", - sort: 29, - color: "#C5F9AD", - enabled: true, - type: "EVM", - chainId: "0x7a", - info: { - chainName: "Fuse Mainnet", - nativeCurrency: { name: "FUSE", symbol: "FUSE", decimals: 18 }, - rpcUrls: ["https://rpc.fuse.io"], - blockExplorerUrls: ["https://explorer.fuse.io"], - addressUrl: "https://explorer.fuse.io/address/{wallet}", - transactionUrl: "https://explorer.fuse.io/tx/{txHash}", - }, - }, - { - name: "BOBA", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "BOBA", symbol: "ETH", address: null }], - logo: "https://api.rango.exchange/blockchains/boba.png", - displayName: "Boba", - shortName: "Boba", - sort: 39, - color: "#ccff00", - enabled: true, - type: "EVM", - chainId: "0x120", - info: { - chainName: "Boba Network", - nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 }, - rpcUrls: ["https://mainnet.boba.network"], - blockExplorerUrls: ["https://bobascan.com/"], - addressUrl: "https://bobascan.com//address/{wallet}", - transactionUrl: "https://bobascan.com//tx/{txHash}", - }, - }, - { - name: "OSMOSIS", - defaultDecimals: 6, - addressPatterns: ["^(osmo1)[0-9a-z]{38}$"], - feeAssets: [{ blockchain: "OSMOSIS", symbol: "OSMO", address: null }], - logo: "https://api.rango.exchange/blockchains/osmosis.svg", - displayName: "Osmosis", - shortName: "Osmosis", - sort: 4, - color: "#7901B4", - enabled: true, - type: "COSMOS", - chainId: "osmosis-1", - info: { - experimental: false, - rpc: "https://rpc-osmosis.keplr.app", - rest: "https://lcd-osmosis.keplr.app", - cosmostationLcdUrl: "https://lcd-osmosis.cosmostation.io", - cosmostationApiUrl: "https://api-osmosis.cosmostation.io", - cosmostationDenomTracePath: "/ibc/apps/transfer/v1/denom_traces/", - mintScanName: "osmosis", - chainName: "Osmosis", - stakeCurrency: { - coinDenom: "OSMO", - coinMinimalDenom: "uosmo", - coinDecimals: 6, - coinGeckoId: "pool:uosmo", - coinImageUrl: "/tokens/blockchain/osmosis.svg", - }, - bip44: { coinType: 118 }, - bech32Config: { - bech32PrefixAccAddr: "osmo", - bech32PrefixAccPub: "osmopub", - bech32PrefixValAddr: "osmovaloper", - bech32PrefixValPub: "osmovaloperpub", - bech32PrefixConsAddr: "osmovalcons", - bech32PrefixConsPub: "osmovalconspub", - }, - currencies: [ - { - coinDenom: "OSMO", - coinMinimalDenom: "uosmo", - coinDecimals: 6, - coinGeckoId: "pool:uosmo", - coinImageUrl: "/tokens/blockchain/osmosis.svg", - }, - { - coinDenom: "ION", - coinMinimalDenom: "uion", - coinDecimals: 6, - coinGeckoId: "pool:uion", - coinImageUrl: "/tokens/blockchain/ion.png", - }, - ], - feeCurrencies: [ - { - coinDenom: "OSMO", - coinMinimalDenom: "uosmo", - coinDecimals: 6, - coinGeckoId: "pool:uosmo", - coinImageUrl: "/tokens/blockchain/osmosis.svg", - }, - ], - features: ["stargate", "ibc-transfer"], - explorerUrlToTx: "https://www.mintscan.io/osmosis/txs/{txHash}", - gasPriceStep: { low: 0, average: 0.025, high: 0.04 }, - }, - }, - { - name: "JUNO", - defaultDecimals: 6, - addressPatterns: ["^(juno1)[0-9a-z]{38}$"], - feeAssets: [{ blockchain: "JUNO", symbol: "JUNO", address: null }], - logo: "https://api.rango.exchange/blockchains/juno.svg", - displayName: "Juno", - shortName: "Juno", - sort: 5, - color: "#f0827d", - enabled: true, - type: "COSMOS", - chainId: "juno-1", - info: { - experimental: false, - rpc: "https://rpc-juno.itastakers.com:443/", - rest: "https://lcd-juno.keplr.app", - cosmostationLcdUrl: "https://lcd-juno.cosmostation.io", - cosmostationApiUrl: "https://api-juno.cosmostation.io", - cosmostationDenomTracePath: "/ibc/apps/transfer/v1/denom_traces/", - mintScanName: "juno", - chainName: "Juno", - stakeCurrency: { - coinDenom: "JUNO", - coinMinimalDenom: "ujuno", - coinDecimals: 6, - coinGeckoId: "juno-network", - coinImageUrl: "/tokens/blockchain/JUNO.png", - }, - bip44: { coinType: 118 }, - bech32Config: { - bech32PrefixAccAddr: "juno", - bech32PrefixAccPub: "junopub", - bech32PrefixValAddr: "junovaloper", - bech32PrefixValPub: "junovaloperpub", - bech32PrefixConsAddr: "junovalcons", - bech32PrefixConsPub: "junovalconspub", - }, - currencies: [ - { - coinDenom: "JUNO", - coinMinimalDenom: "ujuno", - coinDecimals: 6, - coinGeckoId: "juno-network", - coinImageUrl: "/tokens/blockchain/JUNO.png", - }, - ], - feeCurrencies: [ - { - coinDenom: "JUNO", - coinMinimalDenom: "ujuno", - coinDecimals: 6, - coinGeckoId: "juno-network", - coinImageUrl: "/tokens/blockchain/JUNO.png", - }, - ], - features: ["stargate", "ibc-transfer"], - explorerUrlToTx: "https://www.mintscan.io/juno/txs/{txHash}", - gasPriceStep: { low: 0.001, average: 0.0025, high: 0.004 }, - }, - }, - { - name: "COSMOS", - defaultDecimals: 6, - addressPatterns: ["^(cosmos1)[0-9a-z]{38}$"], - feeAssets: [{ blockchain: "COSMOS", symbol: "ATOM", address: null }], - logo: "https://api.rango.exchange/blockchains/cosmos.svg", - displayName: "Cosmos", - shortName: "Cosmos", - sort: 8, - color: "#2E3148", - enabled: true, - type: "COSMOS", - chainId: "cosmoshub-4", - info: { - experimental: false, - rpc: "https://cosmos-rpc.polkachu.com", - rest: "https://lcd-cosmoshub.keplr.app", - cosmostationLcdUrl: "https://lcd-cosmos.cosmostation.io", - cosmostationApiUrl: "https://api-cosmos.cosmostation.io", - cosmostationDenomTracePath: "/ibc/apps/transfer/v1/denom_traces/", - mintScanName: "cosmos", - chainName: "Cosmos", - stakeCurrency: { - coinDenom: "ATOM", - coinMinimalDenom: "uatom", - coinDecimals: 6, - coinGeckoId: "cosmos", - coinImageUrl: "/tokens/blockchain/cosmos.svg", - }, - bip44: { coinType: 118 }, - bech32Config: { - bech32PrefixAccAddr: "cosmos", - bech32PrefixAccPub: "cosmospub", - bech32PrefixValAddr: "cosmosvaloper", - bech32PrefixValPub: "cosmosvaloperpub", - bech32PrefixConsAddr: "cosmosvalcons", - bech32PrefixConsPub: "cosmosvalconspub", - }, - currencies: [ - { - coinDenom: "ATOM", - coinMinimalDenom: "uatom", - coinDecimals: 6, - coinGeckoId: "cosmos", - coinImageUrl: "/tokens/blockchain/cosmos.svg", - }, - ], - feeCurrencies: [ - { - coinDenom: "ATOM", - coinMinimalDenom: "uatom", - coinDecimals: 6, - coinGeckoId: "cosmos", - coinImageUrl: "/tokens/blockchain/cosmos.svg", - }, - ], - features: ["stargate", "ibc-transfer"], - explorerUrlToTx: "https://www.mintscan.io/cosmos/txs/{txHash}", - gasPriceStep: { low: 0.01, average: 0.025, high: 0.04 }, - }, - }, - { - name: "SIF", - defaultDecimals: 18, - addressPatterns: ["^(sif1)[0-9a-z]{38}$"], - feeAssets: [{ blockchain: "SIF", symbol: "ROWAN", address: null }], - logo: "https://api.rango.exchange/blockchains/sif.png", - displayName: "Sifchain", - shortName: "Sifchain", - sort: 16, - color: "#CAAA3A", - enabled: true, - type: "COSMOS", - chainId: "sifchain-1", - info: { - experimental: false, - rpc: "https://rpc.sifchain.finance", - rest: "https://api-int.sifchain.finance", - cosmostationLcdUrl: "https://lcd-sifchain.cosmostation.io", - cosmostationApiUrl: "https://api-sifchain.cosmostation.io", - cosmostationDenomTracePath: "/ibc/apps/transfer/v1/denom_traces/", - mintScanName: "sifchain", - chainName: "Sifchain", - stakeCurrency: { - coinDenom: "ROWAN", - coinMinimalDenom: "rowan", - coinDecimals: 18, - coinGeckoId: "", - coinImageUrl: "", - }, - bip44: { coinType: 118 }, - bech32Config: { - bech32PrefixAccAddr: "sif", - bech32PrefixAccPub: "sifpub", - bech32PrefixValAddr: "sifvaloper", - bech32PrefixValPub: "sifvaloperpub", - bech32PrefixConsAddr: "sifvalcons", - bech32PrefixConsPub: "sifvalconspub", - }, - currencies: [ - { - coinDenom: "ROWAN", - coinMinimalDenom: "rowan", - coinDecimals: 18, - coinGeckoId: "", - coinImageUrl: "", - }, - ], - feeCurrencies: [ - { - coinDenom: "ROWAN", - coinMinimalDenom: "rowan", - coinDecimals: 18, - coinGeckoId: "", - coinImageUrl: "", - }, - ], - features: ["stargate", "ibc-transfer"], - explorerUrlToTx: "https://www.mintscan.io/sifchain/txs/{txHash}", - gasPriceStep: { - low: 1000000000000, - average: 1500000000000, - high: 2000000000000, - }, - }, - }, - { - name: "STARGAZE", - defaultDecimals: 6, - addressPatterns: ["^(stars1)[0-9a-z]{38}$"], - feeAssets: [{ blockchain: "STARGAZE", symbol: "STARS", address: null }], - logo: "https://api.rango.exchange/blockchains/stargaze.png", - displayName: "Stargaze", - shortName: "Stargaze", - sort: 19, - color: "#231B60", - enabled: true, - type: "COSMOS", - chainId: "stargaze-1", - info: { - experimental: false, - rpc: "https://rpc.stargaze-apis.com", - rest: "https://rest.stargaze-apis.com", - cosmostationLcdUrl: "https://lcd-stargaze.cosmostation.io", - cosmostationApiUrl: "https://api-stargaze.cosmostation.io", - cosmostationDenomTracePath: "/ibc/apps/transfer/v1/denom_traces/", - mintScanName: "stargaze", - chainName: "Stargaze", - stakeCurrency: { - coinDenom: "STARS", - coinMinimalDenom: "ustars", - coinDecimals: 6, - coinGeckoId: "pool:ustars", - coinImageUrl: "/tokens/blockchain/STARS.png", - }, - bip44: { coinType: 118 }, - bech32Config: { - bech32PrefixAccAddr: "stars", - bech32PrefixAccPub: "starspub", - bech32PrefixValAddr: "starsvaloper", - bech32PrefixValPub: "starsvaloperpub", - bech32PrefixConsAddr: "starsvalcons", - bech32PrefixConsPub: "starsvalconspub", - }, - currencies: [ - { - coinDenom: "STARS", - coinMinimalDenom: "ustars", - coinDecimals: 6, - coinGeckoId: "pool:ustars", - coinImageUrl: "/tokens/blockchain/STARS.png", - }, - ], - feeCurrencies: [ - { - coinDenom: "STARS", - coinMinimalDenom: "ustars", - coinDecimals: 6, - coinGeckoId: "pool:ustars", - coinImageUrl: "/tokens/blockchain/STARS.png", - }, - ], - features: ["stargate", "ibc-transfer", "no-legacy-stdTx"], - explorerUrlToTx: "https://www.mintscan.io/stargaze/txs/{txHash}", - gasPriceStep: { low: 1, average: 1, high: 1 }, - }, - }, - { - name: "CRYPTO_ORG", - defaultDecimals: 8, - addressPatterns: ["^(cro1)[0-9a-z]{38}$"], - feeAssets: [{ blockchain: "CRYPTO_ORG", symbol: "CRO", address: null }], - logo: "https://api.rango.exchange/blockchains/crypto_org.png", - displayName: "Crypto.org", - shortName: "Crypto.org", - sort: 21, - color: "#103F68", - enabled: true, - type: "COSMOS", - chainId: "crypto-org-chain-mainnet-1", - info: { - experimental: false, - rpc: "https://rpc-crypto-org.keplr.app", - rest: "https://lcd-crypto-org.keplr.app", - cosmostationLcdUrl: "https://lcd-cryptocom.cosmostation.io", - cosmostationApiUrl: "https://api-cryptocom.cosmostation.io", - cosmostationDenomTracePath: "/ibc/apps/transfer/v1/denom_traces/", - mintScanName: "crypto-org", - chainName: "Crypto.org", - stakeCurrency: { - coinDenom: "CRO", - coinMinimalDenom: "basecro", - coinDecimals: 8, - coinGeckoId: "crypto-com-chain", - coinImageUrl: "/tokens/blockchain/cro.png", - }, - bip44: { coinType: 394 }, - bech32Config: { - bech32PrefixAccAddr: "cro", - bech32PrefixAccPub: "cropub", - bech32PrefixValAddr: "crovaloper", - bech32PrefixValPub: "crovaloperpub", - bech32PrefixConsAddr: "crovalcons", - bech32PrefixConsPub: "crovalconspub", - }, - currencies: [ - { - coinDenom: "CRO", - coinMinimalDenom: "basecro", - coinDecimals: 8, - coinGeckoId: "crypto-com-chain", - coinImageUrl: "/tokens/blockchain/cro.png", - }, - ], - feeCurrencies: [ - { - coinDenom: "CRO", - coinMinimalDenom: "basecro", - coinDecimals: 8, - coinGeckoId: "crypto-com-chain", - coinImageUrl: "/tokens/blockchain/cro.png", - }, - ], - features: ["stargate", "ibc-transfer"], - explorerUrlToTx: "https://www.mintscan.io/crypto-org/txs/{txHash}", - gasPriceStep: { low: 0.025, average: 0.03, high: 0.04 }, - }, - }, - { - name: "CHIHUAHUA", - defaultDecimals: 6, - addressPatterns: ["^(chihuahua1)[0-9a-z]{38}$"], - feeAssets: [{ blockchain: "CHIHUAHUA", symbol: "HUAHUA", address: null }], - logo: "https://api.rango.exchange/blockchains/chihuahua.png", - displayName: "Chihuahua", - shortName: "Chihuahua", - sort: 22, - color: "#EFC92B", - enabled: true, - type: "COSMOS", - chainId: "chihuahua-1", - info: { - experimental: true, - rpc: "https://rpc.chihuahua.wtf/", - rest: "https://api.chihuahua.wtf/", - cosmostationLcdUrl: "https://lcd-chihuahua.cosmostation.io", - cosmostationApiUrl: "https://api-chihuahua.cosmostation.io", - cosmostationDenomTracePath: "/ibc/apps/transfer/v1/denom_traces/", - mintScanName: "chihuahua", - chainName: "Chihuahua", - stakeCurrency: { - coinDenom: "HUAHUA", - coinMinimalDenom: "uhuahua", - coinDecimals: 6, - coinGeckoId: "pool:uhuahua", - coinImageUrl: "/tokens/blockchain/HUAHUA.svg", - }, - bip44: { coinType: 118 }, - bech32Config: { - bech32PrefixAccAddr: "chihuahua", - bech32PrefixAccPub: "chihuahuapub", - bech32PrefixValAddr: "chihuahuavaloper", - bech32PrefixValPub: "chihuahuavaloperpub", - bech32PrefixConsAddr: "chihuahuavalcons", - bech32PrefixConsPub: "chihuahuavalconspub", - }, - currencies: [ - { - coinDenom: "HUAHUA", - coinMinimalDenom: "uhuahua", - coinDecimals: 6, - coinGeckoId: "pool:uhuahua", - coinImageUrl: "/tokens/blockchain/HUAHUA.svg", - }, - ], - feeCurrencies: [ - { - coinDenom: "HUAHUA", - coinMinimalDenom: "uhuahua", - coinDecimals: 6, - coinGeckoId: "pool:uhuahua", - coinImageUrl: "/tokens/blockchain/HUAHUA.svg", - }, - ], - features: ["stargate", "ibc-transfer", "no-legacy-stdTx"], - explorerUrlToTx: "https://ping.pub/chihuahua/tx/{txHash}", - gasPriceStep: { low: 0.025, average: 0.03, high: 0.035 }, - }, - }, - { - name: "BANDCHAIN", - defaultDecimals: 6, - addressPatterns: ["^(band1)[0-9a-z]{38}$"], - feeAssets: [{ blockchain: "BANDCHAIN", symbol: "BAND", address: null }], - logo: "https://api.rango.exchange/blockchains/bandchain.svg", - displayName: "BandChain", - shortName: "BandChain", - sort: 23, - color: "#4520E6", - enabled: true, - type: "COSMOS", - chainId: "laozi-mainnet", - info: { - experimental: true, - rpc: "https://rpc.laozi3.bandchain.org/", - rest: "https://lcd-band.cosmostation.io", - cosmostationLcdUrl: "https://lcd-band.cosmostation.io", - cosmostationApiUrl: "https://api-band.cosmostation.io", - cosmostationDenomTracePath: "/ibc/apps/transfer/v1/denom_traces/", - mintScanName: "band", - chainName: "BandChain", - stakeCurrency: { - coinDenom: "BAND", - coinMinimalDenom: "uband", - coinDecimals: 6, - coinGeckoId: "band-protocol", - coinImageUrl: "/tokens/blockchain/BAND.svg", - }, - bip44: { coinType: 494 }, - bech32Config: { - bech32PrefixAccAddr: "band", - bech32PrefixAccPub: "bandpub", - bech32PrefixValAddr: "bandvaloper", - bech32PrefixValPub: "bandvaloperpub", - bech32PrefixConsAddr: "bandvalcons", - bech32PrefixConsPub: "bandvalconspub", - }, - currencies: [ - { - coinDenom: "BAND", - coinMinimalDenom: "uband", - coinDecimals: 6, - coinGeckoId: "band-protocol", - coinImageUrl: "/tokens/blockchain/BAND.svg", - }, - ], - feeCurrencies: [ - { - coinDenom: "BAND", - coinMinimalDenom: "uband", - coinDecimals: 6, - coinGeckoId: "band-protocol", - coinImageUrl: "/tokens/blockchain/BAND.svg", - }, - ], - features: ["stargate", "ibc-transfer", "no-legacy-stdTx"], - explorerUrlToTx: "https://cosmoscan.io/tx/{txHash}", - gasPriceStep: null, - }, - }, - { - name: "COMDEX", - defaultDecimals: 6, - addressPatterns: ["^(comdex1)[0-9a-z]{38}$"], - feeAssets: [{ blockchain: "COMDEX", symbol: "CMDX", address: null }], - logo: "https://api.rango.exchange/blockchains/comdex.svg", - displayName: "Comdex", - shortName: "Comdex", - sort: 23, - color: "#FE4350", - enabled: true, - type: "COSMOS", - chainId: "comdex-1", - info: { - experimental: true, - rpc: "https://rpc.comdex.one", - rest: "https://rest.comdex.one", - cosmostationLcdUrl: "https://lcd-comdex.cosmostation.io", - cosmostationApiUrl: "https://api-comdex.cosmostation.io", - cosmostationDenomTracePath: "/ibc/apps/transfer/v1/denom_traces/", - mintScanName: "comdex", - chainName: "Comdex", - stakeCurrency: { - coinDenom: "CMDX", - coinMinimalDenom: "ucmdx", - coinDecimals: 6, - coinGeckoId: "comdex", - coinImageUrl: "/tokens/blockchain/CMDX.png", - }, - bip44: { coinType: 118 }, - bech32Config: { - bech32PrefixAccAddr: "comdex", - bech32PrefixAccPub: "comdexpub", - bech32PrefixValAddr: "comdexvaloper", - bech32PrefixValPub: "comdexvaloperpub", - bech32PrefixConsAddr: "comdexvalcons", - bech32PrefixConsPub: "comdexvalconspub", - }, - currencies: [ - { - coinDenom: "CMDX", - coinMinimalDenom: "ucmdx", - coinDecimals: 6, - coinGeckoId: "comdex", - coinImageUrl: "/tokens/blockchain/CMDX.png", - }, - ], - feeCurrencies: [ - { - coinDenom: "CMDX", - coinMinimalDenom: "ucmdx", - coinDecimals: 6, - coinGeckoId: "comdex", - coinImageUrl: "/tokens/blockchain/CMDX.png", - }, - ], - features: ["stargate", "ibc-transfer", "no-legacy-stdTx"], - explorerUrlToTx: "https://www.mintscan.io/comdex/txs/{txHash}", - gasPriceStep: null, - }, - }, - { - name: "REGEN", - defaultDecimals: 6, - addressPatterns: ["^(regen1)[0-9a-z]{38}$"], - feeAssets: [{ blockchain: "REGEN", symbol: "REGEN", address: null }], - logo: "https://api.rango.exchange/blockchains/regen.png", - displayName: "Regen Network", - shortName: "Regen Network", - sort: 24, - color: "#4FB573", - enabled: true, - type: "COSMOS", - chainId: "regen-1", - info: { - experimental: false, - rpc: "https://rpc-regen.keplr.app", - rest: "https://lcd-regen.keplr.app", - cosmostationLcdUrl: "https://lcd-regen.keplr.app", - cosmostationApiUrl: "https://api-regen.cosmostation.io/", - cosmostationDenomTracePath: "/ibc/apps/transfer/v1/denom_traces/", - mintScanName: "regen", - chainName: "Regen Network", - stakeCurrency: { - coinDenom: "REGEN", - coinMinimalDenom: "uregen", - coinDecimals: 6, - coinGeckoId: "pool:uregen", - coinImageUrl: "/tokens/blockchain/regen.png", - }, - bip44: { coinType: 118 }, - bech32Config: { - bech32PrefixAccAddr: "regen", - bech32PrefixAccPub: "regenpub", - bech32PrefixValAddr: "regenvaloper", - bech32PrefixValPub: "regenvaloperpub", - bech32PrefixConsAddr: "regenvalcons", - bech32PrefixConsPub: "regenvalconspub", - }, - currencies: [ - { - coinDenom: "REGEN", - coinMinimalDenom: "uregen", - coinDecimals: 6, - coinGeckoId: "pool:uregen", - coinImageUrl: "/tokens/blockchain/regen.png", - }, - ], - feeCurrencies: [ - { - coinDenom: "REGEN", - coinMinimalDenom: "uregen", - coinDecimals: 6, - coinGeckoId: "pool:uregen", - coinImageUrl: "/tokens/blockchain/regen.png", - }, - ], - features: ["stargate", "ibc-transfer"], - explorerUrlToTx: "https://regen.aneka.io/txs/{txHash}", - gasPriceStep: { low: 0.015, average: 0.025, high: 0.04 }, - }, - }, - { - name: "IRIS", - defaultDecimals: 6, - addressPatterns: ["^(iaa1)[0-9a-z]{38}$"], - feeAssets: [{ blockchain: "IRIS", symbol: "IRIS", address: null }], - logo: "https://api.rango.exchange/blockchains/iris.png", - displayName: "IRISnet", - shortName: "IRISnet", - sort: 25, - color: "#8A4A8E", - enabled: true, - type: "COSMOS", - chainId: "irishub-1", - info: { - experimental: false, - rpc: "https://rpc-iris.keplr.app", - rest: "https://lcd-iris.keplr.app", - cosmostationLcdUrl: "https://lcd-iris.cosmostation.io", - cosmostationApiUrl: "https://api-iris.cosmostation.io", - cosmostationDenomTracePath: "/ibc/apps/transfer/v1/denom_traces/", - mintScanName: "iris", - chainName: "IRISnet", - stakeCurrency: { - coinDenom: "IRIS", - coinMinimalDenom: "uiris", - coinDecimals: 6, - coinGeckoId: "iris-network", - coinImageUrl: "/tokens/blockchain/iris.svg", - }, - bip44: { coinType: 118 }, - bech32Config: { - bech32PrefixAccAddr: "iaa", - bech32PrefixAccPub: "iaapub", - bech32PrefixValAddr: "iaavaloper", - bech32PrefixValPub: "iaavaloperpub", - bech32PrefixConsAddr: "iaavalcons", - bech32PrefixConsPub: "iaavalconspub", - }, - currencies: [ - { - coinDenom: "IRIS", - coinMinimalDenom: "uiris", - coinDecimals: 6, - coinGeckoId: "iris-network", - coinImageUrl: "/tokens/blockchain/iris.svg", - }, - ], - feeCurrencies: [ - { - coinDenom: "IRIS", - coinMinimalDenom: "uiris", - coinDecimals: 6, - coinGeckoId: "iris-network", - coinImageUrl: "/tokens/blockchain/iris.svg", - }, - ], - features: ["stargate", "ibc-transfer"], - explorerUrlToTx: "https://www.mintscan.io/iris/txs/{txHash}", - gasPriceStep: { low: 0.2, average: 0.3, high: 0.4 }, - }, - }, - { - name: "EMONEY", - defaultDecimals: 6, - addressPatterns: ["^(emoney1)[0-9a-z]{38}$"], - feeAssets: [{ blockchain: "EMONEY", symbol: "NGM", address: null }], - logo: "https://api.rango.exchange/blockchains/emoney.svg", - displayName: "e-Money", - shortName: "e-Money", - sort: 25, - color: "#DFF5EF", - enabled: true, - type: "COSMOS", - chainId: "emoney-3", - info: { - experimental: true, - rpc: "https://rpc-emoney.keplr.app", - rest: "https://lcd-emoney.keplr.app", - cosmostationLcdUrl: "https://lcd-emoney.cosmostation.io", - cosmostationApiUrl: "https://api-emoney.cosmostation.io", - cosmostationDenomTracePath: - "/ibc/applications/transfer/v1beta1/denom_traces/", - mintScanName: "emoney", - chainName: "e-Money", - stakeCurrency: { - coinDenom: "NGM", - coinMinimalDenom: "ungm", - coinDecimals: 6, - coinGeckoId: "e-money", - coinImageUrl: "/tokens/blockchain/NGM.png", - }, - bip44: { coinType: 118 }, - bech32Config: { - bech32PrefixAccAddr: "emoney", - bech32PrefixAccPub: "emoneypub", - bech32PrefixValAddr: "emoneyvaloper", - bech32PrefixValPub: "emoneyvaloperpub", - bech32PrefixConsAddr: "emoneyvalcons", - bech32PrefixConsPub: "emoneyvalconspub", - }, - currencies: [ - { - coinDenom: "NGM", - coinMinimalDenom: "ungm", - coinDecimals: 6, - coinGeckoId: "e-money", - coinImageUrl: "/tokens/blockchain/NGM.png", - }, - { - coinDenom: "EEUR", - coinMinimalDenom: "eeur", - coinDecimals: 6, - coinGeckoId: "e-money-eur", - coinImageUrl: "/tokens/blockchain/EEUR.png", - }, - ], - feeCurrencies: [ - { - coinDenom: "NGM", - coinMinimalDenom: "ungm", - coinDecimals: 6, - coinGeckoId: "e-money", - coinImageUrl: "/tokens/blockchain/NGM.png", - }, - ], - features: ["stargate", "ibc-transfer"], - explorerUrlToTx: "https://emoney.bigdipper.live/transactions/{txHash}", - gasPriceStep: { low: 1, average: 1, high: 1 }, - }, - }, - { - name: "AKASH", - defaultDecimals: 6, - addressPatterns: ["^(akash1)[0-9a-z]{38}$"], - feeAssets: [{ blockchain: "AKASH", symbol: "AKT", address: null }], - logo: "https://api.rango.exchange/blockchains/akash.svg", - displayName: "Akash", - shortName: "Akash", - sort: 30, - color: "#ED3524", - enabled: true, - type: "COSMOS", - chainId: "akashnet-2", - info: { - experimental: false, - rpc: "https://rpc-akash.keplr.app", - rest: "https://lcd-akash.keplr.app", - cosmostationLcdUrl: "https://lcd-akash.cosmostation.io", - cosmostationApiUrl: "https://api-akash.cosmostation.io", - cosmostationDenomTracePath: "/ibc/apps/transfer/v1/denom_traces/", - mintScanName: "akash", - chainName: "Akash", - stakeCurrency: { - coinDenom: "AKT", - coinMinimalDenom: "uakt", - coinDecimals: 6, - coinGeckoId: "akash-network", - coinImageUrl: "/tokens/blockchain/akt.svg", - }, - bip44: { coinType: 118 }, - bech32Config: { - bech32PrefixAccAddr: "akash", - bech32PrefixAccPub: "akashpub", - bech32PrefixValAddr: "akashvaloper", - bech32PrefixValPub: "akashvaloperpub", - bech32PrefixConsAddr: "akashvalcons", - bech32PrefixConsPub: "akashvalconspub", - }, - currencies: [ - { - coinDenom: "AKT", - coinMinimalDenom: "uakt", - coinDecimals: 6, - coinGeckoId: "akash-network", - coinImageUrl: "/tokens/blockchain/akt.svg", - }, - ], - feeCurrencies: [ - { - coinDenom: "AKT", - coinMinimalDenom: "uakt", - coinDecimals: 6, - coinGeckoId: "akash-network", - coinImageUrl: "/tokens/blockchain/akt.svg", - }, - ], - features: ["stargate", "ibc-transfer"], - explorerUrlToTx: "https://www.mintscan.io/akash/txs/{txHash}", - gasPriceStep: { low: 0.001, average: 0.0025, high: 0.004 }, - }, - }, - { - name: "KI", - defaultDecimals: 6, - addressPatterns: ["^(ki1)[0-9a-z]{38}$"], - feeAssets: [{ blockchain: "KI", symbol: "XKI", address: null }], - logo: "https://api.rango.exchange/blockchains/ki.png", - displayName: "Ki", - shortName: "Ki", - sort: 30, - color: "#0F2B3D", - enabled: true, - type: "COSMOS", - chainId: "kichain-2", - info: { - experimental: true, - rpc: "https://rpc-mainnet.blockchain.ki", - rest: "https://api-mainnet.blockchain.ki", - cosmostationLcdUrl: "https://lcd-kichain.cosmostation.io", - cosmostationApiUrl: "https://api-kichain.cosmostation.io", - cosmostationDenomTracePath: "/ibc/apps/transfer/v1/denom_traces/", - mintScanName: "ki-chain", - chainName: "Ki", - stakeCurrency: { - coinDenom: "XKI", - coinMinimalDenom: "uxki", - coinDecimals: 6, - coinGeckoId: "pool:uxki", - coinImageUrl: "/tokens/blockchain/XKI.png", - }, - bip44: { coinType: 118 }, - bech32Config: { - bech32PrefixAccAddr: "ki", - bech32PrefixAccPub: "kipub", - bech32PrefixValAddr: "kivaloper", - bech32PrefixValPub: "kivaloperpub", - bech32PrefixConsAddr: "kivalcons", - bech32PrefixConsPub: "kivalconspub", - }, - currencies: [ - { - coinDenom: "XKI", - coinMinimalDenom: "uxki", - coinDecimals: 6, - coinGeckoId: "pool:uxki", - coinImageUrl: "/tokens/blockchain/XKI.png", - }, - ], - feeCurrencies: [ - { - coinDenom: "XKI", - coinMinimalDenom: "uxki", - coinDecimals: 6, - coinGeckoId: "pool:uxki", - coinImageUrl: "/tokens/blockchain/XKI.png", - }, - ], - features: ["stargate", "ibc-transfer"], - explorerUrlToTx: "https://www.mintscan.io/ki-chain/txs/{txHash}", - gasPriceStep: null, - }, - }, - { - name: "KUJIRA", - defaultDecimals: 6, - addressPatterns: ["^(kujira1)[0-9a-z]{38}$"], - feeAssets: [{ blockchain: "KUJIRA", symbol: "KUJI", address: null }], - logo: "https://api.rango.exchange/blockchains/kuji.svg", - displayName: "Kujira", - shortName: "Kujira", - sort: 31, - color: "#DF3935", - enabled: true, - type: "COSMOS", - chainId: "kaiyo-1", - info: { - experimental: true, - rpc: "https://rpc.kaiyo.kujira.setten.io", - rest: "https://lcd.kaiyo.kujira.setten.io", - cosmostationLcdUrl: "https://lcd-kujira.cosmostation.io", - cosmostationApiUrl: "https://api-kujira.cosmostation.io", - cosmostationDenomTracePath: "/ibc/apps/transfer/v1/denom_traces/", - mintScanName: "kujira", - chainName: "Kujira", - stakeCurrency: { - coinDenom: "KUJI", - coinMinimalDenom: "ukuji", - coinDecimals: 6, - coinGeckoId: "kujira", - coinImageUrl: "/tokens/blockchain/kuji.svg", - }, - bip44: { coinType: 118 }, - bech32Config: { - bech32PrefixAccAddr: "kujira", - bech32PrefixAccPub: "kujirapub", - bech32PrefixValAddr: "kujiravaloper", - bech32PrefixValPub: "kujiravaloperpub", - bech32PrefixConsAddr: "kujiravalcons", - bech32PrefixConsPub: "kujiravalconspub", - }, - currencies: [ - { - coinDenom: "KUJI", - coinMinimalDenom: "ukuji", - coinDecimals: 6, - coinGeckoId: "kujira", - coinImageUrl: "/tokens/blockchain/kuji.png", - }, - ], - feeCurrencies: [ - { - coinDenom: "KUJI", - coinMinimalDenom: "ukuji", - coinDecimals: 6, - coinGeckoId: "kujira", - coinImageUrl: "/tokens/blockchain/kuji.png", - }, - ], - features: ["stargate", "ibc-transfer"], - explorerUrlToTx: "https://finder.kujira.app/kaiyo-1/tx/{txHash}", - gasPriceStep: { low: 0.01, average: 0.025, high: 0.03 }, - }, - }, - { - name: "PERSISTENCE", - defaultDecimals: 6, - addressPatterns: ["^(persistence1)[0-9a-z]{38}$"], - feeAssets: [{ blockchain: "PERSISTENCE", symbol: "XPRT", address: null }], - logo: "https://api.rango.exchange/blockchains/persistence.png", - displayName: "Persistence", - shortName: "Persistence", - sort: 31, - color: "#383838", - enabled: true, - type: "COSMOS", - chainId: "core-1", - info: { - experimental: false, - rpc: "https://rpc-persistence.keplr.app", - rest: "https://lcd-persistence.keplr.app", - cosmostationLcdUrl: "https://lcd-persistence.cosmostation.io", - cosmostationApiUrl: "https://api-persistence.cosmostation.io", - cosmostationDenomTracePath: "/ibc/apps/transfer/v1/denom_traces/", - mintScanName: "persistence", - chainName: "Persistence", - stakeCurrency: { - coinDenom: "XPRT", - coinMinimalDenom: "uxprt", - coinDecimals: 6, - coinGeckoId: "persistence", - coinImageUrl: "/tokens/blockchain/xprt.png", - }, - bip44: { coinType: 750 }, - bech32Config: { - bech32PrefixAccAddr: "persistence", - bech32PrefixAccPub: "persistencepub", - bech32PrefixValAddr: "persistencevaloper", - bech32PrefixValPub: "persistencevaloperpub", - bech32PrefixConsAddr: "persistencevalcons", - bech32PrefixConsPub: "persistencevalconspub", - }, - currencies: [ - { - coinDenom: "XPRT", - coinMinimalDenom: "uxprt", - coinDecimals: 6, - coinGeckoId: "persistence", - coinImageUrl: "/tokens/blockchain/xprt.png", - }, - ], - feeCurrencies: [ - { - coinDenom: "XPRT", - coinMinimalDenom: "uxprt", - coinDecimals: 6, - coinGeckoId: "persistence", - coinImageUrl: "/tokens/blockchain/xprt.png", - }, - ], - features: ["stargate", "ibc-transfer"], - explorerUrlToTx: "https://www.mintscan.io/persistence/txs/{txHash}", - gasPriceStep: { low: 0, average: 0.025, high: 0.04 }, - }, - }, - { - name: "SENTINEL", - defaultDecimals: 6, - addressPatterns: ["^(sent1)[0-9a-z]{38}$"], - feeAssets: [{ blockchain: "SENTINEL", symbol: "DVPN", address: null }], - logo: "https://api.rango.exchange/blockchains/sentinel.png", - displayName: "Sentinel", - shortName: "Sentinel", - sort: 32, - color: "#142E51", - enabled: true, - type: "COSMOS", - chainId: "sentinelhub-2", - info: { - experimental: false, - rpc: "https://rpc-sentinel.keplr.app", - rest: "https://lcd-sentinel.keplr.app", - cosmostationLcdUrl: "https://lcd-sentinel.cosmostation.io", - cosmostationApiUrl: "https://api-sentinel.cosmostation.io", - cosmostationDenomTracePath: "/ibc/apps/transfer/v1/denom_traces/", - mintScanName: "sentinel", - chainName: "Sentinel", - stakeCurrency: { - coinDenom: "DVPN", - coinMinimalDenom: "udvpn", - coinDecimals: 6, - coinGeckoId: "sentinel", - coinImageUrl: "/tokens/blockchain/dvpn.png", - }, - bip44: { coinType: 118 }, - bech32Config: { - bech32PrefixAccAddr: "sent", - bech32PrefixAccPub: "sentpub", - bech32PrefixValAddr: "sentvaloper", - bech32PrefixValPub: "sentvaloperpub", - bech32PrefixConsAddr: "sentvalcons", - bech32PrefixConsPub: "sentvalconspub", - }, - currencies: [ - { - coinDenom: "DVPN", - coinMinimalDenom: "udvpn", - coinDecimals: 6, - coinGeckoId: "sentinel", - coinImageUrl: "/tokens/blockchain/dvpn.png", - }, - ], - feeCurrencies: [ - { - coinDenom: "DVPN", - coinMinimalDenom: "udvpn", - coinDecimals: 6, - coinGeckoId: "sentinel", - coinImageUrl: "/tokens/blockchain/dvpn.png", - }, - ], - features: ["stargate", "ibc-transfer"], - explorerUrlToTx: "https://www.mintscan.io/sentinel/txs/{txHash}", - gasPriceStep: { low: 0.1, average: 0.25, high: 0.4 }, - }, - }, - { - name: "STARNAME", - defaultDecimals: 6, - addressPatterns: ["^(star1)[0-9a-z]{38}$"], - feeAssets: [{ blockchain: "STARNAME", symbol: "IOV", address: null }], - logo: "https://api.rango.exchange/blockchains/starname.png", - displayName: "Starname", - shortName: "Starname", - sort: 35, - color: "#BC64BB", - enabled: true, - type: "COSMOS", - chainId: "iov-mainnet-ibc", - info: { - experimental: false, - rpc: "https://rpc-iov.keplr.app", - rest: "https://lcd-iov.keplr.app", - cosmostationLcdUrl: "https://lcd-iov.cosmostation.io", - cosmostationApiUrl: "https://api-iov.cosmostation.io", - cosmostationDenomTracePath: - "/ibc/applications/transfer/v1beta1/denom_traces/", - mintScanName: "starname", - chainName: "Starname", - stakeCurrency: { - coinDenom: "IOV", - coinMinimalDenom: "uiov", - coinDecimals: 6, - coinGeckoId: "starname", - coinImageUrl: "/tokens/blockchain/IOV.png", - }, - bip44: { coinType: 494 }, - bech32Config: { - bech32PrefixAccAddr: "star", - bech32PrefixAccPub: "starpub", - bech32PrefixValAddr: "starvaloper", - bech32PrefixValPub: "starvaloperpub", - bech32PrefixConsAddr: "starvalcons", - bech32PrefixConsPub: "starvalconspub", - }, - currencies: [ - { - coinDenom: "IOV", - coinMinimalDenom: "uiov", - coinDecimals: 6, - coinGeckoId: "starname", - coinImageUrl: "/tokens/blockchain/IOV.png", - }, - ], - feeCurrencies: [ - { - coinDenom: "IOV", - coinMinimalDenom: "uiov", - coinDecimals: 6, - coinGeckoId: "starname", - coinImageUrl: "/tokens/blockchain/IOV.png", - }, - ], - features: ["stargate", "ibc-transfer"], - explorerUrlToTx: "https://www.mintscan.io/starname/txs/{txHash}", - gasPriceStep: { low: 1, average: 2, high: 3 }, - }, - }, - { - name: "UMEE", - defaultDecimals: 6, - addressPatterns: ["^(umee1)[0-9a-z]{38}$"], - feeAssets: [{ blockchain: "UMEE", symbol: "UMEE", address: null }], - logo: "https://api.rango.exchange/blockchains/umee.svg", - displayName: "Umee", - shortName: "Umee", - sort: 36, - color: "#D2B6FF", - enabled: true, - type: "COSMOS", - chainId: "umee-1", - info: { - experimental: false, - rpc: "https://api.barnacle.mainnet.network.umee.cc", - rest: "https://lcd-umee.cosmostation.io", - cosmostationLcdUrl: "https://lcd-umee.cosmostation.io", - cosmostationApiUrl: "https://api-umee.cosmostation.io", - cosmostationDenomTracePath: "/ibc/apps/transfer/v1/denom_traces/", - mintScanName: "umee", - chainName: "Umee", - stakeCurrency: { - coinDenom: "UMEE", - coinMinimalDenom: "uumee", - coinDecimals: 6, - coinGeckoId: "pool:uumee", - coinImageUrl: "/tokens/blockchain/UMEE.png", - }, - bip44: { coinType: 118 }, - bech32Config: { - bech32PrefixAccAddr: "umee", - bech32PrefixAccPub: "umeepub", - bech32PrefixValAddr: "umeevaloper", - bech32PrefixValPub: "umeevaloperpub", - bech32PrefixConsAddr: "umeevalcons", - bech32PrefixConsPub: "umeevalconspub", - }, - currencies: [ - { - coinDenom: "UMEE", - coinMinimalDenom: "uumee", - coinDecimals: 6, - coinGeckoId: "pool:uumee", - coinImageUrl: "/tokens/blockchain/UMEE.png", - }, - ], - feeCurrencies: [ - { - coinDenom: "UMEE", - coinMinimalDenom: "uumee", - coinDecimals: 6, - coinGeckoId: "pool:uumee", - coinImageUrl: "/tokens/blockchain/UMEE.png", - }, - ], - features: ["stargate", "ibc-transfer", "no-legacy-stdTx"], - explorerUrlToTx: "https://www.mintscan.io/umee/txs/{txHash}", - gasPriceStep: { low: 0.05, average: 0.06, high: 0.1 }, - }, - }, - { - name: "BITCANNA", - defaultDecimals: 6, - addressPatterns: ["^(bcna1)[0-9a-z]{38}$"], - feeAssets: [{ blockchain: "BITCANNA", symbol: "BCNA", address: null }], - logo: "https://api.rango.exchange/blockchains/bitcanna.svg", - displayName: "BitCanna", - shortName: "BitCanna", - sort: 36, - color: "#3CC194", - enabled: true, - type: "COSMOS", - chainId: "bitcanna-1", - info: { - experimental: true, - rpc: "https://rpc.bitcanna.io", - rest: "https://lcd.bitcanna.io", - cosmostationLcdUrl: "https://lcd-bitcanna.cosmostation.io", - cosmostationApiUrl: "https://api-bitcanna.cosmostation.io", - cosmostationDenomTracePath: "/ibc/apps/transfer/v1/denom_traces/", - mintScanName: "bitcanna", - chainName: "BitCanna", - stakeCurrency: { - coinDenom: "BCNA", - coinMinimalDenom: "ubcna", - coinDecimals: 6, - coinGeckoId: "bitcanna", - coinImageUrl: "/tokens/blockchain/BCNA.png", - }, - bip44: { coinType: 118 }, - bech32Config: { - bech32PrefixAccAddr: "bcna", - bech32PrefixAccPub: "bcnapub", - bech32PrefixValAddr: "bcnavaloper", - bech32PrefixValPub: "bcnavaloperpub", - bech32PrefixConsAddr: "bcnavalcons", - bech32PrefixConsPub: "bcnavalconspub", - }, - currencies: [ - { - coinDenom: "BCNA", - coinMinimalDenom: "ubcna", - coinDecimals: 6, - coinGeckoId: "bitcanna", - coinImageUrl: "/tokens/blockchain/BCNA.png", - }, - ], - feeCurrencies: [ - { - coinDenom: "BCNA", - coinMinimalDenom: "ubcna", - coinDecimals: 6, - coinGeckoId: "bitcanna", - coinImageUrl: "/tokens/blockchain/BCNA.png", - }, - ], - features: ["stargate", "ibc-transfer", "no-legacy-stdTx"], - explorerUrlToTx: "https://www.mintscan.io/bitcanna/txs/{txHash}", - gasPriceStep: null, - }, - }, - { - name: "DESMOS", - defaultDecimals: 6, - addressPatterns: ["^(desmos1)[0-9a-z]{38}$"], - feeAssets: [{ blockchain: "DESMOS", symbol: "DSM", address: null }], - logo: "https://api.rango.exchange/blockchains/desmos.svg", - displayName: "Desmos", - shortName: "Desmos", - sort: 37, - color: "#DF6952", - enabled: true, - type: "COSMOS", - chainId: "desmos-mainnet", - info: { - experimental: true, - rpc: "https://rpc.mainnet.desmos.network", - rest: "https://api.mainnet.desmos.network", - cosmostationLcdUrl: "https://lcd-desmos.cosmostation.io", - cosmostationApiUrl: "https://api-desmos.cosmostation.io", - cosmostationDenomTracePath: "/ibc/apps/transfer/v1/denom_traces/", - mintScanName: "desmos", - chainName: "Desmos", - stakeCurrency: { - coinDenom: "DSM", - coinMinimalDenom: "udsm", - coinDecimals: 6, - coinGeckoId: "pool:udsm", - coinImageUrl: "/tokens/blockchain/DSM.png", - }, - bip44: { coinType: 852 }, - bech32Config: { - bech32PrefixAccAddr: "desmos", - bech32PrefixAccPub: "desmospub", - bech32PrefixValAddr: "desmosvaloper", - bech32PrefixValPub: "desmosvaloperpub", - bech32PrefixConsAddr: "desmosvalcons", - bech32PrefixConsPub: "desmosvalconspub", - }, - currencies: [ - { - coinDenom: "DSM", - coinMinimalDenom: "udsm", - coinDecimals: 6, - coinGeckoId: "pool:udsm", - coinImageUrl: "/tokens/blockchain/DSM.png", - }, - ], - feeCurrencies: [ - { - coinDenom: "DSM", - coinMinimalDenom: "udsm", - coinDecimals: 6, - coinGeckoId: "pool:udsm", - coinImageUrl: "/tokens/blockchain/DSM.png", - }, - ], - features: ["stargate", "ibc-transfer", "no-legacy-stdTx", "ibc-go"], - explorerUrlToTx: - "https://explorer.desmos.network/transactions/{txHash}", - gasPriceStep: null, - }, - }, - { - name: "LUMNETWORK", - defaultDecimals: 6, - addressPatterns: ["^(lum1)[0-9a-z]{38}$"], - feeAssets: [{ blockchain: "LUMNETWORK", symbol: "LUM", address: null }], - logo: "https://api.rango.exchange/blockchains/lumnetwork.svg", - displayName: "Lum Network", - shortName: "Lum Network", - sort: 38, - color: "#1B42B4", - enabled: true, - type: "COSMOS", - chainId: "lum-network-1", - info: { - experimental: true, - rpc: "https://node0.mainnet.lum.network/rpc", - rest: "https://node0.mainnet.lum.network/rest", - cosmostationLcdUrl: "https://lcd-lum.cosmostation.io", - cosmostationApiUrl: "https://api-lum.cosmostation.io", - cosmostationDenomTracePath: "/ibc/apps/transfer/v1/denom_traces/", - mintScanName: "lum", - chainName: "Lum Network", - stakeCurrency: { - coinDenom: "LUM", - coinMinimalDenom: "ulum", - coinDecimals: 6, - coinGeckoId: "pool:ulum", - coinImageUrl: "/tokens/blockchain/LUM.png", - }, - bip44: { coinType: 118 }, - bech32Config: { - bech32PrefixAccAddr: "lum", - bech32PrefixAccPub: "lumpub", - bech32PrefixValAddr: "lumvaloper", - bech32PrefixValPub: "lumvaloperpub", - bech32PrefixConsAddr: "lumvalcons", - bech32PrefixConsPub: "lumvalconspub", - }, - currencies: [ - { - coinDenom: "LUM", - coinMinimalDenom: "ulum", - coinDecimals: 6, - coinGeckoId: "pool:ulum", - coinImageUrl: "/tokens/blockchain/LUM.png", - }, - ], - feeCurrencies: [ - { - coinDenom: "LUM", - coinMinimalDenom: "ulum", - coinDecimals: 6, - coinGeckoId: "pool:ulum", - coinImageUrl: "/tokens/blockchain/LUM.png", - }, - ], - features: ["stargate", "ibc-transfer", "no-legacy-stdTx", "ibc-go"], - explorerUrlToTx: "https://www.mintscan.io/lum/txs/{txHash}", - gasPriceStep: null, - }, - }, - ], - brave: [ - { - name: "BSC", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "BSC", symbol: "BNB", address: null }], - logo: "https://api.rango.exchange/blockchains/binance.svg", - displayName: "BSC", - shortName: "BSC", - sort: 1, - color: "#F3BA2F", - enabled: true, - type: "EVM", - chainId: "0x38", - info: { - chainName: "Binance Smart Chain Mainnet", - nativeCurrency: { name: "BNB", symbol: "BNB", decimals: 18 }, - rpcUrls: ["https://bsc-dataseed1.ninicoin.io"], - blockExplorerUrls: ["https://bscscan.com"], - addressUrl: "https://bscscan.com/address/{wallet}", - transactionUrl: "https://bscscan.com/tx/{txHash}", - }, - }, - { - name: "POLYGON", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "POLYGON", symbol: "MATIC", address: null }], - logo: "https://api.rango.exchange/blockchains/polygon.svg", - displayName: "Polygon", - shortName: "Polygon", - sort: 2, - color: "#8247E5", - enabled: true, - type: "EVM", - chainId: "0x89", - info: { - chainName: "Polygon Mainnet", - nativeCurrency: { name: "MATIC", symbol: "MATIC", decimals: 18 }, - rpcUrls: ["https://polygon-rpc.com"], - blockExplorerUrls: ["https://polygonscan.com"], - addressUrl: "https://polygonscan.com/address/{wallet}", - transactionUrl: "https://polygonscan.com/tx/{txHash}", - }, - }, - { - name: "ETH", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "ETH", symbol: "ETH", address: null }], - logo: "https://api.rango.exchange/blockchains/ethereum.svg", - displayName: "Ethereum", - shortName: "ETH", - sort: 3, - color: "#ecf0f1", - enabled: true, - type: "EVM", - chainId: "0x1", - info: { - chainName: "Ethereum Mainnet", - nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 }, - rpcUrls: ["https://rpc.ankr.com/eth"], - blockExplorerUrls: ["https://etherscan.io"], - addressUrl: "https://etherscan.io/address/{wallet}", - transactionUrl: "https://etherscan.io/tx/{txHash}", - }, - }, - { - name: "AVAX_CCHAIN", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "AVAX_CCHAIN", symbol: "AVAX", address: null }], - logo: "https://api.rango.exchange/blockchains/avax_cchain.svg", - displayName: "Avalanche", - shortName: "Avax", - sort: 6, - color: "#e84142", - enabled: true, - type: "EVM", - chainId: "0xa86a", - info: { - chainName: "Avalanche C-Chain", - nativeCurrency: { name: "AVAX", symbol: "AVAX", decimals: 18 }, - rpcUrls: ["https://api.avax.network/ext/bc/C/rpc"], - blockExplorerUrls: ["https://snowtrace.io"], - addressUrl: "https://snowtrace.io/address/{wallet}", - transactionUrl: "https://snowtrace.io/tx/{txHash}", - }, - }, - { - name: "ARBITRUM", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "ARBITRUM", symbol: "ETH", address: null }], - logo: "https://api.rango.exchange/blockchains/arbitrum.svg", - displayName: "Arbitrum", - shortName: "Arbitrum", - sort: 7, - color: "#28a0f0", - enabled: true, - type: "EVM", - chainId: "0xa4b1", - info: { - chainName: "Arbitrum One", - nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 }, - rpcUrls: ["https://arb1.arbitrum.io/rpc"], - blockExplorerUrls: ["https://arbiscan.io"], - addressUrl: "https://arbiscan.io/address/{wallet}", - transactionUrl: "https://arbiscan.io/tx/{txHash}", - }, - }, - { - name: "FANTOM", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "FANTOM", symbol: "FTM", address: null }], - logo: "https://api.rango.exchange/blockchains/fantom.png", - displayName: "Fantom", - shortName: "Fantom", - sort: 9, - color: "#337afe", - enabled: true, - type: "EVM", - chainId: "0xfa", - info: { - chainName: "Fantom Opera", - nativeCurrency: { name: "FTM", symbol: "FTM", decimals: 18 }, - rpcUrls: ["https://rpc.ftm.tools"], - blockExplorerUrls: ["https://ftmscan.com"], - addressUrl: "https://ftmscan.com/address/{wallet}", - transactionUrl: "https://ftmscan.com/tx/{txHash}", - }, - }, - { - name: "OPTIMISM", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "OPTIMISM", symbol: "ETH", address: null }], - logo: "https://api.rango.exchange/blockchains/optimism.svg", - displayName: "Optimism", - shortName: "Optimism", - sort: 10, - color: "#FF0420", - enabled: true, - type: "EVM", - chainId: "0xa", - info: { - chainName: "Optimism", - nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 }, - rpcUrls: ["https://mainnet.optimism.io"], - blockExplorerUrls: ["https://optimistic.etherscan.io"], - addressUrl: "https://optimistic.etherscan.io/address/{wallet}", - transactionUrl: "https://optimistic.etherscan.io/tx/{txHash}", - }, - }, - { - name: "OKC", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "OKC", symbol: "OKT", address: null }], - logo: "https://api.rango.exchange/blockchains/okx.png", - displayName: "OKX Chain (OKC)", - shortName: "Okx", - sort: 11, - color: "#29a0f0", - enabled: true, - type: "EVM", - chainId: "0x42", - info: { - chainName: "OKX Chain", - nativeCurrency: { name: "OKT", symbol: "OKT", decimals: 18 }, - rpcUrls: ["https://exchainrpc.okex.org"], - blockExplorerUrls: ["https://www.oklink.com/en/okc"], - addressUrl: "https://www.oklink.com/en/okc/address/{wallet}", - transactionUrl: "https://www.oklink.com/en/okc/tx/{txHash}", - }, - }, - { - name: "CRONOS", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "CRONOS", symbol: "CRO", address: null }], - logo: "https://api.rango.exchange/blockchains/cronos.svg", - displayName: "Cronos", - shortName: "Cronos", - sort: 12, - color: "#1a90ff", - enabled: true, - type: "EVM", - chainId: "0x19", - info: { - chainName: "Cronos Mainnet Beta", - nativeCurrency: { name: "CRO", symbol: "CRO", decimals: 18 }, - rpcUrls: ["https://cronosrpc-1.xstaking.sg"], - blockExplorerUrls: ["https://cronoscan.com"], - addressUrl: "https://cronoscan.com/address/{wallet}", - transactionUrl: "https://cronoscan.com/tx/{txHash}", - }, - }, - { - name: "MOONRIVER", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "MOONRIVER", symbol: "MOVR", address: null }], - logo: "https://api.rango.exchange/blockchains/moonriver.svg", - displayName: "MoonRiver", - shortName: "MoonRiver", - sort: 13, - color: "#F3B404", - enabled: true, - type: "EVM", - chainId: "0x505", - info: { - chainName: "MoonRiver", - nativeCurrency: { name: "MOVR", symbol: "MOVR", decimals: 18 }, - rpcUrls: ["https://rpc.moonriver.moonbeam.network"], - blockExplorerUrls: ["https://moonriver.moonscan.io"], - addressUrl: "https://moonriver.moonscan.io/address/{wallet}", - transactionUrl: "https://moonriver.moonscan.io/tx/{txHash}", - }, - }, - { - name: "MOONBEAM", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "MOONBEAM", symbol: "GLMR", address: null }], - logo: "https://api.rango.exchange/blockchains/moonbeam.png", - displayName: "MoonBeam", - shortName: "MoonBeam", - sort: 14, - color: "#B3206B", - enabled: true, - type: "EVM", - chainId: "0x504", - info: { - chainName: "MoonBeam", - nativeCurrency: { name: "GLMR", symbol: "GLMR", decimals: 18 }, - rpcUrls: ["https://rpc.api.moonbeam.network"], - blockExplorerUrls: ["https://moonbeam.moonscan.io"], - addressUrl: "https://moonbeam.moonscan.io/address/{wallet}", - transactionUrl: "https://moonbeam.moonscan.io/tx/{txHash}", - }, - }, - { - name: "HECO", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "HECO", symbol: "HT", address: null }], - logo: "https://api.rango.exchange/blockchains/heco.png", - displayName: "Heco", - shortName: "Heco", - sort: 15, - color: "#4CA852", - enabled: true, - type: "EVM", - chainId: "0x80", - info: { - chainName: "Huobi ECO Chain Mainnet", - nativeCurrency: { name: "HT", symbol: "HT", decimals: 18 }, - rpcUrls: ["https://http-mainnet.hecochain.com"], - blockExplorerUrls: ["https://hecoinfo.com"], - addressUrl: "https://hecoinfo.com/address/{wallet}", - transactionUrl: "https://hecoinfo.com/tx/{txHash}", - }, - }, - { - name: "AURORA", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "AURORA", symbol: "ETH", address: null }], - logo: "https://api.rango.exchange/blockchains/aurora.svg", - displayName: "Aurora", - shortName: "Aurora", - sort: 15, - color: "#78d64b", - enabled: true, - type: "EVM", - chainId: "0x4e454152", - info: { - chainName: "Aurora Mainnet", - nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 }, - rpcUrls: ["https://mainnet.aurora.dev"], - blockExplorerUrls: ["https://explorer.mainnet.aurora.dev"], - addressUrl: "https://explorer.mainnet.aurora.dev/address/{wallet}", - transactionUrl: "https://explorer.mainnet.aurora.dev/tx/{txHash}", - }, - }, - { - name: "HARMONY", - defaultDecimals: 18, - addressPatterns: ["^(one1)[0-9a-z]{38}$", "^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "HARMONY", symbol: "ONE", address: null }], - logo: "https://api.rango.exchange/blockchains/harmony.svg", - displayName: "Harmony", - shortName: "Harmony", - sort: 15, - color: "#50AEE9", - enabled: true, - type: "EVM", - chainId: "0x63564c40", - info: { - chainName: "Harmony Mainnet", - nativeCurrency: { name: "ONE", symbol: "ONE", decimals: 18 }, - rpcUrls: ["https://api.s0.t.hmny.io"], - blockExplorerUrls: ["https://explorer.harmony.one"], - addressUrl: "https://explorer.harmony.one/address/{wallet}", - transactionUrl: "https://explorer.harmony.one/tx/{txHash}", - }, - }, - { - name: "EVMOS", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "EVMOS", symbol: "EVMOS", address: null }], - logo: "https://api.rango.exchange/blockchains/evmos.png", - displayName: "Evmos", - shortName: "Evmos", - sort: 15, - color: "#2D2925", - enabled: true, - type: "EVM", - chainId: "0x2329", - info: { - chainName: "Evmos", - nativeCurrency: { name: "EVMOS", symbol: "EVMOS", decimals: 18 }, - rpcUrls: ["https://eth.bd.evmos.org:8545"], - blockExplorerUrls: ["https://evm.evmos.org"], - addressUrl: "https://evm.evmos.org/address/{wallet}", - transactionUrl: "https://evm.evmos.org/tx/{txHash}", - }, - }, - { - name: "GNOSIS", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "GNOSIS", symbol: "XDAI", address: null }], - logo: "https://api.rango.exchange/blockchains/gnosis.svg", - displayName: "Gnosis", - shortName: "Gnosis", - sort: 26, - color: "#3E6957", - enabled: true, - type: "EVM", - chainId: "0x64", - info: { - chainName: "Gnosis Chain", - nativeCurrency: { name: "XDAI", symbol: "XDAI", decimals: 18 }, - rpcUrls: ["https://rpc.gnosischain.com"], - blockExplorerUrls: ["https://blockscout.com/xdai/mainnet"], - addressUrl: "https://blockscout.com/xdai/mainnet/address/{wallet}", - transactionUrl: "https://blockscout.com/xdai/mainnet/tx/{txHash}", - }, - }, - { - name: "FUSE", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "FUSE", symbol: "FUSE", address: null }], - logo: "https://api.rango.exchange/blockchains/fuse.png", - displayName: "Fuse", - shortName: "Fuse", - sort: 29, - color: "#C5F9AD", - enabled: true, - type: "EVM", - chainId: "0x7a", - info: { - chainName: "Fuse Mainnet", - nativeCurrency: { name: "FUSE", symbol: "FUSE", decimals: 18 }, - rpcUrls: ["https://rpc.fuse.io"], - blockExplorerUrls: ["https://explorer.fuse.io"], - addressUrl: "https://explorer.fuse.io/address/{wallet}", - transactionUrl: "https://explorer.fuse.io/tx/{txHash}", - }, - }, - { - name: "BOBA", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "BOBA", symbol: "ETH", address: null }], - logo: "https://api.rango.exchange/blockchains/boba.png", - displayName: "Boba", - shortName: "Boba", - sort: 39, - color: "#ccff00", - enabled: true, - type: "EVM", - chainId: "0x120", - info: { - chainName: "Boba Network", - nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 }, - rpcUrls: ["https://mainnet.boba.network"], - blockExplorerUrls: ["https://bobascan.com/"], - addressUrl: "https://bobascan.com//address/{wallet}", - transactionUrl: "https://bobascan.com//tx/{txHash}", - }, - }, - { - name: "SOLANA", - defaultDecimals: 9, - addressPatterns: ["^[1-9A-HJ-NP-Za-km-z]{32,44}$"], - feeAssets: [{ blockchain: "SOLANA", symbol: "SOL", address: null }], - logo: "https://api.rango.exchange/blockchains/solana.svg", - displayName: "Solana", - shortName: "Solana", - sort: 11, - color: "#708DD2", - enabled: true, - type: "SOLANA", - chainId: "mainnet-beta", - info: null, - }, - ], - unknown: [], -} as unknown as WalletsAndSupportedChains; - -export const meta = { - blockchains: { - BSC: { - name: "BSC", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "BSC", symbol: "BNB", address: null }], - logo: "https://api.rango.exchange/blockchains/binance.svg", - displayName: "BSC", - shortName: "BSC", - sort: 1, - color: "#F3BA2F", - enabled: true, - type: "EVM", - chainId: "0x38", - info: { - chainName: "Binance Smart Chain Mainnet", - nativeCurrency: { name: "BNB", symbol: "BNB", decimals: 18 }, - rpcUrls: ["https://bsc-dataseed1.ninicoin.io"], - blockExplorerUrls: ["https://bscscan.com"], - addressUrl: "https://bscscan.com/address/{wallet}", - transactionUrl: "https://bscscan.com/tx/{txHash}", - }, - }, - POLYGON: { - name: "POLYGON", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "POLYGON", symbol: "MATIC", address: null }], - logo: "https://api.rango.exchange/blockchains/polygon.svg", - displayName: "Polygon", - shortName: "Polygon", - sort: 2, - color: "#8247E5", - enabled: true, - type: "EVM", - chainId: "0x89", - info: { - chainName: "Polygon Mainnet", - nativeCurrency: { name: "MATIC", symbol: "MATIC", decimals: 18 }, - rpcUrls: ["https://polygon-rpc.com"], - blockExplorerUrls: ["https://polygonscan.com"], - addressUrl: "https://polygonscan.com/address/{wallet}", - transactionUrl: "https://polygonscan.com/tx/{txHash}", - }, - }, - ETH: { - name: "ETH", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "ETH", symbol: "ETH", address: null }], - logo: "https://api.rango.exchange/blockchains/ethereum.svg", - displayName: "Ethereum", - shortName: "ETH", - sort: 3, - color: "#ecf0f1", - enabled: true, - type: "EVM", - chainId: "0x1", - info: { - chainName: "Ethereum Mainnet", - nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 }, - rpcUrls: ["https://rpc.ankr.com/eth"], - blockExplorerUrls: ["https://etherscan.io"], - addressUrl: "https://etherscan.io/address/{wallet}", - transactionUrl: "https://etherscan.io/tx/{txHash}", - }, - }, - OSMOSIS: { - name: "OSMOSIS", - defaultDecimals: 6, - addressPatterns: ["^(osmo1)[0-9a-z]{38}$"], - feeAssets: [{ blockchain: "OSMOSIS", symbol: "OSMO", address: null }], - logo: "https://api.rango.exchange/blockchains/osmosis.svg", - displayName: "Osmosis", - shortName: "Osmosis", - sort: 4, - color: "#7901B4", - enabled: true, - type: "COSMOS", - chainId: "osmosis-1", - info: { - experimental: false, - rpc: "https://rpc-osmosis.keplr.app", - rest: "https://lcd-osmosis.keplr.app", - cosmostationLcdUrl: "https://lcd-osmosis.cosmostation.io", - cosmostationApiUrl: "https://api-osmosis.cosmostation.io", - cosmostationDenomTracePath: "/ibc/apps/transfer/v1/denom_traces/", - mintScanName: "osmosis", - chainName: "Osmosis", - stakeCurrency: { - coinDenom: "OSMO", - coinMinimalDenom: "uosmo", - coinDecimals: 6, - coinGeckoId: "pool:uosmo", - coinImageUrl: "/tokens/blockchain/osmosis.svg", - }, - bip44: { coinType: 118 }, - bech32Config: { - bech32PrefixAccAddr: "osmo", - bech32PrefixAccPub: "osmopub", - bech32PrefixValAddr: "osmovaloper", - bech32PrefixValPub: "osmovaloperpub", - bech32PrefixConsAddr: "osmovalcons", - bech32PrefixConsPub: "osmovalconspub", - }, - currencies: [ - { - coinDenom: "OSMO", - coinMinimalDenom: "uosmo", - coinDecimals: 6, - coinGeckoId: "pool:uosmo", - coinImageUrl: "/tokens/blockchain/osmosis.svg", - }, - { - coinDenom: "ION", - coinMinimalDenom: "uion", - coinDecimals: 6, - coinGeckoId: "pool:uion", - coinImageUrl: "/tokens/blockchain/ion.png", - }, - ], - feeCurrencies: [ - { - coinDenom: "OSMO", - coinMinimalDenom: "uosmo", - coinDecimals: 6, - coinGeckoId: "pool:uosmo", - coinImageUrl: "/tokens/blockchain/osmosis.svg", - }, - ], - features: ["stargate", "ibc-transfer"], - explorerUrlToTx: "https://www.mintscan.io/osmosis/txs/{txHash}", - gasPriceStep: { low: 0, average: 0.025, high: 0.04 }, - }, - }, - JUNO: { - name: "JUNO", - defaultDecimals: 6, - addressPatterns: ["^(juno1)[0-9a-z]{38}$"], - feeAssets: [{ blockchain: "JUNO", symbol: "JUNO", address: null }], - logo: "https://api.rango.exchange/blockchains/juno.svg", - displayName: "Juno", - shortName: "Juno", - sort: 5, - color: "#f0827d", - enabled: true, - type: "COSMOS", - chainId: "juno-1", - info: { - experimental: false, - rpc: "https://rpc-juno.itastakers.com:443/", - rest: "https://lcd-juno.keplr.app", - cosmostationLcdUrl: "https://lcd-juno.cosmostation.io", - cosmostationApiUrl: "https://api-juno.cosmostation.io", - cosmostationDenomTracePath: "/ibc/apps/transfer/v1/denom_traces/", - mintScanName: "juno", - chainName: "Juno", - stakeCurrency: { - coinDenom: "JUNO", - coinMinimalDenom: "ujuno", - coinDecimals: 6, - coinGeckoId: "juno-network", - coinImageUrl: "/tokens/blockchain/JUNO.png", - }, - bip44: { coinType: 118 }, - bech32Config: { - bech32PrefixAccAddr: "juno", - bech32PrefixAccPub: "junopub", - bech32PrefixValAddr: "junovaloper", - bech32PrefixValPub: "junovaloperpub", - bech32PrefixConsAddr: "junovalcons", - bech32PrefixConsPub: "junovalconspub", - }, - currencies: [ - { - coinDenom: "JUNO", - coinMinimalDenom: "ujuno", - coinDecimals: 6, - coinGeckoId: "juno-network", - coinImageUrl: "/tokens/blockchain/JUNO.png", - }, - ], - feeCurrencies: [ - { - coinDenom: "JUNO", - coinMinimalDenom: "ujuno", - coinDecimals: 6, - coinGeckoId: "juno-network", - coinImageUrl: "/tokens/blockchain/JUNO.png", - }, - ], - features: ["stargate", "ibc-transfer"], - explorerUrlToTx: "https://www.mintscan.io/juno/txs/{txHash}", - gasPriceStep: { low: 0.001, average: 0.0025, high: 0.004 }, - }, - }, - AVAX_CCHAIN: { - name: "AVAX_CCHAIN", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "AVAX_CCHAIN", symbol: "AVAX", address: null }], - logo: "https://api.rango.exchange/blockchains/avax_cchain.svg", - displayName: "Avalanche", - shortName: "Avax", - sort: 6, - color: "#e84142", - enabled: true, - type: "EVM", - chainId: "0xa86a", - info: { - chainName: "Avalanche C-Chain", - nativeCurrency: { name: "AVAX", symbol: "AVAX", decimals: 18 }, - rpcUrls: ["https://api.avax.network/ext/bc/C/rpc"], - blockExplorerUrls: ["https://snowtrace.io"], - addressUrl: "https://snowtrace.io/address/{wallet}", - transactionUrl: "https://snowtrace.io/tx/{txHash}", - }, - }, - ARBITRUM: { - name: "ARBITRUM", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "ARBITRUM", symbol: "ETH", address: null }], - logo: "https://api.rango.exchange/blockchains/arbitrum.svg", - displayName: "Arbitrum", - shortName: "Arbitrum", - sort: 7, - color: "#28a0f0", - enabled: true, - type: "EVM", - chainId: "0xa4b1", - info: { - chainName: "Arbitrum One", - nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 }, - rpcUrls: ["https://arb1.arbitrum.io/rpc"], - blockExplorerUrls: ["https://arbiscan.io"], - addressUrl: "https://arbiscan.io/address/{wallet}", - transactionUrl: "https://arbiscan.io/tx/{txHash}", - }, - }, - COSMOS: { - name: "COSMOS", - defaultDecimals: 6, - addressPatterns: ["^(cosmos1)[0-9a-z]{38}$"], - feeAssets: [{ blockchain: "COSMOS", symbol: "ATOM", address: null }], - logo: "https://api.rango.exchange/blockchains/cosmos.svg", - displayName: "Cosmos", - shortName: "Cosmos", - sort: 8, - color: "#2E3148", - enabled: true, - type: "COSMOS", - chainId: "cosmoshub-4", - info: { - experimental: false, - rpc: "https://cosmos-rpc.polkachu.com", - rest: "https://lcd-cosmoshub.keplr.app", - cosmostationLcdUrl: "https://lcd-cosmos.cosmostation.io", - cosmostationApiUrl: "https://api-cosmos.cosmostation.io", - cosmostationDenomTracePath: "/ibc/apps/transfer/v1/denom_traces/", - mintScanName: "cosmos", - chainName: "Cosmos", - stakeCurrency: { - coinDenom: "ATOM", - coinMinimalDenom: "uatom", - coinDecimals: 6, - coinGeckoId: "cosmos", - coinImageUrl: "/tokens/blockchain/cosmos.svg", - }, - bip44: { coinType: 118 }, - bech32Config: { - bech32PrefixAccAddr: "cosmos", - bech32PrefixAccPub: "cosmospub", - bech32PrefixValAddr: "cosmosvaloper", - bech32PrefixValPub: "cosmosvaloperpub", - bech32PrefixConsAddr: "cosmosvalcons", - bech32PrefixConsPub: "cosmosvalconspub", - }, - currencies: [ - { - coinDenom: "ATOM", - coinMinimalDenom: "uatom", - coinDecimals: 6, - coinGeckoId: "cosmos", - coinImageUrl: "/tokens/blockchain/cosmos.svg", - }, - ], - feeCurrencies: [ - { - coinDenom: "ATOM", - coinMinimalDenom: "uatom", - coinDecimals: 6, - coinGeckoId: "cosmos", - coinImageUrl: "/tokens/blockchain/cosmos.svg", - }, - ], - features: ["stargate", "ibc-transfer"], - explorerUrlToTx: "https://www.mintscan.io/cosmos/txs/{txHash}", - gasPriceStep: { low: 0.01, average: 0.025, high: 0.04 }, - }, - }, - STARKNET: { - name: "STARKNET", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{64}$"], - feeAssets: [ - { - blockchain: "STARKNET", - symbol: "ETH", - address: - "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", - }, - ], - logo: "https://api.rango.exchange/blockchains/starknet.svg", - displayName: "StarkNet", - shortName: "StarkNet", - sort: 8, - color: "#28286E", - enabled: true, - type: "ZK_ROLLUP", - chainId: "SN_MAIN", - info: null, - }, - FANTOM: { - name: "FANTOM", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "FANTOM", symbol: "FTM", address: null }], - logo: "https://api.rango.exchange/blockchains/fantom.png", - displayName: "Fantom", - shortName: "Fantom", - sort: 9, - color: "#337afe", - enabled: true, - type: "EVM", - chainId: "0xfa", - info: { - chainName: "Fantom Opera", - nativeCurrency: { name: "FTM", symbol: "FTM", decimals: 18 }, - rpcUrls: ["https://rpc.ftm.tools"], - blockExplorerUrls: ["https://ftmscan.com"], - addressUrl: "https://ftmscan.com/address/{wallet}", - transactionUrl: "https://ftmscan.com/tx/{txHash}", - }, - }, - OPTIMISM: { - name: "OPTIMISM", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "OPTIMISM", symbol: "ETH", address: null }], - logo: "https://api.rango.exchange/blockchains/optimism.svg", - displayName: "Optimism", - shortName: "Optimism", - sort: 10, - color: "#FF0420", - enabled: true, - type: "EVM", - chainId: "0xa", - info: { - chainName: "Optimism", - nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 }, - rpcUrls: ["https://mainnet.optimism.io"], - blockExplorerUrls: ["https://optimistic.etherscan.io"], - addressUrl: "https://optimistic.etherscan.io/address/{wallet}", - transactionUrl: "https://optimistic.etherscan.io/tx/{txHash}", - }, - }, - SOLANA: { - name: "SOLANA", - defaultDecimals: 9, - addressPatterns: ["^[1-9A-HJ-NP-Za-km-z]{32,44}$"], - feeAssets: [{ blockchain: "SOLANA", symbol: "SOL", address: null }], - logo: "https://api.rango.exchange/blockchains/solana.svg", - displayName: "Solana", - shortName: "Solana", - sort: 11, - color: "#708DD2", - enabled: true, - type: "SOLANA", - chainId: "mainnet-beta", - info: null, - }, - OKC: { - name: "OKC", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "OKC", symbol: "OKT", address: null }], - logo: "https://api.rango.exchange/blockchains/okx.png", - displayName: "OKX Chain (OKC)", - shortName: "Okx", - sort: 11, - color: "#29a0f0", - enabled: true, - type: "EVM", - chainId: "0x42", - info: { - chainName: "OKX Chain", - nativeCurrency: { name: "OKT", symbol: "OKT", decimals: 18 }, - rpcUrls: ["https://exchainrpc.okex.org"], - blockExplorerUrls: ["https://www.oklink.com/en/okc"], - addressUrl: "https://www.oklink.com/en/okc/address/{wallet}", - transactionUrl: "https://www.oklink.com/en/okc/tx/{txHash}", - }, - }, - CRONOS: { - name: "CRONOS", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "CRONOS", symbol: "CRO", address: null }], - logo: "https://api.rango.exchange/blockchains/cronos.svg", - displayName: "Cronos", - shortName: "Cronos", - sort: 12, - color: "#1a90ff", - enabled: true, - type: "EVM", - chainId: "0x19", - info: { - chainName: "Cronos Mainnet Beta", - nativeCurrency: { name: "CRO", symbol: "CRO", decimals: 18 }, - rpcUrls: ["https://cronosrpc-1.xstaking.sg"], - blockExplorerUrls: ["https://cronoscan.com"], - addressUrl: "https://cronoscan.com/address/{wallet}", - transactionUrl: "https://cronoscan.com/tx/{txHash}", - }, - }, - MOONRIVER: { - name: "MOONRIVER", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "MOONRIVER", symbol: "MOVR", address: null }], - logo: "https://api.rango.exchange/blockchains/moonriver.svg", - displayName: "MoonRiver", - shortName: "MoonRiver", - sort: 13, - color: "#F3B404", - enabled: true, - type: "EVM", - chainId: "0x505", - info: { - chainName: "MoonRiver", - nativeCurrency: { name: "MOVR", symbol: "MOVR", decimals: 18 }, - rpcUrls: ["https://rpc.moonriver.moonbeam.network"], - blockExplorerUrls: ["https://moonriver.moonscan.io"], - addressUrl: "https://moonriver.moonscan.io/address/{wallet}", - transactionUrl: "https://moonriver.moonscan.io/tx/{txHash}", - }, - }, - MOONBEAM: { - name: "MOONBEAM", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "MOONBEAM", symbol: "GLMR", address: null }], - logo: "https://api.rango.exchange/blockchains/moonbeam.png", - displayName: "MoonBeam", - shortName: "MoonBeam", - sort: 14, - color: "#B3206B", - enabled: true, - type: "EVM", - chainId: "0x504", - info: { - chainName: "MoonBeam", - nativeCurrency: { name: "GLMR", symbol: "GLMR", decimals: 18 }, - rpcUrls: ["https://rpc.api.moonbeam.network"], - blockExplorerUrls: ["https://moonbeam.moonscan.io"], - addressUrl: "https://moonbeam.moonscan.io/address/{wallet}", - transactionUrl: "https://moonbeam.moonscan.io/tx/{txHash}", - }, - }, - HECO: { - name: "HECO", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "HECO", symbol: "HT", address: null }], - logo: "https://api.rango.exchange/blockchains/heco.png", - displayName: "Heco", - shortName: "Heco", - sort: 15, - color: "#4CA852", - enabled: true, - type: "EVM", - chainId: "0x80", - info: { - chainName: "Huobi ECO Chain Mainnet", - nativeCurrency: { name: "HT", symbol: "HT", decimals: 18 }, - rpcUrls: ["https://http-mainnet.hecochain.com"], - blockExplorerUrls: ["https://hecoinfo.com"], - addressUrl: "https://hecoinfo.com/address/{wallet}", - transactionUrl: "https://hecoinfo.com/tx/{txHash}", - }, - }, - AURORA: { - name: "AURORA", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "AURORA", symbol: "ETH", address: null }], - logo: "https://api.rango.exchange/blockchains/aurora.svg", - displayName: "Aurora", - shortName: "Aurora", - sort: 15, - color: "#78d64b", - enabled: true, - type: "EVM", - chainId: "0x4e454152", - info: { - chainName: "Aurora Mainnet", - nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 }, - rpcUrls: ["https://mainnet.aurora.dev"], - blockExplorerUrls: ["https://explorer.mainnet.aurora.dev"], - addressUrl: "https://explorer.mainnet.aurora.dev/address/{wallet}", - transactionUrl: "https://explorer.mainnet.aurora.dev/tx/{txHash}", - }, - }, - HARMONY: { - name: "HARMONY", - defaultDecimals: 18, - addressPatterns: ["^(one1)[0-9a-z]{38}$", "^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "HARMONY", symbol: "ONE", address: null }], - logo: "https://api.rango.exchange/blockchains/harmony.svg", - displayName: "Harmony", - shortName: "Harmony", - sort: 15, - color: "#50AEE9", - enabled: true, - type: "EVM", - chainId: "0x63564c40", - info: { - chainName: "Harmony Mainnet", - nativeCurrency: { name: "ONE", symbol: "ONE", decimals: 18 }, - rpcUrls: ["https://api.s0.t.hmny.io"], - blockExplorerUrls: ["https://explorer.harmony.one"], - addressUrl: "https://explorer.harmony.one/address/{wallet}", - transactionUrl: "https://explorer.harmony.one/tx/{txHash}", - }, - }, - EVMOS: { - name: "EVMOS", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "EVMOS", symbol: "EVMOS", address: null }], - logo: "https://api.rango.exchange/blockchains/evmos.png", - displayName: "Evmos", - shortName: "Evmos", - sort: 15, - color: "#2D2925", - enabled: true, - type: "EVM", - chainId: "0x2329", - info: { - chainName: "Evmos", - nativeCurrency: { name: "EVMOS", symbol: "EVMOS", decimals: 18 }, - rpcUrls: ["https://eth.bd.evmos.org:8545"], - blockExplorerUrls: ["https://evm.evmos.org"], - addressUrl: "https://evm.evmos.org/address/{wallet}", - transactionUrl: "https://evm.evmos.org/tx/{txHash}", - }, - }, - SIF: { - name: "SIF", - defaultDecimals: 18, - addressPatterns: ["^(sif1)[0-9a-z]{38}$"], - feeAssets: [{ blockchain: "SIF", symbol: "ROWAN", address: null }], - logo: "https://api.rango.exchange/blockchains/sif.png", - displayName: "Sifchain", - shortName: "Sifchain", - sort: 16, - color: "#CAAA3A", - enabled: true, - type: "COSMOS", - chainId: "sifchain-1", - info: { - experimental: false, - rpc: "https://rpc.sifchain.finance", - rest: "https://api-int.sifchain.finance", - cosmostationLcdUrl: "https://lcd-sifchain.cosmostation.io", - cosmostationApiUrl: "https://api-sifchain.cosmostation.io", - cosmostationDenomTracePath: "/ibc/apps/transfer/v1/denom_traces/", - mintScanName: "sifchain", - chainName: "Sifchain", - stakeCurrency: { - coinDenom: "ROWAN", - coinMinimalDenom: "rowan", - coinDecimals: 18, - coinGeckoId: "", - coinImageUrl: "", - }, - bip44: { coinType: 118 }, - bech32Config: { - bech32PrefixAccAddr: "sif", - bech32PrefixAccPub: "sifpub", - bech32PrefixValAddr: "sifvaloper", - bech32PrefixValPub: "sifvaloperpub", - bech32PrefixConsAddr: "sifvalcons", - bech32PrefixConsPub: "sifvalconspub", - }, - currencies: [ - { - coinDenom: "ROWAN", - coinMinimalDenom: "rowan", - coinDecimals: 18, - coinGeckoId: "", - coinImageUrl: "", - }, - ], - feeCurrencies: [ - { - coinDenom: "ROWAN", - coinMinimalDenom: "rowan", - coinDecimals: 18, - coinGeckoId: "", - coinImageUrl: "", - }, - ], - features: ["stargate", "ibc-transfer"], - explorerUrlToTx: "https://www.mintscan.io/sifchain/txs/{txHash}", - gasPriceStep: { - low: 1000000000000, - average: 1500000000000, - high: 2000000000000, - }, - }, - }, - THOR: { - name: "THOR", - defaultDecimals: 8, - addressPatterns: ["^(thor1)[0-9a-z]{38}$"], - feeAssets: [{ blockchain: "THOR", symbol: "RUNE", address: null }], - logo: "https://api.rango.exchange/blockchains/thorchain.svg", - displayName: "Thorchain", - shortName: "Thorchain", - sort: 17, - color: "#1AE6CB", - enabled: true, - type: "TRANSFER", - chainId: null, - info: null, - }, - BNB: { - name: "BNB", - defaultDecimals: 8, - addressPatterns: ["^(bnb1)[0-9a-z]{38}$"], - feeAssets: [{ blockchain: "BNB", symbol: "BNB", address: null }], - logo: "https://api.rango.exchange/blockchains/bnb.svg", - displayName: "Binance Chain", - shortName: "BNB", - sort: 18, - color: "#F3BA2F", - enabled: true, - type: "COSMOS", - chainId: null, - info: null, - }, - STARGAZE: { - name: "STARGAZE", - defaultDecimals: 6, - addressPatterns: ["^(stars1)[0-9a-z]{38}$"], - feeAssets: [{ blockchain: "STARGAZE", symbol: "STARS", address: null }], - logo: "https://api.rango.exchange/blockchains/stargaze.png", - displayName: "Stargaze", - shortName: "Stargaze", - sort: 19, - color: "#231B60", - enabled: true, - type: "COSMOS", - chainId: "stargaze-1", - info: { - experimental: false, - rpc: "https://rpc.stargaze-apis.com", - rest: "https://rest.stargaze-apis.com", - cosmostationLcdUrl: "https://lcd-stargaze.cosmostation.io", - cosmostationApiUrl: "https://api-stargaze.cosmostation.io", - cosmostationDenomTracePath: "/ibc/apps/transfer/v1/denom_traces/", - mintScanName: "stargaze", - chainName: "Stargaze", - stakeCurrency: { - coinDenom: "STARS", - coinMinimalDenom: "ustars", - coinDecimals: 6, - coinGeckoId: "pool:ustars", - coinImageUrl: "/tokens/blockchain/STARS.png", - }, - bip44: { coinType: 118 }, - bech32Config: { - bech32PrefixAccAddr: "stars", - bech32PrefixAccPub: "starspub", - bech32PrefixValAddr: "starsvaloper", - bech32PrefixValPub: "starsvaloperpub", - bech32PrefixConsAddr: "starsvalcons", - bech32PrefixConsPub: "starsvalconspub", - }, - currencies: [ - { - coinDenom: "STARS", - coinMinimalDenom: "ustars", - coinDecimals: 6, - coinGeckoId: "pool:ustars", - coinImageUrl: "/tokens/blockchain/STARS.png", - }, - ], - feeCurrencies: [ - { - coinDenom: "STARS", - coinMinimalDenom: "ustars", - coinDecimals: 6, - coinGeckoId: "pool:ustars", - coinImageUrl: "/tokens/blockchain/STARS.png", - }, - ], - features: ["stargate", "ibc-transfer", "no-legacy-stdTx"], - explorerUrlToTx: "https://www.mintscan.io/stargaze/txs/{txHash}", - gasPriceStep: { low: 1, average: 1, high: 1 }, - }, - }, - BTC: { - name: "BTC", - defaultDecimals: 8, - addressPatterns: [ - "^[13][a-km-zA-HJ-NP-Z1-9]{25,34}$|^(bc1)[0-9A-Za-z]{39,59}$", - ], - feeAssets: [{ blockchain: "BTC", symbol: "BTC", address: null }], - logo: "https://api.rango.exchange/blockchains/btc.svg", - displayName: "Bitcoin", - shortName: "BTC", - sort: 20, - color: "#F7931A", - enabled: true, - type: "TRANSFER", - chainId: null, - info: null, - }, - CRYPTO_ORG: { - name: "CRYPTO_ORG", - defaultDecimals: 8, - addressPatterns: ["^(cro1)[0-9a-z]{38}$"], - feeAssets: [{ blockchain: "CRYPTO_ORG", symbol: "CRO", address: null }], - logo: "https://api.rango.exchange/blockchains/crypto_org.png", - displayName: "Crypto.org", - shortName: "Crypto.org", - sort: 21, - color: "#103F68", - enabled: true, - type: "COSMOS", - chainId: "crypto-org-chain-mainnet-1", - info: { - experimental: false, - rpc: "https://rpc-crypto-org.keplr.app", - rest: "https://lcd-crypto-org.keplr.app", - cosmostationLcdUrl: "https://lcd-cryptocom.cosmostation.io", - cosmostationApiUrl: "https://api-cryptocom.cosmostation.io", - cosmostationDenomTracePath: "/ibc/apps/transfer/v1/denom_traces/", - mintScanName: "crypto-org", - chainName: "Crypto.org", - stakeCurrency: { - coinDenom: "CRO", - coinMinimalDenom: "basecro", - coinDecimals: 8, - coinGeckoId: "crypto-com-chain", - coinImageUrl: "/tokens/blockchain/cro.png", - }, - bip44: { coinType: 394 }, - bech32Config: { - bech32PrefixAccAddr: "cro", - bech32PrefixAccPub: "cropub", - bech32PrefixValAddr: "crovaloper", - bech32PrefixValPub: "crovaloperpub", - bech32PrefixConsAddr: "crovalcons", - bech32PrefixConsPub: "crovalconspub", - }, - currencies: [ - { - coinDenom: "CRO", - coinMinimalDenom: "basecro", - coinDecimals: 8, - coinGeckoId: "crypto-com-chain", - coinImageUrl: "/tokens/blockchain/cro.png", - }, - ], - feeCurrencies: [ - { - coinDenom: "CRO", - coinMinimalDenom: "basecro", - coinDecimals: 8, - coinGeckoId: "crypto-com-chain", - coinImageUrl: "/tokens/blockchain/cro.png", - }, - ], - features: ["stargate", "ibc-transfer"], - explorerUrlToTx: "https://www.mintscan.io/crypto-org/txs/{txHash}", - gasPriceStep: { low: 0.025, average: 0.03, high: 0.04 }, - }, - }, - CHIHUAHUA: { - name: "CHIHUAHUA", - defaultDecimals: 6, - addressPatterns: ["^(chihuahua1)[0-9a-z]{38}$"], - feeAssets: [{ blockchain: "CHIHUAHUA", symbol: "HUAHUA", address: null }], - logo: "https://api.rango.exchange/blockchains/chihuahua.png", - displayName: "Chihuahua", - shortName: "Chihuahua", - sort: 22, - color: "#EFC92B", - enabled: true, - type: "COSMOS", - chainId: "chihuahua-1", - info: { - experimental: true, - rpc: "https://rpc.chihuahua.wtf/", - rest: "https://api.chihuahua.wtf/", - cosmostationLcdUrl: "https://lcd-chihuahua.cosmostation.io", - cosmostationApiUrl: "https://api-chihuahua.cosmostation.io", - cosmostationDenomTracePath: "/ibc/apps/transfer/v1/denom_traces/", - mintScanName: "chihuahua", - chainName: "Chihuahua", - stakeCurrency: { - coinDenom: "HUAHUA", - coinMinimalDenom: "uhuahua", - coinDecimals: 6, - coinGeckoId: "pool:uhuahua", - coinImageUrl: "/tokens/blockchain/HUAHUA.svg", - }, - bip44: { coinType: 118 }, - bech32Config: { - bech32PrefixAccAddr: "chihuahua", - bech32PrefixAccPub: "chihuahuapub", - bech32PrefixValAddr: "chihuahuavaloper", - bech32PrefixValPub: "chihuahuavaloperpub", - bech32PrefixConsAddr: "chihuahuavalcons", - bech32PrefixConsPub: "chihuahuavalconspub", - }, - currencies: [ - { - coinDenom: "HUAHUA", - coinMinimalDenom: "uhuahua", - coinDecimals: 6, - coinGeckoId: "pool:uhuahua", - coinImageUrl: "/tokens/blockchain/HUAHUA.svg", - }, - ], - feeCurrencies: [ - { - coinDenom: "HUAHUA", - coinMinimalDenom: "uhuahua", - coinDecimals: 6, - coinGeckoId: "pool:uhuahua", - coinImageUrl: "/tokens/blockchain/HUAHUA.svg", - }, - ], - features: ["stargate", "ibc-transfer", "no-legacy-stdTx"], - explorerUrlToTx: "https://ping.pub/chihuahua/tx/{txHash}", - gasPriceStep: { low: 0.025, average: 0.03, high: 0.035 }, - }, - }, - BANDCHAIN: { - name: "BANDCHAIN", - defaultDecimals: 6, - addressPatterns: ["^(band1)[0-9a-z]{38}$"], - feeAssets: [{ blockchain: "BANDCHAIN", symbol: "BAND", address: null }], - logo: "https://api.rango.exchange/blockchains/bandchain.svg", - displayName: "BandChain", - shortName: "BandChain", - sort: 23, - color: "#4520E6", - enabled: true, - type: "COSMOS", - chainId: "laozi-mainnet", - info: { - experimental: true, - rpc: "https://rpc.laozi3.bandchain.org/", - rest: "https://lcd-band.cosmostation.io", - cosmostationLcdUrl: "https://lcd-band.cosmostation.io", - cosmostationApiUrl: "https://api-band.cosmostation.io", - cosmostationDenomTracePath: "/ibc/apps/transfer/v1/denom_traces/", - mintScanName: "band", - chainName: "BandChain", - stakeCurrency: { - coinDenom: "BAND", - coinMinimalDenom: "uband", - coinDecimals: 6, - coinGeckoId: "band-protocol", - coinImageUrl: "/tokens/blockchain/BAND.svg", - }, - bip44: { coinType: 494 }, - bech32Config: { - bech32PrefixAccAddr: "band", - bech32PrefixAccPub: "bandpub", - bech32PrefixValAddr: "bandvaloper", - bech32PrefixValPub: "bandvaloperpub", - bech32PrefixConsAddr: "bandvalcons", - bech32PrefixConsPub: "bandvalconspub", - }, - currencies: [ - { - coinDenom: "BAND", - coinMinimalDenom: "uband", - coinDecimals: 6, - coinGeckoId: "band-protocol", - coinImageUrl: "/tokens/blockchain/BAND.svg", - }, - ], - feeCurrencies: [ - { - coinDenom: "BAND", - coinMinimalDenom: "uband", - coinDecimals: 6, - coinGeckoId: "band-protocol", - coinImageUrl: "/tokens/blockchain/BAND.svg", - }, - ], - features: ["stargate", "ibc-transfer", "no-legacy-stdTx"], - explorerUrlToTx: "https://cosmoscan.io/tx/{txHash}", - gasPriceStep: null, - }, - }, - COMDEX: { - name: "COMDEX", - defaultDecimals: 6, - addressPatterns: ["^(comdex1)[0-9a-z]{38}$"], - feeAssets: [{ blockchain: "COMDEX", symbol: "CMDX", address: null }], - logo: "https://api.rango.exchange/blockchains/comdex.svg", - displayName: "Comdex", - shortName: "Comdex", - sort: 23, - color: "#FE4350", - enabled: true, - type: "COSMOS", - chainId: "comdex-1", - info: { - experimental: true, - rpc: "https://rpc.comdex.one", - rest: "https://rest.comdex.one", - cosmostationLcdUrl: "https://lcd-comdex.cosmostation.io", - cosmostationApiUrl: "https://api-comdex.cosmostation.io", - cosmostationDenomTracePath: "/ibc/apps/transfer/v1/denom_traces/", - mintScanName: "comdex", - chainName: "Comdex", - stakeCurrency: { - coinDenom: "CMDX", - coinMinimalDenom: "ucmdx", - coinDecimals: 6, - coinGeckoId: "comdex", - coinImageUrl: "/tokens/blockchain/CMDX.png", - }, - bip44: { coinType: 118 }, - bech32Config: { - bech32PrefixAccAddr: "comdex", - bech32PrefixAccPub: "comdexpub", - bech32PrefixValAddr: "comdexvaloper", - bech32PrefixValPub: "comdexvaloperpub", - bech32PrefixConsAddr: "comdexvalcons", - bech32PrefixConsPub: "comdexvalconspub", - }, - currencies: [ - { - coinDenom: "CMDX", - coinMinimalDenom: "ucmdx", - coinDecimals: 6, - coinGeckoId: "comdex", - coinImageUrl: "/tokens/blockchain/CMDX.png", - }, - ], - feeCurrencies: [ - { - coinDenom: "CMDX", - coinMinimalDenom: "ucmdx", - coinDecimals: 6, - coinGeckoId: "comdex", - coinImageUrl: "/tokens/blockchain/CMDX.png", - }, - ], - features: ["stargate", "ibc-transfer", "no-legacy-stdTx"], - explorerUrlToTx: "https://www.mintscan.io/comdex/txs/{txHash}", - gasPriceStep: null, - }, - }, - REGEN: { - name: "REGEN", - defaultDecimals: 6, - addressPatterns: ["^(regen1)[0-9a-z]{38}$"], - feeAssets: [{ blockchain: "REGEN", symbol: "REGEN", address: null }], - logo: "https://api.rango.exchange/blockchains/regen.png", - displayName: "Regen Network", - shortName: "Regen Network", - sort: 24, - color: "#4FB573", - enabled: true, - type: "COSMOS", - chainId: "regen-1", - info: { - experimental: false, - rpc: "https://rpc-regen.keplr.app", - rest: "https://lcd-regen.keplr.app", - cosmostationLcdUrl: "https://lcd-regen.keplr.app", - cosmostationApiUrl: "https://api-regen.cosmostation.io/", - cosmostationDenomTracePath: "/ibc/apps/transfer/v1/denom_traces/", - mintScanName: "regen", - chainName: "Regen Network", - stakeCurrency: { - coinDenom: "REGEN", - coinMinimalDenom: "uregen", - coinDecimals: 6, - coinGeckoId: "pool:uregen", - coinImageUrl: "/tokens/blockchain/regen.png", - }, - bip44: { coinType: 118 }, - bech32Config: { - bech32PrefixAccAddr: "regen", - bech32PrefixAccPub: "regenpub", - bech32PrefixValAddr: "regenvaloper", - bech32PrefixValPub: "regenvaloperpub", - bech32PrefixConsAddr: "regenvalcons", - bech32PrefixConsPub: "regenvalconspub", - }, - currencies: [ - { - coinDenom: "REGEN", - coinMinimalDenom: "uregen", - coinDecimals: 6, - coinGeckoId: "pool:uregen", - coinImageUrl: "/tokens/blockchain/regen.png", - }, - ], - feeCurrencies: [ - { - coinDenom: "REGEN", - coinMinimalDenom: "uregen", - coinDecimals: 6, - coinGeckoId: "pool:uregen", - coinImageUrl: "/tokens/blockchain/regen.png", - }, - ], - features: ["stargate", "ibc-transfer"], - explorerUrlToTx: "https://regen.aneka.io/txs/{txHash}", - gasPriceStep: { low: 0.015, average: 0.025, high: 0.04 }, - }, - }, - IRIS: { - name: "IRIS", - defaultDecimals: 6, - addressPatterns: ["^(iaa1)[0-9a-z]{38}$"], - feeAssets: [{ blockchain: "IRIS", symbol: "IRIS", address: null }], - logo: "https://api.rango.exchange/blockchains/iris.png", - displayName: "IRISnet", - shortName: "IRISnet", - sort: 25, - color: "#8A4A8E", - enabled: true, - type: "COSMOS", - chainId: "irishub-1", - info: { - experimental: false, - rpc: "https://rpc-iris.keplr.app", - rest: "https://lcd-iris.keplr.app", - cosmostationLcdUrl: "https://lcd-iris.cosmostation.io", - cosmostationApiUrl: "https://api-iris.cosmostation.io", - cosmostationDenomTracePath: "/ibc/apps/transfer/v1/denom_traces/", - mintScanName: "iris", - chainName: "IRISnet", - stakeCurrency: { - coinDenom: "IRIS", - coinMinimalDenom: "uiris", - coinDecimals: 6, - coinGeckoId: "iris-network", - coinImageUrl: "/tokens/blockchain/iris.svg", - }, - bip44: { coinType: 118 }, - bech32Config: { - bech32PrefixAccAddr: "iaa", - bech32PrefixAccPub: "iaapub", - bech32PrefixValAddr: "iaavaloper", - bech32PrefixValPub: "iaavaloperpub", - bech32PrefixConsAddr: "iaavalcons", - bech32PrefixConsPub: "iaavalconspub", - }, - currencies: [ - { - coinDenom: "IRIS", - coinMinimalDenom: "uiris", - coinDecimals: 6, - coinGeckoId: "iris-network", - coinImageUrl: "/tokens/blockchain/iris.svg", - }, - ], - feeCurrencies: [ - { - coinDenom: "IRIS", - coinMinimalDenom: "uiris", - coinDecimals: 6, - coinGeckoId: "iris-network", - coinImageUrl: "/tokens/blockchain/iris.svg", - }, - ], - features: ["stargate", "ibc-transfer"], - explorerUrlToTx: "https://www.mintscan.io/iris/txs/{txHash}", - gasPriceStep: { low: 0.2, average: 0.3, high: 0.4 }, - }, - }, - EMONEY: { - name: "EMONEY", - defaultDecimals: 6, - addressPatterns: ["^(emoney1)[0-9a-z]{38}$"], - feeAssets: [{ blockchain: "EMONEY", symbol: "NGM", address: null }], - logo: "https://api.rango.exchange/blockchains/emoney.svg", - displayName: "e-Money", - shortName: "e-Money", - sort: 25, - color: "#DFF5EF", - enabled: true, - type: "COSMOS", - chainId: "emoney-3", - info: { - experimental: true, - rpc: "https://rpc-emoney.keplr.app", - rest: "https://lcd-emoney.keplr.app", - cosmostationLcdUrl: "https://lcd-emoney.cosmostation.io", - cosmostationApiUrl: "https://api-emoney.cosmostation.io", - cosmostationDenomTracePath: - "/ibc/applications/transfer/v1beta1/denom_traces/", - mintScanName: "emoney", - chainName: "e-Money", - stakeCurrency: { - coinDenom: "NGM", - coinMinimalDenom: "ungm", - coinDecimals: 6, - coinGeckoId: "e-money", - coinImageUrl: "/tokens/blockchain/NGM.png", - }, - bip44: { coinType: 118 }, - bech32Config: { - bech32PrefixAccAddr: "emoney", - bech32PrefixAccPub: "emoneypub", - bech32PrefixValAddr: "emoneyvaloper", - bech32PrefixValPub: "emoneyvaloperpub", - bech32PrefixConsAddr: "emoneyvalcons", - bech32PrefixConsPub: "emoneyvalconspub", - }, - currencies: [ - { - coinDenom: "NGM", - coinMinimalDenom: "ungm", - coinDecimals: 6, - coinGeckoId: "e-money", - coinImageUrl: "/tokens/blockchain/NGM.png", - }, - { - coinDenom: "EEUR", - coinMinimalDenom: "eeur", - coinDecimals: 6, - coinGeckoId: "e-money-eur", - coinImageUrl: "/tokens/blockchain/EEUR.png", - }, - ], - feeCurrencies: [ - { - coinDenom: "NGM", - coinMinimalDenom: "ungm", - coinDecimals: 6, - coinGeckoId: "e-money", - coinImageUrl: "/tokens/blockchain/NGM.png", - }, - ], - features: ["stargate", "ibc-transfer"], - explorerUrlToTx: "https://emoney.bigdipper.live/transactions/{txHash}", - gasPriceStep: { low: 1, average: 1, high: 1 }, - }, - }, - GNOSIS: { - name: "GNOSIS", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "GNOSIS", symbol: "XDAI", address: null }], - logo: "https://api.rango.exchange/blockchains/gnosis.svg", - displayName: "Gnosis", - shortName: "Gnosis", - sort: 26, - color: "#3E6957", - enabled: true, - type: "EVM", - chainId: "0x64", - info: { - chainName: "Gnosis Chain", - nativeCurrency: { name: "XDAI", symbol: "XDAI", decimals: 18 }, - rpcUrls: ["https://rpc.gnosischain.com"], - blockExplorerUrls: ["https://blockscout.com/xdai/mainnet"], - addressUrl: "https://blockscout.com/xdai/mainnet/address/{wallet}", - transactionUrl: "https://blockscout.com/xdai/mainnet/tx/{txHash}", - }, - }, - LTC: { - name: "LTC", - defaultDecimals: 8, - addressPatterns: ["^(L|M|3)[A-Za-z0-9]{33}$|^(ltc1)[0-9A-Za-z]{39}$"], - feeAssets: [{ blockchain: "LTC", symbol: "LTC", address: null }], - logo: "https://api.rango.exchange/blockchains/ltc.svg", - displayName: "LiteCoin", - shortName: "LTC", - sort: 27, - color: "#345D9D", - enabled: true, - type: "TRANSFER", - chainId: null, - info: null, - }, - BCH: { - name: "BCH", - defaultDecimals: 8, - addressPatterns: [ - "^[13][a-km-zA-HJ-NP-Z1-9]{25,34}$|^[0-9A-Za-z]{42,42}$", - ], - feeAssets: [{ blockchain: "BCH", symbol: "BCH", address: null }], - logo: "https://api.rango.exchange/blockchains/bch.svg", - displayName: "Bitcoin Cash", - shortName: "BCH", - sort: 28, - color: "#0AC18E", - enabled: true, - type: "TRANSFER", - chainId: null, - info: null, - }, - FUSE: { - name: "FUSE", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "FUSE", symbol: "FUSE", address: null }], - logo: "https://api.rango.exchange/blockchains/fuse.png", - displayName: "Fuse", - shortName: "Fuse", - sort: 29, - color: "#C5F9AD", - enabled: true, - type: "EVM", - chainId: "0x7a", - info: { - chainName: "Fuse Mainnet", - nativeCurrency: { name: "FUSE", symbol: "FUSE", decimals: 18 }, - rpcUrls: ["https://rpc.fuse.io"], - blockExplorerUrls: ["https://explorer.fuse.io"], - addressUrl: "https://explorer.fuse.io/address/{wallet}", - transactionUrl: "https://explorer.fuse.io/tx/{txHash}", - }, - }, - AKASH: { - name: "AKASH", - defaultDecimals: 6, - addressPatterns: ["^(akash1)[0-9a-z]{38}$"], - feeAssets: [{ blockchain: "AKASH", symbol: "AKT", address: null }], - logo: "https://api.rango.exchange/blockchains/akash.svg", - displayName: "Akash", - shortName: "Akash", - sort: 30, - color: "#ED3524", - enabled: true, - type: "COSMOS", - chainId: "akashnet-2", - info: { - experimental: false, - rpc: "https://rpc-akash.keplr.app", - rest: "https://lcd-akash.keplr.app", - cosmostationLcdUrl: "https://lcd-akash.cosmostation.io", - cosmostationApiUrl: "https://api-akash.cosmostation.io", - cosmostationDenomTracePath: "/ibc/apps/transfer/v1/denom_traces/", - mintScanName: "akash", - chainName: "Akash", - stakeCurrency: { - coinDenom: "AKT", - coinMinimalDenom: "uakt", - coinDecimals: 6, - coinGeckoId: "akash-network", - coinImageUrl: "/tokens/blockchain/akt.svg", - }, - bip44: { coinType: 118 }, - bech32Config: { - bech32PrefixAccAddr: "akash", - bech32PrefixAccPub: "akashpub", - bech32PrefixValAddr: "akashvaloper", - bech32PrefixValPub: "akashvaloperpub", - bech32PrefixConsAddr: "akashvalcons", - bech32PrefixConsPub: "akashvalconspub", - }, - currencies: [ - { - coinDenom: "AKT", - coinMinimalDenom: "uakt", - coinDecimals: 6, - coinGeckoId: "akash-network", - coinImageUrl: "/tokens/blockchain/akt.svg", - }, - ], - feeCurrencies: [ - { - coinDenom: "AKT", - coinMinimalDenom: "uakt", - coinDecimals: 6, - coinGeckoId: "akash-network", - coinImageUrl: "/tokens/blockchain/akt.svg", - }, - ], - features: ["stargate", "ibc-transfer"], - explorerUrlToTx: "https://www.mintscan.io/akash/txs/{txHash}", - gasPriceStep: { low: 0.001, average: 0.0025, high: 0.004 }, - }, - }, - KI: { - name: "KI", - defaultDecimals: 6, - addressPatterns: ["^(ki1)[0-9a-z]{38}$"], - feeAssets: [{ blockchain: "KI", symbol: "XKI", address: null }], - logo: "https://api.rango.exchange/blockchains/ki.png", - displayName: "Ki", - shortName: "Ki", - sort: 30, - color: "#0F2B3D", - enabled: true, - type: "COSMOS", - chainId: "kichain-2", - info: { - experimental: true, - rpc: "https://rpc-mainnet.blockchain.ki", - rest: "https://api-mainnet.blockchain.ki", - cosmostationLcdUrl: "https://lcd-kichain.cosmostation.io", - cosmostationApiUrl: "https://api-kichain.cosmostation.io", - cosmostationDenomTracePath: "/ibc/apps/transfer/v1/denom_traces/", - mintScanName: "ki-chain", - chainName: "Ki", - stakeCurrency: { - coinDenom: "XKI", - coinMinimalDenom: "uxki", - coinDecimals: 6, - coinGeckoId: "pool:uxki", - coinImageUrl: "/tokens/blockchain/XKI.png", - }, - bip44: { coinType: 118 }, - bech32Config: { - bech32PrefixAccAddr: "ki", - bech32PrefixAccPub: "kipub", - bech32PrefixValAddr: "kivaloper", - bech32PrefixValPub: "kivaloperpub", - bech32PrefixConsAddr: "kivalcons", - bech32PrefixConsPub: "kivalconspub", - }, - currencies: [ - { - coinDenom: "XKI", - coinMinimalDenom: "uxki", - coinDecimals: 6, - coinGeckoId: "pool:uxki", - coinImageUrl: "/tokens/blockchain/XKI.png", - }, - ], - feeCurrencies: [ - { - coinDenom: "XKI", - coinMinimalDenom: "uxki", - coinDecimals: 6, - coinGeckoId: "pool:uxki", - coinImageUrl: "/tokens/blockchain/XKI.png", - }, - ], - features: ["stargate", "ibc-transfer"], - explorerUrlToTx: "https://www.mintscan.io/ki-chain/txs/{txHash}", - gasPriceStep: null, - }, - }, - KUJIRA: { - name: "KUJIRA", - defaultDecimals: 6, - addressPatterns: ["^(kujira1)[0-9a-z]{38}$"], - feeAssets: [{ blockchain: "KUJIRA", symbol: "KUJI", address: null }], - logo: "https://api.rango.exchange/blockchains/kuji.svg", - displayName: "Kujira", - shortName: "Kujira", - sort: 31, - color: "#DF3935", - enabled: true, - type: "COSMOS", - chainId: "kaiyo-1", - info: { - experimental: true, - rpc: "https://rpc.kaiyo.kujira.setten.io", - rest: "https://lcd.kaiyo.kujira.setten.io", - cosmostationLcdUrl: "https://lcd-kujira.cosmostation.io", - cosmostationApiUrl: "https://api-kujira.cosmostation.io", - cosmostationDenomTracePath: "/ibc/apps/transfer/v1/denom_traces/", - mintScanName: "kujira", - chainName: "Kujira", - stakeCurrency: { - coinDenom: "KUJI", - coinMinimalDenom: "ukuji", - coinDecimals: 6, - coinGeckoId: "kujira", - coinImageUrl: "/tokens/blockchain/kuji.svg", - }, - bip44: { coinType: 118 }, - bech32Config: { - bech32PrefixAccAddr: "kujira", - bech32PrefixAccPub: "kujirapub", - bech32PrefixValAddr: "kujiravaloper", - bech32PrefixValPub: "kujiravaloperpub", - bech32PrefixConsAddr: "kujiravalcons", - bech32PrefixConsPub: "kujiravalconspub", - }, - currencies: [ - { - coinDenom: "KUJI", - coinMinimalDenom: "ukuji", - coinDecimals: 6, - coinGeckoId: "kujira", - coinImageUrl: "/tokens/blockchain/kuji.png", - }, - ], - feeCurrencies: [ - { - coinDenom: "KUJI", - coinMinimalDenom: "ukuji", - coinDecimals: 6, - coinGeckoId: "kujira", - coinImageUrl: "/tokens/blockchain/kuji.png", - }, - ], - features: ["stargate", "ibc-transfer"], - explorerUrlToTx: "https://finder.kujira.app/kaiyo-1/tx/{txHash}", - gasPriceStep: { low: 0.01, average: 0.025, high: 0.03 }, - }, - }, - PERSISTENCE: { - name: "PERSISTENCE", - defaultDecimals: 6, - addressPatterns: ["^(persistence1)[0-9a-z]{38}$"], - feeAssets: [{ blockchain: "PERSISTENCE", symbol: "XPRT", address: null }], - logo: "https://api.rango.exchange/blockchains/persistence.png", - displayName: "Persistence", - shortName: "Persistence", - sort: 31, - color: "#383838", - enabled: true, - type: "COSMOS", - chainId: "core-1", - info: { - experimental: false, - rpc: "https://rpc-persistence.keplr.app", - rest: "https://lcd-persistence.keplr.app", - cosmostationLcdUrl: "https://lcd-persistence.cosmostation.io", - cosmostationApiUrl: "https://api-persistence.cosmostation.io", - cosmostationDenomTracePath: "/ibc/apps/transfer/v1/denom_traces/", - mintScanName: "persistence", - chainName: "Persistence", - stakeCurrency: { - coinDenom: "XPRT", - coinMinimalDenom: "uxprt", - coinDecimals: 6, - coinGeckoId: "persistence", - coinImageUrl: "/tokens/blockchain/xprt.png", - }, - bip44: { coinType: 750 }, - bech32Config: { - bech32PrefixAccAddr: "persistence", - bech32PrefixAccPub: "persistencepub", - bech32PrefixValAddr: "persistencevaloper", - bech32PrefixValPub: "persistencevaloperpub", - bech32PrefixConsAddr: "persistencevalcons", - bech32PrefixConsPub: "persistencevalconspub", - }, - currencies: [ - { - coinDenom: "XPRT", - coinMinimalDenom: "uxprt", - coinDecimals: 6, - coinGeckoId: "persistence", - coinImageUrl: "/tokens/blockchain/xprt.png", - }, - ], - feeCurrencies: [ - { - coinDenom: "XPRT", - coinMinimalDenom: "uxprt", - coinDecimals: 6, - coinGeckoId: "persistence", - coinImageUrl: "/tokens/blockchain/xprt.png", - }, - ], - features: ["stargate", "ibc-transfer"], - explorerUrlToTx: "https://www.mintscan.io/persistence/txs/{txHash}", - gasPriceStep: { low: 0, average: 0.025, high: 0.04 }, - }, - }, - SENTINEL: { - name: "SENTINEL", - defaultDecimals: 6, - addressPatterns: ["^(sent1)[0-9a-z]{38}$"], - feeAssets: [{ blockchain: "SENTINEL", symbol: "DVPN", address: null }], - logo: "https://api.rango.exchange/blockchains/sentinel.png", - displayName: "Sentinel", - shortName: "Sentinel", - sort: 32, - color: "#142E51", - enabled: true, - type: "COSMOS", - chainId: "sentinelhub-2", - info: { - experimental: false, - rpc: "https://rpc-sentinel.keplr.app", - rest: "https://lcd-sentinel.keplr.app", - cosmostationLcdUrl: "https://lcd-sentinel.cosmostation.io", - cosmostationApiUrl: "https://api-sentinel.cosmostation.io", - cosmostationDenomTracePath: "/ibc/apps/transfer/v1/denom_traces/", - mintScanName: "sentinel", - chainName: "Sentinel", - stakeCurrency: { - coinDenom: "DVPN", - coinMinimalDenom: "udvpn", - coinDecimals: 6, - coinGeckoId: "sentinel", - coinImageUrl: "/tokens/blockchain/dvpn.png", - }, - bip44: { coinType: 118 }, - bech32Config: { - bech32PrefixAccAddr: "sent", - bech32PrefixAccPub: "sentpub", - bech32PrefixValAddr: "sentvaloper", - bech32PrefixValPub: "sentvaloperpub", - bech32PrefixConsAddr: "sentvalcons", - bech32PrefixConsPub: "sentvalconspub", - }, - currencies: [ - { - coinDenom: "DVPN", - coinMinimalDenom: "udvpn", - coinDecimals: 6, - coinGeckoId: "sentinel", - coinImageUrl: "/tokens/blockchain/dvpn.png", - }, - ], - feeCurrencies: [ - { - coinDenom: "DVPN", - coinMinimalDenom: "udvpn", - coinDecimals: 6, - coinGeckoId: "sentinel", - coinImageUrl: "/tokens/blockchain/dvpn.png", - }, - ], - features: ["stargate", "ibc-transfer"], - explorerUrlToTx: "https://www.mintscan.io/sentinel/txs/{txHash}", - gasPriceStep: { low: 0.1, average: 0.25, high: 0.4 }, - }, - }, - STARNAME: { - name: "STARNAME", - defaultDecimals: 6, - addressPatterns: ["^(star1)[0-9a-z]{38}$"], - feeAssets: [{ blockchain: "STARNAME", symbol: "IOV", address: null }], - logo: "https://api.rango.exchange/blockchains/starname.png", - displayName: "Starname", - shortName: "Starname", - sort: 35, - color: "#BC64BB", - enabled: true, - type: "COSMOS", - chainId: "iov-mainnet-ibc", - info: { - experimental: false, - rpc: "https://rpc-iov.keplr.app", - rest: "https://lcd-iov.keplr.app", - cosmostationLcdUrl: "https://lcd-iov.cosmostation.io", - cosmostationApiUrl: "https://api-iov.cosmostation.io", - cosmostationDenomTracePath: - "/ibc/applications/transfer/v1beta1/denom_traces/", - mintScanName: "starname", - chainName: "Starname", - stakeCurrency: { - coinDenom: "IOV", - coinMinimalDenom: "uiov", - coinDecimals: 6, - coinGeckoId: "starname", - coinImageUrl: "/tokens/blockchain/IOV.png", - }, - bip44: { coinType: 494 }, - bech32Config: { - bech32PrefixAccAddr: "star", - bech32PrefixAccPub: "starpub", - bech32PrefixValAddr: "starvaloper", - bech32PrefixValPub: "starvaloperpub", - bech32PrefixConsAddr: "starvalcons", - bech32PrefixConsPub: "starvalconspub", - }, - currencies: [ - { - coinDenom: "IOV", - coinMinimalDenom: "uiov", - coinDecimals: 6, - coinGeckoId: "starname", - coinImageUrl: "/tokens/blockchain/IOV.png", - }, - ], - feeCurrencies: [ - { - coinDenom: "IOV", - coinMinimalDenom: "uiov", - coinDecimals: 6, - coinGeckoId: "starname", - coinImageUrl: "/tokens/blockchain/IOV.png", - }, - ], - features: ["stargate", "ibc-transfer"], - explorerUrlToTx: "https://www.mintscan.io/starname/txs/{txHash}", - gasPriceStep: { low: 1, average: 2, high: 3 }, - }, - }, - UMEE: { - name: "UMEE", - defaultDecimals: 6, - addressPatterns: ["^(umee1)[0-9a-z]{38}$"], - feeAssets: [{ blockchain: "UMEE", symbol: "UMEE", address: null }], - logo: "https://api.rango.exchange/blockchains/umee.svg", - displayName: "Umee", - shortName: "Umee", - sort: 36, - color: "#D2B6FF", - enabled: true, - type: "COSMOS", - chainId: "umee-1", - info: { - experimental: false, - rpc: "https://api.barnacle.mainnet.network.umee.cc", - rest: "https://lcd-umee.cosmostation.io", - cosmostationLcdUrl: "https://lcd-umee.cosmostation.io", - cosmostationApiUrl: "https://api-umee.cosmostation.io", - cosmostationDenomTracePath: "/ibc/apps/transfer/v1/denom_traces/", - mintScanName: "umee", - chainName: "Umee", - stakeCurrency: { - coinDenom: "UMEE", - coinMinimalDenom: "uumee", - coinDecimals: 6, - coinGeckoId: "pool:uumee", - coinImageUrl: "/tokens/blockchain/UMEE.png", - }, - bip44: { coinType: 118 }, - bech32Config: { - bech32PrefixAccAddr: "umee", - bech32PrefixAccPub: "umeepub", - bech32PrefixValAddr: "umeevaloper", - bech32PrefixValPub: "umeevaloperpub", - bech32PrefixConsAddr: "umeevalcons", - bech32PrefixConsPub: "umeevalconspub", - }, - currencies: [ - { - coinDenom: "UMEE", - coinMinimalDenom: "uumee", - coinDecimals: 6, - coinGeckoId: "pool:uumee", - coinImageUrl: "/tokens/blockchain/UMEE.png", - }, - ], - feeCurrencies: [ - { - coinDenom: "UMEE", - coinMinimalDenom: "uumee", - coinDecimals: 6, - coinGeckoId: "pool:uumee", - coinImageUrl: "/tokens/blockchain/UMEE.png", - }, - ], - features: ["stargate", "ibc-transfer", "no-legacy-stdTx"], - explorerUrlToTx: "https://www.mintscan.io/umee/txs/{txHash}", - gasPriceStep: { low: 0.05, average: 0.06, high: 0.1 }, - }, - }, - BITCANNA: { - name: "BITCANNA", - defaultDecimals: 6, - addressPatterns: ["^(bcna1)[0-9a-z]{38}$"], - feeAssets: [{ blockchain: "BITCANNA", symbol: "BCNA", address: null }], - logo: "https://api.rango.exchange/blockchains/bitcanna.svg", - displayName: "BitCanna", - shortName: "BitCanna", - sort: 36, - color: "#3CC194", - enabled: true, - type: "COSMOS", - chainId: "bitcanna-1", - info: { - experimental: true, - rpc: "https://rpc.bitcanna.io", - rest: "https://lcd.bitcanna.io", - cosmostationLcdUrl: "https://lcd-bitcanna.cosmostation.io", - cosmostationApiUrl: "https://api-bitcanna.cosmostation.io", - cosmostationDenomTracePath: "/ibc/apps/transfer/v1/denom_traces/", - mintScanName: "bitcanna", - chainName: "BitCanna", - stakeCurrency: { - coinDenom: "BCNA", - coinMinimalDenom: "ubcna", - coinDecimals: 6, - coinGeckoId: "bitcanna", - coinImageUrl: "/tokens/blockchain/BCNA.png", - }, - bip44: { coinType: 118 }, - bech32Config: { - bech32PrefixAccAddr: "bcna", - bech32PrefixAccPub: "bcnapub", - bech32PrefixValAddr: "bcnavaloper", - bech32PrefixValPub: "bcnavaloperpub", - bech32PrefixConsAddr: "bcnavalcons", - bech32PrefixConsPub: "bcnavalconspub", - }, - currencies: [ - { - coinDenom: "BCNA", - coinMinimalDenom: "ubcna", - coinDecimals: 6, - coinGeckoId: "bitcanna", - coinImageUrl: "/tokens/blockchain/BCNA.png", - }, - ], - feeCurrencies: [ - { - coinDenom: "BCNA", - coinMinimalDenom: "ubcna", - coinDecimals: 6, - coinGeckoId: "bitcanna", - coinImageUrl: "/tokens/blockchain/BCNA.png", - }, - ], - features: ["stargate", "ibc-transfer", "no-legacy-stdTx"], - explorerUrlToTx: "https://www.mintscan.io/bitcanna/txs/{txHash}", - gasPriceStep: null, - }, - }, - DESMOS: { - name: "DESMOS", - defaultDecimals: 6, - addressPatterns: ["^(desmos1)[0-9a-z]{38}$"], - feeAssets: [{ blockchain: "DESMOS", symbol: "DSM", address: null }], - logo: "https://api.rango.exchange/blockchains/desmos.svg", - displayName: "Desmos", - shortName: "Desmos", - sort: 37, - color: "#DF6952", - enabled: true, - type: "COSMOS", - chainId: "desmos-mainnet", - info: { - experimental: true, - rpc: "https://rpc.mainnet.desmos.network", - rest: "https://api.mainnet.desmos.network", - cosmostationLcdUrl: "https://lcd-desmos.cosmostation.io", - cosmostationApiUrl: "https://api-desmos.cosmostation.io", - cosmostationDenomTracePath: "/ibc/apps/transfer/v1/denom_traces/", - mintScanName: "desmos", - chainName: "Desmos", - stakeCurrency: { - coinDenom: "DSM", - coinMinimalDenom: "udsm", - coinDecimals: 6, - coinGeckoId: "pool:udsm", - coinImageUrl: "/tokens/blockchain/DSM.png", - }, - bip44: { coinType: 852 }, - bech32Config: { - bech32PrefixAccAddr: "desmos", - bech32PrefixAccPub: "desmospub", - bech32PrefixValAddr: "desmosvaloper", - bech32PrefixValPub: "desmosvaloperpub", - bech32PrefixConsAddr: "desmosvalcons", - bech32PrefixConsPub: "desmosvalconspub", - }, - currencies: [ - { - coinDenom: "DSM", - coinMinimalDenom: "udsm", - coinDecimals: 6, - coinGeckoId: "pool:udsm", - coinImageUrl: "/tokens/blockchain/DSM.png", - }, - ], - feeCurrencies: [ - { - coinDenom: "DSM", - coinMinimalDenom: "udsm", - coinDecimals: 6, - coinGeckoId: "pool:udsm", - coinImageUrl: "/tokens/blockchain/DSM.png", - }, - ], - features: ["stargate", "ibc-transfer", "no-legacy-stdTx", "ibc-go"], - explorerUrlToTx: - "https://explorer.desmos.network/transactions/{txHash}", - gasPriceStep: null, - }, - }, - LUMNETWORK: { - name: "LUMNETWORK", - defaultDecimals: 6, - addressPatterns: ["^(lum1)[0-9a-z]{38}$"], - feeAssets: [{ blockchain: "LUMNETWORK", symbol: "LUM", address: null }], - logo: "https://api.rango.exchange/blockchains/lumnetwork.svg", - displayName: "Lum Network", - shortName: "Lum Network", - sort: 38, - color: "#1B42B4", - enabled: true, - type: "COSMOS", - chainId: "lum-network-1", - info: { - experimental: true, - rpc: "https://node0.mainnet.lum.network/rpc", - rest: "https://node0.mainnet.lum.network/rest", - cosmostationLcdUrl: "https://lcd-lum.cosmostation.io", - cosmostationApiUrl: "https://api-lum.cosmostation.io", - cosmostationDenomTracePath: "/ibc/apps/transfer/v1/denom_traces/", - mintScanName: "lum", - chainName: "Lum Network", - stakeCurrency: { - coinDenom: "LUM", - coinMinimalDenom: "ulum", - coinDecimals: 6, - coinGeckoId: "pool:ulum", - coinImageUrl: "/tokens/blockchain/LUM.png", - }, - bip44: { coinType: 118 }, - bech32Config: { - bech32PrefixAccAddr: "lum", - bech32PrefixAccPub: "lumpub", - bech32PrefixValAddr: "lumvaloper", - bech32PrefixValPub: "lumvaloperpub", - bech32PrefixConsAddr: "lumvalcons", - bech32PrefixConsPub: "lumvalconspub", - }, - currencies: [ - { - coinDenom: "LUM", - coinMinimalDenom: "ulum", - coinDecimals: 6, - coinGeckoId: "pool:ulum", - coinImageUrl: "/tokens/blockchain/LUM.png", - }, - ], - feeCurrencies: [ - { - coinDenom: "LUM", - coinMinimalDenom: "ulum", - coinDecimals: 6, - coinGeckoId: "pool:ulum", - coinImageUrl: "/tokens/blockchain/LUM.png", - }, - ], - features: ["stargate", "ibc-transfer", "no-legacy-stdTx", "ibc-go"], - explorerUrlToTx: "https://www.mintscan.io/lum/txs/{txHash}", - gasPriceStep: null, - }, - }, - BOBA: { - name: "BOBA", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "BOBA", symbol: "ETH", address: null }], - logo: "https://api.rango.exchange/blockchains/boba.png", - displayName: "Boba", - shortName: "Boba", - sort: 39, - color: "#ccff00", - enabled: true, - type: "EVM", - chainId: "0x120", - info: { - chainName: "Boba Network", - nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 }, - rpcUrls: ["https://mainnet.boba.network"], - blockExplorerUrls: ["https://bobascan.com/"], - addressUrl: "https://bobascan.com//address/{wallet}", - transactionUrl: "https://bobascan.com//tx/{txHash}", - }, - }, - }, - evmNetworkChainInfo: { - BSC: { - chainName: "Binance Smart Chain Mainnet", - chainId: "0x38", - nativeCurrency: { name: "BNB", symbol: "BNB", decimals: 18 }, - rpcUrls: ["https://bsc-dataseed1.ninicoin.io"], - blockExplorerUrls: ["https://bscscan.com"], - }, - POLYGON: { - chainName: "Polygon Mainnet", - chainId: "0x89", - nativeCurrency: { name: "MATIC", symbol: "MATIC", decimals: 18 }, - rpcUrls: ["https://polygon-rpc.com"], - blockExplorerUrls: ["https://polygonscan.com"], - }, - ETH: { - chainName: "Ethereum Mainnet", - chainId: "0x1", - nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 }, - rpcUrls: ["https://rpc.ankr.com/eth"], - blockExplorerUrls: ["https://etherscan.io"], - }, - AVAX_CCHAIN: { - chainName: "Avalanche C-Chain", - chainId: "0xa86a", - nativeCurrency: { name: "AVAX", symbol: "AVAX", decimals: 18 }, - rpcUrls: ["https://api.avax.network/ext/bc/C/rpc"], - blockExplorerUrls: ["https://snowtrace.io"], - }, - ARBITRUM: { - chainName: "Arbitrum One", - chainId: "0xa4b1", - nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 }, - rpcUrls: ["https://arb1.arbitrum.io/rpc"], - blockExplorerUrls: ["https://arbiscan.io"], - }, - FANTOM: { - chainName: "Fantom Opera", - chainId: "0xfa", - nativeCurrency: { name: "FTM", symbol: "FTM", decimals: 18 }, - rpcUrls: ["https://rpc.ftm.tools"], - blockExplorerUrls: ["https://ftmscan.com"], - }, - OPTIMISM: { - chainName: "Optimism", - chainId: "0xa", - nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 }, - rpcUrls: ["https://mainnet.optimism.io"], - blockExplorerUrls: ["https://optimistic.etherscan.io"], - }, - OKC: { - chainName: "OKX Chain", - chainId: "0x42", - nativeCurrency: { name: "OKT", symbol: "OKT", decimals: 18 }, - rpcUrls: ["https://exchainrpc.okex.org"], - blockExplorerUrls: ["https://www.oklink.com/en/okc"], - }, - CRONOS: { - chainName: "Cronos Mainnet Beta", - chainId: "0x19", - nativeCurrency: { name: "CRO", symbol: "CRO", decimals: 18 }, - rpcUrls: ["https://cronosrpc-1.xstaking.sg"], - blockExplorerUrls: ["https://cronoscan.com"], - }, - MOONRIVER: { - chainName: "MoonRiver", - chainId: "0x505", - nativeCurrency: { name: "MOVR", symbol: "MOVR", decimals: 18 }, - rpcUrls: ["https://rpc.moonriver.moonbeam.network"], - blockExplorerUrls: ["https://moonriver.moonscan.io"], - }, - MOONBEAM: { - chainName: "MoonBeam", - chainId: "0x504", - nativeCurrency: { name: "GLMR", symbol: "GLMR", decimals: 18 }, - rpcUrls: ["https://rpc.api.moonbeam.network"], - blockExplorerUrls: ["https://moonbeam.moonscan.io"], - }, - HECO: { - chainName: "Huobi ECO Chain Mainnet", - chainId: "0x80", - nativeCurrency: { name: "HT", symbol: "HT", decimals: 18 }, - rpcUrls: ["https://http-mainnet.hecochain.com"], - blockExplorerUrls: ["https://hecoinfo.com"], - }, - AURORA: { - chainName: "Aurora Mainnet", - chainId: "0x4e454152", - nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 }, - rpcUrls: ["https://mainnet.aurora.dev"], - blockExplorerUrls: ["https://explorer.mainnet.aurora.dev"], - }, - HARMONY: { - chainName: "Harmony Mainnet", - chainId: "0x63564c40", - nativeCurrency: { name: "ONE", symbol: "ONE", decimals: 18 }, - rpcUrls: ["https://api.s0.t.hmny.io"], - blockExplorerUrls: ["https://explorer.harmony.one"], - }, - EVMOS: { - chainName: "Evmos", - chainId: "0x2329", - nativeCurrency: { name: "EVMOS", symbol: "EVMOS", decimals: 18 }, - rpcUrls: ["https://eth.bd.evmos.org:8545"], - blockExplorerUrls: ["https://evm.evmos.org"], - }, - GNOSIS: { - chainName: "Gnosis Chain", - chainId: "0x64", - nativeCurrency: { name: "XDAI", symbol: "XDAI", decimals: 18 }, - rpcUrls: ["https://rpc.gnosischain.com"], - blockExplorerUrls: ["https://blockscout.com/xdai/mainnet"], - }, - FUSE: { - chainName: "Fuse Mainnet", - chainId: "0x7a", - nativeCurrency: { name: "FUSE", symbol: "FUSE", decimals: 18 }, - rpcUrls: ["https://rpc.fuse.io"], - blockExplorerUrls: ["https://explorer.fuse.io"], - }, - BOBA: { - chainName: "Boba Network", - chainId: "0x120", - nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 }, - rpcUrls: ["https://mainnet.boba.network"], - blockExplorerUrls: ["https://bobascan.com/"], - }, - }, - walletsAndSupportedChainsNames: { - "binance-chain": ["BSC", "ETH", "BNB"], - metamask: [ - "BSC", - "POLYGON", - "ETH", - "AVAX_CCHAIN", - "ARBITRUM", - "FANTOM", - "OPTIMISM", - "OKC", - "CRONOS", - "MOONRIVER", - "MOONBEAM", - "HECO", - "AURORA", - "HARMONY", - "EVMOS", - "GNOSIS", - "FUSE", - "BOBA", - ], - coinbase: [ - "BSC", - "POLYGON", - "ETH", - "AVAX_CCHAIN", - "ARBITRUM", - "FANTOM", - "OPTIMISM", - "OKC", - "CRONOS", - "MOONRIVER", - "MOONBEAM", - "HECO", - "AURORA", - "HARMONY", - "EVMOS", - "GNOSIS", - "FUSE", - "BOBA", - "SOLANA", - ], - keplr: [ - "OSMOSIS", - "JUNO", - "COSMOS", - "SIF", - "STARGAZE", - "CRYPTO_ORG", - "CHIHUAHUA", - "BANDCHAIN", - "COMDEX", - "REGEN", - "IRIS", - "EMONEY", - "AKASH", - "KI", - "KUJIRA", - "PERSISTENCE", - "SENTINEL", - "STARNAME", - "UMEE", - "BITCANNA", - "DESMOS", - "LUMNETWORK", - ], - phantom: ["SOLANA"], - xdefi: [ - "BSC", - "POLYGON", - "ETH", - "AVAX_CCHAIN", - "ARBITRUM", - "FANTOM", - "SOLANA", - "THOR", - "BNB", - "BTC", - "LTC", - "BCH", - ], - "wallet-connect": [ - "BSC", - "POLYGON", - "ETH", - "AVAX_CCHAIN", - "ARBITRUM", - "FANTOM", - "OPTIMISM", - "OKC", - "CRONOS", - "MOONRIVER", - "MOONBEAM", - "HECO", - "AURORA", - "HARMONY", - "EVMOS", - "GNOSIS", - "FUSE", - "BOBA", - ], - "trust-wallet": [ - "BSC", - "POLYGON", - "ETH", - "AVAX_CCHAIN", - "ARBITRUM", - "FANTOM", - "OPTIMISM", - "OKC", - "CRONOS", - "MOONRIVER", - "MOONBEAM", - "HECO", - "AURORA", - "HARMONY", - "EVMOS", - "GNOSIS", - "FUSE", - "BOBA", - ], - coin98: [ - "BSC", - "POLYGON", - "ETH", - "AVAX_CCHAIN", - "ARBITRUM", - "FANTOM", - "OPTIMISM", - "OKC", - "CRONOS", - "MOONRIVER", - "MOONBEAM", - "HECO", - "AURORA", - "HARMONY", - "EVMOS", - "GNOSIS", - "FUSE", - "BOBA", - "SOLANA", - ], - okx: [ - "BSC", - "POLYGON", - "ETH", - "AVAX_CCHAIN", - "ARBITRUM", - "FANTOM", - "OPTIMISM", - "SOLANA", - "CRONOS", - "MOONRIVER", - "MOONBEAM", - "HARMONY", - "BTC", - "GNOSIS", - "LTC", - "BOBA", - ], - exodus: ["BSC", "POLYGON", "ETH", "AVAX_CCHAIN", "SOLANA", "BNB"], - "token-pocket": [ - "BSC", - "POLYGON", - "ETH", - "AVAX_CCHAIN", - "ARBITRUM", - "FANTOM", - "OPTIMISM", - "OKC", - "CRONOS", - "MOONRIVER", - "MOONBEAM", - "HECO", - "AURORA", - "HARMONY", - "EVMOS", - "GNOSIS", - "FUSE", - "BOBA", - ], - "terra-station": [], - leap: [], - math: [ - "BSC", - "POLYGON", - "ETH", - "AVAX_CCHAIN", - "ARBITRUM", - "FANTOM", - "OPTIMISM", - "OKC", - "CRONOS", - "MOONRIVER", - "MOONBEAM", - "HECO", - "AURORA", - "HARMONY", - "EVMOS", - "GNOSIS", - "FUSE", - "BOBA", - "SOLANA", - ], - safepal: [ - "BSC", - "POLYGON", - "ETH", - "AVAX_CCHAIN", - "ARBITRUM", - "FANTOM", - "OPTIMISM", - "OKC", - "CRONOS", - "MOONRIVER", - "MOONBEAM", - "HECO", - "AURORA", - "HARMONY", - "EVMOS", - "GNOSIS", - "FUSE", - "BOBA", - "SOLANA", - ], - clover: [ - "BSC", - "POLYGON", - "ETH", - "AVAX_CCHAIN", - "ARBITRUM", - "FANTOM", - "OPTIMISM", - "OKC", - "CRONOS", - "MOONRIVER", - "MOONBEAM", - "HECO", - "AURORA", - "HARMONY", - "EVMOS", - "GNOSIS", - "FUSE", - "BOBA", - "SOLANA", - ], - cosmostation: [ - "BSC", - "POLYGON", - "ETH", - "AVAX_CCHAIN", - "ARBITRUM", - "FANTOM", - "OPTIMISM", - "OKC", - "CRONOS", - "MOONRIVER", - "MOONBEAM", - "HECO", - "AURORA", - "HARMONY", - "EVMOS", - "GNOSIS", - "FUSE", - "BOBA", - "OSMOSIS", - "JUNO", - "COSMOS", - "SIF", - "STARGAZE", - "CRYPTO_ORG", - "CHIHUAHUA", - "BANDCHAIN", - "COMDEX", - "REGEN", - "IRIS", - "EMONEY", - "AKASH", - "KI", - "KUJIRA", - "PERSISTENCE", - "SENTINEL", - "STARNAME", - "UMEE", - "BITCANNA", - "DESMOS", - "LUMNETWORK", - ], - brave: [ - "BSC", - "POLYGON", - "ETH", - "AVAX_CCHAIN", - "ARBITRUM", - "FANTOM", - "OPTIMISM", - "OKC", - "CRONOS", - "MOONRIVER", - "MOONBEAM", - "HECO", - "AURORA", - "HARMONY", - "EVMOS", - "GNOSIS", - "FUSE", - "BOBA", - "SOLANA", - ], - unknown: [], - }, - evmBasedChains: [ - { - name: "BSC", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "BSC", symbol: "BNB", address: null }], - logo: "https://api.rango.exchange/blockchains/binance.svg", - displayName: "BSC", - shortName: "BSC", - sort: 1, - color: "#F3BA2F", - enabled: true, - type: "EVM", - chainId: "0x38", - info: { - chainName: "Binance Smart Chain Mainnet", - nativeCurrency: { name: "BNB", symbol: "BNB", decimals: 18 }, - rpcUrls: ["https://bsc-dataseed1.ninicoin.io"], - blockExplorerUrls: ["https://bscscan.com"], - addressUrl: "https://bscscan.com/address/{wallet}", - transactionUrl: "https://bscscan.com/tx/{txHash}", - }, - }, - { - name: "POLYGON", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "POLYGON", symbol: "MATIC", address: null }], - logo: "https://api.rango.exchange/blockchains/polygon.svg", - displayName: "Polygon", - shortName: "Polygon", - sort: 2, - color: "#8247E5", - enabled: true, - type: "EVM", - chainId: "0x89", - info: { - chainName: "Polygon Mainnet", - nativeCurrency: { name: "MATIC", symbol: "MATIC", decimals: 18 }, - rpcUrls: ["https://polygon-rpc.com"], - blockExplorerUrls: ["https://polygonscan.com"], - addressUrl: "https://polygonscan.com/address/{wallet}", - transactionUrl: "https://polygonscan.com/tx/{txHash}", - }, - }, - { - name: "ETH", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "ETH", symbol: "ETH", address: null }], - logo: "https://api.rango.exchange/blockchains/ethereum.svg", - displayName: "Ethereum", - shortName: "ETH", - sort: 3, - color: "#ecf0f1", - enabled: true, - type: "EVM", - chainId: "0x1", - info: { - chainName: "Ethereum Mainnet", - nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 }, - rpcUrls: ["https://rpc.ankr.com/eth"], - blockExplorerUrls: ["https://etherscan.io"], - addressUrl: "https://etherscan.io/address/{wallet}", - transactionUrl: "https://etherscan.io/tx/{txHash}", - }, - }, - { - name: "AVAX_CCHAIN", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "AVAX_CCHAIN", symbol: "AVAX", address: null }], - logo: "https://api.rango.exchange/blockchains/avax_cchain.svg", - displayName: "Avalanche", - shortName: "Avax", - sort: 6, - color: "#e84142", - enabled: true, - type: "EVM", - chainId: "0xa86a", - info: { - chainName: "Avalanche C-Chain", - nativeCurrency: { name: "AVAX", symbol: "AVAX", decimals: 18 }, - rpcUrls: ["https://api.avax.network/ext/bc/C/rpc"], - blockExplorerUrls: ["https://snowtrace.io"], - addressUrl: "https://snowtrace.io/address/{wallet}", - transactionUrl: "https://snowtrace.io/tx/{txHash}", - }, - }, - { - name: "ARBITRUM", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "ARBITRUM", symbol: "ETH", address: null }], - logo: "https://api.rango.exchange/blockchains/arbitrum.svg", - displayName: "Arbitrum", - shortName: "Arbitrum", - sort: 7, - color: "#28a0f0", - enabled: true, - type: "EVM", - chainId: "0xa4b1", - info: { - chainName: "Arbitrum One", - nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 }, - rpcUrls: ["https://arb1.arbitrum.io/rpc"], - blockExplorerUrls: ["https://arbiscan.io"], - addressUrl: "https://arbiscan.io/address/{wallet}", - transactionUrl: "https://arbiscan.io/tx/{txHash}", - }, - }, - { - name: "FANTOM", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "FANTOM", symbol: "FTM", address: null }], - logo: "https://api.rango.exchange/blockchains/fantom.png", - displayName: "Fantom", - shortName: "Fantom", - sort: 9, - color: "#337afe", - enabled: true, - type: "EVM", - chainId: "0xfa", - info: { - chainName: "Fantom Opera", - nativeCurrency: { name: "FTM", symbol: "FTM", decimals: 18 }, - rpcUrls: ["https://rpc.ftm.tools"], - blockExplorerUrls: ["https://ftmscan.com"], - addressUrl: "https://ftmscan.com/address/{wallet}", - transactionUrl: "https://ftmscan.com/tx/{txHash}", - }, - }, - { - name: "OPTIMISM", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "OPTIMISM", symbol: "ETH", address: null }], - logo: "https://api.rango.exchange/blockchains/optimism.svg", - displayName: "Optimism", - shortName: "Optimism", - sort: 10, - color: "#FF0420", - enabled: true, - type: "EVM", - chainId: "0xa", - info: { - chainName: "Optimism", - nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 }, - rpcUrls: ["https://mainnet.optimism.io"], - blockExplorerUrls: ["https://optimistic.etherscan.io"], - addressUrl: "https://optimistic.etherscan.io/address/{wallet}", - transactionUrl: "https://optimistic.etherscan.io/tx/{txHash}", - }, - }, - { - name: "OKC", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "OKC", symbol: "OKT", address: null }], - logo: "https://api.rango.exchange/blockchains/okx.png", - displayName: "OKX Chain (OKC)", - shortName: "Okx", - sort: 11, - color: "#29a0f0", - enabled: true, - type: "EVM", - chainId: "0x42", - info: { - chainName: "OKX Chain", - nativeCurrency: { name: "OKT", symbol: "OKT", decimals: 18 }, - rpcUrls: ["https://exchainrpc.okex.org"], - blockExplorerUrls: ["https://www.oklink.com/en/okc"], - addressUrl: "https://www.oklink.com/en/okc/address/{wallet}", - transactionUrl: "https://www.oklink.com/en/okc/tx/{txHash}", - }, - }, - { - name: "CRONOS", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "CRONOS", symbol: "CRO", address: null }], - logo: "https://api.rango.exchange/blockchains/cronos.svg", - displayName: "Cronos", - shortName: "Cronos", - sort: 12, - color: "#1a90ff", - enabled: true, - type: "EVM", - chainId: "0x19", - info: { - chainName: "Cronos Mainnet Beta", - nativeCurrency: { name: "CRO", symbol: "CRO", decimals: 18 }, - rpcUrls: ["https://cronosrpc-1.xstaking.sg"], - blockExplorerUrls: ["https://cronoscan.com"], - addressUrl: "https://cronoscan.com/address/{wallet}", - transactionUrl: "https://cronoscan.com/tx/{txHash}", - }, - }, - { - name: "MOONRIVER", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "MOONRIVER", symbol: "MOVR", address: null }], - logo: "https://api.rango.exchange/blockchains/moonriver.svg", - displayName: "MoonRiver", - shortName: "MoonRiver", - sort: 13, - color: "#F3B404", - enabled: true, - type: "EVM", - chainId: "0x505", - info: { - chainName: "MoonRiver", - nativeCurrency: { name: "MOVR", symbol: "MOVR", decimals: 18 }, - rpcUrls: ["https://rpc.moonriver.moonbeam.network"], - blockExplorerUrls: ["https://moonriver.moonscan.io"], - addressUrl: "https://moonriver.moonscan.io/address/{wallet}", - transactionUrl: "https://moonriver.moonscan.io/tx/{txHash}", - }, - }, - { - name: "MOONBEAM", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "MOONBEAM", symbol: "GLMR", address: null }], - logo: "https://api.rango.exchange/blockchains/moonbeam.png", - displayName: "MoonBeam", - shortName: "MoonBeam", - sort: 14, - color: "#B3206B", - enabled: true, - type: "EVM", - chainId: "0x504", - info: { - chainName: "MoonBeam", - nativeCurrency: { name: "GLMR", symbol: "GLMR", decimals: 18 }, - rpcUrls: ["https://rpc.api.moonbeam.network"], - blockExplorerUrls: ["https://moonbeam.moonscan.io"], - addressUrl: "https://moonbeam.moonscan.io/address/{wallet}", - transactionUrl: "https://moonbeam.moonscan.io/tx/{txHash}", - }, - }, - { - name: "HECO", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "HECO", symbol: "HT", address: null }], - logo: "https://api.rango.exchange/blockchains/heco.png", - displayName: "Heco", - shortName: "Heco", - sort: 15, - color: "#4CA852", - enabled: true, - type: "EVM", - chainId: "0x80", - info: { - chainName: "Huobi ECO Chain Mainnet", - nativeCurrency: { name: "HT", symbol: "HT", decimals: 18 }, - rpcUrls: ["https://http-mainnet.hecochain.com"], - blockExplorerUrls: ["https://hecoinfo.com"], - addressUrl: "https://hecoinfo.com/address/{wallet}", - transactionUrl: "https://hecoinfo.com/tx/{txHash}", - }, - }, - { - name: "AURORA", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "AURORA", symbol: "ETH", address: null }], - logo: "https://api.rango.exchange/blockchains/aurora.svg", - displayName: "Aurora", - shortName: "Aurora", - sort: 15, - color: "#78d64b", - enabled: true, - type: "EVM", - chainId: "0x4e454152", - info: { - chainName: "Aurora Mainnet", - nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 }, - rpcUrls: ["https://mainnet.aurora.dev"], - blockExplorerUrls: ["https://explorer.mainnet.aurora.dev"], - addressUrl: "https://explorer.mainnet.aurora.dev/address/{wallet}", - transactionUrl: "https://explorer.mainnet.aurora.dev/tx/{txHash}", - }, - }, - { - name: "HARMONY", - defaultDecimals: 18, - addressPatterns: ["^(one1)[0-9a-z]{38}$", "^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "HARMONY", symbol: "ONE", address: null }], - logo: "https://api.rango.exchange/blockchains/harmony.svg", - displayName: "Harmony", - shortName: "Harmony", - sort: 15, - color: "#50AEE9", - enabled: true, - type: "EVM", - chainId: "0x63564c40", - info: { - chainName: "Harmony Mainnet", - nativeCurrency: { name: "ONE", symbol: "ONE", decimals: 18 }, - rpcUrls: ["https://api.s0.t.hmny.io"], - blockExplorerUrls: ["https://explorer.harmony.one"], - addressUrl: "https://explorer.harmony.one/address/{wallet}", - transactionUrl: "https://explorer.harmony.one/tx/{txHash}", - }, - }, - { - name: "EVMOS", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "EVMOS", symbol: "EVMOS", address: null }], - logo: "https://api.rango.exchange/blockchains/evmos.png", - displayName: "Evmos", - shortName: "Evmos", - sort: 15, - color: "#2D2925", - enabled: true, - type: "EVM", - chainId: "0x2329", - info: { - chainName: "Evmos", - nativeCurrency: { name: "EVMOS", symbol: "EVMOS", decimals: 18 }, - rpcUrls: ["https://eth.bd.evmos.org:8545"], - blockExplorerUrls: ["https://evm.evmos.org"], - addressUrl: "https://evm.evmos.org/address/{wallet}", - transactionUrl: "https://evm.evmos.org/tx/{txHash}", - }, - }, - { - name: "GNOSIS", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "GNOSIS", symbol: "XDAI", address: null }], - logo: "https://api.rango.exchange/blockchains/gnosis.svg", - displayName: "Gnosis", - shortName: "Gnosis", - sort: 26, - color: "#3E6957", - enabled: true, - type: "EVM", - chainId: "0x64", - info: { - chainName: "Gnosis Chain", - nativeCurrency: { name: "XDAI", symbol: "XDAI", decimals: 18 }, - rpcUrls: ["https://rpc.gnosischain.com"], - blockExplorerUrls: ["https://blockscout.com/xdai/mainnet"], - addressUrl: "https://blockscout.com/xdai/mainnet/address/{wallet}", - transactionUrl: "https://blockscout.com/xdai/mainnet/tx/{txHash}", - }, - }, - { - name: "FUSE", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "FUSE", symbol: "FUSE", address: null }], - logo: "https://api.rango.exchange/blockchains/fuse.png", - displayName: "Fuse", - shortName: "Fuse", - sort: 29, - color: "#C5F9AD", - enabled: true, - type: "EVM", - chainId: "0x7a", - info: { - chainName: "Fuse Mainnet", - nativeCurrency: { name: "FUSE", symbol: "FUSE", decimals: 18 }, - rpcUrls: ["https://rpc.fuse.io"], - blockExplorerUrls: ["https://explorer.fuse.io"], - addressUrl: "https://explorer.fuse.io/address/{wallet}", - transactionUrl: "https://explorer.fuse.io/tx/{txHash}", - }, - }, - { - name: "BOBA", - defaultDecimals: 18, - addressPatterns: ["^(0x)[0-9A-Fa-f]{40}$"], - feeAssets: [{ blockchain: "BOBA", symbol: "ETH", address: null }], - logo: "https://api.rango.exchange/blockchains/boba.png", - displayName: "Boba", - shortName: "Boba", - sort: 39, - color: "#ccff00", - enabled: true, - type: "EVM", - chainId: "0x120", - info: { - chainName: "Boba Network", - nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 }, - rpcUrls: ["https://mainnet.boba.network"], - blockExplorerUrls: ["https://bobascan.com/"], - addressUrl: "https://bobascan.com//address/{wallet}", - transactionUrl: "https://bobascan.com//tx/{txHash}", - }, - }, - ], -} as unknown as Meta; diff --git a/queue-manager/demo/src/flows/rango/types.ts b/queue-manager/demo/src/flows/rango/types.ts deleted file mode 100644 index 27b554f6af..0000000000 --- a/queue-manager/demo/src/flows/rango/types.ts +++ /dev/null @@ -1,470 +0,0 @@ -import { - WalletType, - Network, - EvmTransaction, - CosmosTransaction, - TransferTransaction, - SolanaTransaction, - Asset, - Transaction, -} from "@rango-dev/wallets-shared"; -import BigNumber from "bignumber.js"; - -export type WalletTypeAndAddress = { - walletType: WalletType; - address: string; -}; - -export enum MessageSeverity { - error = "error", - warning = "warning", - info = "info", - success = "success", -} - -export type SwapStatus = "running" | "failed" | "success"; - -export type SwapSavedSettings = { - slippage: string; - disabledSwappersIds: string[]; - disabledSwappersGroups: string[]; -}; - -export type SwapperId = - | "ThorChain" - | "OneInchEth" - | "Binance Bridge" - | "OneInchBsc" - | "OneInchPolygon" - | "Terra Bridge" - | "TerraSwap" - | "Osmosis" - | "Lido" - | "PoS Bridge" - | "Wormhole"; - -export type StepStatus = - | "created" - | "running" - | "failed" - | "success" - | "waitingForApproval" - | "approved"; - -export enum PendingSwapNetworkStatus { - WaitingForConnectingWallet = "waitingForConnectingWallet", - WaitingForQueue = "waitingForQueue", - WaitingForNetworkChange = "waitingForNetworkChange", - NetworkChanged = "networkChanged", -} - -export type SwapExplorerUrl = { - url: string; - description: string | null; -}; - -type InternalStepState = - | "PENDING" - | "CREATED" - | "WAITING" - | "SIGNED" - | "SUCCESSED" - | "FAILED"; - -export type SwapperStatusStep = { - name: string; - state: InternalStepState; - current: boolean; -}; - -export type PendingSwapStep = { - id: number; - fromBlockchain: Network; - fromSymbol: string; - fromSymbolAddress: string | null; - fromDecimals: number; - fromAmountPrecision: number | null; - fromAmountMinValue: number | null; - fromAmountMaxValue: number | null; - fromLogo: string; - toBlockchain: string; - toSymbol: string; - toSymbolAddress: string | null; - toDecimals: number; - toLogo: string; - swapperId: SwapperId; - expectedOutputAmountHumanReadable: string | null; - startTransactionTime: number; - outputAmount: string | null; - status: StepStatus; - networkStatus: PendingSwapNetworkStatus | null; - executedTransactionId: string | null; - explorerUrl: SwapExplorerUrl[] | null; - evmApprovalTransaction: EvmTransaction | null; - evmTransaction: EvmTransaction | null; - cosmosTransaction: CosmosTransaction | null; - transferTransaction: TransferTransaction | null; - solanaTransaction: SolanaTransaction | null; - diagnosisUrl: string | null; - internalSteps: SwapperStatusStep[] | null; -}; - -export type SwapResultAsset = { - symbol: string; - logo: string; - address: string | null; - blockchain: Network; - decimals: number; - usdPrice: number | null; -}; - -export type ExpenseType = "FROM_SOURCE_WALLET" | "DECREASE_FROM_OUTPUT"; - -export type SwapFee = { - asset: Asset; - amount: string; - expenseType: ExpenseType; -}; - -export type TimeStat = { - min: number; - avg: number; - max: number; -}; - -export type SwapNode = { - marketName: string; - marketId: string | null; - percent: number; -}; - -export type SwapSuperNode = { - nodes: SwapNode[]; - from: string; - fromLogo: string; - fromAddress: string | null; - fromBlockchain: string; - to: string; - toLogo: string; - toAddress: string | null; - toBlockchain: string; -}; - -export type SwapRoute = { - nodes: SwapSuperNode[] | null; -}; - -export type RecommendedSlippage = { - error: boolean; - slippage: string | null; -}; - -export type SwapResult = { - swapperId: SwapperId; - from: SwapResultAsset; - to: SwapResultAsset; - fromAmount: string; - fromAmountPrecision: number | null; - fromAmountRestrictionType: "EXCLUSIVE" | "INCLUSIVE"; - fromAmountMinValue: number | null; - fromAmountMaxValue: number | null; - toAmount: string; - fee: SwapFee[]; - estimatedTimeInSeconds: number; - timeStat: TimeStat | null; - swapChainType: string; - routes: SwapRoute[] | null; - recommendedSlippage: RecommendedSlippage | null; - includesDestinationTx: boolean | null | undefined; -}; - -export type SimulationResult = { - outputAmount: string; - swaps: SwapResult[]; -}; - -export type PendingSwap = { - creationTime: string; - finishTime: string | null; - requestId: string; - inputAmount: string; - status: SwapStatus; - isPaused: boolean; - extraMessage: string | null; - extraMessageSeverity: MessageSeverity | null; - extraMessageErrorCode: string | null; - extraMessageDetail: string | null | undefined; - networkStatusExtraMessage: string | null; - networkStatusExtraMessageDetail: string | null; - lastNotificationTime: string | null; - wallets: { [p: string]: WalletTypeAndAddress }; - settings: SwapSavedSettings; - steps: PendingSwapStep[]; - simulationResult: SimulationResult; - validateBalanceOrFee: boolean; -}; -export type Amount = { amount: string; decimals: number }; -export type WalletRequiredAssetReason = - | "FEE" - | "INPUT_ASSET" - | "FEE_AND_INPUT_ASSET"; - -export type SimulationAssetAndAmount = { - asset: Asset; - requiredAmount: Amount; - currentAmount: Amount; - reason: WalletRequiredAssetReason; - ok: boolean; -}; - -export type SimulationWallet = { - address: string; - validResult: boolean; - requiredAssets: SimulationAssetAndAmount[]; - addressIsValid: boolean; -}; - -export type SimulationValidationStatus = { - blockchain: string; - wallets: SimulationWallet[]; -}; - -export type BestRoute = { - from: Asset; - to: Asset; - requestAmount: string; - result: SimulationResult | null; - validationStatus: SimulationValidationStatus[] | null; - requestId: string; - missingBlockchains: string[]; - diagnosisMessages: string[]; -}; - -export const SWAPPER_ONE_INCH_ETH = "OneInchEth"; -export const SWAPPER_ONE_INCH_BSC = "OneInchBsc"; -export const SWAPPER_ONE_INCH_POLYGON = "OneInchPolygon"; -export const SWAPPER_TERRA_BRIDGE = "Terra Bridge"; -export const SWAPPER_LIDO = "Lido"; -export const SWAPPER_TERRA_SWAP = "TerraSwap"; -export const SWAPPER_THORCHAIN = "ThorChain"; -export const SWAPPER_BINANCE_BRIDGE = "Binance Bridge"; -export const SWAPPER_OSMOSIS = "Osmosis"; - -export const SWAPPER_ONE_INCH_LIST = [ - SWAPPER_ONE_INCH_ETH, - SWAPPER_ONE_INCH_BSC, - SWAPPER_ONE_INCH_POLYGON, -]; - -export const NETWORKS_FOR_1INCH = [ - Network.POLYGON, - Network.ETHEREUM, - Network.BSC, -]; - -export const BNB_SYMBOL = "BNB"; -export const MATIC_SYMBOL = "MATIC"; - -export const NETWORK_TO_NATIVE_SYMBOL_MAP_FOR_1INCH = new Map([ - [Network.ETHEREUM, Network.ETHEREUM], - [Network.BSC, BNB_SYMBOL], - [Network.POLYGON, MATIC_SYMBOL], -]); - -export type TokenMeta = { - blockchain: Network; - symbol: string; - image: string; - address: string | null; - usdPrice: number | null; - isSecondaryCoin: boolean; - coinSource: string | null; - coinSourceUrl: string | null; - name: string | null; - decimals: number; -}; - -export type RawAccounts = { - blockchains: { - name: string; - accounts: { address: string; walletType: WalletType }[]; - }[]; -} | null; - -export type UserWalletBlockchain = { - blockchain: string; - addresses: string[]; -}; - -export type BestRouteRequest = { - from: Asset; - to: Asset; - amount: string; - connectedWallets: UserWalletBlockchain[]; - selectedWallets: { [p: string]: string }; - checkPrerequisites: boolean; - affiliateRef: string | null; - swappers?: string[]; - blockchains?: Network[]; - swapperGroups?: string[]; - swappersGroupsExclude?: boolean; -}; - -export type WalletBalance = { - chain: Network; - symbol: string; - ticker: string; - address: string | null; - rawAmount: string; - decimal: number | null; - amount: string; - logo: string | null; - usdPrice: number | null; -}; - -export type Account = { - balances: WalletBalance[] | null; - address: string; - loading: boolean; - walletType: WalletType; - error: boolean; - explorerUrl: string | null; - isConnected: boolean; -}; - -export type Blockchain = { name: Network; accounts: Account[] }; -export type Wallet = { blockchains: Blockchain[] }; - -export type EventType = - | "swap_started" - | "confirm_contract" - | "confirm_transfer" - | "task_failed" - | "task_completed" - | "task_canceled" - | "task_paused" - | "contract_confirmed" - | "contract_rejected" - | "transfer_confirmed" - | "transfer_rejected" - | "calling_smart_contract" - | "smart_contract_called" - | "smart_contract_call_failed" - | "step_completed_with_output" - | "waiting_for_network_change" - | "waiting_for_connecting_wallet" - | "network_changed" - | "not_enough_balance" - | "check_fee_failed" - | "route_failed_to_find"; - -export type SwapperStatusResponse = { - status: "running" | "failed" | "success" | null; - extraMessage: string | null; - timestamp: number; - outputAmount: BigNumber | null; - explorerUrl: SwapExplorerUrl[] | null; - trackingCode: string; - newTx: Transaction | null; - diagnosisUrl: string | null; - steps: SwapperStatusStep[] | null; -}; - -export type CheckTxStatusRequest = { - requestId: string; - txId: string; - step: number; -}; - -export enum ApiMethodName { - RequestingSwapTransaction = "Requesting Swap Transaction", - CreatingSwap = "Creating Swap", - CheckingTransactionStatus = "Checking transaction status", - CreateTransaction = "Create Transaction", - CheckApproval = "Check TX Approval", - GettingSwapDetail = "Getting Swap Detail", - GettingUserLimits = "Getting user limits", -} - -export type APIErrorCode = - | "TX_FAIL" - | "FETCH_TX_FAILED" - | "USER_REJECT" - | "CALL_WALLET_FAILED" - | "SEND_TX_FAILED" - | "CALL_OR_SEND_FAILED" - | "CLIENT_UNEXPECTED_BEHAVIOUR"; - -export type ErrorDetail = { - extraMessage: string; - extraMessageDetail?: string | null | undefined; - extraMessageErrorCode: string | null; -}; - -export enum TransactionName { - GenericTransaction = "transaction", - SendingOneInchTransaction = "1inch transaction", - Approval = "approve transaction", -} - -export type UserSettings = { - slippage: string; -}; - -export type CreateTransactionValidation = { - balance: boolean; - fee: boolean; -}; - -export type CreateTransactionRequest = { - requestId: string; - step: number; - userSettings: UserSettings; - validations: CreateTransactionValidation; -}; - -export type CreateTransactionResponse = { - ok: boolean; - error: string | null; - transaction: Transaction; -}; - -export const OKX_WALLET_SUPPORTED_CHAINS = [ - Network.ETHEREUM, - Network.BTC, - Network.BSC, - Network.TRON, - Network.SOLANA, - Network.POLYGON, - Network.FANTOM, - Network.ARBITRUM, - Network.OPTIMISM, - Network.CRONOS, - Network.BOBA, - Network.GNOSIS, - Network.MOONBEAM, - Network.MOONRIVER, - Network.HARMONY, - Network.LTC, - Network.AVAX_CCHAIN, -]; - -export const BINANCE_CHAIN_WALLET_SUPPORTED_CHAINS = [ - Network.ETHEREUM, - Network.BSC, - Network.BINANCE, -]; -export const EXODUS_WALLET_SUPPORTED_CHAINS = [ - Network.SOLANA, - Network.ETHEREUM, - Network.BSC, - Network.POLYGON, - Network.AVAX_CCHAIN, - BNB_SYMBOL, -]; - -export type SwapProgressNotification = { - eventType: EventType; - swap: PendingSwap | null; - step: PendingSwapStep | null; -}; diff --git a/queue-manager/demo/src/flows/swap/helpers.ts b/queue-manager/demo/src/flows/swap/helpers.ts deleted file mode 100644 index bada956d44..0000000000 --- a/queue-manager/demo/src/flows/swap/helpers.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { SwapProgressNotification } from "@rango-dev/queue-manager-rango-preset/dist/shared"; - -export function notifier({ eventType, swap, step }: SwapProgressNotification) { - console.log('[notifier]', { eventType, swap, step }); -} \ No newline at end of file diff --git a/queue-manager/demo/src/index.tsx b/queue-manager/demo/src/index.tsx deleted file mode 100644 index 42bda78ce8..0000000000 --- a/queue-manager/demo/src/index.tsx +++ /dev/null @@ -1,44 +0,0 @@ -import React, { useState } from "react"; -import { createRoot } from "react-dom/client"; -import { Events, Provider as WalletsProvider } from "@rango-dev/wallets-core"; -import { allProviders } from "@rango-dev/provider-all"; -import { App } from "./App"; -import { walletsAndSupportedChains } from "./flows/rango/mock"; -import { WalletType } from "@rango-dev/wallets-shared"; - -const providers = allProviders(); - -function AppContainer() { - const [connectedWallets, setConnectedWallets] = useState([]); - console.log("connected", connectedWallets); - - return ( - { - if (event === Events.ACCOUNTS && coreState.connected) { - console.log({ type, event }); - if (coreState.connected) { - if (!connectedWallets.includes(type)) { - const nextState = [...connectedWallets]; - nextState.push(type); - setConnectedWallets(nextState); - } - } else { - const nextState = [...connectedWallets].filter( - (wallet) => wallet !== type - ); - setConnectedWallets(nextState); - } - } - }} - > - - - ); -} - -const container = document.getElementById("app")!!; -const root = createRoot(container); -root.render(); diff --git a/queue-manager/demo/src/wallet.js b/queue-manager/demo/src/wallet.js deleted file mode 100644 index 30608de07d..0000000000 --- a/queue-manager/demo/src/wallet.js +++ /dev/null @@ -1,44 +0,0 @@ -import { providers } from 'ethers'; - -const { ethereum } = window; - -let activeAccount = null; - -export async function connect(){ - const accounts = await ethereum.request({ method: 'eth_requestAccounts' }); - activeAccount = accounts[0]; - console.log("connected", activeAccount) -} - - -export async function switchNetwork(chainId){ - await ethereum.request({ - method: 'wallet_switchEthereumChain', - params: [{ chainId}], - }); - - console.log("network switched.") -} - - -export async function signEvmTx(evmTransaction){ - let provider = new providers.Web3Provider(ethereum); - let signer = provider.getSigner(); - - let tx = {}; - if (!!evmTransaction.from) tx = { ...tx, from: evmTransaction.from }; - if (!!evmTransaction.txTo) tx = { ...tx, to: evmTransaction.txTo }; - if (!!evmTransaction.txData) tx = { ...tx, data: evmTransaction.txData }; - if (!!evmTransaction.value) tx = { ...tx, value: evmTransaction.value }; - if (!!evmTransaction.gasLimit) tx = { ...tx, gasLimit: evmTransaction.gasLimit }; - if (!!evmTransaction.gasPrice) tx = { ...tx, gasPrice: evmTransaction.gasPrice }; - if (!!evmTransaction.nonce) tx = { ...tx, nonce: evmTransaction.nonce }; - - const tr = await signer.sendTransaction(tx); - return tr.hash; -} - -// Switch network -// Make a transaction and run -// check status from server -// notif the resul \ No newline at end of file diff --git a/queue-manager/rango-preset/CHANGELOG.md b/queue-manager/rango-preset/CHANGELOG.md new file mode 100644 index 0000000000..aba8c97fce --- /dev/null +++ b/queue-manager/rango-preset/CHANGELOG.md @@ -0,0 +1,214 @@ +# [0.41.0](https://github.com/rango-exchange/rango-client/compare/queue-manager-rango-preset@0.40.0...queue-manager-rango-preset@0.41.0) (2024-12-30) + + + +# [0.40.0](https://github.com/rango-exchange/rango-client/compare/queue-manager-rango-preset@0.39.0...queue-manager-rango-preset@0.40.0) (2024-11-27) + + + +# [0.39.0](https://github.com/rango-exchange/rango-client/compare/queue-manager-rango-preset@0.38.0...queue-manager-rango-preset@0.39.0) (2024-11-12) + + + +# [0.38.0](https://github.com/rango-exchange/rango-client/compare/queue-manager-rango-preset@0.37.0...queue-manager-rango-preset@0.38.0) (2024-10-12) + + +### Bug Fixes + +* bump sdk and fix type issues ([d442208](https://github.com/rango-exchange/rango-client/commit/d4422083bf5dd27d5f509ce1db7f9560d05428c8)) + + +### Performance Improvements + +* lazy load signer packages ([7b88f18](https://github.com/rango-exchange/rango-client/commit/7b88f1834f7b29b4b81ab6c81a07bb88e8ccf55c)) + + + +# [0.37.0](https://github.com/rango-exchange/rango-client/compare/queue-manager-rango-preset@0.36.0...queue-manager-rango-preset@0.37.0) (2024-09-10) + + + +# [0.36.0](https://github.com/rango-exchange/rango-client/compare/queue-manager-rango-preset@0.35.1...queue-manager-rango-preset@0.36.0) (2024-08-11) + + + +## [0.35.1](https://github.com/rango-exchange/rango-client/compare/queue-manager-rango-preset@0.35.0...queue-manager-rango-preset@0.35.1) (2024-07-14) + + + +# [0.35.0](https://github.com/rango-exchange/rango-client/compare/queue-manager-rango-preset@0.33.2...queue-manager-rango-preset@0.35.0) (2024-07-09) + + +### Features + +* support new widget events ([37a9b6c](https://github.com/rango-exchange/rango-client/commit/37a9b6c023cba660c87af27bcbfceadfb8daa8d0)) + + +### Performance Improvements + +* improve finding tokens from store ([3e890bd](https://github.com/rango-exchange/rango-client/commit/3e890bdcd47971b072f347c368c4370225cb11ff)) + + + +# [0.34.0](https://github.com/rango-exchange/rango-client/compare/queue-manager-rango-preset@0.33.2...queue-manager-rango-preset@0.34.0) (2024-06-01) + + + +## [0.33.2](https://github.com/rango-exchange/rango-client/compare/queue-manager-rango-preset@0.33.1...queue-manager-rango-preset@0.33.2) (2024-05-26) + + + +## [0.33.1](https://github.com/rango-exchange/rango-client/compare/queue-manager-rango-preset@0.33.0...queue-manager-rango-preset@0.33.1) (2024-05-25) + + + +# [0.33.0](https://github.com/rango-exchange/rango-client/compare/queue-manager-rango-preset@0.32.0...queue-manager-rango-preset@0.33.0) (2024-05-14) + + + +# [0.32.0](https://github.com/rango-exchange/rango-client/compare/queue-manager-rango-preset@0.31.0...queue-manager-rango-preset@0.32.0) (2024-04-24) + + + +# [0.31.0](https://github.com/rango-exchange/rango-client/compare/queue-manager-rango-preset@0.30.0...queue-manager-rango-preset@0.31.0) (2024-04-23) + + + +# [0.30.0](https://github.com/rango-exchange/rango-client/compare/queue-manager-rango-preset@0.29.1...queue-manager-rango-preset@0.30.0) (2024-04-09) + + +### Bug Fixes + +* fix widget event hook ([c8547b6](https://github.com/rango-exchange/rango-client/commit/c8547b6a31354afe13aa32c0b72be5b62b3f0d67)) + + + +## [0.29.1](https://github.com/rango-exchange/rango-client/compare/queue-manager-rango-preset@0.29.0...queue-manager-rango-preset@0.29.1) (2024-03-12) + + +### Bug Fixes + +* increase approval checking interval ([e6444c8](https://github.com/rango-exchange/rango-client/commit/e6444c84dd216ddcf949b49708bb2c358fee2d88)) + + + +# [0.29.0](https://github.com/rango-exchange/rango-client/compare/queue-manager-rango-preset@0.28.0...queue-manager-rango-preset@0.29.0) (2024-03-12) + + +### Features + +* logging packages to be able to create log records and capture them. ([ca9b7e9](https://github.com/rango-exchange/rango-client/commit/ca9b7e918d67bf0d93e5b8313264c5984f3adb4e)) + + + +# [0.28.0](https://github.com/rango-exchange/rango-client/compare/queue-manager-rango-preset@0.27.0...queue-manager-rango-preset@0.28.0) (2024-02-20) + + +### Bug Fixes + +* fix some swap messages in widget-embedded ([f859190](https://github.com/rango-exchange/rango-client/commit/f85919050b0c8f3bb0f91d4f3b87a58cca29601b)) + + + +# [0.27.0](https://github.com/rango-exchange/rango-client/compare/queue-manager-rango-preset@0.26.0...queue-manager-rango-preset@0.27.0) (2024-02-07) + + + +# [0.26.0](https://github.com/rango-exchange/rango-client/compare/queue-manager-rango-preset@0.25.0...queue-manager-rango-preset@0.26.0) (2024-01-22) + + +### Features + +* export notifications from useWidget ([fc50baf](https://github.com/rango-exchange/rango-client/commit/fc50baf1b4043755162a54bcdd07f10fab94da39)) + + + +# [0.25.0](https://github.com/rango-exchange/rango-client/compare/queue-manager-rango-preset@0.24.0...queue-manager-rango-preset@0.25.0) (2023-12-24) + + +### Bug Fixes + +* add initial state with props in app store and fix bug of passing liquidity sources via config ([5d50d0f](https://github.com/rango-exchange/rango-client/commit/5d50d0fa18c0519a9464bb205684ecdaf881d936)) +* add wallets-core to rango-preset package dependencies ([0a8920a](https://github.com/rango-exchange/rango-client/commit/0a8920a11db4a8d213e01ee770289242bf1defc8)) +* display transaction url after refreshing ([c976bff](https://github.com/rango-exchange/rango-client/commit/c976bffd3827ee20de5dd0f21be6d430432fff28)) +* fix emitting failed event in swap execution ([cedc535](https://github.com/rango-exchange/rango-client/commit/cedc53523dc8ddc5f339b4da6afa822058bd760d)) +* fix HMR for widget and playground ([8524820](https://github.com/rango-exchange/rango-client/commit/8524820f10cf0b8921f3db0c4f620ff98daa4103)) + + +### Features + +* add state of wallets' details to useWidget ([2a59055](https://github.com/rango-exchange/rango-client/commit/2a590551cc0a3d663fd9901e125890ff1386c0aa)) + + + +# [0.14.0](https://github.com/rango-exchange/rango-client/compare/queue-manager-rango-preset@0.13.0...queue-manager-rango-preset@0.14.0) (2023-08-03) + + + +# [0.13.0](https://github.com/rango-exchange/rango-client/compare/queue-manager-rango-preset@0.12.0...queue-manager-rango-preset@0.13.0) (2023-08-01) + + + +# [0.9.0](https://github.com/rango-exchange/rango-client/compare/queue-manager-rango-preset@0.8.0...queue-manager-rango-preset@0.9.0) (2023-07-31) + + +### Features + +* Get Wallet Connect project id from config ([9fb30b4](https://github.com/rango-exchange/rango-client/commit/9fb30b4b1a83e2005bbf42553298f24b1e278e1c)) +* support safe wallet ([d04cbcd](https://github.com/rango-exchange/rango-client/commit/d04cbcd2a612755563512d9dff6f2312088d8b4d)) + + + +# [0.7.0](https://github.com/rango-exchange/rango-client/compare/queue-manager-rango-preset@0.6.0...queue-manager-rango-preset@0.7.0) (2023-07-11) + + + +# [0.6.0](https://github.com/rango-exchange/rango-client/compare/queue-manager-rango-preset@0.5.0...queue-manager-rango-preset@0.6.0) (2023-07-11) + + +### Bug Fixes + +* better parsing of evm rpc errors ([f23031a](https://github.com/rango-exchange/rango-client/commit/f23031ae14e6e841ee488591bd1bf58cfa7ca15b)) +* fix signer wait change network issues ([e453db6](https://github.com/rango-exchange/rango-client/commit/e453db6ccf7736e36e5ada0c29502be32254fe9c)) + + +### Features + +* add widget events and refactor swap execution events ([0d76806](https://github.com/rango-exchange/rango-client/commit/0d7680693dd77439de38cd0b20f263f6ae8cceb0)) + + + +# [0.5.0](https://github.com/rango-exchange/rango-client/compare/queue-manager-rango-preset@0.4.0...queue-manager-rango-preset@0.5.0) (2023-05-31) + + + +# [0.4.0](https://github.com/rango-exchange/rango-client/compare/queue-manager-rango-preset@0.3.0...queue-manager-rango-preset@0.4.0) (2023-05-31) + + + +# [0.3.0](https://github.com/rango-exchange/rango-client/compare/queue-manager-rango-preset@0.2.0...queue-manager-rango-preset@0.3.0) (2023-05-30) + + + +# [0.2.0](https://github.com/rango-exchange/rango-client/compare/queue-manager-rango-preset@0.1.14...queue-manager-rango-preset@0.2.0) (2023-05-30) + + +### Bug Fixes + +* avoid getting transaction receipt multiple times ([3ef2875](https://github.com/rango-exchange/rango-client/commit/3ef2875bfad470cf2780ae5f82c4841e7eeb60ff)) +* fix bug of duplicate modals for wallet connect ([efb5482](https://github.com/rango-exchange/rango-client/commit/efb54827fd51e6c6c8f42c6abf33c3d7610755e8)) +* handle replaced transactions ([1c8598d](https://github.com/rango-exchange/rango-client/commit/1c8598d2755afc9e439ee80c0951d83c6aed9f2a)) + + + +## [0.1.13](https://github.com/rango-exchange/rango-client/compare/queue-manager-rango-preset@0.1.12...queue-manager-rango-preset@0.1.13) (2023-05-15) + + +### Bug Fixes + +* fix flow bug when check status failed ([3a886e6](https://github.com/rango-exchange/rango-client/commit/3a886e68cf45c8bf500823fae96070acbbd3942a)) +* getChainId & networkMatched on wallet connect v1 ([9ec8cfb](https://github.com/rango-exchange/rango-client/commit/9ec8cfbd3f9be9befcfb632485afa1ee436e92a2)) +* update rango-types and fix notification bugs ([993f185](https://github.com/rango-exchange/rango-client/commit/993f185e0b8c5e5e15a2c65ba2d85d1f9c8daa90)) + + + diff --git a/queue-manager/rango-preset/package.json b/queue-manager/rango-preset/package.json index e7c8d101a3..34e2bb8ed4 100644 --- a/queue-manager/rango-preset/package.json +++ b/queue-manager/rango-preset/package.json @@ -1,59 +1,41 @@ { "name": "@rango-dev/queue-manager-rango-preset", - "version": "0.1.12-next.1", + "version": "0.40.1-next.6", "license": "MIT", - "module": "dist/queue-manager-rango-preset.esm.js", - "main": "dist/index.js", + "type": "module", + "source": "./src/index.ts", + "main": "./dist/index.js", + "exports": { + ".": "./dist/index.js" + }, "typings": "dist/index.d.ts", "files": [ "dist", "src" ], "scripts": { - "dev": "tsdx watch", - "build": "tsdx build --tsconfig ./tsconfig.json", - "test": "tsdx test", - "lint": "tsdx lint", - "size": "size-limit", - "analyze": "size-limit --why" + "build": "node ../../scripts/build/command.mjs --path queue-manager/rango-preset", + "ts-check": "tsc --declaration --emitDeclarationOnly -p ./tsconfig.json", + "clean": "rimraf dist", + "format": "prettier --write '{.,src}/**/*.{ts,tsx}'", + "lint": "eslint \"**/*.{ts,tsx}\" --ignore-path ../../.eslintignore" }, "peerDependencies": { "@rango-dev/queue-manager-core": "*", "@rango-dev/queue-manager-react": "*", "@rango-dev/wallets-core": "*", "@rango-dev/wallets-shared": "*", - "@sentry/browser": "*", "bignumber.js": "*", "rango-sdk": "*", "rango-types": "*", "uuid": "*" }, - "husky": { - "hooks": { - "pre-commit": "tsdx lint" - } - }, - "prettier": { - "printWidth": 80, - "semi": true, - "singleQuote": true, - "trailingComma": "es5" - }, - "size-limit": [ - { - "path": "dist/queue-manager-rango-preset.cjs.production.min.js", - "limit": "10 KB" - }, - { - "path": "dist/queue-manager-rango-preset.esm.js", - "limit": "10 KB" - } - ], "devDependencies": { "@types/uuid": "^8.3.4" }, "dependencies": { - "@sentry/browser": "^6.12.0", + "@rango-dev/logging-core": "^0.6.0", + "rango-types": "^0.1.74", "uuid": "^9.0.0" }, "publishConfig": { diff --git a/queue-manager/rango-preset/readme.md b/queue-manager/rango-preset/readme.md index 23149ca1ec..119b482fe2 100644 --- a/queue-manager/rango-preset/readme.md +++ b/queue-manager/rango-preset/readme.md @@ -1 +1,2 @@ # @rango-dev/queue-manager-rango-preset + diff --git a/queue-manager/rango-preset/src/actions/checkStatus.ts b/queue-manager/rango-preset/src/actions/checkStatus.ts index 246d0aa2b1..881e97e947 100644 --- a/queue-manager/rango-preset/src/actions/checkStatus.ts +++ b/queue-manager/rango-preset/src/actions/checkStatus.ts @@ -1,22 +1,33 @@ -import { ExecuterActions } from '@rango-dev/queue-manager-core'; +import type { SwapQueueContext, SwapStorage } from '../types'; +import type { ExecuterActions } from '@rango-dev/queue-manager-core'; +import type { Transaction, TransactionStatusResponse } from 'rango-sdk'; +import type { GenericSigner } from 'rango-types'; + +import { DEFAULT_ERROR_CODE } from '../constants'; import { delay, getCurrentStep, - isCosmosTransaction, - isEvmTransaction, - isSolanaTransaction, - isStarknetTransaction, - isTrasnferTransaction, - isTronTransaction, + getCurrentStepTx, + getCurrentStepTxType, + inMemoryTransactionsData, resetNetworkStatus, + setCurrentStepTx, updateSwapStatus, } from '../helpers'; -import { SwapActionTypes, SwapQueueContext, SwapStorage } from '../types'; -import { getNextStep, MessageSeverity } from '../shared'; -import { TransactionStatusResponse } from 'rango-sdk'; import { httpService } from '../services'; +import { notifier } from '../services/eventEmitter'; +import { + getCurrentNamespaceOf, + getNextStep, + getRelatedWallet, + getScannerUrl, + MessageSeverity, +} from '../shared'; +import { prettifyErrorMessage } from '../shared-errors'; +import { StepEventType, SwapActionTypes } from '../types'; -const INTERVAL_FOR_CHECK = 3_000; +const INTERVAL_FOR_CHECK_STATUS = 5_000; +const INTERVAL_FOR_CHECK_APPROVAL = 5_000; /** * Subscribe to status of swap transaction by checking from server periodically. @@ -28,6 +39,7 @@ async function checkTransactionStatus({ next, schedule, retry, + failed, context, }: ExecuterActions< SwapStorage, @@ -35,27 +47,136 @@ async function checkTransactionStatus({ SwapQueueContext >): Promise { const swap = getStorage().swapDetails; + const { meta } = context; // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const currentStep = getCurrentStep(swap)!; - const txId = currentStep.executedTransactionId; + if (!currentStep?.executedTransactionId) { + return; + } + const tx = getCurrentStepTx(currentStep); + let txId = currentStep.executedTransactionId; + let getTxReceiptFailed = false; let status: TransactionStatusResponse | null = null; + let signer: GenericSigner | null = null; + const { getTransactionDataByHash, setTransactionDataByHash } = + inMemoryTransactionsData(); + + try { + const txType = getCurrentStepTxType(currentStep); + const sourceWallet = getRelatedWallet(swap, currentStep); + if (txType && sourceWallet) { + signer = (await context.getSigners(sourceWallet.walletType)).getSigner( + txType + ); + } + } catch (error) { + /* + * wallet is not connected yet + * no need to do anything + */ + } + + try { + // if wallet is connected, try to get transaction reciept + const { response: txResponse, receiptReceived } = + getTransactionDataByHash(txId); + if (signer?.wait && !receiptReceived) { + const chainId = + (tx?.blockChain && meta.blockchains?.[tx?.blockChain]?.chainId) || + undefined; + const { hash: updatedTxHash, response: updatedTxResponse } = + await signer.wait(txId, chainId, txResponse); + if (updatedTxHash !== txId) { + currentStep.executedTransactionId = + updatedTxHash || currentStep.executedTransactionId; + const currentStepNamespace = getCurrentNamespaceOf(swap, currentStep); + let explorerUrl: string | undefined; + const blockchainsMetaNotEmpty = !!Object.keys(meta.blockchains).length; + if (blockchainsMetaNotEmpty) { + explorerUrl = getScannerUrl( + currentStep.executedTransactionId, + currentStepNamespace.network, + meta.blockchains + ); + } + if (explorerUrl) { + if (currentStep.explorerUrl && currentStep.explorerUrl?.length >= 1) { + currentStep.explorerUrl[currentStep.explorerUrl.length - 1] = { + url: explorerUrl, + description: 'Replaced Swap', + }; + } + } + txId = currentStep.executedTransactionId; + if (updatedTxHash && updatedTxResponse) { + setTransactionDataByHash(updatedTxHash, { + response: updatedTxResponse, + }); + } + } else { + setTransactionDataByHash(updatedTxHash, { + receiptReceived: true, + }); + } + } + } catch (error) { + const { extraMessage, extraMessageDetail, extraMessageErrorCode } = + prettifyErrorMessage(error); + const updateResult = updateSwapStatus({ + getStorage, + setStorage, + nextStatus: 'failed', + nextStepStatus: 'failed', + message: extraMessage, + details: extraMessageDetail, + errorCode: extraMessageErrorCode, + }); + + notifier({ + event: { + type: StepEventType.FAILED, + reason: extraMessage, + reasonCode: updateResult.failureType ?? DEFAULT_ERROR_CODE, + }, + ...updateResult, + }); + + getTxReceiptFailed = true; + /* + * We shouldn't return here, because we need to trigger check status job in backend. + * This is not a ui requirement but the backend one. + */ + } + try { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion status = await httpService().checkStatus({ requestId: swap.requestId, - txId: txId!, + txId, step: currentStep.id, }); } catch (e) { - await delay(INTERVAL_FOR_CHECK); + await delay(INTERVAL_FOR_CHECK_STATUS); retry(); return; } + /* + * If user cancel swap during check status api call, + * or getting transaction receipt failed, + * we should ignore check status response and return + */ + if (getTxReceiptFailed) { + return failed(); + } + if (currentStep?.status === 'failed') { + return; + } + const outputAmount: string | null = status?.outputAmount || - (!!currentStep.outputAmount ? currentStep.outputAmount : null); + (currentStep.outputAmount ? currentStep.outputAmount : null); const prevOutputAmount = currentStep.outputAmount || null; swap.extraMessage = status?.extraMessage || swap.extraMessage; swap.extraMessageSeverity = MessageSeverity.info; @@ -70,51 +191,23 @@ async function checkTransactionStatus({ const newTransaction = status?.newTx; - if (!!newTransaction) { + if (newTransaction) { currentStep.status = 'created'; currentStep.executedTransactionId = null; currentStep.executedTransactionTime = null; - currentStep.transferTransaction = null; - currentStep.cosmosTransaction = null; - currentStep.evmTransaction = null; - currentStep.solanaTransaction = null; - currentStep.evmApprovalTransaction = null; - currentStep.starknetApprovalTransaction = null; - currentStep.starknetTransaction = null; - currentStep.tronApprovalTransaction = null; - currentStep.tronTransaction = null; - - if (isEvmTransaction(newTransaction)) { - if (newTransaction.isApprovalTx) - currentStep.evmApprovalTransaction = newTransaction; - else currentStep.evmTransaction = newTransaction; - } else if (isCosmosTransaction(newTransaction)) { - currentStep.cosmosTransaction = newTransaction; - } else if (isSolanaTransaction(newTransaction)) { - currentStep.solanaTransaction = newTransaction; - } else if (isTrasnferTransaction(newTransaction)) { - currentStep.transferTransaction = newTransaction; - } else if (isStarknetTransaction(newTransaction)) { - if (newTransaction.isApprovalTx) - currentStep.starknetApprovalTransaction = newTransaction; - else currentStep.starknetTransaction = newTransaction; - } else if (isTronTransaction(newTransaction)) { - if (newTransaction.isApprovalTx) - currentStep.tronApprovalTransaction = newTransaction; - else currentStep.tronTransaction = newTransaction; - } + setCurrentStepTx(currentStep, newTransaction); } - if (prevOutputAmount === null && outputAmount !== null) - context.notifier({ - eventType: 'step_completed_with_output', + if (prevOutputAmount === null && outputAmount !== null) { + notifier({ + event: { type: StepEventType.OUTPUT_REVEALED, outputAmount }, swap: swap, step: currentStep, }); - else if (prevOutputAmount === null && outputAmount === null) { + } else if (prevOutputAmount === null && outputAmount === null) { // it is needed to set notification after reloading the page - context.notifier({ - eventType: 'check_tx_status', + notifier({ + event: { type: StepEventType.CHECK_STATUS }, swap: swap, step: currentStep, }); @@ -123,27 +216,38 @@ async function checkTransactionStatus({ if (currentStep.status === 'success') { const nextStep = getNextStep(swap, currentStep); swap.extraMessageDetail = ''; - swap.extraMessage = !!nextStep + swap.extraMessage = nextStep ? `starting next step: ${nextStep.swapperId}: ${nextStep.fromBlockchain} -> ${nextStep.toBlockchain}` : ''; + notifier({ + event: { + type: StepEventType.SUCCEEDED, + outputAmount: currentStep.outputAmount ?? '', + }, + swap, + step: currentStep, + }); } else if (currentStep.status === 'failed') { swap.extraMessage = 'Transaction failed in blockchain'; swap.extraMessageSeverity = MessageSeverity.error; - swap.extraMessageDetail = ''; + swap.extraMessageDetail = status?.extraMessage || ''; + swap.status = 'failed'; + swap.finishTime = new Date().getTime().toString(); } // Sync data with storage setStorage({ ...getStorage(), swapDetails: swap }); - if ( - status?.status === 'failed' || + if (status?.status === 'failed') { + failed(); + } else if ( status?.status === 'success' || (status?.status === 'running' && !!status.newTx) ) { schedule(SwapActionTypes.SCHEDULE_NEXT_STEP); next(); } else { - await delay(INTERVAL_FOR_CHECK); + await delay(INTERVAL_FOR_CHECK_STATUS); retry(); } } @@ -165,46 +269,161 @@ async function checkApprovalStatus({ SwapActionTypes, SwapQueueContext >): Promise { - const swap = getStorage().swapDetails as SwapStorage['swapDetails']; - // double check it after fixing parallel - // const onFinish = () => { - // // TODO resetClaimedBy is undefined here - // if (context.resetClaimedBy) { - // context.resetClaimedBy(); - // } - // }; - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - const currentStep = getCurrentStep(swap)!; + const swap = getStorage().swapDetails; + const { meta } = context; + const { getTransactionDataByHash, setTransactionDataByHash } = + inMemoryTransactionsData(); + + const currentStep = getCurrentStep(swap); + if (!currentStep) { + console.log('ignore check status, current step is null'); + return; + } + const tx = getCurrentStepTx(currentStep); + + if (!currentStep?.executedTransactionId) { + return; + } + let txId = currentStep.executedTransactionId; + + let signer: GenericSigner | null = null; + try { + const txType = getCurrentStepTxType(currentStep); + const sourceWallet = getRelatedWallet(swap, currentStep); + if (txType && sourceWallet) { + const walletSigners = await context.getSigners(sourceWallet.walletType); + signer = walletSigners.getSigner(txType); + } + } catch (error) { + /* + * wallet is not connected yet + * no need to do anything + */ + } + + try { + const { response: txResponse, receiptReceived } = + getTransactionDataByHash(txId); + // if wallet is connected, try to get transaction reciept + if (signer?.wait && !receiptReceived) { + const chainId = + (tx?.blockChain && meta.blockchains?.[tx?.blockChain]?.chainId) || + undefined; + const { hash: updatedTxHash, response: updatedTxResponse } = + await signer.wait(txId, chainId, txResponse); + if (updatedTxHash !== txId) { + currentStep.executedTransactionId = + updatedTxHash || currentStep.executedTransactionId; + const currentStepNamespace = getCurrentNamespaceOf(swap, currentStep); + let explorerUrl: string | undefined; + const blockchainsMetaNotEmpty = !!Object.keys(meta.blockchains).length; + if (blockchainsMetaNotEmpty) { + explorerUrl = getScannerUrl( + currentStep.executedTransactionId, + currentStepNamespace.network, + meta.blockchains + ); + } + if (explorerUrl) { + if (currentStep.explorerUrl && currentStep.explorerUrl?.length >= 1) { + currentStep.explorerUrl[currentStep.explorerUrl.length - 1] = { + url: explorerUrl, + description: 'Replaced Approve', + }; + } + } + txId = currentStep.executedTransactionId; + if (updatedTxHash && updatedTxResponse) { + setTransactionDataByHash(updatedTxHash, { + response: updatedTxResponse, + }); + } + } else { + setTransactionDataByHash(updatedTxHash, { + receiptReceived: true, + }); + } + } + } catch (error) { + const { extraMessage, extraMessageDetail, extraMessageErrorCode } = + prettifyErrorMessage(error); + const updateResult = updateSwapStatus({ + getStorage, + setStorage, + nextStatus: 'failed', + nextStepStatus: 'failed', + message: extraMessage, + details: extraMessageDetail, + errorCode: extraMessageErrorCode, + }); + notifier({ + event: { + type: StepEventType.FAILED, + reason: extraMessage, + reasonCode: updateResult.failureType ?? DEFAULT_ERROR_CODE, + }, + ...updateResult, + }); + return failed(); + } + let isApproved = false; try { const response = await httpService().checkApproval( swap.requestId, - currentStep.executedTransactionId || '' + currentStep.executedTransactionId ); + // If user cancel swap during check status api call, we should ignore check approval response + if (currentStep?.status === 'failed') { + return; + } + isApproved = response.isApproved; - if (!isApproved && response.txStatus === 'failed') { - // approve transaction failed on - // we should fail the whole swap + if ( + !isApproved && + (response.txStatus === 'failed' || response.txStatus === 'success') + ) { + let message, details; + if (response.txStatus === 'failed') { + message = 'Approve transaction failed'; + details = 'Smart contract approval tx failed in blockchain.'; + } else { + message = 'Not enough approval'; + if (response.requiredApprovedAmount && response.currentApprovedAmount) { + details = `Required approval: ${response.requiredApprovedAmount}, current approval: ${response.currentApprovedAmount}`; + } else { + details = `You still don't have enough approval for this swap.`; + } + } + /* + * approve transaction failed on + * we should fail the whole swap + */ const updateResult = updateSwapStatus({ getStorage, setStorage, nextStatus: 'failed', nextStepStatus: 'failed', - errorCode: 'SEND_TX_FAILED', - message: 'Approve transaction failed', - details: 'Smart contract approval failed in blockchain.', + errorCode: 'INSUFFICIENT_APPROVE', + message: message, + details: details, }); - context.notifier({ - eventType: 'smart_contract_call_failed', + + notifier({ + event: { + type: StepEventType.FAILED, + reason: message, + reasonCode: updateResult.failureType ?? DEFAULT_ERROR_CODE, + }, ...updateResult, }); + failed(); - // onFinish(); } else if (!isApproved) { // it is needed to set notification after reloading the page - context.notifier({ - eventType: 'check_approve_tx_status', - swap: swap, + notifier({ + event: { type: StepEventType.CHECK_STATUS }, + swap, step: currentStep, }); } @@ -227,8 +446,8 @@ async function checkApprovalStatus({ swapDetails: swap, }); - context.notifier({ - eventType: 'contract_confirmed', + notifier({ + event: { type: StepEventType.APPROVAL_TX_SUCCEEDED }, swap: swap, step: currentStep, }); @@ -236,7 +455,7 @@ async function checkApprovalStatus({ schedule(SwapActionTypes.SCHEDULE_NEXT_STEP); next(); } else { - await delay(2000); + await delay(INTERVAL_FOR_CHECK_APPROVAL); retry(); } } @@ -253,11 +472,16 @@ export async function checkStatus( actions: ExecuterActions ): Promise { const swap = actions.getStorage().swapDetails; - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - const currentStep = getCurrentStep(swap)!; + const currentStep = getCurrentStep(swap); + if (!currentStep) { + console.log('ignore check status, current step is null', swap.requestId); + return; + } - // Reset network status - // Because when check status is on `loading` or `failed` status, it shows previous message that isn't related to current state. + /* + * Reset network status + * Because when check status is on `loading` or `failed` status, it shows previous message that isn't related to current state. + */ resetNetworkStatus(actions); if (currentStep.status === 'running') { diff --git a/queue-manager/rango-preset/src/actions/createTransaction.ts b/queue-manager/rango-preset/src/actions/createTransaction.ts index cae72c3e1c..e2d3f50a73 100644 --- a/queue-manager/rango-preset/src/actions/createTransaction.ts +++ b/queue-manager/rango-preset/src/actions/createTransaction.ts @@ -1,19 +1,23 @@ -import { ExecuterActions } from '@rango-dev/queue-manager-core'; -import { SwapActionTypes, SwapQueueContext, SwapStorage } from '../types'; +import type { SwapQueueContext, SwapStorage } from '../types'; +import type { ExecuterActions } from '@rango-dev/queue-manager-core'; +import type { CreateTransactionRequest } from 'rango-sdk'; + +import { DEFAULT_ERROR_CODE } from '../constants'; import { getCurrentStep, - isCosmosTransaction, - isEvmTransaction, - isSolanaTransaction, - isTrasnferTransaction, - isStarknetTransaction, - isTronTransaction, - updateSwapStatus, + getCurrentStepTx, + setCurrentStepTx, throwOnOK, + updateSwapStatus, } from '../helpers'; -import { prettifyErrorMessage } from '../shared-errors'; -import { CreateTransactionRequest } from 'rango-sdk'; import { httpService } from '../services'; +import { notifier } from '../services/eventEmitter'; +import { prettifyErrorMessage } from '../shared-errors'; +import { + StepEventType, + StepExecutionEventStatus, + SwapActionTypes, +} from '../types'; /** * @@ -25,34 +29,21 @@ import { httpService } from '../services'; export async function createTransaction( actions: ExecuterActions ): Promise { - const { setStorage, getStorage, next, schedule, context } = actions; + const { setStorage, getStorage, next, schedule } = actions; const swap = getStorage().swapDetails; // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const currentStep = getCurrentStep(swap)!; + const transaction = getCurrentStepTx(currentStep); - const { - evmTransaction, - cosmosTransaction, - transferTransaction, - evmApprovalTransaction, - solanaTransaction, - tronTransaction, - tronApprovalTransaction, - starknetTransaction, - starknetApprovalTransaction, - } = currentStep; - - if ( - !evmTransaction && - !evmApprovalTransaction && - !tronTransaction && - !tronApprovalTransaction && - !starknetTransaction && - !starknetApprovalTransaction && - !cosmosTransaction && - !transferTransaction && - !solanaTransaction - ) { + if (!transaction) { + notifier({ + event: { + type: StepEventType.TX_EXECUTION, + status: StepExecutionEventStatus.CREATE_TX, + }, + swap, + step: currentStep, + }); const request: CreateTransactionRequest = { requestId: swap.requestId, step: currentStep.id, @@ -63,6 +54,7 @@ export async function createTransaction( validations: { balance: swap.validateBalanceOrFee, fee: swap.validateBalanceOrFee, + approve: true, }, }; try { @@ -73,25 +65,7 @@ export async function createTransaction( ); if (transaction) { - if (isEvmTransaction(transaction)) { - if (transaction.isApprovalTx) - currentStep.evmApprovalTransaction = transaction; - else currentStep.evmTransaction = transaction; - } else if (isCosmosTransaction(transaction)) { - currentStep.cosmosTransaction = transaction; - } else if (isSolanaTransaction(transaction)) { - currentStep.solanaTransaction = transaction; - } else if (isTrasnferTransaction(transaction)) { - currentStep.transferTransaction = transaction; - } else if (isStarknetTransaction(transaction)) { - if (transaction.isApprovalTx) - currentStep.starknetApprovalTransaction = transaction; - else currentStep.starknetTransaction = transaction; - } else if (isTronTransaction(transaction)) { - if (transaction.isApprovalTx) - currentStep.tronApprovalTransaction = transaction; - else currentStep.tronTransaction = transaction; - } + setCurrentStepTx(currentStep, transaction); } setStorage({ ...getStorage(), swapDetails: swap }); @@ -111,8 +85,13 @@ export async function createTransaction( details: extraMessageDetail, errorCode: 'FETCH_TX_FAILED', }); - context.notifier({ - eventType: 'task_failed', + + notifier({ + event: { + type: StepEventType.FAILED, + reason: extraMessage, + reasonCode: updateResult.failureType ?? DEFAULT_ERROR_CODE, + }, ...updateResult, }); diff --git a/queue-manager/rango-preset/src/actions/executeTransaction.ts b/queue-manager/rango-preset/src/actions/executeTransaction.ts index ade0a523bb..eaee9886f0 100644 --- a/queue-manager/rango-preset/src/actions/executeTransaction.ts +++ b/queue-manager/rango-preset/src/actions/executeTransaction.ts @@ -1,27 +1,28 @@ -import { ExecuterActions } from '@rango-dev/queue-manager-core'; +import type { SwapActionTypes, SwapQueueContext, SwapStorage } from '../types'; +import type { ExecuterActions } from '@rango-dev/queue-manager-core'; + +import { PendingSwapNetworkStatus } from 'rango-types'; + import { + ERROR_MESSAGE_DEPENDS_ON_OTHER_QUEUES, ERROR_MESSAGE_WAIT_FOR_CHANGE_NETWORK, ERROR_MESSAGE_WAIT_FOR_WALLET_DESCRIPTION, ERROR_MESSAGE_WAIT_FOR_WALLET_DESCRIPTION_WRONG_WALLET, } from '../constants'; - import { + claimQueue, getCurrentStep, + getRequiredWallet, + isNeedBlockQueueForParallel, isNetworkMatchedForTransaction, isRequiredWalletConnected, - updateNetworkStatus, - singTransaction, + isWalletNull, resetNetworkStatus, - getRequiredWallet, - isNeedBlockQueueForParallel, + signTransaction, + updateNetworkStatus, } from '../helpers'; -import { getCurrentBlockchainOf, PendingSwapNetworkStatus } from '../shared'; -import { - BlockReason, - SwapActionTypes, - SwapQueueContext, - SwapStorage, -} from '../types'; +import { getCurrentNamespaceOf } from '../shared'; +import { BlockReason } from '../types'; /** * Excecute a created transaction. @@ -37,6 +38,7 @@ export async function executeTransaction( ): Promise { const { getStorage, context } = actions; const { meta, wallets, providers } = context; + const { claimedBy } = claimQueue(); const isClaimed = context.claimedBy === context._queue?.id; const requestBlock: typeof actions.block = (blockedFor) => { @@ -61,7 +63,7 @@ export async function executeTransaction( (w) => !w.accounts?.find((account) => account.walletType === type) ); const description = - !wallets || isWalletInCompatible + isWalletNull(wallets) || isWalletInCompatible ? ERROR_MESSAGE_WAIT_FOR_WALLET_DESCRIPTION(type) : ERROR_MESSAGE_WAIT_FOR_WALLET_DESCRIPTION_WRONG_WALLET(type, address); @@ -73,22 +75,6 @@ export async function executeTransaction( return; } - /* - For avoiding conflict by making too many requests to wallet, we need to make sure - We only run one request at a time (In parallel mode). - */ - const needsToBlockQueue = isNeedBlockQueueForParallel(currentStep); - - if (needsToBlockQueue && !isClaimed) { - const blockedFor = { - reason: BlockReason.DEPENDS_ON_OTHER_QUEUES, - description: 'Waiting for other swaps to complete', - details: {}, - }; - requestBlock(blockedFor); - return; - } - /* Wallet should be on correct network */ const networkMatched = await isNetworkMatchedForTransaction( swap, @@ -97,9 +83,22 @@ export async function executeTransaction( meta, providers ); - if (!networkMatched) { - const fromBlockchain = getCurrentBlockchainOf(swap, currentStep); - const details = ERROR_MESSAGE_WAIT_FOR_CHANGE_NETWORK(fromBlockchain); + const claimerId = claimedBy(); + const isClaimedByAnyQueue = !!claimerId && !isClaimed; + if (isClaimedByAnyQueue && !networkMatched) { + const details = ERROR_MESSAGE_DEPENDS_ON_OTHER_QUEUES; + + const blockedFor = { + reason: BlockReason.DEPENDS_ON_OTHER_QUEUES, + details: details, + }; + requestBlock(blockedFor); + return; + } else if (!networkMatched) { + const fromNamespace = getCurrentNamespaceOf(swap, currentStep); + const details = ERROR_MESSAGE_WAIT_FOR_CHANGE_NETWORK( + fromNamespace.network + ); const blockedFor = { reason: BlockReason.WAIT_FOR_NETWORK_CHANGE, @@ -107,15 +106,30 @@ export async function executeTransaction( }; requestBlock(blockedFor); return; - } else { - // Update network to mark it as network changed successfully. - updateNetworkStatus(actions, { - message: '', - details: 'Wallet network changed successfully', - status: PendingSwapNetworkStatus.NetworkChanged, - }); + } + // Update network to mark it as network changed successfully. + updateNetworkStatus(actions, { + message: '', + details: 'Wallet network changed successfully', + status: PendingSwapNetworkStatus.NetworkChanged, + }); + + /* + *For avoiding conflict by making too many requests to wallet, we need to make sure + *We only run one request at a time (In parallel mode). + */ + const needsToBlockQueue = isNeedBlockQueueForParallel(currentStep); + + if (needsToBlockQueue && !isClaimed) { + const blockedFor = { + reason: BlockReason.DEPENDS_ON_OTHER_QUEUES, + description: ERROR_MESSAGE_DEPENDS_ON_OTHER_QUEUES, + details: {}, + }; + requestBlock(blockedFor); + return; } // All the conditions are met. We can safely send the tx to wallet for sign. - singTransaction(actions); + await signTransaction(actions); } diff --git a/queue-manager/rango-preset/src/actions/scheduleNextStep.ts b/queue-manager/rango-preset/src/actions/scheduleNextStep.ts index dfe4e5bf1d..61b7c2ac4a 100644 --- a/queue-manager/rango-preset/src/actions/scheduleNextStep.ts +++ b/queue-manager/rango-preset/src/actions/scheduleNextStep.ts @@ -1,6 +1,14 @@ -import { ExecuterActions } from '@rango-dev/queue-manager-core'; -import { SwapActionTypes, SwapQueueContext, SwapStorage } from '../types'; -import { getCurrentStep, isTxAlreadyCreated } from '../helpers'; +import type { SwapQueueContext, SwapStorage } from '../types'; +import type { ExecuterActions } from '@rango-dev/queue-manager-core'; +import type { PendingSwapStep } from 'rango-types'; + +import { + getCurrentStep, + getLastSuccessfulStep, + isTxAlreadyCreated, +} from '../helpers'; +import { notifier } from '../services/eventEmitter'; +import { StepEventType, SwapActionTypes } from '../types'; /** * @@ -17,17 +25,19 @@ export function scheduleNextStep({ failed, setStorage, getStorage, - context, }: ExecuterActions): void { const swap = getStorage().swapDetails; const currentStep = getCurrentStep(swap); - if (!!currentStep) { + const isFailed = swap.steps.find( + (step: PendingSwapStep) => step.status === 'failed' + ); + + if (!!currentStep && !isFailed) { if (isTxAlreadyCreated(swap, currentStep)) { schedule(SwapActionTypes.EXECUTE_TRANSACTION); return next(); } - // TODO double check it after approval changes if (currentStep?.executedTransactionId) { schedule(SwapActionTypes.CHECK_TRANSACTION_STATUS); return next(); @@ -37,10 +47,15 @@ export function scheduleNextStep({ setStorage({ ...getStorage(), swapDetails: swap }); + notifier({ + event: { type: StepEventType.STARTED }, + swap, + step: currentStep, + }); + schedule(SwapActionTypes.CREATE_TRANSACTION); next(); } else { - const isFailed = swap.steps.find((step) => step.status === 'failed'); swap.status = isFailed ? 'failed' : 'success'; swap.finishTime = new Date().getTime().toString(); @@ -49,13 +64,30 @@ export function scheduleNextStep({ swapDetails: swap, }); - context.notifier({ - eventType: isFailed ? 'task_failed' : 'task_completed', + notifier({ + ...(isFailed + ? { + event: { + type: StepEventType.FAILED, + reason: swap.extraMessage ?? undefined, + reasonCode: 'CALL_OR_SEND_FAILED', + }, + } + : { + event: { + type: StepEventType.SUCCEEDED, + outputAmount: + getLastSuccessfulStep(swap.steps)?.outputAmount ?? '', + }, + }), swap: swap, step: null, }); - if (isFailed) failed(); - else next(); + if (isFailed) { + failed(); + } else { + next(); + } } } diff --git a/queue-manager/rango-preset/src/actions/start.ts b/queue-manager/rango-preset/src/actions/start.ts index a56f2f5c16..d5d13c64c4 100644 --- a/queue-manager/rango-preset/src/actions/start.ts +++ b/queue-manager/rango-preset/src/actions/start.ts @@ -1,10 +1,16 @@ import { ExecuterActions } from '@rango-dev/queue-manager-core'; -import { SwapActionTypes, SwapStorage } from '../types'; +import { StepEventType, SwapActionTypes, SwapStorage } from '../types'; +import { notifier } from '../services/eventEmitter'; export function start({ schedule, next, + getStorage, }: ExecuterActions): void { + const swap = getStorage().swapDetails; + + notifier({ event: { type: StepEventType.STARTED }, swap, step: null }); + schedule(SwapActionTypes.SCHEDULE_NEXT_STEP); next(); } diff --git a/queue-manager/rango-preset/src/configs.ts b/queue-manager/rango-preset/src/configs.ts index d53b8b0c8d..12a97cb5cf 100644 --- a/queue-manager/rango-preset/src/configs.ts +++ b/queue-manager/rango-preset/src/configs.ts @@ -1,19 +1,29 @@ +import type { RouteExecutionEvents } from './types'; + +interface Emitter> { + emit(type: K, event: Events[K]): void; +} + export interface Configs { API_KEY: string; BASE_URL?: string; + emitter?: Emitter; } -// this API key is limited and -// it is only for test purpose +/* + * this API key is limited and + * it is only for test purpose + */ const RANGO_PUBLIC_API_KEY = 'c6381a79-2817-4602-83bf-6a641a409e32'; let configs: Configs = { API_KEY: RANGO_PUBLIC_API_KEY, + BASE_URL: '', }; -export function getConfig(name: keyof Configs) { - return configs[name] || ''; +export function getConfig(name: K): Configs[K] { + return configs[name]; } export function setConfig(name: keyof Configs, value: any) { @@ -23,12 +33,6 @@ export function setConfig(name: keyof Configs, value: any) { } export function initConfig(nextConfigs: Configs) { - let clonedConfigs; - if (typeof structuredClone === 'function') { - clonedConfigs = structuredClone(nextConfigs); - } else { - clonedConfigs = JSON.parse(JSON.stringify(nextConfigs)); - } - configs = clonedConfigs; + configs = nextConfigs; return configs; } diff --git a/queue-manager/rango-preset/src/constants.ts b/queue-manager/rango-preset/src/constants.ts index fcfc125568..737c0f56b1 100644 --- a/queue-manager/rango-preset/src/constants.ts +++ b/queue-manager/rango-preset/src/constants.ts @@ -10,10 +10,9 @@ export const ERROR_MESSAGE_WAIT_FOR_WALLET_DESCRIPTION_WRONG_WALLET = ( }`; export const ERROR_MESSAGE_WAIT_FOR_WALLET_DESCRIPTION = ( type: string | null -): string => - `Please connect to ${ - type || 'your wallet' - } by using bellow button or top right button on page.`; +): string => `Please connect your ${type ?? ''} wallet.`; export const ERROR_MESSAGE_WAIT_FOR_CHANGE_NETWORK = ( network: string | null ): string => `Please change your network to ${network}.`; + +export const DEFAULT_ERROR_CODE = 'CLIENT_UNEXPECTED_BEHAVIOUR'; diff --git a/queue-manager/rango-preset/src/helpers.ts b/queue-manager/rango-preset/src/helpers.ts index 00231f6e12..8f76d7f553 100644 --- a/queue-manager/rango-preset/src/helpers.ts +++ b/queue-manager/rango-preset/src/helpers.ts @@ -1,72 +1,81 @@ -import { +/* eslint-disable destructuring/in-params */ +/* eslint-disable @typescript-eslint/no-magic-numbers */ +/* eslint-disable @typescript-eslint/no-floating-promises */ +import type { SwapStatus, TargetNamespace, Wallet } from './shared'; +import type { + ArrayElement, + Step, + SwapQueueContext, + SwapQueueDef, + SwapStorage, +} from './types'; +import type { ExecuterActions, + Manager, QueueInfo, QueueName, QueueType, } from '@rango-dev/queue-manager-core'; -import { - BlockReason, - SwapActionTypes, - SwapQueueContext, - SwapQueueDef, - SwapStorage, -} from './types'; -import { - getBlockChainNameFromId, +import type { Meta, Network, + Providers, WalletState, WalletType, } from '@rango-dev/wallets-shared'; -import { Providers, readAccountAddress } from '@rango-dev/wallets-core'; - -import { - TronTransaction, - StarknetTransaction, - CosmosTransaction, - EvmTransaction, - SolanaTransaction, - Transfer as TransferTransaction, - Transaction, - TransactionType, - EvmBlockchainMeta, +import type { CreateTransactionResponse, + EvmBlockchainMeta, + Transaction, } from 'rango-sdk'; +import type { + APIErrorCode, + PendingSwap, + PendingSwapStep, + SignerErrorCode, + StepStatus, +} from 'rango-types'; + +import { warn } from '@rango-dev/logging-core'; +import { Status } from '@rango-dev/queue-manager-core'; +import { legacyReadAccountAddress as readAccountAddress } from '@rango-dev/wallets-core/legacy'; +import { + getBlockChainNameFromId, + getEvmProvider, + splitWalletNetwork, +} from '@rango-dev/wallets-shared'; +import { TransactionType } from 'rango-sdk'; +import { PendingSwapNetworkStatus, SignerError } from 'rango-types'; import { + DEFAULT_ERROR_CODE, ERROR_MESSAGE_WAIT_FOR_CHANGE_NETWORK, ERROR_MESSAGE_WAIT_FOR_WALLET, ERROR_MESSAGE_WAIT_FOR_WALLET_DESCRIPTION, } from './constants'; -import { Manager } from '@rango-dev/queue-manager-core'; -import { Status } from '@rango-dev/queue-manager-core'; +import { httpService } from './services'; +import { notifier } from './services/eventEmitter'; import { - EventType, - getCurrentBlockchainOf, - getCurrentBlockchainOfOrNull, - getEvmApproveUrl, - getStarknetApproveUrl, - getTronApproveUrl, + getCurrentAddressOf, + getCurrentNamespaceOf, + getCurrentNamespaceOfOrNull, + getRelatedWallet, getRelatedWalletOrNull, + getScannerUrl, MessageSeverity, - PendingSwap, - PendingSwapNetworkStatus, - PendingSwapStep, - StepStatus, - SwapStatus, - Wallet, - SwapProgressNotification, - getRelatedWallet, - getCurrentAddressOf, } from './shared'; -import { logRPCError } from './shared-sentry'; import { - PrettyError, mapAppErrorCodesToAPIErrorCode, prettifyErrorMessage, + PrettyError, } from './shared-errors'; -import { httpService } from './services'; -import { APIErrorCode, SignerErrorCode } from 'rango-types/lib'; +import { + BlockReason, + StepEventType, + StepExecutionBlockedEventStatus, + StepExecutionEventStatus, + SwapActionTypes, +} from './types'; type WhenTaskBlocked = Parameters>; type WhenTaskBlockedEvent = WhenTaskBlocked[0]; @@ -79,7 +88,7 @@ let swapClaimedBy: { id: string } | null = null; * We simply use module-level variable to keep track of which queue has claimed the execution of parallel runnings. * */ -function claimQueue() { +export function claimQueue() { return { claimedBy: () => swapClaimedBy?.id, setClaimer: (queue_id: string) => { @@ -94,26 +103,33 @@ function claimQueue() { } /** - * Sample inputs are: - * - "metamask-ETH" - * - "metamask-BSC-BSC:0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - * - "token-pocket-BSC-BSC:0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - * Returns "wallet and network" separately, even if the wallet is dashed inside. + * + * We use module-level variable to keep track of + * map of transactions hash to the TransactionResponse and ... * */ - -export function splitWalletNetwork(input: string): string[] { - const removedAddressInput = input?.split(':')[0] || ''; - const splittedInput = removedAddressInput.split('-'); - const network = splittedInput[splittedInput.length - 1]; - const walletNetwork = splittedInput.slice(0, -1); - - if (walletNetwork[walletNetwork.length - 1] === network) { - walletNetwork.pop(); - } - const wallet = walletNetwork.join('-'); - - return [wallet, network]; +type TransactionData = { + response?: any; // e.g. TransactionResponse in case of EVM transactions + receiptReceived?: boolean; // e.g. is TransactionReceipt ready in case of EVM transactions +}; +const swapTransactionToDataMap: { [id: string]: TransactionData } = {}; +export function inMemoryTransactionsData() { + return { + getTransactionDataByHash: (hash: string) => + swapTransactionToDataMap[hash] || {}, + setTransactionDataByHash: (hash: string, data: TransactionData) => { + const r = swapTransactionToDataMap[hash]; + if (!r) { + swapTransactionToDataMap[hash] = {}; + } + swapTransactionToDataMap[hash].response = + data.response || swapTransactionToDataMap[hash].response; + swapTransactionToDataMap[hash].receiptReceived = + data.receiptReceived || + swapTransactionToDataMap[hash].receiptReceived || + false; + }, + }; } /** @@ -130,6 +146,134 @@ export const getCurrentStep = (swap: PendingSwap): PendingSwapStep | null => { ); }; +/** + * + * Returns current step transaction + * + */ +export const getCurrentStepTx = ( + currentStep: PendingSwapStep +): Transaction | null => { + const { + evmTransaction, + evmApprovalTransaction, + cosmosTransaction, + solanaTransaction, + transferTransaction, + starknetApprovalTransaction, + starknetTransaction, + tronApprovalTransaction, + tronTransaction, + tonTransaction, + } = currentStep; + return ( + evmTransaction || + evmApprovalTransaction || + cosmosTransaction || + solanaTransaction || + transferTransaction || + starknetApprovalTransaction || + starknetTransaction || + tronApprovalTransaction || + tronTransaction || + tonTransaction + ); +}; + +/** + * + * Set current step transaction + * + */ +export const setCurrentStepTx = ( + currentStep: PendingSwapStep, + transaction: Transaction +): PendingSwapStep => { + currentStep.transferTransaction = null; + currentStep.cosmosTransaction = null; + currentStep.evmTransaction = null; + currentStep.solanaTransaction = null; + currentStep.evmApprovalTransaction = null; + currentStep.starknetApprovalTransaction = null; + currentStep.starknetTransaction = null; + currentStep.tronApprovalTransaction = null; + currentStep.tronTransaction = null; + currentStep.tonTransaction = null; + + const txType = transaction.type; + switch (txType) { + case TransactionType.EVM: + if (transaction.isApprovalTx) { + currentStep.evmApprovalTransaction = transaction; + } else { + currentStep.evmTransaction = transaction; + } + break; + case TransactionType.TRON: + if (transaction.isApprovalTx) { + currentStep.tronApprovalTransaction = transaction; + } else { + currentStep.tronTransaction = transaction; + } + break; + case TransactionType.STARKNET: + if (transaction.isApprovalTx) { + currentStep.starknetApprovalTransaction = transaction; + } else { + currentStep.starknetTransaction = transaction; + } + break; + case TransactionType.COSMOS: + currentStep.cosmosTransaction = transaction; + break; + case TransactionType.SOLANA: + currentStep.solanaTransaction = transaction; + break; + case TransactionType.TRANSFER: + currentStep.transferTransaction = transaction; + break; + case TransactionType.TON: + currentStep.tonTransaction = transaction; + break; + default: + ((x: never) => { + throw new Error(`${x} was unhandled!`); + })(txType); + } + return currentStep; +}; + +/** + * + * Returns current step transaction type + * + */ +export const getCurrentStepTxType = ( + currentStep: PendingSwapStep +): TransactionType | undefined => { + return getCurrentStepTx(currentStep)?.type; +}; + +/** + * + * Returns a boolean indicating that current step is an approval tx or not. + * + */ +export const isApprovalCurrentStepTx = ( + currentStep: PendingSwapStep +): boolean => { + const { + evmApprovalTransaction, + starknetApprovalTransaction, + tronApprovalTransaction, + } = currentStep; + return !!( + evmApprovalTransaction || + starknetApprovalTransaction || + tronApprovalTransaction + ); +}; + /** * When we are doing a swap, there are some common fields that will be updated together. * This function helps us to update a swap status and also it will update some more fields like `extraMessageSeverity` based on the input. @@ -143,6 +287,7 @@ export function updateSwapStatus({ details, errorCode = null, hasAlreadyProceededToSign, + trace = null, }: { getStorage: ExecuterActions< SwapStorage, @@ -160,18 +305,33 @@ export function updateSwapStatus({ details?: string | null | undefined; errorCode?: APIErrorCode | SignerErrorCode | null; hasAlreadyProceededToSign?: boolean; + trace?: Error | null | undefined; }): { swap: PendingSwap; step: PendingSwapStep | null; + failureType?: APIErrorCode; } { const swap = getStorage().swapDetails; const currentStep = getCurrentStep(swap); - if (!!nextStepStatus && !!currentStep) currentStep.status = nextStepStatus; + const updatedResult: { + swap: PendingSwap; + step: PendingSwapStep | null; + failureType?: APIErrorCode; + } = { + swap, + step: currentStep, + }; + if (!!nextStepStatus && !!currentStep) { + currentStep.status = nextStepStatus; + } - if (!!nextStatus) swap.status = nextStatus; + if (nextStatus) { + swap.status = nextStatus; + } swap.hasAlreadyProceededToSign = hasAlreadyProceededToSign; - if (!!nextStatus && ['failed', 'success'].includes(nextStatus)) + if (!!nextStatus && ['failed', 'success'].includes(nextStatus)) { swap.finishTime = new Date().getTime().toString(); + } if (!!message || !!details) { swap.extraMessage = message || ''; @@ -184,46 +344,69 @@ export function updateSwapStatus({ details && details.includes('Warning') ? 'Swap canceled by user.' : details; - const walletType = getRelatedWalletOrNull(swap, currentStep!)?.walletType; + const walletType = getRelatedWalletOrNull(swap, currentStep)?.walletType; swap.extraMessageSeverity = MessageSeverity.error; + const failureType = mapAppErrorCodesToAPIErrorCode(errorCode); + updatedResult.failureType = failureType; + + // If trace of error was available, we will send it to the api (except user rejection) + const errorReasonForAPI = + errorCode !== 'REJECTED_BY_USER' && + trace?.message && + typeof trace.message === 'string' + ? trace.message + : errorReason || ''; + httpService() .reportFailure({ requestId: swap.requestId, step: currentStep?.id || 1, - eventType: mapAppErrorCodesToAPIErrorCode(errorCode), - reason: errorReason || '', - data: walletType ? { wallet: walletType } : undefined, + eventType: failureType, + reason: errorReasonForAPI, + tags: walletType + ? { + wallet: walletType, + } + : undefined, }) .then() .catch(); - } else if (!!nextStepStatus && ['running'].includes(nextStepStatus)) + } else if (!!nextStepStatus && ['running'].includes(nextStepStatus)) { swap.extraMessageSeverity = MessageSeverity.info; - else if (!!nextStepStatus && ['success', 'approved'].includes(nextStepStatus)) + } else if ( + !!nextStepStatus && + ['success', 'approved'].includes(nextStepStatus) + ) { swap.extraMessageSeverity = MessageSeverity.success; - else if (nextStepStatus && ['waitingForApproval'].includes(nextStepStatus)) + } else if ( + nextStepStatus && + ['waitingForApproval'].includes(nextStepStatus) + ) { swap.extraMessageSeverity = MessageSeverity.warning; + } - if (nextStepStatus === 'running' && currentStep) + if (nextStepStatus === 'running' && currentStep) { currentStep.startTransactionTime = new Date().getTime(); + } setStorage({ ...getStorage(), swapDetails: swap, }); - return { - swap, - step: currentStep, - }; + return updatedResult; } +/** + * + * Set current step transaction hash, update pending swap status, and notify user if needed + * + */ export function setStepTransactionIds( { getStorage, setStorage }: ExecuterActions, txId: string | null, - notifier: SwapQueueContext['notifier'], - eventType?: EventType, - approveUrl?: string + explorerUrl?: { url?: string; description?: string } ): void { const swap = getStorage().swapDetails; swap.hasAlreadyProceededToSign = null; @@ -231,42 +414,46 @@ export function setStepTransactionIds( const currentStep = getCurrentStep(swap)!; currentStep.executedTransactionId = txId; currentStep.executedTransactionTime = new Date().getTime().toString(); - if (!!approveUrl) + if (explorerUrl?.url) { currentStep.explorerUrl = [ ...(currentStep.explorerUrl || []), { - url: approveUrl, - description: `approve`, + url: explorerUrl.url, + description: explorerUrl.description || null, }, ]; - if (eventType === 'check_tx_status') { - swap.extraMessage = 'Checking transaction status ...'; - swap.extraMessageDetail = ''; - swap.extraMessageSeverity = MessageSeverity.info; - } else if (eventType === 'check_approve_tx_status') { + } + + const isApproval = isApprovalCurrentStepTx(currentStep); + + if (isApproval) { swap.extraMessage = 'Checking approve transaction status ...'; - swap.extraMessageDetail = ''; - swap.extraMessageSeverity = MessageSeverity.info; + } else { + swap.extraMessage = 'Checking transaction status ...'; } + swap.extraMessageDetail = ''; + swap.extraMessageSeverity = MessageSeverity.info; + setStorage({ ...getStorage(), swapDetails: swap, }); - if (!!eventType) - notifier({ eventType: eventType, swap: swap, step: currentStep }); -} -export function getSwapNotitfication( - eventType: EventType, - updateResult: { swap: PendingSwap; step: PendingSwapStep | null } -): SwapProgressNotification { - if (updateResult.swap.hasAlreadyProceededToSign) { - return { - eventType: 'transaction_expired', - ...updateResult, - }; - } else return { eventType, ...updateResult }; + notifier({ + event: { + type: StepEventType.TX_EXECUTION, + status: StepExecutionEventStatus.TX_SENT, + }, + swap: swap, + step: currentStep, + }); + + notifier({ + event: { type: StepEventType.CHECK_STATUS }, + swap: swap, + step: currentStep, + }); } /** @@ -283,7 +470,9 @@ export function markRunningSwapAsWaitingForConnectingWallet( ): void { const swap = getStorage().swapDetails as SwapStorage['swapDetails']; const currentStep = getCurrentStep(swap); - if (!currentStep) return; + if (!currentStep) { + return; + } const currentTime = new Date(); swap.lastNotificationTime = currentTime.getTime().toString(); @@ -324,16 +513,15 @@ export function markRunningSwapAsSwitchingNetwork({ const swap = getStorage().swapDetails as SwapStorage['swapDetails']; const currentStep = getCurrentStep(swap); - if (!currentStep) return; + if (!currentStep) { + return; + } // Generate message const { type } = getRequiredWallet(swap); - const fromBlockchain = getCurrentBlockchainOf(swap, currentStep); - const reason = `Change ${type} wallet network to ${fromBlockchain}`; - let metamaskMessage = ''; - if (type === WalletType.META_MASK) - metamaskMessage = `(Networks -> Select '${fromBlockchain}' network.)`; - const reasonDetail = `Please change your ${type} wallet network to ${fromBlockchain}. ${metamaskMessage}`; + const fromNamespace = getCurrentNamespaceOf(swap, currentStep); + const reason = `Change ${type} wallet network to ${fromNamespace.network}`; + const reasonDetail = `Please change your ${type} wallet network to ${fromNamespace.namespace}.`; const currentTime = new Date(); swap.lastNotificationTime = currentTime.getTime().toString(); @@ -360,10 +548,7 @@ export function markRunningSwapAsSwitchingNetwork({ export function markRunningSwapAsDependsOnOtherQueues({ getStorage, setStorage, - notifier, -}: Pick & { - notifier: SwapQueueContext['notifier']; -}): +}: Pick): | { swap: PendingSwap; step: PendingSwapStep; @@ -371,14 +556,19 @@ export function markRunningSwapAsDependsOnOtherQueues({ | undefined { const swap = getStorage().swapDetails as SwapStorage['swapDetails']; const currentStep = getCurrentStep(swap); - if (!currentStep) return; + if (!currentStep) { + return; + } swap.networkStatusExtraMessage = ''; swap.networkStatusExtraMessageDetail = ''; currentStep.networkStatus = PendingSwapNetworkStatus.WaitingForQueue; notifier({ - eventType: 'waiting_for_queue', + event: { + type: StepEventType.TX_EXECUTION_BLOCKED, + status: StepExecutionBlockedEventStatus.WAITING_FOR_QUEUE, + }, swap, step: currentStep, }); @@ -394,26 +584,10 @@ export function markRunningSwapAsDependsOnOtherQueues({ }; } -export function delay(ms: number): Promise { +export async function delay(ms: number): Promise { return new Promise((res) => setTimeout(res, ms)); } -export const isEvmTransaction = (tx: Transaction): tx is EvmTransaction => - tx.type === TransactionType.EVM; - -export const isCosmosTransaction = (tx: Transaction): tx is CosmosTransaction => - tx.type === TransactionType.COSMOS; -export const isSolanaTransaction = (tx: Transaction): tx is SolanaTransaction => - tx.type === TransactionType.SOLANA; -export const isTrasnferTransaction = ( - tx: Transaction -): tx is TransferTransaction => tx.type === TransactionType.TRANSFER; -export const isStarknetTransaction = ( - tx: Transaction -): tx is StarknetTransaction => tx.type === TransactionType.STARKNET; -export const isTronTransaction = (tx: Transaction): tx is TronTransaction => - tx.type === TransactionType.TRON; - /** * * To execute a swap, we are keeping the user prefrences on what wallet they are going to use for a sepecific blockchain @@ -441,49 +615,32 @@ export function isWalletNull(wallet: Wallet | null): boolean { ); } -/** - * On our implementation for `wallets` package, We keep the instance in 2 ways - * If it's a single chain wallet, it returns the instance directly, - * If it's a multichain wallet, it returns a `Map` of instances. - * This function will get the `ETHEREUM` instance in both types. - */ -// eslint-disable-next-line @typescript-eslint/no-explicit-any -export function getEvmProvider(providers: Providers, type: WalletType): any { - if (type && providers[type]) { - // we need this because provider can return an instance or a map of instances, so what you are doing here is try to detect that. - if (providers[type].size) return providers[type].get(Network.ETHEREUM); - - return providers[type]; - } - return null; -} - /** * In a `PendingSwap`, each step needs a wallet to proceed, * By using this function we can access what wallet exactly we need to run current step. */ export function getRequiredWallet(swap: PendingSwap): { type: WalletType | null; - network: Network | null; + namespace: TargetNamespace | null; address: string | null; } { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const step = getCurrentStep(swap)!; - const bcName = getCurrentBlockchainOfOrNull(swap, step); - if (!bcName) { + const currentNamespace = getCurrentNamespaceOfOrNull(swap, step); + if (!currentNamespace) { return { type: null, - network: null, + namespace: null, address: null, }; } - const walletType = getSwapWalletType(swap, bcName); - const sourceWallet = swap.wallets[bcName]; + const walletType = getSwapWalletType(swap, currentNamespace.network); + const sourceWallet = swap.wallets[currentNamespace.network]; return { type: walletType || null, - network: bcName, + namespace: currentNamespace, address: sourceWallet ? sourceWallet.address : null, }; } @@ -494,9 +651,13 @@ export function getRequiredWallet(swap: PendingSwap): { */ // eslint-disable-next-line @typescript-eslint/no-explicit-any async function getChainId(provider: any): Promise { - const chainId: number | string | null = - (await provider.request({ method: 'eth_chainId' })) || provider?.chainId; - return chainId; + try { + const chainId: number | string | null = + (await provider.request({ method: 'eth_chainId' })) || provider?.chainId; + return chainId; + } catch { + return provider?.chainId; + } } /** @@ -513,60 +674,40 @@ export async function isNetworkMatchedForTransaction( if (isWalletNull(wallet)) { return false; } - const fromBlockChain = getCurrentBlockchainOfOrNull(swap, step); - if (!fromBlockChain) return false; + const fromNamespace = getCurrentNamespaceOfOrNull(swap, step); + if (!fromNamespace) { + return false; + } if ( - !!meta.evmBasedChains.find( - (evmBlochain) => evmBlochain.name === fromBlockChain + meta.evmBasedChains.find( + (evmBlochain) => evmBlochain.name === fromNamespace.network ) ) { try { - const sourceWallet = swap.wallets[fromBlockChain]; + const sourceWallet = swap.wallets[fromNamespace.network]; if (sourceWallet) { - if ( - [ - WalletType.META_MASK, - WalletType.BINANCE_CHAIN, - WalletType.XDEFI, - WalletType.WALLET_CONNECT, - WalletType.TRUST_WALLET, - WalletType.COIN98, - WalletType.EXODUS, - WalletType.OKX, - WalletType.COINBASE, - WalletType.TOKEN_POCKET, - WalletType.MATH, - WalletType.SAFEPAL, - WalletType.COSMOSTATION, - WalletType.CLOVER, - WalletType.BRAVE, - WalletType.FRONTIER, - WalletType.KUCOIN, - ].includes(sourceWallet.walletType) - ) { - const provider = getEvmProvider(providers, sourceWallet.walletType); - const chainId: number | string | null = await getChainId(provider); - if (chainId) { - const blockChain = getBlockChainNameFromId( - chainId, - Object.entries(meta.blockchains).map( - ([, blockchainMeta]) => blockchainMeta - ) - ); - if ( - blockChain && - blockChain.toLowerCase() === fromBlockChain.toLowerCase() + const provider = getEvmProvider(providers, sourceWallet.walletType); + const chainId: number | string | null = await getChainId(provider); + if (chainId) { + const blockChain = getBlockChainNameFromId( + chainId, + Object.entries(meta.blockchains).map( + ([, blockchainMeta]) => blockchainMeta ) - return true; - if ( - blockChain && - blockChain.toLowerCase() !== fromBlockChain.toLowerCase() - ) - return false; + ); + if ( + blockChain && + blockChain.toLowerCase() === fromNamespace.network.toLowerCase() + ) { + return true; + } + if ( + blockChain && + blockChain.toLowerCase() !== fromNamespace.network.toLowerCase() + ) { + return false; } - } else { - return true; } } } catch (e) { @@ -590,6 +731,7 @@ export const isTxAlreadyCreated = ( swap.wallets[step.starknetApprovalTransaction?.blockChain || ''] || swap.wallets[step.cosmosTransaction?.blockChain || ''] || swap.wallets[step.solanaTransaction?.blockChain || ''] || + swap.wallets[step.tonTransaction?.blockChain || ''] || step.transferTransaction?.fromWalletAddress || null; @@ -653,11 +795,23 @@ export function onBlockForConnectWallet( if (!ok) { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const currentStep = getCurrentStep(swap)!; - context.notifier({ - eventType: - reason === 'account_miss_match' - ? 'waiting_for_change_wallet_account' - : 'waiting_for_connecting_wallet', + const { type: walletType, address } = getRequiredWallet(swap); + notifier({ + event: { + type: StepEventType.TX_EXECUTION_BLOCKED, + ...(reason === 'account_miss_match' + ? { + status: + StepExecutionBlockedEventStatus.WAITING_FOR_CHANGE_WALLET_ACCOUNT, + requiredAccount: address ?? undefined, + } + : { + status: + StepExecutionBlockedEventStatus.WAITING_FOR_WALLET_CONNECT, + requiredWallet: walletType ?? undefined, + requiredAccount: address ?? undefined, + }), + }, swap: swap, step: currentStep, }); @@ -693,29 +847,54 @@ export function onBlockForChangeNetwork( const swap = queue.getStorage().swapDetails as SwapStorage['swapDetails']; const currentStep = getCurrentStep(swap); - if (!currentStep || swap.status !== 'running') return; + if (!currentStep || swap.status !== 'running') { + return; + } const result = markRunningSwapAsSwitchingNetwork({ getStorage: queue.getStorage.bind(queue), setStorage: queue.setStorage.bind(queue), }); + const requiredNetwork = getCurrentNamespaceOfOrNull( + swap, + currentStep + )?.network; + + const requiredWallet = getRequiredWallet(swap).type; + + const currentNetwork = requiredWallet + ? context.state(requiredWallet).network + : undefined; + if (result) { - context.notifier({ - eventType: 'waiting_for_network_change', + notifier({ + event: { + type: StepEventType.TX_EXECUTION_BLOCKED, + status: StepExecutionBlockedEventStatus.WAITING_FOR_NETWORK_CHANGE, + requiredNetwork: requiredNetwork ?? undefined, + currentNetwork: currentNetwork ?? undefined, + }, swap: result.swap, step: result.step, }); } // Try to auto switch - const { type, network } = getRequiredWallet(swap); - if (!!type && !!network) { - const result = context.switchNetwork(type, network); - if (result) { - result.then(() => { - queue.unblock(); - }); + const { type, namespace } = getRequiredWallet(swap); + if (!!type && !!namespace?.network) { + if (context.canSwitchNetworkTo(type, namespace.network)) { + const result = context.switchNetwork(type, namespace); + if (result) { + result + .then(() => { + queue.unblock(); + }) + .catch((error) => { + // ignore switch network errors + console.log({ error }); + }); + } } } } @@ -746,7 +925,9 @@ export function onDependsOnOtherQueues( const claimerId = claimedBy(); const isClaimedByAnyQueue = !!claimerId; - if (claimerId === queue.id) return; + if (claimerId === queue.id) { + return; + } // Check if any queue `claimed` before, if yes, we don't should do anything. if (isClaimedByAnyQueue) { @@ -754,7 +935,6 @@ export function onDependsOnOtherQueues( markRunningSwapAsDependsOnOtherQueues({ getStorage: queue.getStorage.bind(queue), setStorage: queue.setStorage.bind(queue), - notifier: context.notifier, }); return; } @@ -773,7 +953,7 @@ export function onDependsOnOtherQueues( setClaimer(task.queue_id); const claimedStorage = task.storage.get() as SwapStorage; - const { type, network, address } = getRequiredWallet( + const { type, namespace, address } = getRequiredWallet( claimedStorage.swapDetails ); @@ -783,7 +963,11 @@ export function onDependsOnOtherQueues( resetClaimedBy: () => { reset(); // TODO: Use key generator - retryOn(`${type}-${network}:${address}`, context.notifier, manager); + retryOn( + `${type}-${namespace?.network}:${address}`, + manager, + context.canSwitchNetworkTo + ); }, }); } @@ -799,37 +983,31 @@ export function isRequiredWalletConnected( const walletState = getState(type); const { accounts, connected } = walletState; const connectedAccounts = accounts || []; - if (!connected) return { ok: false, reason: 'not_connected' }; + if (!connected) { + return { ok: false, reason: 'not_connected' }; + } const matched = connectedAccounts.some((account) => { const { address: accountAddress } = readAccountAddress(account); - return address === accountAddress; + return address.toLocaleLowerCase() === accountAddress.toLocaleLowerCase(); }); return { ok: matched, reason: 'account_miss_match' }; } -export function singTransaction( +export async function signTransaction( actions: ExecuterActions -): void { +): Promise { + const { setTransactionDataByHash } = inMemoryTransactionsData(); const { getStorage, setStorage, failed, next, schedule, context } = actions; - const { meta, getSigners, notifier } = context; + const { meta, getSigners, isMobileWallet } = context; const swap = getStorage().swapDetails; // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const currentStep = getCurrentStep(swap)!; - const { - evmTransaction, - evmApprovalTransaction, - cosmosTransaction, - solanaTransaction, - transferTransaction, - tronTransaction, - tronApprovalTransaction, - starknetTransaction, - starknetApprovalTransaction, - } = currentStep; + const sourceWallet = getRelatedWallet(swap, currentStep); + const mobileWallet = isMobileWallet(sourceWallet?.walletType); const walletAddress = getCurrentAddressOf(swap, currentStep); - const walletSigners = getSigners(sourceWallet.walletType); + const currentStepNamespace = getCurrentNamespaceOf(swap, currentStep); const onFinish = () => { // TODO resetClaimedBy is undefined here @@ -838,677 +1016,185 @@ export function singTransaction( } }; - if (!!evmApprovalTransaction) { - const spenderContract = evmApprovalTransaction?.to; + const tx = getCurrentStepTx(currentStep); + const txType = tx?.type; + const isApproval = isApprovalCurrentStepTx(currentStep); - if (!spenderContract) - throw PrettyError.AssertionFailed( - 'contract address is null for checking approval' - ); - - // Update swap status - const message = `Waiting for approval of ${currentStep?.fromSymbol} coin ${ - sourceWallet.walletType === WalletType.WALLET_CONNECT - ? 'on your mobile phone' - : '' - }`; + if (!tx || !txType) { + const extraMessage = 'Unexpected Error: tx is null!'; const updateResult = updateSwapStatus({ getStorage, setStorage, - nextStepStatus: 'waitingForApproval', - message, - details: - 'Waiting for approve transaction to be mined and confirmed successfully', + nextStatus: 'failed', + nextStepStatus: 'failed', + message: extraMessage, + details: undefined, + errorCode: 'CLIENT_UNEXPECTED_BEHAVIOUR', }); notifier({ - eventType: 'confirm_approve_contract', + event: { + type: StepEventType.FAILED, + reason: extraMessage, + reasonCode: 'CLIENT_UNEXPECTED_BEHAVIOUR', + }, ...updateResult, }); + failed(); + return onFinish(); + } - // Execute transaction - walletSigners - .getSigner(TransactionType.EVM) - .signAndSendTx(evmApprovalTransaction, walletAddress, null) - .then( - (hash) => { - const approveUrl = getEvmApproveUrl( - hash, - getCurrentBlockchainOf(swap, currentStep), - meta.evmBasedChains - ); - setStepTransactionIds( - actions, - hash, - notifier, - 'check_approve_tx_status', - approveUrl - ); - schedule(SwapActionTypes.CHECK_TRANSACTION_STATUS); - next(); - onFinish(); - }, - - (error) => { - if (swap.status === 'failed') return; + const chainId = meta.blockchains?.[tx.blockChain]?.chainId; - const { extraMessage, extraMessageDetail, extraMessageErrorCode } = - prettifyErrorMessage(error); - if ( - error && - error?.root && - error?.root?.message && - error?.root?.code && - error?.root?.reason - ) { - logRPCError( - error.root, - swap, - currentStep, - sourceWallet?.walletType - ); - } + const hasAlreadyProceededToSign = + typeof swap.hasAlreadyProceededToSign === 'boolean'; - const updateResult = updateSwapStatus({ - getStorage, - setStorage, - nextStatus: 'failed', - nextStepStatus: 'failed', - message: extraMessage, - details: extraMessageDetail, - errorCode: extraMessageErrorCode, - }); - notifier({ - eventType: 'contract_rejected', - ...updateResult, - }); + let nextStatus: SwapStatus | undefined, + nextStepStatus: StepStatus, + message: string, + details: string, + eventType: StepEventType; - failed(); - onFinish(); - } - ); - return; - } else if (!!tronApprovalTransaction) { - // Update swap status - const message = `Waiting for approval of ${currentStep?.fromSymbol} coin ${ - sourceWallet.walletType === WalletType.WALLET_CONNECT - ? 'on your mobile phone' - : '' + if (isApproval) { + message = `Waiting for approval of ${currentStep?.fromSymbol} coin ${ + mobileWallet ? 'on your mobile phone!' : '' }`; - const updateResult = updateSwapStatus({ - getStorage, - setStorage, - nextStepStatus: 'waitingForApproval', - message, - details: - 'Waiting for approve transaction to be mined and confirmed successfully', - }); - notifier({ - eventType: 'confirm_approve_contract', - ...updateResult, - }); - - // Execute transaction - walletSigners - .getSigner(TransactionType.TRON) - .signAndSendTx(tronApprovalTransaction, walletAddress, null) - .then( - (hash) => { - const approveUrl = getTronApproveUrl(hash); - setStepTransactionIds( - actions, - hash, - notifier, - 'check_approve_tx_status', - approveUrl - ); - schedule(SwapActionTypes.CHECK_TRANSACTION_STATUS); - next(); - onFinish(); - }, - - (error) => { - if (swap.status === 'failed') return; - - const { extraMessage, extraMessageDetail, extraMessageErrorCode } = - prettifyErrorMessage(error); - if ( - error && - error?.root && - error?.root?.message && - error?.root?.code && - error?.root?.reason - ) { - logRPCError( - error.root, - swap, - currentStep, - sourceWallet?.walletType - ); - } + details = + 'Waiting for approve transaction to be mined and confirmed successfully'; + nextStepStatus = 'waitingForApproval'; + nextStatus = undefined; + eventType = StepEventType.TX_EXECUTION; + } else if (hasAlreadyProceededToSign) { + message = 'Transaction is expired. Please try again.'; + nextStepStatus = 'failed'; + nextStatus = 'failed'; + details = ''; + eventType = StepEventType.FAILED; + } else { + message = 'Executing transaction ...'; + nextStepStatus = 'running'; + nextStatus = 'running'; + details = `${mobileWallet ? 'Check your mobile phone!' : ''}`; + eventType = StepEventType.TX_EXECUTION; + } - const updateResult = updateSwapStatus({ - getStorage, - setStorage, - nextStatus: 'failed', - nextStepStatus: 'failed', - message: extraMessage, - details: extraMessageDetail, - errorCode: extraMessageErrorCode, - }); - notifier({ - eventType: 'contract_rejected', - ...updateResult, - }); + const updateResult = updateSwapStatus({ + getStorage, + setStorage, + nextStepStatus, + nextStatus, + message: message, + details: details, + hasAlreadyProceededToSign: isApproval + ? undefined + : hasAlreadyProceededToSign, + errorCode: hasAlreadyProceededToSign ? 'TX_EXPIRED' : undefined, + }); - failed(); - onFinish(); - } - ); - return; - } else if (!!starknetApprovalTransaction) { - // Update swap status - const message = `Waiting for approval of ${currentStep?.fromSymbol} coin ${ - sourceWallet.walletType === WalletType.WALLET_CONNECT - ? 'on your mobile phone' - : '' - }`; - const updateResult = updateSwapStatus({ - getStorage, - setStorage, - nextStepStatus: 'waitingForApproval', - message, - details: - 'Waiting for approve transaction to be mined and confirmed successfully', + if (eventType === StepEventType.FAILED) { + notifier({ + event: { + type: eventType, + reason: message, + reasonCode: updateResult.failureType ?? DEFAULT_ERROR_CODE, + }, + ...updateResult, }); + } else { notifier({ - eventType: 'confirm_approve_contract', + event: { type: eventType, status: StepExecutionEventStatus.SEND_TX }, ...updateResult, }); + } - // Execute transaction - walletSigners - .getSigner(TransactionType.STARKNET) - .signAndSendTx(starknetApprovalTransaction, walletAddress, null) - .then( - (hash) => { - const approveUrl = getStarknetApproveUrl(hash); - setStepTransactionIds( - actions, - hash, - notifier, - 'check_approve_tx_status', - approveUrl - ); - schedule(SwapActionTypes.CHECK_TRANSACTION_STATUS); - next(); - onFinish(); - }, - - (error) => { - if (swap.status === 'failed') return; - - const { extraMessage, extraMessageDetail, extraMessageErrorCode } = - prettifyErrorMessage(error); - if ( - error && - error?.root && - error?.root?.message && - error?.root?.code && - error?.root?.reason - ) { - logRPCError( - error.root, - swap, - currentStep, - sourceWallet?.walletType - ); - } - - const updateResult = updateSwapStatus({ - getStorage, - setStorage, - nextStatus: 'failed', - nextStepStatus: 'failed', - message: extraMessage, - details: extraMessageDetail, - errorCode: extraMessageErrorCode, - }); - notifier({ - eventType: 'contract_rejected', - ...updateResult, - }); - - failed(); - onFinish(); - } - ); + if (hasAlreadyProceededToSign) { + failed(); + onFinish(); return; } - const hasAlreadyProceededToSign = - typeof swap.hasAlreadyProceededToSign === 'boolean'; - const nextStepStatusBasedOnHasAlreadyProceededToSign = - hasAlreadyProceededToSign ? 'failed' : 'running'; - const errorCodeBasedOnHasAlreadyProceededToSign = hasAlreadyProceededToSign - ? 'TX_EXPIRED' - : null; - const executeMessage = hasAlreadyProceededToSign - ? 'Transaction is expired. Please try again' - : 'executing transaction'; - const executeDetails = `${ - sourceWallet.walletType === WalletType.WALLET_CONNECT - ? 'Check your mobile phone' - : '' - }`; - - if (!!transferTransaction) { - const updateResult = updateSwapStatus({ - getStorage, - setStorage, - nextStepStatus: nextStepStatusBasedOnHasAlreadyProceededToSign, - nextStatus: nextStepStatusBasedOnHasAlreadyProceededToSign, - message: executeMessage, - details: executeDetails, - hasAlreadyProceededToSign, - errorCode: errorCodeBasedOnHasAlreadyProceededToSign, - }); - - const notification = getSwapNotitfication('confirm_transfer', updateResult); - notifier(notification); + const walletSigners = await getSigners(sourceWallet.walletType); - if (notification.eventType === 'transaction_expired') { - failed(); - onFinish(); - } else { - walletSigners - .getSigner(TransactionType.TRANSFER) - .signAndSendTx(transferTransaction, walletAddress, null) - .then( - (txId) => { - setStepTransactionIds(actions, txId, notifier, 'check_tx_status'); - schedule(SwapActionTypes.CHECK_TRANSACTION_STATUS); - next(); - onFinish(); - }, - (error) => { - if (swap.status === 'failed') return; - const { extraMessage, extraMessageDetail, extraMessageErrorCode } = - prettifyErrorMessage(error); - const updateResult = updateSwapStatus({ - getStorage, - setStorage, - nextStatus: 'failed', - nextStepStatus: 'failed', - message: extraMessage, - details: extraMessageDetail, - errorCode: extraMessageErrorCode, - }); - notifier({ - eventType: 'transfer_rejected', - ...updateResult, - }); - failed(); - onFinish(); - } - ); - } - } else if (!!evmTransaction) { - const updateResult = updateSwapStatus({ - getStorage, - setStorage, - nextStepStatus: nextStepStatusBasedOnHasAlreadyProceededToSign, - nextStatus: nextStepStatusBasedOnHasAlreadyProceededToSign, - message: executeMessage, - details: executeDetails, - hasAlreadyProceededToSign, - errorCode: errorCodeBasedOnHasAlreadyProceededToSign, - }); - const notification = getSwapNotitfication( - 'calling_smart_contract', - updateResult - ); - notifier(notification); - - if (notification.eventType === 'transaction_expired') { - failed(); - onFinish(); - } else { - walletSigners - .getSigner(TransactionType.EVM) - .signAndSendTx(evmTransaction, walletAddress, null) - .then( - (id) => { - setStepTransactionIds(actions, id, notifier, 'check_tx_status'); - schedule(SwapActionTypes.CHECK_TRANSACTION_STATUS); - next(); - onFinish(); - }, - (error) => { - if (swap.status === 'failed') return; - const { extraMessage, extraMessageDetail, extraMessageErrorCode } = - prettifyErrorMessage(error); - if ( - error && - error?.root && - error?.root?.message && - error?.root?.code && - error?.root?.reason - ) { - logRPCError( - error.root, - swap, - currentStep, - sourceWallet?.walletType - ); + const signer = walletSigners.getSigner(txType); + signer.signAndSendTx(tx, walletAddress, chainId).then( + ({ hash, response }) => { + const explorerUrl = getScannerUrl( + hash, + currentStepNamespace.network, + meta.blockchains + ); + setStepTransactionIds( + actions, + hash, + explorerUrl && + (!response || (response && !response.hashRequiringUpdate)) + ? { + url: explorerUrl, + description: isApproval ? 'Approve' : 'Swap', } - const updateResult = updateSwapStatus({ - getStorage, - setStorage, - nextStatus: 'failed', - nextStepStatus: 'failed', - message: extraMessage, - details: extraMessageDetail, - errorCode: extraMessageErrorCode, - }); - notifier({ - eventType: 'smart_contract_call_failed', - ...updateResult, - }); - - failed(); - onFinish(); - } - ); - } - } else if (!!cosmosTransaction) { - const updateResult = updateSwapStatus({ - getStorage, - setStorage, - nextStepStatus: nextStepStatusBasedOnHasAlreadyProceededToSign, - nextStatus: nextStepStatusBasedOnHasAlreadyProceededToSign, - message: executeMessage, - details: executeDetails, - hasAlreadyProceededToSign, - errorCode: errorCodeBasedOnHasAlreadyProceededToSign, - }); - const notification = getSwapNotitfication( - 'calling_smart_contract', - updateResult - ); - notifier(notification); - - if (notification.eventType === 'transaction_expired') { - failed(); + : undefined + ); + // response used for evm transactions to get receipt and track replaced + response && setTransactionDataByHash(hash, { response }); + schedule(SwapActionTypes.CHECK_TRANSACTION_STATUS); + next(); onFinish(); - } else { - // If keplr wallet is executing contracts on terra, throw error. keplr doesn't support transfer or execute contracts. only IBC messages are supported - if ( - (currentStep?.swapperId.toString() === 'TerraSwap' || - (currentStep?.swapperId.toString() === 'ThorChain' && - currentStep?.fromBlockchain === Network.TERRA) || - (currentStep?.swapperId.toString() === 'Terra Bridge' && - currentStep.fromBlockchain === Network.TERRA)) && // here we must allow ibc on terrastatus - sourceWallet.walletType === WalletType.KEPLR - ) { - const { extraMessage, extraMessageDetail, extraMessageErrorCode } = - prettifyErrorMessage( - 'Keplr only supports IBC Transactions on Terra. ' + - 'Using Terra Bridge, TerraSwap and THORChain is not possible with Keplr. Please use TerraStation or Leap wallet' - ); - const updateResult = updateSwapStatus({ - getStorage, - setStorage, - nextStatus: 'failed', - nextStepStatus: 'failed', - message: extraMessage, - details: extraMessageDetail, - errorCode: extraMessageErrorCode, - }); - notifier({ - eventType: 'smart_contract_call_failed', - ...updateResult, - }); - failed(); - onFinish(); + }, + (error) => { + if (swap.status === 'failed') { return; } - walletSigners - .getSigner(TransactionType.COSMOS) - .signAndSendTx(cosmosTransaction, walletAddress, null) - .then( - // todo - (id: string | null) => { - setStepTransactionIds(actions, id, notifier, 'check_tx_status'); - schedule(SwapActionTypes.CHECK_TRANSACTION_STATUS); - next(); - onFinish(); - }, - (error: string | null) => { - if (swap.status === 'failed') return; - const { extraMessage, extraMessageDetail, extraMessageErrorCode } = - prettifyErrorMessage(error); - const updateResult = updateSwapStatus({ - getStorage, - setStorage, - nextStatus: 'failed', - nextStepStatus: 'failed', - message: extraMessage, - details: extraMessageDetail, - errorCode: extraMessageErrorCode, - }); - notifier({ - eventType: 'smart_contract_call_failed', - ...updateResult, - }); - failed(); - onFinish(); - } - ); - } - } else if (!!solanaTransaction) { - const updateResult = updateSwapStatus({ - getStorage, - setStorage, - nextStepStatus: nextStepStatusBasedOnHasAlreadyProceededToSign, - nextStatus: nextStepStatusBasedOnHasAlreadyProceededToSign, - message: executeMessage, - details: executeDetails, - hasAlreadyProceededToSign, - errorCode: errorCodeBasedOnHasAlreadyProceededToSign, - }); - const notification = getSwapNotitfication( - 'calling_smart_contract', - updateResult - ); - notifier(notification); + const { extraMessage, extraMessageDetail, extraMessageErrorCode } = + prettifyErrorMessage(error); - if (notification.eventType === 'transaction_expired') { - failed(); - onFinish(); - } else { - const tx = solanaTransaction; - walletSigners - .getSigner(TransactionType.SOLANA) - .signAndSendTx(tx, walletAddress, null) - .then( - (txId) => { - setStepTransactionIds(actions, txId, notifier, 'check_tx_status'); - schedule(SwapActionTypes.CHECK_TRANSACTION_STATUS); - next(); - onFinish(); - }, - (error) => { - if (swap.status === 'failed') return; - const { extraMessage, extraMessageDetail, extraMessageErrorCode } = - prettifyErrorMessage(error); - const updateResult = updateSwapStatus({ - getStorage, - setStorage, - nextStatus: 'failed', - nextStepStatus: 'failed', - message: extraMessage, - details: extraMessageDetail, - errorCode: extraMessageErrorCode, - }); - notifier({ - eventType: 'smart_contract_call_failed', - ...updateResult, - }); - failed(); - onFinish(); - } - ); - } - } else if (!!tronTransaction) { - const updateResult = updateSwapStatus({ - getStorage, - setStorage, - nextStepStatus: nextStepStatusBasedOnHasAlreadyProceededToSign, - nextStatus: nextStepStatusBasedOnHasAlreadyProceededToSign, - message: executeMessage, - details: executeDetails, - hasAlreadyProceededToSign, - errorCode: errorCodeBasedOnHasAlreadyProceededToSign, - }); - const notification = getSwapNotitfication( - 'calling_smart_contract', - updateResult - ); - notifier(notification); - - if (notification.eventType === 'transaction_expired') { - failed(); - onFinish(); - } else { - walletSigners - .getSigner(TransactionType.TRON) - .signAndSendTx(tronTransaction, walletAddress, null) - .then( - (id) => { - setStepTransactionIds(actions, id, notifier, 'check_tx_status'); - schedule(SwapActionTypes.CHECK_TRANSACTION_STATUS); - next(); - onFinish(); - }, - (error) => { - if (swap.status === 'failed') return; - const { extraMessage, extraMessageDetail, extraMessageErrorCode } = - prettifyErrorMessage(error); - if ( - error && - error?.root && - error?.root?.message && - error?.root?.code && - error?.root?.reason - ) { - logRPCError( - error.root, - swap, - currentStep, - sourceWallet?.walletType - ); - } - const updateResult = updateSwapStatus({ - getStorage, - setStorage, - nextStatus: 'failed', - nextStepStatus: 'failed', - message: extraMessage, - details: extraMessageDetail, - errorCode: extraMessageErrorCode, - }); - notifier({ - eventType: 'smart_contract_call_failed', - ...updateResult, - }); + warn(error, { + tags: { + requestId: swap.requestId, + rpc: true, + swapper: currentStep?.swapperId || '', + walletType: sourceWallet?.walletType || '', + }, + context: SignerError.isSignerError(error) + ? error.getErrorContext() + : {}, + }); - failed(); - onFinish(); - } - ); - } - } else if (!!starknetTransaction) { - const updateResult = updateSwapStatus({ - getStorage, - setStorage, - nextStepStatus: nextStepStatusBasedOnHasAlreadyProceededToSign, - nextStatus: nextStepStatusBasedOnHasAlreadyProceededToSign, - message: executeMessage, - details: executeDetails, - hasAlreadyProceededToSign, - errorCode: errorCodeBasedOnHasAlreadyProceededToSign, - }); - const notification = getSwapNotitfication( - 'calling_smart_contract', - updateResult - ); - notifier(notification); + const updateResult = updateSwapStatus({ + getStorage, + setStorage, + nextStatus: 'failed', + nextStepStatus: 'failed', + message: extraMessage, + details: extraMessageDetail, + errorCode: extraMessageErrorCode, + trace: error?.cause, + }); - if (notification.eventType === 'transaction_expired') { + notifier({ + event: { + type: StepEventType.FAILED, + reason: extraMessage, + reasonCode: updateResult.failureType ?? DEFAULT_ERROR_CODE, + }, + ...updateResult, + }); failed(); onFinish(); - } else { - walletSigners - .getSigner(TransactionType.STARKNET) - .signAndSendTx(starknetTransaction, walletAddress, null) - .then( - (id) => { - setStepTransactionIds(actions, id, notifier, 'check_tx_status'); - schedule(SwapActionTypes.CHECK_TRANSACTION_STATUS); - next(); - onFinish(); - }, - (error) => { - if (swap.status === 'failed') return; - const { extraMessage, extraMessageDetail, extraMessageErrorCode } = - prettifyErrorMessage(error); - if ( - error && - error?.root && - error?.root?.message && - error?.root?.code && - error?.root?.reason - ) { - logRPCError( - error.root, - swap, - currentStep, - sourceWallet?.walletType - ); - } - const updateResult = updateSwapStatus({ - getStorage, - setStorage, - nextStatus: 'failed', - nextStepStatus: 'failed', - message: extraMessage, - details: extraMessageDetail, - errorCode: extraMessageErrorCode, - }); - notifier({ - eventType: 'smart_contract_call_failed', - ...updateResult, - }); - - failed(); - onFinish(); - } - ); } - } + ); } export function checkWaitingForConnectWalletChange(params: { wallet_network: string; manager?: Manager; evmChains: EvmBlockchainMeta[]; - notifier: SwapQueueContext['notifier']; }): void { const { wallet_network, evmChains, manager } = params; const [wallet, network] = splitWalletNetwork(wallet_network); // We only need change network for EVM chains. - if (!evmChains.some((chain) => chain.name == network)) return; + if (!evmChains.some((chain) => chain.name == network)) { + return; + } manager?.getAll().forEach((q) => { const queueStorage = q.list.getStorage() as SwapStorage | undefined; @@ -1532,10 +1218,15 @@ export function checkWaitingForConnectWalletChange(params: { } ); + const requiredNetwork = getCurrentNamespaceOfOrNull( + swap, + currentStep + )?.network; + if ( currentStepRequiredWallet === wallet && hasWaitingForConnect && - getCurrentBlockchainOfOrNull(swap, currentStep) != network + requiredNetwork != network ) { const queueInstance = q.list; const { type } = getRequiredWallet(swap); @@ -1555,8 +1246,14 @@ export function checkWaitingForConnectWalletChange(params: { }); if (result) { - params?.notifier({ - eventType: 'waiting_for_network_change', + notifier({ + event: { + type: StepEventType.TX_EXECUTION_BLOCKED, + status: + StepExecutionBlockedEventStatus.WAITING_FOR_NETWORK_CHANGE, + currentNetwork: network, + requiredNetwork: requiredNetwork ?? undefined, + }, swap: result.swap, step: result.step, }); @@ -1609,12 +1306,14 @@ export function checkWaitingForNetworkChange(manager?: Manager): void { */ export function getRunningSwaps(manager: Manager): PendingSwap[] { const queues = manager?.getAll() || new Map(); - let result: PendingSwap[] = []; + const result: PendingSwap[] = []; queues.forEach((q) => { // retry only on affected queues const queueStorage = q.list.getStorage() as SwapStorage | undefined; const swap = queueStorage?.swapDetails; - if (!swap || swap.status !== 'running') return; + if (!swap || swap.status !== 'running') { + return; + } result.push(swap); }); return result; @@ -1629,21 +1328,28 @@ export function getRunningSwaps(manager: Manager): PendingSwap[] { * @param notifier * @returns */ -export function resetRunningSwapNotifsOnPageLoad( - runningSwaps: PendingSwap[], - notifier: SwapQueueContext['notifier'] -) { +export function resetRunningSwapNotifsOnPageLoad(runningSwaps: PendingSwap[]) { runningSwaps.forEach((swap) => { const currentStep = getCurrentStep(swap); - let eventType: EventType | undefined; - if (currentStep?.networkStatus === PendingSwapNetworkStatus.WaitingForQueue) - eventType = 'waiting_for_queue'; - else if (swap?.status === 'running') { - eventType = 'waiting_for_connecting_wallet'; + const eventType = StepEventType.TX_EXECUTION_BLOCKED; + let eventSubtype: + | StepExecutionBlockedEventStatus.WAITING_FOR_QUEUE + | StepExecutionBlockedEventStatus.WAITING_FOR_WALLET_CONNECT + | undefined; + if ( + currentStep?.networkStatus === PendingSwapNetworkStatus.WaitingForQueue + ) { + eventSubtype = StepExecutionBlockedEventStatus.WAITING_FOR_QUEUE; + } else if (swap?.status === 'running') { + eventSubtype = StepExecutionBlockedEventStatus.WAITING_FOR_WALLET_CONNECT; } if (!!eventType && !!notifier) { notifier({ - eventType, + event: { + type: eventType, + status: + eventSubtype ?? StepExecutionBlockedEventStatus.WAITING_FOR_QUEUE, + }, swap: swap, step: currentStep, }); @@ -1664,8 +1370,8 @@ export function resetRunningSwapNotifsOnPageLoad( */ export function retryOn( wallet_network: string, - notifier: SwapQueueContext['notifier'], manager?: Manager, + canSwitchNetworkTo?: (type: WalletType, network: Network) => boolean, options = { fallbackToOnlyWallet: true } ): void { const [wallet, network] = splitWalletNetwork(wallet_network); @@ -1686,7 +1392,8 @@ export function retryOn( const currentStep = getCurrentStep(swap); if (currentStep) { if ( - getCurrentBlockchainOfOrNull(swap, currentStep) == network && + getCurrentNamespaceOfOrNull(swap, currentStep)?.network == + network && queueStorage?.swapDetails.wallets[network]?.walletType === wallet ) { walletAndNetworkMatched.push(q.list); @@ -1712,7 +1419,6 @@ export function retryOn( markRunningSwapAsDependsOnOtherQueues({ getStorage: currentQueue.getStorage.bind(currentQueue), setStorage: currentQueue.setStorage.bind(currentQueue), - notifier: notifier, }); } } @@ -1720,47 +1426,48 @@ export function retryOn( finalQueueToBeRun = onlyWalletMatched[0]; } - finalQueueToBeRun?.checkBlock(); + if (!canSwitchNetworkTo?.(wallet, network)) { + finalQueueToBeRun?.unblock(); + } else { + finalQueueToBeRun?.checkBlock(); + } } -/* - For avoiding conflict by making too many requests to wallet, we need to make sure - We only run one request at a time (In parallel mode). - */ +/* + *For avoiding conflict by making too many requests to wallet, we need to make sure + *We only run one request at a time (In parallel mode). + */ export function isNeedBlockQueueForParallel(step: PendingSwapStep): boolean { - return ( - !!step.evmTransaction || - !!step.evmApprovalTransaction || - !!step.cosmosTransaction - ); + return !!step.evmTransaction || !!step.evmApprovalTransaction; } /* -Create transaction endpoint doesn't return error code on http status code, -For backward compatibilty with server and sdk, we use this wrapper to reject the promise. -*/ + *Create transaction endpoint doesn't return error code on http status code, + *For backward compatibilty with server and sdk, we use this wrapper to reject the promise. + */ export async function throwOnOK( rawResponse: Promise ): Promise { - try { - const responseBody = await rawResponse; - if (!responseBody.ok || !responseBody.transaction) { - throw PrettyError.CreateTransaction( - responseBody.error || 'bad response from create tx endpoint' - ); - } - return responseBody; - } catch (e) { - throw e; + const responseBody = await rawResponse; + if (!responseBody.ok || !responseBody.transaction) { + throw PrettyError.CreateTransaction( + responseBody.error || 'bad response from create tx endpoint' + ); } + return responseBody; } -export function cancelSwap(swap: QueueInfo): { +export function cancelSwap( + swap: QueueInfo, + manager?: Manager +): { swap: PendingSwap; step: PendingSwapStep | null; } { + const { reset } = claimQueue(); swap.actions.cancel(); - return updateSwapStatus({ + + const updateResult = updateSwapStatus({ getStorage: swap.actions.getStorage, setStorage: swap.actions.setStorage, message: 'Swap canceled by user.', @@ -1770,4 +1477,51 @@ export function cancelSwap(swap: QueueInfo): { nextStepStatus: 'failed', errorCode: 'USER_CANCEL', }); + + notifier({ + event: { + type: StepEventType.FAILED, + reasonCode: 'USER_CANCEL', + reason: updateResult.swap.extraMessage ?? undefined, + }, + + swap: updateResult.swap, + step: updateResult.step, + }); + + reset(); + if (manager) { + manager?.retry(); + } + + return updateResult; +} + +export function getLastSuccessfulStep( + steps: T +): ArrayElement | undefined { + return steps + .slice() + .reverse() + .find((step) => step.status === 'success') as ArrayElement | undefined; +} + +export function getFailedStep( + steps: T +): ArrayElement | undefined { + return steps + .slice() + .reverse() + .find((step) => step.status === 'failed') as ArrayElement | undefined; +} + +export function isApprovalTX(step: Step): boolean { + const { transaction } = step; + const approvalTx = + (transaction?.type === TransactionType.EVM && transaction.isApprovalTx) || + (transaction?.type === TransactionType.STARKNET && + transaction.isApprovalTx) || + (transaction?.type === TransactionType.TRON && transaction.isApprovalTx); + + return approvalTx; } diff --git a/queue-manager/rango-preset/src/hooks.ts b/queue-manager/rango-preset/src/hooks.ts index a140b85b41..9935f5daae 100644 --- a/queue-manager/rango-preset/src/hooks.ts +++ b/queue-manager/rango-preset/src/hooks.ts @@ -1,12 +1,13 @@ import { useManager } from '@rango-dev/queue-manager-react'; import { useEffect, useState } from 'react'; + import { checkWaitingForConnectWalletChange, checkWaitingForNetworkChange, retryOn, } from './helpers'; import { migrated, migration } from './migration'; -import { UseQueueManagerParams } from './types'; +import { type UseQueueManagerParams } from './types'; let isCalled = 0; @@ -23,9 +24,11 @@ function useMigration(): { const [status, setStatus] = useState(isMigrated); useEffect(() => { - (async () => { + void (async () => { // Preventing react to be called twice on Strict Mode (development) - if (isCalled) return; + if (isCalled) { + return; + } isCalled = 1; migration().finally(() => { @@ -41,7 +44,7 @@ function useMigration(): { /** * - * On initial load and also connect/disconnet we may need to update swap's notified message. + * On initial load and also connect/disconnect we may need to update swap's notified message. * And also if a new wallet is connected we will retry the queue to see we can resume it or not. * */ @@ -54,9 +57,8 @@ function useQueueManager(params: UseQueueManagerParams): void { evmChains: params.evmChains, wallet_network: params.lastConnectedWallet, manager, - notifier: params.notifier, }); - retryOn(params.lastConnectedWallet, params.notifier, manager); + retryOn(params.lastConnectedWallet, manager, params.canSwitchNetworkTo); } }, [params.lastConnectedWallet]); @@ -64,10 +66,10 @@ function useQueueManager(params: UseQueueManagerParams): void { if (params.disconnectedWallet) { checkWaitingForNetworkChange(manager); - /* - We need to reset the state value, so if a wallet disconnected twice (after reconnect), - this effect will be run properly. - */ + /* + *We need to reset the state value, so if a wallet disconnected twice (after reconnect), + *this effect will be run properly. + */ params.clearDisconnectedWallet(); } }, [params.disconnectedWallet]); diff --git a/queue-manager/rango-preset/src/index.ts b/queue-manager/rango-preset/src/index.ts index ae72d5f3f3..202aebb3f3 100644 --- a/queue-manager/rango-preset/src/index.ts +++ b/queue-manager/rango-preset/src/index.ts @@ -1,32 +1,63 @@ -import { Configs, initConfig } from './configs'; -import { SwapQueueDef } from './types'; +import type { Configs } from './configs'; +import type { SwapQueueDef } from './types'; + +import { initConfig } from './configs'; import { swapQueueDef } from './queueDef'; export { PrettyError, prettifyErrorMessage } from './shared-errors'; -export { SwapQueueContext, SwapStorage } from './types'; +export type { + SwapQueueContext, + SwapStorage, + RouteExecutionEvents, + Route, + Step, + RouteEvent, + StepEvent, + RouteEventData, + StepEventData, + RouteStartedEvent, + RouteSucceededEvent, + RouteFailedEvent, + StepStartedEvent, + StepSucceededEvent, + StepFailedEvent, + StepTxExecutionUpdatedEvent, + StepTxExecutionBlockedEvent, + StepCheckStatusEvent, + StepApprovalTxSucceededEvent, + StepOutputRevealedEvent, +} from './types'; export { + WidgetEvents, + StepEventType, + RouteEventType, + StepExecutionEventStatus, + StepExecutionBlockedEventStatus, + EventSeverity, +} from './types'; +export type { PendingSwapWithQueueID, - getCurrentBlockchainOfOrNull, + EventType, + TargetNamespace, +} from './shared'; +export { + getCurrentNamespaceOfOrNull, getRelatedWalletOrNull, getRelatedWallet, MessageSeverity, - PendingSwapStep, - PendingSwapNetworkStatus, - PendingSwap, - EventType, - SwapProgressNotification, calculatePendingSwap, + getUsdPrice, } from './shared'; export { updateSwapStatus, checkWaitingForNetworkChange, getCurrentStep, - getEvmProvider, cancelSwap, getRequiredWallet, getRunningSwaps, - splitWalletNetwork, resetRunningSwapNotifsOnPageLoad, + isApprovalTX, + getLastSuccessfulStep, } from './helpers'; export { useMigration, useQueueManager } from './hooks'; diff --git a/queue-manager/rango-preset/src/migration.ts b/queue-manager/rango-preset/src/migration.ts index 23b8d62f40..0117671aa4 100644 --- a/queue-manager/rango-preset/src/migration.ts +++ b/queue-manager/rango-preset/src/migration.ts @@ -1,11 +1,9 @@ -import { - PersistedQueue, - Persistor, - Status, - DB_NAME, -} from '@rango-dev/queue-manager-core'; +import type { PersistedQueue } from '@rango-dev/queue-manager-core'; +import type { PendingSwap } from 'rango-types'; + +import { DB_NAME, Persistor, Status } from '@rango-dev/queue-manager-core'; import { v4 as uuid } from 'uuid'; -import { PendingSwap } from './shared'; + import { SwapActionTypes } from './types'; const MIGRATED_KEY = 'migratedToQueueManager'; @@ -49,9 +47,9 @@ async function migration(): Promise { const convertedSwaps: PersistedQueue[] = []; swaps.forEach((swap) => { - /* - For running task we need to add some more work - We need to create a queue task to be run and resume the running task from queue manager. + /* + *For running task we need to add some more work + *We need to create a queue task to be run and resume the running task from queue manager. */ if (swap.status === 'running') { const taskId = uuid(); @@ -112,7 +110,9 @@ async function migration(): Promise { // Getting an instance from persistor, so we can directly put our data inside it. const persistor = new Persistor(); - const promises = convertedSwaps.map((queue) => persistor.insertQueue(queue)); + const promises = convertedSwaps.map(async (queue) => + persistor.insertQueue(queue) + ); await Promise.all(promises); // Mark as the data has been successfully migrated. diff --git a/queue-manager/rango-preset/src/services/eventEmitter.ts b/queue-manager/rango-preset/src/services/eventEmitter.ts new file mode 100644 index 0000000000..d2540abeb7 --- /dev/null +++ b/queue-manager/rango-preset/src/services/eventEmitter.ts @@ -0,0 +1,272 @@ +import type { + RemoveNameField, + Route, + RouteEvent, + Step, + StepEvent, +} from '../types'; +import type { PendingSwap, PendingSwapStep } from 'rango-types'; + +import { getConfig } from '../configs'; +import { + getCurrentStepTx, + getFailedStep, + getLastSuccessfulStep, + isApprovalCurrentStepTx, +} from '../helpers'; +import { getCurrentNamespaceOfOrNull } from '../shared'; +import { + EventSeverity, + RouteEventType, + StepEventType, + StepExecutionBlockedEventStatus, + StepExecutionEventStatus, + WidgetEvents, +} from '../types'; + +type NotifierParams = { + swap: PendingSwap; + step: PendingSwapStep | null; +} & { + event: RemoveNameField; +}; + +function createSteps(swapSteps: PendingSwapStep[]): Step[] { + return swapSteps.map((swapStep) => { + const { + diagnosisUrl, + estimatedTimeInSeconds, + explorerUrl, + feeInUsd, + executedTransactionId, + executedTransactionTime, + expectedOutputAmountHumanReadable, + fromBlockchain, + toBlockchain, + fromSymbol, + toSymbol, + fromSymbolAddress, + toSymbolAddress, + swapperType, + swapperId, + outputAmount, + fromAmountMaxValue, + fromAmountMinValue, + fromAmountPrecision, + fromAmountRestrictionType, + fromDecimals, + status: stepStatus, + } = swapStep; + + const step: Step = { + diagnosisUrl, + estimatedTimeInSeconds, + explorerUrl, + feeInUsd, + executedTransactionId, + executedTransactionTime, + expectedOutputAmountHumanReadable, + fromBlockchain, + toBlockchain, + fromSymbol, + toSymbol, + fromSymbolAddress, + toSymbolAddress, + swapperName: swapperId, + swapperType, + outputAmount, + fromAmountMaxValue, + fromAmountMinValue, + fromAmountPrecision, + fromAmountRestrictionType, + fromDecimals, + status: stepStatus, + transaction: getCurrentStepTx(swapStep), + }; + + return step; + }); +} + +function getEventPayload( + swap: PendingSwap, + type: StepEventType | RouteEventType, + swapStep?: PendingSwapStep +): { route: Route; step: Step } { + const { + creationTime, + finishTime, + requestId, + inputAmount, + status, + wallets, + steps, + settings, + } = swap; + + const routeSteps = createSteps(steps); + const route: Route = { + creationTime, + finishTime, + requestId, + inputAmount, + status, + wallets, + steps: routeSteps, + slippage: settings.slippage, + infiniteApproval: settings.infiniteApprove, + }; + + const result: { route: Route; step: Step } = { + route, + step: routeSteps[routeSteps.length - 1], + }; + if (swapStep) { + result.step = createSteps([swapStep])[0]; + } else { + if (type === 'failed') { + const failedStep = getFailedStep(routeSteps); + if (failedStep) { + result.step = failedStep; + } + } else { + const lastSuccessfulStep = getLastSuccessfulStep(routeSteps); + if (lastSuccessfulStep) { + result.step = lastSuccessfulStep; + } + } + } + + return result; +} + +function emitRouteEvent(stepEvent: StepEvent, route: Route) { + let routeEvent: RouteEvent | undefined; + const { type } = stepEvent; + switch (type) { + case StepEventType.STARTED: + routeEvent = { ...stepEvent, type: RouteEventType.STARTED }; + break; + case StepEventType.FAILED: + routeEvent = { ...stepEvent, type: RouteEventType.FAILED }; + break; + case StepEventType.SUCCEEDED: + routeEvent = { ...stepEvent, type: RouteEventType.SUCCEEDED }; + break; + default: + break; + } + if (routeEvent) { + const eventEmitter = getConfig('emitter'); + eventEmitter?.emit(WidgetEvents.RouteEvent, { event: routeEvent, route }); + } +} + +function emitStepEvent(stepEvent: StepEvent, route: Route, step: Step) { + const eventEmitter = getConfig('emitter'); + eventEmitter?.emit(WidgetEvents.StepEvent, { event: stepEvent, route, step }); +} + +export function notifier(params: NotifierParams) { + const { event } = params; + const { type } = event; + const { route, step } = getEventPayload( + params.swap, + type, + params.step ?? undefined + ); + const fromAsset = `${step.fromBlockchain}.${step.fromSymbol}`; + const toAsset = `${step.toBlockchain}.${step.toSymbol}`; + const outputAmount = step.outputAmount ?? ''; + const currentFromNamespace = !!params.step + ? getCurrentNamespaceOfOrNull(params.swap, params.step) + : null; + let message = ''; + let messageSeverity: StepEvent['messageSeverity'] = EventSeverity.INFO; + + switch (type) { + case StepEventType.STARTED: + message = 'Swap process started'; + messageSeverity = EventSeverity.SUCCESS; + break; + case StepEventType.SUCCEEDED: + message = `You received ${outputAmount} ${toAsset}, hooray!`; + messageSeverity = EventSeverity.SUCCESS; + break; + case StepEventType.FAILED: + message = `Swap failed: ${ + params.swap?.extraMessage ?? 'Reason is unknown' + }`; + messageSeverity = EventSeverity.ERROR; + break; + case StepEventType.TX_EXECUTION: + if (event.status === StepExecutionEventStatus.CREATE_TX) { + message = 'Please wait while the transaction is created ...'; + messageSeverity = EventSeverity.INFO; + } else if (event.status === StepExecutionEventStatus.SEND_TX) { + if (params.step && isApprovalCurrentStepTx(params.step)) { + message = `Please confirm '${step.swapperName}' smart contract access to ${fromAsset}`; + } else { + message = 'Please confirm transaction request in your wallet'; + } + messageSeverity = EventSeverity.WARNING; + } else if (event.status === StepExecutionEventStatus.TX_SENT) { + message = 'Transaction sent successfully'; + messageSeverity = EventSeverity.INFO; + } + break; + case StepEventType.CHECK_STATUS: + if (params.step && isApprovalCurrentStepTx(params.step)) { + message = 'Checking approve transaction status ...'; + } else { + message = 'Checking transaction status ...'; + } + messageSeverity = EventSeverity.INFO; + break; + case StepEventType.APPROVAL_TX_SUCCEEDED: + message = 'Smart contract called successfully'; + messageSeverity = EventSeverity.SUCCESS; + break; + case StepEventType.OUTPUT_REVEALED: + message = 'Transaction output amount revealed'; + messageSeverity = EventSeverity.SUCCESS; + break; + + case StepEventType.TX_EXECUTION_BLOCKED: + if ( + event.status === + StepExecutionBlockedEventStatus.WAITING_FOR_WALLET_CONNECT + ) { + message = 'Please connect your wallet.'; + messageSeverity = EventSeverity.WARNING; + } else if ( + event.status === StepExecutionBlockedEventStatus.WAITING_FOR_QUEUE + ) { + message = 'Waiting for other swaps to complete'; + messageSeverity = EventSeverity.WARNING; + } else if ( + event.status === + StepExecutionBlockedEventStatus.WAITING_FOR_CHANGE_WALLET_ACCOUNT + ) { + message = 'Please change your wallet account.'; + messageSeverity = EventSeverity.WARNING; + } else if ( + event.status === + StepExecutionBlockedEventStatus.WAITING_FOR_NETWORK_CHANGE + ) { + message = `Please change your wallet network to ${currentFromNamespace?.network}.`; + messageSeverity = EventSeverity.WARNING; + } + break; + + default: + break; + } + + if (params.step) { + emitStepEvent({ ...event, message, messageSeverity }, route, step); + } + if (params.event.type === StepEventType.FAILED || !params.step) { + emitRouteEvent({ ...event, message, messageSeverity }, route); + } +} diff --git a/queue-manager/rango-preset/src/shared-errors.ts b/queue-manager/rango-preset/src/shared-errors.ts index 1590f3aa96..30b8fcf0cf 100644 --- a/queue-manager/rango-preset/src/shared-errors.ts +++ b/queue-manager/rango-preset/src/shared-errors.ts @@ -1,15 +1,19 @@ -import { +import type { APIErrorCode, - SignerError, + SignerErrorCode as SignerErrorCodeType, +} from 'rango-types'; +import { SignerErrorCode, - isAPIErrorCode, + SignerError, isSignerErrorCode, + isAPIErrorCode, } from 'rango-types'; +import { DEFAULT_ERROR_CODE } from './constants'; export type ErrorDetail = { extraMessage: string; extraMessageDetail?: string | null | undefined; - extraMessageErrorCode: SignerErrorCode | APIErrorCode | null; + extraMessageErrorCode: SignerErrorCodeType | APIErrorCode | null; }; const ERROR_ASSERTION_FAILED = 'Assertion failed (Unexpected behaviour)'; @@ -41,7 +45,7 @@ export class PrettyError extends Error { static isPrettyError(obj: unknown): obj is PrettyError { return ( obj instanceof PrettyError || - Object.prototype.hasOwnProperty('_isPrettyError') + Object.prototype.hasOwnProperty.call(obj, '_isPrettyError') ); } @@ -67,6 +71,7 @@ export class PrettyError extends Error { return new PrettyError( 'CLIENT_UNEXPECTED_BEHAVIOUR', ERROR_ASSERTION_FAILED, + null, m ); } @@ -114,24 +119,24 @@ export class PrettyError extends Error { export function mapAppErrorCodesToAPIErrorCode( errorCode: string | null ): APIErrorCode { - const defaultErrorCode = 'CLIENT_UNEXPECTED_BEHAVIOUR'; try { - if (!errorCode) return defaultErrorCode; + if (!errorCode) return DEFAULT_ERROR_CODE; if (isAPIErrorCode(errorCode)) return errorCode; if (isSignerErrorCode(errorCode)) { - const t: { [key in SignerErrorCode]: APIErrorCode } = { + const t: { [key in SignerErrorCodeType]: APIErrorCode } = { [SignerErrorCode.REJECTED_BY_USER]: 'USER_REJECT', [SignerErrorCode.SIGN_TX_ERROR]: 'CALL_WALLET_FAILED', [SignerErrorCode.SEND_TX_ERROR]: 'SEND_TX_FAILED', - [SignerErrorCode.NOT_IMPLEMENTED]: defaultErrorCode, - [SignerErrorCode.OPERATION_UNSUPPORTED]: defaultErrorCode, - [SignerErrorCode.UNEXPECTED_BEHAVIOUR]: defaultErrorCode, + [SignerErrorCode.TX_FAILED_IN_BLOCKCHAIN]: 'TX_FAILED_IN_BLOCKCHAIN', + [SignerErrorCode.NOT_IMPLEMENTED]: DEFAULT_ERROR_CODE, + [SignerErrorCode.OPERATION_UNSUPPORTED]: DEFAULT_ERROR_CODE, + [SignerErrorCode.UNEXPECTED_BEHAVIOUR]: DEFAULT_ERROR_CODE, }; return t[errorCode]; } - return defaultErrorCode; + return DEFAULT_ERROR_CODE; } catch (err) { - return defaultErrorCode; + return DEFAULT_ERROR_CODE; } } diff --git a/queue-manager/rango-preset/src/shared-sentry.ts b/queue-manager/rango-preset/src/shared-sentry.ts deleted file mode 100644 index f1ae55cd39..0000000000 --- a/queue-manager/rango-preset/src/shared-sentry.ts +++ /dev/null @@ -1,24 +0,0 @@ -import * as Sentry from '@sentry/browser'; -import { PendingSwap, PendingSwapStep } from './shared'; -import { WalletType } from '@rango-dev/wallets-shared'; - -export function logRPCError( - error: unknown, - swap: PendingSwap, - currentStep: PendingSwapStep | undefined, - walletType: WalletType | undefined -): void { - try { - Sentry.captureException(error, { - tags: { - requestId: swap.requestId, - rpc: true, - swapper: currentStep?.swapperId || '', - walletType: walletType || '', - }, - level: 'warning' as any, - }); - } catch (e) { - console.log({ e }); - } -} diff --git a/queue-manager/rango-preset/src/shared.ts b/queue-manager/rango-preset/src/shared.ts index 563e129df2..1f4d3c1396 100644 --- a/queue-manager/rango-preset/src/shared.ts +++ b/queue-manager/rango-preset/src/shared.ts @@ -1,35 +1,30 @@ -import { Network, WalletType } from '@rango-dev/wallets-shared'; -import { - CosmosTransaction, - EvmBlockchainMeta, - EvmTransaction, - SimulationResult, - SolanaTransaction, - StarknetTransaction, - TronTransaction, - Transfer as TransferTransaction, - AmountRestrictionType, - BestRouteResponse, +import type { NamespaceInputForConnect } from '@rango-dev/wallets-core/dist/legacy/types'; +import type { Network, WalletType } from '@rango-dev/wallets-shared'; +import type { + BlockchainMeta, + ConfirmRouteResponse, MetaResponse, - Token, SwapResult, + Token, } from 'rango-sdk'; +import type { + PendingSwap, + PendingSwapStep, + SwapSavedSettings, + SwapStepRoute, + WalletTypeAndAddress, +} from 'rango-types'; -import { PrettyError } from './shared-errors'; import BigNumber from 'bignumber.js'; + import { numberToString } from './numbers'; +import { PrettyError } from './shared-errors'; export interface PendingSwapWithQueueID { id: string; swap: PendingSwap; } -export type SwapProgressNotification = { - eventType: EventType; - swap: PendingSwap | null; - step: PendingSwapStep | null; -}; - export type WalletBalance = { chain: Network; symbol: string; @@ -43,7 +38,6 @@ export type WalletBalance = { }; export type Account = { - balances: WalletBalance[] | null; address: string; loading: boolean; walletType: WalletType; @@ -68,6 +62,7 @@ export type EventType = | 'check_tx_status' | 'check_approve_tx_status' | 'transfer_rejected' + | 'transfer_failed' | 'calling_smart_contract' | 'smart_contract_called' | 'smart_contract_call_failed' @@ -77,109 +72,12 @@ export type EventType = | 'waiting_for_change_wallet_account' | 'network_changed' | 'not_enough_balance' + | 'not_enough_approval' | 'waiting_for_queue' | 'check_fee_failed' | 'route_failed_to_find' | 'transaction_expired'; -export type SwapSavedSettings = { - slippage: string; - disabledSwappersIds?: string[]; - disabledSwappersGroups?: string[]; - infiniteApprove?: boolean; -}; - -type InternalStepState = - | 'PENDING' - | 'CREATED' - | 'WAITING' - | 'SIGNED' - | 'SUCCESSED' - | 'FAILED'; - -export type SwapperStatusStep = { - name: string; - state: InternalStepState; - current: boolean; -}; - -export enum PendingSwapNetworkStatus { - WaitingForConnectingWallet = 'waitingForConnectingWallet', - WaitingForQueue = 'waitingForQueue', - WaitingForNetworkChange = 'waitingForNetworkChange', - NetworkChanged = 'networkChanged', -} - -export type SwapExplorerUrl = { - url: string; - description: string | null; -}; - -export type StepStatus = - | 'created' - | 'running' - | 'failed' - | 'success' - | 'waitingForApproval' - | 'approved'; - -export type PendingSwapStep = { - // routing data - id: number; - fromBlockchain: string; - fromSymbol: string; - fromSymbolAddress: string | null; - fromDecimals: number; - fromAmountPrecision: string | null; - fromAmountMinValue: string | null; - fromAmountMaxValue: string | null; - fromAmountRestrictionType: AmountRestrictionType | null; - fromLogo: string; - toBlockchain: string; - toSymbol: string; - toSymbolAddress: string | null; - toDecimals: number; - toLogo: string; - swapperId: string; - expectedOutputAmountHumanReadable: string | null; - startTransactionTime: number; - internalSteps: SwapperStatusStep[] | null; - estimatedTimeInSeconds: number | null; - - // status data - status: StepStatus; - networkStatus: PendingSwapNetworkStatus | null; - executedTransactionId: string | null; - executedTransactionTime: string | null; - explorerUrl: SwapExplorerUrl[] | null; - diagnosisUrl: string | null; - outputAmount: string | null; - - // txs data - cosmosTransaction: CosmosTransaction | null; - transferTransaction: TransferTransaction | null; - solanaTransaction: SolanaTransaction | null; - evmApprovalTransaction: EvmTransaction | null; - evmTransaction: EvmTransaction | null; - tronApprovalTransaction: TronTransaction | null; - tronTransaction: TronTransaction | null; - starknetApprovalTransaction: StarknetTransaction | null; - starknetTransaction: StarknetTransaction | null; - - // missing fields in older versions - // keeping null for backward compatability - swapperLogo: string | null; - swapperType: string | null; - fromBlockchainLogo: string | null; - toBlockchainLogo: string | null; - feeInUsd: string | null; -}; - -export type WalletTypeAndAddress = { - walletType: WalletType; - address: string; -}; - export enum MessageSeverity { error = 'error', warning = 'warning', @@ -189,101 +87,107 @@ export enum MessageSeverity { export type SwapStatus = 'running' | 'failed' | 'success'; -export type PendingSwap = { - creationTime: string; - finishTime: string | null; - requestId: string; - inputAmount: string; - status: SwapStatus; - isPaused: boolean; - extraMessage: string | null; - extraMessageSeverity: MessageSeverity | null; - extraMessageErrorCode: string | null; - extraMessageDetail: string | null | undefined; - networkStatusExtraMessage: string | null; - networkStatusExtraMessageDetail: string | null; - lastNotificationTime: string | null; - wallets: { [p: string]: WalletTypeAndAddress }; - settings: SwapSavedSettings; - steps: PendingSwapStep[]; - simulationResult: SimulationResult; - validateBalanceOrFee: boolean; - hasAlreadyProceededToSign?: boolean | null; -}; - -export const getCurrentBlockchainOfOrNull = ( +export interface TargetNamespace { + namespace: NamespaceInputForConnect['namespace']; + network: string; +} +export const getCurrentNamespaceOfOrNull = ( swap: PendingSwap, step: PendingSwapStep -): Network | null => { +): TargetNamespace | null => { try { - return getCurrentBlockchainOf(swap, step); + return getCurrentNamespaceOf(swap, step); } catch (e) { return null; } }; -export const getCurrentBlockchainOf = ( +export const getCurrentNamespaceOf = ( swap: PendingSwap, step: PendingSwapStep -): Network => { - const b1 = - step.evmTransaction?.blockChain || - step.evmApprovalTransaction?.blockChain || +): TargetNamespace => { + const evmNetwork = + step.evmTransaction?.blockChain || step.evmApprovalTransaction?.blockChain; + const starknetNetwork = step.starknetTransaction?.blockChain || - step.starknetApprovalTransaction?.blockChain || + step.starknetApprovalTransaction?.blockChain; + const tronNetwork = step.tronTransaction?.blockChain || - step.tronApprovalTransaction?.blockChain || - step.cosmosTransaction?.blockChain || - step.solanaTransaction?.blockChain; - if (!!b1) return b1 as Network; - - const transferAddress = step.transferTransaction?.fromWalletAddress; - if (!transferAddress) throw PrettyError.BlockchainMissing(); - - const blockchain = - Object.keys(swap.wallets).find( - (b) => swap.wallets[b]?.address === transferAddress - ) || null; - if (blockchain == null) throw PrettyError.BlockchainMissing(); - - // TODO: check why it returns string - return blockchain as Network; -}; - -export const getEvmApproveUrl = ( - tx: string, - network: Network, - evmBasedBlockchains: EvmBlockchainMeta[] -): string => { - const evmBlochain = evmBasedBlockchains.find( - (blockchain) => blockchain.name === network - ); - - if (!evmBlochain) { - throw Error(`unsupported network: ${network} for getting approve url.`); - } - - if (evmBlochain.info.transactionUrl) - return evmBlochain.info.transactionUrl.replace( - '{txHash}', - tx.toLowerCase() + step.tronApprovalTransaction?.blockChain; + const cosmosNetwork = step.cosmosTransaction?.blockChain; + const solanaNetwork = step.solanaTransaction?.blockChain; + const tonNetwork = step.tonTransaction?.blockChain; + + if (evmNetwork) { + return { + namespace: 'EVM', + network: evmNetwork, + }; + } else if (starknetNetwork) { + return { + namespace: 'Starknet', + network: starknetNetwork, + }; + } else if (tronNetwork) { + return { + namespace: 'Tron', + network: tronNetwork, + }; + } else if (cosmosNetwork) { + return { + namespace: 'Cosmos', + network: cosmosNetwork, + }; + } else if (solanaNetwork) { + return { + namespace: 'Solana', + network: solanaNetwork, + }; + } else if (tonNetwork) { + return { + namespace: 'Ton', + network: tonNetwork, + }; + } else if (!!step.transferTransaction) { + const transferAddress = step.transferTransaction.fromWalletAddress; + if (!transferAddress) { + throw PrettyError.BlockchainMissing(); + } + const utxoNetwork = Object.keys(swap.wallets).find( + (network) => swap.wallets[network]?.address === transferAddress ); + if (!utxoNetwork) { + throw PrettyError.BlockchainMissing(); + } + + return { + namespace: 'UTXO', + network: utxoNetwork, + }; + } - throw Error(`Explorer url for ${network} is not implemented`); -}; - -export const getStarknetApproveUrl = (tx: string): string => { - return 'https://starkscan.co/tx/{txHash}'.replace( - '{txHash}', - tx.toLowerCase() + throw new Error( + 'Unsupported transaction type has been included in your swap.', + { + cause: step, + } ); }; -export const getTronApproveUrl = (tx: string): string => { - return 'https://tronscan.org/#/transaction/{txHash}'.replace( - '{txHash}', - tx.toLowerCase() - ); +export const getScannerUrl = ( + txHash: string, + network: Network, + blockchainMetaMap: { [key: string]: BlockchainMeta } +): string | undefined => { + const blockchainMeta = blockchainMetaMap[network]; + const baseUrl = blockchainMeta.info?.transactionUrl; + if (!baseUrl) { + return; + } + if (baseUrl.indexOf('/{txHash}') !== -1) { + return baseUrl.replace('{txHash}', txHash); + } + return `${baseUrl}/${txHash}`; }; export function getNextStep( @@ -316,11 +220,14 @@ export const getCurrentAddressOf = ( swap.wallets[step.starknetApprovalTransaction?.blockChain || ''] || swap.wallets[step.cosmosTransaction?.blockChain || ''] || swap.wallets[step.solanaTransaction?.blockChain || ''] || + swap.wallets[step.tonTransaction?.blockChain || ''] || (step.transferTransaction?.fromWalletAddress ? { address: step.transferTransaction?.fromWalletAddress } : null) || null; - if (result == null) throw PrettyError.WalletMissing(); + if (result == null) { + throw PrettyError.WalletMissing(); + } return result.address; }; @@ -337,17 +244,21 @@ export function getRelatedWallet( const wallet = walletKV?.v || null; const walletType = wallet?.walletType; - if (walletType === WalletType.UNKNOWN || wallet === null) + if (wallet === null) { throw PrettyError.AssertionFailed( `Wallet for source ${blockchain} not passed: walletType: ${walletType}` ); + } return wallet; } export function getRelatedWalletOrNull( swap: PendingSwap, - currentStep: PendingSwapStep + currentStep: PendingSwapStep | null ): WalletTypeAndAddress | null { + if (!currentStep) { + return null; + } try { return getRelatedWallet(swap, currentStep); } catch (e) { @@ -377,7 +288,9 @@ export function getUsdFeeOfStep( let totalFeeInUsd = new BigNumber(0); for (let i = 0; i < step.fee.length; i++) { const fee = step.fee[i]; - if (fee.expenseType === 'DECREASE_FROM_OUTPUT') continue; + if (fee.expenseType === 'DECREASE_FROM_OUTPUT') { + continue; + } const unitPrice = getUsdPrice( fee.asset.blockchain, @@ -393,16 +306,61 @@ export function getUsdFeeOfStep( return totalFeeInUsd; } +function mapSwapStepToPendingSwapStep( + swap: SwapResult, + meta: Pick | null +): SwapStepRoute { + return { + // from + fromBlockchain: swap.from.blockchain, + fromBlockchainLogo: swap.from.blockchainLogo, + fromLogo: swap.from.logo, + fromSymbol: swap.from.symbol, + fromSymbolAddress: swap.from.address, + fromDecimals: swap.from.decimals, + fromAmountPrecision: swap.fromAmountPrecision, + fromAmountMinValue: swap.fromAmountMinValue, + fromAmountMaxValue: swap.fromAmountMaxValue, + fromAmountRestrictionType: swap.fromAmountRestrictionType, + fromUsdPrice: swap.from.usdPrice, + + // to + toBlockchain: swap.to.blockchain, + toBlockchainLogo: swap.to.blockchainLogo, + toSymbol: swap.to.symbol, + toSymbolAddress: swap.to.address, + toDecimals: swap.to.decimals, + toLogo: swap.to.logo, + toUsdPrice: swap.to.usdPrice, + + // swapper + swapperId: swap.swapperId, + swapperLogo: swap.swapperLogo, + swapperType: swap.swapperType, + + // route + expectedOutputAmountHumanReadable: swap.toAmount, + feeInUsd: meta + ? // eslint-disable-next-line @typescript-eslint/no-magic-numbers + numberToString(getUsdFeeOfStep(swap, meta?.tokens), null, 8) + : null, + estimatedTimeInSeconds: swap.estimatedTimeInSeconds || null, + internalSteps: null, + }; +} + export function calculatePendingSwap( inputAmount: string, - bestRoute: BestRouteResponse, + bestRoute: NonNullable, wallets: { [p: string]: WalletTypeAndAddress }, settings: SwapSavedSettings, validateBalanceOrFee: boolean, - meta: MetaResponse | null + meta: Pick | null ): PendingSwap { const simulationResult = bestRoute.result; - if (!simulationResult) throw Error('Simulation result should not be null'); + if (!simulationResult) { + throw Error('Simulation result should not be null'); + } return { creationTime: new Date().getTime().toString(), @@ -424,43 +382,23 @@ export function calculatePendingSwap( validateBalanceOrFee, steps: bestRoute.result?.swaps?.map((swap, index) => { + const stepRoute = mapSwapStepToPendingSwapStep(swap, meta); return { id: index + 1, - // from - fromBlockchain: swap.from.blockchain, - fromBlockchainLogo: swap.from.blockchainLogo, - fromLogo: swap.from.logo, - fromSymbol: swap.from.symbol, - fromSymbolAddress: swap.from.address, - fromDecimals: swap.from.decimals, - fromAmountPrecision: swap.fromAmountPrecision, - fromAmountMinValue: swap.fromAmountMinValue, - fromAmountMaxValue: swap.fromAmountMaxValue, - fromAmountRestrictionType: swap.fromAmountRestrictionType, - - // to - toBlockchain: swap.to.blockchain, - toBlockchainLogo: swap.to.blockchainLogo, - toSymbol: swap.to.symbol, - toSymbolAddress: swap.to.address, - toDecimals: swap.to.decimals, - toLogo: swap.to.logo, - - // swapper - swapperId: swap.swapperId, - swapperLogo: swap.swapperLogo, - swapperType: swap.swapperType, - - // output, fee, timing - expectedOutputAmountHumanReadable: swap.toAmount, - outputAmount: '', - feeInUsd: meta - ? numberToString(getUsdFeeOfStep(swap, meta?.tokens), null, 8) - : null, - estimatedTimeInSeconds: swap.estimatedTimeInSeconds || null, + // route + ...stepRoute, + internalSwaps: + swap?.internalSwaps?.map((internalSwap) => { + const stepRoute = mapSwapStepToPendingSwapStep( + internalSwap, + meta + ); + return stepRoute; + }) || null, // status, tracking + outputAmount: '', status: 'created', networkStatus: null, startTransactionTime: new Date().getTime(), @@ -482,6 +420,7 @@ export function calculatePendingSwap( cosmosTransaction: null, solanaTransaction: null, transferTransaction: null, + tonTransaction: null, // front fields hasAlreadyProceededToSign: false, diff --git a/queue-manager/rango-preset/src/types.ts b/queue-manager/rango-preset/src/types.ts index 56f2c424a3..40ce1475d5 100644 --- a/queue-manager/rango-preset/src/types.ts +++ b/queue-manager/rango-preset/src/types.ts @@ -1,14 +1,31 @@ -import { QueueStorage, QueueDef } from '@rango-dev/queue-manager-core'; -import { QueueContext } from '@rango-dev/queue-manager-core/dist/queue'; -import { ConnectResult, Providers } from '@rango-dev/wallets-core'; -import { +import type { TargetNamespace, Wallet } from './shared'; +import type { + QueueContext, + QueueDef, + QueueStorage, +} from '@rango-dev/queue-manager-core'; +import type { LegacyConnectResult as ConnectResult } from '@rango-dev/wallets-core/legacy'; +import type { Meta, Network, + Providers, WalletState, WalletType, } from '@rango-dev/wallets-shared'; -import { PendingSwap, SwapProgressNotification, Wallet } from './shared'; -import { EvmBlockchainMeta, SignerFactory } from 'rango-types'; +import type { Transaction } from 'rango-sdk'; +import type { + APIErrorCode, + EvmBlockchainMeta, + PendingSwap, + PendingSwapStep, + SignerFactory, +} from 'rango-types'; + +export type RemoveNameField = { + [Property in keyof T as Exclude]: T[Property]; +}; + +export type ArrayElement = A extends readonly (infer T)[] ? T : never; export type SwapQueueDef = QueueDef< SwapStorage, @@ -50,17 +67,14 @@ export interface SwapQueueContext extends QueueContext { meta: Meta; wallets: Wallet | null; providers: Providers; - getSigners: (type: WalletType) => SignerFactory; + getSigners: (type: WalletType) => Promise; switchNetwork: ( wallet: WalletType, - network: Network - ) => Promise | undefined; - connect: ( - wallet: WalletType, - network: Network - ) => Promise | undefined; + namespaces: TargetNamespace + ) => Promise | undefined; + canSwitchNetworkTo: (type: WalletType, network: Network) => boolean; state: (type: WalletType) => WalletState; - notifier: (data: SwapProgressNotification) => void; + isMobileWallet: (type: WalletType) => boolean; // Dynamically will be added to context. claimedBy?: string; @@ -72,5 +86,198 @@ export interface UseQueueManagerParams { disconnectedWallet: WalletType | undefined; clearDisconnectedWallet: () => void; evmChains: EvmBlockchainMeta[]; - notifier: SwapQueueContext['notifier']; + canSwitchNetworkTo: (type: WalletType, network: Network) => boolean; +} + +export enum WidgetEvents { + RouteEvent = 'routeEvent', + StepEvent = 'stepEvent', +} + +export type Step = Pick< + PendingSwapStep, + | 'diagnosisUrl' + | 'estimatedTimeInSeconds' + | 'explorerUrl' + | 'feeInUsd' + | 'executedTransactionId' + | 'executedTransactionTime' + | 'expectedOutputAmountHumanReadable' + | 'fromBlockchain' + | 'toBlockchain' + | 'fromSymbol' + | 'toSymbol' + | 'toSymbolAddress' + | 'fromSymbolAddress' + | 'swapperType' + | 'outputAmount' + | 'fromAmountMaxValue' + | 'fromAmountMinValue' + | 'fromAmountPrecision' + | 'fromAmountRestrictionType' + | 'fromDecimals' + | 'status' +> & { swapperName: string; transaction: Transaction | null }; + +export type Route = Pick< + PendingSwap, + | 'creationTime' + | 'finishTime' + | 'requestId' + | 'inputAmount' + | 'status' + | 'wallets' +> & { steps: Step[]; slippage: string; infiniteApproval?: boolean }; + +export type SwapEvent = RouteEvent | StepEvent; + +export enum RouteEventType { + STARTED = 'started', + FAILED = 'failed', + SUCCEEDED = 'succeeded', +} + +export enum StepExecutionEventStatus { + CREATE_TX = 'create_tx', + SEND_TX = 'send_tx', + TX_SENT = 'tx_sent', } + +export enum StepExecutionBlockedEventStatus { + WAITING_FOR_QUEUE = 'waiting_for_queue', + WAITING_FOR_WALLET_CONNECT = 'waiting_for_wallet_connect', + WAITING_FOR_NETWORK_CHANGE = 'waiting_for_network_change', + WAITING_FOR_CHANGE_WALLET_ACCOUNT = 'waiting_for_change_wallet_account', +} + +export enum StepEventType { + STARTED = 'started', + FAILED = 'failed', + SUCCEEDED = 'succeeded', + TX_EXECUTION = 'tx_execution', + TX_EXECUTION_BLOCKED = 'tx_execution_blocked', + APPROVAL_TX_SUCCEEDED = 'approval_tx_succeeded', + CHECK_STATUS = 'check_status', + OUTPUT_REVEALED = 'output_revealed', +} + +export enum EventSeverity { + ERROR = 'error', + SUCCESS = 'success', + WARNING = 'warning', + INFO = 'info', +} + +export type Event< + T extends StepEventType | RouteEventType, + U extends Record = Record +> = { + type: T; + message: string; + messageSeverity: EventSeverity; +} & U; + +export type FailedRouteEventPayload = { + reason?: string; + reasonCode: APIErrorCode; +}; + +export type FailedStepEventPayload = FailedRouteEventPayload; + +export type SucceededRouteEventPayload = { + outputAmount: string; +}; + +export type SucceededStepEventPayload = SucceededRouteEventPayload; + +export type OutputRevealedEventPayload = SucceededRouteEventPayload; + +export type StepExecutionEventPayload = { + status: + | StepExecutionEventStatus.CREATE_TX + | StepExecutionEventStatus.SEND_TX + | StepExecutionEventStatus.TX_SENT; +}; + +export type StepBlockedEventPayload = + | { status: StepExecutionBlockedEventStatus.WAITING_FOR_QUEUE } + | { + status: StepExecutionBlockedEventStatus.WAITING_FOR_WALLET_CONNECT; + requiredWallet?: string; + requiredAccount?: string; + } + | { + status: StepExecutionBlockedEventStatus.WAITING_FOR_CHANGE_WALLET_ACCOUNT; + requiredAccount?: string; + } + | { + status: StepExecutionBlockedEventStatus.WAITING_FOR_NETWORK_CHANGE; + currentNetwork?: string; + requiredNetwork?: string; + }; + +export type RouteStartedEvent = Event; + +export type RouteFailedEvent = Event< + RouteEventType.FAILED, + FailedRouteEventPayload +>; + +export type RouteSucceededEvent = Event< + RouteEventType.SUCCEEDED, + SucceededRouteEventPayload +>; + +export type StepStartedEvent = Event; + +export type StepSucceededEvent = Event< + StepEventType.SUCCEEDED, + SucceededStepEventPayload +>; +export type StepFailedEvent = Event< + StepEventType.FAILED, + FailedStepEventPayload +>; + +export type StepTxExecutionUpdatedEvent = Event< + StepEventType.TX_EXECUTION, + StepExecutionEventPayload +>; + +export type StepTxExecutionBlockedEvent = Event< + StepEventType.TX_EXECUTION_BLOCKED, + StepBlockedEventPayload +>; + +export type StepCheckStatusEvent = Event; + +export type StepApprovalTxSucceededEvent = + Event; + +export type StepOutputRevealedEvent = Event< + StepEventType.OUTPUT_REVEALED, + OutputRevealedEventPayload +>; + +export type StepEvent = + | StepStartedEvent + | StepSucceededEvent + | StepFailedEvent + | StepTxExecutionUpdatedEvent + | StepTxExecutionBlockedEvent + | StepCheckStatusEvent + | StepApprovalTxSucceededEvent + | StepOutputRevealedEvent; + +export type RouteEvent = + | RouteStartedEvent + | RouteSucceededEvent + | RouteFailedEvent; + +export type RouteEventData = { route: Route; event: RouteEvent }; +export type StepEventData = { route: Route; step: Step; event: StepEvent }; + +export type RouteExecutionEvents = { + [WidgetEvents.RouteEvent]: RouteEventData; + [WidgetEvents.StepEvent]: StepEventData; +}; diff --git a/queue-manager/rango-preset/tsconfig.build.json b/queue-manager/rango-preset/tsconfig.build.json new file mode 100644 index 0000000000..579fb407b9 --- /dev/null +++ b/queue-manager/rango-preset/tsconfig.build.json @@ -0,0 +1,11 @@ +{ + // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs + "extends": "../../tsconfig.lib.json", + "include": ["src", "types"], + "compilerOptions": { + "outDir": "dist", + "rootDir": "./src", + "lib": ["dom", "esnext"] + // match output dir to input dir. e.g. dist/index instead of dist/src/index + } +} diff --git a/queue-manager/rango-preset/tsconfig.json b/queue-manager/rango-preset/tsconfig.json index a1d99b2777..a3a0b0f59d 100644 --- a/queue-manager/rango-preset/tsconfig.json +++ b/queue-manager/rango-preset/tsconfig.json @@ -1,36 +1 @@ -{ - // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs - "extends": "../../tsconfig.base.json", - "include": ["src", "types"], - "compilerOptions": { - "module": "esnext", - "lib": ["dom", "esnext"], - "importHelpers": true, - // output .d.ts declaration files for consumers - "declaration": true, - // output .js.map sourcemap files for consumers - "sourceMap": true, - // match output dir to input dir. e.g. dist/index instead of dist/src/index - "rootDir": "./src", - // stricter type-checking for stronger correctness. Recommended by TS - "strict": true, - // linter checks for common issues - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true, - // noUnused* overlap with @typescript-eslint/no-unused-vars, can disable if duplicative - "noUnusedLocals": true, - "noUnusedParameters": true, - // use Node's module resolution algorithm, instead of the legacy TS one - "moduleResolution": "node", - // transpile JSX to React.createElement - "jsx": "react", - // interop between ESM and CJS modules. Recommended by TS - "esModuleInterop": true, - // significant perf increase by skipping checking .d.ts files, particularly those in node_modules. Recommended by TS - "skipLibCheck": true, - // error out if import and file system have a casing mismatch. Recommended by TS - "forceConsistentCasingInFileNames": true, - // `tsdx build` ignores this option, but it is commonly used when type-checking separately with `tsc` - "noEmit": true - } -} +{ "extends": "./tsconfig.build.json", "include": ["src", "tests"] } diff --git a/queue-manager/react/CHANGELOG.md b/queue-manager/react/CHANGELOG.md new file mode 100644 index 0000000000..773e980ebe --- /dev/null +++ b/queue-manager/react/CHANGELOG.md @@ -0,0 +1,81 @@ +# [0.27.0](https://github.com/rango-exchange/rango-client/compare/queue-manager-react@0.26.0...queue-manager-react@0.27.0) (2024-08-11) + + + +# [0.26.0](https://github.com/rango-exchange/rango-client/compare/queue-manager-react@0.25.0...queue-manager-react@0.26.0) (2024-02-20) + + + +# [0.25.0](https://github.com/rango-exchange/rango-client/compare/queue-manager-react@0.24.0...queue-manager-react@0.25.0) (2024-01-22) + + +### Features + +* handle active tab in widget-embedded ([427a3bb](https://github.com/rango-exchange/rango-client/commit/427a3bb42dcaf899c4241aa5bd60c15a3475882a)) + + + +# [0.24.0](https://github.com/rango-exchange/rango-client/compare/queue-manager-react@0.23.0...queue-manager-react@0.24.0) (2023-12-24) + + +### Bug Fixes + +* fix HMR for widget and playground ([8524820](https://github.com/rango-exchange/rango-client/commit/8524820f10cf0b8921f3db0c4f620ff98daa4103)) + + + +# [0.14.0](https://github.com/rango-exchange/rango-client/compare/queue-manager-react@0.13.0...queue-manager-react@0.14.0) (2023-08-03) + + + +# [0.13.0](https://github.com/rango-exchange/rango-client/compare/queue-manager-react@0.12.0...queue-manager-react@0.13.0) (2023-08-01) + + + +# [0.9.0](https://github.com/rango-exchange/rango-client/compare/queue-manager-react@0.8.0...queue-manager-react@0.9.0) (2023-07-31) + + +### Bug Fixes + +* seems npm needs a bit time to update the cdn and return the correct version ([09168ac](https://github.com/rango-exchange/rango-client/commit/09168acdc3ca400abd2016eebc0c62103edae3a2)) + + +### Features + +* Support for WalletConnect 2 ([faedef0](https://github.com/rango-exchange/rango-client/commit/faedef0b5e6fc3c5ef881cbbe4ec05334cc1c910)) + + + +# [0.7.0](https://github.com/rango-exchange/rango-client/compare/queue-manager-react@0.6.0...queue-manager-react@0.7.0) (2023-07-11) + + + +# [0.6.0](https://github.com/rango-exchange/rango-client/compare/queue-manager-react@0.5.0...queue-manager-react@0.6.0) (2023-07-11) + + + +# [0.5.0](https://github.com/rango-exchange/rango-client/compare/queue-manager-react@0.4.0...queue-manager-react@0.5.0) (2023-05-31) + + + +# [0.4.0](https://github.com/rango-exchange/rango-client/compare/queue-manager-react@0.3.0...queue-manager-react@0.4.0) (2023-05-31) + + + +# [0.3.0](https://github.com/rango-exchange/rango-client/compare/queue-manager-react@0.2.0...queue-manager-react@0.3.0) (2023-05-30) + + + +# [0.2.0](https://github.com/rango-exchange/rango-client/compare/queue-manager-react@0.1.13...queue-manager-react@0.2.0) (2023-05-30) + + + +## [0.1.12](https://github.com/rango-exchange/rango-client/compare/queue-manager-react@0.1.11...queue-manager-react@0.1.12) (2023-05-15) + + +### Bug Fixes + +* fix type inconsistency in queue-manager-react Provider props ([1c2d484](https://github.com/rango-exchange/rango-client/commit/1c2d484dd251628791d39c45be97058f38bc02e7)) + + + diff --git a/queue-manager/react/package.json b/queue-manager/react/package.json index 8ef9c7d936..7b04282391 100644 --- a/queue-manager/react/package.json +++ b/queue-manager/react/package.json @@ -1,21 +1,24 @@ { "name": "@rango-dev/queue-manager-react", - "version": "0.1.11-next.0", + "version": "0.27.0", "license": "MIT", - "module": "dist/queue-manager-react.esm.js", - "main": "dist/index.js", + "type": "module", + "source": "./src/index.ts", + "main": "./dist/index.js", + "exports": { + ".": "./dist/index.js" + }, "typings": "dist/index.d.ts", "files": [ "dist", "src" ], "scripts": { - "dev": "tsdx watch", - "build": "tsdx build --tsconfig ./tsconfig.json", - "test": "tsdx test --passWithNoTests", - "lint": "tsdx lint", - "size": "size-limit", - "analyze": "size-limit --why" + "build": "node ../../scripts/build/command.mjs --path queue-manager/react", + "ts-check": "tsc --declaration --emitDeclarationOnly -p ./tsconfig.json", + "clean": "rimraf dist", + "format": "prettier --write '{.,src}/**/*.{ts,tsx}'", + "lint": "eslint \"**/*.{ts,tsx}\" --ignore-path ../../.eslintignore" }, "peerDependencies": { "@rango-dev/queue-manager-core": "*", @@ -23,27 +26,6 @@ "react": "^17.0.0 || ^18.0.0", "react-dom": "^17.0.0 || ^18.0.0" }, - "husky": { - "hooks": { - "pre-commit": "tsdx lint" - } - }, - "prettier": { - "printWidth": 80, - "semi": true, - "singleQuote": true, - "trailingComma": "es5" - }, - "size-limit": [ - { - "path": "dist/queue-manager-react.cjs.production.min.js", - "limit": "10 KB" - }, - { - "path": "dist/queue-manager-react.esm.js", - "limit": "10 KB" - } - ], "devDependencies": { "react": "^18.2.0", "react-dom": "^18.2.0" diff --git a/queue-manager/react/readme.md b/queue-manager/react/readme.md index 6e1d7af94f..173e4850c5 100644 --- a/queue-manager/react/readme.md +++ b/queue-manager/react/readme.md @@ -1 +1 @@ -# @rango-dev/queue-manager-rango-preset \ No newline at end of file +# @rango-dev/queue-manager-react diff --git a/queue-manager/react/src/index.tsx b/queue-manager/react/src/index.ts similarity index 100% rename from queue-manager/react/src/index.tsx rename to queue-manager/react/src/index.ts diff --git a/queue-manager/react/src/provider.tsx b/queue-manager/react/src/provider.tsx index 0985345860..a65feb0c04 100644 --- a/queue-manager/react/src/provider.tsx +++ b/queue-manager/react/src/provider.tsx @@ -1,6 +1,14 @@ +import type { ManagerContext, ManagerState } from './types'; +import type { + ManagerContext as Context, + Events, + QueueDef, +} from '@rango-dev/queue-manager-core'; +import type { PropsWithChildren } from 'react'; + +import { Manager } from '@rango-dev/queue-manager-core'; import React, { createContext, - PropsWithChildren, useContext, useEffect, useLayoutEffect, @@ -8,14 +16,8 @@ import React, { useRef, useState, } from 'react'; -import { - ManagerContext as Context, - Manager, - QueueDef, - Events, -} from '@rango-dev/queue-manager-core'; -import { ManagerContext, ManagerState } from './types'; -import { useManagerState, initState as initManagerState } from './state'; + +import { initState as initManagerState, useManagerState } from './state'; const ManagerCtx = createContext<{ manager: ManagerContext; @@ -26,7 +28,7 @@ const ManagerCtx = createContext<{ }); interface PropTypes { - queuesDefs: QueueDef[]; + queuesDefs: QueueDef[]; context: Context; onPersistedDataLoaded?: Events['onPersistedDataLoaded']; isPaused?: boolean; @@ -64,8 +66,10 @@ function Provider(props: PropsWithChildren) { props.onPersistedDataLoaded(manager); } - // This condition will make sure, we only update the `loadedFromPersistor`. - // But be aware `onPersistedDataLoaded` is calling after each `sync` which means can be called multiple times. + /* + * This condition will make sure, we only update the `loadedFromPersistor`. + * But be aware `onPersistedDataLoaded` is calling after each `sync` which means can be called multiple times. + */ if (!state.loadedFromPersistor) { update('loadedFromPersistor', true); } @@ -73,6 +77,9 @@ function Provider(props: PropsWithChildren) { onTaskBlock: () => { forceRender({}); }, + onDeleteQueue: () => { + forceRender({}); + }, }, context: context || {}, isPaused: props.isPaused, @@ -95,6 +102,7 @@ function Provider(props: PropsWithChildren) { }, [props.isPaused]); return ( + // eslint-disable-next-line react/jsx-no-constructed-context-values {props.children} @@ -103,8 +111,9 @@ function Provider(props: PropsWithChildren) { export function useManager(): { manager: ManagerContext; state: ManagerState } { const context = useContext(ManagerCtx); - if (!context) + if (!context) { throw Error('useManager can only be used within the Provider component'); + } return context; } diff --git a/queue-manager/react/src/types.ts b/queue-manager/react/src/types.ts index 85853f553b..22bff20bf7 100644 --- a/queue-manager/react/src/types.ts +++ b/queue-manager/react/src/types.ts @@ -1,4 +1,4 @@ -import { Manager } from '@rango-dev/queue-manager-core'; +import type { Manager } from '@rango-dev/queue-manager-core'; export type ManagerContext = Manager | undefined; export type ManagerState = { diff --git a/queue-manager/react/tsconfig.build.json b/queue-manager/react/tsconfig.build.json new file mode 100644 index 0000000000..9e3b11c3e2 --- /dev/null +++ b/queue-manager/react/tsconfig.build.json @@ -0,0 +1,13 @@ +{ + // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs + "extends": "../../tsconfig.lib.json", + "include": ["src", "types"], + "compilerOptions": { + "outDir": "dist", + "lib": ["dom", "esnext"], + // match output dir to input dir. e.g. dist/index instead of dist/src/index + "rootDir": "./src", + // transpile JSX to React.createElement + "jsx": "react" + } +} diff --git a/queue-manager/react/tsconfig.json b/queue-manager/react/tsconfig.json index a1d99b2777..a3a0b0f59d 100644 --- a/queue-manager/react/tsconfig.json +++ b/queue-manager/react/tsconfig.json @@ -1,36 +1 @@ -{ - // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs - "extends": "../../tsconfig.base.json", - "include": ["src", "types"], - "compilerOptions": { - "module": "esnext", - "lib": ["dom", "esnext"], - "importHelpers": true, - // output .d.ts declaration files for consumers - "declaration": true, - // output .js.map sourcemap files for consumers - "sourceMap": true, - // match output dir to input dir. e.g. dist/index instead of dist/src/index - "rootDir": "./src", - // stricter type-checking for stronger correctness. Recommended by TS - "strict": true, - // linter checks for common issues - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true, - // noUnused* overlap with @typescript-eslint/no-unused-vars, can disable if duplicative - "noUnusedLocals": true, - "noUnusedParameters": true, - // use Node's module resolution algorithm, instead of the legacy TS one - "moduleResolution": "node", - // transpile JSX to React.createElement - "jsx": "react", - // interop between ESM and CJS modules. Recommended by TS - "esModuleInterop": true, - // significant perf increase by skipping checking .d.ts files, particularly those in node_modules. Recommended by TS - "skipLibCheck": true, - // error out if import and file system have a casing mismatch. Recommended by TS - "forceConsistentCasingInFileNames": true, - // `tsdx build` ignores this option, but it is commonly used when type-checking separately with `tsc` - "noEmit": true - } -} +{ "extends": "./tsconfig.build.json", "include": ["src", "tests"] } diff --git a/queue-manager/readme.md b/queue-manager/readme.md new file mode 100644 index 0000000000..2a33db7721 --- /dev/null +++ b/queue-manager/readme.md @@ -0,0 +1,76 @@ +# Queue Manager + +The `queue-manager` package is a JavaScript library for enqueuing tasks and running them based on their conditions. It uses the core package to manage the state machine and store data in the browser's IndexedDB. The react package provides a wrapper around queue-manager to make it easy to use in React applications. The rango-preset package provides some default values, services, and actions of Rango Exchange to use in Rango. + +# Packages + +## Core + +The `core` package is the backbone of queue-manager. It provides a state machine to manage the queue of tasks and the conditions under which they should be executed. It also stores data in the browser's IndexedDB so that it can be retrieved later. + +## React + +The `react` package is a wrapper around queue-manager that makes it easy to use in React applications. It provides a context to store data using React hooks, which allows you to easily pass data between components. + +## Rango-Preset + +The `rango-preset` package provides some default values, services, and actions of Rango Exchange to use in Rango. It can be used to quickly get started with Rango without having to write all of the boilerplate code yourself. +First, you need to add `@rango-dev/wallets-react` to your project + +# Installation + +To use `queue-manager` in your project, you can install it using NPM + +``` +yarn add @rango-dev/queue-manager-core @rango-dev/queue-manager-react @rango-dev/queue-manager-rango-preset + + +# or using NPM + +npm install @rango-dev/queue-manager-core @rango-dev/queue-manager-react @rango-dev/queue-manager-rango-preset +``` + +You can also install the individual packages separately: + +``` +npm install @rango-dev/queue-manager-core +npm install @rango-dev/queue-manager-react +npm install @rango-dev/queue-manager-rango-preset +``` + +# Usage + +To use `queue-manager`, you need to create a queue definition and pass it to the Provider component of `react` package. You can use the `makeQueueDefinition` function from `rango-preset` package to create a queue definition quickly. + +```js +import { Provider } from '@rango-dev/queue-manager-react'; +import { SwapQueueContext, makeQueueDefinition } from '@rango-dev/queue-manager-rango-preset'; + +const swapQueueDef = () => + makeQueueDefinition({ + API_KEY, + }); + +return ( + + {props.children} + +); +``` + +You can then use the useManager to access the queueManager object and get store data using React hooks. + +``` +import { useManager } from "@rango-dev/queue-manager-react"; + + const { manager } = useManager(); + const storage = manager?.getAll(); +``` + +# Example + +- Check out the demo for queue-manager on [Vercel](https://q-self.vercel.app) to see it in action. + +# Contributing + +Contributions to queue-manager are welcome! To get started, fork the repository and create a new branch for your changes. Then, submit a pull request with your changes. diff --git a/scripts/analyze-bundle/command.mjs b/scripts/analyze-bundle/command.mjs new file mode 100644 index 0000000000..d94b10ed31 --- /dev/null +++ b/scripts/analyze-bundle/command.mjs @@ -0,0 +1,54 @@ +import fs from 'fs/promises'; +import path from 'path'; +import commandLineArgs from 'command-line-args'; +import { downloadTargetBranchArtifacts } from './downloadTargetBranchArtifacts.mjs'; +import { findBuildJsonFiles } from './findBuildFiles.mjs'; +import { compareBuildJsonFiles } from './compare.mjs'; + +async function run() { + const optionDefinitions = [ + { name: 'currentBranchDirectory', type: String }, + { name: 'targetBranchDirectory', type: String }, + { name: 'targetBranchArtifactName', type: String }, + ]; + const { + currentBranchDirectory, + targetBranchDirectory, + targetBranchArtifactName, + } = commandLineArgs(optionDefinitions); + + const githubToken = process.env.GH_TOKEN; + const repository = process.env.GH_REPOSITORY; + + const targetBranchPath = path.join(process.cwd(), targetBranchDirectory); + const currentBranchPath = path.join(process.cwd(), currentBranchDirectory); + + try { + await downloadTargetBranchArtifacts( + targetBranchDirectory, + targetBranchArtifactName, + repository, + githubToken + ); + await Promise.all([fs.stat(targetBranchPath), fs.stat(currentBranchPath)]); + } catch (error) { + console.log( + 'Directories for the target or current branch do not exist, the bundle size comparison will be skipped.' + ); + process.exit(0); + } + + const targetBranchBuilds = await findBuildJsonFiles(targetBranchPath); + const currentBranchBuilds = await findBuildJsonFiles(currentBranchPath); + + const comparison = await compareBuildJsonFiles( + targetBranchBuilds, + currentBranchBuilds + ); + console.table(comparison); +} + +run().catch((error) => { + console.error(error); + process.exit(1); +}); diff --git a/scripts/analyze-bundle/compare.mjs b/scripts/analyze-bundle/compare.mjs new file mode 100644 index 0000000000..022260a2b9 --- /dev/null +++ b/scripts/analyze-bundle/compare.mjs @@ -0,0 +1,116 @@ +import fs from 'fs/promises'; +import path from 'path'; +import { BUILD_META_FILE_SUFFIX, NPM_ORG_NAME } from '../common/constants.mjs'; +import { partial } from 'filesize'; + +const size = partial({ standard: 'jedec' }); + +/** + * Generates the package name based on the file name. + * @param {string} fileName - The file name. + * @returns {string} - The generated package name. example: @rango-dev/widget-embedded + * + */ +function getPackageName(fileName) { + return `${NPM_ORG_NAME}/${fileName.split(BUILD_META_FILE_SUFFIX)[0]}`; +} + +/** + * Formats the bundle size difference for display. + * @param {number} bundleSizeDiff - The difference in bundle size. + * @param {number} initialBundleSize - The initial bundle size. + * @returns {string} - The formatted bundle size difference. + */ +function formatBundleSizeDiff(bundleSizeDiff, initialBundleSize) { + if (bundleSizeDiff === 0 && initialBundleSize > 0) { + return 'No changes'; + } + + if (bundleSizeDiff > 0 && initialBundleSize === 0) { + return 'Added'; + } + + if (bundleSizeDiff < 0 && bundleSizeDiff === initialBundleSize) { + return 'Deleted'; + } + + const sign = bundleSizeDiff > 0 ? '+' : '-'; + const diffPercentage = Math.round( + (Math.abs(bundleSizeDiff) / initialBundleSize) * 100 + ); + + return `${sign}${size(Math.abs(bundleSizeDiff))} (${sign}${diffPercentage}%)`; +} + +/** + * ESBuild meta file interface: + * https://esbuild.github.io/api/#metafile + */ + +/** + * Parses ESBuild meta JSON files to extract package names and bundle sizes. + * @param {string[]} files - An array of file paths to ESBuild meta JSON files. + * @returns {Promise<{[packageName: string]: number}>} - A promise resolving to an object containing package names and their respective bundle sizes. + */ +async function parseBuildJsonFiles(files) { + const packagesAndBundleSize = {}; + + for (const build of files) { + const data = JSON.parse(await fs.readFile(build, 'utf8')); + const outputBytes = Object.values(data.outputs) + .map((outputs) => outputs.bytes) + .reduce((prev, item) => prev + item, 0); + packagesAndBundleSize[path.basename(build)] = outputBytes; + } + + return packagesAndBundleSize; +} + +/** + * Compares the bundle sizes between the target and current branches. + * @param {string[]} targetBranchBuilds - An array of file paths to ESBuild meta JSON files from the target branch. + * @param {string[]} currentBranchBuilds - An array of file paths to ESBuild meta JSON files from the current branch. + * @returns {Promise<{[packageName: string]: { 'current branch': string, 'target branch': string, diff: string }}>} - A promise resolving to an object containing package names and their respective bundle size differences. + */ +export async function compareBuildJsonFiles( + targetBranchBuilds, + currentBranchBuilds +) { + const targetBranchPackagesAndBundleSize = await parseBuildJsonFiles( + targetBranchBuilds + ); + const currentBranchPackagesAndBundlesSize = await parseBuildJsonFiles( + currentBranchBuilds + ); + + const addedPackages = Object.keys(currentBranchPackagesAndBundlesSize).filter( + (item) => !Object.keys(targetBranchPackagesAndBundleSize).includes(item) + ); + + const changes = {}; + + for (const key in targetBranchPackagesAndBundleSize) { + const bundleSizeDiff = + (currentBranchPackagesAndBundlesSize[key] || 0) - + targetBranchPackagesAndBundleSize[key]; + + changes[getPackageName(key)] = { + 'current branch': size(currentBranchPackagesAndBundlesSize[key] || 0), + 'target branch': size(targetBranchPackagesAndBundleSize[key]), + diff: formatBundleSizeDiff( + bundleSizeDiff, + targetBranchPackagesAndBundleSize[key] + ), + }; + } + + addedPackages.forEach((item) => { + changes[getPackageName(item)] = { + 'current branch': size(currentBranchPackagesAndBundlesSize[item]), + 'target branch': size(0), + diff: formatBundleSizeDiff(currentBranchPackagesAndBundlesSize[item], 0), + }; + }); + + return changes; +} diff --git a/scripts/analyze-bundle/downloadTargetBranchArtifacts.mjs b/scripts/analyze-bundle/downloadTargetBranchArtifacts.mjs new file mode 100644 index 0000000000..92b55232d1 --- /dev/null +++ b/scripts/analyze-bundle/downloadTargetBranchArtifacts.mjs @@ -0,0 +1,87 @@ +import fs from 'fs'; +import { pipeline } from 'stream/promises'; +import { execa } from 'execa'; + +/** + * Downloads and extracts artifacts from the specified GitHub repository's actions for the target branch. + * @param {string} targetBranchDirectory - The directory where the artifacts will be extracted. + * @param {string} artifactName - The name of the artifact to be downloaded. + * @param {string} repository - The GitHub repository in the format owner/repo. + * @param {string} githubToken - The GitHub token for authentication. + * @returns {Promise} - A Promise that resolves when the artifacts are downloaded and extracted successfully. + * @throws {Error} - If there's an error during the process. + */ +export async function downloadTargetBranchArtifacts( + targetBranchDirectory, + artifactName, + repository, + githubToken +) { + if (!githubToken || !repository || !artifactName) { + console.error( + 'Missing required parameters (githubToken, repository, artifactName)' + ); + process.exit(1); + } + try { + // List Artifacts + const artifactsResponse = await fetch( + `https://api.github.com/repos/${repository}/actions/artifacts`, + { + headers: { Authorization: `token ${githubToken}` }, + } + ); + + if (!artifactsResponse.ok) { + throw new Error( + `Failed to fetch artifacts: ${artifactsResponse.statusText}` + ); + } + + const artifactsData = await artifactsResponse.json(); + const artifacts = artifactsData.artifacts; + + // Find the artifact with the specified name + const targetArtifact = artifacts.find( + (artifact) => artifact.name === artifactName + ); + + if (!targetArtifact) { + console.error('Target Branch Artifact not found'); + return; + } + + // Extract Target Branch Artifact Download URL + const artifactUrl = targetArtifact.archive_download_url; + if (!artifactUrl) { + console.error('Target Branch Artifact URL not found'); + return; + } + + // Download Target Branch Artifact + const downloadResponse = await fetch(artifactUrl, { + headers: { Authorization: `token ${githubToken}` }, + }); + + if (!downloadResponse.ok) { + throw new Error( + `Failed to download artifact: ${downloadResponse.statusText}` + ); + } + + // Save the artifact zip file + const artifactZipPath = 'artifact.zip'; + await pipeline( + downloadResponse.body, + fs.createWriteStream(artifactZipPath) + ); + + // Unzip the artifact + await execa('unzip', [artifactZipPath, '-d', `./${targetBranchDirectory}`]); + + console.log('Artifact downloaded and extracted successfully.'); + } catch (error) { + console.error('Error:', error.message); + process.exit(1); + } +} diff --git a/scripts/analyze-bundle/findBuildFiles.mjs b/scripts/analyze-bundle/findBuildFiles.mjs new file mode 100644 index 0000000000..73422f3b72 --- /dev/null +++ b/scripts/analyze-bundle/findBuildFiles.mjs @@ -0,0 +1,47 @@ +import fs from 'fs/promises'; +import path from 'path'; +import { BUILD_META_FILE_SUFFIX } from '../common/constants.mjs'; + +/** + * Each artifact directory mirrors the hierarchy of our monorepo directory: + * + * branch-directory + * /widget + * /embedded + * widget-embedded.build.json + * /ui + * widget-ui.build.json + * ... + */ + +/** + * Recursively searches for ESBuild meta JSON files in the specified directory. + * @param {string} directory - The directory to search in. + * @returns {Promise} - A promise resolving to an array of file paths to ESBuild meta JSON files found in the directory and its subdirectories. + */ +export async function findBuildJsonFiles(directory) { + const files = []; + + /** + * Recursively traverses the directory to find ESBuild meta JSON files. + * @param {string} currentDir - The current directory to traverse. + * @returns {Promise} - A promise that resolves when the traversal is complete. + */ + async function traverseDirectory(currentDir) { + const dirContents = await fs.readdir(currentDir); + for (const item of dirContents) { + const itemPath = path.join(currentDir, item); + const stats = await fs.stat(itemPath); + const isDirectory = stats.isDirectory(); + + if (isDirectory) { + await traverseDirectory(itemPath); + } else if (item.endsWith(BUILD_META_FILE_SUFFIX)) { + files.push(itemPath); + } + } + } + + await traverseDirectory(directory); + return files; +} diff --git a/scripts/build-libs/command.mjs b/scripts/build-libs/command.mjs new file mode 100755 index 0000000000..f4c68f69ec --- /dev/null +++ b/scripts/build-libs/command.mjs @@ -0,0 +1,21 @@ +#!/usr/bin/env node +'use strict'; +import process from 'node:process'; +import { workspacePackages } from '../common/utils.mjs'; +import { build } from '../publish/build.mjs'; + +async function run() { + const packages = await workspacePackages(); + let packagesToBeBuild = packages.filter((pkg) => !pkg.private); + + console.log('these packages will be built:', packagesToBeBuild.map(pkg=>pkg.name).join(', ')) ; + + console.log(`🔨 Start building...`); + await build(packagesToBeBuild); + console.log('🔨 Finish building'); +} + +run().catch((e) => { + console.error(e); + process.exit(1); +}); diff --git a/scripts/build/command.mjs b/scripts/build/command.mjs new file mode 100644 index 0000000000..e68b51bb45 --- /dev/null +++ b/scripts/build/command.mjs @@ -0,0 +1,119 @@ +import commandLineArgs from 'command-line-args'; +import * as esbuild from 'esbuild'; +import { $ } from 'execa'; +import { join } from 'path'; +import process from 'process'; +import { nodeModulesPolyfillPlugin } from 'esbuild-plugins-node-modules-polyfill'; +import { + packageJson, + packageNameWithoutScope, + printDirname, +} from '../common/utils.mjs'; +import fs from 'fs/promises'; +import { BUILD_META_FILE_SUFFIX } from '../common/constants.mjs'; + +const root = join(printDirname(), '..', '..'); + +async function run() { + const optionDefinitions = [ + { name: 'path', type: String }, + // It accepts a comma separated file paths. e.g. src/main.ts,src/net.ts + { name: 'inputs', type: String }, + // Comma separated list. https://esbuild.github.io/api/#external + { name: 'external', type: String }, + // When you want to make all the packages external, and only include some specific packages as your library bundle, this will be usefull. + // Comma separated. + { name: 'external-all-except', type: String }, + // Enable code splitting + { name: 'splitting', type: Boolean }, + ]; + + const { + path, + inputs, + external, + 'external-all-except': externalAllExcept, + splitting, + } = commandLineArgs(optionDefinitions); + + if (!path) { + throw new Error('You need to specify package name.'); + } + + if (!!external && !!externalAllExcept) + throw new Error( + 'You should only use one of `external` or `external-all-except` at the sametime.' + ); + + const pkgPath = `${root}/${path}`; + const pkg = packageJson(path); + const packageName = packageNameWithoutScope(pkg.name); + + let entryPoints = []; + if (!inputs) { + entryPoints = [`${pkgPath}/src/index.ts`]; + } else { + entryPoints = inputs.split(',').map((input) => `${pkgPath}/${input}`); + } + + // read more: https://esbuild.github.io/api/#packages + let externalPackages = {}; + if (!!external) { + externalPackages = { + external: external.split(','), + }; + } else if (!!externalAllExcept) { + const excludedPackages = externalAllExcept.split(','); + const dependencies = Object.keys(pkg.dependencies).filter( + (name) => !excludedPackages.includes(name) + ); + + externalPackages = { + external: dependencies, + }; + } else { + externalPackages = { + packages: 'external', + }; + } + + console.log(`[build] Running for ${path}`); + + const typeCheckingTask = $({ + cwd: pkgPath, + stderr: process.stderr, + stdout: process.stdout, + })`tsc --declaration --emitDeclarationOnly -p tsconfig.build.json`; + const esbuildTask = esbuild.build({ + bundle: true, + minify: true, + splitting: !!splitting, + keepNames: true, + sourcemap: true, + platform: 'browser', + format: 'esm', + outdir: `${pkgPath}/dist`, + entryPoints: entryPoints, + metafile: true, + plugins: [ + nodeModulesPolyfillPlugin({ + globals: { + fs: true, + }, + }), + ], + ...externalPackages, + }); + const result = await Promise.all([typeCheckingTask, esbuildTask]); + console.log(`[build] ${path} built successfully.`); + + await fs.writeFile( + `dist/${packageName}${BUILD_META_FILE_SUFFIX}`, + JSON.stringify(result[1].metafile) + ); +} + +run().catch((e) => { + console.error(e); + process.exit(1); +}); diff --git a/scripts/check-conventional-commits/command.mjs b/scripts/check-conventional-commits/command.mjs new file mode 100644 index 0000000000..979f38a58b --- /dev/null +++ b/scripts/check-conventional-commits/command.mjs @@ -0,0 +1,34 @@ +import { execa } from 'execa'; +import { logAsSection } from '../publish/utils.mjs'; +import { detectChannel } from '../common/github.mjs'; +import parser from 'conventional-commits-parser'; +import filter from 'conventional-commits-filter'; + +async function run() { + const channel = detectChannel(); + + logAsSection('Run...', `at ${channel}..HEAD`); + + const { stdout: logs } = await execa('git', [ + 'log', + `origin/${channel}..HEAD`, + '--pretty=format:%B__________', + ]); + const commits = logs.split('__________').filter(Boolean); + const parsedCommits = filter(commits.map(parser.sync)); + const hasAnyConventionalCommit = parsedCommits.some( + (commit) => !!commit.type + ); + + if (hasAnyConventionalCommit) { + console.log('found a conventional commit.'); + console.debug(parsedCommits); + } else { + throw new Error('There is no conventional commit. you need at least one.'); + } +} + +run().catch((e) => { + console.error(e); + process.exit(1); +}); diff --git a/scripts/common/changelog.mjs b/scripts/common/changelog.mjs new file mode 100644 index 0000000000..59340e3540 --- /dev/null +++ b/scripts/common/changelog.mjs @@ -0,0 +1,49 @@ +import { execa } from 'execa'; +import { GenerateChangelogFailedError, YarnError } from './errors.mjs'; +import { packageNameWithoutScope } from './utils.mjs'; + +/** + * Generate a changelog by using convetional commit format. + * + * @param {import("./typedefs.mjs").Package} pkg + * @param {Object} options + * @param {boolean} options.saveToFile `true` for using it for creating `pkg/CHANGELOG.com` and `false` for Github Release note. + */ +export async function generateChangelog(pkg, options) { + const { saveToFile = false } = options || {}; + + const conventionalChangelogBinPath = await execa('yarn', [ + 'bin', + 'conventional-changelog', + ]) + .then((result) => result.stdout) + .catch((err) => { + throw new YarnError(`GetBinaryPathFailed: \n${err.stdout}`); + }); + + const tagName = packageNameWithoutScope(pkg.name); + const command = [ + 'conventional-changelog', + '-p', + 'angular', + '-l', + `${tagName}`, + '-k', + pkg.location, + '--commit-path', + pkg.location, + ]; + + if (saveToFile) { + const changelogPath = `${pkg.location}/CHANGELOG.md`; + command.push('-i', changelogPath, '-s'); + } + + const result = await execa(conventionalChangelogBinPath, command) + .then((result) => result.stdout) + .catch((err) => { + throw new GenerateChangelogFailedError(err.stdout); + }); + + return result; +} diff --git a/scripts/common/constants.mjs b/scripts/common/constants.mjs new file mode 100644 index 0000000000..4c35e09889 --- /dev/null +++ b/scripts/common/constants.mjs @@ -0,0 +1,4 @@ +/** A fixed subject for using in publish commit. */ +export const PUBLISH_COMMIT_SUBJECT = 'chore(release): publish'; +export const NPM_ORG_NAME = '@rango-dev'; +export const BUILD_META_FILE_SUFFIX = '.build.json'; diff --git a/scripts/common/errors.mjs b/scripts/common/errors.mjs new file mode 100644 index 0000000000..d0ceabe491 --- /dev/null +++ b/scripts/common/errors.mjs @@ -0,0 +1,113 @@ +export class GithubGetReleaseError extends Error { + name = 'GithubGetReleaseError'; + constructor(msg) { + super(msg); + } +} + +export class GithubReleaseNotFoundError extends Error { + name = 'GithubReleaseNotFoundError'; + constructor(tag) { + super(`Couldn't find any github release for ${tag}`); + } +} + +export class GithubCreateReleaseFailedError extends Error { + name = 'GithubCreateReleaseFailedError'; + constructor(msg) { + super(msg); + } +} + +export class GithubCommandError extends Error { + name = 'GithubCommandError'; + constructor(msg) { + super(msg); + } +} + +export class NpmPackageNotFoundError extends Error { + name = 'NpmPackageNotFoundError'; + constructor(packageName) { + super(`Couldn't find ${packageName} on NPM.`); + } +} + +export class NpmGetPackageError extends Error { + name = 'NpmGetPackageError'; + constructor(msg) { + super(msg); + } +} + +export class NpmPublishError extends Error { + name = 'NpmPublishError'; + constructor(msg) { + super(msg); + } +} + +export class IncreaseVersionFailedError extends Error { + name = 'IncreaseVersionFailedError'; + constructor(msg) { + super(msg); + } +} + +export class GenerateChangelogFailedError extends Error { + name = 'GenerateChangelogFailedError'; + constructor(msg) { + super(msg); + } +} + +export class UnableToProceedPublishError extends Error { + name = 'UnableToProceedPublishError'; + constructor(msg) { + super(msg); + } +} + +export class YarnError extends Error { + name = 'YarnError'; + constructor(msg) { + super(msg); + } +} + +export class NxError extends Error { + name = 'NxError'; + constructor(msg) { + super(msg); + } +} + +export class GitError extends Error { + name = 'GitError'; + + constructor(msg) { + super(msg); + } +} + +export class CustomScriptError extends Error { + name = 'CustomScriptError'; + + constructor(msg) { + super(msg); + } +} + +export class CrowdinError extends Error { + name = 'CrowdinError'; + constructor(msg) { + super(msg); + } +} + +export class VercelError extends Error { + name = 'VercelError'; + constructor(msg) { + super(msg); + } +} \ No newline at end of file diff --git a/scripts/common/features.mjs b/scripts/common/features.mjs new file mode 100644 index 0000000000..9e916e6ce8 --- /dev/null +++ b/scripts/common/features.mjs @@ -0,0 +1,32 @@ +import { detectChannel } from './github.mjs'; + +/** + * Features configurations + * + * Note 1: Please add to `checkEnvironments` proper values when you add something to this object. + * Note 2: Pass distribution channel as value. + * + */ +const config = { + generateChangelog: ['prod'], + checkGithubRelease: ['prod'], + checkGitTags: ['prod'], + checkNpm: ['prod', 'next'], +}; + +/** + * + * Check a config and returns `true` if should do anything. + * + * @param {*} key + * @returns + */ +export function should(key) { + const channel = detectChannel(); + + if (config[key].includes(channel)) { + return true; + } + + return false; +} diff --git a/scripts/common/git.mjs b/scripts/common/git.mjs new file mode 100644 index 0000000000..4bc764c5d0 --- /dev/null +++ b/scripts/common/git.mjs @@ -0,0 +1,298 @@ +import { execa } from 'execa'; +import { PUBLISH_COMMIT_SUBJECT } from './constants.mjs'; +import { GitError } from './errors.mjs'; +import { detectChannel } from './github.mjs'; +import { generateTagName, workspacePackages } from './utils.mjs'; + +export async function isReleaseTagExistFor(pkg) { + const tag = generateTagName(pkg); + + const result = await execa('git', ['tag', '-l', tag]) + .then((result) => result.stdout) + .catch((err) => { + throw new GitError( + `An error occured on getting tags \n ${err.message} \n ${err.stderr}` + ); + }); + + const isExist = !!result; + return isExist; +} + +/** + * + * @param {import('./typedefs.mjs').Package} pkg + * @returns {Promise} + */ +export async function gitTagFor(pkg) { + const tagExist = await isReleaseTagExistFor(pkg); + + if (tagExist) { + const tagName = generateTagName(pkg); + return tagName; + } + + return null; +} + +/** + * Get git tags for a list of packages + * @deprecated + * + * @param {Array} packages + * @returns {Promise>} + * + */ +export async function gitTagsFor(packages) { + const result = packages.map((pkg) => { + return isReleaseTagExistFor(pkg).then((tagExist) => { + if (tagExist) { + const tagName = generateTagName(pkg); + + return { + package: pkg, + tag: { + tagName, + }, + }; + } + + return { + package: pkg, + tag: null, + }; + }); + }); + + return await Promise.all(result); +} + +// TODO: Check for when there is no tag. +/** + * + * @param {boolean} useTag - if true, we looking up for a git relase tag, if not, we use commit message. + * @returns {Promise} commit hash + */ +export async function getLastReleasedHashId(useTag = false) { + if (useTag) { + const { stdout: hash } = await execa('git', [ + 'rev-list', + '--max-count', + 1, + '--tags', + ]); + return hash.toString(); + } else { + const { stdout: hash } = await execa('git', [ + 'log', + '--grep', + '^chore(release): publish', + '-n', + 1, + '--pretty=format:%H', + ]); + return hash.toString(); + } +} + +/** + * Returns a list of changed packages since an specific commit. + * + * @param {string} since - commit hash + * @returns {Promise} + */ +export async function changed(since) { + const pkgs = await workspacePackages(); + const all = await Promise.all( + pkgs.map((pkg) => { + let command = ['log', `${since}..HEAD`, '--oneline', '--', pkg.location]; + if (!since) { + command = ['log', '--oneline', '--', pkg.location]; + } + + return execa('git', command).then(({ stdout: result }) => { + return { + ...pkg, + changed: !!result, + }; + }); + }) + ); + + // Kepp only changed packages and then clean up the object to remove `changed` property. + return all.filter((pkg) => pkg.changed).map(({ changed, ...pkg }) => pkg); +} + +/** + * Getting changed packages by passing a distribution channel name. + * + * @param {'prod' | 'next'} channel + * @returns {Promise>} + */ +export async function getChangedPackagesFor(channel) { + // Detect last release and what packages has changed since then. + const useTagForDetectLastRelease = channel === 'prod'; + const baseCommit = await getLastReleasedHashId(useTagForDetectLastRelease); + + const changedPkgs = await changed(baseCommit); + + return changedPkgs; +} + +/** + * Tagging and create a publish commit. + * + * @param {import('./typedefs.mjs').Package[]} pkgs + * @param {string} options.subject - Commit subject + * + */ +export async function publishCommitAndTags(pkgs) { + const channel = detectChannel(); + const isTaggingSkipped = channel !== 'prod'; + const subject = `${PUBLISH_COMMIT_SUBJECT}\n\n`; + const tags = pkgs.map(generateTagName); + + const list = tags.map((tag) => `- ${tag}`).join('\n'); + const message = subject + list; + let body = `Affected packages: ${tags.join(',')}`; + + /* + When we are pushing a publish commit into main or next, it triggers a redundant workflow run, + To avoid this, by adding a [skip ci] the workflow run will be skipped. + */ + body += '\n[skip ci]'; + + // Making a publish commit + await execa('git', [ + 'commit', + '-m', + message, + '-m', + body, + // We need to pass no-verify to bypass commitlint. + // NOTE: it will bypass precommit and commit-msg hooks. + '--no-verify', + ]).catch((error) => { + throw new GitError(`git commit failed. \n ${error.stderr}`); + }); + + // Creating annotated tags based on packages + if (!isTaggingSkipped) { + await publishTags(pkgs); + } + + return tags; +} + +export async function publishTags(pkgs) { + const tags = pkgs.map(generateTagName); + + // Creating annotated tags based on packages + await Promise.all( + tags.map((tag) => + execa('git', ['tag', '-a', tag, '-m', tag]).catch((error) => { + throw new GitError(`git tag failed. \n ${error.stderr}`); + }) + ) + ); + + return tags; +} + +export async function addFileToStage(path) { + await execa('git', ['add', path]).catch((e) => { + throw new GitError(`"git add" failed. ${e.stderr}`); + }); +} + +export async function push(options) { + const { setupRemote, branch, remote = 'origin' } = options || {}; + + let pushOptions = []; + if (setupRemote) { + if (!branch) { + throw new CustomScriptError( + `You should also pass branch name as parameter to push. \n ${error.stderr}` + ); + } + + pushOptions = ['--set-upstream', remote, branch]; + } else { + pushOptions = [remote, '--follow-tags', '--no-verify', '--atomic']; + } + + const output = await execa('git', ['push', ...pushOptions]) + .then(({ stdout }) => stdout) + .catch((error) => { + throw new GitError(`git push failed. \n ${error.stderr}`); + }); + + return output; +} + +export async function pull(remote = 'origin') { + const output = await execa('git', ['pull', remote]) + .then(({ stdout }) => stdout) + .catch((error) => { + throw new GitError(`git pull failed. \n ${error.stderr}`); + }); + + return output; +} + +export async function checkout(branch) { + const output = await execa('git', ['checkout', branch]) + .then(({ stdout }) => stdout) + .catch((error) => { + throw new GitError(`git checkout failed. \n ${error.stderr}`); + }); + + return output; +} + +export async function merge(branch, mergeOptions) { + const { mergeStrategy = '' } = mergeOptions; + const output = await execa('git', ['merge', mergeStrategy, branch]) + .then(({ stdout }) => stdout) + .catch((error) => { + throw new GitError(`git merge failed. \n ${error.stderr}`); + }); + + return output; +} + +export async function getLastCommitId() { + const commitId = await execa('git', ['log', '--format=%s', '-n', 1]) + .then(({ stdout }) => stdout) + .catch((e) => { + throw new GitError( + `Getting last commit using git log failed \n ${e.stderr}` + ); + }); + + return commitId; +} + +export async function getLastCommitSubject() { + const commitId = await execa('git', ['log', '--format=%s', '-n', 1]) + .then(({ stdout }) => stdout) + .catch((e) => { + throw new GitError( + `Getting last commit using git log failed \n ${e.stderr}` + ); + }); + + return commitId; +} + +export async function getLastCommitMessage() { + const commitId = await execa('git', ['log', '--format=%B', '-n', 1]) + .then(({ stdout }) => stdout) + .catch((e) => { + throw new GitError( + `Getting last commit using git log failed \n ${e.stderr}` + ); + }); + + return commitId; +} diff --git a/scripts/common/github.mjs b/scripts/common/github.mjs new file mode 100644 index 0000000000..0482e0000d --- /dev/null +++ b/scripts/common/github.mjs @@ -0,0 +1,181 @@ +import { execa } from 'execa'; +import { generateChangelog } from './changelog.mjs'; +import { + GithubCommandError, + GithubCreateReleaseFailedError, + GithubGetReleaseError, + GithubReleaseNotFoundError, +} from './errors.mjs'; +import { should } from './features.mjs'; +import { generateTagName, getEnvWithFallback } from './utils.mjs'; + +/** + * + * @param {import("./typedefs.mjs").Package} pkg + * @returns {Promise} + * + */ +export async function getGithubReleaseFor(pkg) { + const tag = generateTagName(pkg); + + const result = await execa('gh', [ + 'release', + 'view', + tag, + '--json', + 'tagName', + ]).catch((err) => { + if (err.stderr === 'release not found') { + throw new GithubReleaseNotFoundError(tag); + } + throw new GithubGetReleaseError(err.message); + }); + + const release = JSON.parse(result.stdout); + + return release; +} + +/** + * Generate changelog for a package and making a release on Github. + * @param {import('./typedefs.mjs').Package} pkg + */ +export async function makeGithubRelease(pkg) { + const notes = await generateChangelog(pkg, { + saveToFile: false, + }); + const tagName = generateTagName(pkg); + const output = await execa('gh', [ + 'release', + 'create', + tagName, + '--target', + 'main', + '--notes', + notes, + '--verify-tag', + ]) + .then(({ stdout }) => stdout) + .catch((err) => { + throw new GithubCreateReleaseFailedError(err.stdout); + }); + + return output; +} + +/** + * Get a package and try to get a github release with same (tag) name. + * Returns null if any release not found. + * + * @param {import('./typedefs.mjs').Package} pkg + * @returns {Promise} + */ +export async function githubReleaseFor(pkg) { + try { + const release = await getGithubReleaseFor(pkg); + return release.tagName; + } catch (err) { + if (err instanceof GithubReleaseNotFoundError) { + return null; + } + + throw err; + } +} + +/** + * + * @param {PullRequestInfo} pr + * + * @typedef {Object} PullRequestInfo + * @property {string} title PR title + * @property {string} branch your current branch + * @property {string} baseBranch PR will be merge into base branch. + * @property {string} templatePath template path for PR + * + */ +export async function createPullRequest(pr) { + const { title, baseBranch, branch, templatePath } = pr; + + if (!title || !baseBranch || !branch || !templatePath) { + throw new GithubCommandError( + 'Creating pull request can not be proceed without required parameters. \n', + JSON.stringify({ title, baseBranch, branch, templatePath }) + ); + } + + const ghCreateParams = [ + '--title', + title, + '--base', + baseBranch, + '--head', + branch, + '--body-file', + templatePath, + ]; + const output = await execa('gh', ['pr', 'create', ...ghCreateParams]) + .then(({ stdout }) => stdout) + .catch((err) => { + throw new GithubCommandError( + `gh pr command failed. \n ${err.stdout || err} \n` + ); + }); + + return output; +} + +export async function createComment(comment) { + const {commentBody, issueNumber} = comment; + + if (!issueNumber || !commentBody) { + throw new GithubCommandError( + 'Creating comment cannot proceed without required parameters. \n', + JSON.stringify({ issueNumber, commentBody }) + ); + } + + const output = await execa('gh', ['issue', 'comment', issueNumber, '--body', commentBody]) + .then(({ stdout }) => stdout) + .catch((err) => { + throw new GithubCommandError( + `Failed to add comment to issue. \n ${err.stdout || err} \n` + ); + }); + + return output; +} + +export function checkEnvironments() { + const envs = { + NPM_TOKEN: !!process.env.NPM_TOKEN, + REF: !!process.env.REF, + GH_TOKEN: !!process.env.GH_TOKEN, + VERCEL_ORG_ID: !!process.env.VERCEL_ORG_ID, + VERCEL_TOKEN: !!process.env.VERCEL_TOKEN, + VERCEL_PROJECT_WALLETS: !!process.env.VERCEL_PROJECT_WALLETS, + VERCEL_PROJECT_Q: !!process.env.VERCEL_PROJECT_Q, + VERCEL_PROJECT_WALLET_ADAPTER: !!process.env.VERCEL_PROJECT_WALLET_ADAPTER, + VERCEL_PROJECT_WIDGET_CONFIG: !!process.env.VERCEL_PROJECT_WIDGET_CONFIG, + VERCEL_PROJECT_WIDGET_APP: !!process.env.VERCEL_PROJECT_WIDGET_APP, + VERCEL_PROJECT_STORYBOOK: !!process.env.VERCEL_PROJECT_STORYBOOK, + }; + + const features = [ + { name: 'check github release', value: should('checkGithubRelease') }, + { name: 'check git tags', value: should('checkGitTags') }, + { name: 'check versions on npm', value: should('checkNpm') }, + ]; + + console.log('Environments Variables:'); + console.table(envs); + console.log('Features:'); + console.table(features); +} + +export function detectChannel() { + if (getEnvWithFallback('REF') === 'refs/heads/main') { + return 'prod'; + } + return 'next'; +} diff --git a/scripts/common/graph/helpers.mjs b/scripts/common/graph/helpers.mjs new file mode 100644 index 0000000000..a3e3a1b4a5 --- /dev/null +++ b/scripts/common/graph/helpers.mjs @@ -0,0 +1,107 @@ +import { readFile } from 'fs/promises'; + +export const ROOT_KEY = '__ROOT__'; + +export async function importJson(filename) { + const json = JSON.parse(await readFile(new URL(filename, import.meta.url))); + + return json; +} + +export function removeEdgeTo(targetNode, graph) { + for (const node of graph.keys()) { + graph.set( + node, + graph.get(node).filter((edge) => edge !== targetNode) + ); + } +} + +function add(data, list) { + const { node, indeg, outdeg } = data; + + if (!list.has(node)) { + list.set(node, { + indeg: [], + outdeg: [], + }); + } + + const recored = list.get(node); + if (indeg) { + recored.indeg.push(...indeg); + } + if (outdeg) { + recored.outdeg.push(...outdeg); + } + + return list; +} + +export function normalizeNXDependencies(deps) { + const output = new Map(); + Object.keys(deps).forEach((node) => { + output.set( + node, + deps[node].map((depNode) => depNode.target) + ); + }); + return output; +} +/* +Output: +'@rango-test/signer-evm' => { indeg: 18, outdeg: 0 }, +*/ +export function detectEdges(nodesWithDependecies) { + const output = new Map(); + nodesWithDependecies.forEach((targetNodes, sourceNode) => { + const data = { + node: sourceNode, + outdeg: targetNodes, + }; + + // Add/update source target + add(data, output); + + // Update target node + if (nodesWithDependecies.get(sourceNode).length > 0) { + targetNodes.forEach((targetNode) => { + add({ node: targetNode, indeg: [sourceNode] }, output); + }); + } + }); + + return output; +} + +export function nxToGraph(nx, graph) { + const nodes = Object.keys(nx.graph.nodes); + nodes.forEach((node) => graph.addNode(node)); + + const edges = detectEdges(normalizeNXDependencies(nx.graph.dependencies)); + + edges.forEach((sourceNodeValue, sourceNode) => { + if (sourceNodeValue.outdeg.length > 0) { + sourceNodeValue.outdeg.forEach((targetNode) => { + graph.addEdge(sourceNode, targetNode); + }); + } + + // If there is no indeg, it means it's a root package. + if (sourceNodeValue.indeg.length === 0) { + graph.addEdge(ROOT_KEY, sourceNode); + } + }); + + return { + edgesCount: edges.size, + nodesCount: nodes.length, + }; +} + +export function bubbleUp(result, nodesWithEdges, targetNode) { + nodesWithEdges.get(targetNode).indeg.forEach((parentNode) => { + result.add(parentNode); + bubbleUp(result, nodesWithEdges, parentNode); + }); +} diff --git a/scripts/common/graph/index.mjs b/scripts/common/graph/index.mjs new file mode 100644 index 0000000000..fa53e599b8 --- /dev/null +++ b/scripts/common/graph/index.mjs @@ -0,0 +1,88 @@ +import { bubbleUp, detectEdges, removeEdgeTo, ROOT_KEY } from './helpers.mjs'; + +class Graph { + constructor() { + this.nodes = new Map(); + this.addNode(ROOT_KEY); + } + + addNode(node) { + this.nodes.set(node, []); + } + + addEdge(source, destination) { + this.nodes.get(source).push(destination); + } + + onlyAffected(list) { + const finalNodes = new Set(); + const edges = detectEdges(this.nodes); + + list.forEach((affectedNode) => { + finalNodes.add(affectedNode); + bubbleUp(finalNodes, edges, affectedNode); + }); + + const nextNodes = new Map(); + this.nodes.forEach((edges, node) => { + if (finalNodes.has(node)) { + nextNodes.set( + node, + edges.filter((dependentOnNode) => { + return finalNodes.has(dependentOnNode); + }), + ); + } + }); + + this.nodes = nextNodes; + } + + sort() { + const sortedList = new Set(); + + const tempGraph = structuredClone(this.nodes); + while (tempGraph.size > 1) { + this.kindaDFS(ROOT_KEY, sortedList, tempGraph); + } + + return sortedList; + } + + kindaDFS(startNode, sortedList, graph) { + const visitedNodes = new Map(); + this.dfs(startNode, visitedNodes, graph); + + visitedNodes.forEach((value, node) => { + if (value.outdeg === 0) { + sortedList.add(node); + graph.delete(node); + removeEdgeTo(node, graph); + } + }); + } + + dfs(node, visitedNodes, graph) { + const neighbors = graph.get(node); + visitedNodes.set(node, { + outdeg: neighbors.length, + }); + for (const neighbor of neighbors) { + if (!visitedNodes.has(neighbor)) { + this.dfs(neighbor, visitedNodes, graph); + } + } + } + + toString() { + let output = ''; + for (const [node, neighbors] of this.nodes) { + let neighborsStr = neighbors.length > 0 ? neighbors.join(', ') : 'None'; + output += `${node} -> ${neighborsStr}\n`; + } + + return output; + } +} + +export { Graph }; diff --git a/scripts/common/npm.mjs b/scripts/common/npm.mjs new file mode 100644 index 0000000000..842b5ba0c9 --- /dev/null +++ b/scripts/common/npm.mjs @@ -0,0 +1,218 @@ +import fs from 'node:fs/promises'; +import { $, execa } from 'execa'; +import { join } from 'node:path'; +import { printDirname } from '../common/utils.mjs'; +import { compareSemVer } from 'semver-parser'; +import fetch, { Headers } from 'node-fetch'; +import { + NpmGetPackageError, + NpmPackageNotFoundError, + NpmPublishError, + YarnError, +} from './errors.mjs'; +import { detectChannel } from './github.mjs'; + +const cwd = join(printDirname(), '..', '..'); + +/** + * Publish a package using `yarn publish` + * + * @param {import('../common/utils.mjs').Package} pkg + */ +export async function publishOnNpm(pkg) { + const channel = detectChannel(); + const distTag = channel === 'prod' ? 'latest' : channel; + const output = await execa('yarn', [ + 'publish', + pkg.location, + '--tag', + distTag, + ]) + .then(({ stdout }) => stdout) + .catch((error) => { + throw new NpmPublishError(error.stderr); + }); + + return output; +} + +/** + * Accept a package and send a request to npm registry for getting information. + * + * @param {import('./typedefs.mjs').Package} pkg + * @returns {Promise} + */ +export async function getNpmPackage(pkg) { + const packageName = pkg.name; + const headers = new Headers(); + // This is to use less bandwidth unless we really need to get the full response. + // See https://github.com/npm/npm-registry-client#request + headers.append( + 'Accept', + 'application/vnd.npm.install-v1+json; q=1.0, application/json; q=0.8, */*' + ); + const response = await fetch( + `https://registry.npmjs.org/${escapeName(packageName)}`, + { + headers, + } + ).catch((err) => { + const msg = + err.message || 'An error has occured when trying to get npm package.'; + throw new NpmGetPackageError(msg); + }); + + const body = await response.json(); + + // A new package which never has been published on npm. + if (response.status === 404) { + throw new NpmPackageNotFoundError(packageName); + } else if (response.status > 300) { + const msg = `Package: ${packageName}, Status: ${response.status}, Body: ${body}`; + throw new NpmGetPackageError(msg); + } + + const versions = { + next: body['dist-tags'].next || null, + prod: body['dist-tags'].latest || null, + }; + + return versions; +} + +/** + * Getting version from NPM + * returns null if found anything. + * + * @param {import('./typedefs.mjs').Package} pkg + * @returns {Promise} + */ +export async function npmVersionFor(pkg) { + try { + const npmVersions = await getNpmPackage(pkg); + return npmVersions; + } catch (err) { + if (err instanceof NpmPackageNotFoundError) { + return null; + } + + throw err; + } +} + +export async function packagePath(project) { + const { stdout: info } = await $`yarn workspaces info`.catch((error) => { + throw new YarnError(`'yarn workspaces info' failed. \n ${error.stderr}`); + }); + const workspaces = JSON.parse(info); + const pkg = workspaces[project]; + const path = pkg.location; + + return join(cwd, path); +} + +export async function readPackageJson(project) { + const pkgJsonPath = join(await packagePath(project), 'package.json'); + const pkgJsonFile = await fs.readFile(pkgJsonPath, { encoding: 'utf8' }); + const pkgJson = JSON.parse(pkgJsonFile); + return { + content: pkgJson, + update: (newContent) => { + return fs.writeFile(pkgJsonPath, JSON.stringify(newContent, null, 2)); + }, + }; +} + +async function requestNpmPackageInfo(name) { + const headers = new Headers(); + // This is to use less bandwidth unless we really need to get the full response. + // See https://github.com/npm/npm-registry-client#request + headers.append( + 'Accept', + 'application/vnd.npm.install-v1+json; q=1.0, application/json; q=0.8, */*' + ); + const res = await fetch(`https://registry.npmjs.org/${escapeName(name)}`, { + headers, + }); + const body = await res.json(); + + return { + status: res.status, + body, + }; +} + +export async function packageVersionOnNPM(project, dist) { + const { content, update } = await readPackageJson(project); + const local_version = content.version; + + if (content.private) { + console.log( + `::notice::considering npm_version same as local_version because it is a private package.` + ); + return { + npm_version: local_version, + local_version, + }; + } + + // Continue if it's not a private package. + + const { status, body } = await requestNpmPackageInfo(project).catch((e) => { + console.log(`::error::npm_request_failed: ${e}`); + throw new Error(e); + }); + + // A new package which never has been published on npm. + if (status === 404) { + console.log( + `::notice::considering npm_version same as local_version because it is a new package.` + ); + return { + npm_version: local_version, + local_version, + }; + } + + const versions = body['dist-tags']; + + // Fallback to local version, if package isn't published on NPM yet. + let npm_version = versions[dist] || local_version; + + // We should check if `latest` version is greater than `dist` version (next), use latest version instead. + // Because it will get stuck on a version forever. + console.log(`::debug::${dist} ${JSON.stringify(versions)}`); + if (dist !== 'latest') { + const latest_version = versions['latest']; + const dist_version = versions[dist]; + + console.log( + `::debug::latest: ${latest_version}, dist: ${dist_version}, result: ${compareSemVer( + dist_version, + latest_version + )} cond: ${compareSemVer(dist_version, latest_version) > 0} ` + ); + // compareSemVer returns 1 if dist_version is greater than latest_version. + if (compareSemVer(dist_version, latest_version) > 0) { + npm_version = dist_version; + } else { + console.log( + `[info] latest version: ${latest_version}, ${dist} version: ${dist_version}. we use latest version because it's greater that ${dist_version}` + ); + npm_version = latest_version; + } + } + + // update pkg json + content.version = npm_version; + await update(content); + return { + npm_version, + local_version, + }; +} + +function escapeName(name) { + // scoped packages contain slashes and the npm registry expects them to be escaped + return name.replace('/', '%2f'); +} diff --git a/scripts/common/repository.mjs b/scripts/common/repository.mjs new file mode 100644 index 0000000000..27232c3c16 --- /dev/null +++ b/scripts/common/repository.mjs @@ -0,0 +1,83 @@ +import { execa } from 'execa'; +import { join } from 'path'; +import { NxError } from './errors.mjs'; +import { getChangedPackagesFor } from './git.mjs'; +import { detectChannel } from './github.mjs'; +import { importJson, nxToGraph } from './graph/helpers.mjs'; +import { Graph } from './graph/index.mjs'; +import { packageNamesToPackagesWithInfo, printDirname } from './utils.mjs'; + +const root = join(printDirname(), '..', '..'); + +/** + * + * When a packages has been updated (source code), we will check what packages is dependent on that. + * + * @param {Array} changedPkgs + * @returns + */ +export async function analyzeChangesEffects(changedPkgs) { + const nxGraph = await exportNx(); + const graph = new Graph(); + const { nodesCount, edgesCount } = nxToGraph(nxGraph, graph); + graph.onlyAffected(changedPkgs.map((pkg) => pkg.name)); + const sortedList = graph.sort(); + const sortedPackagesToPublish = await packageNamesToPackagesWithInfo([ + ...sortedList, + ]); + + console.table([ + { + name: 'Affected pacakges', + value: sortedPackagesToPublish.length, + }, + { + name: 'Nodes', + value: nodesCount, + }, + { + name: 'edges', + value: edgesCount, + }, + { + name: 'Are we good?', + // Note: these two numbers should be equal. + value: nodesCount === edgesCount ? 'yes' : 'no', + }, + ]); + + console.log( + 'Ordering:', + sortedPackagesToPublish.map((pkg) => pkg.name).join(',') + ); + return sortedPackagesToPublish; +} + +export async function exportNx() { + const filename = '__output__.json'; + const filepath = join(root, filename); + await execa('yarn', ['nx', 'graph', '--file', filename]).catch((error) => { + throw new NxError(`Creating graph file failed. \n ${error.stderr}`); + }); + const nxGraph = await importJson(filepath); + await execa('rm', ['-f', filename]).catch((error) => { + throw new NxError( + `Removing temporary ${filename} failed. \n ${error.stderr}` + ); + }); + return nxGraph; +} + +/** + * NOTE: For publish, we only consider `private: false` packages (client will not be included) + * @returns {Promise} + */ +export async function getAffectedPackages() { + const channel = detectChannel(); + // the source code for these packages have been updated. + const onlyChangedPackages = await getChangedPackagesFor(channel); + // changes will affect other packages as well, this is the full list. + const allAffectedPackages = await analyzeChangesEffects(onlyChangedPackages); + + return allAffectedPackages; +} diff --git a/scripts/common/typedefs.mjs b/scripts/common/typedefs.mjs new file mode 100644 index 0000000000..5a4a00cf9d --- /dev/null +++ b/scripts/common/typedefs.mjs @@ -0,0 +1,49 @@ +/** + * Packages that has been changed since a specific commit/tag + * + * @typedef {Object} Package + * @property {string} name - The name of the package. + * @property {string} location - The location of the package. + * @property {string} version - The version of the package. + * @property {boolean} private - Whether the package is private or not. + */ + +/** + * @typedef {Object} Release + * @property {string} tagName - The name of the package followed by version. + */ + +/** + * @typedef {Object} Tag + * @property {string} tagName - The name of the package followed by version. + */ + +/** + * @typedef {Object} PackageAndRelease + * @property {Package} package + * @property {Release | null} release + */ + +/** + * @typedef {Object} PackageAndTag + * @property {Package} package + * @property {Tag | null} tag + */ + +/** + * @typedef {Object} NpmVersions + * @property {string} next - last next release version + * @property {string} prod - last prod release version + */ + +/** + * @typedef {Object} PackageAndNpmVersions + * @property {Package} package + * @property {NpmVersions | null} npm + */ + +/** + * @typedef {Object} IncreaseVersionResult + * @property {string} current - current version + * @property {string} next - increased version + */ diff --git a/scripts/common/utils.mjs b/scripts/common/utils.mjs index 74e2bfbea6..257054482a 100644 --- a/scripts/common/utils.mjs +++ b/scripts/common/utils.mjs @@ -1,8 +1,111 @@ import path from 'path'; import { fileURLToPath } from 'url'; +import { readFileSync } from 'fs'; +import { join } from 'path'; +import { execa } from 'execa'; +import process from 'node:process'; +import { NPM_ORG_NAME } from './constants.mjs'; + +const root = join(printDirname(), '..', '..'); export function printDirname() { const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); return __dirname; } + +/** + * Getting workspace members using Yarn. + * + * @returns {Promise} + */ +export async function workspacePackages() { + // --json flag guarantees that whether it is run with yarn or node, the output always has a consistent result. + const { stdout } = await execa('yarn', ['workspaces', '--json', 'info']); + const result = JSON.parse(JSON.parse(stdout).data); + const packagesName = Object.keys(result); + const output = packagesName.map((name) => { + const pkgJson = packageJson(result[name].location); + return { + name, + location: result[name].location, + version: pkgJson.version, + private: pkgJson.private || false, + }; + }); + return output; +} + +export function convertPackageLocationToFullPath(pkgLocation) { + const fullPath = join(root, pkgLocation); + return fullPath; +} + +/** + * Getting a package json and deserialize it to JS object. + * @param {string} location + * @returns {Object} + */ +export function packageJson(location) { + const pkgPath = convertPackageLocationToFullPath(location); + const fullPath = join(pkgPath, 'package.json'); + const file = readFileSync(fullPath); + return JSON.parse(file); +} + +/** + * Getting a name and returns info related to that package name. + * + * @param {string[]} names Package names for getting information about. + * @returns {Promise} + */ +export async function packageNamesToPackagesWithInfo(names) { + const allPackages = await workspacePackages(); + const packages = []; + names.forEach((pkgName) => { + const packageInWorkspace = allPackages.find((pkg) => pkg.name === pkgName); + if (!!packageInWorkspace) { + packages.push(packageInWorkspace); + } + }); + + return packages; +} + +/** + * Getting a package name (e.g. @hello-wrold/a-b) and get the name of pkg (e.g. a-b). + * + * @param {string} name + */ +export function packageNameWithoutScope(name) { + return name.replace(/@.+\//, ''); +} + +/** + * Note: we are adding a fallback, to make sure predefiend VERCEL_PACKAGES always will be true. + * + * @param {string} name enviroment variable name + * @returns {string} + */ +export function getEnvWithFallback(name) { + return process.env[name] || 'NOT SET'; +} + +/** + * + * @param {import('./typedefs.mjs').Package} pkg + * @returns + */ +export function generateTagName(pkg) { + return `${packageNameWithoutScope(pkg.name)}@${pkg.version}`; +} + +/** + * Opposite of `generateTagName` + * + * @param {string} pkgNameWithoutScope + * @returns + */ +export function tagNameToPkgName(pkgNameWithoutScope) { + return `${NPM_ORG_NAME}/${pkgNameWithoutScope}`; +} diff --git a/scripts/common/version.mjs b/scripts/common/version.mjs new file mode 100644 index 0000000000..9a82610d25 --- /dev/null +++ b/scripts/common/version.mjs @@ -0,0 +1,134 @@ +import { execa } from 'execa'; +import { IncreaseVersionFailedError } from './errors.mjs'; +import conventionanRecommendBump from 'conventional-recommended-bump'; +import { packageNameWithoutScope } from './utils.mjs'; + +/** + * + * @param {import('./typedefs.mjs').Package} pkg + * @returns {Promise} Returns package with updated version + */ +export async function increaseVersionForNext(pkg) { + /** @type {import('./typedefs.mjs').IncreaseVersionResult} */ + const versions = await execa('yarn', [ + 'workspace', + pkg.name, + 'version', + '--preid=next', + '--prerelease', + '--no-git-tag-version', + '--json', + ]) + .then((result) => result.stdout) + .then((output) => { + const versions = parseYarnVersionResult(output); + + if (!versions.current && !versions.next) { + throw new IncreaseVersionFailedError( + `Couldn't extract versions from logs \n ${logs.join('\n')}` + ); + } + return versions; + }) + .catch((err) => { + if (err instanceof IncreaseVersionFailedError) throw err; + + throw new IncreaseVersionFailedError(err.stderr); + }); + + return { + ...pkg, + version: versions.next, + }; +} + +/** + * + * @param {import('./typedefs.mjs').Package} pkg + * @returns {Promise} Returns package with updated version + */ +export async function increaseVersionForProd(pkg) { + const recommendation = await recommendBump(pkg); + const releaseType = recommendation.releaseType; + + /** @type {import('./typedefs.mjs').IncreaseVersionResult} */ + const versions = await execa('yarn', [ + 'workspace', + pkg.name, + 'version', + `--${releaseType}`, + '--no-git-tag-version', + '--json', + ]) + .then((result) => result.stdout) + .then((output) => { + const versions = parseYarnVersionResult(output); + + if (!versions.current && !versions.next) { + throw new IncreaseVersionFailedError( + `Couldn't extract versions from logs \n ${logs.join('\n')}` + ); + } + return versions; + }) + .catch((err) => { + if (err instanceof IncreaseVersionFailedError) throw err; + + throw new IncreaseVersionFailedError(err.stderr); + }); + + return { + ...pkg, + version: versions.next, + }; +} + +/** + * + * Recommend next version based on Angular conventional commits + * + * @param {import('./typedefs.mjs').Package} pkg package + * @return {Promise<{level: number,reason: string, releaseType: 'patch' | 'minor' | 'major',}>} + */ +export async function recommendBump(pkg) { + const tagName = packageNameWithoutScope(pkg.name); + return new Promise((resolve, reject) => { + conventionanRecommendBump( + { + preset: 'angular', + lernaPackage: tagName, + }, + (error, recommendation) => { + if (error) { + reject(error); + } else { + resolve(recommendation); + } + } + ); + }); +} + +function parseYarnVersionResult(output) { + const logs = output.split('\n').map((jsonString) => JSON.parse(jsonString)); + + const versions = logs.reduce( + (prev, log) => { + if (log.data.startsWith('Current version:')) { + return { + ...prev, + current: log.data.replace('Current version: ', ''), + }; + } + if (log.data.startsWith('New version:')) { + return { + ...prev, + next: log.data.replace('New version: ', ''), + }; + } + }, + { current: null, next: null } + ); + + return versions; +} diff --git a/scripts/crowdin/command.mjs b/scripts/crowdin/command.mjs new file mode 100644 index 0000000000..1e939194d8 --- /dev/null +++ b/scripts/crowdin/command.mjs @@ -0,0 +1,53 @@ +import { PROJECT_ID, TOKEN } from "./constants.mjs"; +import { CrowdinError } from "../common/errors.mjs"; +import { + checkPreTranslateStatus, + getLanguageIds, + getMachineTranslationEngineID, + getSourceFileId, + sendPreTranslateRequest +} from "./pretranslate.mjs"; + + +const preTranslationOption = { + method: 'mt', + autoApproveOption: 'all', + duplicateTranslations: false, + skipApprovedTranslations: true, + translateUntranslatedOnly: true, + translateWithPerfectMatchOnly: false, +}; + + +async function run() { + console.log('🔨 Start pre-translation...'); + + if(!PROJECT_ID || !TOKEN){ + throw new CrowdinError('environments are not set correctly'); + } + + console.log('[1/5]', 'Get source file id'); + const sourceFileId = await getSourceFileId(); + + console.log('[2/5]', 'Get target languages ids'); + const languageIds = await getLanguageIds(); + + console.log('[3/5]', 'Get machine translation engine id'); + const engineId = await getMachineTranslationEngineID(); + preTranslationOption.engineId = engineId ; + + console.log('[4/5]', 'Send pre-translate to crowdin'); + const preTranslationId = await sendPreTranslateRequest({ sourceFileId, languageIds, preTranslationOption }); + + console.log('[5/5]', 'Check pre-translate status:',preTranslationId); + const status = await checkPreTranslateStatus(preTranslationId); + + if (status === 'finished'){ + console.log('✅ Pre-translation finished!'); + } +} + +run().catch((e) => { + console.error(e); + process.exit(1); +}); diff --git a/scripts/crowdin/constants.mjs b/scripts/crowdin/constants.mjs new file mode 100644 index 0000000000..dac7aee19b --- /dev/null +++ b/scripts/crowdin/constants.mjs @@ -0,0 +1,11 @@ +export const PROJECT_ID = process.env.CROWDIN_PROJECT_ID; +export const TOKEN = process.env.CROWDIN_PERSONAL_TOKEN; + +export const BASE_URL = `https://api.crowdin.com/api/v2`; +export const PROJECT_API = `${BASE_URL}/projects/${PROJECT_ID}`; +export const PRETRANSLATE_API = `${PROJECT_API}/pre-translations` +export const FILE_API = `${PROJECT_API}/files` +export const MACHINE_TRANSLATE_API = `${BASE_URL}/mts`; + +export const REQUEST_INTERVAL_TIMEOUT = 10_000; +export const MAXIMUM_PRETRANSLATION_STATUS_CHECK = 20; \ No newline at end of file diff --git a/scripts/crowdin/pretranslate.mjs b/scripts/crowdin/pretranslate.mjs new file mode 100644 index 0000000000..bfb9343bc7 --- /dev/null +++ b/scripts/crowdin/pretranslate.mjs @@ -0,0 +1,63 @@ +import { CrowdinError } from "../common/errors.mjs"; +import { fetchDataWithAuthorization } from "./utils.mjs"; + +import { + MAXIMUM_PRETRANSLATION_STATUS_CHECK, + PRETRANSLATE_API, + REQUEST_INTERVAL_TIMEOUT, + FILE_API, + MACHINE_TRANSLATE_API, + PROJECT_API, +} from "./constants.mjs"; + + +export const getMachineTranslationEngineID = async () => { + const responseData = await fetchDataWithAuthorization(MACHINE_TRANSLATE_API); + + if (!responseData.data || !responseData.data.length) { + throw new CrowdinError('No data received for machine translation'); + } + const data = responseData.data; + const googleMachine = data.find(item => item.data.type === 'google'); + return googleMachine ? googleMachine.data.id : data[0].data.id; +} + +export const getLanguageIds = async () => { + const responseData = await fetchDataWithAuthorization(PROJECT_API); + return responseData.data.targetLanguageIds; +}; + +export const getSourceFileId = async () => { + const responseData = await fetchDataWithAuthorization(FILE_API); + if (!responseData.data || !responseData.data.length) { + throw new CrowdinError('No data received for source file id'); + } + return responseData.data[0].data.id; +}; + +export const sendPreTranslateRequest = async ({ sourceFileId, languageIds, preTranslationOption }) => { + const responseData = await fetchDataWithAuthorization(PRETRANSLATE_API, 'POST', { + ...preTranslationOption, + fileIds: [sourceFileId], + languageIds, + }); + return responseData.data.identifier; +}; + +export const checkPreTranslateStatus = async (preTranslationId) => { + const maxAttempts = MAXIMUM_PRETRANSLATION_STATUS_CHECK; + let attempt = 0; + const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); + while (attempt < maxAttempts) { + const responseData = await fetchDataWithAuthorization(`${PRETRANSLATE_API}/${preTranslationId}`); + const status = responseData.data.status; + if (status === 'finished') { + return status; + } else { + console.log(`Pre-translation status: ${status}. Retrying in 10 seconds...`); + await delay(REQUEST_INTERVAL_TIMEOUT); + attempt++; + } + } + throw new CrowdinError('Timeout: Pre-translation did not succeed within the specified time.'); +}; \ No newline at end of file diff --git a/scripts/crowdin/utils.mjs b/scripts/crowdin/utils.mjs new file mode 100644 index 0000000000..07121e8d67 --- /dev/null +++ b/scripts/crowdin/utils.mjs @@ -0,0 +1,25 @@ +import {TOKEN } from "./constants.mjs"; +import { CrowdinError } from "../common/errors.mjs"; + +// Reusable function to handle fetch requests with authorization headers +export const fetchDataWithAuthorization = async (url, method = 'GET', body = null) => { + const options = { + method, + headers: { + Authorization: `Bearer ${TOKEN}`, + 'Content-Type': 'application/json', + }, + }; + + if (body) { + options.body = JSON.stringify(body); + } + + const response = await fetch(url, options); + + if (!response.ok) { + throw new CrowdinError(`Failed to fetch data from ${url}. Status: ${response.status}`); + } + + return await response.json(); +}; diff --git a/scripts/deploy/command.mjs b/scripts/deploy/command.mjs new file mode 100755 index 0000000000..1e7e697eb3 --- /dev/null +++ b/scripts/deploy/command.mjs @@ -0,0 +1,35 @@ +#!/usr/bin/env node +'use strict'; +import process from 'node:process'; +import { build } from '../publish/build.mjs'; +import { logAsSection } from '../publish/utils.mjs'; +import { + deployProjectsToVercel, + getClientsListToBeDeployed, +} from './utils.mjs'; + +// TODO: Working directory should be empty. +async function run() { + const listPackagesToBeDeployed = await getClientsListToBeDeployed(); + logAsSection('[x] Check Environment'); + + await build(listPackagesToBeDeployed).catch((e) => { + console.log( + '[-] BUILD FAILED. Ignore it to workflow run the rest of tasks.' + ); + throw e; + }); + logAsSection('[x] Build for VERCEL'); + await deployProjectsToVercel(listPackagesToBeDeployed).catch((e) => { + console.log( + '[-] DEPLOY FAILED. Ignore it to workflow run the rest of tasks.' + ); + throw e; + }); + logAsSection('[x] Deploy to VERCEL'); +} + +run().catch((e) => { + console.error(e); + process.exit(1); +}); diff --git a/scripts/deploy/config.mjs b/scripts/deploy/config.mjs new file mode 100644 index 0000000000..be4c0c880d --- /dev/null +++ b/scripts/deploy/config.mjs @@ -0,0 +1,21 @@ +import { getEnvWithFallback } from '../common/utils.mjs'; +import process from 'node:process'; + +const scope = `@rango-dev`; +export const VERCEL_ORG_ID = process.env.VERCEL_ORG_ID; +export const VERCEL_TOKEN = process.env.VERCEL_TOKEN; +export const ENABLE_PREVIEW_DEPLOY = process.env.ENABLE_PREVIEW_DEPLOY; +export const EXCLUDED_PACKAGES = ['@rango-dev/widget-iframe']; + +export const VERCEL_PACKAGES = { + [`${scope}/wallets-demo`]: getEnvWithFallback('VERCEL_PROJECT_WALLETS'), + [`${scope}/queue-manager-demo`]: getEnvWithFallback('VERCEL_PROJECT_Q'), + [`${scope}/wallets-adapter-demo`]: getEnvWithFallback( + 'VERCEL_PROJECT_WALLET_ADAPTER' + ), + [`${scope}/widget-playground`]: getEnvWithFallback( + 'VERCEL_PROJECT_WIDGET_CONFIG' + ), + [`${scope}/widget-app`]: getEnvWithFallback('VERCEL_PROJECT_WIDGET_APP'), + [`${scope}/storybook`]: getEnvWithFallback('VERCEL_PROJECT_STORYBOOK'), +}; diff --git a/scripts/deploy/utils.mjs b/scripts/deploy/utils.mjs new file mode 100644 index 0000000000..4165c51823 --- /dev/null +++ b/scripts/deploy/utils.mjs @@ -0,0 +1,248 @@ +import { execa } from 'execa'; +import { cp, readFile, writeFile } from 'node:fs/promises'; +import { detectChannel } from '../common/github.mjs'; +import { + ENABLE_PREVIEW_DEPLOY, + EXCLUDED_PACKAGES, + VERCEL_ORG_ID, + VERCEL_PACKAGES, + VERCEL_TOKEN, +} from './config.mjs'; +import * as actionCore from '@actions/core'; +import { VercelError } from '../common/errors.mjs'; +import { + convertPackageLocationToFullPath, + packageJson, + packageNameWithoutScope, + workspacePackages, +} from '../common/utils.mjs'; +import { getTransformedRoutes } from '@vercel/routing-utils'; +import { dirname, join } from 'node:path'; +import { mkdir } from 'node:fs/promises'; + +import { fileURLToPath } from 'node:url'; + +export function getVercelProjectId(packageName) { + return VERCEL_PACKAGES[packageName]; +} + +export async function deployProjectsToVercel(pkgs) { + await Promise.all(pkgs.map((pkg) => deploySingleProjectToVercel(pkg))); +} +export async function deploySingleProjectToVercel(pkg) { + const deployTo = detectChannel() === 'prod' ? 'production' : 'preview'; + + const env = { + VERCEL_ORG_ID: VERCEL_ORG_ID, + VERCEL_PROJECT_ID: getVercelProjectId(pkg.name), + }; + + if (!env.VERCEL_PROJECT_ID) { + console.log(`::warning::Couldn't find PROJECT_ID env for ${pkg.name}`); + } + + console.log(`start deploying ${pkg.name} (environment: ${deployTo})...`); + + await execa( + 'vercel', + [ + 'pull', + '--cwd', + pkg.location, + '--environment', + deployTo, + '--token', + VERCEL_TOKEN, + '--yes', + ], + { env } + ); + + const currentDir = dirname(fileURLToPath(import.meta.url)); + const configPath = join(currentDir, 'vercel.json'); + await makeOutputFolderForBuildOutputApi(pkg.location, configPath); + + const vercelResult = await execa( + 'vercel', + [pkg.location, '--prebuilt', '--token', VERCEL_TOKEN], + { env } + ) + .then((result) => result.stdout) + .catch((err) => { + throw new VercelError( + `An error occurred on deploy ${pkg.name} package \n\n command: vercel ${pkg.location} --prebuilt \n\n message: \n ${err.message} \n\n stderr:\n ${err.stderr} \n\n stack: ${err.stack}` + ); + }); + + // Run tail -1 on the stdout to get the last line, because `vercel` command returns the URL in the last line. + const urlPreview = await execa('tail', ['-1'], { input: vercelResult }) + .then((result) => result.stdout) + .catch((err) => { + throw new VercelError( + `An error occurred on get url preview for ${pkg.name} package \n\n command: tail -1 \n\n message: \n ${err.message} \n\n stderr:\n ${err.stderr}` + ); + }); + + // set package name and url preview to github output for use in workflow + const tagName = packageNameWithoutScope(pkg.name); + actionCore.setOutput(`${tagName}-url`, urlPreview); + + console.log(`${tagName}-url:`, urlPreview); + console.log(`${pkg.name} deployed.`); +} + +export function groupPackagesForDeploy(packages) { + const output = { + npm: [], + vercel: [], + }; + + packages.forEach((pkg) => { + if (!!getVercelProjectId(pkg.name)) { + output.vercel.push(pkg); + } else if (!pkg.private) { + // If getVercelProjectId returns undefined, it's possible to be added as npm package + // So here we are making sure it's not a private package and can be published using npm + output.npm.push(pkg); + } + }); + + return output; +} + +export async function getClientsListToBeDeployed() { + /* + Deploys packages based on the state of the `ENABLE_PREVIEW_DEPLOY` environment variable. + if ENABLE_PREVIEW_DEPLOY is true, only packages that has project id in workflow environments will be deployed. + else private packages will be deployed. + */ + + // Detect last release and what packages has changed since then. + const packages = await workspacePackages(); + const listPackagesToBeDeployed = packages.filter((pkg) => { + if (EXCLUDED_PACKAGES.includes(pkg.name)) return false; + + if (ENABLE_PREVIEW_DEPLOY) { + const hasProjectId = + getVercelProjectId(pkg.name) && + getVercelProjectId(pkg.name) !== 'NOT SET'; + return pkg.private && hasProjectId; + } else { + return pkg.private; + } + }); + + if (ENABLE_PREVIEW_DEPLOY) { + console.log('preview deployment is enabled.'); + console.log( + 'these packages will be deployed:', + listPackagesToBeDeployed.map((pkg) => pkg.name).join(', ') + ); + console.log( + 'note: if you need add more packages to be deployed, first you need to add vercel project id to workflow environments then follow documentation there.' + ); + } else { + console.log('preview deployment is disabled.'); + console.log( + 'these packages will be deployed:', + listPackagesToBeDeployed.map((pkg) => pkg.name).join(', ') + ); + } + + return listPackagesToBeDeployed; +} + +/** + * + * Reading a vercel.json file and convert into `Build Output API` compatible format. + * And also adding some more configs in addition to what exists in `vercel.json`. + * + * References: + * https://vercel.com/docs/build-output-api/v3/features + * https://vercel.com/docs/projects/project-configuration + * + * @param {Path} configPath + */ +export async function getVercelJsonAndMakeBuildOutputApi(configPath) { + const vercelJson = await readFile(configPath); + const parsedVercelJson = JSON.parse(vercelJson); + + const supportedConfigs = ['rewrites']; + const unsupportedKeys = Object.keys(parsedVercelJson).filter( + (key) => !supportedConfigs.includes(key) + ); + if (unsupportedKeys.length > 0) { + throw new Error( + "You've used unsupported config in vercel.json. Please make sure you've implemented it first. Supported configs:" + + supportedConfigs.join(',') + ); + } + const configJsonRewrites = parsedVercelJson.rewrites; + const routes = getTransformedRoutes({ + rewrites: configJsonRewrites, + }); + + if (routes.error) { + throw new Error( + `An error occurred during reading reading config.json. \n\n ${routes.error}` + ); + } + + const configRoutes = routes.routes; + // This copied from `vercel build` output. + configRoutes.unshift({ + src: '^/[^./]+\\.[0-9a-f]{8}\\.(css|js|png|jpg|webp|avif|svg)$', + headers: { + 'cache-control': 's-maxage=31536000, immutable', + }, + continue: true, + }); + + const config = { + version: 3, + routes: configRoutes, + }; + + return config; +} + +/** + * + * Vercel's Build Output API needs to create `.vercel/output` and put static files and a config in there. + * This function should be run after a client has been built + * then by running this function it copies dist folder and create a config.json that vercel needs for deployments. + * + * @param {Path} pkgLocation + * @param {Path} configPath + */ +export async function makeOutputFolderForBuildOutputApi( + pkgLocation, + configPath +) { + const pkg = packageJson(pkgLocation); + + if (!pkg.main) { + throw new Error( + `We relying on 'main' field inside your package.json. Make sure you've set it for ${pkg.name}.` + ); + } + + // Paths + const pkgPath = convertPackageLocationToFullPath(pkgLocation); + const mainDir = dirname(join(pkgPath, pkg.main)); + const targetDir = join(pkgPath, '.vercel/output'); + const targetStaticDir = join(targetDir, 'static'); + + console.log( + `copying build artifacts to .vercel/output for ${pkgLocation}...` + ); + await mkdir(targetStaticDir, { recursive: true }); + await cp(mainDir, targetStaticDir, { recursive: true }); + console.log(`copied. path: ${targetStaticDir}`); + + console.log(`creating config.json for ${pkgLocation}...`); + const buildOutput = await getVercelJsonAndMakeBuildOutputApi(configPath); + const targetConfigPath = join(targetDir, 'config.json'); + await writeFile(targetConfigPath, JSON.stringify(buildOutput)); + console.log(`created. path: ${targetConfigPath}`); +} diff --git a/scripts/deploy/vercel.json b/scripts/deploy/vercel.json new file mode 100644 index 0000000000..3a48e56ba5 --- /dev/null +++ b/scripts/deploy/vercel.json @@ -0,0 +1,3 @@ +{ + "rewrites": [{ "source": "/(.*)", "destination": "/" }] +} diff --git a/scripts/dev-ts-check/command.mjs b/scripts/dev-ts-check/command.mjs new file mode 100644 index 0000000000..ee82f01d93 --- /dev/null +++ b/scripts/dev-ts-check/command.mjs @@ -0,0 +1,21 @@ +#!/usr/bin/env node + +'use strict'; +import { join } from 'node:path'; +import commandLineArgs from 'command-line-args'; +import { watch } from './watch.mjs'; +import { awake } from '../dev-watch/utils.mjs'; +import { printDirname } from '../common/utils.mjs'; + +const cwd = join(printDirname(), '..', '..'); +const nx = join(cwd, 'node_modules', '.bin', 'nx'); + +async function run() { + const optionDefinitions = [{ name: 'project', type: String }]; + const { project } = commandLineArgs(optionDefinitions); + + awake(); + watch({ project, nx, cwd }); +} + +run(); diff --git a/scripts/dev-ts-check/watch.mjs b/scripts/dev-ts-check/watch.mjs new file mode 100644 index 0000000000..86dfd56c96 --- /dev/null +++ b/scripts/dev-ts-check/watch.mjs @@ -0,0 +1,41 @@ +import { exec } from 'node:child_process'; +import process from 'node:process'; +import OS from 'os'; +import { parseCommand, headStyle } from '../dev-watch/utils.mjs'; + +export function watch(params) { + const { project, nx, cwd } = params; + const isWindowsOS = OS.platform() === 'win32'; + const command = `${nx} watch --projects=${project} --includeDependentProjects -- echo "[build]${ + isWindowsOS ? '%' : '\\$' + }NX_PROJECT_NAME${isWindowsOS ? '%' : ''}"`; + console.log(headStyle('main'), `Running ts check command\n\n`); + + const watcher = exec(command, { cwd }, (err, stdout, stderr) => { + if (err) { + console.log(headStyle('watch', 'error', 'bgRed'), stderr); + process.exit(1); + } + console.log(headStyle('watch'), stdout); + }); + watcher.stdout.on('data', (d) => { + console.log(d); + const [command, data] = parseCommand(d); + if (command === 'build' && data != project) { + const build_command = `${nx} run ${data}:ts-check`; + const build = exec(build_command, (err, result, stderr) => { + if (err) { + console.log(headStyle('watch', 'build/error', 'bgRed'), stderr); + return; + } + console.log(headStyle('watch', 'build'), result); + }); + + build.stdout.on('data', (da) => { + console.log(headStyle('watch', 'build'), da); + }); + } + + console.log(headStyle('watch'), d); + }); +} diff --git a/scripts/dev-watch/subcommands/watch.mjs b/scripts/dev-watch/subcommands/watch.mjs index 2c23fd5ae0..ea394170f5 100644 --- a/scripts/dev-watch/subcommands/watch.mjs +++ b/scripts/dev-watch/subcommands/watch.mjs @@ -1,11 +1,14 @@ import { exec } from 'node:child_process'; import process from 'node:process'; +import OS from 'os'; import { parseCommand, headStyle } from '../utils.mjs'; export function watch(params) { const { project, nx, cwd } = params; - const command = `${nx} watch --projects=${project} --includeDependentProjects -- echo "[build]\\$NX_PROJECT_NAME"`; - + const isWindowsOS = OS.platform() === 'win32'; + const command = `${nx} watch --projects=${project} --includeDependentProjects -- echo "[build]${ + isWindowsOS ? '%' : '\\$' + }NX_PROJECT_NAME${isWindowsOS ? '%' : ''}"`; console.log(headStyle('main'), `Running watch command\n\n`); const watcher = exec(command, { cwd }, (err, stdout, stderr) => { @@ -15,7 +18,8 @@ export function watch(params) { } console.log(headStyle('watch'), stdout); }); - watcher.stdout.on('data', d => { + watcher.stdout.on('data', (d) => { + console.log(d); const [command, data] = parseCommand(d); if (command === 'build' && data != project) { const build_command = `${nx} run ${data}:build`; @@ -27,7 +31,7 @@ export function watch(params) { console.log(headStyle('watch', 'build'), result); }); - build.stdout.on('data', da => { + build.stdout.on('data', (da) => { console.log(headStyle('watch', 'build'), da); }); } diff --git a/scripts/lingui/command.js b/scripts/lingui/command.js new file mode 100644 index 0000000000..0294f7f0cf --- /dev/null +++ b/scripts/lingui/command.js @@ -0,0 +1,20 @@ +// Wrapper around lingui command that exits with a non zero value if an error is detected. Lingui commands do not fail with a non-zero exit code in some cases. There is an open issue here: https://github.com/lingui/js-lingui/issues/1419 +const { exec } = require('child_process'); + +const args = process.argv.splice(2); +const command = `yarn lingui ${args.join(' ')}`; + +const handleLinguiCommand = function (error, stdout, stderr) { + if (error) { + // Handle exec command error (lingui command not found?) + console.log(`error: ${error}`); + throw error; + } + // Display command standard output + console.log(`stdout: ${stdout}`); + // Display command standard error + console.log(`stderr: ${stderr}`); + const errorExists = stderr?.trim() !== '✔'; + process.exit(errorExists ? 1 : 0); +}; +exec(command, handleLinguiCommand); diff --git a/scripts/post-release/command.mjs b/scripts/post-release/command.mjs new file mode 100644 index 0000000000..ef286290fd --- /dev/null +++ b/scripts/post-release/command.mjs @@ -0,0 +1,21 @@ +import { checkout, merge, pull, push } from '../common/git.mjs'; +import { checkCommitAndGetPkgs } from './tag.mjs'; + +async function run() { + // Make sure we are on main and having latest changes + await checkout('main'); + await pull(); + + await checkCommitAndGetPkgs(); + + // Merge phase + await checkout('next'); + await pull(); + await merge('main', { mergeStrategy: '--no-ff' }); + await push(); +} + +run().catch((e) => { + console.error(e); + process.exit(1); +}); diff --git a/scripts/post-release/tag.mjs b/scripts/post-release/tag.mjs new file mode 100644 index 0000000000..a1ed257f6d --- /dev/null +++ b/scripts/post-release/tag.mjs @@ -0,0 +1,42 @@ +import { PUBLISH_COMMIT_SUBJECT } from '../common/constants.mjs'; +import { getLastCommitMessage, getLastCommitSubject } from '../common/git.mjs'; +import { tagNameToPkgName } from '../common/utils.mjs'; + +/** + * + * @returns {Promise} + * @typedef {Object} pkg + * @property {string} pkg.name + * @property {string} pkg.version + */ +export async function checkCommitAndGetPkgs() { + const lastCommitSubject = await getLastCommitSubject(); + const lastCommitMessage = await getLastCommitMessage(); + + if (lastCommitSubject !== PUBLISH_COMMIT_SUBJECT) { + throw new Error('Can not proceed'); + } + + const lines = lastCommitMessage.split('\n'); + const affectedPackagesList = lines.find((line) => + line.startsWith('Affected packages:') + ); + + if (!affectedPackagesList) { + throw new Error("Commit message isn't valid"); + } + + const [, affectedPackages] = affectedPackagesList.split( + 'Affected packages: ' + ); + const pkgs = affectedPackages.split(',').map((pkg) => { + const [name, version] = pkg.split('@'); + + return { + name: tagNameToPkgName(name), + version: version, + }; + }); + + return pkgs; +} \ No newline at end of file diff --git a/scripts/publish/build.mjs b/scripts/publish/build.mjs new file mode 100644 index 0000000000..3829f68cce --- /dev/null +++ b/scripts/publish/build.mjs @@ -0,0 +1,36 @@ +import { execa } from 'execa'; +import { NxError } from '../common/errors.mjs'; + +/** + * Get a list of packages to run `build` on them. + * + * @param {import("../common/typedefs.mjs").Package[]} pkgs + * + */ +export async function build(pkgs) { + performance.mark(`start-publish-build`); + + const projects = pkgs.map((pkg) => pkg.name).join(','); + const result = await execa('yarn', [ + 'nx', + 'run-many', + '--projects', + projects, + '--target', + 'build', + ]) + .then(({ stdout }) => stdout) + .catch((err) => { + throw new NxError(err.stderr + err.stdout); + }); + + performance.mark(`end-publish-build`); + const duration_build = performance.measure( + `publish-build`, + `start-publish-build`, + `end-publish-build` + ).duration; + console.log(`Built. ${duration_build}ms`); + + return result; +} diff --git a/scripts/publish/command.mjs b/scripts/publish/command.mjs index 213435aae0..f8739b6bde 100755 --- a/scripts/publish/command.mjs +++ b/scripts/publish/command.mjs @@ -1,102 +1,194 @@ #!/usr/bin/env node 'use strict'; +import process from 'node:process'; +import { State } from './state.mjs'; +import { checkEnvironments, makeGithubRelease } from '../common/github.mjs'; +import { tryPublish } from './publish.mjs'; +import { getAffectedPackages } from '../common/repository.mjs'; import { - buildPackages, - changed, - deployProjectsToVercel, - detectChannel, - getLastReleasedHashId, - groupPackagesForDeploy, - increaseVersionForMain, - increaseVersionForNext, + addPkgFileChangesToStage, logAsSection, - publishPackages, - pushToRemote, - tagPackages, + sequentiallyRun, + throwIfUnableToProceed, } from './utils.mjs'; +import { addFileToStage, publishCommitAndTags, push } from '../common/git.mjs'; +import { update } from './package.mjs'; +import { build } from './build.mjs'; +import { should } from '../common/features.mjs'; -// TODO: Working directory should be empty. async function run() { - // Detect last relase and what packages has changed since then. - const channel = detectChannel(); - const useTagForDetectLastRelease = channel === 'prod'; - const baseCommit = await getLastReleasedHashId(useTagForDetectLastRelease); - const changedPkgs = await changed(baseCommit); - - // Info logs - logAsSection('Run...', `at ${baseCommit}`); - - console.log( - changedPkgs.map((pkg) => `- ${pkg.name} (current version: ${pkg.version})`).join('\n'), - ); - - // If any package has changed, we exit from the process. - if (changedPkgs.length === 0) { - console.log(`There is no changed package since ${baseCommit}`); + logAsSection('::group::🔍 Checking environments...'); + checkEnvironments(); + console.log('::endgroup::'); + + // 1. Detect affected packages and increase version + logAsSection('::group::🔍 Anlyzing dependencies...'); + const affectedPkgs = await getAffectedPackages(); + const libPkgs = affectedPkgs.filter((pkg) => !pkg.private); + const clientPkgs = affectedPkgs.filter((pkg) => pkg.private); + + if (libPkgs.length === 0) { + console.log('No library has changed. Skip.'); process.exit(0); } - // Run a specific workflow based on channel - await publish(changedPkgs, channel); -} + console.log('Current state:'); + console.table(libPkgs); + + const state = new State(libPkgs); + const updateTasks = libPkgs.map((pkg) => { + return update(pkg).then((pkgState) => { + state.setState(pkg.name, 'gitTag', pkgState.gitTag); + state.setState(pkg.name, 'npmVersion', pkgState.npmVersion); + state.setState(pkg.name, 'version', pkgState.version); + }); + }); + await Promise.all(updateTasks); + + const pkgs = state.list(); + const pkgStates = pkgs.map((pkg) => state.getState(pkg.name)); + + console.log('Next state:'); + console.table( + pkgs.map((pkg) => { + return { + name: pkg.name, + ...state.getState(pkg.name), + }; + }) + ); -run().catch((e) => { - console.error(e); - process.exit(1); -}); + throwIfUnableToProceed(pkgStates); + + console.log('::endgroup::'); + + // 2. Build all packacges + /** + * IMPORTANT NOTE: + * We are all the libs in parallel, parcel has a limitation on running `parcel` instances. + * So if you are trying to build multiple parcel apps it goes through some erros. here, for publishing libs + * We are using esbuild so don't need to do anything. + * but if we need, the potential solution is filtering parcel apps and run them secquentially. + */ + + logAsSection(`::group::🔨 Start building...`); + await build(pkgs); + console.log('::endgroup::'); + + // 3. Publish + logAsSection(`::group::🚀 Start publishing...`); + try { + await tryPublish(pkgs, { + onUpdateState: state.setState.bind(state), + }); + } catch (e) { + console.error(e); + + /** @type {import('../common/typedefs.mjs').Package | undefined} */ + const pkg = e.cause.pkg; + if (!pkg) { + console.error( + "🚨 The error hasn't thrown `pkg`. Here is more information to debug" + ); + console.log(state.toJSON()); + } else { + // Ignoring error since it's possible to file hasn't changed yet. + await addPkgFileChangesToStage(pkg).catch(console.warn); + } + } -/* -------------- Flows ------------------ */ + console.log('::endgroup::'); -async function publish(changedPkgs, channel) { - // Versioning - logAsSection(`Versioning, Start...`, `for ${changedPkgs.length} packages`); + // 4. Tag and Push - let updatedPackages; - if (channel === 'prod') { - updatedPackages = await increaseVersionForMain(changedPkgs); - } else { - updatedPackages = await increaseVersionForNext(changedPkgs); - } + /** + * Our final list will includes only packages that published on NPM. + * If a package failed on making changelog, github release, ... + * We are considering it's published and should handle those cases manually. + */ + const listPkgsForTag = state.list().filter((pkg) => { + const isPublishedOnNpm = !!state.getState(pkg.name, 'npmVersion'); + return isPublishedOnNpm; + }); - logAsSection(`Versioning, Done.`); - console.log( - updatedPackages.map((pkg) => `- ${pkg.name} (next version: ${pkg.version})`).join('\n'), + logAsSection( + '::group::🏷️ Tagging and commit...', + `${listPkgsForTag.length} packages for tagging.` ); - - logAsSection(`Tagging, Start...`, `for ${updatedPackages.length} packages`); - const tagOptions = channel === 'prod' ? { skipGitTagging: false } : { skipGitTagging: true }; - const taggedPackages = await tagPackages(updatedPackages, tagOptions); - logAsSection(`Tagging, Done.`); - console.log({ taggedPackages }); - - logAsSection(`Pushing tags to remote...`); - const branch = channel === 'prod' ? 'main' : 'next'; - await pushToRemote(branch); - logAsSection(`Pushed.`); - - // Publish to NPM - const packages = groupPackagesForDeploy(updatedPackages); - - logAsSection(`It's time for building artifacts...`); - - if (packages.npm.length) { - logAsSection('NPM Build', `Build npm packages...`); - await buildPackages(packages.npm); - logAsSection('NPM Build', `Successfully built.`); - logAsSection('NPM Publish', 'Publishing npm packages....'); - const distTag = channel === 'prod' ? 'latest' : 'next'; - await publishPackages(packages.npm, distTag); - logAsSection('NPM Publish', 'Published. Congrats 🎉'); + if (listPkgsForTag.length > 0) { + performance.mark(`start-publish-tagging`); + + /** + * We don't need to tag and mention them while publishing, they have a separate github action. + * But we updated their package json to use the latest version of published libs + * So we should includes them in our commit. + */ + await sequentiallyRun( + clientPkgs.map( + (pkg) => () => addFileToStage(`${pkg.location}`).catch(console.warn) + ) + ); + + await publishCommitAndTags(listPkgsForTag); + await push(); + performance.mark(`end-publish-tagging`); + const duration_build = performance.measure( + `publish-tagging`, + `start-publish-tagging`, + `end-publish-tagging` + ).duration; + console.log(`Tagged. ${duration_build}ms`); + } else { + console.log('Skipped.'); } - // Publish to Vercel - if (packages.vercel.length) { - logAsSection(`Build clients & deploy to vercel...`); - // TODO: This is not a good solution, because it will build the package itself twice. - await buildPackages(packages.vercel); - logAsSection('Dependency', `Successfully built.`); - await deployProjectsToVercel(packages.vercel); - logAsSection(`We are good. Done.`); + console.log('::endgroup::'); + + // 5. Making github release + // NOTE: If any error happens in this step we are don't bail out the process and will continue. A warning will be shown. + console.log('::group::🐙 Github release'); + if (should('generateChangelog')) { + if (listPkgsForTag.length > 0) { + performance.mark(`start-publish-gh-release`); + + const tasks = listPkgsForTag.map((pkg) => { + return makeGithubRelease(pkg) + .then(() => { + state.setState(pkg.name, 'githubRelease', pkg.version); + }) + .catch(console.warn); + }); + + await Promise.all(tasks); + + performance.mark(`end-publish-gh-release`); + const duration_build = performance.measure( + `publish-gh-release`, + `start-publish-gh-release`, + `end-publish-gh-release` + ).duration; + console.log(`Finished. ${duration_build}ms`); + } else { + console.log('Skipped.'); + } + } else { + console.log('Skipped as it set on environments.'); } + console.log('::endgroup::'); + + // 6. Report + console.log('::group::📊 Report'); + console.table( + pkgs.map((pkg) => ({ + name: pkg.name, + ...state.getState(pkg.name), + })) + ); + console.log('::endgroup::'); } + +run().catch((e) => { + console.error(e); + process.exit(1); +}); diff --git a/scripts/publish/config.mjs b/scripts/publish/config.mjs deleted file mode 100644 index ff00e8ed1b..0000000000 --- a/scripts/publish/config.mjs +++ /dev/null @@ -1,11 +0,0 @@ -import { getEnvWithFallback } from './utils.mjs'; - -const scope = `@rango-dev`; -export const VERCEL_ORG_ID = process.env.VERCEL_ORG_ID; -export const VERCEL_TOKEN = process.env.VERCEL_TOKEN; -export const VERCEL_PACKAGES = { - [`${scope}/wallets-demo`]: getEnvWithFallback('VERCEL_PROJECT_WALLETS'), - [`${scope}/queue-manager-demo`]: getEnvWithFallback('VERCEL_PROJECT_Q'), - [`${scope}/wallets-adapter-demo`]: getEnvWithFallback('VERCEL_PROJECT_WALLET_ADAPTER'), - [`${scope}/config-client`]: getEnvWithFallback('VERCEL_PROJECT_WIDGET_CONFIG'), -}; diff --git a/scripts/publish/package.mjs b/scripts/publish/package.mjs new file mode 100644 index 0000000000..09d1bd1239 --- /dev/null +++ b/scripts/publish/package.mjs @@ -0,0 +1,40 @@ +import { should } from '../common/features.mjs'; +import { gitTagFor } from '../common/git.mjs'; +import { detectChannel, githubReleaseFor } from '../common/github.mjs'; +import { npmVersionFor } from '../common/npm.mjs'; +import { + increaseVersionForNext, + increaseVersionForProd, +} from '../common/version.mjs'; + +/** + * + * @param {import('../common/typedefs.mjs').Package} pkg + * @returns {Promise} + */ +export async function update(pkg) { + const channel = detectChannel(); + + // Increase package version + const updatedPkg = + channel === 'prod' + ? await increaseVersionForProd(pkg) + : await increaseVersionForNext(pkg); + + const tag = should('checkGitTags') ? await gitTagFor(updatedPkg) : null; + + const release = should('checkGithubRelease') + ? await githubReleaseFor(updatedPkg) + : null; + const npmVersionInfo = should('checkNpm') + ? await npmVersionFor(updatedPkg) + : null; + const npmVersion = npmVersionInfo ? npmVersionInfo[channel] : null; + + return { + version: updatedPkg.version, + githubRelease: release, + gitTag: tag, + npmVersion: npmVersion, + }; +} diff --git a/scripts/publish/publish.mjs b/scripts/publish/publish.mjs new file mode 100644 index 0000000000..6af913ad25 --- /dev/null +++ b/scripts/publish/publish.mjs @@ -0,0 +1,62 @@ +import chalk from 'chalk'; +import { generateChangelog } from '../common/changelog.mjs'; +import { should } from '../common/features.mjs'; +import { publishOnNpm } from '../common/npm.mjs'; +import { upgradeDependents } from './upgrade.mjs'; +import { + addPkgFileChangesToStage, + sequentiallyRun, +} from './utils.mjs'; + +/** + * + * By giving a list of packages, we will try to publish all of them. + * Publishing includes some steps to be done. + * + * @param {import("../common/utils.mjs").Package[]} pkgs + */ +export async function tryPublish(pkgs, { onUpdateState }) { + const tasks = pkgs.map( + (pkg) => () => + publishTask(pkg, { onUpdateState }).catch((e) => { + e.cause = { + pkg, + }; + throw e; + }) + ); + await sequentiallyRun(tasks); + + console.log(`Published.`); +} + +/** + * + * There are some few steps to be finshed to publish a package. + * This function contains these steps. + * + * @param {import('../common/typedefs.mjs').Package} pkg + */ +async function publishTask(pkg, { onUpdateState }) { + console.log(chalk.green('[1/4]'), `Publish ${pkg.name} to npm`); + await publishOnNpm(pkg); + onUpdateState(pkg.name, 'npmVersion', pkg.version); + + if (should('generateChangelog')) { + console.log(chalk.green('[2/4]'), `Making changelog`); + await generateChangelog(pkg, { saveToFile: true }); + } else { + console.log(chalk.green('[2/4]'), `Skipping changelog and github release.`); + } + + console.log( + chalk.green('[3/4]'), + `Upgrade all the dependent packages to latest version` + ); + await upgradeDependents(pkg); + + console.log(chalk.green('[4/4]'), `Adding files to staging area`); + await addPkgFileChangesToStage(pkg); + + console.log(`🚀 ${pkg.name} published.`); +} diff --git a/scripts/publish/state.mjs b/scripts/publish/state.mjs new file mode 100644 index 0000000000..19e82860df --- /dev/null +++ b/scripts/publish/state.mjs @@ -0,0 +1,67 @@ +export class State { + /** @type {import('../common/typedefs.mjs').Package[]} */ + pkgs = []; + /** @type {Object.} */ + state = {}; + + /** @param {import('../common/typedefs.mjs').Package[]} pkgs */ + constructor(pkgs) { + this.pkgs = pkgs; + } + + toJSON() { + const output = { + pkgs: this.pkgs, + state: this.state, + }; + + return JSON.stringify(output); + } + + /** + * + * Get packages in state **with latest version**. + * + * @returns {import('../common/typedefs.mjs').Package[]} + */ + list() { + return this.pkgs.map((pkg) => { + return { + ...pkg, + version: this.getState(pkg.name, 'version'), + }; + }); + } + + /** + * + * @param {string} pkgName + * @param {"gitTag" | "githubRelease" | "npmVersion" | "version" | undefined} name + */ + getState(pkgName, name) { + if (!this.state[pkgName]) { + return undefined; + } + + // Return whole state + if (!name) { + return this.state[pkgName]; + } + + return this.state[pkgName][name]; + } + + /** + * + * @param {string} pkgName + * @param {"gitTag" | "githubRelease" | "npmVersion" | "version"} name + * @param {string} value + */ + setState(pkgName, name, value) { + if (!this.state[pkgName]) { + this.state[pkgName] = {}; + } + + this.state[pkgName][name] = value; + } +} diff --git a/scripts/publish/typedefs.mjs b/scripts/publish/typedefs.mjs new file mode 100644 index 0000000000..95f5c843c6 --- /dev/null +++ b/scripts/publish/typedefs.mjs @@ -0,0 +1,9 @@ +/** + * @typedef {Object} PackageState + * @property {string | null} version + * @property {string | null} githubRelease + * @property {string | null} gitTag + * @property {string | null} npmVersion + * @example + * { '@myorg/x-pkg': {version: "1.0.0", gitTag: "1.0.0", githubRelease: "1.0.0", npmVersion: "1.0.0"} } + */ diff --git a/scripts/publish/upgrade.mjs b/scripts/publish/upgrade.mjs new file mode 100644 index 0000000000..88c83de08a --- /dev/null +++ b/scripts/publish/upgrade.mjs @@ -0,0 +1,21 @@ +import { execa } from 'execa'; +import { CustomScriptError } from '../common/errors.mjs'; + +/** + * + * Update all the packages that use a specific package to a specific package + * + * @param {import("../common/typedefs.mjs").Package} pkgs + */ +export async function upgradeDependents(pkg) { + await execa('yarn', [ + 'upgrade-all', + '--project', + pkg.name, + '--version', + pkg.version, + '--no-install', + ]).catch((e) => { + throw new CustomScriptError(e.stderr); + }); +} diff --git a/scripts/publish/utils.mjs b/scripts/publish/utils.mjs index 58fec32faf..acdd6ad620 100644 --- a/scripts/publish/utils.mjs +++ b/scripts/publish/utils.mjs @@ -1,275 +1,34 @@ import chalk from 'chalk'; -import { execa } from 'execa'; -import { readFileSync } from 'fs'; -import { join } from 'path'; -import conventionanRecommendBump from 'conventional-recommended-bump'; -import { printDirname } from '../common/utils.mjs'; -import { VERCEL_ORG_ID, VERCEL_PACKAGES, VERCEL_TOKEN } from './config.mjs'; -const root = join(printDirname(), '..', '..'); +import { UnableToProceedPublishError } from '../common/errors.mjs'; +import { should } from '../common/features.mjs'; +import { addFileToStage } from '../common/git.mjs'; +import { detectChannel } from '../common/github.mjs'; /** * - * Recommend next version based on Angular conventional commits + * For publishing a package we are changing somefiles, + * using this function it helps to add them git staging area. * - * @param {string} pkg pacakge name - * @return {Promise<{level: number,reason: string, releaseType: 'patch' | 'minor' | 'major',}>} + * @param {import('../common/typedefs.mjs').Package} pkg */ -export async function recommendBump(pkg) { - return new Promise((resolve, reject) => { - conventionanRecommendBump( - { - preset: `angular`, - lernaPackage: pkg, - }, - (error, recommendation) => { - if (error) { - reject(error); - } else { - resolve(recommendation); - } - }, - ); - }); -} -export async function deployProjectsToVercel(pkgs) { - await Promise.all(pkgs.map((pkg) => deploySingleProjectToVercel(pkg))); -} -export async function deploySingleProjectToVercel(pkg) { - const deployTo = detectChannel() === 'prod' ? 'production' : 'preview'; - - const env = { - VERCEL_ORG_ID: VERCEL_ORG_ID, - VERCEL_PROJECT_ID: getVercelProjectId(pkg.name), - }; - - console.log(`start deplyoing ${pkg.name}...`); - - await execa( - 'yarn', - [ - 'vercel', - 'pull', - '--cwd', - pkg.location, - '--environment', - deployTo, - '--token', - VERCEL_TOKEN, - '--yes', - ], - { env }, - ); - await execa('yarn', ['vercel', 'build', '--cwd', pkg.location, '--token', VERCEL_TOKEN], { env }); - await execa('yarn', ['vercel', pkg.location, '--prebuilt', '--token', VERCEL_TOKEN], { env }); - - console.log(`${pkg.name} deployed.`); -} - -export async function publishPackages(updatedPkgs, dist = 'next') { - const result = await Promise.all( - updatedPkgs.map(({ location }) => - execa('yarn', ['publish', location, '--tag', dist]).then(({ stdout }) => stdout), - ), - ); - - console.log('Published...'); - console.log(result); -} - -export async function buildPackages(updatedPkgs) { - const projects = updatedPkgs.map((pkg) => pkg.name).join(','); - const ps = execa('yarn', ['nx', 'run-many', '--projects', projects, '--target', 'build']); - ps.stdout.pipe(process.stdout); - return ps; -} - -export async function pushToRemote(branch, remote = 'origin') { - const { stdout } = await execa('git', [ - 'push', - '--follow-tags', - '--no-verify', - '--atomic', - remote, - branch, - ]); - - console.log(stdout); -} -export async function tagPackages(updatedPackages, { skipGitTagging }) { - const tags = updatedPackages.map((pkg) => `${packageNameWithoutScope(pkg.name)}@${pkg.version}`); - const files = updatedPackages.map((pkg) => join(root, pkg.location, 'package.json')); - - const subject = `chore(release): publish\n\n`; - const list = tags.map((tag) => `- ${tag}`).join('\n'); - const message = subject + list; - - // making a publish commit - await execa('git', ['add', '--', ...files]); - await execa('git', ['commit', '-m', message, '-m', `Affected packages: ${tags.join(',')}`]); - - // creating annotated tags based on packages - if (!skipGitTagging) { - await Promise.all(tags.map((tag) => execa('git', ['tag', '-a', tag, '-m', tag]))); - } - - return tags; -} - -export async function increaseVersionForNext(changedPkgs) { - await Promise.all( - changedPkgs.map(({ name }) => - execa('yarn', [ - 'workspace', - name, - 'version', - '--preid=next', - '--prerelease', - '--no-git-tag-version', - ]).then(({ stdout }) => stdout), - ), - ); - - // Getting latest packages info to show the updated version. - // We only return changed packges, not whole repo. - const packages = (await workspacePackages()).filter((pkg) => { - return !!changedPkgs.find((changedPkg) => pkg.name === changedPkg.name); - }); - - return packages; -} - -export async function increaseVersionForMain(changedPkgs) { - const nextVersions = {}; - - try { - await Promise.all( - changedPkgs.map(({ name }) => - recommendBump(name).then((recommendation) => { - console.log({ name, recommendation }); - nextVersions[name] = recommendation.releaseType; - }), - ), - ); - } catch (e) { - throw new Error(`Calculating next version failed. details: ${e}`); - } - - await Promise.all( - changedPkgs.map(({ name }) => { - const nextVersion = nextVersions[name]; - return execa('yarn', [ - 'workspace', - name, - 'version', - `--${nextVersion}`, - '--no-git-tag-version', - ]).then(({ stdout }) => stdout); - }), - ); - - // Getting latest packages info to show the updated version. - // We only return changed packges, not whole repo. - const packages = (await workspacePackages()).filter((pkg) => { - return !!changedPkgs.find((changedPkg) => pkg.name === changedPkg.name); - }); - - return packages; -} - -export async function changed(since) { - const pkgs = await workspacePackages(); - const all = await Promise.all( - pkgs.map(({ name, location, version }) => { - let params = []; - - // Releasing for the first time on repo. - if (!since) { - params = ['log', '--oneline', '--', location]; - } else { - params = ['log', `${since}..HEAD`, '--oneline', '--', location]; - } - - return execa('git', params).then(({ stdout: result }) => { - return { - name, - location, - version, - changed: !!result, - }; - }); - }), - ); - return all.filter((pkg) => pkg.changed); -} -export async function workspacePackages() { - const { stdout } = await execa('yarn', ['workspaces', 'info']); - const result = JSON.parse(stdout); - const packagesName = Object.keys(result); - const output = packagesName.map((name) => { - const pkgJson = pacakgeJson(result[name].location); - return { - name, - location: result[name].location, - version: pkgJson.version, - private: pkgJson.private || false, - }; - }); - return output; -} - -export function pacakgeJson(location) { - const fullPath = join(root, location, 'package.json'); - const file = readFileSync(fullPath); - return JSON.parse(file); -} - -export function detectChannel() { - console.log('base', getEnvWithFallback('REF')); - if (getEnvWithFallback('REF') === 'refs/heads/main') { - return 'prod'; - } - return 'next'; -} - -// TODO: Check for when there is no tag. -export async function getLastReleasedHashId(useTag = false) { - if (useTag) { - const { stdout: hash } = await execa('git', ['rev-list', '--max-count', 1, '--tags']); - return hash; - } else { - const { stdout: hash } = await execa('git', [ - 'log', - '--grep', - '^chore(release): publish', - '-n', - 1, - '--pretty=format:%H', - ]); - return hash; +export async function addPkgFileChangesToStage(pkg) { + await addFileToStage(`${pkg.location}/package.json`); + if (should('generateChangelog')) { + await addFileToStage(`${pkg.location}/CHANGELOG.md`); } } -export function groupPackagesForDeploy(packages) { - const output = { - npm: [], - vercel: [], - }; - - packages.forEach((pkg) => { - if (!!getVercelProjectId(pkg.name)) { - output.vercel.push(pkg); - } else if (!pkg.private) { - // If getVercelProjectId returns undefined, it's possible to be added as npm package - // So here we are making sure it's not a private package and can be published using npm - output.npm.push(pkg); - } - }); - - return output; -} - -export function getVercelProjectId(packageName) { - return VERCEL_PACKAGES[packageName]; +/** + * Getting a list of (lazy) promises and run them one after another. + * @param {Promise[]} promises + * @returns {Promise} + */ +export async function sequentiallyRun(promises) { + return promises.reduce((prev, task) => { + return prev.then(() => { + return task(); + }); + }, Promise.resolve()); } export function logAsSection(title, sub = '') { @@ -281,15 +40,47 @@ export function logAsSection(title, sub = '') { console.log(message); } -/* - Convert: - @hello-wrold/a-b -> a-b -*/ -function packageNameWithoutScope(name) { - return name.replace(/@.+\//, ''); -} +/** + * Get state and check some conditions on the state to make sure we can publish. + * + * @param {import('./typedefs.mjs').PackageState[]} pkgsState + */ +export function throwIfUnableToProceed(pkgsState) { + const channel = detectChannel(); -// we are adding a fallback, to make sure predefiend VERCEL_PACKAGES always will be true. -export function getEnvWithFallback(name) { - return process.env[name] || 'NOT SET'; + if (channel === 'prod') { + // TODO: it's better to check `npm` version should be less than `package.version` + const alreadyPublishedPackages = pkgsState.filter( + (pkgState) => pkgState.version === pkgState.npmVersion + ); + const alreadyHasGithubReleasePackages = pkgsState.filter( + (pkgState) => !!pkgState.githubRelease + ); + const alreadyHasGitTagPackages = pkgsState.filter( + (pkgState) => !!pkgState.gitTag + ); + + if (alreadyPublishedPackages.length) { + const list = alreadyPublishedPackages + .map((pkg) => pkg.npmVersion) + .join(','); + throw new UnableToProceedPublishError( + `These versions have been published on NPM already. \n ${list}` + ); + } else if (alreadyHasGithubReleasePackages.length) { + const list = alreadyHasGithubReleasePackages + .map((pkg) => pkg.githubRelease) + .join(','); + throw new UnableToProceedPublishError( + `These versions have been released on Github before. \n ${list}` + ); + } else if (alreadyHasGitTagPackages.length) { + const list = alreadyHasGithubReleasePackages + .map((pkg) => pkg.gitTag) + .join(','); + throw new UnableToProceedPublishError( + `These tags already exist. \n ${list}` + ); + } + } } diff --git a/scripts/release/command.mjs b/scripts/release/command.mjs index fc81066064..42dc6135e9 100644 --- a/scripts/release/command.mjs +++ b/scripts/release/command.mjs @@ -1,28 +1,28 @@ -import { $ } from 'execa'; +import { checkout, merge, pull, push } from '../common/git.mjs'; async function run() { // Checkout to `next` - const { stdout: checkoutNextOutput } = await $`git checkout next`; + const checkoutNextOutput = await checkout('next'); console.log(`Result for: checkout\n`, checkoutNextOutput); // Get latest changes from `next` - const { stdout: pullNextOutput } = await $`git pull`; - console.log(`Result for: checkout\n`, pullNextOutput); + const pullNextOutput = await pull(); + console.log(`Result for: pull\n`, pullNextOutput); // Checkout to `main` - const { stdout: checkoutOutput } = await $`git checkout main`; + const checkoutOutput = await checkout('main'); console.log(`Result for: checkout\n`, checkoutOutput); // Get latest changes from `main` - const { stdout: pullOutput } = await $`git pull`; + const pullOutput = await pull(); console.log(`Result for: pull\n`, pullOutput); // Merge `next` into `main` - const { stdout: mergeOutput } = await $`git merge next`; + const mergeOutput = await merge('next',{ mergeStrategy: '--no-ff' }); console.log(`Result for: merge\n`, mergeOutput); // Push merged commits to `main` - const { stdout: pushOutput } = await $`git push`; + const pushOutput = await push(); console.log(`Result for: push\n`, pushOutput); } diff --git a/scripts/upgrade-all/command.mjs b/scripts/upgrade-all/command.mjs index 45ce2a28a2..d304bcd4fc 100644 --- a/scripts/upgrade-all/command.mjs +++ b/scripts/upgrade-all/command.mjs @@ -3,30 +3,48 @@ import commandLineArgs from 'command-line-args'; import { getAllPackages, upgradeDepndendentsOf } from './utils.mjs'; async function run() { - const optionDefinitions = [{ name: 'project', type: String }]; - const { project } = commandLineArgs(optionDefinitions); + const optionDefinitions = [ + { name: 'project', type: String }, + { name: 'no-install', type: Boolean, defaultOption: false }, + { name: 'version', type: String, defaultOption: '' }, + ]; + const { project, noInstall, version } = commandLineArgs(optionDefinitions, { + camelCase: true, + }); const { stdout: currentBranch } = await $`git branch --show-current`; const dist = currentBranch === 'main' ? 'latest' : 'next'; + if (!project && !!version) { + throw new Error( + `To set a fixed "version," you must provide the "project" parameter. project=${project}, version=${version}` + ); + } + if (!project) { - console.log(`you didn't specify any "project". So we will check all the workspace packages.`); + console.log( + `you didn't specify any "project". So we will check all the workspace packages.` + ); const packages = await getAllPackages(); - console.log(`All packages (without clients/demos): ${packages.length}`); + console.log(`All packages (with clients/demos): ${packages.length}`); console.log(`Dist channel: ${dist}`); - await Promise.all(packages.map((project) => upgradeDepndendentsOf(project, dist))); - return; + // TODO: using Promise.all to run in parallel will speed up the proccess + // but it has lock/unlock issue with fs write/read and can not be used reliably. + for (const project of packages) { + await upgradeDepndendentsOf(project, dist); + } } else { console.log(`Running upgrade-all for ${project} \n`); console.log(`Dist channel: ${dist}`); - await upgradeDepndendentsOf(project, dist); + await upgradeDepndendentsOf(project, dist, version); } - console.log(`package.json has been updated. Trying to install... \n`); - - const { stdout, stderr } = await $`yarn`; - console.log(stdout, stderr); + if (!noInstall) { + console.log(`package.json has been updated. Trying to install... \n`); + const { stdout, stderr } = await $`yarn`; + console.log(stdout, stderr); + } } run().catch((e) => { diff --git a/scripts/upgrade-all/utils.mjs b/scripts/upgrade-all/utils.mjs index 90acb2845d..5d94721c79 100644 --- a/scripts/upgrade-all/utils.mjs +++ b/scripts/upgrade-all/utils.mjs @@ -2,6 +2,7 @@ import fs from 'node:fs/promises'; import { join } from 'node:path'; import { $ } from 'execa'; import { printDirname } from '../common/utils.mjs'; +import { packageVersionOnNPM } from '../common/npm.mjs'; const cwd = join(printDirname(), '..', '..'); @@ -17,7 +18,9 @@ export async function updateVersion(target, upgrade) { } else if (updatedPkgJson['devDependencies'][name]) { updatedPkgJson['devDependencies'][name] = `^${version}`; } else { - throw new Error(`${name} not found, neither dependencies or devDependencies.`); + throw new Error( + `${name} not found, neither dependencies or devDependencies.` + ); } await fs.writeFile(pkgPath, JSON.stringify(updatedPkgJson, null, 2)); @@ -30,11 +33,13 @@ export async function getAllPackages() { return pkgs; } -/* +/** By passing a project (package) name, this function will go through all workspace and will upgrade the version if any package has `project` inside its `dependency` or `devDependency`. -*/ -export async function upgradeDepndendentsOf(project, dist) { + + @param version If set, it will use the passed version, if not, it will get the version from NPM. By default it's an empty string. +**/ +export async function upgradeDepndendentsOf(project, dist, version) { const { stdout: info } = await $`yarn workspaces info`; const workspaces = JSON.parse(info); @@ -55,17 +60,27 @@ export async function upgradeDepndendentsOf(project, dist) { return; } - console.log(`These packages are using ${project}: ${dependents.join(',')} \n`); - - const { stdout: npmInfo } = await $`yarn info ${project}@${dist} --json`; - const versions = JSON.parse(npmInfo).data['dist-tags']; - const version = versions[dist]; + console.log( + `These packages are using ${project}: ${dependents.join(',')} \n` + ); - console.log(`NPM version for ${project} is ${version}. \n`); + // If set, it will use the passed version, if not, it will get the version from NPM. By default it's an empty string. + let project_version; + if (!!version) { + console.log(`Using fixed version for ${project} which is ${version}. \n`); + project_version = version; + } else { + const versions = await packageVersionOnNPM(project, dist); + console.log(`NPM version for ${project} is ${versions.npm_version}. \n`); + project_version = versions.npm_version; + } await Promise.all( dependents.map((pkg) => - updateVersion({ path: workspaces[pkg].location }, { name: project, version }), - ), + updateVersion( + { path: workspaces[pkg].location }, + { name: project, version: project_version } + ) + ) ); } diff --git a/signers/signer-cosmos/CHANGELOG.md b/signers/signer-cosmos/CHANGELOG.md new file mode 100644 index 0000000000..efb0e6a397 --- /dev/null +++ b/signers/signer-cosmos/CHANGELOG.md @@ -0,0 +1,88 @@ +## [0.30.1](https://github.com/rango-exchange/rango-client/compare/signer-cosmos@0.30.0...signer-cosmos@0.30.1) (2024-11-06) + + + +# [0.30.0](https://github.com/rango-exchange/rango-client/compare/signer-cosmos@0.29.0...signer-cosmos@0.30.0) (2024-10-12) + + +### Bug Fixes + +* bump sdk and fix type issues ([d442208](https://github.com/rango-exchange/rango-client/commit/d4422083bf5dd27d5f509ce1db7f9560d05428c8)) + + + +# [0.29.0](https://github.com/rango-exchange/rango-client/compare/signer-cosmos@0.28.0...signer-cosmos@0.29.0) (2024-09-10) + + + +# [0.28.0](https://github.com/rango-exchange/rango-client/compare/signer-cosmos@0.27.0...signer-cosmos@0.28.0) (2024-08-11) + + + +# [0.27.0](https://github.com/rango-exchange/rango-client/compare/signer-cosmos@0.26.0...signer-cosmos@0.27.0) (2024-07-09) + + + +# [0.26.0](https://github.com/rango-exchange/rango-client/compare/signer-cosmos@0.25.0...signer-cosmos@0.26.0) (2024-02-20) + + + +# [0.25.0](https://github.com/rango-exchange/rango-client/compare/signer-cosmos@0.23.0...signer-cosmos@0.25.0) (2023-12-24) + + +### Bug Fixes + +* fix HMR for widget and playground ([8524820](https://github.com/rango-exchange/rango-client/commit/8524820f10cf0b8921f3db0c4f620ff98daa4103)) + + + +# [0.14.0](https://github.com/rango-exchange/rango-client/compare/signer-cosmos@0.13.0...signer-cosmos@0.14.0) (2023-08-03) + + + +# [0.13.0](https://github.com/rango-exchange/rango-client/compare/signer-cosmos@0.12.0...signer-cosmos@0.13.0) (2023-08-01) + + + +# [0.9.0](https://github.com/rango-exchange/rango-client/compare/signer-cosmos@0.8.0...signer-cosmos@0.9.0) (2023-07-31) + + +### Features + +* Support for WalletConnect 2 ([faedef0](https://github.com/rango-exchange/rango-client/commit/faedef0b5e6fc3c5ef881cbbe4ec05334cc1c910)) + + + +# [0.7.0](https://github.com/rango-exchange/rango-client/compare/signer-cosmos@0.6.0...signer-cosmos@0.7.0) (2023-07-11) + + + +# [0.6.0](https://github.com/rango-exchange/rango-client/compare/signer-cosmos@0.5.0...signer-cosmos@0.6.0) (2023-07-11) + + + +# [0.5.0](https://github.com/rango-exchange/rango-client/compare/signer-cosmos@0.4.0...signer-cosmos@0.5.0) (2023-05-31) + + + +# [0.4.0](https://github.com/rango-exchange/rango-client/compare/signer-cosmos@0.3.0...signer-cosmos@0.4.0) (2023-05-31) + + + +# [0.3.0](https://github.com/rango-exchange/rango-client/compare/signer-cosmos@0.2.0...signer-cosmos@0.3.0) (2023-05-30) + + + +# [0.2.0](https://github.com/rango-exchange/rango-client/compare/signer-cosmos@0.1.14...signer-cosmos@0.2.0) (2023-05-30) + + + +## [0.1.13](https://github.com/rango-exchange/rango-client/compare/signer-cosmos@0.1.12...signer-cosmos@0.1.13) (2023-05-15) + + +### Bug Fixes + +* update rango-types and fix notification bugs ([993f185](https://github.com/rango-exchange/rango-client/commit/993f185e0b8c5e5e15a2c65ba2d85d1f9c8daa90)) + + + diff --git a/signers/signer-cosmos/package.json b/signers/signer-cosmos/package.json index 3aca0f2c19..79a4e5fcae 100644 --- a/signers/signer-cosmos/package.json +++ b/signers/signer-cosmos/package.json @@ -1,54 +1,39 @@ { "name": "@rango-dev/signer-cosmos", - "version": "0.1.11", + "version": "0.30.1", "license": "MIT", - "module": "dist/signer-cosmos.esm.js", - "main": "dist/index.js", + "type": "module", + "source": "./src/index.ts", + "main": "./dist/index.js", + "exports": { + ".": "./dist/index.js" + }, "typings": "dist/index.d.ts", "files": [ "dist", "src" ], "scripts": { - "dev": "tsdx watch", - "build": "tsdx build --tsconfig ./tsconfig.json", - "test": "tsdx test", - "lint": "tsdx lint", - "size": "size-limit", - "analyze": "size-limit --why" - }, - "husky": { - "hooks": { - "pre-commit": "tsdx lint" - } - }, - "prettier": { - "printWidth": 80, - "semi": true, - "singleQuote": true, - "trailingComma": "es5" + "build": "node ../../scripts/build/command.mjs --path signers/signer-cosmos", + "ts-check": "tsc --declaration --emitDeclarationOnly -p ./tsconfig.json", + "clean": "rimraf dist", + "format": "prettier --write '{.,src}/**/*.{ts,tsx}'", + "lint": "eslint \"**/*.{ts,tsx}\" --ignore-path ../../.eslintignore" }, - "size-limit": [ - { - "path": "dist/signer-cosmos.cjs.production.min.js", - "limit": "10 KB" - }, - { - "path": "dist/signer-cosmos.esm.js", - "limit": "10 KB" - } - ], "dependencies": { "@cosmjs/launchpad": "^0.27.1", - "@cosmjs/stargate": "^0.29.4", + "@cosmjs/stargate": "^0.31.0", "@keplr-wallet/cosmos": "^0.9.12", "cosmjs-types": "^0.5.2", - "long": "^5.2.1", - "rango-types": "^0.1.28" + "long": "^5.2.3", + "rango-types": "^0.1.74" }, "devDependencies": { "@keplr-wallet/types": "^0.9.12" }, + "resolutions": { + "protobufjs": "^6.11.4" + }, "publishConfig": { "access": "public" } diff --git a/signers/signer-cosmos/patches/long+5.2.3.patch b/signers/signer-cosmos/patches/long+5.2.3.patch new file mode 100644 index 0000000000..a8bfa1a9d1 --- /dev/null +++ b/signers/signer-cosmos/patches/long+5.2.3.patch @@ -0,0 +1,14 @@ +diff --git a/node_modules/long/umd/index.d.ts b/node_modules/long/umd/index.d.ts +index c623535..e622f98 100644 +--- a/node_modules/long/umd/index.d.ts ++++ b/node_modules/long/umd/index.d.ts +@@ -1,2 +1,9 @@ ++// This library has a build issue which breaks `esnext` and `nodendex` module resolution. ++// Issues: ++// https://github.com/dcodeIO/long.js/issues/125 ++// https://github.com/dcodeIO/long.js/issues/131 ++// https://github.com/dcodeIO/long.js/issues/109 ++// eslint-disable-next-line @typescript-eslint/ban-ts-comment ++// @ts-ignore + import Long from "../index.js"; + export = Long; diff --git a/signers/signer-cosmos/readme.md b/signers/signer-cosmos/readme.md index 2f8659bd6a..0564dd4db4 100644 --- a/signers/signer-cosmos/readme.md +++ b/signers/signer-cosmos/readme.md @@ -1 +1,3 @@ -# @rango-dev/signer-cosmos \ No newline at end of file +# @rango-dev/signer-cosmos + +Signer for Cosmos Transacations generated by Rango API diff --git a/signers/signer-cosmos/src/helpers.ts b/signers/signer-cosmos/src/helpers.ts index 99f99c5441..f46dd2971a 100644 --- a/signers/signer-cosmos/src/helpers.ts +++ b/signers/signer-cosmos/src/helpers.ts @@ -1,29 +1,17 @@ -import Long from 'long'; -import { BroadcastMode, makeSignDoc, makeStdTx } from '@cosmjs/launchpad'; +import type { AminoSignResponse } from '@cosmjs/launchpad'; +import type { Keplr, KeplrSignOptions } from '@keplr-wallet/types'; +import type { CosmosTransaction } from 'rango-types'; + +import { BroadcastMode, makeSignDoc } from '@cosmjs/launchpad'; import { SigningStargateClient } from '@cosmjs/stargate'; import { cosmos } from '@keplr-wallet/cosmos'; -import { MsgExecuteContract } from 'cosmjs-types/cosmwasm/wasm/v1/tx'; -import { Keplr, KeplrSignOptions } from '@keplr-wallet/types'; -import { CosmosTransaction, SignerError, SignerErrorCode } from 'rango-types'; +import { MsgExecuteContract } from 'cosmjs-types/cosmwasm/wasm/v1/tx.js'; +import Long from 'long'; +import { SignerError, SignerErrorCode } from 'rango-types'; -// todo: unhardcode this. -// sifchain has some gas price apis. but gaslimits might be hardcoded still -// hardcoded based on -// https://github.com/Sifchain/sifchain-ui/blob/develop/ui/core/src/clients/bridges/IBCBridge/IBCBridge.ts#L236 -// https://github.com/Sifchain/sifchain-ui/blob/7dad360eaa8a6b8e71e0ff818896f0c7d062b53c/ui/core/src/clients/bridges/IBCBridge/IBCBridge.ts#L229 -// https://github.com/Sifchain/sifchain-ui/blob/develop/ui/core/src/clients/wallets/cosmos/CosmosWalletProvider.ts#L93 -// https://github.com/Sifchain/sifchain-ui/blob/f8ac705c625af72521785c4cb61206173ed2080f/ui/core/src/clients/bridges/IBCBridge/IBCBridge.ts#L359 // 500000 for ibc const STARGATE_CLIENT_OPTIONS = { gasLimits: { - send: 80000, - ibcTransfer: 500000, - // transfer: 360000, transfer: 250000, - delegate: 250000, - undelegate: 250000, - redelegate: 250000, - withdrawRewards: 140000, - govVote: 250000, }, }; @@ -35,7 +23,9 @@ export const executeCosmosTransaction = async ( cosmosTx: CosmosTransaction, cosmosProvider: Keplr ): Promise => { - if (!cosmosProvider) throw SignerError.AssertionFailed('wallet is null!'); + if (!cosmosProvider) { + throw SignerError.AssertionFailed('wallet is null!'); + } try { const { memo, @@ -48,18 +38,21 @@ export const executeCosmosTransaction = async ( rpcUrl, } = cosmosTx.data; const msgsWithoutType = msgs.map((m) => ({ - ...manipulateMsg(m), + ...m, __type: undefined, '@type': undefined, })); - if (!chainId) + if (!chainId) { throw SignerError.AssertionFailed('chainId is undefined from server'); - if (!account_number) + } + if (!account_number) { throw SignerError.AssertionFailed( 'account_number is undefined from server' ); - if (!sequence) + } + if (!sequence) { throw SignerError.AssertionFailed('sequence is undefined from server'); + } if (signType === 'AMINO') { const signDoc = makeSignDoc( @@ -88,51 +81,7 @@ export const executeCosmosTransaction = async ( } catch (err) { throw new SignerError(SignerErrorCode.SIGN_TX_ERROR, undefined, err); } - let signedTx; - if (cosmosTx.data.protoMsgs.length > 0) { - signedTx = cosmos.tx.v1beta1.TxRaw.encode({ - bodyBytes: cosmos.tx.v1beta1.TxBody.encode({ - messages: cosmosTx.data.protoMsgs.map((m) => ({ - type_url: m.type_url, - value: new Uint8Array(m.value), - })), - memo: signResponse.signed.memo, - }).finish(), - authInfoBytes: cosmos.tx.v1beta1.AuthInfo.encode({ - signerInfos: [ - { - publicKey: { - type_url: '/cosmos.crypto.secp256k1.PubKey', - value: cosmos.crypto.secp256k1.PubKey.encode({ - key: Buffer.from( - signResponse.signature.pub_key.value, - 'base64' - ), - }).finish(), - }, - modeInfo: { - single: { - mode: cosmos.tx.signing.v1beta1.SignMode - .SIGN_MODE_LEGACY_AMINO_JSON, - }, - }, - sequence: Long.fromString(signResponse.signed.sequence), - }, - ], - fee: { - amount: signResponse.signed.fee.amount as any[], - gasLimit: Long.fromString(signResponse.signed.fee.gas), - }, - }).finish(), - signatures: [Buffer.from(signResponse.signature.signature, 'base64')], - }).finish(); - } else { - try { - signedTx = makeStdTx(signResponse.signed, signResponse.signature); - } catch (err) { - throw new SignerError(SignerErrorCode.SIGN_TX_ERROR, undefined, err); - } - } + const signedTx = getsignedTx(cosmosTx, signResponse); const result = await cosmosProvider.sendTx( chainId, signedTx, @@ -155,100 +104,86 @@ export const executeCosmosTransaction = async ( ? [{ denom: fee.amount[0].denom, amount: fee?.amount[0].amount }] : []; - const isIbcTx = - cosmosTx.data.msgs.filter( - (k) => - k.__type === 'DirectCosmosIBCTransferMessage' || - k.__type === 'CosmosIBCTransferMessage' - ).length > 0; - const tmpGas = isIbcTx - ? STARGATE_CLIENT_OPTIONS.gasLimits.ibcTransfer - : STARGATE_CLIENT_OPTIONS.gasLimits.transfer; - let gasLimit = tmpGas.toString(); - if ( - (cosmosTx.data.chainId === 'kaiyo-1' || isIbcTx) && - typeof cosmosTx.data.fee?.gas == 'string' - ) { - // if gasLimit is defined in server, use that instead of default for ibc transactions - gasLimit = Long.fromString(cosmosTx.data.fee?.gas).toString(); - } - - if (!!chainId && chainId?.toLowerCase()?.startsWith('juno-')) { - gasLimit = fee?.gas - ? fee?.gas - : STARGATE_CLIENT_OPTIONS.gasLimits.transfer.toString(); - } - const msgsWithoutType1 = msgs.map((m) => ({ - ...manipulateMsgForDirectIBC(m), - })); + const defaultGas = STARGATE_CLIENT_OPTIONS.gasLimits.transfer.toString(); + const gasLimit = + typeof fee?.gas === 'string' + ? Long.fromString(fee?.gas).toString() + : defaultGas; const broadcastTxRes = await sendingStargateClient.signAndBroadcast( cosmosTx.fromWalletAddress, - msgsWithoutType1 as any, + msgsWithoutType, { - // ...sendingStargateClient.fees.transfer, gas: gasLimit, amount: feeArray, } ); return broadcastTxRes.transactionHash; - } else { - throw new SignerError( - SignerErrorCode.OPERATION_UNSUPPORTED, - `Sign type for cosmos not supported, type: ${signType}` - ); } + throw new SignerError( + SignerErrorCode.OPERATION_UNSUPPORTED, + `Sign type for cosmos not supported, type: ${signType}` + ); } catch (err) { - if (SignerError.isSignerError(err)) throw err; - else throw new SignerError(SignerErrorCode.SEND_TX_ERROR, undefined, err); + console.log({ err }); + if (SignerError.isSignerError(err)) { + throw err; + } else { + throw new SignerError(SignerErrorCode.SEND_TX_ERROR, undefined, err); + } } }; -function manipulateMsg(m: any): any { - if (!m.__type) return m; - if (m.__type === 'DirectCosmosIBCTransferMessage') { - const result = { ...m }; - if (result.value.timeoutTimestamp) - result.value.timeoutTimestamp = Long.fromString( - result.value.timeoutTimestamp - ) as any; - if (!!result.value.timeoutHeight?.revisionHeight) - result.value.timeoutHeight.revisionHeight = Long.fromString( - result.value.timeoutHeight.revisionHeight - ) as any; - if (!!result.value.timeoutHeight?.revisionNumber) - result.value.timeoutHeight.revisionNumber = Long.fromString( - result.value.timeoutHeight.revisionNumber - ) as any; - return result; - } - return { ...m }; -} +export function getsignedTx( + cosmosTx: CosmosTransaction, + signResponse: AminoSignResponse +) { + let signedTx; -function manipulateMsgForDirectIBC(m: any): any { - if (m.__type === 'CosmosIBCTransferMessage') { - const x = m['@type']; - const sourcePort = m['value']['source_port']; - const sourceChannel = m['value']['source_channel']; - const timeoutTimestamp = m['value']['timeout_timestamp']; - const revisionNumber = m['value']['timeout_height']['revision_number']; - const revisionHeight = m['value']['timeout_height']['revision_height']; - delete m['@type']; - delete m['type']; - delete m['value']['source_port']; - delete m['value']['source_channel']; - delete m['value']['timeout_timestamp']; - delete m['value']['timeout_height']; - const result = { ...m }; - result.typeUrl = x; - result.value.timeoutTimestamp = timeoutTimestamp; - result.value.sourceChannel = sourceChannel; - result.value.sourcePort = sourcePort; - result.value.timeoutHeight = { - revisionNumber, - revisionHeight, - }; - result.__type = 'DirectCosmosIBCTransferMessage'; - return result; + if (cosmosTx.data.protoMsgs.length > 0) { + /* + * based on this link: + * https://github.com/chainapsis/keplr-wallet/blob/40211c8dd75ccbdc4c868db9dc22599f4cb952e9/packages/stores/src/account/cosmos.ts#L508 + */ + signedTx = cosmos.tx.v1beta1.TxRaw.encode({ + bodyBytes: cosmos.tx.v1beta1.TxBody.encode({ + messages: cosmosTx.data.protoMsgs.map((m) => ({ + type_url: m.type_url, + value: new Uint8Array(m.value), + })), + memo: signResponse.signed.memo, + }).finish(), + authInfoBytes: cosmos.tx.v1beta1.AuthInfo.encode({ + signerInfos: [ + { + publicKey: { + type_url: '/cosmos.crypto.secp256k1.PubKey', + value: cosmos.crypto.secp256k1.PubKey.encode({ + key: Buffer.from( + signResponse.signature.pub_key.value, + 'base64' + ), + }).finish(), + }, + modeInfo: { + single: { + mode: cosmos.tx.signing.v1beta1.SignMode + .SIGN_MODE_LEGACY_AMINO_JSON, + }, + }, + sequence: Long.fromString(signResponse.signed.sequence), + }, + ], + fee: { + amount: signResponse.signed.fee.amount as any[], + gasLimit: Long.fromString(signResponse.signed.fee.gas), + }, + }).finish(), + signatures: [Buffer.from(signResponse.signature.signature, 'base64')], + }).finish(); + } else { + throw SignerError.AssertionFailed( + 'protoMsgs is required in Amino messages' + ); } - return { ...m }; + return signedTx; } diff --git a/signers/signer-cosmos/src/index.ts b/signers/signer-cosmos/src/index.ts index 0ec91d62a5..4ef8a6471d 100644 --- a/signers/signer-cosmos/src/index.ts +++ b/signers/signer-cosmos/src/index.ts @@ -1,2 +1,2 @@ -export { DefaultCosmosSigner } from './signer'; -export { executeCosmosTransaction } from './helpers'; +export { DefaultCosmosSigner } from './signer.js'; +export { executeCosmosTransaction, getsignedTx } from './helpers.js'; diff --git a/signers/signer-cosmos/src/signer.ts b/signers/signer-cosmos/src/signer.ts index 55f9729d6a..2efe5ab694 100644 --- a/signers/signer-cosmos/src/signer.ts +++ b/signers/signer-cosmos/src/signer.ts @@ -1,6 +1,7 @@ -import { GenericSigner, CosmosTransaction } from 'rango-types'; -import { executeCosmosTransaction } from './helpers'; -import { Keplr } from '@keplr-wallet/types'; +import type { Keplr } from '@keplr-wallet/types'; +import type { CosmosTransaction, GenericSigner } from 'rango-types'; + +import { executeCosmosTransaction } from './helpers.js'; type CosmosExternalProvider = Keplr; @@ -16,7 +17,9 @@ export class DefaultCosmosSigner implements GenericSigner { address: string, chainId: string | null ): Promise { - if (!chainId) throw Error('ChainId is required'); + if (!chainId) { + throw Error('ChainId is required'); + } const { signature } = await this.provider.signArbitrary( chainId, address, @@ -25,7 +28,8 @@ export class DefaultCosmosSigner implements GenericSigner { return signature; } - async signAndSendTx(tx: CosmosTransaction): Promise { - return await executeCosmosTransaction(tx, this.provider); + async signAndSendTx(tx: CosmosTransaction): Promise<{ hash: string }> { + const hash = await executeCosmosTransaction(tx, this.provider); + return { hash }; } } diff --git a/signers/signer-cosmos/tsconfig.build.json b/signers/signer-cosmos/tsconfig.build.json new file mode 100644 index 0000000000..369287d895 --- /dev/null +++ b/signers/signer-cosmos/tsconfig.build.json @@ -0,0 +1,10 @@ +{ + // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs + "extends": "../../tsconfig.libnext.json", + "include": ["src", "types"], + "compilerOptions": { + "outDir": "dist", + "rootDir": "./src", + "lib": ["dom", "esnext"] + } +} diff --git a/signers/signer-cosmos/tsconfig.json b/signers/signer-cosmos/tsconfig.json index 2c85b2d991..a3a0b0f59d 100644 --- a/signers/signer-cosmos/tsconfig.json +++ b/signers/signer-cosmos/tsconfig.json @@ -1,35 +1 @@ -{ - // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs - "include": ["src", "types"], - "compilerOptions": { - "module": "esnext", - "lib": ["dom", "esnext"], - "importHelpers": true, - // output .d.ts declaration files for consumers - "declaration": true, - // output .js.map sourcemap files for consumers - "sourceMap": true, - // match output dir to input dir. e.g. dist/index instead of dist/src/index - "rootDir": "./src", - // stricter type-checking for stronger correctness. Recommended by TS - "strict": true, - // linter checks for common issues - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true, - // noUnused* overlap with @typescript-eslint/no-unused-vars, can disable if duplicative - "noUnusedLocals": true, - "noUnusedParameters": true, - // use Node's module resolution algorithm, instead of the legacy TS one - "moduleResolution": "node", - // transpile JSX to React.createElement - "jsx": "react", - // interop between ESM and CJS modules. Recommended by TS - "esModuleInterop": true, - // significant perf increase by skipping checking .d.ts files, particularly those in node_modules. Recommended by TS - "skipLibCheck": true, - // error out if import and file system have a casing mismatch. Recommended by TS - "forceConsistentCasingInFileNames": true, - // `tsdx build` ignores this option, but it is commonly used when type-checking separately with `tsc` - "noEmit": true, - } -} +{ "extends": "./tsconfig.build.json", "include": ["src", "tests"] } diff --git a/signers/signer-evm/CHANGELOG.md b/signers/signer-evm/CHANGELOG.md new file mode 100644 index 0000000000..68b16f0e97 --- /dev/null +++ b/signers/signer-evm/CHANGELOG.md @@ -0,0 +1,114 @@ +# [0.32.0](https://github.com/rango-exchange/rango-client/compare/signer-evm@0.31.0...signer-evm@0.32.0) (2024-11-12) + + + +# [0.31.0](https://github.com/rango-exchange/rango-client/compare/signer-evm@0.30.0...signer-evm@0.31.0) (2024-10-12) + + +### Bug Fixes + +* bump sdk and fix type issues ([d442208](https://github.com/rango-exchange/rango-client/commit/d4422083bf5dd27d5f509ce1db7f9560d05428c8)) + + + +# [0.30.0](https://github.com/rango-exchange/rango-client/compare/signer-evm@0.29.0...signer-evm@0.30.0) (2024-09-10) + + + +# [0.29.0](https://github.com/rango-exchange/rango-client/compare/signer-evm@0.28.0...signer-evm@0.29.0) (2024-08-11) + + + +# [0.28.0](https://github.com/rango-exchange/rango-client/compare/signer-evm@0.27.1...signer-evm@0.28.0) (2024-07-09) + + +### Bug Fixes + +* fix tx data for evm signers when transfering native tokens ([a5d9f6e](https://github.com/rango-exchange/rango-client/commit/a5d9f6e3f5bada210a05c0d1f5c57d7917bf869c)) + + + +## [0.27.1](https://github.com/rango-exchange/rango-client/compare/signer-evm@0.27.0...signer-evm@0.27.1) (2024-05-26) + + + +# [0.27.0](https://github.com/rango-exchange/rango-client/compare/signer-evm@0.26.0...signer-evm@0.27.0) (2024-05-25) + + +### Bug Fixes + +* exclude the gas price from evm transaction specifications in version 2 ([49c5005](https://github.com/rango-exchange/rango-client/commit/49c50058f717f439833fe4cff216e5a45fbe252d)) + + + +# [0.26.0](https://github.com/rango-exchange/rango-client/compare/signer-evm@0.25.0...signer-evm@0.26.0) (2024-02-20) + + + +# [0.25.0](https://github.com/rango-exchange/rango-client/compare/signer-evm@0.23.0...signer-evm@0.25.0) (2023-12-24) + + +### Bug Fixes + +* fix HMR for widget and playground ([8524820](https://github.com/rango-exchange/rango-client/commit/8524820f10cf0b8921f3db0c4f620ff98daa4103)) + + + +# [0.14.0](https://github.com/rango-exchange/rango-client/compare/signer-evm@0.13.0...signer-evm@0.14.0) (2023-08-03) + + + +# [0.13.0](https://github.com/rango-exchange/rango-client/compare/signer-evm@0.12.0...signer-evm@0.13.0) (2023-08-01) + + + +# [0.9.0](https://github.com/rango-exchange/rango-client/compare/signer-evm@0.8.0...signer-evm@0.9.0) (2023-07-31) + + +### Features + +* Support for WalletConnect 2 ([faedef0](https://github.com/rango-exchange/rango-client/commit/faedef0b5e6fc3c5ef881cbbe4ec05334cc1c910)) +* support safe wallet ([d04cbcd](https://github.com/rango-exchange/rango-client/commit/d04cbcd2a612755563512d9dff6f2312088d8b4d)) + + + +# [0.7.0](https://github.com/rango-exchange/rango-client/compare/signer-evm@0.6.0...signer-evm@0.7.0) (2023-07-11) + + + +# [0.6.0](https://github.com/rango-exchange/rango-client/compare/signer-evm@0.5.0...signer-evm@0.6.0) (2023-07-11) + + +### Bug Fixes + +* better parsing of evm rpc errors ([f23031a](https://github.com/rango-exchange/rango-client/commit/f23031ae14e6e841ee488591bd1bf58cfa7ca15b)) +* fix signer wait change network issues ([e453db6](https://github.com/rango-exchange/rango-client/commit/e453db6ccf7736e36e5ada0c29502be32254fe9c)) +* show tenderly error on call exception ([c218f49](https://github.com/rango-exchange/rango-client/commit/c218f49f3330706d9262b0cf3ec8e293e91e3729)) + + + +# [0.5.0](https://github.com/rango-exchange/rango-client/compare/signer-evm@0.4.0...signer-evm@0.5.0) (2023-05-31) + + + +# [0.4.0](https://github.com/rango-exchange/rango-client/compare/signer-evm@0.3.0...signer-evm@0.4.0) (2023-05-31) + + + +# [0.3.0](https://github.com/rango-exchange/rango-client/compare/signer-evm@0.2.0...signer-evm@0.3.0) (2023-05-30) + + + +# [0.2.0](https://github.com/rango-exchange/rango-client/compare/signer-evm@0.1.14...signer-evm@0.2.0) (2023-05-30) + + + +## [0.1.13](https://github.com/rango-exchange/rango-client/compare/signer-evm@0.1.12...signer-evm@0.1.13) (2023-05-15) + + +### Bug Fixes + +* update rango-types and fix notification bugs ([993f185](https://github.com/rango-exchange/rango-client/commit/993f185e0b8c5e5e15a2c65ba2d85d1f9c8daa90)) + + + diff --git a/signers/signer-evm/package.json b/signers/signer-evm/package.json index 6a946d5fb0..d17e975e90 100644 --- a/signers/signer-evm/package.json +++ b/signers/signer-evm/package.json @@ -1,46 +1,31 @@ { "name": "@rango-dev/signer-evm", - "version": "0.1.11", + "version": "0.32.0", "license": "MIT", - "module": "dist/signer-evm.esm.js", - "main": "dist/index.js", + "type": "module", + "source": "./src/index.ts", + "main": "./dist/index.js", + "exports": { + ".": "./dist/index.js" + }, "typings": "dist/index.d.ts", "files": [ "dist", "src" ], "scripts": { - "dev": "tsdx watch", - "build": "tsdx build --tsconfig ./tsconfig.json", - "test": "tsdx test", - "lint": "tsdx lint", - "size": "size-limit", - "analyze": "size-limit --why" - }, - "husky": { - "hooks": { - "pre-commit": "tsdx lint" - } + "build": "node ../../scripts/build/command.mjs --path signers/signer-evm", + "ts-check": "tsc --declaration --emitDeclarationOnly -p ./tsconfig.json", + "clean": "rimraf dist", + "format": "prettier --write '{.,src}/**/*.{ts,tsx}'", + "lint": "eslint \"**/*.{ts,tsx}\" --ignore-path ../../.eslintignore", + "test": "vitest", + "test:watch": "vitest --watch", + "test:coverage": "vitest run --coverage" }, - "prettier": { - "printWidth": 80, - "semi": true, - "singleQuote": true, - "trailingComma": "es5" - }, - "size-limit": [ - { - "path": "dist/signer-evm.cjs.production.min.js", - "limit": "10 KB" - }, - { - "path": "dist/signer-evm.esm.js", - "limit": "10 KB" - } - ], "dependencies": { - "ethers": "^5.7.2", - "rango-types": "^0.1.28" + "ethers": "^6.13.2", + "rango-types": "^0.1.74" }, "publishConfig": { "access": "public" diff --git a/signers/signer-evm/readme.md b/signers/signer-evm/readme.md index 8d78264136..0ae04d762f 100644 --- a/signers/signer-evm/readme.md +++ b/signers/signer-evm/readme.md @@ -1 +1,3 @@ -# @rango-dev/signer-evm \ No newline at end of file +# @rango-dev/signer-evm + +Signer for EVM Transacations generated by Rango API \ No newline at end of file diff --git a/signers/signer-evm/src/helper.ts b/signers/signer-evm/src/helper.ts new file mode 100644 index 0000000000..fa1ebbcca3 --- /dev/null +++ b/signers/signer-evm/src/helper.ts @@ -0,0 +1,88 @@ +import type { SignerError as SignerErrorType } from 'rango-types'; + +import { isError } from 'ethers'; +import { + RPCErrorCode as RangoRPCErrorCode, + SignerError, + SignerErrorCode, +} from 'rango-types'; + +export const cleanEvmError = (error: any): SignerErrorType => { + if (!error) { + return new SignerError(SignerErrorCode.SEND_TX_ERROR); + } + + if (SignerError.isSignerError(error)) { + return error; + } + + if (error.code) { + if (isError(error, 'UNKNOWN_ERROR')) { + const msg = error.error?.message || error.message; + return new SignerError( + SignerErrorCode.SEND_TX_ERROR, + undefined, + msg, + RangoRPCErrorCode.UNKNOWN_ERROR, + error + ); + } + + if (isError(error, 'ACTION_REJECTED')) { + const msg = error.shortMessage.replace('action', `'${error.action}'`); + return new SignerError( + SignerErrorCode.SEND_TX_ERROR, + undefined, + msg, + RangoRPCErrorCode.REJECTION, + error + ); + } + + const msg = error.shortMessage || error.message; + return new SignerError( + SignerErrorCode.SEND_TX_ERROR, + undefined, + msg, + RangoRPCErrorCode.UNKNOWN_ERROR, + error + ); + } + return new SignerError( + SignerErrorCode.SEND_TX_ERROR, + undefined, + error, + RangoRPCErrorCode.UNKNOWN_ERROR, + error + ); +}; + +interface TenderlyResponse { + error_message: string; +} + +export async function getTenderlyError( + chainId: string | undefined, + txHash: string +): Promise { + if (!chainId || !txHash) { + return; + } + const chainIdInt = parseInt(chainId); + try { + const url = `https://api.tenderly.co/api/v1/public-contract/${chainIdInt}/tx/${txHash}`; + const response = await fetch(url, { + method: 'GET', + }); + if (!response.ok) { + return; + } + const data: TenderlyResponse = await response.json(); + return data?.error_message; + } catch (error) { + return; + } +} + +export const waitMs = async (ms: number) => + new Promise((resolve) => setTimeout(resolve, ms)); diff --git a/signers/signer-evm/src/index.ts b/signers/signer-evm/src/index.ts index 90039574a6..e78ccc5711 100644 --- a/signers/signer-evm/src/index.ts +++ b/signers/signer-evm/src/index.ts @@ -1 +1,2 @@ -export { DefaultEvmSigner } from './signer'; +export { DefaultEvmSigner } from './signer.js'; +export { waitMs, cleanEvmError } from './helper.js'; diff --git a/signers/signer-evm/src/signer.ts b/signers/signer-evm/src/signer.ts index a01de7a41b..2b45bcf98c 100644 --- a/signers/signer-evm/src/signer.ts +++ b/signers/signer-evm/src/signer.ts @@ -1,18 +1,106 @@ -import { TransactionRequest } from '@ethersproject/abstract-provider'; -import { GenericSigner, SignerError, SignerErrorCode } from 'rango-types'; -import { EvmTransaction } from 'rango-types/lib/api/main'; -import { providers } from 'ethers'; +import type { + AbstractProvider, + Eip1193Provider, + TransactionRequest, + TransactionResponse, +} from 'ethers'; +import type { GenericSigner } from 'rango-types'; +import type { EvmTransaction } from 'rango-types/mainApi'; + +import { BrowserProvider, isError } from 'ethers'; +import { + RPCErrorCode as RangoRPCErrorCode, + SignerError, + SignerErrorCode, +} from 'rango-types'; + +import { cleanEvmError, getTenderlyError, waitMs } from './helper.js'; + +const waitWithMempoolCheck = async ( + provider: AbstractProvider, + tx: TransactionResponse, + txHash: string, + confirmations?: number +) => { + const TIMEOUT = 3_000; + let finished = false; + return await Promise.race([ + (async () => { + await tx.wait(confirmations); + finished = true; + })(), + (async () => { + while (!finished) { + await waitMs(TIMEOUT); + if (finished) { + return null; + } + try { + const mempoolTx = await provider.getTransaction(txHash); + if (!mempoolTx) { + return null; + } + } catch (error) { + console.log({ error }); + return null; + } + } + return null; + })(), + ]); +}; export class DefaultEvmSigner implements GenericSigner { - private signer: providers.JsonRpcSigner; + private provider: BrowserProvider; - constructor(provider: providers.ExternalProvider) { - this.signer = new providers.Web3Provider(provider).getSigner(); + constructor(provider: Eip1193Provider) { + this.provider = new BrowserProvider(provider); // provides read-only access to the provider + } + + static buildTx(evmTx: EvmTransaction, disableV2 = false): TransactionRequest { + const TO_STRING_BASE = 16; + let tx: TransactionRequest = {}; + /* + * it's better to pass 0x instead of undefined, otherwise some wallets could face issue + * https://github.com/WalletConnect/web3modal/issues/1082#issuecomment-1637793242 + */ + tx = { + data: evmTx.data || '0x', + }; + if (evmTx.from) { + tx = { ...tx, from: evmTx.from }; + } + if (evmTx.to) { + tx = { ...tx, to: evmTx.to }; + } + if (evmTx.value) { + tx = { ...tx, value: evmTx.value }; + } + if (evmTx.nonce) { + tx = { ...tx, nonce: parseInt(evmTx.nonce) }; + } + if (evmTx.gasLimit) { + tx = { ...tx, gasLimit: evmTx.gasLimit }; + } + if (!disableV2 && evmTx.maxFeePerGas && evmTx.maxPriorityFeePerGas) { + tx = { + ...tx, + maxFeePerGas: evmTx.maxFeePerGas, + maxPriorityFeePerGas: evmTx.maxPriorityFeePerGas, + }; + } else if (evmTx.gasPrice) { + tx = { + ...tx, + gasPrice: '0x' + parseInt(evmTx.gasPrice).toString(TO_STRING_BASE), + }; + } + return tx; } async signMessage(msg: string): Promise { try { - return await this.signer.signMessage(msg); + const signer = await this.provider.getSigner(); // provides access to write operations + return await signer.signMessage(msg); } catch (error) { throw new SignerError(SignerErrorCode.SIGN_TX_ERROR, undefined, error); } @@ -22,18 +110,23 @@ export class DefaultEvmSigner implements GenericSigner { tx: EvmTransaction, address: string, chainId: string | null - ): Promise { + ): Promise<{ hash: string; response: TransactionResponse }> { try { + const signer = await this.provider.getSigner(tx.from ?? undefined); + const transaction = DefaultEvmSigner.buildTx(tx); - const signerChainId = await this.signer.getChainId(); - const signerAddress = await this.signer.getAddress(); + + const signerChainId = (await this.provider.getNetwork()).chainId; + const signerAddress = await signer.getAddress(); + if ( !!chainId && !!signerChainId && - signerChainId.toString().toLowerCase() !== chainId?.toLowerCase() + signerChainId.toString() !== Number(chainId).toString() ) { throw new SignerError( SignerErrorCode.UNEXPECTED_BEHAVIOUR, + undefined, `Signer chainId: '${signerChainId}' doesn't match with required chainId: '${chainId}' for tx.` ); } @@ -44,51 +137,112 @@ export class DefaultEvmSigner implements GenericSigner { ) { throw new SignerError( SignerErrorCode.UNEXPECTED_BEHAVIOUR, + undefined, `Signer address: '${signerAddress.toLowerCase()}' doesn't match with required address: '${address.toLowerCase()}' for tx.` ); } - return (await this.signer.sendTransaction(transaction)).hash; + try { + const response = await signer.sendTransaction(transaction); + return { hash: response.hash, response }; + } catch (error: any) { + // retrying EIP-1559 without v2 related fields + if ( + !!error?.message && + typeof error.message === 'string' && + error.message.indexOf('EIP-1559') !== -1 + ) { + console.log('retrying EIP-1559 error without v2 fields ...'); + const transaction = DefaultEvmSigner.buildTx(tx, true); + const response = await signer.sendTransaction(transaction); + return { hash: response.hash, response }; + } + throw error; + } } catch (error) { - let message = undefined; + throw cleanEvmError(error); + } + } + + async wait( + txHash: string, + chainId?: string, + txResponse?: TransactionResponse, + confirmations?: number + ): Promise<{ hash: string; response?: TransactionResponse }> { + try { + /* + * if we have transaction response, use that to wait + * otherwise, try to get tx response from the wallet provider + */ + if (txResponse) { + // if we use waitWithMempoolCheck here, we can't detect replaced tx anymore + await txResponse?.wait(confirmations); + return { hash: txHash }; + } + + // ignore wait if wallet not connected yet + if (!this.provider) { + return { hash: txHash }; + } + + /* + * don't proceed if signer chain changed or chain id is not specified + * because if user change the wallet network, we receive null on getTransaction + */ + if (!chainId) { + return { hash: txHash }; + } + const signerChainId = (await this.provider.getNetwork()).chainId; if ( - error && - error.hasOwnProperty('message') && - error.hasOwnProperty('code') && - error.hasOwnProperty('reason') - ) { - message = `Error sending the tx (code: ${(error as any).code})`; - } else if ( - error && - error.hasOwnProperty('code') && - error.hasOwnProperty('message') && - (error as any)?.code === -32603 + !signerChainId || + Number(chainId).toString() !== signerChainId.toString() ) { - throw new SignerError( - SignerErrorCode.SEND_TX_ERROR, - undefined, - (error as any).message - ); + return { hash: txHash }; } - throw new SignerError(SignerErrorCode.SEND_TX_ERROR, message, error); - } - } - static buildTx(evmTx: EvmTransaction): TransactionRequest { - let tx: TransactionRequest = {}; - if (!!evmTx.from) tx = { ...tx, from: evmTx.from }; - if (!!evmTx.to) tx = { ...tx, to: evmTx.to }; - if (!!evmTx.data) tx = { ...tx, data: evmTx.data }; - if (!!evmTx.value) tx = { ...tx, value: evmTx.value }; - if (!!evmTx.nonce) tx = { ...tx, nonce: evmTx.nonce }; - if (!!evmTx.gasLimit) tx = { ...tx, gasLimit: evmTx.gasLimit }; - if (!!evmTx.gasPrice) - tx = { - ...tx, - gasPrice: '0x' + parseInt(evmTx.gasPrice).toString(16), - }; - if (!!evmTx.maxFeePerGas) tx = { ...tx, maxFeePerGas: evmTx.maxFeePerGas }; - if (!!evmTx.maxPriorityFeePerGas) - tx = { ...tx, maxPriorityFeePerGas: evmTx.maxPriorityFeePerGas }; - return tx; + const tx = await this.provider.getTransaction(txHash); + if (!tx) { + throw Error(`Transaction hash '${txHash}' not found in blockchain.`); + } + + await waitWithMempoolCheck(this.provider, tx, txHash, confirmations); + return { hash: txHash }; + } catch (error) { + if (isError(error, 'TRANSACTION_REPLACED')) { + const reason = error.reason; + if (reason === 'cancelled') { + throw new SignerError( + SignerErrorCode.SEND_TX_ERROR, + undefined, + 'Transaction replaced and canceled by user', + undefined, + error + ); + } + return { hash: error.replacement.hash, response: error.replacement }; + } else if (isError(error, 'CALL_EXCEPTION')) { + const tError = await getTenderlyError(chainId, txHash); + if (!!tError) { + throw new SignerError( + SignerErrorCode.TX_FAILED_IN_BLOCKCHAIN, + 'Trannsaction failed in blockchain', + tError, + RangoRPCErrorCode.CALL_EXCEPTION, + error + ); + } else { + /** + * In cases where the is no error returen from tenderly, we could ignore + * the error and proceed with check status flow. + */ + return { hash: txHash }; + } + } + /** + * Ignore other errors in confirming transaction and proceed with check status flow, + * Some times rpc gives internal error or other type of errors even if the transaction succeeded + */ + return { hash: txHash }; + } } } diff --git a/signers/signer-evm/tests/index.test.ts b/signers/signer-evm/tests/index.test.ts new file mode 100644 index 0000000000..a9b9dc91e6 --- /dev/null +++ b/signers/signer-evm/tests/index.test.ts @@ -0,0 +1,63 @@ +import { beforeEach, describe, expect, it } from 'vitest'; + +import { MockEvmProvider } from '../../../test-utils/mock.evm.provider.js'; +import { DefaultEvmSigner } from '../src/index.js'; + +import { address, EVM_TX, privateKey } from './mock.data.js'; + +describe('Test EVM Signer', () => { + let provider: MockEvmProvider; + let signer: DefaultEvmSigner; + + beforeEach(() => { + provider = new MockEvmProvider({ + address, + privateKey, + networkVersion: 1337, + debug: false, + }); + signer = new DefaultEvmSigner(provider); + }); + + describe('personal_sign', () => { + it('returns the correct signature for the message', async () => { + const signed = await signer.signMessage('Hello World'); + + expect(signed).toEqual( + '0xc22ee8f90ace365af000af37078743d4e72136a61a4f5838a537f573af45911f1445a2dfae662c79d98ce865cf134e7f4be896f19f59a6ed4dfe34c52c80c8581b' + ); + }); + }); + + describe('sign and send Tx', () => { + it(`the sign fails when doesn't match chains`, async () => { + try { + await signer.signAndSendTx(EVM_TX, address, '1338'); + } catch (e) { + expect(e.root).toMatch( + `Signer chainId: '1337' doesn't match with required chainId: '1338' for tx.` + ); + } + }); + + it(`the sign fails when doesn't match addresses`, async () => { + try { + await signer.signAndSendTx(EVM_TX, 'sample address', '1337'); + } catch (e) { + expect(e.root).toMatch( + `Signer address: '0x17ec8597ff92c3f44523bdc65bf0f1be632917ff' doesn't match with required address: 'sample address' for tx.` + ); + } + }); + + it(`the sign fails when doesn't match addresses`, async () => { + try { + expect( + await signer.signAndSendTx(EVM_TX, address, '1337') + ).toBeDefined(); + } catch (e) { + expect(e).toBeDefined(); + } + }); + }); +}); diff --git a/signers/signer-evm/tests/mock.data.ts b/signers/signer-evm/tests/mock.data.ts new file mode 100644 index 0000000000..4d43ebee82 --- /dev/null +++ b/signers/signer-evm/tests/mock.data.ts @@ -0,0 +1,22 @@ +import type { EvmTransaction } from 'rango-types/mainApi'; + +import { TransactionType } from 'rango-types'; + +export const address = '0x17ec8597ff92C3F44523bDc65BF0f1bE632917ff'; +export const privateKey = + 'de926db3012af759b4f24b5a51ef6afa397f04670f634aa4f48d4480417007f3'; + +export const EVM_TX: EvmTransaction = { + type: TransactionType.EVM, + blockChain: 'ETH', + isApprovalTx: false, + from: address, + to: '0x69460570c93f9DE5E2edbC3052bf10125f0Ca22d', + data: '0xb17d0e6e0000000000000000000000000000000017cd96c9a71941e692ae0a7241bd5c250000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000046f9e29952a000000000000000000000000000000000000000000000000000000001d1a94a20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012309ce540000000000000000000000000002702d89c1c8658b49c45dd460deebcc45faec03c0000000000000000000000000000000000000000000000000000000002400738000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005423e28219d6d568dcf62a8134d623e6f4a1c2df000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000001111111254eeb25477b68fb85ed929f73a9605820000000000000000000000001111111254eeb25477b68fb85ed929f73a9605820000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000046f9e29952a00000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000c80502b1c500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000046f9e29952a00000000000000000000000000000000000000000000000000000000000024007380000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000180000000000000003b6d0340b4e16d0168e52d35cacd2c6185b44281ec28c9dc95e51660000000000000000000000000000000000000000000000000', + value: '0x470de4df820000', + gasLimit: '0x49329', + gasPrice: null, + maxPriorityFeePerGas: '2342363475', + maxFeePerGas: '25832357338', + nonce: null, +}; diff --git a/signers/signer-evm/tsconfig.build.json b/signers/signer-evm/tsconfig.build.json new file mode 100644 index 0000000000..4f5441876c --- /dev/null +++ b/signers/signer-evm/tsconfig.build.json @@ -0,0 +1,11 @@ +{ + // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs + "extends": "../../tsconfig.libnext.json", + "include": ["src", "types"], + "compilerOptions": { + "outDir": "dist", + "rootDir": "./src", + "lib": ["dom", "esnext"] + // match output dir to input dir. e.g. dist/index instead of dist/src/index + } +} diff --git a/signers/signer-evm/tsconfig.json b/signers/signer-evm/tsconfig.json index 2c85b2d991..a3a0b0f59d 100644 --- a/signers/signer-evm/tsconfig.json +++ b/signers/signer-evm/tsconfig.json @@ -1,35 +1 @@ -{ - // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs - "include": ["src", "types"], - "compilerOptions": { - "module": "esnext", - "lib": ["dom", "esnext"], - "importHelpers": true, - // output .d.ts declaration files for consumers - "declaration": true, - // output .js.map sourcemap files for consumers - "sourceMap": true, - // match output dir to input dir. e.g. dist/index instead of dist/src/index - "rootDir": "./src", - // stricter type-checking for stronger correctness. Recommended by TS - "strict": true, - // linter checks for common issues - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true, - // noUnused* overlap with @typescript-eslint/no-unused-vars, can disable if duplicative - "noUnusedLocals": true, - "noUnusedParameters": true, - // use Node's module resolution algorithm, instead of the legacy TS one - "moduleResolution": "node", - // transpile JSX to React.createElement - "jsx": "react", - // interop between ESM and CJS modules. Recommended by TS - "esModuleInterop": true, - // significant perf increase by skipping checking .d.ts files, particularly those in node_modules. Recommended by TS - "skipLibCheck": true, - // error out if import and file system have a casing mismatch. Recommended by TS - "forceConsistentCasingInFileNames": true, - // `tsdx build` ignores this option, but it is commonly used when type-checking separately with `tsc` - "noEmit": true, - } -} +{ "extends": "./tsconfig.build.json", "include": ["src", "tests"] } diff --git a/signers/signer-evm/yarn.lock b/signers/signer-evm/yarn.lock deleted file mode 100644 index d27ecb227c..0000000000 --- a/signers/signer-evm/yarn.lock +++ /dev/null @@ -1,471 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@ethersproject/abi@5.7.0", "@ethersproject/abi@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.7.0.tgz#b3f3e045bbbeed1af3947335c247ad625a44e449" - integrity sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA== - dependencies: - "@ethersproject/address" "^5.7.0" - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/constants" "^5.7.0" - "@ethersproject/hash" "^5.7.0" - "@ethersproject/keccak256" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/strings" "^5.7.0" - -"@ethersproject/abstract-provider@5.7.0", "@ethersproject/abstract-provider@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/abstract-provider/-/abstract-provider-5.7.0.tgz#b0a8550f88b6bf9d51f90e4795d48294630cb9ef" - integrity sha512-R41c9UkchKCpAqStMYUpdunjo3pkEvZC3FAwZn5S5MGbXoMQOHIdHItezTETxAO5bevtMApSyEhn9+CHcDsWBw== - dependencies: - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/networks" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/transactions" "^5.7.0" - "@ethersproject/web" "^5.7.0" - -"@ethersproject/abstract-signer@5.7.0", "@ethersproject/abstract-signer@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/abstract-signer/-/abstract-signer-5.7.0.tgz#13f4f32117868452191a4649723cb086d2b596b2" - integrity sha512-a16V8bq1/Cz+TGCkE2OPMTOUDLS3grCpdjoJCYNnVBbdYEMSgKrU0+B90s8b6H+ByYTBZN7a3g76jdIJi7UfKQ== - dependencies: - "@ethersproject/abstract-provider" "^5.7.0" - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - -"@ethersproject/address@5.7.0", "@ethersproject/address@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/address/-/address-5.7.0.tgz#19b56c4d74a3b0a46bfdbb6cfcc0a153fc697f37" - integrity sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA== - dependencies: - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/keccak256" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/rlp" "^5.7.0" - -"@ethersproject/base64@5.7.0", "@ethersproject/base64@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/base64/-/base64-5.7.0.tgz#ac4ee92aa36c1628173e221d0d01f53692059e1c" - integrity sha512-Dr8tcHt2mEbsZr/mwTPIQAf3Ai0Bks/7gTw9dSqk1mQvhW3XvRlmDJr/4n+wg1JmCl16NZue17CDh8xb/vZ0sQ== - dependencies: - "@ethersproject/bytes" "^5.7.0" - -"@ethersproject/basex@5.7.0", "@ethersproject/basex@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/basex/-/basex-5.7.0.tgz#97034dc7e8938a8ca943ab20f8a5e492ece4020b" - integrity sha512-ywlh43GwZLv2Voc2gQVTKBoVQ1mti3d8HK5aMxsfu/nRDnMmNqaSJ3r3n85HBByT8OpoY96SXM1FogC533T4zw== - dependencies: - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - -"@ethersproject/bignumber@5.7.0", "@ethersproject/bignumber@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/bignumber/-/bignumber-5.7.0.tgz#e2f03837f268ba655ffba03a57853e18a18dc9c2" - integrity sha512-n1CAdIHRWjSucQO3MC1zPSVgV/6dy/fjL9pMrPP9peL+QxEg9wOsVqwD4+818B6LUEtaXzVHQiuivzRoxPxUGw== - dependencies: - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - bn.js "^5.2.1" - -"@ethersproject/bytes@5.7.0", "@ethersproject/bytes@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/bytes/-/bytes-5.7.0.tgz#a00f6ea8d7e7534d6d87f47188af1148d71f155d" - integrity sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A== - dependencies: - "@ethersproject/logger" "^5.7.0" - -"@ethersproject/constants@5.7.0", "@ethersproject/constants@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/constants/-/constants-5.7.0.tgz#df80a9705a7e08984161f09014ea012d1c75295e" - integrity sha512-DHI+y5dBNvkpYUMiRQyxRBYBefZkJfo70VUkUAsRjcPs47muV9evftfZ0PJVCXYbAiCgght0DtcF9srFQmIgWA== - dependencies: - "@ethersproject/bignumber" "^5.7.0" - -"@ethersproject/contracts@5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/contracts/-/contracts-5.7.0.tgz#c305e775abd07e48aa590e1a877ed5c316f8bd1e" - integrity sha512-5GJbzEU3X+d33CdfPhcyS+z8MzsTrBGk/sc+G+59+tPa9yFkl6HQ9D6L0QMgNTA9q8dT0XKxxkyp883XsQvbbg== - dependencies: - "@ethersproject/abi" "^5.7.0" - "@ethersproject/abstract-provider" "^5.7.0" - "@ethersproject/abstract-signer" "^5.7.0" - "@ethersproject/address" "^5.7.0" - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/constants" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/transactions" "^5.7.0" - -"@ethersproject/hash@5.7.0", "@ethersproject/hash@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/hash/-/hash-5.7.0.tgz#eb7aca84a588508369562e16e514b539ba5240a7" - integrity sha512-qX5WrQfnah1EFnO5zJv1v46a8HW0+E5xuBBDTwMFZLuVTx0tbU2kkx15NqdjxecrLGatQN9FGQKpb1FKdHCt+g== - dependencies: - "@ethersproject/abstract-signer" "^5.7.0" - "@ethersproject/address" "^5.7.0" - "@ethersproject/base64" "^5.7.0" - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/keccak256" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/strings" "^5.7.0" - -"@ethersproject/hdnode@5.7.0", "@ethersproject/hdnode@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/hdnode/-/hdnode-5.7.0.tgz#e627ddc6b466bc77aebf1a6b9e47405ca5aef9cf" - integrity sha512-OmyYo9EENBPPf4ERhR7oj6uAtUAhYGqOnIS+jE5pTXvdKBS99ikzq1E7Iv0ZQZ5V36Lqx1qZLeak0Ra16qpeOg== - dependencies: - "@ethersproject/abstract-signer" "^5.7.0" - "@ethersproject/basex" "^5.7.0" - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/pbkdf2" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/sha2" "^5.7.0" - "@ethersproject/signing-key" "^5.7.0" - "@ethersproject/strings" "^5.7.0" - "@ethersproject/transactions" "^5.7.0" - "@ethersproject/wordlists" "^5.7.0" - -"@ethersproject/json-wallets@5.7.0", "@ethersproject/json-wallets@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/json-wallets/-/json-wallets-5.7.0.tgz#5e3355287b548c32b368d91014919ebebddd5360" - integrity sha512-8oee5Xgu6+RKgJTkvEMl2wDgSPSAQ9MB/3JYjFV9jlKvcYHUXZC+cQp0njgmxdHkYWn8s6/IqIZYm0YWCjO/0g== - dependencies: - "@ethersproject/abstract-signer" "^5.7.0" - "@ethersproject/address" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/hdnode" "^5.7.0" - "@ethersproject/keccak256" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/pbkdf2" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/random" "^5.7.0" - "@ethersproject/strings" "^5.7.0" - "@ethersproject/transactions" "^5.7.0" - aes-js "3.0.0" - scrypt-js "3.0.1" - -"@ethersproject/keccak256@5.7.0", "@ethersproject/keccak256@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/keccak256/-/keccak256-5.7.0.tgz#3186350c6e1cd6aba7940384ec7d6d9db01f335a" - integrity sha512-2UcPboeL/iW+pSg6vZ6ydF8tCnv3Iu/8tUmLLzWWGzxWKFFqOBQFLo6uLUv6BDrLgCDfN28RJ/wtByx+jZ4KBg== - dependencies: - "@ethersproject/bytes" "^5.7.0" - js-sha3 "0.8.0" - -"@ethersproject/logger@5.7.0", "@ethersproject/logger@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/logger/-/logger-5.7.0.tgz#6ce9ae168e74fecf287be17062b590852c311892" - integrity sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig== - -"@ethersproject/networks@5.7.1", "@ethersproject/networks@^5.7.0": - version "5.7.1" - resolved "https://registry.yarnpkg.com/@ethersproject/networks/-/networks-5.7.1.tgz#118e1a981d757d45ccea6bb58d9fd3d9db14ead6" - integrity sha512-n/MufjFYv3yFcUyfhnXotyDlNdFb7onmkSy8aQERi2PjNcnWQ66xXxa3XlS8nCcA8aJKJjIIMNJTC7tu80GwpQ== - dependencies: - "@ethersproject/logger" "^5.7.0" - -"@ethersproject/pbkdf2@5.7.0", "@ethersproject/pbkdf2@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/pbkdf2/-/pbkdf2-5.7.0.tgz#d2267d0a1f6e123f3771007338c47cccd83d3102" - integrity sha512-oR/dBRZR6GTyaofd86DehG72hY6NpAjhabkhxgr3X2FpJtJuodEl2auADWBZfhDHgVCbu3/H/Ocq2uC6dpNjjw== - dependencies: - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/sha2" "^5.7.0" - -"@ethersproject/properties@5.7.0", "@ethersproject/properties@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/properties/-/properties-5.7.0.tgz#a6e12cb0439b878aaf470f1902a176033067ed30" - integrity sha512-J87jy8suntrAkIZtecpxEPxY//szqr1mlBaYlQ0r4RCaiD2hjheqF9s1LVE8vVuJCXisjIP+JgtK/Do54ej4Sw== - dependencies: - "@ethersproject/logger" "^5.7.0" - -"@ethersproject/providers@5.7.2": - version "5.7.2" - resolved "https://registry.yarnpkg.com/@ethersproject/providers/-/providers-5.7.2.tgz#f8b1a4f275d7ce58cf0a2eec222269a08beb18cb" - integrity sha512-g34EWZ1WWAVgr4aptGlVBF8mhl3VWjv+8hoAnzStu8Ah22VHBsuGzP17eb6xDVRzw895G4W7vvx60lFFur/1Rg== - dependencies: - "@ethersproject/abstract-provider" "^5.7.0" - "@ethersproject/abstract-signer" "^5.7.0" - "@ethersproject/address" "^5.7.0" - "@ethersproject/base64" "^5.7.0" - "@ethersproject/basex" "^5.7.0" - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/constants" "^5.7.0" - "@ethersproject/hash" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/networks" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/random" "^5.7.0" - "@ethersproject/rlp" "^5.7.0" - "@ethersproject/sha2" "^5.7.0" - "@ethersproject/strings" "^5.7.0" - "@ethersproject/transactions" "^5.7.0" - "@ethersproject/web" "^5.7.0" - bech32 "1.1.4" - ws "7.4.6" - -"@ethersproject/random@5.7.0", "@ethersproject/random@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/random/-/random-5.7.0.tgz#af19dcbc2484aae078bb03656ec05df66253280c" - integrity sha512-19WjScqRA8IIeWclFme75VMXSBvi4e6InrUNuaR4s5pTF2qNhcGdCUwdxUVGtDDqC00sDLCO93jPQoDUH4HVmQ== - dependencies: - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - -"@ethersproject/rlp@5.7.0", "@ethersproject/rlp@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/rlp/-/rlp-5.7.0.tgz#de39e4d5918b9d74d46de93af80b7685a9c21304" - integrity sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w== - dependencies: - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - -"@ethersproject/sha2@5.7.0", "@ethersproject/sha2@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/sha2/-/sha2-5.7.0.tgz#9a5f7a7824ef784f7f7680984e593a800480c9fb" - integrity sha512-gKlH42riwb3KYp0reLsFTokByAKoJdgFCwI+CCiX/k+Jm2mbNs6oOaCjYQSlI1+XBVejwH2KrmCbMAT/GnRDQw== - dependencies: - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - hash.js "1.1.7" - -"@ethersproject/signing-key@5.7.0", "@ethersproject/signing-key@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/signing-key/-/signing-key-5.7.0.tgz#06b2df39411b00bc57c7c09b01d1e41cf1b16ab3" - integrity sha512-MZdy2nL3wO0u7gkB4nA/pEf8lu1TlFswPNmy8AiYkfKTdO6eXBJyUdmHO/ehm/htHw9K/qF8ujnTyUAD+Ry54Q== - dependencies: - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - bn.js "^5.2.1" - elliptic "6.5.4" - hash.js "1.1.7" - -"@ethersproject/solidity@5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/solidity/-/solidity-5.7.0.tgz#5e9c911d8a2acce2a5ebb48a5e2e0af20b631cb8" - integrity sha512-HmabMd2Dt/raavyaGukF4XxizWKhKQ24DoLtdNbBmNKUOPqwjsKQSdV9GQtj9CBEea9DlzETlVER1gYeXXBGaA== - dependencies: - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/keccak256" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/sha2" "^5.7.0" - "@ethersproject/strings" "^5.7.0" - -"@ethersproject/strings@5.7.0", "@ethersproject/strings@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/strings/-/strings-5.7.0.tgz#54c9d2a7c57ae8f1205c88a9d3a56471e14d5ed2" - integrity sha512-/9nu+lj0YswRNSH0NXYqrh8775XNyEdUQAuf3f+SmOrnVewcJ5SBNAjF7lpgehKi4abvNNXyf+HX86czCdJ8Mg== - dependencies: - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/constants" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - -"@ethersproject/transactions@5.7.0", "@ethersproject/transactions@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/transactions/-/transactions-5.7.0.tgz#91318fc24063e057885a6af13fdb703e1f993d3b" - integrity sha512-kmcNicCp1lp8qanMTC3RIikGgoJ80ztTyvtsFvCYpSCfkjhD0jZ2LOrnbcuxuToLIUYYf+4XwD1rP+B/erDIhQ== - dependencies: - "@ethersproject/address" "^5.7.0" - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/constants" "^5.7.0" - "@ethersproject/keccak256" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/rlp" "^5.7.0" - "@ethersproject/signing-key" "^5.7.0" - -"@ethersproject/units@5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/units/-/units-5.7.0.tgz#637b563d7e14f42deeee39245275d477aae1d8b1" - integrity sha512-pD3xLMy3SJu9kG5xDGI7+xhTEmGXlEqXU4OfNapmfnxLVY4EMSSRp7j1k7eezutBPH7RBN/7QPnwR7hzNlEFeg== - dependencies: - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/constants" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - -"@ethersproject/wallet@5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/wallet/-/wallet-5.7.0.tgz#4e5d0790d96fe21d61d38fb40324e6c7ef350b2d" - integrity sha512-MhmXlJXEJFBFVKrDLB4ZdDzxcBxQ3rLyCkhNqVu3CDYvR97E+8r01UgrI+TI99Le+aYm/in/0vp86guJuM7FCA== - dependencies: - "@ethersproject/abstract-provider" "^5.7.0" - "@ethersproject/abstract-signer" "^5.7.0" - "@ethersproject/address" "^5.7.0" - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/hash" "^5.7.0" - "@ethersproject/hdnode" "^5.7.0" - "@ethersproject/json-wallets" "^5.7.0" - "@ethersproject/keccak256" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/random" "^5.7.0" - "@ethersproject/signing-key" "^5.7.0" - "@ethersproject/transactions" "^5.7.0" - "@ethersproject/wordlists" "^5.7.0" - -"@ethersproject/web@5.7.1", "@ethersproject/web@^5.7.0": - version "5.7.1" - resolved "https://registry.yarnpkg.com/@ethersproject/web/-/web-5.7.1.tgz#de1f285b373149bee5928f4eb7bcb87ee5fbb4ae" - integrity sha512-Gueu8lSvyjBWL4cYsWsjh6MtMwM0+H4HvqFPZfB6dV8ctbP9zFAO73VG1cMWae0FLPCtz0peKPpZY8/ugJJX2w== - dependencies: - "@ethersproject/base64" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/strings" "^5.7.0" - -"@ethersproject/wordlists@5.7.0", "@ethersproject/wordlists@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/wordlists/-/wordlists-5.7.0.tgz#8fb2c07185d68c3e09eb3bfd6e779ba2774627f5" - integrity sha512-S2TFNJNfHWVHNE6cNDjbVlZ6MgE17MIxMbMg2zv3wn+3XSJGosL1m9ZVv3GXCf/2ymSsQ+hRI5IzoMJTG6aoVA== - dependencies: - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/hash" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/strings" "^5.7.0" - -aes-js@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-3.0.0.tgz#e21df10ad6c2053295bcbb8dab40b09dbea87e4d" - integrity sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw== - -bech32@1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/bech32/-/bech32-1.1.4.tgz#e38c9f37bf179b8eb16ae3a772b40c356d4832e9" - integrity sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ== - -bn.js@^4.11.9: - version "4.12.0" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" - integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== - -bn.js@^5.2.1: - version "5.2.1" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.1.tgz#0bc527a6a0d18d0aa8d5b0538ce4a77dccfa7b70" - integrity sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ== - -brorand@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" - integrity sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w== - -elliptic@6.5.4: - version "6.5.4" - resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb" - integrity sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ== - dependencies: - bn.js "^4.11.9" - brorand "^1.1.0" - hash.js "^1.0.0" - hmac-drbg "^1.0.1" - inherits "^2.0.4" - minimalistic-assert "^1.0.1" - minimalistic-crypto-utils "^1.0.1" - -ethers@^5.7.2: - version "5.7.2" - resolved "https://registry.yarnpkg.com/ethers/-/ethers-5.7.2.tgz#3a7deeabbb8c030d4126b24f84e525466145872e" - integrity sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg== - dependencies: - "@ethersproject/abi" "5.7.0" - "@ethersproject/abstract-provider" "5.7.0" - "@ethersproject/abstract-signer" "5.7.0" - "@ethersproject/address" "5.7.0" - "@ethersproject/base64" "5.7.0" - "@ethersproject/basex" "5.7.0" - "@ethersproject/bignumber" "5.7.0" - "@ethersproject/bytes" "5.7.0" - "@ethersproject/constants" "5.7.0" - "@ethersproject/contracts" "5.7.0" - "@ethersproject/hash" "5.7.0" - "@ethersproject/hdnode" "5.7.0" - "@ethersproject/json-wallets" "5.7.0" - "@ethersproject/keccak256" "5.7.0" - "@ethersproject/logger" "5.7.0" - "@ethersproject/networks" "5.7.1" - "@ethersproject/pbkdf2" "5.7.0" - "@ethersproject/properties" "5.7.0" - "@ethersproject/providers" "5.7.2" - "@ethersproject/random" "5.7.0" - "@ethersproject/rlp" "5.7.0" - "@ethersproject/sha2" "5.7.0" - "@ethersproject/signing-key" "5.7.0" - "@ethersproject/solidity" "5.7.0" - "@ethersproject/strings" "5.7.0" - "@ethersproject/transactions" "5.7.0" - "@ethersproject/units" "5.7.0" - "@ethersproject/wallet" "5.7.0" - "@ethersproject/web" "5.7.1" - "@ethersproject/wordlists" "5.7.0" - -hash.js@1.1.7, hash.js@^1.0.0, hash.js@^1.0.3: - version "1.1.7" - resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" - integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== - dependencies: - inherits "^2.0.3" - minimalistic-assert "^1.0.1" - -hmac-drbg@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" - integrity sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg== - dependencies: - hash.js "^1.0.3" - minimalistic-assert "^1.0.0" - minimalistic-crypto-utils "^1.0.1" - -inherits@^2.0.3, inherits@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" - integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== - -js-sha3@0.8.0: - version "0.8.0" - resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840" - integrity sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q== - -minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" - integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== - -minimalistic-crypto-utils@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" - integrity sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg== - -rango-types@^0.1.17: - version "0.1.17" - resolved "https://registry.yarnpkg.com/rango-types/-/rango-types-0.1.17.tgz#3c7cc26f45bc2fe1c248bbcc512a253c12b4263f" - integrity sha512-LH6XovZv3hdUsFqN6PVMWqTGqv0ZYBM2L4da46sGmq26EQx4Jpzg7Hbvy9Gk1Ak+Hq8r8zVmvDgFgMnkN9He0Q== - -scrypt-js@3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/scrypt-js/-/scrypt-js-3.0.1.tgz#d314a57c2aef69d1ad98a138a21fe9eafa9ee312" - integrity sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA== - -ws@7.4.6: - version "7.4.6" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c" - integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A== diff --git a/signers/signer-solana/CHANGELOG.md b/signers/signer-solana/CHANGELOG.md new file mode 100644 index 0000000000..0ada785883 --- /dev/null +++ b/signers/signer-solana/CHANGELOG.md @@ -0,0 +1,147 @@ +# [0.35.0](https://github.com/rango-exchange/rango-client/compare/signer-solana@0.34.0...signer-solana@0.35.0) (2024-11-27) + + + +# [0.34.0](https://github.com/rango-exchange/rango-client/compare/signer-solana@0.33.0...signer-solana@0.34.0) (2024-11-12) + + +### Bug Fixes + +* fix solana signer by migrating confirm transaction to get signature statuses ([07b2b89](https://github.com/rango-exchange/rango-client/commit/07b2b89fec1d22a09ed9215691ff296a6e77a382)) + + + +# [0.33.0](https://github.com/rango-exchange/rango-client/compare/signer-solana@0.32.0...signer-solana@0.33.0) (2024-10-12) + + +### Bug Fixes + +* bump sdk and fix type issues ([d442208](https://github.com/rango-exchange/rango-client/commit/d4422083bf5dd27d5f509ce1db7f9560d05428c8)) +* resolve issues with the sign message method for certain solana providers ([cbe83a3](https://github.com/rango-exchange/rango-client/commit/cbe83a3da8b48560b206fc2a7fa7cf062cdeaa23)) + + +### Features + +* add signature to versioned transactions ([d7f374b](https://github.com/rango-exchange/rango-client/commit/d7f374b460dc6a51e761614235575eb924f8d71a)) + + + +# [0.32.0](https://github.com/rango-exchange/rango-client/compare/signer-solana@0.31.0...signer-solana@0.32.0) (2024-09-10) + + +### Bug Fixes + +* update signMessage in the default Solana signer to return a base58 string instead of base64 ([b60609b](https://github.com/rango-exchange/rango-client/commit/b60609b71d55ff205324aee87fb440d23cba5c79)) + + + +# [0.31.0](https://github.com/rango-exchange/rango-client/compare/signer-solana@0.30.0...signer-solana@0.31.0) (2024-08-11) + + +### Features + +* implement sign message method for providers with a custom signer ([cf9515f](https://github.com/rango-exchange/rango-client/commit/cf9515feb5d3754aac9c228fe83315daf1350c85)) +* integrate solflare wallet ([fb6aaf1](https://github.com/rango-exchange/rango-client/commit/fb6aaf1c255149df18a75a7bfb16fc83c23b85a8)) + + + +# [0.30.0](https://github.com/rango-exchange/rango-client/compare/signer-solana@0.28.0...signer-solana@0.30.0) (2024-07-09) + + +### Features + +* add custom solana rpc url to config ([8d46ebf](https://github.com/rango-exchange/rango-client/commit/8d46ebf4fcd58c7ecd180ea29c071176c0f863e9)) +* improve solana simulation failed errors ([c7ccb97](https://github.com/rango-exchange/rango-client/commit/c7ccb97cbdc571b615ee3129a8fcadd52cb0bc9f)) + + + +# [0.29.0](https://github.com/rango-exchange/rango-client/compare/signer-solana@0.28.0...signer-solana@0.29.0) (2024-06-01) + + +### Features + +* add custom solana rpc url to config ([8d46ebf](https://github.com/rango-exchange/rango-client/commit/8d46ebf4fcd58c7ecd180ea29c071176c0f863e9)) + + + +# [0.28.0](https://github.com/rango-exchange/rango-client/compare/signer-solana@0.27.0...signer-solana@0.28.0) (2024-05-14) + + +### Features + +* clean solana signer simulation errors ([5d623ab](https://github.com/rango-exchange/rango-client/commit/5d623ab632945cb28581ea896fb95d7c84f92607)) + + + +# [0.27.0](https://github.com/rango-exchange/rango-client/compare/signer-solana@0.26.0...signer-solana@0.27.0) (2024-04-23) + + +### Bug Fixes + +* improve solana transaction sign flow ([65b7be0](https://github.com/rango-exchange/rango-client/commit/65b7be0ce02bed88c98280999b615bc405e95cb6)) + + +### Features + +* add solflare snap connect and signer ([42aa2b0](https://github.com/rango-exchange/rango-client/commit/42aa2b039dd910e8e44db473e1acd28689a8b43b)) + + + +# [0.26.0](https://github.com/rango-exchange/rango-client/compare/signer-solana@0.25.0...signer-solana@0.26.0) (2024-02-20) + + + +# [0.25.0](https://github.com/rango-exchange/rango-client/compare/signer-solana@0.23.0...signer-solana@0.25.0) (2023-12-24) + + +### Bug Fixes + +* fix HMR for widget and playground ([8524820](https://github.com/rango-exchange/rango-client/commit/8524820f10cf0b8921f3db0c4f620ff98daa4103)) + + + +# [0.14.0](https://github.com/rango-exchange/rango-client/compare/signer-solana@0.13.0...signer-solana@0.14.0) (2023-08-03) + + + +# [0.13.0](https://github.com/rango-exchange/rango-client/compare/signer-solana@0.12.0...signer-solana@0.13.0) (2023-08-01) + + + +# [0.9.0](https://github.com/rango-exchange/rango-client/compare/signer-solana@0.8.0...signer-solana@0.9.0) (2023-07-31) + + + +# [0.7.0](https://github.com/rango-exchange/rango-client/compare/signer-solana@0.6.0...signer-solana@0.7.0) (2023-07-11) + + + +# [0.6.0](https://github.com/rango-exchange/rango-client/compare/signer-solana@0.5.0...signer-solana@0.6.0) (2023-07-11) + + + +# [0.5.0](https://github.com/rango-exchange/rango-client/compare/signer-solana@0.4.0...signer-solana@0.5.0) (2023-05-31) + + + +# [0.4.0](https://github.com/rango-exchange/rango-client/compare/signer-solana@0.3.0...signer-solana@0.4.0) (2023-05-31) + + + +# [0.3.0](https://github.com/rango-exchange/rango-client/compare/signer-solana@0.2.0...signer-solana@0.3.0) (2023-05-30) + + + +# [0.2.0](https://github.com/rango-exchange/rango-client/compare/signer-solana@0.1.14...signer-solana@0.2.0) (2023-05-30) + + + +## [0.1.13](https://github.com/rango-exchange/rango-client/compare/signer-solana@0.1.12...signer-solana@0.1.13) (2023-05-15) + + +### Bug Fixes + +* update rango-types and fix notification bugs ([993f185](https://github.com/rango-exchange/rango-client/commit/993f185e0b8c5e5e15a2c65ba2d85d1f9c8daa90)) + + + diff --git a/signers/signer-solana/package.json b/signers/signer-solana/package.json index 9c8dfbdbe2..64149c03c6 100644 --- a/signers/signer-solana/package.json +++ b/signers/signer-solana/package.json @@ -1,46 +1,33 @@ { "name": "@rango-dev/signer-solana", - "version": "0.1.11", + "version": "0.35.1-next.0", "license": "MIT", - "module": "dist/signer-solana.esm.js", - "main": "dist/index.js", + "type": "module", + "source": "./src/index.ts", + "main": "./dist/index.js", + "exports": { + ".": "./dist/index.js" + }, "typings": "dist/index.d.ts", "files": [ "dist", "src" ], "scripts": { - "dev": "tsdx watch", - "build": "tsdx build --tsconfig ./tsconfig.json", - "test": "tsdx test", - "lint": "tsdx lint", - "size": "size-limit", - "analyze": "size-limit --why" - }, - "husky": { - "hooks": { - "pre-commit": "tsdx lint" - } - }, - "prettier": { - "printWidth": 80, - "semi": true, - "singleQuote": true, - "trailingComma": "es5" + "build": "node ../../scripts/build/command.mjs --path signers/signer-solana", + "ts-check": "tsc --declaration --emitDeclarationOnly -p ./tsconfig.json", + "clean": "rimraf dist", + "format": "prettier --write '{.,src}/**/*.{ts,tsx}'", + "lint": "eslint \"**/*.{ts,tsx}\" --ignore-path ../../.eslintignore" }, - "size-limit": [ - { - "path": "dist/signer-solana.cjs.production.min.js", - "limit": "10 KB" - }, - { - "path": "dist/signer-solana.esm.js", - "limit": "10 KB" - } - ], "dependencies": { - "@solana/web3.js": "^1.67.2", - "rango-types": "^0.1.28" + "@solana/web3.js": "^1.91.4", + "bs58": "^5.0.0", + "promise-retry": "^2.0.1", + "rango-types": "^0.1.74" + }, + "devDependencies": { + "@types/promise-retry": "^1.1.6" }, "publishConfig": { "access": "public" diff --git a/signers/signer-solana/readme.md b/signers/signer-solana/readme.md index d35922f48f..f7d01135a1 100644 --- a/signers/signer-solana/readme.md +++ b/signers/signer-solana/readme.md @@ -1 +1,55 @@ -# @rango-dev/signer-solana \ No newline at end of file +# @rango-dev/signer-solana + +## Summary + +Signer for Rango Solana Transactions + +Currecntly all Rango Solana transactions are Versioned (and serialized), only Solana Wrapper is already using the legacy format. (which is used only for SOL <-> WSol routes) + +## Versioned Transaction Sign Flow Overview: + +1. Get connection and recent blockhash + + ```ts + const connection = new Connection(SOLANA_RPC_URL, { + commitment: 'confirmed', + disableRetryOnRateLimit: false, + }); + const latestBlock = await connection.getLatestBlockhash('confirmed'); + ``` + +2. Prepare the transaction + + ```ts + const transaction = VersionedTransaction.deserialize( + new Uint8Array(tx.serializedMessage) + ); + transaction.message.recentBlockhash = recentBlockhash; + ``` + +3. Simulate the transaction + + ```ts + const { value } = await connection.simulateTransaction(transaction, { + replaceRecentBlockhash: true, + commitment: 'processed', + }); + ``` + +4. Sign the transaction + + ```ts + const signedTransaction = await solanaProvider.signTransaction( + solanaWeb3Transaction + ); + const serializedTransaction = Buffer.from(signedTransaction.serialize()); + ``` + +5. Send and confirm the transaction (similar to [jupiter suggested code](https://github.com/jup-ag/jupiter-quote-api-node/blob/main/example/utils/transactionSender.ts)) + + ```ts + const { txId, txResponse } = await transactionSenderAndConfirmationWaiter({ + connection, + serializedTransaction, + }); + ``` diff --git a/signers/signer-solana/src/config.ts b/signers/signer-solana/src/config.ts new file mode 100644 index 0000000000..e7d0a88b57 --- /dev/null +++ b/signers/signer-solana/src/config.ts @@ -0,0 +1,20 @@ +type SolanaSignerConfig = { + customRPC?: string; +}; + +const solanaSignerConfig: SolanaSignerConfig = {}; + +export function setSolanaSignerConfig( + key: Key, + value: SolanaSignerConfig[Key] +) { + solanaSignerConfig[key] = value; + + return value; +} + +export function getSolanaSignerConfig( + key: Key +): SolanaSignerConfig[Key] { + return solanaSignerConfig[key]; +} diff --git a/signers/signer-solana/src/helpers.ts b/signers/signer-solana/src/helpers.ts deleted file mode 100644 index 1678f1a280..0000000000 --- a/signers/signer-solana/src/helpers.ts +++ /dev/null @@ -1,216 +0,0 @@ -import { - Connection, - PublicKey, - Transaction, - TransactionInstruction, - VersionedTransaction, -} from '@solana/web3.js'; -import { SignerError, SignerErrorCode, SolanaTransaction } from 'rango-types'; -import { SolanaExternalProvider } from './signer'; - -async function retryPromise( - promise: Promise, - count: number, - timeoutMs: number, - verifier: ((input: Type) => boolean) | null = null -): Promise { - let remained = count; - while (remained > 0) { - try { - const result = (await Promise.race([ - promise, - new Promise((_, reject) => - setTimeout(() => reject(new Error('timeout')), timeoutMs) - ), - ])) as Type; - if (remained > 1 && verifier != null && !verifier(result)) - throw new Error('bad result'); - return result; - } catch (er) { - console.log( - 'cant get result. time=' + - new Date().toLocaleTimeString() + - ' i=' + - remained + - ' , err=', - er - ); - remained--; - } - } - throw new SignerError( - SignerErrorCode.SEND_TX_ERROR, - 'function reached max retry count' - ); -} -function getFailedHash(tx: SolanaTransaction) { - const random = Math.floor(Math.random() * 9000) + 1000; - return 'failed::' + tx.identifier + '::' + random; -} - -const IS_DEV = !process.env.NODE_ENV || process.env.NODE_ENV === 'development'; -const SOLANA_RPC_URL = !IS_DEV - ? 'https://icy-crimson-wind.solana-mainnet.quiknode.pro/c83f94ebeb39a6d6a9d2ab03d4cba2c2af83c5c0/' - : 'https://fluent-still-scion.solana-mainnet.discover.quiknode.pro/fc8be9b8ac7aea382ec591359628e16d8c52ef6a/'; - -function getSolanaConnection(): Connection { - return new Connection(SOLANA_RPC_URL, { - commitment: 'confirmed', - disableRetryOnRateLimit: false, - }); -} - -function confirmTx(signature: string): Promise { - // eslint-disable-next-line no-async-promise-executor - return new Promise(async function (resolve, reject) { - let confirmRetry = 3; - let successfulConfirm = false; - while (confirmRetry > 0) { - try { - const confirmResult = await getSolanaConnection().confirmTransaction( - signature - ); - if ( - !!confirmResult && - !!confirmResult.value && - confirmResult.value.err == null - ) { - successfulConfirm = true; - break; - } else if ( - confirmRetry === 1 && - !!confirmResult && - !!confirmResult.value && - !!confirmResult.value.err - ) - reject(confirmResult.value.err); - } catch (e) { - if (confirmRetry === 1) reject(e); - } - - confirmRetry -= 1; - } - resolve(successfulConfirm); - }); -} - -// https://docs.phantom.app/integrating/sending-a-transaction -// https://codesandbox.io/s/github/phantom-labs/sandbox -export type SolanaWeb3Signer = ( - solanaWeb3Transaction: Transaction | VersionedTransaction -) => Promise; - -export const generalSolanaTransactionExecutor = async ( - tx: SolanaTransaction, - DefaultSolanaSigner: SolanaWeb3Signer -): Promise => { - const connection = getSolanaConnection(); - let versionedTransaction: VersionedTransaction | undefined = undefined; - let transaction: Transaction | undefined = undefined; - if (tx.serializedMessage != null) { - if (tx.txType === 'VERSIONED') { - versionedTransaction = VersionedTransaction.deserialize( - new Uint8Array(tx.serializedMessage) - ); - const blockhash = ( - await retryPromise( - connection.getLatestBlockhash('confirmed'), - 5, - 10_000 - ) - ).blockhash; - if (!!blockhash) versionedTransaction.message.recentBlockhash = blockhash; - } else if (tx.txType === 'LEGACY') { - transaction = Transaction.from( - Buffer.from(new Uint8Array(tx.serializedMessage)) - ); - transaction.feePayer = new PublicKey(tx.from); - transaction.recentBlockhash = undefined; - } - } else { - transaction = new Transaction(); - transaction.feePayer = new PublicKey(tx.from); - if (tx.recentBlockhash) transaction.recentBlockhash = tx.recentBlockhash; - else - transaction.recentBlockhash = ( - await retryPromise( - connection.getLatestBlockhash('confirmed'), - 5, - 10_000 - ) - ).blockhash; - tx.instructions.forEach((instruction) => { - transaction?.add( - new TransactionInstruction({ - keys: instruction.keys.map((accountMeta) => ({ - pubkey: new PublicKey(accountMeta.pubkey), - isSigner: accountMeta.isSigner, - isWritable: accountMeta.isWritable, - })), - programId: new PublicKey(instruction.programId), - data: Buffer.from(instruction.data), - }) - ); - }); - tx.signatures.forEach(function (signatureItem) { - const signature = Buffer.from(new Uint8Array(signatureItem.signature)); - const publicKey = new PublicKey(signatureItem.publicKey); - transaction?.addSignature(publicKey, signature); - }); - } - try { - let finalTx: Transaction | VersionedTransaction; - if (!!transaction) { - finalTx = transaction; - } else if (!!versionedTransaction) { - finalTx = versionedTransaction; - } else { - throw new Error('error creating transaction'); - } - const raw = await DefaultSolanaSigner(finalTx); - const signature = await retryPromise( - connection.sendRawTransaction(raw), - 2, - 30_000 - ); - if (!signature) - throw new Error('tx cant send to blockchain. signature=' + signature); - const confirmed = await confirmTx(signature); - if (!confirmed) - throw new Error('tx cant confirm on blockchain. signature=' + signature); - - return signature; - } catch (e) { - if ( - e && - SignerError.isSignerError(e) && - (e as SignerError).code === SignerErrorCode.REJECTED_BY_USER - ) - throw e; - if (e && (e as any).hasOwnProperty('code') && (e as any).code === 4001) - throw new SignerError(SignerErrorCode.REJECTED_BY_USER, undefined, e); - - return getFailedHash(tx); - } -}; - -export async function executeSolanaTransaction( - tx: SolanaTransaction, - solanaProvider: SolanaExternalProvider -): Promise { - const DefaultSolanaSigner: SolanaWeb3Signer = async ( - solanaWeb3Transaction - ) => { - try { - const signedTransaction = await solanaProvider.signTransaction( - solanaWeb3Transaction - ); - return signedTransaction.serialize(); - } catch (e) { - // if (e && (e as any).hasOwnProperty('code') && (e as any).code === 4001) - // throw new SignerError(SignerErrorCode .REJECTED_BY_USER, undefined, e); - throw new SignerError(SignerErrorCode.SIGN_TX_ERROR, undefined, e); - } - }; - return await generalSolanaTransactionExecutor(tx, DefaultSolanaSigner); -} diff --git a/signers/signer-solana/src/index.ts b/signers/signer-solana/src/index.ts index 1fe278ee8f..de319a0f62 100644 --- a/signers/signer-solana/src/index.ts +++ b/signers/signer-solana/src/index.ts @@ -1,2 +1,10 @@ -export { DefaultSolanaSigner } from './signer'; -export { generalSolanaTransactionExecutor, SolanaWeb3Signer } from './helpers'; +export { DefaultSolanaSigner } from './signer.js'; +export { + executeSolanaTransaction, + generalSolanaTransactionExecutor, + prepareTransaction, + getSolanaConnection, + simulateTransaction, +} from './utils/index.js'; +export type { SolanaWeb3Signer } from './utils/index.js'; +export { setSolanaSignerConfig } from './config.js'; diff --git a/signers/signer-solana/src/signer.ts b/signers/signer-solana/src/signer.ts index 04228c4e89..b6f5b5f2cc 100644 --- a/signers/signer-solana/src/signer.ts +++ b/signers/signer-solana/src/signer.ts @@ -1,68 +1,39 @@ -import { - GenericSigner, - SignerError, - SignerErrorCode, - SolanaTransaction, -} from 'rango-types'; +import type { SolanaExternalProvider } from './utils/types.js'; +import type { GenericSigner, SolanaTransaction } from 'rango-types'; -import { executeSolanaTransaction } from './helpers'; -import { - PublicKey, - SendOptions, - Transaction, - TransactionSignature, - VersionedTransaction, -} from '@solana/web3.js'; +import base58 from 'bs58'; +import { SignerError, SignerErrorCode } from 'rango-types'; -// https://github.com/solana-labs/wallet-adapter/blob/01c6316ce0725e0a075d6adb237bbcb4128e76ad/packages/wallets/phantom/src/adapter.ts#L30 -export interface SolanaExternalProvider { - isPhantom?: boolean; - publicKey?: { toBytes(): Uint8Array }; - isConnected: boolean; - signTransaction( - transaction: T - ): Promise; - signAllTransactions( - transactions: T[] - ): Promise; - signAndSendTransaction( - transaction: T, - options?: SendOptions - ): Promise<{ signature: TransactionSignature }>; - signMessage(message: Uint8Array): Promise<{ signature: Uint8Array }>; - request(...args: any[]): Promise; - connect(...args: any[]): Promise; - disconnect(): Promise; - accountChanged(newPublicKey: PublicKey): any; -} +import { executeSolanaTransaction } from './utils/main.js'; export class DefaultSolanaSigner implements GenericSigner { - private provider: SolanaExternalProvider; + private _provider: SolanaExternalProvider; constructor(provider: SolanaExternalProvider) { - this.provider = provider; + this._provider = provider; + } + + get provider(): SolanaExternalProvider { + return this._provider; } async signMessage(msg: string): Promise { try { const encodedMessage = new TextEncoder().encode(msg); - const { signature } = await this.provider.request({ + const { signature } = await this._provider.request({ method: 'signMessage', params: { message: encodedMessage, }, }); - return signature; + return base58.encode(signature); } catch (error) { throw new SignerError(SignerErrorCode.SIGN_TX_ERROR, undefined, error); } } - async signAndSendTx(tx: SolanaTransaction): Promise { - try { - return await executeSolanaTransaction(tx, this.provider); - } catch (error) { - throw new SignerError(SignerErrorCode.SEND_TX_ERROR, undefined, error); - } + async signAndSendTx(tx: SolanaTransaction): Promise<{ hash: string }> { + const hash = await executeSolanaTransaction(tx, this._provider); + return { hash }; } } diff --git a/signers/signer-solana/src/utils/helpers.ts b/signers/signer-solana/src/utils/helpers.ts new file mode 100644 index 0000000000..97d81ae6ba --- /dev/null +++ b/signers/signer-solana/src/utils/helpers.ts @@ -0,0 +1,20 @@ +import { Connection } from '@solana/web3.js'; + +import { getSolanaSignerConfig } from '../config.js'; + +const IS_DEV = !process.env.NODE_ENV || process.env.NODE_ENV === 'development'; +const SOLANA_RPC_URL = !IS_DEV + ? 'https://purple-practical-friday.solana-mainnet.quiknode.pro/d94ab067f793d48c81354c78c86ae908d9fc1582/' + : 'https://fluent-still-scion.solana-mainnet.discover.quiknode.pro/fc8be9b8ac7aea382ec591359628e16d8c52ef6a/'; + +export function getSolanaConnection(): Connection { + const customRPC = getSolanaSignerConfig('customRPC'); + + return new Connection(customRPC || SOLANA_RPC_URL, { + commitment: 'confirmed', + disableRetryOnRateLimit: false, + }); +} + +export const wait = async (time: number) => + new Promise((resolve) => setTimeout(resolve, time)); diff --git a/signers/signer-solana/src/utils/index.ts b/signers/signer-solana/src/utils/index.ts new file mode 100644 index 0000000000..16ba9dfe0e --- /dev/null +++ b/signers/signer-solana/src/utils/index.ts @@ -0,0 +1,8 @@ +export type { SolanaWeb3Signer, SolanaExternalProvider } from './types.js'; +export { + executeSolanaTransaction, + generalSolanaTransactionExecutor, +} from './main.js'; +export { prepareTransaction } from './prepare.js'; +export { getSolanaConnection } from './helpers.js'; +export { simulateTransaction } from './simulate.js'; diff --git a/signers/signer-solana/src/utils/main.ts b/signers/signer-solana/src/utils/main.ts new file mode 100644 index 0000000000..14e893a1b8 --- /dev/null +++ b/signers/signer-solana/src/utils/main.ts @@ -0,0 +1,77 @@ +import type { SolanaExternalProvider, SolanaWeb3Signer } from './types.js'; +import type { SolanaTransaction } from 'rango-types'; + +import { SignerError, SignerErrorCode } from 'rango-types'; + +import { getSolanaConnection } from './helpers.js'; +import { prepareTransaction } from './prepare.js'; +import { transactionSenderAndConfirmationWaiter } from './send.js'; +import { simulateTransaction } from './simulate.js'; + +/* + * https://docs.phantom.app/integrating/sending-a-transaction + * https://station.jup.ag/docs/apis/troubleshooting + */ +export const generalSolanaTransactionExecutor = async ( + tx: SolanaTransaction, + DefaultSolanaSigner: SolanaWeb3Signer +): Promise => { + const connection = getSolanaConnection(); + const latestBlock = await connection.getLatestBlockhash('confirmed'); + + const finalTx = prepareTransaction(tx, latestBlock.blockhash); + const serializedTransaction = await DefaultSolanaSigner(finalTx); + + // We first simulate whether the transaction would be successful + await simulateTransaction(finalTx, tx.txType); + + const { txId, txResponse } = await transactionSenderAndConfirmationWaiter({ + connection, + serializedTransaction, + }); + if (!txId || !txResponse) { + throw new SignerError( + SignerErrorCode.SEND_TX_ERROR, + undefined, + 'Error confirming the transaction' + ); + } + return txId; +}; + +export async function executeSolanaTransaction( + tx: SolanaTransaction, + solanaProvider: SolanaExternalProvider +): Promise { + const DefaultSolanaSigner: SolanaWeb3Signer = async ( + solanaWeb3Transaction + ) => { + if (!solanaProvider.publicKey) { + throw new SignerError( + SignerErrorCode.SIGN_TX_ERROR, + 'Please make sure the required account is connected properly.' + ); + } + + if (tx.from !== solanaProvider.publicKey?.toString()) { + throw new SignerError( + SignerErrorCode.SIGN_TX_ERROR, + `Your connected account doesn't match with the required account. Please ensure that you are connected with the correct account and try again.` + ); + } + + try { + const signedTransaction = await solanaProvider.signTransaction( + solanaWeb3Transaction + ); + return signedTransaction.serialize(); + } catch (e: any) { + const REJECTION_CODE = 4001; + if (e && Object.hasOwn(e, 'code') && e.code === REJECTION_CODE) { + throw new SignerError(SignerErrorCode.REJECTED_BY_USER, undefined, e); + } + throw new SignerError(SignerErrorCode.SIGN_TX_ERROR, undefined, e); + } + }; + return await generalSolanaTransactionExecutor(tx, DefaultSolanaSigner); +} diff --git a/signers/signer-solana/src/utils/prepare.ts b/signers/signer-solana/src/utils/prepare.ts new file mode 100644 index 0000000000..c76b0b1266 --- /dev/null +++ b/signers/signer-solana/src/utils/prepare.ts @@ -0,0 +1,75 @@ +import type { SolanaTransaction } from 'rango-types'; + +import { + PublicKey, + Transaction, + TransactionInstruction, + VersionedTransaction, +} from '@solana/web3.js'; + +export const prepareTransaction = ( + tx: SolanaTransaction, + recentBlockhash: string +): Transaction | VersionedTransaction => { + if (tx.txType === 'VERSIONED') { + return prepareVersionedTransaction(tx, recentBlockhash); + } + + return prepareLegacyTransaction(tx, recentBlockhash); +}; + +export function prepareVersionedTransaction( + tx: SolanaTransaction, + recentBlockhash: string +): VersionedTransaction { + const versionedTransaction = VersionedTransaction.deserialize( + new Uint8Array(tx.serializedMessage || []) + ); + /* + * We shouldn't override the recent blockhash provided by the API + * Otherwise, the transaction will become invalid if partially signed by the API + */ + versionedTransaction.message.recentBlockhash = + tx.recentBlockhash || recentBlockhash; + + tx.signatures.forEach(({ publicKey, signature }) => { + versionedTransaction.addSignature( + new PublicKey(publicKey), + new Uint8Array(signature) + ); + }); + + return versionedTransaction; +} + +export function prepareLegacyTransaction( + tx: SolanaTransaction, + recentBlockhash: string +): Transaction { + const transaction = new Transaction({ + feePayer: new PublicKey(tx.from), + recentBlockhash: tx.recentBlockhash || recentBlockhash, + }); + + tx.instructions.forEach(({ keys, programId, data }) => { + const instruction = new TransactionInstruction({ + keys: keys.map(({ pubkey, isSigner, isWritable }) => ({ + pubkey: new PublicKey(pubkey), + isSigner, + isWritable, + })), + programId: new PublicKey(programId), + data: Buffer.from(data), + }); + transaction.add(instruction); + }); + + tx.signatures.forEach(({ publicKey, signature }) => { + transaction.addSignature( + new PublicKey(publicKey), + Buffer.from(new Uint8Array(signature)) + ); + }); + + return transaction; +} diff --git a/signers/signer-solana/src/utils/send.ts b/signers/signer-solana/src/utils/send.ts new file mode 100644 index 0000000000..f96e375a8e --- /dev/null +++ b/signers/signer-solana/src/utils/send.ts @@ -0,0 +1,130 @@ +import type { + TransactionSenderAndConfirmationWaiterArgs, + TransactionSenderAndConfirmationWaiterResponse, +} from './types.js'; + +import { TransactionExpiredBlockheightExceededError } from '@solana/web3.js'; +import promiseRetry from 'promise-retry'; +import { SignerError, SignerErrorCode } from 'rango-types'; + +import { wait } from './helpers.js'; + +const SEND_OPTIONS = { + skipPreflight: true, +}; +const TIME_OUT = 2_000; +const CONFIRMATION_TIME_OUT = 60_000; + +// https://github.com/jup-ag/jupiter-quote-api-node/blob/main/example/utils/transactionSender.ts +export async function transactionSenderAndConfirmationWaiter({ + connection, + serializedTransaction, +}: TransactionSenderAndConfirmationWaiterArgs): Promise { + const txId = await connection.sendRawTransaction( + serializedTransaction, + SEND_OPTIONS + ); + + const controller = new AbortController(); + const abortSignal = controller.signal; + + const abortableResender = async () => { + // eslint-disable-next-line no-constant-condition + while (true) { + await wait(TIME_OUT); + if (abortSignal.aborted) { + return; + } + try { + await connection.sendRawTransaction( + serializedTransaction, + SEND_OPTIONS + ); + } catch (e) { + console.warn(`Failed to resend transaction: ${e}`); + } + } + }; + + try { + void abortableResender(); + + // this would throw TransactionExpiredBlockheightExceededError + await Promise.race([ + new Promise((_, reject) => + setTimeout(() => { + if (!abortSignal.aborted) { + reject( + new SignerError( + SignerErrorCode.SEND_TX_ERROR, + undefined, + `Error confirming transaction (timeout)` + ) + ); + } + }, CONFIRMATION_TIME_OUT) + ), + // eslint-disable-next-line no-async-promise-executor + new Promise(async (resolve, reject) => { + // in case ws socket died + while (!abortSignal.aborted) { + await wait(TIME_OUT); + const { value: statuses } = await connection.getSignatureStatuses( + [txId], + { + searchTransactionHistory: false, + } + ); + if (statuses?.length > 0) { + const status = statuses[0]; + if (status) { + if (status.err) { + reject( + new SignerError( + SignerErrorCode.SEND_TX_ERROR, + undefined, + `Transaction failed: ${JSON.stringify(status.err)}` + ) + ); + } + if ( + status.confirmationStatus && + ['confirmed', 'finalized'].includes(status.confirmationStatus) + ) { + resolve(true); + } + } + } + } + }), + ]); + } catch (e) { + if (e instanceof TransactionExpiredBlockheightExceededError) { + // we consume this error and getTransaction would return null + return { txId, txResponse: null }; + } + throw e; + } finally { + controller.abort(); + } + + // in case rpc is not synced yet, we add some retries + const txResponse = await promiseRetry( + async (retry: any) => { + const response = await connection.getTransaction(txId, { + commitment: 'confirmed', + maxSupportedTransactionVersion: 0, + }); + if (!response) { + retry(response); + } + return response; + }, + { + retries: 5, + minTimeout: 1e3, + } + ); + + return { txId, txResponse }; +} diff --git a/signers/signer-solana/src/utils/simulate.ts b/signers/signer-solana/src/utils/simulate.ts new file mode 100644 index 0000000000..188a6ff456 --- /dev/null +++ b/signers/signer-solana/src/utils/simulate.ts @@ -0,0 +1,93 @@ +import type { Transaction, VersionedTransaction } from '@solana/web3.js'; + +import { SignerError, SignerErrorCode } from 'rango-types'; + +import { getSolanaConnection } from './helpers.js'; + +const INSUFFICIENT_FUNDS_ERROR_CODE = 1; +const SLIPPAGE_ERROR_CODE = 6001; +const PROGRAM_FAILED_TO_COMPLETE_ERROR = 'ProgramFailedToComplete'; +const ACCOUNT_NOT_FOUND_ERROR = 'AccountNotFound'; + +export async function simulateTransaction( + tx: Transaction | VersionedTransaction, + type: 'VERSIONED' | 'LEGACY' +) { + if (type === 'VERSIONED') { + const connection = getSolanaConnection(); + + // We first simulate whether the transaction would be successful + const { value: simulatedTransactionResponse } = + await connection.simulateTransaction(tx as VersionedTransaction, { + replaceRecentBlockhash: true, + commitment: 'processed', + }); + const { err, logs } = simulatedTransactionResponse; + if (err) { + /* + * Simulation error, we can check the logs for more details + * If you are getting an invalid account error, make sure that you have the input mint account to actually swap from. + */ + console.error('Simulation Error:', { err, logs }); + + throw getSimulationError(err, logs); + } + } +} + +function getInsufficientFundsErrorMessage(logs: string[] | null) { + const insufficientLamportErrorMessage = logs?.find((log) => + log.toLowerCase()?.includes('insufficient lamports') + ); + return insufficientLamportErrorMessage || 'Insufficient funds'; +} + +function getSimulationError( + error: string | { [key: string]: any }, + logs: string[] | null +) { + let message = + (logs?.length || 0) > 0 ? logs?.[logs?.length - 1] : JSON.stringify(error); + + /* + * trying to detect common errors (e.g. insufficient fund or slippage error) + * We could probably remove this code after upgrading solana/web3 lib to v2 + */ + if (typeof error === 'string') { + message = + error === ACCOUNT_NOT_FOUND_ERROR + ? 'Attempt to debit an account but found no record of a prior credit.' + : error; + } else { + if ( + Array.isArray(error?.InstructionError) && + error.InstructionError.length > 1 + ) { + const instructionError = error.InstructionError[1]; + + if (typeof instructionError === 'object') { + switch (instructionError.Custom) { + case INSUFFICIENT_FUNDS_ERROR_CODE: + message = getInsufficientFundsErrorMessage(logs); + break; + case SLIPPAGE_ERROR_CODE: + message = 'Slippage error'; + break; + default: + break; + } + } else if (instructionError === PROGRAM_FAILED_TO_COMPLETE_ERROR) { + message = 'Program failed to complete'; + } + } else if (error?.InsufficientFundsForRent) { + message = + 'Transaction results in an account with insufficient funds for rent.'; + } + } + + return new SignerError( + SignerErrorCode.SEND_TX_ERROR, + undefined, + `Simulation failed: ${message}` + ); +} diff --git a/signers/signer-solana/src/utils/types.ts b/signers/signer-solana/src/utils/types.ts new file mode 100644 index 0000000000..1cc9b4adb8 --- /dev/null +++ b/signers/signer-solana/src/utils/types.ts @@ -0,0 +1,47 @@ +import type { + Connection, + PublicKey, + SendOptions, + Transaction, + TransactionSignature, + VersionedTransaction, + VersionedTransactionResponse, +} from '@solana/web3.js'; + +export type SerializedTransaction = Buffer | Uint8Array | number[]; + +export type SolanaWeb3Signer = ( + solanaWeb3Transaction: Transaction | VersionedTransaction +) => Promise; + +// https://github.com/solana-labs/wallet-adapter/blob/01c6316ce0725e0a075d6adb237bbcb4128e76ad/packages/wallets/phantom/src/adapter.ts#L30 +export interface SolanaExternalProvider { + isPhantom?: boolean; + publicKey?: { toBytes(): Uint8Array }; + isConnected: boolean; + signTransaction( + transaction: T + ): Promise; + signAllTransactions( + transactions: T[] + ): Promise; + signAndSendTransaction( + transaction: T, + options?: SendOptions + ): Promise<{ signature: TransactionSignature }>; + signMessage(message: Uint8Array | string): Promise<{ signature: Uint8Array }>; + request(...args: any[]): Promise; + connect(...args: any[]): Promise; + disconnect(): Promise; + accountChanged(newPublicKey: PublicKey): any; +} + +export type TransactionSenderAndConfirmationWaiterArgs = { + connection: Connection; + serializedTransaction: SerializedTransaction; +}; + +export type TransactionSenderAndConfirmationWaiterResponse = { + txId: string | null; + txResponse: VersionedTransactionResponse | null; +}; diff --git a/signers/signer-solana/tsconfig.build.json b/signers/signer-solana/tsconfig.build.json new file mode 100644 index 0000000000..07758b39a6 --- /dev/null +++ b/signers/signer-solana/tsconfig.build.json @@ -0,0 +1,11 @@ +{ + // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs + "extends": "../../tsconfig.libnext.json", + "include": ["src", "types"], + "compilerOptions": { + "outDir": "dist", + "lib": ["dom", "esnext"], + // match output dir to input dir. e.g. dist/index instead of dist/src/index + "rootDir": "./src" + } +} diff --git a/signers/signer-solana/tsconfig.json b/signers/signer-solana/tsconfig.json index 2c85b2d991..a3a0b0f59d 100644 --- a/signers/signer-solana/tsconfig.json +++ b/signers/signer-solana/tsconfig.json @@ -1,35 +1 @@ -{ - // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs - "include": ["src", "types"], - "compilerOptions": { - "module": "esnext", - "lib": ["dom", "esnext"], - "importHelpers": true, - // output .d.ts declaration files for consumers - "declaration": true, - // output .js.map sourcemap files for consumers - "sourceMap": true, - // match output dir to input dir. e.g. dist/index instead of dist/src/index - "rootDir": "./src", - // stricter type-checking for stronger correctness. Recommended by TS - "strict": true, - // linter checks for common issues - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true, - // noUnused* overlap with @typescript-eslint/no-unused-vars, can disable if duplicative - "noUnusedLocals": true, - "noUnusedParameters": true, - // use Node's module resolution algorithm, instead of the legacy TS one - "moduleResolution": "node", - // transpile JSX to React.createElement - "jsx": "react", - // interop between ESM and CJS modules. Recommended by TS - "esModuleInterop": true, - // significant perf increase by skipping checking .d.ts files, particularly those in node_modules. Recommended by TS - "skipLibCheck": true, - // error out if import and file system have a casing mismatch. Recommended by TS - "forceConsistentCasingInFileNames": true, - // `tsdx build` ignores this option, but it is commonly used when type-checking separately with `tsc` - "noEmit": true, - } -} +{ "extends": "./tsconfig.build.json", "include": ["src", "tests"] } diff --git a/signers/signer-starknet/CHANGELOG.md b/signers/signer-starknet/CHANGELOG.md new file mode 100644 index 0000000000..0f4aa765c9 --- /dev/null +++ b/signers/signer-starknet/CHANGELOG.md @@ -0,0 +1,87 @@ +# [0.32.0](https://github.com/rango-exchange/rango-client/compare/signer-starknet@0.31.0...signer-starknet@0.32.0) (2024-11-12) + + + +# [0.31.0](https://github.com/rango-exchange/rango-client/compare/signer-starknet@0.30.0...signer-starknet@0.31.0) (2024-10-12) + + +### Bug Fixes + +* bump sdk and fix type issues ([d442208](https://github.com/rango-exchange/rango-client/commit/d4422083bf5dd27d5f509ce1db7f9560d05428c8)) + + + +# [0.30.0](https://github.com/rango-exchange/rango-client/compare/signer-starknet@0.29.0...signer-starknet@0.30.0) (2024-09-10) + + + +# [0.29.0](https://github.com/rango-exchange/rango-client/compare/signer-starknet@0.28.0...signer-starknet@0.29.0) (2024-08-11) + + + +# [0.28.0](https://github.com/rango-exchange/rango-client/compare/signer-starknet@0.27.0...signer-starknet@0.28.0) (2024-07-09) + + + +# [0.27.0](https://github.com/rango-exchange/rango-client/compare/signer-starknet@0.26.0...signer-starknet@0.27.0) (2024-02-20) + + + +# [0.26.0](https://github.com/rango-exchange/rango-client/compare/signer-starknet@0.25.0...signer-starknet@0.26.0) (2024-01-22) + + + +# [0.25.0](https://github.com/rango-exchange/rango-client/compare/signer-starknet@0.23.0...signer-starknet@0.25.0) (2023-12-24) + + +### Bug Fixes + +* fix HMR for widget and playground ([8524820](https://github.com/rango-exchange/rango-client/commit/8524820f10cf0b8921f3db0c4f620ff98daa4103)) + + + +# [0.14.0](https://github.com/rango-exchange/rango-client/compare/signer-starknet@0.13.0...signer-starknet@0.14.0) (2023-08-03) + + + +# [0.13.0](https://github.com/rango-exchange/rango-client/compare/signer-starknet@0.12.0...signer-starknet@0.13.0) (2023-08-01) + + + +# [0.9.0](https://github.com/rango-exchange/rango-client/compare/signer-starknet@0.8.0...signer-starknet@0.9.0) (2023-07-31) + + + +# [0.7.0](https://github.com/rango-exchange/rango-client/compare/signer-starknet@0.6.0...signer-starknet@0.7.0) (2023-07-11) + + + +# [0.6.0](https://github.com/rango-exchange/rango-client/compare/signer-starknet@0.5.0...signer-starknet@0.6.0) (2023-07-11) + + + +# [0.5.0](https://github.com/rango-exchange/rango-client/compare/signer-starknet@0.4.0...signer-starknet@0.5.0) (2023-05-31) + + + +# [0.4.0](https://github.com/rango-exchange/rango-client/compare/signer-starknet@0.3.0...signer-starknet@0.4.0) (2023-05-31) + + + +# [0.3.0](https://github.com/rango-exchange/rango-client/compare/signer-starknet@0.2.0...signer-starknet@0.3.0) (2023-05-30) + + + +# [0.2.0](https://github.com/rango-exchange/rango-client/compare/signer-starknet@0.1.14...signer-starknet@0.2.0) (2023-05-30) + + + +## [0.1.13](https://github.com/rango-exchange/rango-client/compare/signer-starknet@0.1.12...signer-starknet@0.1.13) (2023-05-15) + + +### Bug Fixes + +* update rango-types and fix notification bugs ([993f185](https://github.com/rango-exchange/rango-client/commit/993f185e0b8c5e5e15a2c65ba2d85d1f9c8daa90)) + + + diff --git a/signers/signer-starknet/package.json b/signers/signer-starknet/package.json index be19d65837..209e71e805 100644 --- a/signers/signer-starknet/package.json +++ b/signers/signer-starknet/package.json @@ -1,45 +1,27 @@ { "name": "@rango-dev/signer-starknet", - "version": "0.1.11", + "version": "0.32.0", "license": "MIT", - "module": "dist/signer-starknet.esm.js", - "main": "dist/index.js", + "type": "module", + "source": "./src/index.ts", + "main": "./dist/index.js", + "exports": { + ".": "./dist/index.js" + }, "typings": "dist/index.d.ts", "files": [ "dist", "src" ], "scripts": { - "dev": "tsdx watch", - "build": "tsdx build --tsconfig ./tsconfig.json", - "test": "tsdx test", - "lint": "tsdx lint", - "size": "size-limit", - "analyze": "size-limit --why" - }, - "husky": { - "hooks": { - "pre-commit": "tsdx lint" - } + "build": "node ../../scripts/build/command.mjs --path signers/signer-starknet", + "ts-check": "tsc --declaration --emitDeclarationOnly -p ./tsconfig.json", + "clean": "rimraf dist", + "format": "prettier --write '{.,src}/**/*.{ts,tsx}'", + "lint": "eslint \"**/*.{ts,tsx}\" --ignore-path ../../.eslintignore" }, - "prettier": { - "printWidth": 80, - "semi": true, - "singleQuote": true, - "trailingComma": "es5" - }, - "size-limit": [ - { - "path": "dist/signer-starknet.cjs.production.min.js", - "limit": "10 KB" - }, - { - "path": "dist/signer-starknet.esm.js", - "limit": "10 KB" - } - ], "dependencies": { - "rango-types": "^0.1.28" + "rango-types": "^0.1.74" }, "publishConfig": { "access": "public" diff --git a/signers/signer-starknet/readme.md b/signers/signer-starknet/readme.md index 5ada5dcd8b..f26cced604 100644 --- a/signers/signer-starknet/readme.md +++ b/signers/signer-starknet/readme.md @@ -1 +1,3 @@ -# @rango-dev/signer-starknet \ No newline at end of file +# @rango-dev/signer-starknet + +Signer for Starknet Transacations generated by Rango API diff --git a/signers/signer-starknet/src/index.ts b/signers/signer-starknet/src/index.ts index 699910a3c1..b367e66430 100644 --- a/signers/signer-starknet/src/index.ts +++ b/signers/signer-starknet/src/index.ts @@ -1 +1 @@ -export { DefaultStarknetSigner } from './signer'; +export { DefaultStarknetSigner } from './signer.js'; diff --git a/signers/signer-starknet/src/signer.ts b/signers/signer-starknet/src/signer.ts index 78b47b028a..ae5ff7aeec 100644 --- a/signers/signer-starknet/src/signer.ts +++ b/signers/signer-starknet/src/signer.ts @@ -1,12 +1,12 @@ -import { - GenericSigner, - SignerError, - SignerErrorCode, - StarknetTransaction, -} from 'rango-types'; +import type { GenericSigner } from 'rango-types'; +import type { StarknetTransaction } from 'rango-types/mainApi'; -// TODO - replace with real type -// tslint:disable-next-line: no-any +import { SignerError, SignerErrorCode } from 'rango-types'; + +/* + * TODO - replace with real type + * tslint:disable-next-line: no-any + */ type StarknetExternalProvider = any; export class DefaultStarknetSigner @@ -22,12 +22,13 @@ export class DefaultStarknetSigner throw SignerError.UnimplementedError('signMessage'); } - async signAndSendTx(tx: StarknetTransaction): Promise { + async signAndSendTx(tx: StarknetTransaction): Promise<{ hash: string }> { try { + await this.provider.enable(); const { transaction_hash } = await this.provider.account.execute( tx.calls ); - return transaction_hash; + return { hash: transaction_hash }; } catch (error) { throw new SignerError(SignerErrorCode.SEND_TX_ERROR, undefined, error); } diff --git a/signers/signer-starknet/tsconfig.build.json b/signers/signer-starknet/tsconfig.build.json new file mode 100644 index 0000000000..301a2cceeb --- /dev/null +++ b/signers/signer-starknet/tsconfig.build.json @@ -0,0 +1,11 @@ +{ + // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs + "extends": "../../tsconfig.libnext.json", + "include": ["src", "types"], + "compilerOptions": { + "rootDir": "./src", + "outDir": "dist", + "lib": ["dom", "esnext"] + // match output dir to input dir. e.g. dist/index instead of dist/src/index + } +} diff --git a/signers/signer-starknet/tsconfig.json b/signers/signer-starknet/tsconfig.json index 2c85b2d991..a3a0b0f59d 100644 --- a/signers/signer-starknet/tsconfig.json +++ b/signers/signer-starknet/tsconfig.json @@ -1,35 +1 @@ -{ - // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs - "include": ["src", "types"], - "compilerOptions": { - "module": "esnext", - "lib": ["dom", "esnext"], - "importHelpers": true, - // output .d.ts declaration files for consumers - "declaration": true, - // output .js.map sourcemap files for consumers - "sourceMap": true, - // match output dir to input dir. e.g. dist/index instead of dist/src/index - "rootDir": "./src", - // stricter type-checking for stronger correctness. Recommended by TS - "strict": true, - // linter checks for common issues - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true, - // noUnused* overlap with @typescript-eslint/no-unused-vars, can disable if duplicative - "noUnusedLocals": true, - "noUnusedParameters": true, - // use Node's module resolution algorithm, instead of the legacy TS one - "moduleResolution": "node", - // transpile JSX to React.createElement - "jsx": "react", - // interop between ESM and CJS modules. Recommended by TS - "esModuleInterop": true, - // significant perf increase by skipping checking .d.ts files, particularly those in node_modules. Recommended by TS - "skipLibCheck": true, - // error out if import and file system have a casing mismatch. Recommended by TS - "forceConsistentCasingInFileNames": true, - // `tsdx build` ignores this option, but it is commonly used when type-checking separately with `tsc` - "noEmit": true, - } -} +{ "extends": "./tsconfig.build.json", "include": ["src", "tests"] } diff --git a/signers/signer-terra/CHANGELOG.md b/signers/signer-terra/CHANGELOG.md new file mode 100644 index 0000000000..c54d01f9be --- /dev/null +++ b/signers/signer-terra/CHANGELOG.md @@ -0,0 +1,92 @@ +# [0.31.0](https://github.com/rango-exchange/rango-client/compare/signer-terra@0.30.0...signer-terra@0.31.0) (2024-11-12) + + + +# [0.30.0](https://github.com/rango-exchange/rango-client/compare/signer-terra@0.29.0...signer-terra@0.30.0) (2024-10-12) + + +### Bug Fixes + +* bump sdk and fix type issues ([d442208](https://github.com/rango-exchange/rango-client/commit/d4422083bf5dd27d5f509ce1db7f9560d05428c8)) + + + +# [0.29.0](https://github.com/rango-exchange/rango-client/compare/signer-terra@0.28.0...signer-terra@0.29.0) (2024-09-10) + + + +# [0.28.0](https://github.com/rango-exchange/rango-client/compare/signer-terra@0.27.0...signer-terra@0.28.0) (2024-08-11) + + +### Features + +* implement sign message method for providers with a custom signer ([cf9515f](https://github.com/rango-exchange/rango-client/commit/cf9515feb5d3754aac9c228fe83315daf1350c85)) + + + +# [0.27.0](https://github.com/rango-exchange/rango-client/compare/signer-terra@0.26.0...signer-terra@0.27.0) (2024-07-09) + + + +# [0.26.0](https://github.com/rango-exchange/rango-client/compare/signer-terra@0.25.0...signer-terra@0.26.0) (2024-02-20) + + + +# [0.25.0](https://github.com/rango-exchange/rango-client/compare/signer-terra@0.23.0...signer-terra@0.25.0) (2023-12-24) + + +### Bug Fixes + +* fix HMR for widget and playground ([8524820](https://github.com/rango-exchange/rango-client/commit/8524820f10cf0b8921f3db0c4f620ff98daa4103)) + + + +# [0.14.0](https://github.com/rango-exchange/rango-client/compare/signer-terra@0.13.0...signer-terra@0.14.0) (2023-08-03) + + + +# [0.13.0](https://github.com/rango-exchange/rango-client/compare/signer-terra@0.12.0...signer-terra@0.13.0) (2023-08-01) + + + +# [0.9.0](https://github.com/rango-exchange/rango-client/compare/signer-terra@0.8.0...signer-terra@0.9.0) (2023-07-31) + + + +# [0.7.0](https://github.com/rango-exchange/rango-client/compare/signer-terra@0.6.0...signer-terra@0.7.0) (2023-07-11) + + + +# [0.6.0](https://github.com/rango-exchange/rango-client/compare/signer-terra@0.5.0...signer-terra@0.6.0) (2023-07-11) + + + +# [0.5.0](https://github.com/rango-exchange/rango-client/compare/signer-terra@0.4.0...signer-terra@0.5.0) (2023-05-31) + + + +# [0.4.0](https://github.com/rango-exchange/rango-client/compare/signer-terra@0.3.0...signer-terra@0.4.0) (2023-05-31) + + + +# [0.3.0](https://github.com/rango-exchange/rango-client/compare/signer-terra@0.2.0...signer-terra@0.3.0) (2023-05-30) + + + +# [0.2.0](https://github.com/rango-exchange/rango-client/compare/signer-terra@0.1.20...signer-terra@0.2.0) (2023-05-30) + + + +## [0.1.20](https://github.com/rango-exchange/rango-client/compare/signer-terra@0.1.19...signer-terra@0.1.20) (2023-05-15) + + + +## 0.1.13 (2023-05-15) + + +### Bug Fixes + +* update rango-types and fix notification bugs ([993f185](https://github.com/rango-exchange/rango-client/commit/993f185e0b8c5e5e15a2c65ba2d85d1f9c8daa90)) + + + diff --git a/signers/signer-terra/package.json b/signers/signer-terra/package.json new file mode 100644 index 0000000000..ea4af3432b --- /dev/null +++ b/signers/signer-terra/package.json @@ -0,0 +1,30 @@ +{ + "name": "@rango-dev/signer-terra", + "version": "0.31.0", + "license": "MIT", + "type": "module", + "source": "./src/index.ts", + "main": "./dist/index.js", + "exports": { + ".": "./dist/index.js" + }, + "typings": "dist/index.d.ts", + "files": [ + "dist", + "src" + ], + "scripts": { + "build": "node ../../scripts/build/command.mjs --path signers/signer-terra", + "ts-check": "tsc --declaration --emitDeclarationOnly -p ./tsconfig.json", + "clean": "rimraf dist", + "format": "prettier --write '{.,src}/**/*.{ts,tsx}'", + "lint": "eslint \"**/*.{ts,tsx}\" --ignore-path ../../.eslintignore" + }, + "dependencies": { + "@terra-money/terra.js": "^3.1.7", + "rango-types": "^0.1.74" + }, + "publishConfig": { + "access": "public" + } +} diff --git a/signers/signer-terra/readme.md b/signers/signer-terra/readme.md new file mode 100644 index 0000000000..5607543e67 --- /dev/null +++ b/signers/signer-terra/readme.md @@ -0,0 +1,3 @@ +# @rango-dev/signer-terra + +Signer for Terra Transacations generated by Rango API diff --git a/signers/signer-terra/src/helpers.ts b/signers/signer-terra/src/helpers.ts new file mode 100644 index 0000000000..27e7a134ab --- /dev/null +++ b/signers/signer-terra/src/helpers.ts @@ -0,0 +1,71 @@ +import type { CreateTxOptions, Msg as TerraMsg } from '@terra-money/terra.js'; +import type { CosmosTransaction } from 'rango-types'; + +import { Coin } from '@terra-money/terra.js'; +import { Fee } from '@terra-money/terra.js/dist/core/index.js'; +import { JSONSerializable } from '@terra-money/terra.js/dist/util/json.js'; + +export const executeTerraTransaction = async ( + cosmosTx: CosmosTransaction, + provider: any +): Promise => { + return new Promise((resolve, reject) => { + provider + .post(cosmosTxToTerraTx(cosmosTx)) + .then((result: { result: { txhash: string | PromiseLike } }) => + resolve(result?.result?.txhash) + ) + .catch((error: any) => { + console.log({ error }); + reject(error); + }); + }); +}; + +function cosmosTxToTerraTx(tx: CosmosTransaction): CreateTxOptions { + let tmpStdFee: Fee | undefined = undefined; + if (tx.data.fee) { + const tmpCoinsFee = tx.data.fee.amount.map( + (item) => new Coin(item.denom, item.amount) + ); + tmpStdFee = new Fee(parseInt(tx.data.fee.gas), tmpCoinsFee); + } + + const msgs = tx.data.msgs.map( + (m) => new TerraMessageGeneralJsonSerializable(m) as unknown as TerraMsg + ); + + return { + msgs, + fee: tmpStdFee, + memo: tx.data.memo || '', + gas: tx.data.fee?.gas, + }; +} + +export class TerraMessageGeneralJsonSerializable extends JSONSerializable< + any, + any, + any +> { + constructor(public raw: any) { + super(); + } + + public static fromData(data: any): TerraMessageGeneralJsonSerializable { + return new TerraMessageGeneralJsonSerializable(data); + } + + toData(): any { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const { __type, value, ...rest } = this.raw; + return JSON.parse(JSON.stringify({ ...rest, ...value })); + } + + toAmino(): any { + return this.toData(); + } + toProto(): any { + return this.toData(); + } +} diff --git a/signers/signer-terra/src/index.ts b/signers/signer-terra/src/index.ts new file mode 100644 index 0000000000..48f186501b --- /dev/null +++ b/signers/signer-terra/src/index.ts @@ -0,0 +1,2 @@ +export { DefaultTerraSigner } from './signer.js'; +export { executeTerraTransaction } from './helpers.js'; diff --git a/signers/signer-terra/src/signer.ts b/signers/signer-terra/src/signer.ts new file mode 100644 index 0000000000..b57fbb7be3 --- /dev/null +++ b/signers/signer-terra/src/signer.ts @@ -0,0 +1,33 @@ +import type { CosmosTransaction, GenericSigner } from 'rango-types'; + +import { executeTerraTransaction } from './helpers.js'; + +type TerraExternalProvider = any; + +export class DefaultTerraSigner implements GenericSigner { + private provider: TerraExternalProvider; + + constructor(provider: TerraExternalProvider) { + this.provider = provider; + } + + async signMessage( + msg: string, + address: string, + chainId: string | null + ): Promise { + if (!chainId) { + throw Error('ChainId is required'); + } + const { result } = await this.provider.signBytes( + Buffer.from(msg, 'utf-8'), + address + ); + return Buffer.from(result.signature).toString('base64'); + } + + async signAndSendTx(tx: CosmosTransaction): Promise<{ hash: string }> { + const hash = await executeTerraTransaction(tx, this.provider); + return { hash }; + } +} diff --git a/signers/signer-terra/tsconfig.build.json b/signers/signer-terra/tsconfig.build.json new file mode 100644 index 0000000000..4f5441876c --- /dev/null +++ b/signers/signer-terra/tsconfig.build.json @@ -0,0 +1,11 @@ +{ + // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs + "extends": "../../tsconfig.libnext.json", + "include": ["src", "types"], + "compilerOptions": { + "outDir": "dist", + "rootDir": "./src", + "lib": ["dom", "esnext"] + // match output dir to input dir. e.g. dist/index instead of dist/src/index + } +} diff --git a/signers/signer-terra/tsconfig.json b/signers/signer-terra/tsconfig.json new file mode 100644 index 0000000000..a3a0b0f59d --- /dev/null +++ b/signers/signer-terra/tsconfig.json @@ -0,0 +1 @@ +{ "extends": "./tsconfig.build.json", "include": ["src", "tests"] } diff --git a/signers/signer-ton/CHANGELOG.md b/signers/signer-ton/CHANGELOG.md new file mode 100644 index 0000000000..c7862478e2 --- /dev/null +++ b/signers/signer-ton/CHANGELOG.md @@ -0,0 +1,47 @@ +# [0.18.0](https://github.com/rango-exchange/rango-client/compare/signer-ton@0.17.0...signer-ton@0.18.0) (2024-11-27) + + +### Bug Fixes + +* improve ton signer and mytonwallet provider ([7027755](https://github.com/rango-exchange/rango-client/commit/7027755740426359f42b088b842dfd01590df5c3)) + + + +# [0.17.0](https://github.com/rango-exchange/rango-client/compare/signer-ton@0.16.0...signer-ton@0.17.0) (2024-11-12) + + + +# [0.16.0](https://github.com/rango-exchange/rango-client/compare/signer-ton@0.15.0...signer-ton@0.16.0) (2024-10-12) + + +### Bug Fixes + +* bump sdk and fix type issues ([d442208](https://github.com/rango-exchange/rango-client/commit/d4422083bf5dd27d5f509ce1db7f9560d05428c8)) + + + +# [0.15.0](https://github.com/rango-exchange/rango-client/compare/signer-ton@0.14.0...signer-ton@0.15.0) (2024-09-10) + + + +# [0.14.0](https://github.com/rango-exchange/rango-client/compare/signer-ton@0.13.0...signer-ton@0.14.0) (2024-08-11) + + + +# [0.13.0](https://github.com/rango-exchange/rango-client/compare/signer-ton@0.12.0...signer-ton@0.13.0) (2024-07-09) + + + +# [0.12.0](https://github.com/rango-exchange/rango-client/compare/signer-ton@0.11.0...signer-ton@0.12.0) (2024-02-20) + + + +# [0.11.0](https://github.com/rango-exchange/rango-client/compare/signer-ton@0.9.0...signer-ton@0.11.0) (2023-12-24) + + +### Bug Fixes + +* fix HMR for widget and playground ([8524820](https://github.com/rango-exchange/rango-client/commit/8524820f10cf0b8921f3db0c4f620ff98daa4103)) + + + diff --git a/signers/signer-ton/package.json b/signers/signer-ton/package.json new file mode 100644 index 0000000000..c5005ae472 --- /dev/null +++ b/signers/signer-ton/package.json @@ -0,0 +1,33 @@ +{ + "name": "@rango-dev/signer-ton", + "version": "0.18.1-next.0", + "license": "MIT", + "type": "module", + "source": "./src/index.ts", + "main": "./dist/index.js", + "exports": { + ".": "./dist/index.js" + }, + "typings": "dist/index.d.ts", + "files": [ + "dist", + "src" + ], + "scripts": { + "build": "node ../../scripts/build/command.mjs --path signers/signer-ton", + "ts-check": "tsc --declaration --emitDeclarationOnly -p ./tsconfig.json", + "clean": "rimraf dist", + "format": "prettier --write '{.,src}/**/*.{ts,tsx}'", + "lint": "eslint \"**/*.{ts,tsx}\" --ignore-path ../../.eslintignore" + }, + "dependencies": { + "rango-types": "^0.1.74" + }, + "peerDependencies": { + "@ton/core": ">=0.59.0", + "@ton/crypto": ">=3.3.0" + }, + "publishConfig": { + "access": "public" + } +} diff --git a/signers/signer-ton/readme.md b/signers/signer-ton/readme.md new file mode 100644 index 0000000000..909d674172 --- /dev/null +++ b/signers/signer-ton/readme.md @@ -0,0 +1,3 @@ +# @rango-dev/signer-ton + +Signer for Ton Transacations generated by Rango API diff --git a/signers/signer-ton/src/index.ts b/signers/signer-ton/src/index.ts new file mode 100644 index 0000000000..9cde28770f --- /dev/null +++ b/signers/signer-ton/src/index.ts @@ -0,0 +1 @@ +export { DefaultTonSigner } from './signer.js'; diff --git a/signers/signer-ton/src/signer.ts b/signers/signer-ton/src/signer.ts new file mode 100644 index 0000000000..644036ca83 --- /dev/null +++ b/signers/signer-ton/src/signer.ts @@ -0,0 +1,27 @@ +import type { GenericSigner, TonTransaction } from 'rango-types'; + +import { Cell } from '@ton/core'; +import { SignerError } from 'rango-types'; + +export class DefaultTonSigner implements GenericSigner { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + constructor(private provider: any) { + this.provider = provider; + } + + async signMessage(): Promise { + throw SignerError.UnimplementedError('signMessage'); + } + + async signAndSendTx(tx: TonTransaction): Promise<{ hash: string }> { + const { type, blockChain, ...transactionObjectForSign } = tx; + + const { result } = await this.provider.send({ + method: 'sendTransaction', + params: [JSON.stringify(transactionObjectForSign)], + }); + + const hash = Cell.fromBase64(result).hash().toString('hex'); + return { hash }; + } +} diff --git a/signers/signer-ton/tsconfig.build.json b/signers/signer-ton/tsconfig.build.json new file mode 100644 index 0000000000..33308f0bc6 --- /dev/null +++ b/signers/signer-ton/tsconfig.build.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig.libnext.json", + "include": ["src", "types"], + "compilerOptions": { + "outDir": "dist", + "rootDir": "./src", + "lib": ["dom", "esnext"] + } +} diff --git a/signers/signer-ton/tsconfig.json b/signers/signer-ton/tsconfig.json new file mode 100644 index 0000000000..a3a0b0f59d --- /dev/null +++ b/signers/signer-ton/tsconfig.json @@ -0,0 +1 @@ +{ "extends": "./tsconfig.build.json", "include": ["src", "tests"] } diff --git a/signers/signer-tron/CHANGELOG.md b/signers/signer-tron/CHANGELOG.md new file mode 100644 index 0000000000..274fb42843 --- /dev/null +++ b/signers/signer-tron/CHANGELOG.md @@ -0,0 +1,88 @@ +# [0.31.0](https://github.com/rango-exchange/rango-client/compare/signer-tron@0.30.0...signer-tron@0.31.0) (2024-11-12) + + + +# [0.30.0](https://github.com/rango-exchange/rango-client/compare/signer-tron@0.29.0...signer-tron@0.30.0) (2024-10-12) + + +### Bug Fixes + +* bump sdk and fix type issues ([d442208](https://github.com/rango-exchange/rango-client/commit/d4422083bf5dd27d5f509ce1db7f9560d05428c8)) + + + +# [0.29.0](https://github.com/rango-exchange/rango-client/compare/signer-tron@0.28.0...signer-tron@0.29.0) (2024-09-10) + + + +# [0.28.0](https://github.com/rango-exchange/rango-client/compare/signer-tron@0.27.0...signer-tron@0.28.0) (2024-08-11) + + +### Features + +* implement sign message method for providers with a custom signer ([cf9515f](https://github.com/rango-exchange/rango-client/commit/cf9515feb5d3754aac9c228fe83315daf1350c85)) + + + +# [0.27.0](https://github.com/rango-exchange/rango-client/compare/signer-tron@0.26.0...signer-tron@0.27.0) (2024-07-09) + + + +# [0.26.0](https://github.com/rango-exchange/rango-client/compare/signer-tron@0.25.0...signer-tron@0.26.0) (2024-02-20) + + + +# [0.25.0](https://github.com/rango-exchange/rango-client/compare/signer-tron@0.23.0...signer-tron@0.25.0) (2023-12-24) + + +### Bug Fixes + +* fix HMR for widget and playground ([8524820](https://github.com/rango-exchange/rango-client/commit/8524820f10cf0b8921f3db0c4f620ff98daa4103)) + + + +# [0.14.0](https://github.com/rango-exchange/rango-client/compare/signer-tron@0.13.0...signer-tron@0.14.0) (2023-08-03) + + + +# [0.13.0](https://github.com/rango-exchange/rango-client/compare/signer-tron@0.12.0...signer-tron@0.13.0) (2023-08-01) + + + +# [0.9.0](https://github.com/rango-exchange/rango-client/compare/signer-tron@0.8.0...signer-tron@0.9.0) (2023-07-31) + + + +# [0.7.0](https://github.com/rango-exchange/rango-client/compare/signer-tron@0.6.0...signer-tron@0.7.0) (2023-07-11) + + + +# [0.6.0](https://github.com/rango-exchange/rango-client/compare/signer-tron@0.5.0...signer-tron@0.6.0) (2023-07-11) + + + +# [0.5.0](https://github.com/rango-exchange/rango-client/compare/signer-tron@0.4.0...signer-tron@0.5.0) (2023-05-31) + + + +# [0.4.0](https://github.com/rango-exchange/rango-client/compare/signer-tron@0.3.0...signer-tron@0.4.0) (2023-05-31) + + + +# [0.3.0](https://github.com/rango-exchange/rango-client/compare/signer-tron@0.2.0...signer-tron@0.3.0) (2023-05-30) + + + +# [0.2.0](https://github.com/rango-exchange/rango-client/compare/signer-tron@0.1.14...signer-tron@0.2.0) (2023-05-30) + + + +## [0.1.13](https://github.com/rango-exchange/rango-client/compare/signer-tron@0.1.12...signer-tron@0.1.13) (2023-05-15) + + +### Bug Fixes + +* update rango-types and fix notification bugs ([993f185](https://github.com/rango-exchange/rango-client/commit/993f185e0b8c5e5e15a2c65ba2d85d1f9c8daa90)) + + + diff --git a/signers/signer-tron/package.json b/signers/signer-tron/package.json index 2e1f7ef9d4..57d905991f 100644 --- a/signers/signer-tron/package.json +++ b/signers/signer-tron/package.json @@ -1,45 +1,27 @@ { "name": "@rango-dev/signer-tron", - "version": "0.1.11", + "version": "0.31.0", "license": "MIT", - "module": "dist/signer-tron.esm.js", - "main": "dist/index.js", + "type": "module", + "source": "./src/index.ts", + "main": "./dist/index.js", + "exports": { + ".": "./dist/index.js" + }, "typings": "dist/index.d.ts", "files": [ "dist", "src" ], "scripts": { - "dev": "tsdx watch", - "build": "tsdx build --tsconfig ./tsconfig.json", - "test": "tsdx test", - "lint": "tsdx lint", - "size": "size-limit", - "analyze": "size-limit --why" - }, - "husky": { - "hooks": { - "pre-commit": "tsdx lint" - } + "build": "node ../../scripts/build/command.mjs --path signers/signer-tron", + "ts-check": "tsc --declaration --emitDeclarationOnly -p ./tsconfig.json", + "clean": "rimraf dist", + "format": "prettier --write '{.,src}/**/*.{ts,tsx}'", + "lint": "eslint \"**/*.{ts,tsx}\" --ignore-path ../../.eslintignore" }, - "prettier": { - "printWidth": 80, - "semi": true, - "singleQuote": true, - "trailingComma": "es5" - }, - "size-limit": [ - { - "path": "dist/signer-tron.cjs.production.min.js", - "limit": "10 KB" - }, - { - "path": "dist/signer-tron.esm.js", - "limit": "10 KB" - } - ], "dependencies": { - "rango-types": "^0.1.28" + "rango-types": "^0.1.74" }, "publishConfig": { "access": "public" diff --git a/signers/signer-tron/readme.md b/signers/signer-tron/readme.md index 7753ea91e9..cb964f370d 100644 --- a/signers/signer-tron/readme.md +++ b/signers/signer-tron/readme.md @@ -1 +1,3 @@ -# @rango-dev/signer-tron \ No newline at end of file +# @rango-dev/signer-tron + +Signer for Tron Transacations generated by Rango API diff --git a/signers/signer-tron/src/index.ts b/signers/signer-tron/src/index.ts index 7af923aa63..a6dd5368bd 100644 --- a/signers/signer-tron/src/index.ts +++ b/signers/signer-tron/src/index.ts @@ -1 +1 @@ -export { DefaultTronSigner } from './signer'; +export { DefaultTronSigner } from './signer.js'; diff --git a/signers/signer-tron/src/signer.ts b/signers/signer-tron/src/signer.ts index 033bc56465..4ecd331ffd 100644 --- a/signers/signer-tron/src/signer.ts +++ b/signers/signer-tron/src/signer.ts @@ -1,12 +1,11 @@ -import { - GenericSigner, - SignerError, - SignerErrorCode, - TronTransaction, -} from 'rango-types'; +import type { GenericSigner, TronTransaction } from 'rango-types'; -// TODO - replace with real type -// tslint:disable-next-line: no-any +import { SignerError, SignerErrorCode } from 'rango-types'; + +/* + * TODO - replace with real type + * tslint:disable-next-line: no-any + */ type TronExternalProvider = any; export class DefaultTronSigner implements GenericSigner { @@ -16,31 +15,44 @@ export class DefaultTronSigner implements GenericSigner { this.provider = provider; } - async signMessage(): Promise { - throw SignerError.UnimplementedError('signMessage'); + static buildTx(tronTx: TronTransaction) { + let tx = {}; + if (!!tronTx.txID) { + tx = { ...tx, txID: tronTx.txID }; + } + if (tronTx.visible !== undefined) { + tx = { ...tx, visible: tronTx.visible }; + } + if (!!tronTx.__payload__) { + tx = { ...tx, __payload__: tronTx.__payload__ }; + } + if (!!tronTx.raw_data) { + tx = { ...tx, raw_data: tronTx.raw_data }; + } + if (!!tronTx.raw_data_hex) { + tx = { ...tx, raw_data_hex: tronTx.raw_data_hex }; + } + return tx; + } + async signMessage(msg: string): Promise { + try { + return await this.provider.tronWeb.trx.signMessageV2(msg); + } catch (error) { + throw new SignerError(SignerErrorCode.SIGN_TX_ERROR, undefined, error); + } } - async signAndSendTx(tx: TronTransaction): Promise { + async signAndSendTx(tx: TronTransaction): Promise<{ hash: string }> { try { const transaction = DefaultTronSigner.buildTx(tx); const signedTxn = await this.provider.tronWeb.trx.sign(transaction); const receipt = await this.provider.tronWeb.trx.sendRawTransaction( signedTxn ); - return receipt?.transaction?.txID; + const hash = receipt?.transaction?.txID; + return { hash }; } catch (error) { throw new SignerError(SignerErrorCode.SEND_TX_ERROR, undefined, error); } } - - static buildTx(tronTx: TronTransaction) { - let tx = {}; - if (!!tronTx.txID) tx = { ...tx, txID: tronTx.txID }; - if (tronTx.visible !== undefined) tx = { ...tx, visible: tronTx.visible }; - if (!!tronTx.__payload__) tx = { ...tx, __payload__: tronTx.__payload__ }; - if (!!tronTx.raw_data) tx = { ...tx, raw_data: tronTx.raw_data }; - if (!!tronTx.raw_data_hex) - tx = { ...tx, raw_data_hex: tronTx.raw_data_hex }; - return tx; - } } diff --git a/signers/signer-tron/tsconfig.build.json b/signers/signer-tron/tsconfig.build.json new file mode 100644 index 0000000000..a1edf48c04 --- /dev/null +++ b/signers/signer-tron/tsconfig.build.json @@ -0,0 +1,11 @@ +{ + // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs + "extends": "../../tsconfig.libnext.json", + "include": ["src", "types"], + "compilerOptions": { + "outDir": "dist", + // match output dir to input dir. e.g. dist/index instead of dist/src/index + "rootDir": "./src", + "lib": ["dom", "esnext"] + } +} diff --git a/signers/signer-tron/tsconfig.json b/signers/signer-tron/tsconfig.json index 2c85b2d991..a3a0b0f59d 100644 --- a/signers/signer-tron/tsconfig.json +++ b/signers/signer-tron/tsconfig.json @@ -1,35 +1 @@ -{ - // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs - "include": ["src", "types"], - "compilerOptions": { - "module": "esnext", - "lib": ["dom", "esnext"], - "importHelpers": true, - // output .d.ts declaration files for consumers - "declaration": true, - // output .js.map sourcemap files for consumers - "sourceMap": true, - // match output dir to input dir. e.g. dist/index instead of dist/src/index - "rootDir": "./src", - // stricter type-checking for stronger correctness. Recommended by TS - "strict": true, - // linter checks for common issues - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true, - // noUnused* overlap with @typescript-eslint/no-unused-vars, can disable if duplicative - "noUnusedLocals": true, - "noUnusedParameters": true, - // use Node's module resolution algorithm, instead of the legacy TS one - "moduleResolution": "node", - // transpile JSX to React.createElement - "jsx": "react", - // interop between ESM and CJS modules. Recommended by TS - "esModuleInterop": true, - // significant perf increase by skipping checking .d.ts files, particularly those in node_modules. Recommended by TS - "skipLibCheck": true, - // error out if import and file system have a casing mismatch. Recommended by TS - "forceConsistentCasingInFileNames": true, - // `tsdx build` ignores this option, but it is commonly used when type-checking separately with `tsc` - "noEmit": true, - } -} +{ "extends": "./tsconfig.build.json", "include": ["src", "tests"] } diff --git a/test-utils/mock.evm.provider.ts b/test-utils/mock.evm.provider.ts new file mode 100644 index 0000000000..997ef60427 --- /dev/null +++ b/test-utils/mock.evm.provider.ts @@ -0,0 +1,140 @@ +import { Wallet } from 'ethers'; + +type ProviderSetup = { + address: string; + privateKey: string; + networkVersion: number; + debug?: boolean; + manualConfirmEnable?: boolean; +}; + +interface IMockProvider { + request(args: { + method: 'eth_accounts'; + params: string[]; + }): Promise; + request(args: { + method: 'eth_requestAccounts'; + params: string[]; + }): Promise; + + request(args: { method: 'net_version' }): Promise; + request(args: { method: 'eth_chainId'; params: string[] }): Promise; + + request(args: { method: 'personal_sign'; params: string[] }): Promise; + request(args: { + method: 'eth_sendTransaction'; + params: string[]; + }): Promise<{ hash: string }>; + + request(args: { + method: 'eth_blockNumber'; + params: string[]; + }): Promise; + + request(args: { method: string; params?: any[] }): Promise; +} + +export class MockEvmProvider implements IMockProvider { + private setup: ProviderSetup; + public isMetaMask = true; + + private acceptEnable?: (value: unknown) => void; + + private rejectEnable?: (value: unknown) => void; + + constructor(setup: ProviderSetup) { + this.setup = setup; + } + + private log = (...args: (any | null)[]) => + this.setup.debug && console.log('🦄', ...args); + + get selectedAddress(): string { + return this.setup.address; + } + + get networkVersion(): number { + return this.setup.networkVersion; + } + + get chainId(): string { + return `0x${this.setup.networkVersion.toString(16)}`; + } + + answerEnable(acceptance: boolean) { + if (acceptance) this.acceptEnable!('Accepted'); + else this.rejectEnable!('User rejected'); + } + + async request({ method, params }: any): Promise { + this.log(`request[${method}]`); + const walletFrom = new Wallet(this.setup.privateKey); + + switch (method) { + case 'eth_requestAccounts': + case 'eth_accounts': + if (this.setup.manualConfirmEnable) { + return new Promise((resolve, reject) => { + this.acceptEnable = resolve; + this.rejectEnable = reject; + }).then(() => [this.selectedAddress]); + } + return Promise.resolve([this.selectedAddress]); + + case 'net_version': + return Promise.resolve(this.setup.networkVersion); + + case 'eth_chainId': + return Promise.resolve(this.chainId); + + case 'personal_sign': { + const signed: string = await walletFrom.signMessage(params[0]); + return Promise.resolve(signed); + } + + case 'eth_sendTransaction': { + const { gas, ...rest } = params[0]; + return Promise.resolve( + walletFrom.sendTransaction({ + gasLimit: gas, + ...rest, + }) + ); + } + + case 'eth_blockNumber': + return Promise.resolve(1); + + default: + this.log(`requesting missing method ${method}`); + // eslint-disable-next-line prefer-promise-reject-errors + return Promise.reject( + `The method ${method} is not implemented by the mock provider.` + ); + } + } + + sendAsync(props: { method: string }, cb: any) { + switch (props.method) { + case 'eth_accounts': + cb(null, { result: [this.setup.address] }); + break; + + case 'net_version': + cb(null, { result: this.setup.networkVersion }); + break; + + default: + this.log(`Method '${props.method}' is not supported yet.`); + } + } + + on(props: string) { + this.log('registering event:', props); + } + + removeAllListeners() { + this.log('removeAllListeners', null); + } +} diff --git a/translations/af.po b/translations/af.po new file mode 100644 index 0000000000..7285da00f7 --- /dev/null +++ b/translations/af.po @@ -0,0 +1,1339 @@ +msgid "" +msgstr "" +"POT-Creation-Date: 2023-11-06 17:24+0330\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: @lingui/cli\n" +"Language: af\n" +"Project-Id-Version: rango\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2024-11-27 15:57\n" +"Last-Translator: \n" +"Language-Team: Afrikaans\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Crowdin-Project: rango\n" +"X-Crowdin-Project-ID: 622238\n" +"X-Crowdin-Language: af\n" +"X-Crowdin-File: en.po\n" +"X-Crowdin-File-ID: 30\n" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SameTokensWarning/SameTokensWarning.tsx:21 +msgid "No Routes Found" +msgstr "Geen roetes gevind nie" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SameTokensWarning/SameTokensWarning.tsx:25 +msgid "You cannot use the same token for From and To." +msgstr "Jy kan nie dieselfde teken vir Van en To gebruik nie." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:41 +#: widget/embedded/src/components/TokenList/TokenList.tsx:286 +#: widget/embedded/src/pages/HistoryPage.tsx:186 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:143 +msgid "No results found" +msgstr "Geen resultate gevind nie" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:42 +#: widget/embedded/src/components/TokenList/TokenList.tsx:287 +#: widget/embedded/src/pages/HistoryPage.tsx:193 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:144 +msgid "Try using different keywords" +msgstr "Probeer om verskillende sleutelwoorde te gebruik" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:72 +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:46 +#: widget/embedded/src/pages/SelectBlockchainPage.tsx:42 +#: widget/ui/src/containers/SwapInput/TokenSection.tsx:61 +msgid "Select Chain" +msgstr "Kies Ketting" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:66 +msgid "All" +msgstr "Almal" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:100 +msgid "More +{count}" +msgstr "Meer +{count}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabAlert/ActivateTabAlert.tsx:17 +msgid "Activate this tab" +msgstr "Aktiveer hierdie oortjie" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabAlert/ActivateTabAlert.tsx:22 +msgid "Another tab is open and handles transactions." +msgstr "Nog 'n oortjie is oop en hanteer transaksies." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:20 +msgid "Activate current tab" +msgstr "Aktiveer huidige oortjie" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:22 +msgid "Currently, some transactions are running and being handled by other browser tab. If you activate this tab, all transactions that are already in the transaction sign step will expire." +msgstr "Tans loop sommige transaksies en word dit deur 'n ander blaaieroortjie hanteer. As jy hierdie oortjie aktiveer, sal alle transaksies wat reeds in die transaksietekenstap is, verval." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:33 +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:349 +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:152 +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:33 +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:116 +msgid "Confirm" +msgstr "Bevestig" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:365 +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:447 +msgid "Your {blockchainName} wallets" +msgstr "Jou {blockchainName} beursies" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:384 +msgid "Insufficient account balance" +msgstr "Onvoldoende rekeningsaldo" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:394 +msgid "Proceed anyway" +msgstr "Gaan in elk geval voort" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:456 +msgid "You need to connect a {blockchainName} wallet." +msgstr "Jy moet 'n {blockchainName} beursie koppel." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/WalletList.tsx:143 +msgid "Add {chain} chain" +msgstr "Voeg {chain} ketting by" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/WalletList.tsx:244 +msgid "Show more wallets" +msgstr "Wys meer beursies" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:113 +msgid "Send to a different address" +msgstr "Stuur na 'n ander adres" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:129 +msgid "Enter {blockchainName} address" +msgstr "Voer {blockchainName} adres in" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:147 +msgid "Address {destination} doesn't match the blockchain address pattern." +msgstr "Adres {destination} pas nie by die blokkettingadrespatroon nie." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:59 +msgid "via" +msgstr "via" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:74 +msgid "This token doesn't appear on the active token list(s). Make sure this is the token that you want to trade." +msgstr "Hierdie token verskyn nie op die aktiewe tokenlys(e nie). Maak seker dit is die teken wat jy wil verhandel." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:89 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:164 +msgid "Import" +msgstr "Invoer" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/FilterSelector/FilterSelectorContent.tsx:26 +msgid "Status" +msgstr "Status" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/FilterSelector/FilterSelectorContent.tsx:33 +#: widget/embedded/src/components/NoResult/NoResult.helpers.ts:37 +#: widget/embedded/src/pages/SettingsPage.tsx:55 +msgid "Reset" +msgstr "Stel terug" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/CancelButton.tsx:18 +msgid "Cancel" +msgstr "Kanselleer" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:46 +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:34 +msgid "Refresh" +msgstr "Verfris" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:63 +#: widget/ui/src/containers/Notifications/Notifications.tsx:35 +msgid "Notifications" +msgstr "Kennisgewings" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:79 +#: widget/embedded/src/pages/SettingsPage.tsx:38 +msgid "Settings" +msgstr "Instellings" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:93 +#: widget/embedded/src/pages/HistoryPage.tsx:139 +msgid "History" +msgstr "Geskiedenis" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/WalletButton.tsx:22 +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:16 +#: widget/embedded/src/constants/messages.ts:5 +msgid "Connect Wallet" +msgstr "Koppel Wallet" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HistoryGroupedList/HistoryGroupedList.tsx:118 +#: widget/embedded/src/utils/date.ts:18 +#: widget/embedded/src/utils/time.ts:22 +msgid "Today" +msgstr "Vandag" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/LoadingSwapDetails/LoadingSwapDetails.tsx:20 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:424 +msgid "Swaps steps" +msgstr "Ruil trappe om" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/NoResult/NoResult.helpers.ts:25 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:191 +msgid "Retry" +msgstr "Probeer weer" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:149 +msgid "Slippage Error" +msgstr "Glipfout" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:150 +msgid "Slippage Warning" +msgstr "Glipwaarskuwing" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:153 +msgid "Bridge Limit Error" +msgstr "Bruglimietfout" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:240 +msgid "Yours: {amount} {symbol}" +msgstr "Die uwe: {amount} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:261 +msgid "Minimum required slippage: {minRequiredSlippage}" +msgstr "Minimum vereiste glip: {minRequiredSlippage}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:282 +msgid "Yours: {userSlippage}" +msgstr "Die uwe: {userSlippage}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:395 +msgid "See All Routes" +msgstr "Sien Alle Roetes" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:81 +msgid "View more info" +msgstr "Bekyk meer inligting" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:91 +msgid "Gas & Fee Explanation" +msgstr "Gas & Fooi Verduideliking" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:107 +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:103 +msgid "Details" +msgstr "Besonderhede" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:146 +msgid "Total Payable Fee" +msgstr "Totale betaalbare fooi" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:166 +msgid "Hide non-payable fees" +msgstr "Versteek nie-betaalbare fooie" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:167 +msgid "Show non-payable fees" +msgstr "Toon nie-betaalbare fooie" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:177 +msgid "Description" +msgstr "Beskrywing" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:181 +msgid "The following fees are considered in the transaction output and\n" +" you won’t need to pay extra gas for them." +msgstr "Die volgende fooie word in die transaksie-uitset in ag geneem en\n" +" sal jy nie ekstra gas daarvoor hoef te betaal nie." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteSummary.tsx:25 +msgid "Swap input" +msgstr "Wissel invoer" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteSummary.tsx:44 +msgid "Estimated output" +msgstr "Geskatte uitset" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteTrigger.tsx:65 +msgid "Via:" +msgstr "Via:" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteTrigger.tsx:150 +msgid "Chains:" +msgstr "Kettings:" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/Quotes.tsx:77 +msgid "Sort by" +msgstr "Sorteer volgens" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:17 +msgid "Smart Routing" +msgstr "Slim roetering" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:21 +msgid "Lowest Fee" +msgstr "Laagste fooi" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:25 +msgid "Fastest Transfer" +msgstr "Vinnigste oordrag" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:29 +msgid "Maximum Return" +msgstr "Maksimum opbrengs" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:33 +msgid "Maximum Output" +msgstr "Maksimum uitset" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:43 +msgid "Swapping" +msgstr "Omruil" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:51 +msgid "Gas cost" +msgstr "Gas koste" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:59 +msgid "Receiving" +msgstr "Ontvangs" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:67 +msgid "Price impact" +msgstr "Prys impak" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:35 +msgid "You need to increase slippage to at least {minRequiredSlippage} for this route." +msgstr "Jy moet glip verhoog tot minstens {minRequiredSlippage} vir hierdie roete." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:59 +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:61 +msgid "We recommend you to increase slippage to at least {minRequiredSlippage} for this route." +msgstr "Ons beveel aan dat jy glip verhoog tot minstens {minRequiredSlippage} vir hierdie roete." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:68 +msgid "Caution, your slippage is high." +msgstr "Wees versigtig, jou glip is hoog." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.tsx:78 +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.Warning.tsx:26 +msgid "Change" +msgstr "Verander" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:42 +msgid "Change settings" +msgstr "Verander instellings" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:52 +msgid "High slippage" +msgstr "Hoë gly" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:53 +msgid "Low slippage" +msgstr "Lae gly" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:57 +msgid " Caution, your slippage is high (={userSlippage}). Your trade may be front run." +msgstr " Wees versigtig, jou glip is hoog (={userSlippage}). Jou handel kan voorloper wees." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:78 +msgid "Confirm anyway" +msgstr "Bevestig in elk geval" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:22 +msgid "Something went wrong" +msgstr "Iets het verkeerd geloop" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:24 +msgid "Something went wrong. Please refresh the app." +msgstr "Iets het verkeerd geloop. Herlaai asseblief die toepassing." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/Slippage.tsx:38 +msgid "Slippage tolerance per swap" +msgstr "Gliptoleransie per ruil" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/Slippage.tsx:91 +msgid "Custom" +msgstr "Pasgemaak" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:11 +msgid "Your transaction will be reverted if the price changes unfavorably by more than this percentage." +msgstr "Jou transaksie sal teruggedraai word as die prys ongunstig verander met meer as hierdie persentasie." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:16 +#: widget/embedded/src/containers/Settings/Lists.tsx:245 +msgid "Warning" +msgstr "Waarskuwing" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:17 +msgid "This setting is applied to each step (e.g. 1Inch, Thorchain, etc.), meaning only that specific step will be reverted, not the entire route." +msgstr "Hierdie instelling word op elke stap toegepas (bv. 1Inch, Thorchain, ens.), wat beteken dat slegs daardie spesifieke stap teruggekeer sal word, nie die hele roete nie." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:25 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:269 +msgid "Swap Details" +msgstr "Ruil Besonderhede" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:33 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:312 +msgid "Request ID" +msgstr "Versoek ID" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:64 +msgid "Not found" +msgstr "Nie gevind nie" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:65 +msgid "Swap with request ID = {requestId} not found." +msgstr "Ruil met versoek-ID = {requestId} nie gevind nie." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:219 +msgid "You have received {amount} {token} in {conciseAddress} wallet on {chain} chain." +msgstr "Jy het {amount} {token} in {conciseAddress} beursie op {chain} ketting ontvang." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:242 +msgid "Transaction was not sent." +msgstr "Transaksie is nie gestuur nie." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:244 +msgid "{amount} {symbol} on {blockchain} remains in your wallet." +msgstr "{amount} {symbol} op {blockchain} bly in jou beursie." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:281 +msgid "Delete" +msgstr "Vee uit" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:304 +msgid "Try again" +msgstr "Probeer weer" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:322 +msgid "Copied To Clipboard" +msgstr "Gekopieer na knipbord" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:323 +msgid "Copy Request ID" +msgstr "Kopieer versoek-ID" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:346 +msgid "View on Rango Explorer" +msgstr "Kyk op Rango Explorer" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:355 +msgid "Finished at" +msgstr "Klaar om" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:355 +msgid "Created at" +msgstr "Geskep by" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.tsx:50 +msgid "View transaction" +msgstr "Bekyk transaksie" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.Warning.tsx:49 +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:31 +msgid "Connect" +msgstr "Koppel" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:43 +msgid "Swap Successful" +msgstr "Ruil Suksesvol" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:71 +msgid "Transaction Failed" +msgstr "Transaksie het misluk" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:87 +msgid "Done" +msgstr "Klaar" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:100 +msgid "Diagnosis" +msgstr "Diagnose" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:112 +msgid "See Details" +msgstr "Sien Besonderhede" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:13 +msgid "Cancel Swap" +msgstr "Kanselleer Ruil" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:14 +msgid "Are you sure you want to cancel this swap?" +msgstr "Is jy seker jy wil hierdie ruil kanselleer?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:23 +msgid "Yes, Cancel it" +msgstr "Ja, kanselleer dit" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:32 +#: widget/embedded/src/pages/CustomTokensPage.tsx:181 +msgid "No, Continue" +msgstr "Nee, gaan voort" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:13 +msgid "Delete Transaction" +msgstr "Vee transaksie uit" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:14 +msgid "Are you sure you want to delete this swap?" +msgstr "Is jy seker jy wil hierdie ruil uitvee?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:23 +#: widget/embedded/src/pages/CustomTokensPage.tsx:171 +msgid "Yes, Delete it" +msgstr "Ja, verwyder dit" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:33 +#: widget/embedded/src/pages/HistoryPage.tsx:253 +msgid "No, Cancel" +msgstr "Nee, kanselleer" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:12 +msgid "Change Network" +msgstr "Verander netwerk" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:20 +msgid "Network Changed" +msgstr "Netwerk verander" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/TokenList/TokenList.tsx:271 +#: widget/ui/src/containers/SwapInput/TokenSection.tsx:54 +msgid "Select Token" +msgstr "Kies Token" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:27 +msgid "Wallet Connected" +msgstr "Beursie gekoppel" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:28 +msgid "Your wallet is connected, you can use it to swap." +msgstr "Jou beursie is gekoppel, jy kan dit gebruik om te ruil." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:39 +msgid "Failed to Connect" +msgstr "Kon nie koppel nie" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:41 +msgid "Your wallet is not connected. Please try again." +msgstr "Jou beursie is nie gekoppel nie. Probeer asseblief weer." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:50 +msgid "Connecting to your wallet" +msgstr "Koppel aan jou beursie" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:51 +msgid "Click connect in your wallet popup." +msgstr "Klik koppel in jou beursie-opspringer." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:99 +msgid "Select Derivation Path" +msgstr "Kies Afleidingspad" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:100 +msgid "In order to connect to {type}, you must first select a Derivation Path" +msgstr "Om aan {type}te koppel, moet jy eers 'n Afleidingspad kies" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:118 +msgid "Choose Derivation Path Template" +msgstr "Kies Afleidingspadsjabloon" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:133 +msgid "Enter Path" +msgstr "Voer Pad in" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:134 +msgid "Enter Index" +msgstr "Voer indeks in" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:15 +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:18 +msgid "Add {blockchainDisplayName} Chain" +msgstr "Voeg {blockchainDisplayName} Ketting by" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:20 +msgid "Would you like to add the {blockchainDisplayName} experimental chain to your wallet?" +msgstr "Wil jy die {blockchainDisplayName} eksperimentele ketting by jou beursie voeg?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:22 +msgid "Please approve the experimental chain pop-up in your wallet." +msgstr "Keur asseblief die eksperimentele ketting-opspringer in jou beursie goed." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:30 +msgid "{blockchainDisplayName} Chain Added" +msgstr "{blockchainDisplayName} Ketting bygevoeg" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:34 +msgid "The {blockchainDisplayName} chain has been successfully added to your wallet." +msgstr "Die {blockchainDisplayName} -ketting is suksesvol by jou beursie gevoeg." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:42 +msgid "Request Rejected" +msgstr "Versoek afgekeur" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:43 +msgid "You've rejected adding {blockchainDisplayName} chain to your wallet." +msgstr "Jy het geweier om {blockchainDisplayName} -ketting by jou beursie te voeg." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:70 +msgid "Select chain types" +msgstr "Kies tipes ketting" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:71 +msgid "This wallet supports multiple chains. Select which chain you'd like to connect to." +msgstr "Hierdie beursie ondersteun verskeie kettings. Kies aan watter ketting jy wil koppel." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:9 +msgid "Failed Network, Please retry your swap." +msgstr "Mislukte netwerk, probeer asseblief weer jou ruil." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:11 +msgid "Please reset your liquidity sources." +msgstr "Stel asseblief jou likiditeitsbronne terug." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:12 +msgid "You have limited the liquidity sources and this might result in Rango finding no routes. Please consider resetting your liquidity sources." +msgstr "Jy het die likiditeitsbronne beperk en dit kan daartoe lei dat Rango geen roetes vind nie. Oorweeg asseblief om jou likiditeitsbronne terug te stel." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:17 +msgid "No Routes Found." +msgstr "Geen roetes gevind nie." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:18 +msgid "Reasons why Rango couldn't find a route: low liquidity on token, very low input amount or no routes available for the selected input/output token combination." +msgstr "Redes waarom Rango nie 'n roete kon vind nie: lae likiditeit op token, baie lae insetbedrag of geen roetes beskikbaar vir die geselekteerde inset/afvoertokenkombinasie nie." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:23 +msgid "Bridge Limit Error: Please increase your amount." +msgstr "Bruglimietfout: Verhoog asseblief jou bedrag." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:26 +msgid "Bridge Limit Error: Please decrease your amount." +msgstr "Bruglimietfout: verminder asseblief jou bedrag." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:31 +msgid "High Price Impact" +msgstr "Hoë prys impak" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:32 +msgid "Price impact is too high!" +msgstr "Prys impak is te hoog!" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:33 +msgid "The price impact is significantly higher than the allowed amount." +msgstr "Die prysimpak is aansienlik hoër as die toegelate bedrag." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:36 +msgid "Confirm high price impact" +msgstr "Bevestig hoë prys impak" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:39 +msgid "Route updated and price impact is too high, try again later!" +msgstr "Roete is opgedateer en prysimpak is te hoog, probeer later weer!" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:44 +msgid "USD Price Unknown" +msgstr "USD-prys onbekend" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:45 +msgid "USD Price Unknown, Cannot calculate Price Impact." +msgstr "USD-prys onbekend, kan nie prysimpak bereken nie." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:46 +msgid "USD Price Unknown, Cannot calculate Price Impact. The price impact may be higher than usual. Are you sure to continue the Swap?" +msgstr "USD-prys onbekend, kan nie prysimpak bereken nie. Die prysimpak kan hoër as gewoonlik wees. Is jy seker om voort te gaan met die ruil?" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:49 +msgid "Confirm USD Price Unknown" +msgstr "Bevestig USD-prys onbekend" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:6 +#: widget/embedded/src/pages/Home.tsx:163 +msgid "Swap" +msgstr "Ruil" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:7 +msgid "Swap anyway" +msgstr "Ruil in elk geval" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:8 +msgid "The route goes through Ethereum. Continue?" +msgstr "Die roete gaan deur Ethereum. Gaan voort?" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:10 +msgid "Route has been updated." +msgstr "Roete is opgedateer." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:12 +msgid "Output amount changed to {newOutputAmount} ({percentageChange}% change)." +msgstr "Uitsetbedrag verander na {newOutputAmount} ({percentageChange}% verandering)." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:20 +msgid "Route swappers has been updated." +msgstr "Roete-ruilers is opgedateer." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:22 +msgid "Route internal coins has been updated." +msgstr "Roete interne munte is opgedateer." + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/ExpandedQuotes/ExpandedQuotes.tsx:53 +#: widget/embedded/src/pages/Routes.tsx:48 +msgid "Routes" +msgstr "Roetes" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Inputs/Inputs.tsx:76 +msgid "From" +msgstr "Van" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Inputs/Inputs.tsx:118 +msgid "To" +msgstr "Om" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:49 +msgid "Light" +msgstr "Lig" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:58 +msgid "Dark" +msgstr "Donker" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:67 +msgid "Auto" +msgstr "Outo" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:140 +msgid "Loading failed" +msgstr "Kon nie laai nie" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:156 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:41 +msgid "Bridges" +msgstr "Brûe" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:174 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:41 +msgid "Exchanges" +msgstr "Uitruilings" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:195 +#: widget/embedded/src/pages/CustomTokensPage.tsx:90 +msgid "Custom Tokens" +msgstr "Pasgemaakte tekens" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:214 +#: widget/embedded/src/pages/LanguagePage.tsx:43 +msgid "Language" +msgstr "Taal" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:235 +msgid "Infinite approval" +msgstr "Oneindige goedkeuring" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:246 +msgid "Enabling the 'Infinite approval' mode grants unrestricted access to underlying smart contracts, allowing them to utilize the approved token amount without limitations." +msgstr "Deur die 'Oneindige goedkeuring'-modus te aktiveer, verleen onbeperkte toegang tot onderliggende slimkontrakte, wat hulle in staat stel om die goedgekeurde tokenbedrag sonder beperkings te gebruik." + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:266 +msgid "Theme" +msgstr "Tema" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:39 +msgid "Duplicate Token" +msgstr "Duplikaatteken" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:40 +msgid "The address you entered is duplicate, please enter a new address." +msgstr "Die adres wat jy ingevoer het is duplikaat, voer asseblief 'n nuwe adres in." + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:46 +msgid "Token Already Exists" +msgstr "Teken bestaan reeds" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:47 +msgid "There's no need to add this token again because it already exists and is supported by us." +msgstr "Dit is nie nodig om hierdie teken weer by te voeg nie, want dit bestaan reeds en word deur ons ondersteun." + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:53 +msgid "Token Not Found" +msgstr "Teken nie gevind nie" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:54 +msgid "Sorry, no token was found on {blockchain} chain with the provided address. please make sure you have entered the right token address." +msgstr "Jammer, geen teken is op {blockchain} -ketting met die verskafde adres gevind nie. maak asseblief seker dat jy die regte tokenadres ingevoer het." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:78 +msgid "Network Error" +msgstr "Netwerkfout" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:109 +#: widget/embedded/src/pages/CustomTokensPage.tsx:149 +msgid "Add Custom Token" +msgstr "Voeg pasgemaakte teken by" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:127 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:128 +msgid "Select chain" +msgstr "Kies ketting" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:132 +msgid "Enter Address" +msgstr "Voer adres in" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:139 +msgid "Enter token address" +msgstr "Voer tokenadres in" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:176 +msgid "Failed Network, Please retry." +msgstr "Mislukte netwerk, probeer asseblief weer." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:192 +msgid "Add another custom token" +msgstr "Voeg nog 'n pasgemaakte teken by" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:236 +msgid "Confirm Swap" +msgstr "Bevestig omruiling" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:254 +msgid "Start Swap" +msgstr "Begin Swap" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:282 +msgid "You get" +msgstr "Jy kry" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:102 +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:90 +msgid "Search Token" +msgstr "Soek Token" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:134 +msgid "No custom tokens" +msgstr "Geen pasgemaakte tekens nie" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:135 +msgid "press the button to add your custom token" +msgstr "druk die knoppie om jou pasgemaakte teken by te voeg" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:158 +msgid "Delete Custom Token" +msgstr "Vee gepasmaakte teken uit" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:160 +msgid "Are you sure you want to Delete this Token?" +msgstr "Is jy seker jy wil hierdie teken uitvee?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:59 +msgid "Complete" +msgstr "Voltooi" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:63 +msgid "Running" +msgstr "Hardloop" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:65 +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:8 +msgid "Failed" +msgstr "Misluk" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:149 +msgid "Clear" +msgstr "Duidelik" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:161 +msgid "Search Transaction" +msgstr "Soek transaksie" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:187 +msgid "No transactions" +msgstr "Geen transaksies nie" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:194 +msgid "Your transaction history is stored locally and will appear here after you start a swap" +msgstr "Jou transaksiegeskiedenis word plaaslik gestoor en sal hier verskyn nadat jy 'n ruil begin het" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:218 +msgid "Clear Transaction History" +msgstr "Vee transaksiegeskiedenis uit" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:222 +msgid "Proceeding will remove all successful and failed transactions from the widget. Do you want to continue?" +msgstr "As u voortgaan, sal alle suksesvolle en mislukte transaksies van die legstuk verwyder word. Wil jy voortgaan?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:229 +msgid "Note: This does not erase your transaction history on the chain; it only removes them here." +msgstr "Let wel: Dit vee nie jou transaksiegeskiedenis op die ketting uit nie; dit verwyder hulle net hier." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:243 +msgid "Yes, Clear the history" +msgstr "Ja, maak die geskiedenis skoon" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LanguagePage.tsx:56 +msgid "language" +msgstr "taal" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:121 +msgid "Deselect all" +msgstr "Ontkies almal" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:121 +msgid "Select all" +msgstr "Kies alles" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:133 +msgid "Search {sourceType}" +msgstr "Soek {sourceType}" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectBlockchainPage.tsx:60 +msgid "Search Chain" +msgstr "Soekketting" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:67 +msgid "Source" +msgstr "Bron" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:68 +msgid "Destination" +msgstr "Bestemming" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:74 +msgid "Swap {type}" +msgstr "Ruil {type}" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SettingsPage.tsx:45 +msgid "Currently, you're in campaign mode with restrictions on liquidity sources. Would you like to switch out of this mode and make use of all available liquidity sources?" +msgstr "Tans is jy in veldtogmodus met beperkings op likiditeitsbronne. Wil jy uit hierdie modus skakel en van alle beskikbare likiditeitsbronne gebruik maak?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SwapDetailsPage.tsx:27 +msgid "The request ID is necessary to display the swap details." +msgstr "Die versoek-ID is nodig om die ruilbesonderhede te vertoon." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/WalletsPage.tsx:67 +#: widget/ui/src/containers/ConnectWalletsModal/ConnectWalletsModal.tsx:15 +msgid "Connect Wallets" +msgstr "Koppel beursies" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/WalletsPage.tsx:82 +msgid "Choose a wallet to connect." +msgstr "Kies 'n beursie om aan te sluit." + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:25 +msgid "This week" +msgstr "Hierdie week" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:32 +msgid "This month" +msgstr "Hierdie maand" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:39 +msgid "This year" +msgstr "Hierdie jaar" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:129 +msgid "Required: >= {min} {symbol}" +msgstr "Vereis: >= {min} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:142 +msgid "Required: > {min} {symbol}" +msgstr "Vereis: > {min} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:157 +msgid "Required: <= {max} {symbol}" +msgstr "Vereis: <= {max} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:170 +msgid "Required: < {max} {symbol}" +msgstr "Vereis: < {max} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:601 +msgid " for network fee" +msgstr " vir netwerkfooi" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:604 +msgid " for swap" +msgstr " vir ruil" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:607 +msgid " for input and network fee" +msgstr " vir insette en netwerkfooi" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:609 +msgid "Needs ≈ {requiredAmount} {symbol}{reason}, but you have {currentAmount} {symbol} in your {blockchain} wallet." +msgstr "Benodig ≈ {requiredAmount} {symbol}{reason}, maar jy het {currentAmount} {symbol} in jou {blockchain} beursie." + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:669 +msgid "Waiting for connecting wallet" +msgstr "Wag vir koppel beursie" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:673 +msgid "Waiting for other running tasks to be finished" +msgstr "Wag vir ander lopende take om klaar te wees" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:676 +msgid "Waiting for changing wallet network" +msgstr "Wag vir verandering van beursienetwerk" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:6 +msgid "Sunday" +msgstr "Sondag" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:7 +msgid "Monday" +msgstr "Maandag" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:8 +msgid "Tuesday" +msgstr "Dinsdag" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:9 +msgid "Wednesday" +msgstr "Woensdag" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:10 +msgid "Thursday" +msgstr "Donderdag" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:11 +msgid "Friday" +msgstr "Vrydag" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:12 +msgid "Saturday" +msgstr "Saterdag" + +#. js-lingui-explicit-id +#: widget/ui/src/components/BottomLogo/BottomLogo.tsx:14 +msgid "Powered By" +msgstr "Aangedryf deur" + +#. js-lingui-explicit-id +#: widget/ui/src/components/FullExpandedQuote/FullExpandedQuote.Tooltip.tsx:37 +msgid "Aggregated Transaction" +msgstr "Geaggregeerde transaksie" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SelectableCategoryList/SelectableCategoryList.tsx:63 +msgid "{blockchainCategory}" +msgstr "{blockchainCategory}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/StepDetails/StepDetails.tsx:75 +#: widget/ui/src/components/StepDetails/StepDetails.tsx:102 +msgid "Swap on {fromChain} via {swapper}" +msgstr "Ruil op {fromChain} via {swapper}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/StepDetails/StepDetails.tsx:109 +msgid "Bridge to {toChain} via {swapper}" +msgstr "Brug na {toChain} via {swapper}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:10 +msgid "Completed" +msgstr "Voltooi" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:12 +msgid "In progress" +msgstr "Aan die gang" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapToken.tsx:122 +msgid "Waiting for bridge transaction" +msgstr "Wag vir brugtransaksie" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:12 +msgid "Connected" +msgstr "Gekoppel" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:13 +msgid "Disconnect" +msgstr "Ontkoppel" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:18 +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:19 +msgid "Install" +msgstr "Installeer" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:24 +msgid "Connecting ..." +msgstr "Koppel tans …" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:25 +msgid "Connecting" +msgstr "Verbind" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:30 +msgid "Disconnected" +msgstr "Ontkoppel" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:34 +msgid "you need to pass a correct state to Wallet." +msgstr "jy moet 'n korrekte toestand aan Wallet deurgee." + +#. js-lingui-explicit-id +#: widget/ui/src/containers/Notifications/NotificationNotFound.tsx:15 +msgid "There are no notifications." +msgstr "Daar is geen kennisgewings nie." + +#. js-lingui-explicit-id +#: widget/ui/src/containers/Notifications/Notifications.tsx:39 +msgid "Clear all" +msgstr "Vee alles uit" + +#. js-lingui-explicit-id +#: widget/ui/src/containers/SwapInput/SwapInput.tsx:65 +msgid "Balance" +msgstr "Balans" + +#. js-lingui-explicit-id +#: widget/ui/src/containers/SwapInput/SwapInput.tsx:73 +msgid "Max" +msgstr "Maks" + diff --git a/translations/ar.po b/translations/ar.po new file mode 100644 index 0000000000..d30f6a4ead --- /dev/null +++ b/translations/ar.po @@ -0,0 +1,1339 @@ +msgid "" +msgstr "" +"POT-Creation-Date: 2023-11-06 17:24+0330\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: @lingui/cli\n" +"Language: ar\n" +"Project-Id-Version: rango\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2024-11-27 15:57\n" +"Last-Translator: \n" +"Language-Team: Arabic\n" +"Plural-Forms: nplurals=6; plural=(n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5);\n" +"X-Crowdin-Project: rango\n" +"X-Crowdin-Project-ID: 622238\n" +"X-Crowdin-Language: ar\n" +"X-Crowdin-File: en.po\n" +"X-Crowdin-File-ID: 30\n" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SameTokensWarning/SameTokensWarning.tsx:21 +msgid "No Routes Found" +msgstr "لم يتم العثور على أي مسارات" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SameTokensWarning/SameTokensWarning.tsx:25 +msgid "You cannot use the same token for From and To." +msgstr "لا يمكنك استخدام نفس الرمز لـ \"من\" و\"إلى\"." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:41 +#: widget/embedded/src/components/TokenList/TokenList.tsx:286 +#: widget/embedded/src/pages/HistoryPage.tsx:186 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:143 +msgid "No results found" +msgstr "لم يتم العثور على نتائج" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:42 +#: widget/embedded/src/components/TokenList/TokenList.tsx:287 +#: widget/embedded/src/pages/HistoryPage.tsx:193 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:144 +msgid "Try using different keywords" +msgstr "حاول استخدام كلمات رئيسية مختلفة" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:72 +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:46 +#: widget/embedded/src/pages/SelectBlockchainPage.tsx:42 +#: widget/ui/src/containers/SwapInput/TokenSection.tsx:61 +msgid "Select Chain" +msgstr "اختر السلسلة" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:66 +msgid "All" +msgstr "الجميع" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:100 +msgid "More +{count}" +msgstr "المزيد +{count}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabAlert/ActivateTabAlert.tsx:17 +msgid "Activate this tab" +msgstr "تفعيل هذه علامة التبويب" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabAlert/ActivateTabAlert.tsx:22 +msgid "Another tab is open and handles transactions." +msgstr "هناك علامة تبويب أخرى مفتوحة وتتعامل مع المعاملات." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:20 +msgid "Activate current tab" +msgstr "تفعيل علامة التبويب الحالية" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:22 +msgid "Currently, some transactions are running and being handled by other browser tab. If you activate this tab, all transactions that are already in the transaction sign step will expire." +msgstr "حاليًا، يتم تشغيل بعض المعاملات ومعالجتها بواسطة علامة تبويب أخرى بالمتصفح. إذا قمت بتنشيط علامة التبويب هذه، فستنتهي صلاحية جميع المعاملات الموجودة بالفعل في خطوة توقيع المعاملة." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:33 +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:349 +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:152 +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:33 +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:116 +msgid "Confirm" +msgstr "يتأكد" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:365 +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:447 +msgid "Your {blockchainName} wallets" +msgstr "محفظتك {blockchainName}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:384 +msgid "Insufficient account balance" +msgstr "رصيد الحساب غير كاف" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:394 +msgid "Proceed anyway" +msgstr "المضي قدما على أية حال" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:456 +msgid "You need to connect a {blockchainName} wallet." +msgstr "يجب عليك توصيل محفظة {blockchainName} ." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/WalletList.tsx:143 +msgid "Add {chain} chain" +msgstr "أضف سلسلة {chain}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/WalletList.tsx:244 +msgid "Show more wallets" +msgstr "عرض المزيد من المحافظ" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:113 +msgid "Send to a different address" +msgstr "إرسال إلى عنوان مختلف" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:129 +msgid "Enter {blockchainName} address" +msgstr "أدخل عنوان {blockchainName}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:147 +msgid "Address {destination} doesn't match the blockchain address pattern." +msgstr "العنوان {destination} لا يتطابق مع نمط عنوان blockchain." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:59 +msgid "via" +msgstr "عبر" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:74 +msgid "This token doesn't appear on the active token list(s). Make sure this is the token that you want to trade." +msgstr "لا يظهر هذا الرمز في قائمة الرموز النشطة. تأكد من أن هذا هو الرمز الذي تريد تداوله." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:89 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:164 +msgid "Import" +msgstr "يستورد" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/FilterSelector/FilterSelectorContent.tsx:26 +msgid "Status" +msgstr "حالة" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/FilterSelector/FilterSelectorContent.tsx:33 +#: widget/embedded/src/components/NoResult/NoResult.helpers.ts:37 +#: widget/embedded/src/pages/SettingsPage.tsx:55 +msgid "Reset" +msgstr "إعادة ضبط" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/CancelButton.tsx:18 +msgid "Cancel" +msgstr "يلغي" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:46 +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:34 +msgid "Refresh" +msgstr "ينعش" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:63 +#: widget/ui/src/containers/Notifications/Notifications.tsx:35 +msgid "Notifications" +msgstr "إشعارات" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:79 +#: widget/embedded/src/pages/SettingsPage.tsx:38 +msgid "Settings" +msgstr "إعدادات" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:93 +#: widget/embedded/src/pages/HistoryPage.tsx:139 +msgid "History" +msgstr "تاريخ" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/WalletButton.tsx:22 +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:16 +#: widget/embedded/src/constants/messages.ts:5 +msgid "Connect Wallet" +msgstr "ربط المحفظة" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HistoryGroupedList/HistoryGroupedList.tsx:118 +#: widget/embedded/src/utils/date.ts:18 +#: widget/embedded/src/utils/time.ts:22 +msgid "Today" +msgstr "اليوم" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/LoadingSwapDetails/LoadingSwapDetails.tsx:20 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:424 +msgid "Swaps steps" +msgstr "خطوات المبادلة" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/NoResult/NoResult.helpers.ts:25 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:191 +msgid "Retry" +msgstr "إعادة المحاولة" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:149 +msgid "Slippage Error" +msgstr "خطأ الانزلاق" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:150 +msgid "Slippage Warning" +msgstr "تحذير من الانزلاق" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:153 +msgid "Bridge Limit Error" +msgstr "خطأ حد الجسر" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:240 +msgid "Yours: {amount} {symbol}" +msgstr "خاصتك: {amount} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:261 +msgid "Minimum required slippage: {minRequiredSlippage}" +msgstr "الحد الأدنى المطلوب للانزلاق: {minRequiredSlippage}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:282 +msgid "Yours: {userSlippage}" +msgstr "خاصتك: {userSlippage}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:395 +msgid "See All Routes" +msgstr "شاهد جميع الطرق" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:81 +msgid "View more info" +msgstr "عرض المزيد من المعلومات" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:91 +msgid "Gas & Fee Explanation" +msgstr "شرح الغاز والرسوم" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:107 +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:103 +msgid "Details" +msgstr "تفاصيل" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:146 +msgid "Total Payable Fee" +msgstr "إجمالي الرسوم المستحقة" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:166 +msgid "Hide non-payable fees" +msgstr "إخفاء الرسوم غير القابلة للدفع" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:167 +msgid "Show non-payable fees" +msgstr "إظهار الرسوم غير القابلة للدفع" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:177 +msgid "Description" +msgstr "وصف" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:181 +msgid "The following fees are considered in the transaction output and\n" +" you won’t need to pay extra gas for them." +msgstr "يتم أخذ الرسوم التالية في الاعتبار في ناتج المعاملة و\n" +" لن تحتاج إلى دفع رسوم غاز إضافية مقابلها." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteSummary.tsx:25 +msgid "Swap input" +msgstr "تبديل المدخلات" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteSummary.tsx:44 +msgid "Estimated output" +msgstr "الناتج المقدر" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteTrigger.tsx:65 +msgid "Via:" +msgstr "عبر:" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteTrigger.tsx:150 +msgid "Chains:" +msgstr "السلاسل:" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/Quotes.tsx:77 +msgid "Sort by" +msgstr "فرز حسب" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:17 +msgid "Smart Routing" +msgstr "التوجيه الذكي" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:21 +msgid "Lowest Fee" +msgstr "أقل رسوم" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:25 +msgid "Fastest Transfer" +msgstr "أسرع نقل" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:29 +msgid "Maximum Return" +msgstr "الحد الأقصى للعائد" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:33 +msgid "Maximum Output" +msgstr "الحد الأقصى للإخراج" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:43 +msgid "Swapping" +msgstr "تبادل" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:51 +msgid "Gas cost" +msgstr "تكلفة الغاز" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:59 +msgid "Receiving" +msgstr "إستلام" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:67 +msgid "Price impact" +msgstr "تأثير السعر" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:35 +msgid "You need to increase slippage to at least {minRequiredSlippage} for this route." +msgstr "يجب عليك زيادة الانزلاق إلى {minRequiredSlippage} على الأقل لهذا الطريق." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:59 +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:61 +msgid "We recommend you to increase slippage to at least {minRequiredSlippage} for this route." +msgstr "ننصحك بزيادة الانزلاق إلى {minRequiredSlippage} على الأقل لهذا الطريق." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:68 +msgid "Caution, your slippage is high." +msgstr "انتبه، انزلاقك مرتفع." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.tsx:78 +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.Warning.tsx:26 +msgid "Change" +msgstr "يتغير" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:42 +msgid "Change settings" +msgstr "تغيير الإعدادات" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:52 +msgid "High slippage" +msgstr "انزلاق عالي" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:53 +msgid "Low slippage" +msgstr "انزلاق منخفض" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:57 +msgid " Caution, your slippage is high (={userSlippage}). Your trade may be front run." +msgstr " انتبه، انزلاقك مرتفع (={userSlippage}). قد تكون تجارتك في المقدمة." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:78 +msgid "Confirm anyway" +msgstr "تأكيد على أية حال" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:22 +msgid "Something went wrong" +msgstr "لقد حدث خطأ ما" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:24 +msgid "Something went wrong. Please refresh the app." +msgstr "حدث خطأ ما. يرجى تحديث التطبيق." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/Slippage.tsx:38 +msgid "Slippage tolerance per swap" +msgstr "تحمل الانزلاق لكل مبادلة" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/Slippage.tsx:91 +msgid "Custom" +msgstr "مخصص" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:11 +msgid "Your transaction will be reverted if the price changes unfavorably by more than this percentage." +msgstr "سيتم التراجع عن معاملتك إذا تغير السعر بشكل غير مواتٍ بنسبة أكبر من هذه النسبة." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:16 +#: widget/embedded/src/containers/Settings/Lists.tsx:245 +msgid "Warning" +msgstr "تحذير" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:17 +msgid "This setting is applied to each step (e.g. 1Inch, Thorchain, etc.), meaning only that specific step will be reverted, not the entire route." +msgstr "يتم تطبيق هذا الإعداد على كل خطوة (على سبيل المثال 1Inch، Thorchain، وما إلى ذلك)، مما يعني أنه سيتم التراجع عن هذه الخطوة المحددة فقط، وليس المسار بالكامل." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:25 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:269 +msgid "Swap Details" +msgstr "تفاصيل المبادلة" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:33 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:312 +msgid "Request ID" +msgstr "معرف الطلب" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:64 +msgid "Not found" +msgstr "لم يتم العثور عليه" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:65 +msgid "Swap with request ID = {requestId} not found." +msgstr "لم يتم العثور على التبادل مع معرف الطلب = {requestId} ." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:219 +msgid "You have received {amount} {token} in {conciseAddress} wallet on {chain} chain." +msgstr "لقد تلقيت {amount} {token} في محفظة {conciseAddress} على سلسلة {chain} ." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:242 +msgid "Transaction was not sent." +msgstr "لم يتم ارسال المعاملة." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:244 +msgid "{amount} {symbol} on {blockchain} remains in your wallet." +msgstr "{amount} {symbol} على {blockchain} يبقى في محفظتك." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:281 +msgid "Delete" +msgstr "يمسح" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:304 +msgid "Try again" +msgstr "حاول ثانية" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:322 +msgid "Copied To Clipboard" +msgstr "تم نسخها إلى الحافظة" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:323 +msgid "Copy Request ID" +msgstr "نسخة من معرف الطلب" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:346 +msgid "View on Rango Explorer" +msgstr "عرض على رانجو إكسبلورر" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:355 +msgid "Finished at" +msgstr "انتهت في" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:355 +msgid "Created at" +msgstr "تم إنشاؤه في" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.tsx:50 +msgid "View transaction" +msgstr "عرض المعاملة" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.Warning.tsx:49 +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:31 +msgid "Connect" +msgstr "يتصل" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:43 +msgid "Swap Successful" +msgstr "تم التبديل بنجاح" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:71 +msgid "Transaction Failed" +msgstr "فشلت المعاملة" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:87 +msgid "Done" +msgstr "منتهي" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:100 +msgid "Diagnosis" +msgstr "تشخبص" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:112 +msgid "See Details" +msgstr "شاهد التفاصيل" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:13 +msgid "Cancel Swap" +msgstr "إلغاء المبادلة" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:14 +msgid "Are you sure you want to cancel this swap?" +msgstr "هل أنت متأكد أنك تريد إلغاء هذا التبادل؟" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:23 +msgid "Yes, Cancel it" +msgstr "نعم، قم بإلغائه" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:32 +#: widget/embedded/src/pages/CustomTokensPage.tsx:181 +msgid "No, Continue" +msgstr "لا، استمر" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:13 +msgid "Delete Transaction" +msgstr "حذف المعاملة" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:14 +msgid "Are you sure you want to delete this swap?" +msgstr "هل أنت متأكد أنك تريد حذف هذه المبادلة؟" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:23 +#: widget/embedded/src/pages/CustomTokensPage.tsx:171 +msgid "Yes, Delete it" +msgstr "نعم، احذفه" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:33 +#: widget/embedded/src/pages/HistoryPage.tsx:253 +msgid "No, Cancel" +msgstr "لا، إلغاء" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:12 +msgid "Change Network" +msgstr "شبكة التغيير" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:20 +msgid "Network Changed" +msgstr "تم تغيير الشبكة" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/TokenList/TokenList.tsx:271 +#: widget/ui/src/containers/SwapInput/TokenSection.tsx:54 +msgid "Select Token" +msgstr "حدد الرمز" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:27 +msgid "Wallet Connected" +msgstr "المحفظة متصلة" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:28 +msgid "Your wallet is connected, you can use it to swap." +msgstr "محفظتك متصلة، ويمكنك استخدامها للتبديل." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:39 +msgid "Failed to Connect" +msgstr "فشل في الاتصال" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:41 +msgid "Your wallet is not connected. Please try again." +msgstr "محفظتك غير متصلة. يرجى المحاولة مرة أخرى." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:50 +msgid "Connecting to your wallet" +msgstr "الاتصال بمحفظتك" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:51 +msgid "Click connect in your wallet popup." +msgstr "انقر فوق الاتصال في النافذة المنبثقة لمحفظتك." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:99 +msgid "Select Derivation Path" +msgstr "حدد مسار الاشتقاق" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:100 +msgid "In order to connect to {type}, you must first select a Derivation Path" +msgstr "للاتصال بـ {type}، يجب عليك أولاً تحديد مسار الاشتقاق" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:118 +msgid "Choose Derivation Path Template" +msgstr "اختر قالب مسار الاشتقاق" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:133 +msgid "Enter Path" +msgstr "أدخل المسار" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:134 +msgid "Enter Index" +msgstr "أدخل الفهرس" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:15 +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:18 +msgid "Add {blockchainDisplayName} Chain" +msgstr "أضف سلسلة {blockchainDisplayName}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:20 +msgid "Would you like to add the {blockchainDisplayName} experimental chain to your wallet?" +msgstr "هل ترغب في إضافة السلسلة التجريبية {blockchainDisplayName} إلى محفظتك؟" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:22 +msgid "Please approve the experimental chain pop-up in your wallet." +msgstr "يرجى الموافقة على السلسلة التجريبية المنبثقة في محفظتك." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:30 +msgid "{blockchainDisplayName} Chain Added" +msgstr "{blockchainDisplayName} تمت إضافة السلسلة" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:34 +msgid "The {blockchainDisplayName} chain has been successfully added to your wallet." +msgstr "تمت إضافة السلسلة {blockchainDisplayName} إلى محفظتك بنجاح." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:42 +msgid "Request Rejected" +msgstr "تم رفض الطلب" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:43 +msgid "You've rejected adding {blockchainDisplayName} chain to your wallet." +msgstr "لقد رفضت إضافة سلسلة {blockchainDisplayName} إلى محفظتك." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:70 +msgid "Select chain types" +msgstr "اختر أنواع السلسلة" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:71 +msgid "This wallet supports multiple chains. Select which chain you'd like to connect to." +msgstr "تدعم هذه المحفظة سلاسل متعددة. حدد السلسلة التي ترغب في الاتصال بها." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:9 +msgid "Failed Network, Please retry your swap." +msgstr "فشلت الشبكة، يرجى إعادة محاولة التبديل." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:11 +msgid "Please reset your liquidity sources." +msgstr "يرجى إعادة ضبط مصادر السيولة الخاصة بك." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:12 +msgid "You have limited the liquidity sources and this might result in Rango finding no routes. Please consider resetting your liquidity sources." +msgstr "لقد قمت بتقييد مصادر السيولة وقد يؤدي هذا إلى عدم تمكن Rango من العثور على أي مسارات. يرجى التفكير في إعادة ضبط مصادر السيولة لديك." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:17 +msgid "No Routes Found." +msgstr "لم يتم العثور على أي طرق." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:18 +msgid "Reasons why Rango couldn't find a route: low liquidity on token, very low input amount or no routes available for the selected input/output token combination." +msgstr "أسباب عدم تمكن Rango من العثور على مسار: انخفاض السيولة على الرمز، أو انخفاض كمية الإدخال بشكل كبير أو عدم توفر مسارات لمجموعة الرمز المحددة للإدخال/الإخراج." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:23 +msgid "Bridge Limit Error: Please increase your amount." +msgstr "خطأ في حد الجسر: يرجى زيادة المبلغ الخاص بك." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:26 +msgid "Bridge Limit Error: Please decrease your amount." +msgstr "خطأ في حد الجسر: يرجى تقليل المبلغ الخاص بك." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:31 +msgid "High Price Impact" +msgstr "تأثير السعر المرتفع" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:32 +msgid "Price impact is too high!" +msgstr "تأثير السعر مرتفع جدًا!" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:33 +msgid "The price impact is significantly higher than the allowed amount." +msgstr "إن تأثير السعر أعلى بكثير من المبلغ المسموح به." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:36 +msgid "Confirm high price impact" +msgstr "تأكيد تأثير السعر المرتفع" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:39 +msgid "Route updated and price impact is too high, try again later!" +msgstr "تم تحديث المسار وتأثير السعر مرتفع للغاية، حاول مرة أخرى لاحقًا!" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:44 +msgid "USD Price Unknown" +msgstr "سعر الدولار الأمريكي غير معروف" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:45 +msgid "USD Price Unknown, Cannot calculate Price Impact." +msgstr "سعر الدولار الأمريكي غير معروف، لا يمكن حساب تأثير السعر." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:46 +msgid "USD Price Unknown, Cannot calculate Price Impact. The price impact may be higher than usual. Are you sure to continue the Swap?" +msgstr "سعر الدولار الأمريكي غير معروف، لا يمكن حساب تأثير السعر. قد يكون تأثير السعر أعلى من المعتاد. هل أنت متأكد من الاستمرار في المبادلة؟" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:49 +msgid "Confirm USD Price Unknown" +msgstr "تأكيد سعر الدولار الأمريكي غير معروف" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:6 +#: widget/embedded/src/pages/Home.tsx:163 +msgid "Swap" +msgstr "تبديل" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:7 +msgid "Swap anyway" +msgstr "تبادل على أية حال" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:8 +msgid "The route goes through Ethereum. Continue?" +msgstr "المسار يمر عبر الإيثريوم. هل تريد الاستمرار؟" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:10 +msgid "Route has been updated." +msgstr "تم تحديث المسار." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:12 +msgid "Output amount changed to {newOutputAmount} ({percentageChange}% change)." +msgstr "تم تغيير كمية الإخراج إلى {newOutputAmount} ({percentageChange}% التغيير)." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:20 +msgid "Route swappers has been updated." +msgstr "تم تحديث مبادلات المسار." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:22 +msgid "Route internal coins has been updated." +msgstr "تم تحديث العملات المعدنية الداخلية للمسار." + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/ExpandedQuotes/ExpandedQuotes.tsx:53 +#: widget/embedded/src/pages/Routes.tsx:48 +msgid "Routes" +msgstr "الطرق" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Inputs/Inputs.tsx:76 +msgid "From" +msgstr "من" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Inputs/Inputs.tsx:118 +msgid "To" +msgstr "ل" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:49 +msgid "Light" +msgstr "ضوء" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:58 +msgid "Dark" +msgstr "مظلم" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:67 +msgid "Auto" +msgstr "آلي" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:140 +msgid "Loading failed" +msgstr "فشل التحميل" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:156 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:41 +msgid "Bridges" +msgstr "الجسور" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:174 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:41 +msgid "Exchanges" +msgstr "التبادلات" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:195 +#: widget/embedded/src/pages/CustomTokensPage.tsx:90 +msgid "Custom Tokens" +msgstr "الرموز المخصصة" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:214 +#: widget/embedded/src/pages/LanguagePage.tsx:43 +msgid "Language" +msgstr "لغة" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:235 +msgid "Infinite approval" +msgstr "موافقة لا نهائية" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:246 +msgid "Enabling the 'Infinite approval' mode grants unrestricted access to underlying smart contracts, allowing them to utilize the approved token amount without limitations." +msgstr "يتيح تمكين وضع \"الموافقة اللانهائية\" الوصول غير المقيد إلى العقود الذكية الأساسية، مما يسمح لها باستخدام مبلغ الرمز المعتمد دون قيود." + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:266 +msgid "Theme" +msgstr "سمة" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:39 +msgid "Duplicate Token" +msgstr "رمز مكرر" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:40 +msgid "The address you entered is duplicate, please enter a new address." +msgstr "العنوان الذي أدخلته مكرر، يرجى إدخال عنوان جديد." + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:46 +msgid "Token Already Exists" +msgstr "الرمز موجود بالفعل" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:47 +msgid "There's no need to add this token again because it already exists and is supported by us." +msgstr "ليست هناك حاجة لإضافة هذا الرمز مرة أخرى لأنه موجود بالفعل ويدعمه فريقنا." + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:53 +msgid "Token Not Found" +msgstr "لم يتم العثور على الرمز" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:54 +msgid "Sorry, no token was found on {blockchain} chain with the provided address. please make sure you have entered the right token address." +msgstr "عذراً، لم يتم العثور على رمز مميز على سلسلة {blockchain} بالعنوان المقدم. يرجى التأكد من إدخال عنوان الرمز المميز الصحيح." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:78 +msgid "Network Error" +msgstr "خطأ في الشبكة" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:109 +#: widget/embedded/src/pages/CustomTokensPage.tsx:149 +msgid "Add Custom Token" +msgstr "إضافة رمز مخصص" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:127 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:128 +msgid "Select chain" +msgstr "اختر السلسلة" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:132 +msgid "Enter Address" +msgstr "أدخل العنوان" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:139 +msgid "Enter token address" +msgstr "أدخل عنوان الرمز" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:176 +msgid "Failed Network, Please retry." +msgstr "فشلت الشبكة، يرجى المحاولة مرة أخرى." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:192 +msgid "Add another custom token" +msgstr "إضافة رمز مخصص آخر" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:236 +msgid "Confirm Swap" +msgstr "تأكيد المبادلة" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:254 +msgid "Start Swap" +msgstr "ابدأ المبادلة" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:282 +msgid "You get" +msgstr "لقد حصلت" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:102 +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:90 +msgid "Search Token" +msgstr "رمز البحث" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:134 +msgid "No custom tokens" +msgstr "لا توجد رموز مخصصة" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:135 +msgid "press the button to add your custom token" +msgstr "اضغط على الزر لإضافة الرمز المخصص الخاص بك" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:158 +msgid "Delete Custom Token" +msgstr "حذف الرمز المخصص" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:160 +msgid "Are you sure you want to Delete this Token?" +msgstr "هل أنت متأكد أنك تريد حذف هذا الرمز؟" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:59 +msgid "Complete" +msgstr "مكتمل" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:63 +msgid "Running" +msgstr "جري" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:65 +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:8 +msgid "Failed" +msgstr "فشل" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:149 +msgid "Clear" +msgstr "واضح" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:161 +msgid "Search Transaction" +msgstr "بحث المعاملة" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:187 +msgid "No transactions" +msgstr "لا توجد معاملات" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:194 +msgid "Your transaction history is stored locally and will appear here after you start a swap" +msgstr "يتم تخزين سجل معاملاتك محليًا وسيظهر هنا بعد بدء عملية المبادلة" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:218 +msgid "Clear Transaction History" +msgstr "مسح سجل المعاملات" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:222 +msgid "Proceeding will remove all successful and failed transactions from the widget. Do you want to continue?" +msgstr "سيؤدي الاستمرار إلى إزالة جميع المعاملات الناجحة والفاشلة من الأداة. هل تريد الاستمرار؟" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:229 +msgid "Note: This does not erase your transaction history on the chain; it only removes them here." +msgstr "ملاحظة: لن يؤدي هذا إلى مسح سجل معاملاتك على السلسلة؛ بل يزيلها هنا فقط." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:243 +msgid "Yes, Clear the history" +msgstr "نعم، مسح التاريخ" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LanguagePage.tsx:56 +msgid "language" +msgstr "لغة" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:121 +msgid "Deselect all" +msgstr "إلغاء تحديد الكل" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:121 +msgid "Select all" +msgstr "حدد الكل" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:133 +msgid "Search {sourceType}" +msgstr "بحث {sourceType}" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectBlockchainPage.tsx:60 +msgid "Search Chain" +msgstr "سلسلة البحث" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:67 +msgid "Source" +msgstr "مصدر" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:68 +msgid "Destination" +msgstr "وجهة" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:74 +msgid "Swap {type}" +msgstr "مبادلة {type}" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SettingsPage.tsx:45 +msgid "Currently, you're in campaign mode with restrictions on liquidity sources. Would you like to switch out of this mode and make use of all available liquidity sources?" +msgstr "أنت حاليًا في وضع الحملة مع فرض قيود على مصادر السيولة. هل ترغب في الخروج من هذا الوضع والاستفادة من جميع مصادر السيولة المتاحة؟" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SwapDetailsPage.tsx:27 +msgid "The request ID is necessary to display the swap details." +msgstr "معرف الطلب ضروري لعرض تفاصيل المبادلة." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/WalletsPage.tsx:67 +#: widget/ui/src/containers/ConnectWalletsModal/ConnectWalletsModal.tsx:15 +msgid "Connect Wallets" +msgstr "ربط المحافظ" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/WalletsPage.tsx:82 +msgid "Choose a wallet to connect." +msgstr "اختر المحفظة التي تريد الاتصال بها." + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:25 +msgid "This week" +msgstr "هذا الاسبوع" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:32 +msgid "This month" +msgstr "هذا الشهر" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:39 +msgid "This year" +msgstr "هذا العام" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:129 +msgid "Required: >= {min} {symbol}" +msgstr "المطلوب: >= {min} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:142 +msgid "Required: > {min} {symbol}" +msgstr "المطلوب: > {min} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:157 +msgid "Required: <= {max} {symbol}" +msgstr "المطلوب: <= {max} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:170 +msgid "Required: < {max} {symbol}" +msgstr "المطلوب: < {max} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:601 +msgid " for network fee" +msgstr " مقابل رسوم الشبكة" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:604 +msgid " for swap" +msgstr " للتبادل" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:607 +msgid " for input and network fee" +msgstr " مقابل رسوم الإدخال والشبكة" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:609 +msgid "Needs ≈ {requiredAmount} {symbol}{reason}, but you have {currentAmount} {symbol} in your {blockchain} wallet." +msgstr "يحتاج ≈ {requiredAmount} {symbol}{reason}، ولكن لديك {currentAmount} {symbol} في محفظتك {blockchain} ." + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:669 +msgid "Waiting for connecting wallet" +msgstr "في انتظار ربط المحفظة" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:673 +msgid "Waiting for other running tasks to be finished" +msgstr "في انتظار الانتهاء من المهام الأخرى الجارية" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:676 +msgid "Waiting for changing wallet network" +msgstr "في انتظار تغيير شبكة المحفظة" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:6 +msgid "Sunday" +msgstr "الأحد" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:7 +msgid "Monday" +msgstr "الاثنين" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:8 +msgid "Tuesday" +msgstr "يوم الثلاثاء" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:9 +msgid "Wednesday" +msgstr "الأربعاء" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:10 +msgid "Thursday" +msgstr "يوم الخميس" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:11 +msgid "Friday" +msgstr "جمعة" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:12 +msgid "Saturday" +msgstr "السبت" + +#. js-lingui-explicit-id +#: widget/ui/src/components/BottomLogo/BottomLogo.tsx:14 +msgid "Powered By" +msgstr "مدعوم بواسطة" + +#. js-lingui-explicit-id +#: widget/ui/src/components/FullExpandedQuote/FullExpandedQuote.Tooltip.tsx:37 +msgid "Aggregated Transaction" +msgstr "المعاملات المجمعة" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SelectableCategoryList/SelectableCategoryList.tsx:63 +msgid "{blockchainCategory}" +msgstr "{blockchainCategory}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/StepDetails/StepDetails.tsx:75 +#: widget/ui/src/components/StepDetails/StepDetails.tsx:102 +msgid "Swap on {fromChain} via {swapper}" +msgstr "قم بالتبديل على {fromChain} عبر {swapper}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/StepDetails/StepDetails.tsx:109 +msgid "Bridge to {toChain} via {swapper}" +msgstr "جسر إلى {toChain} عبر {swapper}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:10 +msgid "Completed" +msgstr "مكتمل" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:12 +msgid "In progress" +msgstr "في تَقَدم" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapToken.tsx:122 +msgid "Waiting for bridge transaction" +msgstr "في انتظار معاملة الجسر" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:12 +msgid "Connected" +msgstr "متصل" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:13 +msgid "Disconnect" +msgstr "قطع الاتصال" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:18 +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:19 +msgid "Install" +msgstr "ثَبَّتَ" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:24 +msgid "Connecting ..." +msgstr "جاري الاتصال ..." + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:25 +msgid "Connecting" +msgstr "الاتصال" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:30 +msgid "Disconnected" +msgstr "منقطع" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:34 +msgid "you need to pass a correct state to Wallet." +msgstr "يجب عليك تمرير الحالة الصحيحة إلى Wallet." + +#. js-lingui-explicit-id +#: widget/ui/src/containers/Notifications/NotificationNotFound.tsx:15 +msgid "There are no notifications." +msgstr "لا يوجد اشعارات." + +#. js-lingui-explicit-id +#: widget/ui/src/containers/Notifications/Notifications.tsx:39 +msgid "Clear all" +msgstr "مسح الكل" + +#. js-lingui-explicit-id +#: widget/ui/src/containers/SwapInput/SwapInput.tsx:65 +msgid "Balance" +msgstr "توازن" + +#. js-lingui-explicit-id +#: widget/ui/src/containers/SwapInput/SwapInput.tsx:73 +msgid "Max" +msgstr "الأعلى" + diff --git a/translations/bn.po b/translations/bn.po new file mode 100644 index 0000000000..0a462624a0 --- /dev/null +++ b/translations/bn.po @@ -0,0 +1,1339 @@ +msgid "" +msgstr "" +"POT-Creation-Date: 2023-11-06 17:24+0330\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: @lingui/cli\n" +"Language: bn\n" +"Project-Id-Version: rango\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2024-11-27 15:57\n" +"Last-Translator: \n" +"Language-Team: Bengali\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Crowdin-Project: rango\n" +"X-Crowdin-Project-ID: 622238\n" +"X-Crowdin-Language: bn\n" +"X-Crowdin-File: en.po\n" +"X-Crowdin-File-ID: 30\n" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SameTokensWarning/SameTokensWarning.tsx:21 +msgid "No Routes Found" +msgstr "কোন রুট পাওয়া যায়নি" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SameTokensWarning/SameTokensWarning.tsx:25 +msgid "You cannot use the same token for From and To." +msgstr "আপনি From এবং To এর জন্য একই টোকেন ব্যবহার করতে পারবেন না।" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:41 +#: widget/embedded/src/components/TokenList/TokenList.tsx:286 +#: widget/embedded/src/pages/HistoryPage.tsx:186 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:143 +msgid "No results found" +msgstr "কোন ফলাফল পাওয়া যায়নি" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:42 +#: widget/embedded/src/components/TokenList/TokenList.tsx:287 +#: widget/embedded/src/pages/HistoryPage.tsx:193 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:144 +msgid "Try using different keywords" +msgstr "বিভিন্ন কীওয়ার্ড ব্যবহার করে দেখুন" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:72 +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:46 +#: widget/embedded/src/pages/SelectBlockchainPage.tsx:42 +#: widget/ui/src/containers/SwapInput/TokenSection.tsx:61 +msgid "Select Chain" +msgstr "চেইন নির্বাচন করুন" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:66 +msgid "All" +msgstr "সব" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:100 +msgid "More +{count}" +msgstr "আরও +{count}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabAlert/ActivateTabAlert.tsx:17 +msgid "Activate this tab" +msgstr "এই ট্যাব সক্রিয় করুন" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabAlert/ActivateTabAlert.tsx:22 +msgid "Another tab is open and handles transactions." +msgstr "আরেকটি ট্যাব খোলা এবং লেনদেন পরিচালনা করে।" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:20 +msgid "Activate current tab" +msgstr "বর্তমান ট্যাব সক্রিয় করুন" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:22 +msgid "Currently, some transactions are running and being handled by other browser tab. If you activate this tab, all transactions that are already in the transaction sign step will expire." +msgstr "বর্তমানে, কিছু লেনদেন চলছে এবং অন্য ব্রাউজার ট্যাব দ্বারা পরিচালিত হচ্ছে৷ আপনি যদি এই ট্যাবটি সক্রিয় করেন, লেনদেন সাইন ধাপে থাকা সমস্ত লেনদেনের মেয়াদ শেষ হয়ে যাবে।" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:33 +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:349 +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:152 +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:33 +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:116 +msgid "Confirm" +msgstr "নিশ্চিত করুন" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:365 +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:447 +msgid "Your {blockchainName} wallets" +msgstr "আপনার {blockchainName} ওয়ালেট" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:384 +msgid "Insufficient account balance" +msgstr "অপর্যাপ্ত অ্যাকাউন্ট ব্যালেন্স" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:394 +msgid "Proceed anyway" +msgstr "যাইহোক এগিয়ে যান" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:456 +msgid "You need to connect a {blockchainName} wallet." +msgstr "আপনাকে একটি {blockchainName} ওয়ালেট সংযোগ করতে হবে৷" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/WalletList.tsx:143 +msgid "Add {chain} chain" +msgstr "{chain} চেইন যোগ করুন" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/WalletList.tsx:244 +msgid "Show more wallets" +msgstr "আরও মানিব্যাগ দেখান" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:113 +msgid "Send to a different address" +msgstr "অন্য ঠিকানায় পাঠান" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:129 +msgid "Enter {blockchainName} address" +msgstr "{blockchainName} ঠিকানা লিখুন" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:147 +msgid "Address {destination} doesn't match the blockchain address pattern." +msgstr "ঠিকানা {destination} ব্লকচেইন ঠিকানা প্যাটার্নের সাথে মেলে না।" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:59 +msgid "via" +msgstr "মাধ্যমে" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:74 +msgid "This token doesn't appear on the active token list(s). Make sure this is the token that you want to trade." +msgstr "এই টোকেনটি সক্রিয় টোকেন তালিকায় উপস্থিত হয় না৷ নিশ্চিত করুন যে এটি সেই টোকেন যা আপনি ট্রেড করতে চান।" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:89 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:164 +msgid "Import" +msgstr "আমদানি" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/FilterSelector/FilterSelectorContent.tsx:26 +msgid "Status" +msgstr "স্ট্যাটাস" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/FilterSelector/FilterSelectorContent.tsx:33 +#: widget/embedded/src/components/NoResult/NoResult.helpers.ts:37 +#: widget/embedded/src/pages/SettingsPage.tsx:55 +msgid "Reset" +msgstr "রিসেট করুন" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/CancelButton.tsx:18 +msgid "Cancel" +msgstr "বাতিল করুন" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:46 +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:34 +msgid "Refresh" +msgstr "রিফ্রেশ" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:63 +#: widget/ui/src/containers/Notifications/Notifications.tsx:35 +msgid "Notifications" +msgstr "বিজ্ঞপ্তি" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:79 +#: widget/embedded/src/pages/SettingsPage.tsx:38 +msgid "Settings" +msgstr "সেটিংস" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:93 +#: widget/embedded/src/pages/HistoryPage.tsx:139 +msgid "History" +msgstr "ইতিহাস" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/WalletButton.tsx:22 +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:16 +#: widget/embedded/src/constants/messages.ts:5 +msgid "Connect Wallet" +msgstr "ওয়ালেট সংযুক্ত করুন" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HistoryGroupedList/HistoryGroupedList.tsx:118 +#: widget/embedded/src/utils/date.ts:18 +#: widget/embedded/src/utils/time.ts:22 +msgid "Today" +msgstr "আজ" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/LoadingSwapDetails/LoadingSwapDetails.tsx:20 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:424 +msgid "Swaps steps" +msgstr "ধাপগুলি অদলবদল করে" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/NoResult/NoResult.helpers.ts:25 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:191 +msgid "Retry" +msgstr "আবার চেষ্টা করুন" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:149 +msgid "Slippage Error" +msgstr "স্লিপেজ ত্রুটি" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:150 +msgid "Slippage Warning" +msgstr "স্লিপেজ সতর্কতা" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:153 +msgid "Bridge Limit Error" +msgstr "সেতু সীমা ত্রুটি" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:240 +msgid "Yours: {amount} {symbol}" +msgstr "আপনার: {amount} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:261 +msgid "Minimum required slippage: {minRequiredSlippage}" +msgstr "ন্যূনতম প্রয়োজনীয় স্লিপেজ: {minRequiredSlippage}৷" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:282 +msgid "Yours: {userSlippage}" +msgstr "আপনার: {userSlippage}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:395 +msgid "See All Routes" +msgstr "সমস্ত রুট দেখুন" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:81 +msgid "View more info" +msgstr "আরো তথ্য দেখুন" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:91 +msgid "Gas & Fee Explanation" +msgstr "গ্যাস ও ফি ব্যাখ্যা" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:107 +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:103 +msgid "Details" +msgstr "বিস্তারিত" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:146 +msgid "Total Payable Fee" +msgstr "মোট প্রদেয় ফি" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:166 +msgid "Hide non-payable fees" +msgstr "অপ্রদেয় ফি লুকান" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:167 +msgid "Show non-payable fees" +msgstr "অপ্রদেয় ফি দেখান" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:177 +msgid "Description" +msgstr "বর্ণনা" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:181 +msgid "The following fees are considered in the transaction output and\n" +" you won’t need to pay extra gas for them." +msgstr "নিম্নলিখিত ফিগুলি লেনদেনের আউটপুটে বিবেচনা করা হয় এবং\n" +" আপনাকে তাদের জন্য অতিরিক্ত গ্যাস দিতে হবে না৷" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteSummary.tsx:25 +msgid "Swap input" +msgstr "অদলবদল ইনপুট" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteSummary.tsx:44 +msgid "Estimated output" +msgstr "আনুমানিক আউটপুট" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteTrigger.tsx:65 +msgid "Via:" +msgstr "এর মাধ্যমে:" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteTrigger.tsx:150 +msgid "Chains:" +msgstr "চেইন:" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/Quotes.tsx:77 +msgid "Sort by" +msgstr "অনুসারে সাজান" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:17 +msgid "Smart Routing" +msgstr "স্মার্ট রাউটিং" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:21 +msgid "Lowest Fee" +msgstr "সর্বনিম্ন ফি" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:25 +msgid "Fastest Transfer" +msgstr "দ্রুততম স্থানান্তর" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:29 +msgid "Maximum Return" +msgstr "সর্বোচ্চ রিটার্ন" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:33 +msgid "Maximum Output" +msgstr "সর্বোচ্চ আউটপুট" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:43 +msgid "Swapping" +msgstr "অদলবদল" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:51 +msgid "Gas cost" +msgstr "গ্যাস খরচ" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:59 +msgid "Receiving" +msgstr "রিসিভিং" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:67 +msgid "Price impact" +msgstr "দামের প্রভাব" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:35 +msgid "You need to increase slippage to at least {minRequiredSlippage} for this route." +msgstr "এই রুটের জন্য আপনাকে অন্তত {minRequiredSlippage} স্লিপেজ বাড়াতে হবে।" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:59 +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:61 +msgid "We recommend you to increase slippage to at least {minRequiredSlippage} for this route." +msgstr "আমরা আপনাকে এই রুটের জন্য কমপক্ষে {minRequiredSlippage} স্লিপেজ বাড়াতে সুপারিশ করছি৷" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:68 +msgid "Caution, your slippage is high." +msgstr "সাবধান, আপনার স্লিপেজ বেশি।" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.tsx:78 +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.Warning.tsx:26 +msgid "Change" +msgstr "পরিবর্তন" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:42 +msgid "Change settings" +msgstr "সেটিংস পরিবর্তন করুন" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:52 +msgid "High slippage" +msgstr "উচ্চ স্লিপেজ" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:53 +msgid "Low slippage" +msgstr "কম স্লিপেজ" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:57 +msgid " Caution, your slippage is high (={userSlippage}). Your trade may be front run." +msgstr " সাবধান, আপনার স্লিপেজ বেশি (={userSlippage})। আপনার ট্রেড ফ্রন্ট রান হতে পারে." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:78 +msgid "Confirm anyway" +msgstr "যাইহোক নিশ্চিত করুন" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:22 +msgid "Something went wrong" +msgstr "কিছু ভুল হয়েছে" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:24 +msgid "Something went wrong. Please refresh the app." +msgstr "কিছু ভুল হয়েছে অনুগ্রহ করে অ্যাপটি রিফ্রেশ করুন।" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/Slippage.tsx:38 +msgid "Slippage tolerance per swap" +msgstr "অদলবদল প্রতি স্লিপেজ সহনশীলতা" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/Slippage.tsx:91 +msgid "Custom" +msgstr "কাস্টম" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:11 +msgid "Your transaction will be reverted if the price changes unfavorably by more than this percentage." +msgstr "এই শতাংশের বেশি মূল্য প্রতিকূলভাবে পরিবর্তিত হলে আপনার লেনদেন ফিরিয়ে দেওয়া হবে।" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:16 +#: widget/embedded/src/containers/Settings/Lists.tsx:245 +msgid "Warning" +msgstr "সতর্কতা" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:17 +msgid "This setting is applied to each step (e.g. 1Inch, Thorchain, etc.), meaning only that specific step will be reverted, not the entire route." +msgstr "এই সেটিংটি প্রতিটি ধাপে প্রয়োগ করা হয় (যেমন 1 ইঞ্চি, থরচেইন, ইত্যাদি), যার অর্থ শুধুমাত্র সেই নির্দিষ্ট ধাপটি প্রত্যাবর্তন করা হবে, পুরো রুট নয়।" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:25 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:269 +msgid "Swap Details" +msgstr "অদলবদল বিবরণ" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:33 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:312 +msgid "Request ID" +msgstr "আইডি অনুরোধ করুন" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:64 +msgid "Not found" +msgstr "পাওয়া যায়নি" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:65 +msgid "Swap with request ID = {requestId} not found." +msgstr "অনুরোধ আইডি দিয়ে অদলবদল করুন = {requestId} পাওয়া যায়নি।" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:219 +msgid "You have received {amount} {token} in {conciseAddress} wallet on {chain} chain." +msgstr "আপনি {chain} চেইনে {conciseAddress} ওয়ালেটে {amount} {token} পেয়েছেন৷" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:242 +msgid "Transaction was not sent." +msgstr "লেনদেন পাঠানো হয়নি." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:244 +msgid "{amount} {symbol} on {blockchain} remains in your wallet." +msgstr "{amount} {symbol} {blockchain} -এ আপনার ওয়ালেটে থেকে যায়৷" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:281 +msgid "Delete" +msgstr "মুছে দিন" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:304 +msgid "Try again" +msgstr "আবার চেষ্টা করুন" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:322 +msgid "Copied To Clipboard" +msgstr "ক্লিপবোর্ডে কপি করা হয়েছে" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:323 +msgid "Copy Request ID" +msgstr "অনুরোধ আইডি কপি করুন" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:346 +msgid "View on Rango Explorer" +msgstr "Rango Explorer এ দেখুন" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:355 +msgid "Finished at" +msgstr "এ শেষ হয়েছে" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:355 +msgid "Created at" +msgstr "এ তৈরি করা হয়েছে" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.tsx:50 +msgid "View transaction" +msgstr "লেনদেন দেখুন" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.Warning.tsx:49 +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:31 +msgid "Connect" +msgstr "সংযোগ করুন" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:43 +msgid "Swap Successful" +msgstr "অদলবদল সফল" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:71 +msgid "Transaction Failed" +msgstr "লেনদেন ব্যর্থ হয়েছে৷" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:87 +msgid "Done" +msgstr "সম্পন্ন" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:100 +msgid "Diagnosis" +msgstr "রোগ নির্ণয়" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:112 +msgid "See Details" +msgstr "বিস্তারিত দেখুন" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:13 +msgid "Cancel Swap" +msgstr "অদলবদল বাতিল করুন" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:14 +msgid "Are you sure you want to cancel this swap?" +msgstr "আপনি কি এই অদলবদল বাতিল করার বিষয়ে নিশ্চিত?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:23 +msgid "Yes, Cancel it" +msgstr "হ্যাঁ, বাতিল করুন" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:32 +#: widget/embedded/src/pages/CustomTokensPage.tsx:181 +msgid "No, Continue" +msgstr "না, চালিয়ে যান" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:13 +msgid "Delete Transaction" +msgstr "লেনদেন মুছুন" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:14 +msgid "Are you sure you want to delete this swap?" +msgstr "আপনি কি এই অদলবদল মুছে ফেলার বিষয়ে নিশ্চিত?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:23 +#: widget/embedded/src/pages/CustomTokensPage.tsx:171 +msgid "Yes, Delete it" +msgstr "হ্যাঁ, মুছুন" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:33 +#: widget/embedded/src/pages/HistoryPage.tsx:253 +msgid "No, Cancel" +msgstr "না, বাতিল করুন" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:12 +msgid "Change Network" +msgstr "নেটওয়ার্ক পরিবর্তন করুন" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:20 +msgid "Network Changed" +msgstr "নেটওয়ার্ক পরিবর্তিত হয়েছে" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/TokenList/TokenList.tsx:271 +#: widget/ui/src/containers/SwapInput/TokenSection.tsx:54 +msgid "Select Token" +msgstr "টোকেন নির্বাচন করুন" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:27 +msgid "Wallet Connected" +msgstr "ওয়ালেট সংযুক্ত" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:28 +msgid "Your wallet is connected, you can use it to swap." +msgstr "আপনার ওয়ালেট সংযুক্ত আছে, আপনি এটি অদলবদল করতে ব্যবহার করতে পারেন।" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:39 +msgid "Failed to Connect" +msgstr "সংযোগ করতে ব্যর্থ হয়েছে" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:41 +msgid "Your wallet is not connected. Please try again." +msgstr "আপনার ওয়ালেট সংযুক্ত নেই. আবার চেষ্টা করুন." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:50 +msgid "Connecting to your wallet" +msgstr "আপনার ওয়ালেটে সংযোগ করা হচ্ছে" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:51 +msgid "Click connect in your wallet popup." +msgstr "আপনার ওয়ালেট পপআপে সংযোগ ক্লিক করুন।" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:99 +msgid "Select Derivation Path" +msgstr "ডেরিভেশন পাথ নির্বাচন করুন" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:100 +msgid "In order to connect to {type}, you must first select a Derivation Path" +msgstr "{type}এর সাথে সংযোগ করার জন্য, আপনাকে প্রথমে একটি ডেরিভেশন পাথ নির্বাচন করতে হবে" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:118 +msgid "Choose Derivation Path Template" +msgstr "ডেরিভেশন পাথ টেমপ্লেট নির্বাচন করুন" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:133 +msgid "Enter Path" +msgstr "পাথ লিখুন" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:134 +msgid "Enter Index" +msgstr "ইনডেক্স লিখুন" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:15 +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:18 +msgid "Add {blockchainDisplayName} Chain" +msgstr "{blockchainDisplayName} চেইন যোগ করুন" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:20 +msgid "Would you like to add the {blockchainDisplayName} experimental chain to your wallet?" +msgstr "আপনি কি আপনার ওয়ালেটে {blockchainDisplayName} পরীক্ষামূলক চেইন যোগ করতে চান?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:22 +msgid "Please approve the experimental chain pop-up in your wallet." +msgstr "অনুগ্রহ করে আপনার ওয়ালেটে পরীক্ষামূলক চেইন পপ-আপ অনুমোদন করুন।" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:30 +msgid "{blockchainDisplayName} Chain Added" +msgstr "{blockchainDisplayName} চেইন যোগ করা হয়েছে" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:34 +msgid "The {blockchainDisplayName} chain has been successfully added to your wallet." +msgstr "{blockchainDisplayName} চেইন সফলভাবে আপনার ওয়ালেটে যোগ করা হয়েছে৷" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:42 +msgid "Request Rejected" +msgstr "অনুরোধ প্রত্যাখ্যাত" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:43 +msgid "You've rejected adding {blockchainDisplayName} chain to your wallet." +msgstr "আপনি আপনার ওয়ালেটে {blockchainDisplayName} চেইন যোগ করা প্রত্যাখ্যান করেছেন৷" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:70 +msgid "Select chain types" +msgstr "চেইন প্রকার নির্বাচন করুন" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:71 +msgid "This wallet supports multiple chains. Select which chain you'd like to connect to." +msgstr "এই ওয়ালেট একাধিক চেইন সমর্থন করে। আপনি কোন চেইনটির সাথে সংযোগ করতে চান তা নির্বাচন করুন৷" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:9 +msgid "Failed Network, Please retry your swap." +msgstr "ব্যর্থ নেটওয়ার্ক, আপনার অদলবদল পুনরায় চেষ্টা করুন." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:11 +msgid "Please reset your liquidity sources." +msgstr "অনুগ্রহ করে আপনার তারল্য উত্স পুনরায় সেট করুন।" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:12 +msgid "You have limited the liquidity sources and this might result in Rango finding no routes. Please consider resetting your liquidity sources." +msgstr "আপনি তারল্যের উত্স সীমিত করেছেন এবং এর ফলে Rango কোনো রুট খুঁজে না পেতে পারে। অনুগ্রহ করে আপনার তারল্য উত্স পুনরায় সেট করার কথা বিবেচনা করুন।" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:17 +msgid "No Routes Found." +msgstr "কোন রুট পাওয়া যায়নি." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:18 +msgid "Reasons why Rango couldn't find a route: low liquidity on token, very low input amount or no routes available for the selected input/output token combination." +msgstr "রেঙ্গো কেন একটি রুট খুঁজে পায়নি তার কারণ: টোকেনে কম তারল্য, খুব কম ইনপুট পরিমাণ বা নির্বাচিত ইনপুট/আউটপুট টোকেন সংমিশ্রণের জন্য কোনও রুট উপলব্ধ নেই।" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:23 +msgid "Bridge Limit Error: Please increase your amount." +msgstr "সেতু সীমা ত্রুটি: আপনার পরিমাণ বৃদ্ধি করুন." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:26 +msgid "Bridge Limit Error: Please decrease your amount." +msgstr "সেতু সীমা ত্রুটি: আপনার পরিমাণ হ্রাস করুন." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:31 +msgid "High Price Impact" +msgstr "উচ্চ মূল্যের প্রভাব" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:32 +msgid "Price impact is too high!" +msgstr "দামের প্রভাব খুব বেশি!" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:33 +msgid "The price impact is significantly higher than the allowed amount." +msgstr "মূল্যের প্রভাব অনুমোদিত পরিমাণের তুলনায় উল্লেখযোগ্যভাবে বেশি।" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:36 +msgid "Confirm high price impact" +msgstr "উচ্চ মূল্য প্রভাব নিশ্চিত করুন" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:39 +msgid "Route updated and price impact is too high, try again later!" +msgstr "রুট আপডেট করা হয়েছে এবং দামের প্রভাব খুব বেশি, পরে আবার চেষ্টা করুন!" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:44 +msgid "USD Price Unknown" +msgstr "USD মূল্য অজানা" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:45 +msgid "USD Price Unknown, Cannot calculate Price Impact." +msgstr "USD মূল্য অজানা, মূল্যের প্রভাব গণনা করা যাচ্ছে না।" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:46 +msgid "USD Price Unknown, Cannot calculate Price Impact. The price impact may be higher than usual. Are you sure to continue the Swap?" +msgstr "USD মূল্য অজানা, মূল্যের প্রভাব গণনা করা যাচ্ছে না। দামের প্রভাব স্বাভাবিকের চেয়ে বেশি হতে পারে। আপনি কি অদলবদল চালিয়ে যাওয়ার বিষয়ে নিশ্চিত?" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:49 +msgid "Confirm USD Price Unknown" +msgstr "নিশ্চিত করুন USD মূল্য অজানা" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:6 +#: widget/embedded/src/pages/Home.tsx:163 +msgid "Swap" +msgstr "অদলবদল" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:7 +msgid "Swap anyway" +msgstr "যেভাবেই হোক অদলবদল করুন" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:8 +msgid "The route goes through Ethereum. Continue?" +msgstr "রুট Ethereum মাধ্যমে যায়. চালিয়ে যান?" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:10 +msgid "Route has been updated." +msgstr "রুট আপডেট করা হয়েছে।" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:12 +msgid "Output amount changed to {newOutputAmount} ({percentageChange}% change)." +msgstr "আউটপুট পরিমাণ {newOutputAmount} এ পরিবর্তিত হয়েছে ({percentageChange}% পরিবর্তন)।" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:20 +msgid "Route swappers has been updated." +msgstr "রুট সোয়াপার আপডেট করা হয়েছে।" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:22 +msgid "Route internal coins has been updated." +msgstr "রুট অভ্যন্তরীণ মুদ্রা আপডেট করা হয়েছে." + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/ExpandedQuotes/ExpandedQuotes.tsx:53 +#: widget/embedded/src/pages/Routes.tsx:48 +msgid "Routes" +msgstr "রুট" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Inputs/Inputs.tsx:76 +msgid "From" +msgstr "থেকে" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Inputs/Inputs.tsx:118 +msgid "To" +msgstr "প্রতি" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:49 +msgid "Light" +msgstr "আলো" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:58 +msgid "Dark" +msgstr "অন্ধকার" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:67 +msgid "Auto" +msgstr "অটো" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:140 +msgid "Loading failed" +msgstr "লোডিং ব্যর্থ হয়েছে৷" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:156 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:41 +msgid "Bridges" +msgstr "ব্রিজ" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:174 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:41 +msgid "Exchanges" +msgstr "বিনিময়" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:195 +#: widget/embedded/src/pages/CustomTokensPage.tsx:90 +msgid "Custom Tokens" +msgstr "কাস্টম টোকেন" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:214 +#: widget/embedded/src/pages/LanguagePage.tsx:43 +msgid "Language" +msgstr "ভাষা" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:235 +msgid "Infinite approval" +msgstr "অসীম অনুমোদন" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:246 +msgid "Enabling the 'Infinite approval' mode grants unrestricted access to underlying smart contracts, allowing them to utilize the approved token amount without limitations." +msgstr "'অসীম অনুমোদন' মোড সক্ষম করা অন্তর্নিহিত স্মার্ট চুক্তিগুলিতে সীমাহীন অ্যাক্সেস মঞ্জুর করে, তাদের সীমাবদ্ধতা ছাড়াই অনুমোদিত টোকেন পরিমাণ ব্যবহার করার অনুমতি দেয়।" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:266 +msgid "Theme" +msgstr "থিম" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:39 +msgid "Duplicate Token" +msgstr "ডুপ্লিকেট টোকেন" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:40 +msgid "The address you entered is duplicate, please enter a new address." +msgstr "আপনি যে ঠিকানাটি লিখেছেন তা সদৃশ, অনুগ্রহ করে একটি নতুন ঠিকানা লিখুন৷" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:46 +msgid "Token Already Exists" +msgstr "টোকেন ইতিমধ্যেই বিদ্যমান৷" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:47 +msgid "There's no need to add this token again because it already exists and is supported by us." +msgstr "এই টোকেনটি আবার যোগ করার দরকার নেই কারণ এটি ইতিমধ্যেই বিদ্যমান এবং আমাদের দ্বারা সমর্থিত।" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:53 +msgid "Token Not Found" +msgstr "টোকেন পাওয়া যায়নি" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:54 +msgid "Sorry, no token was found on {blockchain} chain with the provided address. please make sure you have entered the right token address." +msgstr "দুঃখিত, প্রদত্ত ঠিকানা সহ {blockchain} চেইনে কোনো টোকেন পাওয়া যায়নি৷ দয়া করে নিশ্চিত করুন যে আপনি সঠিক টোকেন ঠিকানাটি প্রবেশ করেছেন।" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:78 +msgid "Network Error" +msgstr "নেটওয়ার্ক ত্রুটি৷" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:109 +#: widget/embedded/src/pages/CustomTokensPage.tsx:149 +msgid "Add Custom Token" +msgstr "কাস্টম টোকেন যোগ করুন" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:127 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:128 +msgid "Select chain" +msgstr "চেইন নির্বাচন করুন" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:132 +msgid "Enter Address" +msgstr "ঠিকানা লিখুন" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:139 +msgid "Enter token address" +msgstr "টোকেন ঠিকানা লিখুন" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:176 +msgid "Failed Network, Please retry." +msgstr "নেটওয়ার্ক ব্যর্থ হয়েছে, অনুগ্রহ করে আবার চেষ্টা করুন।" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:192 +msgid "Add another custom token" +msgstr "আরেকটি কাস্টম টোকেন যোগ করুন" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:236 +msgid "Confirm Swap" +msgstr "অদলবদল নিশ্চিত করুন" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:254 +msgid "Start Swap" +msgstr "অদলবদল শুরু করুন" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:282 +msgid "You get" +msgstr "আপনি পাবেন" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:102 +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:90 +msgid "Search Token" +msgstr "টোকেন অনুসন্ধান করুন" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:134 +msgid "No custom tokens" +msgstr "কোনো কাস্টম টোকেন নেই" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:135 +msgid "press the button to add your custom token" +msgstr "আপনার কাস্টম টোকেন যোগ করতে বোতাম টিপুন" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:158 +msgid "Delete Custom Token" +msgstr "কাস্টম টোকেন মুছুন" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:160 +msgid "Are you sure you want to Delete this Token?" +msgstr "আপনি কি নিশ্চিত আপনি এই টোকেন মুছে ফেলতে চান?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:59 +msgid "Complete" +msgstr "সম্পূর্ণ" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:63 +msgid "Running" +msgstr "চলছে" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:65 +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:8 +msgid "Failed" +msgstr "ব্যর্থ হয়েছে" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:149 +msgid "Clear" +msgstr "পরিষ্কার" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:161 +msgid "Search Transaction" +msgstr "অনুসন্ধান লেনদেন" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:187 +msgid "No transactions" +msgstr "কোনো লেনদেন নেই" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:194 +msgid "Your transaction history is stored locally and will appear here after you start a swap" +msgstr "আপনার লেনদেনের ইতিহাস স্থানীয়ভাবে সংরক্ষণ করা হয় এবং আপনি একটি অদলবদল শুরু করার পরে এখানে উপস্থিত হবে৷" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:218 +msgid "Clear Transaction History" +msgstr "লেনদেনের ইতিহাস সাফ করুন" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:222 +msgid "Proceeding will remove all successful and failed transactions from the widget. Do you want to continue?" +msgstr "অগ্রসর হলে উইজেট থেকে সমস্ত সফল এবং ব্যর্থ লেনদেন মুছে ফেলা হবে। আপনি কি চালিয়ে যেতে চান?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:229 +msgid "Note: This does not erase your transaction history on the chain; it only removes them here." +msgstr "দ্রষ্টব্য: এটি চেইনে আপনার লেনদেনের ইতিহাস মুছে ফেলবে না; এটি শুধুমাত্র তাদের এখানে সরিয়ে দেয়।" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:243 +msgid "Yes, Clear the history" +msgstr "হ্যাঁ, ইতিহাস সাফ করুন" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LanguagePage.tsx:56 +msgid "language" +msgstr "ভাষা" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:121 +msgid "Deselect all" +msgstr "সব বাদ দিন" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:121 +msgid "Select all" +msgstr "সব নির্বাচন করুন" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:133 +msgid "Search {sourceType}" +msgstr "{sourceType}অনুসন্ধান করুন৷" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectBlockchainPage.tsx:60 +msgid "Search Chain" +msgstr "অনুসন্ধান চেইন" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:67 +msgid "Source" +msgstr "উৎস" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:68 +msgid "Destination" +msgstr "গন্তব্য" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:74 +msgid "Swap {type}" +msgstr "অদলবদল {type}৷" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SettingsPage.tsx:45 +msgid "Currently, you're in campaign mode with restrictions on liquidity sources. Would you like to switch out of this mode and make use of all available liquidity sources?" +msgstr "বর্তমানে, আপনি তারল্য উত্সের উপর বিধিনিষেধ সহ প্রচারাভিযান মোডে আছেন। আপনি কি এই মোড থেকে স্যুইচ আউট করতে এবং সমস্ত উপলব্ধ তারল্য উত্স ব্যবহার করতে চান?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SwapDetailsPage.tsx:27 +msgid "The request ID is necessary to display the swap details." +msgstr "অদলবদল বিবরণ প্রদর্শন করার জন্য অনুরোধ আইডি প্রয়োজনীয়।" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/WalletsPage.tsx:67 +#: widget/ui/src/containers/ConnectWalletsModal/ConnectWalletsModal.tsx:15 +msgid "Connect Wallets" +msgstr "ওয়ালেট সংযুক্ত করুন" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/WalletsPage.tsx:82 +msgid "Choose a wallet to connect." +msgstr "সংযোগ করতে একটি মানিব্যাগ চয়ন করুন." + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:25 +msgid "This week" +msgstr "এই সপ্তাহে" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:32 +msgid "This month" +msgstr "এই মাসে" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:39 +msgid "This year" +msgstr "এই বছর" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:129 +msgid "Required: >= {min} {symbol}" +msgstr "প্রয়োজনীয়: >= {min} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:142 +msgid "Required: > {min} {symbol}" +msgstr "প্রয়োজনীয়: > {min} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:157 +msgid "Required: <= {max} {symbol}" +msgstr "প্রয়োজনীয়: <= {max} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:170 +msgid "Required: < {max} {symbol}" +msgstr "প্রয়োজনীয়: < {max} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:601 +msgid " for network fee" +msgstr " নেটওয়ার্ক ফি জন্য" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:604 +msgid " for swap" +msgstr " অদলবদলের জন্য" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:607 +msgid " for input and network fee" +msgstr " ইনপুট এবং নেটওয়ার্ক ফি জন্য" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:609 +msgid "Needs ≈ {requiredAmount} {symbol}{reason}, but you have {currentAmount} {symbol} in your {blockchain} wallet." +msgstr "প্রয়োজন ≈ {requiredAmount} {symbol}{reason}, কিন্তু আপনার {blockchain} ওয়ালেটে {currentAmount} {symbol} আছে৷" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:669 +msgid "Waiting for connecting wallet" +msgstr "মানিব্যাগ সংযোগের জন্য অপেক্ষা করা হচ্ছে" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:673 +msgid "Waiting for other running tasks to be finished" +msgstr "অন্যান্য চলমান কাজ সমাপ্ত হওয়ার জন্য অপেক্ষা করা হচ্ছে" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:676 +msgid "Waiting for changing wallet network" +msgstr "ওয়ালেট নেটওয়ার্ক পরিবর্তনের জন্য অপেক্ষা করা হচ্ছে" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:6 +msgid "Sunday" +msgstr "রবিবার" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:7 +msgid "Monday" +msgstr "সোমবার" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:8 +msgid "Tuesday" +msgstr "মঙ্গলবার" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:9 +msgid "Wednesday" +msgstr "বুধবার" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:10 +msgid "Thursday" +msgstr "বৃহস্পতিবার" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:11 +msgid "Friday" +msgstr "শুক্রবার" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:12 +msgid "Saturday" +msgstr "শনিবার" + +#. js-lingui-explicit-id +#: widget/ui/src/components/BottomLogo/BottomLogo.tsx:14 +msgid "Powered By" +msgstr "দ্বারা চালিত" + +#. js-lingui-explicit-id +#: widget/ui/src/components/FullExpandedQuote/FullExpandedQuote.Tooltip.tsx:37 +msgid "Aggregated Transaction" +msgstr "সমষ্টিগত লেনদেন" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SelectableCategoryList/SelectableCategoryList.tsx:63 +msgid "{blockchainCategory}" +msgstr "{blockchainCategory}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/StepDetails/StepDetails.tsx:75 +#: widget/ui/src/components/StepDetails/StepDetails.tsx:102 +msgid "Swap on {fromChain} via {swapper}" +msgstr "{swapper}এর মাধ্যমে {fromChain} এ অদলবদল করুন৷" + +#. js-lingui-explicit-id +#: widget/ui/src/components/StepDetails/StepDetails.tsx:109 +msgid "Bridge to {toChain} via {swapper}" +msgstr "{swapper}হয়ে {toChain} এ সেতু" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:10 +msgid "Completed" +msgstr "সম্পন্ন" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:12 +msgid "In progress" +msgstr "চলছে" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapToken.tsx:122 +msgid "Waiting for bridge transaction" +msgstr "সেতু লেনদেনের জন্য অপেক্ষা করছে" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:12 +msgid "Connected" +msgstr "সংযুক্ত" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:13 +msgid "Disconnect" +msgstr "সংযোগ বিচ্ছিন্ন করুন" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:18 +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:19 +msgid "Install" +msgstr "ইনস্টল করুন" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:24 +msgid "Connecting ..." +msgstr "সংযোগ করা হচ্ছে..." + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:25 +msgid "Connecting" +msgstr "সংযোগ করা হচ্ছে" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:30 +msgid "Disconnected" +msgstr "সংযোগ বিচ্ছিন্ন" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:34 +msgid "you need to pass a correct state to Wallet." +msgstr "আপনাকে Wallet এ একটি সঠিক অবস্থা দিতে হবে।" + +#. js-lingui-explicit-id +#: widget/ui/src/containers/Notifications/NotificationNotFound.tsx:15 +msgid "There are no notifications." +msgstr "কোন বিজ্ঞপ্তি নেই." + +#. js-lingui-explicit-id +#: widget/ui/src/containers/Notifications/Notifications.tsx:39 +msgid "Clear all" +msgstr "সব সাফ করুন" + +#. js-lingui-explicit-id +#: widget/ui/src/containers/SwapInput/SwapInput.tsx:65 +msgid "Balance" +msgstr "ভারসাম্য" + +#. js-lingui-explicit-id +#: widget/ui/src/containers/SwapInput/SwapInput.tsx:73 +msgid "Max" +msgstr "সর্বোচ্চ" + diff --git a/translations/ca.po b/translations/ca.po new file mode 100644 index 0000000000..8028030c65 --- /dev/null +++ b/translations/ca.po @@ -0,0 +1,1339 @@ +msgid "" +msgstr "" +"POT-Creation-Date: 2023-11-06 17:24+0330\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: @lingui/cli\n" +"Language: ca\n" +"Project-Id-Version: rango\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2024-11-27 15:57\n" +"Last-Translator: \n" +"Language-Team: Catalan\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Crowdin-Project: rango\n" +"X-Crowdin-Project-ID: 622238\n" +"X-Crowdin-Language: ca\n" +"X-Crowdin-File: en.po\n" +"X-Crowdin-File-ID: 30\n" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SameTokensWarning/SameTokensWarning.tsx:21 +msgid "No Routes Found" +msgstr "No s'han trobat rutes" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SameTokensWarning/SameTokensWarning.tsx:25 +msgid "You cannot use the same token for From and To." +msgstr "No podeu utilitzar el mateix testimoni per a De i Per." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:41 +#: widget/embedded/src/components/TokenList/TokenList.tsx:286 +#: widget/embedded/src/pages/HistoryPage.tsx:186 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:143 +msgid "No results found" +msgstr "No s'han trobat resultats" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:42 +#: widget/embedded/src/components/TokenList/TokenList.tsx:287 +#: widget/embedded/src/pages/HistoryPage.tsx:193 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:144 +msgid "Try using different keywords" +msgstr "Proveu d'utilitzar paraules clau diferents" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:72 +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:46 +#: widget/embedded/src/pages/SelectBlockchainPage.tsx:42 +#: widget/ui/src/containers/SwapInput/TokenSection.tsx:61 +msgid "Select Chain" +msgstr "Seleccioneu Cadena" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:66 +msgid "All" +msgstr "Tots" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:100 +msgid "More +{count}" +msgstr "Més +{count}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabAlert/ActivateTabAlert.tsx:17 +msgid "Activate this tab" +msgstr "Activa aquesta pestanya" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabAlert/ActivateTabAlert.tsx:22 +msgid "Another tab is open and handles transactions." +msgstr "Una altra pestanya està oberta i gestiona les transaccions." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:20 +msgid "Activate current tab" +msgstr "Activa la pestanya actual" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:22 +msgid "Currently, some transactions are running and being handled by other browser tab. If you activate this tab, all transactions that are already in the transaction sign step will expire." +msgstr "Actualment, algunes transaccions s'estan executant i gestionades per una altra pestanya del navegador. Si activeu aquesta pestanya, caducaran totes les transaccions que ja estiguin al pas de signatura de la transacció." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:33 +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:349 +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:152 +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:33 +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:116 +msgid "Confirm" +msgstr "Confirmeu" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:365 +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:447 +msgid "Your {blockchainName} wallets" +msgstr "Les vostres carteres {blockchainName}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:384 +msgid "Insufficient account balance" +msgstr "Saldo del compte insuficient" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:394 +msgid "Proceed anyway" +msgstr "Continueu igualment" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:456 +msgid "You need to connect a {blockchainName} wallet." +msgstr "Heu de connectar una cartera {blockchainName} ." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/WalletList.tsx:143 +msgid "Add {chain} chain" +msgstr "Afegeix {chain} cadena" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/WalletList.tsx:244 +msgid "Show more wallets" +msgstr "Mostra més carteres" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:113 +msgid "Send to a different address" +msgstr "Enviar a una adreça diferent" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:129 +msgid "Enter {blockchainName} address" +msgstr "Introduïu l'adreça {blockchainName}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:147 +msgid "Address {destination} doesn't match the blockchain address pattern." +msgstr "L'adreça {destination} no coincideix amb el patró d'adreces blockchain." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:59 +msgid "via" +msgstr "via" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:74 +msgid "This token doesn't appear on the active token list(s). Make sure this is the token that you want to trade." +msgstr "Aquest testimoni no apareix a les llistes de fitxes actives. Assegureu-vos que aquest és el testimoni que voleu negociar." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:89 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:164 +msgid "Import" +msgstr "Importar" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/FilterSelector/FilterSelectorContent.tsx:26 +msgid "Status" +msgstr "Estat" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/FilterSelector/FilterSelectorContent.tsx:33 +#: widget/embedded/src/components/NoResult/NoResult.helpers.ts:37 +#: widget/embedded/src/pages/SettingsPage.tsx:55 +msgid "Reset" +msgstr "Restableix" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/CancelButton.tsx:18 +msgid "Cancel" +msgstr "Cancel·la" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:46 +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:34 +msgid "Refresh" +msgstr "Actualitza" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:63 +#: widget/ui/src/containers/Notifications/Notifications.tsx:35 +msgid "Notifications" +msgstr "Notificacions" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:79 +#: widget/embedded/src/pages/SettingsPage.tsx:38 +msgid "Settings" +msgstr "Configuració" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:93 +#: widget/embedded/src/pages/HistoryPage.tsx:139 +msgid "History" +msgstr "Història" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/WalletButton.tsx:22 +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:16 +#: widget/embedded/src/constants/messages.ts:5 +msgid "Connect Wallet" +msgstr "Connecta Wallet" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HistoryGroupedList/HistoryGroupedList.tsx:118 +#: widget/embedded/src/utils/date.ts:18 +#: widget/embedded/src/utils/time.ts:22 +msgid "Today" +msgstr "Avui" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/LoadingSwapDetails/LoadingSwapDetails.tsx:20 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:424 +msgid "Swaps steps" +msgstr "Canvia passos" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/NoResult/NoResult.helpers.ts:25 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:191 +msgid "Retry" +msgstr "Torna-ho a provar" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:149 +msgid "Slippage Error" +msgstr "Error de lliscament" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:150 +msgid "Slippage Warning" +msgstr "Avís de lliscament" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:153 +msgid "Bridge Limit Error" +msgstr "Error de límit del pont" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:240 +msgid "Yours: {amount} {symbol}" +msgstr "El teu: {amount} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:261 +msgid "Minimum required slippage: {minRequiredSlippage}" +msgstr "Lliscament mínim requerit: {minRequiredSlippage}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:282 +msgid "Yours: {userSlippage}" +msgstr "El teu: {userSlippage}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:395 +msgid "See All Routes" +msgstr "Veure totes les rutes" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:81 +msgid "View more info" +msgstr "Veure més informació" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:91 +msgid "Gas & Fee Explanation" +msgstr "Explicació de la tarifa i el gas" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:107 +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:103 +msgid "Details" +msgstr "Detalls" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:146 +msgid "Total Payable Fee" +msgstr "Quota total a pagar" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:166 +msgid "Hide non-payable fees" +msgstr "Amaga les taxes no pagables" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:167 +msgid "Show non-payable fees" +msgstr "Mostra les taxes no pagables" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:177 +msgid "Description" +msgstr "Descripció" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:181 +msgid "The following fees are considered in the transaction output and\n" +" you won’t need to pay extra gas for them." +msgstr "Les tarifes següents es tenen en compte a la sortida de la transacció i\n" +" no haureu de pagar gas addicional per elles." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteSummary.tsx:25 +msgid "Swap input" +msgstr "Canvia l'entrada" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteSummary.tsx:44 +msgid "Estimated output" +msgstr "Sortida estimada" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteTrigger.tsx:65 +msgid "Via:" +msgstr "Via:" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteTrigger.tsx:150 +msgid "Chains:" +msgstr "Cadenes:" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/Quotes.tsx:77 +msgid "Sort by" +msgstr "Ordena per" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:17 +msgid "Smart Routing" +msgstr "Enrutament intel·ligent" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:21 +msgid "Lowest Fee" +msgstr "Tarifa més baixa" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:25 +msgid "Fastest Transfer" +msgstr "La transferència més ràpida" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:29 +msgid "Maximum Return" +msgstr "Rendiment màxim" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:33 +msgid "Maximum Output" +msgstr "Sortida màxima" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:43 +msgid "Swapping" +msgstr "Canvi" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:51 +msgid "Gas cost" +msgstr "Cost del gas" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:59 +msgid "Receiving" +msgstr "Recepció" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:67 +msgid "Price impact" +msgstr "Impacte en el preu" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:35 +msgid "You need to increase slippage to at least {minRequiredSlippage} for this route." +msgstr "Heu d'augmentar el lliscament com a mínim a {minRequiredSlippage} per a aquesta ruta." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:59 +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:61 +msgid "We recommend you to increase slippage to at least {minRequiredSlippage} for this route." +msgstr "Us recomanem que augmenteu el lliscament com a mínim a {minRequiredSlippage} per a aquesta ruta." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:68 +msgid "Caution, your slippage is high." +msgstr "Atenció, el vostre lliscament és alt." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.tsx:78 +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.Warning.tsx:26 +msgid "Change" +msgstr "Canviar" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:42 +msgid "Change settings" +msgstr "Canvia la configuració" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:52 +msgid "High slippage" +msgstr "Alt lliscament" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:53 +msgid "Low slippage" +msgstr "Baix lliscament" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:57 +msgid " Caution, your slippage is high (={userSlippage}). Your trade may be front run." +msgstr " Atenció, el vostre lliscament és alt (={userSlippage}). El vostre comerç pot ser al capdavant." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:78 +msgid "Confirm anyway" +msgstr "Confirmeu igualment" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:22 +msgid "Something went wrong" +msgstr "Alguna cosa va fallar" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:24 +msgid "Something went wrong. Please refresh the app." +msgstr "Alguna cosa va fallar. Actualitzeu l'aplicació." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/Slippage.tsx:38 +msgid "Slippage tolerance per swap" +msgstr "Tolerància de lliscament per canvi" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/Slippage.tsx:91 +msgid "Custom" +msgstr "Personalitzat" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:11 +msgid "Your transaction will be reverted if the price changes unfavorably by more than this percentage." +msgstr "La vostra transacció es revertirà si el preu canvia desfavorablement en més d'aquest percentatge." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:16 +#: widget/embedded/src/containers/Settings/Lists.tsx:245 +msgid "Warning" +msgstr "Avís" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:17 +msgid "This setting is applied to each step (e.g. 1Inch, Thorchain, etc.), meaning only that specific step will be reverted, not the entire route." +msgstr "Aquesta configuració s'aplica a cada pas (per exemple, 1 polzada, Thorchain, etc.), el que significa que només es revertirà aquest pas específic, no tota la ruta." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:25 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:269 +msgid "Swap Details" +msgstr "Detalls de l'intercanvi" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:33 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:312 +msgid "Request ID" +msgstr "Sol·licitud d'identificació" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:64 +msgid "Not found" +msgstr "No s'ha trobat" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:65 +msgid "Swap with request ID = {requestId} not found." +msgstr "Canvia amb l'ID de sol·licitud = {requestId} no s'ha trobat." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:219 +msgid "You have received {amount} {token} in {conciseAddress} wallet on {chain} chain." +msgstr "Heu rebut {amount} {token} a la cartera {conciseAddress} de la cadena {chain} ." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:242 +msgid "Transaction was not sent." +msgstr "La transacció no s'ha enviat." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:244 +msgid "{amount} {symbol} on {blockchain} remains in your wallet." +msgstr "{amount} {symbol} el {blockchain} roman a la cartera." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:281 +msgid "Delete" +msgstr "Suprimeix" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:304 +msgid "Try again" +msgstr "Torna-ho a provar" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:322 +msgid "Copied To Clipboard" +msgstr "S'ha copiat al porta-retalls" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:323 +msgid "Copy Request ID" +msgstr "Copia l'identificador de sol·licitud" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:346 +msgid "View on Rango Explorer" +msgstr "Veure a Rango Explorer" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:355 +msgid "Finished at" +msgstr "Acabat a les" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:355 +msgid "Created at" +msgstr "Creat a" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.tsx:50 +msgid "View transaction" +msgstr "Veure transacció" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.Warning.tsx:49 +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:31 +msgid "Connect" +msgstr "Connecta't" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:43 +msgid "Swap Successful" +msgstr "Canvi amb èxit" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:71 +msgid "Transaction Failed" +msgstr "La transacció ha fallat" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:87 +msgid "Done" +msgstr "Fet" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:100 +msgid "Diagnosis" +msgstr "Diagnòstic" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:112 +msgid "See Details" +msgstr "Veure Detalls" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:13 +msgid "Cancel Swap" +msgstr "Cancel·la l'intercanvi" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:14 +msgid "Are you sure you want to cancel this swap?" +msgstr "Esteu segur que voleu cancel·lar aquest intercanvi?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:23 +msgid "Yes, Cancel it" +msgstr "Sí, cancel·la-ho" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:32 +#: widget/embedded/src/pages/CustomTokensPage.tsx:181 +msgid "No, Continue" +msgstr "No, continua" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:13 +msgid "Delete Transaction" +msgstr "Suprimeix la transacció" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:14 +msgid "Are you sure you want to delete this swap?" +msgstr "Esteu segur que voleu suprimir aquest intercanvi?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:23 +#: widget/embedded/src/pages/CustomTokensPage.tsx:171 +msgid "Yes, Delete it" +msgstr "Sí, esborra-ho" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:33 +#: widget/embedded/src/pages/HistoryPage.tsx:253 +msgid "No, Cancel" +msgstr "No, cancel·la" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:12 +msgid "Change Network" +msgstr "Canviar Xarxa" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:20 +msgid "Network Changed" +msgstr "La xarxa ha canviat" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/TokenList/TokenList.tsx:271 +#: widget/ui/src/containers/SwapInput/TokenSection.tsx:54 +msgid "Select Token" +msgstr "Seleccioneu Token" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:27 +msgid "Wallet Connected" +msgstr "Wallet connectat" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:28 +msgid "Your wallet is connected, you can use it to swap." +msgstr "La vostra cartera està connectada, podeu utilitzar-la per intercanviar." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:39 +msgid "Failed to Connect" +msgstr "No s'ha pogut connectar" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:41 +msgid "Your wallet is not connected. Please try again." +msgstr "La teva cartera no està connectada. Si us plau, torna-ho a provar." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:50 +msgid "Connecting to your wallet" +msgstr "Connectant a la teva cartera" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:51 +msgid "Click connect in your wallet popup." +msgstr "Feu clic a connectar a la finestra emergent de la cartera." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:99 +msgid "Select Derivation Path" +msgstr "Seleccioneu Camí de derivació" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:100 +msgid "In order to connect to {type}, you must first select a Derivation Path" +msgstr "Per connectar-vos a {type}, primer heu de seleccionar un camí de derivació" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:118 +msgid "Choose Derivation Path Template" +msgstr "Trieu Plantilla de camí de derivació" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:133 +msgid "Enter Path" +msgstr "Introduïu el camí" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:134 +msgid "Enter Index" +msgstr "Introduïu l'índex" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:15 +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:18 +msgid "Add {blockchainDisplayName} Chain" +msgstr "Afegeix {blockchainDisplayName} cadena" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:20 +msgid "Would you like to add the {blockchainDisplayName} experimental chain to your wallet?" +msgstr "Vols afegir la cadena experimental {blockchainDisplayName} a la teva cartera?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:22 +msgid "Please approve the experimental chain pop-up in your wallet." +msgstr "Aproveu la finestra emergent de la cadena experimental a la vostra cartera." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:30 +msgid "{blockchainDisplayName} Chain Added" +msgstr "{blockchainDisplayName} Cadena afegida" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:34 +msgid "The {blockchainDisplayName} chain has been successfully added to your wallet." +msgstr "La cadena {blockchainDisplayName} s'ha afegit correctament a la vostra cartera." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:42 +msgid "Request Rejected" +msgstr "Sol·licitud rebutjada" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:43 +msgid "You've rejected adding {blockchainDisplayName} chain to your wallet." +msgstr "Has rebutjat afegir la cadena {blockchainDisplayName} a la teva cartera." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:70 +msgid "Select chain types" +msgstr "Seleccioneu els tipus de cadena" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:71 +msgid "This wallet supports multiple chains. Select which chain you'd like to connect to." +msgstr "Aquesta cartera admet múltiples cadenes. Seleccioneu a quina cadena us voleu connectar." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:9 +msgid "Failed Network, Please retry your swap." +msgstr "La xarxa ha fallat. Torneu a provar l'intercanvi." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:11 +msgid "Please reset your liquidity sources." +msgstr "Reinicieu les fonts de liquiditat." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:12 +msgid "You have limited the liquidity sources and this might result in Rango finding no routes. Please consider resetting your liquidity sources." +msgstr "Heu limitat les fonts de liquiditat i això pot fer que Rango no trobi cap ruta. Considereu la possibilitat de restablir les vostres fonts de liquiditat." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:17 +msgid "No Routes Found." +msgstr "No s'han trobat rutes." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:18 +msgid "Reasons why Rango couldn't find a route: low liquidity on token, very low input amount or no routes available for the selected input/output token combination." +msgstr "Motius pels quals Rango no ha pogut trobar una ruta: poca liquiditat al testimoni, quantitat d'entrada molt baixa o no hi ha rutes disponibles per a la combinació de testimoni d'entrada/sortida seleccionada." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:23 +msgid "Bridge Limit Error: Please increase your amount." +msgstr "Error de límit de pont: augmenta l'import." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:26 +msgid "Bridge Limit Error: Please decrease your amount." +msgstr "Error de límit de pont: reduïu l'import." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:31 +msgid "High Price Impact" +msgstr "Alt impacte dels preus" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:32 +msgid "Price impact is too high!" +msgstr "L'impacte del preu és massa alt!" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:33 +msgid "The price impact is significantly higher than the allowed amount." +msgstr "L'impacte del preu és significativament superior a la quantitat permesa." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:36 +msgid "Confirm high price impact" +msgstr "Confirmeu l'alt impacte dels preus" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:39 +msgid "Route updated and price impact is too high, try again later!" +msgstr "La ruta s'ha actualitzat i l'impacte en el preu és massa alt, torna-ho a provar més tard!" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:44 +msgid "USD Price Unknown" +msgstr "Preu en USD desconegut" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:45 +msgid "USD Price Unknown, Cannot calculate Price Impact." +msgstr "Preu en USD desconegut, no es pot calcular l'impacte del preu." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:46 +msgid "USD Price Unknown, Cannot calculate Price Impact. The price impact may be higher than usual. Are you sure to continue the Swap?" +msgstr "Preu en USD desconegut, no es pot calcular l'impacte del preu. L'impacte en el preu pot ser més gran de l'habitual. Esteu segur de continuar l'intercanvi?" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:49 +msgid "Confirm USD Price Unknown" +msgstr "Confirmeu el preu en USD desconegut" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:6 +#: widget/embedded/src/pages/Home.tsx:163 +msgid "Swap" +msgstr "Canviar" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:7 +msgid "Swap anyway" +msgstr "Canvia de totes maneres" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:8 +msgid "The route goes through Ethereum. Continue?" +msgstr "La ruta passa per Ethereum. Continuar?" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:10 +msgid "Route has been updated." +msgstr "La ruta s'ha actualitzat." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:12 +msgid "Output amount changed to {newOutputAmount} ({percentageChange}% change)." +msgstr "La quantitat de sortida ha canviat a {newOutputAmount} ({percentageChange}% de canvi)." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:20 +msgid "Route swappers has been updated." +msgstr "Els intercanviadors de rutes s'han actualitzat." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:22 +msgid "Route internal coins has been updated." +msgstr "Les monedes internes de la ruta s'han actualitzat." + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/ExpandedQuotes/ExpandedQuotes.tsx:53 +#: widget/embedded/src/pages/Routes.tsx:48 +msgid "Routes" +msgstr "Rutes" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Inputs/Inputs.tsx:76 +msgid "From" +msgstr "Des de" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Inputs/Inputs.tsx:118 +msgid "To" +msgstr "A" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:49 +msgid "Light" +msgstr "Llum" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:58 +msgid "Dark" +msgstr "Fosc" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:67 +msgid "Auto" +msgstr "Automàtic" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:140 +msgid "Loading failed" +msgstr "S'ha produït un error en carregar" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:156 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:41 +msgid "Bridges" +msgstr "Ponts" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:174 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:41 +msgid "Exchanges" +msgstr "Intercanvis" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:195 +#: widget/embedded/src/pages/CustomTokensPage.tsx:90 +msgid "Custom Tokens" +msgstr "Fitxes personalitzades" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:214 +#: widget/embedded/src/pages/LanguagePage.tsx:43 +msgid "Language" +msgstr "Llengua" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:235 +msgid "Infinite approval" +msgstr "Aprovació infinita" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:246 +msgid "Enabling the 'Infinite approval' mode grants unrestricted access to underlying smart contracts, allowing them to utilize the approved token amount without limitations." +msgstr "L'habilitació del mode \"Aprovació infinita\" concedeix accés sense restriccions als contractes intel·ligents subjacents, cosa que els permet utilitzar la quantitat de testimoni aprovada sense limitacions." + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:266 +msgid "Theme" +msgstr "Tema" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:39 +msgid "Duplicate Token" +msgstr "Token duplicat" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:40 +msgid "The address you entered is duplicate, please enter a new address." +msgstr "L'adreça que heu introduït és duplicada, introduïu una adreça nova." + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:46 +msgid "Token Already Exists" +msgstr "El testimoni ja existeix" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:47 +msgid "There's no need to add this token again because it already exists and is supported by us." +msgstr "No cal tornar a afegir aquest testimoni perquè ja existeix i el donem suport." + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:53 +msgid "Token Not Found" +msgstr "No s'ha trobat el testimoni" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:54 +msgid "Sorry, no token was found on {blockchain} chain with the provided address. please make sure you have entered the right token address." +msgstr "Ho sentim, no s'ha trobat cap testimoni a la cadena {blockchain} amb l'adreça proporcionada. si us plau, assegureu-vos que heu introduït l'adreça de testimoni correcta." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:78 +msgid "Network Error" +msgstr "Error de xarxa" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:109 +#: widget/embedded/src/pages/CustomTokensPage.tsx:149 +msgid "Add Custom Token" +msgstr "Afegeix un testimoni personalitzat" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:127 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:128 +msgid "Select chain" +msgstr "Seleccioneu la cadena" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:132 +msgid "Enter Address" +msgstr "Introduïu l'adreça" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:139 +msgid "Enter token address" +msgstr "Introduïu l'adreça del testimoni" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:176 +msgid "Failed Network, Please retry." +msgstr "La xarxa ha fallat, torneu-ho a provar." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:192 +msgid "Add another custom token" +msgstr "Afegiu un altre testimoni personalitzat" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:236 +msgid "Confirm Swap" +msgstr "Confirmeu l'intercanvi" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:254 +msgid "Start Swap" +msgstr "Inicia l'intercanvi" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:282 +msgid "You get" +msgstr "Ho aconsegueixes" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:102 +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:90 +msgid "Search Token" +msgstr "Token de cerca" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:134 +msgid "No custom tokens" +msgstr "Sense fitxes personalitzades" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:135 +msgid "press the button to add your custom token" +msgstr "premeu el botó per afegir el vostre testimoni personalitzat" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:158 +msgid "Delete Custom Token" +msgstr "Suprimeix el testimoni personalitzat" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:160 +msgid "Are you sure you want to Delete this Token?" +msgstr "Esteu segur que voleu suprimir aquest testimoni?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:59 +msgid "Complete" +msgstr "Completa" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:63 +msgid "Running" +msgstr "Córrer" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:65 +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:8 +msgid "Failed" +msgstr "Ha fallat" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:149 +msgid "Clear" +msgstr "Clar" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:161 +msgid "Search Transaction" +msgstr "Cerca transacció" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:187 +msgid "No transactions" +msgstr "No hi ha transaccions" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:194 +msgid "Your transaction history is stored locally and will appear here after you start a swap" +msgstr "El vostre historial de transaccions s'emmagatzema localment i apareixerà aquí després d'iniciar un intercanvi" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:218 +msgid "Clear Transaction History" +msgstr "Esborra l'historial de transaccions" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:222 +msgid "Proceeding will remove all successful and failed transactions from the widget. Do you want to continue?" +msgstr "Si continueu, s'eliminaran del widget totes les transaccions reeixides i fallides. Vols continuar?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:229 +msgid "Note: This does not erase your transaction history on the chain; it only removes them here." +msgstr "Nota: Això no esborra el vostre historial de transaccions a la cadena; aquí només els elimina." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:243 +msgid "Yes, Clear the history" +msgstr "Sí, esborra l'historial" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LanguagePage.tsx:56 +msgid "language" +msgstr "llengua" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:121 +msgid "Deselect all" +msgstr "Desseleccioneu-ho tot" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:121 +msgid "Select all" +msgstr "Seleccioneu-ho tot" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:133 +msgid "Search {sourceType}" +msgstr "Cerca {sourceType}" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectBlockchainPage.tsx:60 +msgid "Search Chain" +msgstr "Cadena de cerca" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:67 +msgid "Source" +msgstr "Font" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:68 +msgid "Destination" +msgstr "Destinació" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:74 +msgid "Swap {type}" +msgstr "Canvia {type}" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SettingsPage.tsx:45 +msgid "Currently, you're in campaign mode with restrictions on liquidity sources. Would you like to switch out of this mode and make use of all available liquidity sources?" +msgstr "Actualment, esteu en mode campanya amb restriccions a les fonts de liquiditat. Voleu sortir d'aquest mode i fer ús de totes les fonts de liquiditat disponibles?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SwapDetailsPage.tsx:27 +msgid "The request ID is necessary to display the swap details." +msgstr "L'identificador de sol·licitud és necessari per mostrar els detalls de l'intercanvi." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/WalletsPage.tsx:67 +#: widget/ui/src/containers/ConnectWalletsModal/ConnectWalletsModal.tsx:15 +msgid "Connect Wallets" +msgstr "Connecta Wallets" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/WalletsPage.tsx:82 +msgid "Choose a wallet to connect." +msgstr "Trieu una cartera per connectar-vos." + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:25 +msgid "This week" +msgstr "Aquesta setmana" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:32 +msgid "This month" +msgstr "Aquest mes" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:39 +msgid "This year" +msgstr "Aquest any" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:129 +msgid "Required: >= {min} {symbol}" +msgstr "Necessari: >= {min} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:142 +msgid "Required: > {min} {symbol}" +msgstr "Necessari: > {min} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:157 +msgid "Required: <= {max} {symbol}" +msgstr "Obligatori: <= {max} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:170 +msgid "Required: < {max} {symbol}" +msgstr "Necessari: < {max} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:601 +msgid " for network fee" +msgstr " per tarifa de xarxa" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:604 +msgid " for swap" +msgstr " per intercanvi" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:607 +msgid " for input and network fee" +msgstr " per entrada i tarifa de xarxa" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:609 +msgid "Needs ≈ {requiredAmount} {symbol}{reason}, but you have {currentAmount} {symbol} in your {blockchain} wallet." +msgstr "Necessita ≈ {requiredAmount} {symbol}{reason}, però tens {currentAmount} {symbol} a la teva cartera {blockchain} ." + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:669 +msgid "Waiting for connecting wallet" +msgstr "S'està esperant la connexió de la cartera" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:673 +msgid "Waiting for other running tasks to be finished" +msgstr "Esperant que s'acabin altres tasques en execució" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:676 +msgid "Waiting for changing wallet network" +msgstr "S'està esperant el canvi de xarxa de cartera" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:6 +msgid "Sunday" +msgstr "diumenge" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:7 +msgid "Monday" +msgstr "dilluns" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:8 +msgid "Tuesday" +msgstr "dimarts" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:9 +msgid "Wednesday" +msgstr "dimecres" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:10 +msgid "Thursday" +msgstr "dijous" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:11 +msgid "Friday" +msgstr "divendres" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:12 +msgid "Saturday" +msgstr "dissabte" + +#. js-lingui-explicit-id +#: widget/ui/src/components/BottomLogo/BottomLogo.tsx:14 +msgid "Powered By" +msgstr "Desenvolupat per" + +#. js-lingui-explicit-id +#: widget/ui/src/components/FullExpandedQuote/FullExpandedQuote.Tooltip.tsx:37 +msgid "Aggregated Transaction" +msgstr "Transacció agregada" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SelectableCategoryList/SelectableCategoryList.tsx:63 +msgid "{blockchainCategory}" +msgstr "{blockchainCategory}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/StepDetails/StepDetails.tsx:75 +#: widget/ui/src/components/StepDetails/StepDetails.tsx:102 +msgid "Swap on {fromChain} via {swapper}" +msgstr "Canvia a {fromChain} mitjançant {swapper}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/StepDetails/StepDetails.tsx:109 +msgid "Bridge to {toChain} via {swapper}" +msgstr "Pont cap a {toChain} via {swapper}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:10 +msgid "Completed" +msgstr "Completat" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:12 +msgid "In progress" +msgstr "En curs" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapToken.tsx:122 +msgid "Waiting for bridge transaction" +msgstr "S'està esperant la transacció pont" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:12 +msgid "Connected" +msgstr "Connectat" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:13 +msgid "Disconnect" +msgstr "Desconnecta" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:18 +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:19 +msgid "Install" +msgstr "Instal·lar" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:24 +msgid "Connecting ..." +msgstr "S'està connectant..." + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:25 +msgid "Connecting" +msgstr "Connectant" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:30 +msgid "Disconnected" +msgstr "Desconnectat" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:34 +msgid "you need to pass a correct state to Wallet." +msgstr "heu de passar un estat correcte a Wallet." + +#. js-lingui-explicit-id +#: widget/ui/src/containers/Notifications/NotificationNotFound.tsx:15 +msgid "There are no notifications." +msgstr "No hi ha notificacions." + +#. js-lingui-explicit-id +#: widget/ui/src/containers/Notifications/Notifications.tsx:39 +msgid "Clear all" +msgstr "Esborra-ho tot" + +#. js-lingui-explicit-id +#: widget/ui/src/containers/SwapInput/SwapInput.tsx:65 +msgid "Balance" +msgstr "Balanç" + +#. js-lingui-explicit-id +#: widget/ui/src/containers/SwapInput/SwapInput.tsx:73 +msgid "Max" +msgstr "Màx" + diff --git a/translations/da.po b/translations/da.po new file mode 100644 index 0000000000..257782446c --- /dev/null +++ b/translations/da.po @@ -0,0 +1,1339 @@ +msgid "" +msgstr "" +"POT-Creation-Date: 2023-11-06 17:24+0330\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: @lingui/cli\n" +"Language: da\n" +"Project-Id-Version: rango\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2024-11-27 15:57\n" +"Last-Translator: \n" +"Language-Team: Danish\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Crowdin-Project: rango\n" +"X-Crowdin-Project-ID: 622238\n" +"X-Crowdin-Language: da\n" +"X-Crowdin-File: en.po\n" +"X-Crowdin-File-ID: 30\n" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SameTokensWarning/SameTokensWarning.tsx:21 +msgid "No Routes Found" +msgstr "Ingen ruter fundet" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SameTokensWarning/SameTokensWarning.tsx:25 +msgid "You cannot use the same token for From and To." +msgstr "Du kan ikke bruge det samme token til Fra og Til." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:41 +#: widget/embedded/src/components/TokenList/TokenList.tsx:286 +#: widget/embedded/src/pages/HistoryPage.tsx:186 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:143 +msgid "No results found" +msgstr "Ingen resultater fundet" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:42 +#: widget/embedded/src/components/TokenList/TokenList.tsx:287 +#: widget/embedded/src/pages/HistoryPage.tsx:193 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:144 +msgid "Try using different keywords" +msgstr "Prøv at bruge forskellige søgeord" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:72 +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:46 +#: widget/embedded/src/pages/SelectBlockchainPage.tsx:42 +#: widget/ui/src/containers/SwapInput/TokenSection.tsx:61 +msgid "Select Chain" +msgstr "Vælg Kæde" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:66 +msgid "All" +msgstr "Alle" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:100 +msgid "More +{count}" +msgstr "Mere +{count}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabAlert/ActivateTabAlert.tsx:17 +msgid "Activate this tab" +msgstr "Aktiver denne fane" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabAlert/ActivateTabAlert.tsx:22 +msgid "Another tab is open and handles transactions." +msgstr "En anden fane er åben og håndterer transaktioner." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:20 +msgid "Activate current tab" +msgstr "Aktiver den aktuelle fane" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:22 +msgid "Currently, some transactions are running and being handled by other browser tab. If you activate this tab, all transactions that are already in the transaction sign step will expire." +msgstr "I øjeblikket kører nogle transaktioner og håndteres af en anden browserfane. Hvis du aktiverer denne fane, vil alle transaktioner, der allerede er i transaktionstegntrinnet, udløbe." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:33 +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:349 +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:152 +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:33 +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:116 +msgid "Confirm" +msgstr "Bekræfte" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:365 +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:447 +msgid "Your {blockchainName} wallets" +msgstr "Dine {blockchainName} tegnebøger" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:384 +msgid "Insufficient account balance" +msgstr "Utilstrækkelig kontosaldo" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:394 +msgid "Proceed anyway" +msgstr "Fortsæt alligevel" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:456 +msgid "You need to connect a {blockchainName} wallet." +msgstr "Du skal tilslutte en {blockchainName} tegnebog." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/WalletList.tsx:143 +msgid "Add {chain} chain" +msgstr "Tilføj {chain} kæde" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/WalletList.tsx:244 +msgid "Show more wallets" +msgstr "Vis flere tegnebøger" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:113 +msgid "Send to a different address" +msgstr "Send til en anden adresse" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:129 +msgid "Enter {blockchainName} address" +msgstr "Indtast {blockchainName} adresse" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:147 +msgid "Address {destination} doesn't match the blockchain address pattern." +msgstr "Adressen {destination} matcher ikke blockchain-adressemønsteret." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:59 +msgid "via" +msgstr "via" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:74 +msgid "This token doesn't appear on the active token list(s). Make sure this is the token that you want to trade." +msgstr "Dette token vises ikke på den eller de aktive token-lister. Sørg for, at dette er det token, du vil handle." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:89 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:164 +msgid "Import" +msgstr "Importere" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/FilterSelector/FilterSelectorContent.tsx:26 +msgid "Status" +msgstr "Status" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/FilterSelector/FilterSelectorContent.tsx:33 +#: widget/embedded/src/components/NoResult/NoResult.helpers.ts:37 +#: widget/embedded/src/pages/SettingsPage.tsx:55 +msgid "Reset" +msgstr "Nulstil" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/CancelButton.tsx:18 +msgid "Cancel" +msgstr "Ophæve" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:46 +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:34 +msgid "Refresh" +msgstr "Opfriske" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:63 +#: widget/ui/src/containers/Notifications/Notifications.tsx:35 +msgid "Notifications" +msgstr "Meddelelser" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:79 +#: widget/embedded/src/pages/SettingsPage.tsx:38 +msgid "Settings" +msgstr "Indstillinger" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:93 +#: widget/embedded/src/pages/HistoryPage.tsx:139 +msgid "History" +msgstr "Historie" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/WalletButton.tsx:22 +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:16 +#: widget/embedded/src/constants/messages.ts:5 +msgid "Connect Wallet" +msgstr "Tilslut tegnebog" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HistoryGroupedList/HistoryGroupedList.tsx:118 +#: widget/embedded/src/utils/date.ts:18 +#: widget/embedded/src/utils/time.ts:22 +msgid "Today" +msgstr "I dag" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/LoadingSwapDetails/LoadingSwapDetails.tsx:20 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:424 +msgid "Swaps steps" +msgstr "Bytter trin" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/NoResult/NoResult.helpers.ts:25 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:191 +msgid "Retry" +msgstr "Prøv igen" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:149 +msgid "Slippage Error" +msgstr "Skridningsfejl" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:150 +msgid "Slippage Warning" +msgstr "Advarsel om glidning" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:153 +msgid "Bridge Limit Error" +msgstr "Brogrænsefejl" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:240 +msgid "Yours: {amount} {symbol}" +msgstr "Dine: {amount} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:261 +msgid "Minimum required slippage: {minRequiredSlippage}" +msgstr "Minimum påkrævet glidning: {minRequiredSlippage}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:282 +msgid "Yours: {userSlippage}" +msgstr "Dine: {userSlippage}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:395 +msgid "See All Routes" +msgstr "Se alle ruter" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:81 +msgid "View more info" +msgstr "Se mere info" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:91 +msgid "Gas & Fee Explanation" +msgstr "Gas & gebyrforklaring" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:107 +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:103 +msgid "Details" +msgstr "Detaljer" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:146 +msgid "Total Payable Fee" +msgstr "Samlet betalbar gebyr" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:166 +msgid "Hide non-payable fees" +msgstr "Skjul ikke-betalbare gebyrer" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:167 +msgid "Show non-payable fees" +msgstr "Vis ikke-betalbare gebyrer" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:177 +msgid "Description" +msgstr "Beskrivelse" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:181 +msgid "The following fees are considered in the transaction output and\n" +" you won’t need to pay extra gas for them." +msgstr "Følgende gebyrer tages i betragtning i transaktionens output, og\n" +" behøver du ikke betale ekstra gas for dem." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteSummary.tsx:25 +msgid "Swap input" +msgstr "Skift input" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteSummary.tsx:44 +msgid "Estimated output" +msgstr "Estimeret output" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteTrigger.tsx:65 +msgid "Via:" +msgstr "Via:" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteTrigger.tsx:150 +msgid "Chains:" +msgstr "Kæder:" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/Quotes.tsx:77 +msgid "Sort by" +msgstr "Sorter efter" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:17 +msgid "Smart Routing" +msgstr "Smart Routing" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:21 +msgid "Lowest Fee" +msgstr "Laveste gebyr" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:25 +msgid "Fastest Transfer" +msgstr "Hurtigste overførsel" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:29 +msgid "Maximum Return" +msgstr "Maksimal afkast" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:33 +msgid "Maximum Output" +msgstr "Maksimal output" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:43 +msgid "Swapping" +msgstr "Bytte" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:51 +msgid "Gas cost" +msgstr "Gas omkostninger" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:59 +msgid "Receiving" +msgstr "Modtager" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:67 +msgid "Price impact" +msgstr "Prispåvirkning" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:35 +msgid "You need to increase slippage to at least {minRequiredSlippage} for this route." +msgstr "Du skal øge glidningen til mindst {minRequiredSlippage} for denne rute." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:59 +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:61 +msgid "We recommend you to increase slippage to at least {minRequiredSlippage} for this route." +msgstr "Vi anbefaler, at du øger glidningen til mindst {minRequiredSlippage} for denne rute." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:68 +msgid "Caution, your slippage is high." +msgstr "Forsigtig, din glidning er høj." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.tsx:78 +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.Warning.tsx:26 +msgid "Change" +msgstr "Forandring" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:42 +msgid "Change settings" +msgstr "Skift indstillinger" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:52 +msgid "High slippage" +msgstr "Høj glidning" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:53 +msgid "Low slippage" +msgstr "Lav glidning" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:57 +msgid " Caution, your slippage is high (={userSlippage}). Your trade may be front run." +msgstr " Forsigtig, din glidning er høj (={userSlippage}). Din handel kan være frontløb." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:78 +msgid "Confirm anyway" +msgstr "Bekræft alligevel" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:22 +msgid "Something went wrong" +msgstr "Noget gik galt" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:24 +msgid "Something went wrong. Please refresh the app." +msgstr "Noget gik galt. Opdater venligst appen." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/Slippage.tsx:38 +msgid "Slippage tolerance per swap" +msgstr "Skridtolerance pr. swap" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/Slippage.tsx:91 +msgid "Custom" +msgstr "Skik" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:11 +msgid "Your transaction will be reverted if the price changes unfavorably by more than this percentage." +msgstr "Din transaktion vil blive tilbageført, hvis prisen ændres ugunstigt med mere end denne procentdel." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:16 +#: widget/embedded/src/containers/Settings/Lists.tsx:245 +msgid "Warning" +msgstr "Advarsel" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:17 +msgid "This setting is applied to each step (e.g. 1Inch, Thorchain, etc.), meaning only that specific step will be reverted, not the entire route." +msgstr "Denne indstilling anvendes på hvert trin (f.eks. 1 tomme, Thorchain osv.), hvilket betyder, at kun det specifikke trin vil blive vendt tilbage, ikke hele ruten." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:25 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:269 +msgid "Swap Details" +msgstr "Byt detaljer" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:33 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:312 +msgid "Request ID" +msgstr "Anmod om ID" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:64 +msgid "Not found" +msgstr "Ikke fundet" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:65 +msgid "Swap with request ID = {requestId} not found." +msgstr "Byt med anmodnings-id = {requestId} ikke fundet." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:219 +msgid "You have received {amount} {token} in {conciseAddress} wallet on {chain} chain." +msgstr "Du har modtaget {amount} {token} i {conciseAddress} tegnebog på {chain} kæden." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:242 +msgid "Transaction was not sent." +msgstr "Transaktionen blev ikke sendt." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:244 +msgid "{amount} {symbol} on {blockchain} remains in your wallet." +msgstr "{amount} {symbol} på {blockchain} forbliver i din tegnebog." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:281 +msgid "Delete" +msgstr "Slet" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:304 +msgid "Try again" +msgstr "Prøv igen" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:322 +msgid "Copied To Clipboard" +msgstr "Kopieret til udklipsholder" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:323 +msgid "Copy Request ID" +msgstr "Kopiér anmodnings-id" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:346 +msgid "View on Rango Explorer" +msgstr "Se på Rango Explorer" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:355 +msgid "Finished at" +msgstr "Afsluttet kl" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:355 +msgid "Created at" +msgstr "Oprettet kl" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.tsx:50 +msgid "View transaction" +msgstr "Se transaktion" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.Warning.tsx:49 +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:31 +msgid "Connect" +msgstr "Forbinde" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:43 +msgid "Swap Successful" +msgstr "Swap vellykket" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:71 +msgid "Transaction Failed" +msgstr "Transaktion mislykkedes" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:87 +msgid "Done" +msgstr "Færdig" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:100 +msgid "Diagnosis" +msgstr "Diagnose" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:112 +msgid "See Details" +msgstr "Se detaljer" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:13 +msgid "Cancel Swap" +msgstr "Annuller Swap" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:14 +msgid "Are you sure you want to cancel this swap?" +msgstr "Er du sikker på, at du vil annullere dette bytte?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:23 +msgid "Yes, Cancel it" +msgstr "Ja, annuller det" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:32 +#: widget/embedded/src/pages/CustomTokensPage.tsx:181 +msgid "No, Continue" +msgstr "Nej, fortsæt" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:13 +msgid "Delete Transaction" +msgstr "Slet transaktion" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:14 +msgid "Are you sure you want to delete this swap?" +msgstr "Er du sikker på, at du vil slette denne swap?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:23 +#: widget/embedded/src/pages/CustomTokensPage.tsx:171 +msgid "Yes, Delete it" +msgstr "Ja, slet det" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:33 +#: widget/embedded/src/pages/HistoryPage.tsx:253 +msgid "No, Cancel" +msgstr "Nej, annuller" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:12 +msgid "Change Network" +msgstr "Skift netværk" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:20 +msgid "Network Changed" +msgstr "Netværk ændret" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/TokenList/TokenList.tsx:271 +#: widget/ui/src/containers/SwapInput/TokenSection.tsx:54 +msgid "Select Token" +msgstr "Vælg Token" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:27 +msgid "Wallet Connected" +msgstr "Tegnebog tilsluttet" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:28 +msgid "Your wallet is connected, you can use it to swap." +msgstr "Din tegnebog er tilsluttet, du kan bruge den til at bytte." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:39 +msgid "Failed to Connect" +msgstr "Kunne ikke oprette forbindelse" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:41 +msgid "Your wallet is not connected. Please try again." +msgstr "Din tegnebog er ikke tilsluttet. Prøv venligst igen." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:50 +msgid "Connecting to your wallet" +msgstr "Tilslutning til din tegnebog" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:51 +msgid "Click connect in your wallet popup." +msgstr "Klik på tilslut i din tegnebogs popup." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:99 +msgid "Select Derivation Path" +msgstr "Vælg Afledningssti" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:100 +msgid "In order to connect to {type}, you must first select a Derivation Path" +msgstr "For at oprette forbindelse til {type}skal du først vælge en afledningssti" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:118 +msgid "Choose Derivation Path Template" +msgstr "Vælg Afledningsstiskabelon" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:133 +msgid "Enter Path" +msgstr "Indtast sti" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:134 +msgid "Enter Index" +msgstr "Indtast indeks" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:15 +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:18 +msgid "Add {blockchainDisplayName} Chain" +msgstr "Tilføj {blockchainDisplayName} kæde" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:20 +msgid "Would you like to add the {blockchainDisplayName} experimental chain to your wallet?" +msgstr "Kunne du tænke dig at tilføje {blockchainDisplayName} eksperimentelle kæde til din tegnebog?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:22 +msgid "Please approve the experimental chain pop-up in your wallet." +msgstr "Godkend venligst den eksperimentelle kæde-pop-up i din tegnebog." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:30 +msgid "{blockchainDisplayName} Chain Added" +msgstr "{blockchainDisplayName} Kæde tilføjet" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:34 +msgid "The {blockchainDisplayName} chain has been successfully added to your wallet." +msgstr "{blockchainDisplayName} -kæden er blevet tilføjet til din tegnebog." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:42 +msgid "Request Rejected" +msgstr "Anmodning afvist" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:43 +msgid "You've rejected adding {blockchainDisplayName} chain to your wallet." +msgstr "Du har afvist at tilføje {blockchainDisplayName} -kæden til din tegnebog." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:70 +msgid "Select chain types" +msgstr "Vælg kædetyper" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:71 +msgid "This wallet supports multiple chains. Select which chain you'd like to connect to." +msgstr "Denne pung understøtter flere kæder. Vælg hvilken kæde du vil oprette forbindelse til." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:9 +msgid "Failed Network, Please retry your swap." +msgstr "Mislykket netværk. Prøv venligst at bytte igen." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:11 +msgid "Please reset your liquidity sources." +msgstr "Nulstil venligst dine likviditetskilder." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:12 +msgid "You have limited the liquidity sources and this might result in Rango finding no routes. Please consider resetting your liquidity sources." +msgstr "Du har begrænset likviditetskilderne, og det kan resultere i, at Rango ikke finder nogen ruter. Overvej venligst at nulstille dine likviditetskilder." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:17 +msgid "No Routes Found." +msgstr "Ingen ruter fundet." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:18 +msgid "Reasons why Rango couldn't find a route: low liquidity on token, very low input amount or no routes available for the selected input/output token combination." +msgstr "Årsager til, at Rango ikke kunne finde en rute: lav likviditet på token, meget lavt inputbeløb eller ingen tilgængelige ruter for den valgte input/output token-kombination." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:23 +msgid "Bridge Limit Error: Please increase your amount." +msgstr "Bridge Limit Error: Forøg venligst dit beløb." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:26 +msgid "Bridge Limit Error: Please decrease your amount." +msgstr "Bridge Limit Error: Reducer venligst dit beløb." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:31 +msgid "High Price Impact" +msgstr "Høj prispåvirkning" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:32 +msgid "Price impact is too high!" +msgstr "Prispåvirkningen er for høj!" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:33 +msgid "The price impact is significantly higher than the allowed amount." +msgstr "Prispåvirkningen er væsentligt højere end det tilladte beløb." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:36 +msgid "Confirm high price impact" +msgstr "Bekræft høj prispåvirkning" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:39 +msgid "Route updated and price impact is too high, try again later!" +msgstr "Ruten er opdateret, og prispåvirkningen er for høj. Prøv igen senere!" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:44 +msgid "USD Price Unknown" +msgstr "USD Pris ukendt" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:45 +msgid "USD Price Unknown, Cannot calculate Price Impact." +msgstr "USD-pris ukendt, kan ikke beregne prispåvirkning." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:46 +msgid "USD Price Unknown, Cannot calculate Price Impact. The price impact may be higher than usual. Are you sure to continue the Swap?" +msgstr "USD-pris ukendt, kan ikke beregne prispåvirkning. Prispåvirkningen kan være højere end normalt. Er du sikker på at du vil fortsætte byttet?" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:49 +msgid "Confirm USD Price Unknown" +msgstr "Bekræft USD-pris ukendt" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:6 +#: widget/embedded/src/pages/Home.tsx:163 +msgid "Swap" +msgstr "Byt" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:7 +msgid "Swap anyway" +msgstr "Byt alligevel" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:8 +msgid "The route goes through Ethereum. Continue?" +msgstr "Ruten går gennem Ethereum. Fortsætte?" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:10 +msgid "Route has been updated." +msgstr "Ruten er blevet opdateret." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:12 +msgid "Output amount changed to {newOutputAmount} ({percentageChange}% change)." +msgstr "Outputmængde ændret til {newOutputAmount} ({percentageChange}% ændring)." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:20 +msgid "Route swappers has been updated." +msgstr "Rutebyttere er blevet opdateret." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:22 +msgid "Route internal coins has been updated." +msgstr "Rutens interne mønter er blevet opdateret." + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/ExpandedQuotes/ExpandedQuotes.tsx:53 +#: widget/embedded/src/pages/Routes.tsx:48 +msgid "Routes" +msgstr "Ruter" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Inputs/Inputs.tsx:76 +msgid "From" +msgstr "Fra" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Inputs/Inputs.tsx:118 +msgid "To" +msgstr "Til" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:49 +msgid "Light" +msgstr "Lys" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:58 +msgid "Dark" +msgstr "Mørk" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:67 +msgid "Auto" +msgstr "Auto" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:140 +msgid "Loading failed" +msgstr "Indlæsning mislykkedes" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:156 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:41 +msgid "Bridges" +msgstr "Broer" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:174 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:41 +msgid "Exchanges" +msgstr "Udvekslinger" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:195 +#: widget/embedded/src/pages/CustomTokensPage.tsx:90 +msgid "Custom Tokens" +msgstr "Brugerdefinerede tokens" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:214 +#: widget/embedded/src/pages/LanguagePage.tsx:43 +msgid "Language" +msgstr "Sprog" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:235 +msgid "Infinite approval" +msgstr "Uendelig godkendelse" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:246 +msgid "Enabling the 'Infinite approval' mode grants unrestricted access to underlying smart contracts, allowing them to utilize the approved token amount without limitations." +msgstr "Aktivering af tilstanden 'Uendelig godkendelse' giver ubegrænset adgang til underliggende smarte kontrakter, hvilket giver dem mulighed for at bruge det godkendte tokenbeløb uden begrænsninger." + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:266 +msgid "Theme" +msgstr "Tema" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:39 +msgid "Duplicate Token" +msgstr "Dublet token" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:40 +msgid "The address you entered is duplicate, please enter a new address." +msgstr "Den adresse du indtastede er dublet, indtast venligst en ny adresse." + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:46 +msgid "Token Already Exists" +msgstr "Token findes allerede" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:47 +msgid "There's no need to add this token again because it already exists and is supported by us." +msgstr "Der er ingen grund til at tilføje dette token igen, fordi det allerede eksisterer og understøttes af os." + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:53 +msgid "Token Not Found" +msgstr "Token ikke fundet" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:54 +msgid "Sorry, no token was found on {blockchain} chain with the provided address. please make sure you have entered the right token address." +msgstr "Beklager, der blev ikke fundet noget token på {blockchain} -kæden med den angivne adresse. Sørg for, at du har indtastet den rigtige token-adresse." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:78 +msgid "Network Error" +msgstr "Netværksfejl" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:109 +#: widget/embedded/src/pages/CustomTokensPage.tsx:149 +msgid "Add Custom Token" +msgstr "Tilføj tilpasset token" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:127 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:128 +msgid "Select chain" +msgstr "Vælg kæde" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:132 +msgid "Enter Address" +msgstr "Indtast adresse" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:139 +msgid "Enter token address" +msgstr "Indtast token-adresse" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:176 +msgid "Failed Network, Please retry." +msgstr "Mislykket netværk. Prøv venligst igen." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:192 +msgid "Add another custom token" +msgstr "Tilføj endnu et brugerdefineret token" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:236 +msgid "Confirm Swap" +msgstr "Bekræft Swap" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:254 +msgid "Start Swap" +msgstr "Start Swap" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:282 +msgid "You get" +msgstr "Du får" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:102 +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:90 +msgid "Search Token" +msgstr "Søg token" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:134 +msgid "No custom tokens" +msgstr "Ingen brugerdefinerede tokens" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:135 +msgid "press the button to add your custom token" +msgstr "tryk på knappen for at tilføje dit brugerdefinerede token" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:158 +msgid "Delete Custom Token" +msgstr "Slet brugerdefineret token" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:160 +msgid "Are you sure you want to Delete this Token?" +msgstr "Er du sikker på, at du vil slette dette token?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:59 +msgid "Complete" +msgstr "Komplet" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:63 +msgid "Running" +msgstr "Løb" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:65 +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:8 +msgid "Failed" +msgstr "Mislykkedes" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:149 +msgid "Clear" +msgstr "Klar" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:161 +msgid "Search Transaction" +msgstr "Søg transaktion" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:187 +msgid "No transactions" +msgstr "Ingen transaktioner" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:194 +msgid "Your transaction history is stored locally and will appear here after you start a swap" +msgstr "Din transaktionshistorik gemmes lokalt og vises her, når du har startet en swap" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:218 +msgid "Clear Transaction History" +msgstr "Ryd transaktionshistorik" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:222 +msgid "Proceeding will remove all successful and failed transactions from the widget. Do you want to continue?" +msgstr "Hvis du fortsætter, fjernes alle vellykkede og mislykkede transaktioner fra widgetten. Vil du fortsætte?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:229 +msgid "Note: This does not erase your transaction history on the chain; it only removes them here." +msgstr "Bemærk: Dette sletter ikke din transaktionshistorik på kæden; det fjerner dem kun her." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:243 +msgid "Yes, Clear the history" +msgstr "Ja, Ryd historikken" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LanguagePage.tsx:56 +msgid "language" +msgstr "sprog" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:121 +msgid "Deselect all" +msgstr "Fravælg alle" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:121 +msgid "Select all" +msgstr "Vælg alle" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:133 +msgid "Search {sourceType}" +msgstr "Søg {sourceType}" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectBlockchainPage.tsx:60 +msgid "Search Chain" +msgstr "Søgekæde" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:67 +msgid "Source" +msgstr "Kilde" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:68 +msgid "Destination" +msgstr "Bestemmelsessted" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:74 +msgid "Swap {type}" +msgstr "Byt {type}" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SettingsPage.tsx:45 +msgid "Currently, you're in campaign mode with restrictions on liquidity sources. Would you like to switch out of this mode and make use of all available liquidity sources?" +msgstr "I øjeblikket er du i kampagnetilstand med begrænsninger på likviditetskilder. Vil du skifte ud af denne tilstand og gøre brug af alle tilgængelige likviditetskilder?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SwapDetailsPage.tsx:27 +msgid "The request ID is necessary to display the swap details." +msgstr "Anmodnings-id'et er nødvendigt for at vise bytteoplysningerne." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/WalletsPage.tsx:67 +#: widget/ui/src/containers/ConnectWalletsModal/ConnectWalletsModal.tsx:15 +msgid "Connect Wallets" +msgstr "Tilslut tegnebøger" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/WalletsPage.tsx:82 +msgid "Choose a wallet to connect." +msgstr "Vælg en tegnebog at forbinde." + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:25 +msgid "This week" +msgstr "Denne uge" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:32 +msgid "This month" +msgstr "Denne måned" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:39 +msgid "This year" +msgstr "I år" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:129 +msgid "Required: >= {min} {symbol}" +msgstr "Påkrævet: >= {min} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:142 +msgid "Required: > {min} {symbol}" +msgstr "Påkrævet: > {min} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:157 +msgid "Required: <= {max} {symbol}" +msgstr "Påkrævet: <= {max} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:170 +msgid "Required: < {max} {symbol}" +msgstr "Påkrævet: < {max} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:601 +msgid " for network fee" +msgstr " mod netværksafgift" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:604 +msgid " for swap" +msgstr " til bytte" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:607 +msgid " for input and network fee" +msgstr " for input og netværksgebyr" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:609 +msgid "Needs ≈ {requiredAmount} {symbol}{reason}, but you have {currentAmount} {symbol} in your {blockchain} wallet." +msgstr "Har brug for ≈ {requiredAmount} {symbol}{reason}, men du har {currentAmount} {symbol} i din {blockchain} tegnebog." + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:669 +msgid "Waiting for connecting wallet" +msgstr "Venter på tilslutning af tegnebog" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:673 +msgid "Waiting for other running tasks to be finished" +msgstr "Venter på, at andre kørende opgaver er færdige" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:676 +msgid "Waiting for changing wallet network" +msgstr "Venter på at skifte tegnebogsnetværk" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:6 +msgid "Sunday" +msgstr "søndag" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:7 +msgid "Monday" +msgstr "mandag" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:8 +msgid "Tuesday" +msgstr "tirsdag" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:9 +msgid "Wednesday" +msgstr "onsdag" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:10 +msgid "Thursday" +msgstr "torsdag" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:11 +msgid "Friday" +msgstr "fredag" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:12 +msgid "Saturday" +msgstr "lørdag" + +#. js-lingui-explicit-id +#: widget/ui/src/components/BottomLogo/BottomLogo.tsx:14 +msgid "Powered By" +msgstr "Drevet af" + +#. js-lingui-explicit-id +#: widget/ui/src/components/FullExpandedQuote/FullExpandedQuote.Tooltip.tsx:37 +msgid "Aggregated Transaction" +msgstr "Aggregeret transaktion" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SelectableCategoryList/SelectableCategoryList.tsx:63 +msgid "{blockchainCategory}" +msgstr "{blockchainCategory}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/StepDetails/StepDetails.tsx:75 +#: widget/ui/src/components/StepDetails/StepDetails.tsx:102 +msgid "Swap on {fromChain} via {swapper}" +msgstr "Byt på {fromChain} via {swapper}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/StepDetails/StepDetails.tsx:109 +msgid "Bridge to {toChain} via {swapper}" +msgstr "Bro til {toChain} via {swapper}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:10 +msgid "Completed" +msgstr "Færdiggjort" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:12 +msgid "In progress" +msgstr "I gang" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapToken.tsx:122 +msgid "Waiting for bridge transaction" +msgstr "Venter på brotransaktion" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:12 +msgid "Connected" +msgstr "Forbundet" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:13 +msgid "Disconnect" +msgstr "Afbryde" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:18 +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:19 +msgid "Install" +msgstr "Installere" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:24 +msgid "Connecting ..." +msgstr "Opretter forbindelse..." + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:25 +msgid "Connecting" +msgstr "Forbinder" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:30 +msgid "Disconnected" +msgstr "Afbrudt" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:34 +msgid "you need to pass a correct state to Wallet." +msgstr "du skal sende en korrekt tilstand til Wallet." + +#. js-lingui-explicit-id +#: widget/ui/src/containers/Notifications/NotificationNotFound.tsx:15 +msgid "There are no notifications." +msgstr "Der er ingen meddelelser." + +#. js-lingui-explicit-id +#: widget/ui/src/containers/Notifications/Notifications.tsx:39 +msgid "Clear all" +msgstr "Ryd alle" + +#. js-lingui-explicit-id +#: widget/ui/src/containers/SwapInput/SwapInput.tsx:65 +msgid "Balance" +msgstr "Balance" + +#. js-lingui-explicit-id +#: widget/ui/src/containers/SwapInput/SwapInput.tsx:73 +msgid "Max" +msgstr "Maks" + diff --git a/translations/de.po b/translations/de.po new file mode 100644 index 0000000000..876fe32458 --- /dev/null +++ b/translations/de.po @@ -0,0 +1,1339 @@ +msgid "" +msgstr "" +"POT-Creation-Date: 2023-11-06 17:24+0330\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: @lingui/cli\n" +"Language: de\n" +"Project-Id-Version: rango\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2024-11-27 15:57\n" +"Last-Translator: \n" +"Language-Team: German\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Crowdin-Project: rango\n" +"X-Crowdin-Project-ID: 622238\n" +"X-Crowdin-Language: de\n" +"X-Crowdin-File: en.po\n" +"X-Crowdin-File-ID: 30\n" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SameTokensWarning/SameTokensWarning.tsx:21 +msgid "No Routes Found" +msgstr "Keine Routen gefunden" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SameTokensWarning/SameTokensWarning.tsx:25 +msgid "You cannot use the same token for From and To." +msgstr "Sie können für „Von“ und „An“ nicht dasselbe Token verwenden." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:41 +#: widget/embedded/src/components/TokenList/TokenList.tsx:286 +#: widget/embedded/src/pages/HistoryPage.tsx:186 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:143 +msgid "No results found" +msgstr "Keine Ergebnisse gefunden" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:42 +#: widget/embedded/src/components/TokenList/TokenList.tsx:287 +#: widget/embedded/src/pages/HistoryPage.tsx:193 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:144 +msgid "Try using different keywords" +msgstr "Versuchen Sie, andere Stichwörter zu verwenden" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:72 +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:46 +#: widget/embedded/src/pages/SelectBlockchainPage.tsx:42 +#: widget/ui/src/containers/SwapInput/TokenSection.tsx:61 +msgid "Select Chain" +msgstr "Kette auswählen" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:66 +msgid "All" +msgstr "Alle" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:100 +msgid "More +{count}" +msgstr "Mehr +{count}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabAlert/ActivateTabAlert.tsx:17 +msgid "Activate this tab" +msgstr "Diesen Tab aktivieren" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabAlert/ActivateTabAlert.tsx:22 +msgid "Another tab is open and handles transactions." +msgstr "Ein weiterer Tab ist geöffnet und bearbeitet Transaktionen." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:20 +msgid "Activate current tab" +msgstr "Aktuellen Tab aktivieren" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:22 +msgid "Currently, some transactions are running and being handled by other browser tab. If you activate this tab, all transactions that are already in the transaction sign step will expire." +msgstr "Derzeit laufen einige Transaktionen und werden von einem anderen Browser-Tab abgewickelt. Wenn Sie diesen Tab aktivieren, werden alle Transaktionen, die sich bereits im Schritt zum Transaktionszeichen befinden, ablaufen." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:33 +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:349 +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:152 +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:33 +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:116 +msgid "Confirm" +msgstr "Bestätigen" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:365 +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:447 +msgid "Your {blockchainName} wallets" +msgstr "Ihre {blockchainName} Wallets" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:384 +msgid "Insufficient account balance" +msgstr "Unzureichender Kontostand" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:394 +msgid "Proceed anyway" +msgstr "Trotzdem fortfahren" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:456 +msgid "You need to connect a {blockchainName} wallet." +msgstr "Sie müssen eine {blockchainName} Wallet verbinden." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/WalletList.tsx:143 +msgid "Add {chain} chain" +msgstr "{chain} Kette hinzufügen" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/WalletList.tsx:244 +msgid "Show more wallets" +msgstr "Mehr Brieftaschen anzeigen" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:113 +msgid "Send to a different address" +msgstr "An eine andere Adresse senden" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:129 +msgid "Enter {blockchainName} address" +msgstr "{blockchainName} Adresse eingeben" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:147 +msgid "Address {destination} doesn't match the blockchain address pattern." +msgstr "Adresse {destination} stimmt nicht mit dem Blockchain-Adressmuster überein." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:59 +msgid "via" +msgstr "über" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:74 +msgid "This token doesn't appear on the active token list(s). Make sure this is the token that you want to trade." +msgstr "Dieses Token erscheint nicht in der aktiven Tokenliste(n). Stellen Sie sicher, dass dies das Token ist, das Sie handeln möchten." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:89 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:164 +msgid "Import" +msgstr "Importieren" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/FilterSelector/FilterSelectorContent.tsx:26 +msgid "Status" +msgstr "Status" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/FilterSelector/FilterSelectorContent.tsx:33 +#: widget/embedded/src/components/NoResult/NoResult.helpers.ts:37 +#: widget/embedded/src/pages/SettingsPage.tsx:55 +msgid "Reset" +msgstr "Reset" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/CancelButton.tsx:18 +msgid "Cancel" +msgstr "Abbrechen" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:46 +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:34 +msgid "Refresh" +msgstr "Aktualisieren" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:63 +#: widget/ui/src/containers/Notifications/Notifications.tsx:35 +msgid "Notifications" +msgstr "Benachrichtigungen" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:79 +#: widget/embedded/src/pages/SettingsPage.tsx:38 +msgid "Settings" +msgstr "Einstellungen" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:93 +#: widget/embedded/src/pages/HistoryPage.tsx:139 +msgid "History" +msgstr "Verlauf" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/WalletButton.tsx:22 +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:16 +#: widget/embedded/src/constants/messages.ts:5 +msgid "Connect Wallet" +msgstr "Wallet verbinden" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HistoryGroupedList/HistoryGroupedList.tsx:118 +#: widget/embedded/src/utils/date.ts:18 +#: widget/embedded/src/utils/time.ts:22 +msgid "Today" +msgstr "Heute" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/LoadingSwapDetails/LoadingSwapDetails.tsx:20 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:424 +msgid "Swaps steps" +msgstr "Swaps Schritte" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/NoResult/NoResult.helpers.ts:25 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:191 +msgid "Retry" +msgstr "Wiederholen" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:149 +msgid "Slippage Error" +msgstr "Slippage Fehler" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:150 +msgid "Slippage Warning" +msgstr "Slippage Warnung" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:153 +msgid "Bridge Limit Error" +msgstr "Brückenbegrenzungsfehler" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:240 +msgid "Yours: {amount} {symbol}" +msgstr "Ihre: {amount} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:261 +msgid "Minimum required slippage: {minRequiredSlippage}" +msgstr "Minimal benötigte Slippage: {minRequiredSlippage}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:282 +msgid "Yours: {userSlippage}" +msgstr "Ihre: {userSlippage}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:395 +msgid "See All Routes" +msgstr "Alle Routen anzeigen" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:81 +msgid "View more info" +msgstr "Mehr Infos anzeigen" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:91 +msgid "Gas & Fee Explanation" +msgstr "Gas- & Gebührenerklärung" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:107 +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:103 +msgid "Details" +msgstr "Details" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:146 +msgid "Total Payable Fee" +msgstr "Gesamtgebühr" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:166 +msgid "Hide non-payable fees" +msgstr "Nicht zu zahlende Gebühren ausblenden" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:167 +msgid "Show non-payable fees" +msgstr "Nicht zahlbare Gebühren anzeigen" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:177 +msgid "Description" +msgstr "Beschreibung" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:181 +msgid "The following fees are considered in the transaction output and\n" +" you won’t need to pay extra gas for them." +msgstr "Die folgenden Gebühren werden in der Transaktionsleistung berücksichtigt und\n" +" Sie brauchen kein zusätzliches Gas dafür zu bezahlen." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteSummary.tsx:25 +msgid "Swap input" +msgstr "Swap input" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteSummary.tsx:44 +msgid "Estimated output" +msgstr "Geschätzte Ausgabe" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteTrigger.tsx:65 +msgid "Via:" +msgstr "Via:" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteTrigger.tsx:150 +msgid "Chains:" +msgstr "Ketten:" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/Quotes.tsx:77 +msgid "Sort by" +msgstr "Sortieren nach" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:17 +msgid "Smart Routing" +msgstr "Intelligente Routing" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:21 +msgid "Lowest Fee" +msgstr "Niedrigste Gebühr" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:25 +msgid "Fastest Transfer" +msgstr "Schnellste Übertragung" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:29 +msgid "Maximum Return" +msgstr "Maximale Retoure" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:33 +msgid "Maximum Output" +msgstr "Maximale Ausgabe" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:43 +msgid "Swapping" +msgstr "Swapping" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:51 +msgid "Gas cost" +msgstr "Gaskosten" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:59 +msgid "Receiving" +msgstr "Empfangen" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:67 +msgid "Price impact" +msgstr "Preisauswirkung" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:35 +msgid "You need to increase slippage to at least {minRequiredSlippage} for this route." +msgstr "Sie müssen den Slippage für diese Route auf mindestens {minRequiredSlippage} erhöhen." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:59 +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:61 +msgid "We recommend you to increase slippage to at least {minRequiredSlippage} for this route." +msgstr "Wir empfehlen Ihnen, den Slippage auf mindestens {minRequiredSlippage} für diese Route zu erhöhen." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:68 +msgid "Caution, your slippage is high." +msgstr "Vorsicht, Ihre Slippage ist hoch." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.tsx:78 +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.Warning.tsx:26 +msgid "Change" +msgstr "Ändern" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:42 +msgid "Change settings" +msgstr "Einstellungen ändern" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:52 +msgid "High slippage" +msgstr "Hoher Slippage" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:53 +msgid "Low slippage" +msgstr "Niedrige Slippage" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:57 +msgid " Caution, your slippage is high (={userSlippage}). Your trade may be front run." +msgstr " Achtung, Ihr Slippage ist hoch (={userSlippage}). Ihr Handel könnte vorderhand laufen." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:78 +msgid "Confirm anyway" +msgstr "Trotzdem bestätigen" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:22 +msgid "Something went wrong" +msgstr "Etwas ist schief gelaufen" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:24 +msgid "Something went wrong. Please refresh the app." +msgstr "Etwas ist schief gelaufen. Bitte aktualisieren Sie die App." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/Slippage.tsx:38 +msgid "Slippage tolerance per swap" +msgstr "Slippage Toleranz pro Tausch" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/Slippage.tsx:91 +msgid "Custom" +msgstr "Eigene" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:11 +msgid "Your transaction will be reverted if the price changes unfavorably by more than this percentage." +msgstr "Ihre Transaktion wird rückgängig gemacht, wenn sich der Preis ungünstig um mehr als diesen Prozentsatz ändert." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:16 +#: widget/embedded/src/containers/Settings/Lists.tsx:245 +msgid "Warning" +msgstr "Warnung" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:17 +msgid "This setting is applied to each step (e.g. 1Inch, Thorchain, etc.), meaning only that specific step will be reverted, not the entire route." +msgstr "Diese Einstellung wird auf jeden Schritt angewendet (z.B. 1Inch, Thorchain, etc.), was bedeutet, dass nur ein bestimmter Schritt rückgängig gemacht wird, nicht die gesamte Route." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:25 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:269 +msgid "Swap Details" +msgstr "Swap-Details" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:33 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:312 +msgid "Request ID" +msgstr "Anfrage-ID" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:64 +msgid "Not found" +msgstr "Nicht gefunden" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:65 +msgid "Swap with request ID = {requestId} not found." +msgstr "Swap mit Request ID = {requestId} nicht gefunden." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:219 +msgid "You have received {amount} {token} in {conciseAddress} wallet on {chain} chain." +msgstr "Sie haben {amount} {token} in {conciseAddress} Wallet auf {chain} Kette erhalten." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:242 +msgid "Transaction was not sent." +msgstr "Transaktion wurde nicht versendet." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:244 +msgid "{amount} {symbol} on {blockchain} remains in your wallet." +msgstr "{amount} {symbol} auf {blockchain} verbleibt in Ihrer Brieftasche." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:281 +msgid "Delete" +msgstr "Löschen" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:304 +msgid "Try again" +msgstr "Erneut versuchen" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:322 +msgid "Copied To Clipboard" +msgstr "In Zwischenablage kopiert" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:323 +msgid "Copy Request ID" +msgstr "Anfrage-ID kopieren" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:346 +msgid "View on Rango Explorer" +msgstr "Auf Rango Explorer anzeigen" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:355 +msgid "Finished at" +msgstr "Beendet am" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:355 +msgid "Created at" +msgstr "Erstellt am" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.tsx:50 +msgid "View transaction" +msgstr "Transaktion anzeigen" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.Warning.tsx:49 +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:31 +msgid "Connect" +msgstr "Verbinden" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:43 +msgid "Swap Successful" +msgstr "Tausch erfolgreich" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:71 +msgid "Transaction Failed" +msgstr "Transaktion fehlgeschlagen" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:87 +msgid "Done" +msgstr "Fertig" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:100 +msgid "Diagnosis" +msgstr "Diagnose" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:112 +msgid "See Details" +msgstr "Details ansehen" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:13 +msgid "Cancel Swap" +msgstr "Tausch abbrechen" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:14 +msgid "Are you sure you want to cancel this swap?" +msgstr "Sind Sie sicher, dass Sie diesen Swap abbrechen möchten?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:23 +msgid "Yes, Cancel it" +msgstr "Ja, abbrechen" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:32 +#: widget/embedded/src/pages/CustomTokensPage.tsx:181 +msgid "No, Continue" +msgstr "Nein, Fortfahren" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:13 +msgid "Delete Transaction" +msgstr "Transaktion löschen" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:14 +msgid "Are you sure you want to delete this swap?" +msgstr "Sind Sie sicher, dass Sie diesen Swap löschen möchten?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:23 +#: widget/embedded/src/pages/CustomTokensPage.tsx:171 +msgid "Yes, Delete it" +msgstr "Ja, löschen" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:33 +#: widget/embedded/src/pages/HistoryPage.tsx:253 +msgid "No, Cancel" +msgstr "Nein, abbrechen" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:12 +msgid "Change Network" +msgstr "Netzwerk ändern" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:20 +msgid "Network Changed" +msgstr "Netzwerk geändert" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/TokenList/TokenList.tsx:271 +#: widget/ui/src/containers/SwapInput/TokenSection.tsx:54 +msgid "Select Token" +msgstr "Token auswählen" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:27 +msgid "Wallet Connected" +msgstr "Wallet verbunden" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:28 +msgid "Your wallet is connected, you can use it to swap." +msgstr "Ihre Brieftasche ist verbunden, Sie können sie zum Tausch verwenden." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:39 +msgid "Failed to Connect" +msgstr "Verbindung fehlgeschlagen" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:41 +msgid "Your wallet is not connected. Please try again." +msgstr "Ihre Brieftasche ist nicht verbunden. Bitte versuchen Sie es erneut." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:50 +msgid "Connecting to your wallet" +msgstr "Verbinde mit Ihrer Brieftasche" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:51 +msgid "Click connect in your wallet popup." +msgstr "Klicken Sie in Ihrem Wallet-Popup auf Verbinden." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:99 +msgid "Select Derivation Path" +msgstr "Ableitungspfad auswählen" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:100 +msgid "In order to connect to {type}, you must first select a Derivation Path" +msgstr "Um eine Verbindung zu {type}herzustellen, müssen Sie zuerst einen Derivationspfad auswählen" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:118 +msgid "Choose Derivation Path Template" +msgstr "Wählen Sie Derivationspfad Vorlage" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:133 +msgid "Enter Path" +msgstr "Pfad eingeben" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:134 +msgid "Enter Index" +msgstr "Index eingeben" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:15 +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:18 +msgid "Add {blockchainDisplayName} Chain" +msgstr "{blockchainDisplayName} Kette hinzufügen" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:20 +msgid "Would you like to add the {blockchainDisplayName} experimental chain to your wallet?" +msgstr "Möchten Sie die experimentelle Kette {blockchainDisplayName} zu Ihrer Wallet hinzufügen?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:22 +msgid "Please approve the experimental chain pop-up in your wallet." +msgstr "Bitte genehmigen Sie das experimentelle Kettenpopup in Ihrer Brieftasche." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:30 +msgid "{blockchainDisplayName} Chain Added" +msgstr "{blockchainDisplayName} Kette hinzugefügt" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:34 +msgid "The {blockchainDisplayName} chain has been successfully added to your wallet." +msgstr "Die {blockchainDisplayName} Kette wurde erfolgreich zur Brieftasche hinzugefügt." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:42 +msgid "Request Rejected" +msgstr "Anfrage abgelehnt" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:43 +msgid "You've rejected adding {blockchainDisplayName} chain to your wallet." +msgstr "Sie haben das Hinzufügen von {blockchainDisplayName} Kette zu Ihrer Brieftasche abgelehnt." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:70 +msgid "Select chain types" +msgstr "Kettentypen auswählen" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:71 +msgid "This wallet supports multiple chains. Select which chain you'd like to connect to." +msgstr "Diese Brieftasche unterstützt mehrere Ketten. Wählen Sie aus, zu welcher Kette Sie sich verbinden möchten." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:9 +msgid "Failed Network, Please retry your swap." +msgstr "Netzwerk fehlgeschlagen, bitte versuche deinen Swap." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:11 +msgid "Please reset your liquidity sources." +msgstr "Bitte setzen Sie Ihre Liquiditätsquellen zurück." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:12 +msgid "You have limited the liquidity sources and this might result in Rango finding no routes. Please consider resetting your liquidity sources." +msgstr "Sie haben die Liquiditätsquellen begrenzt und dies könnte dazu führen, dass Rango keine Routen findet. Bitte überlegen Sie Ihre Liquiditätsquellen zurückzusetzen." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:17 +msgid "No Routes Found." +msgstr "Keine Routen gefunden." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:18 +msgid "Reasons why Rango couldn't find a route: low liquidity on token, very low input amount or no routes available for the selected input/output token combination." +msgstr "Gründe warum Rango keine Route finden konnte: geringe Liquidität beim Token, sehr geringe Eingabeaufforderung oder keine Routen für die gewählte Kombination aus Ein-/Ausgabe-Token." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:23 +msgid "Bridge Limit Error: Please increase your amount." +msgstr "Bridge-Limit-Fehler: Bitte erhöhen Sie Ihren Betrag." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:26 +msgid "Bridge Limit Error: Please decrease your amount." +msgstr "Brückenbegrenzung Fehler: Bitte verringern Sie Ihren Betrag." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:31 +msgid "High Price Impact" +msgstr "Hohe Preisbelastung" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:32 +msgid "Price impact is too high!" +msgstr "Preisauswirkungen sind zu hoch!" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:33 +msgid "The price impact is significantly higher than the allowed amount." +msgstr "Die Preisauswirkungen sind deutlich höher als der zulässige Betrag." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:36 +msgid "Confirm high price impact" +msgstr "Bestätigen Sie den hohen Preisausstoß" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:39 +msgid "Route updated and price impact is too high, try again later!" +msgstr "Route aktualisiert und Preis Auswirkungen ist zu hoch, versuchen Sie es später noch einmal!" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:44 +msgid "USD Price Unknown" +msgstr "USD Preis unbekannt" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:45 +msgid "USD Price Unknown, Cannot calculate Price Impact." +msgstr "USD-Preis unbekannt, Preisauswirkungen können nicht berechnet werden." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:46 +msgid "USD Price Unknown, Cannot calculate Price Impact. The price impact may be higher than usual. Are you sure to continue the Swap?" +msgstr "USD-Preis unbekannt, Preisauswirkungen können nicht berechnet werden. Der Preisausstoß kann höher sein als üblich. Möchten Sie den Swap wirklich fortsetzen?" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:49 +msgid "Confirm USD Price Unknown" +msgstr "USD-Preis unbekannt bestätigen" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:6 +#: widget/embedded/src/pages/Home.tsx:163 +msgid "Swap" +msgstr "Tausch" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:7 +msgid "Swap anyway" +msgstr "Trotzdem tauschen" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:8 +msgid "The route goes through Ethereum. Continue?" +msgstr "Die Route geht durch Ethereum. Weiter?" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:10 +msgid "Route has been updated." +msgstr "Route wurde aktualisiert." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:12 +msgid "Output amount changed to {newOutputAmount} ({percentageChange}% change)." +msgstr "Ausgabebetrag wurde auf {newOutputAmount} geändert ({percentageChange}% Änderung)." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:20 +msgid "Route swappers has been updated." +msgstr "Route Swappers wurde aktualisiert." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:22 +msgid "Route internal coins has been updated." +msgstr "Interne Routenmünzen wurden aktualisiert." + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/ExpandedQuotes/ExpandedQuotes.tsx:53 +#: widget/embedded/src/pages/Routes.tsx:48 +msgid "Routes" +msgstr "Routen" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Inputs/Inputs.tsx:76 +msgid "From" +msgstr "Von" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Inputs/Inputs.tsx:118 +msgid "To" +msgstr "An" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:49 +msgid "Light" +msgstr "Hell" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:58 +msgid "Dark" +msgstr "Dunkel" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:67 +msgid "Auto" +msgstr "Auto" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:140 +msgid "Loading failed" +msgstr "Laden fehlgeschlagen" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:156 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:41 +msgid "Bridges" +msgstr "Brücken" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:174 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:41 +msgid "Exchanges" +msgstr "Austausche" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:195 +#: widget/embedded/src/pages/CustomTokensPage.tsx:90 +msgid "Custom Tokens" +msgstr "Eigene Token" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:214 +#: widget/embedded/src/pages/LanguagePage.tsx:43 +msgid "Language" +msgstr "Sprache" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:235 +msgid "Infinite approval" +msgstr "Unendliche Genehmigung" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:246 +msgid "Enabling the 'Infinite approval' mode grants unrestricted access to underlying smart contracts, allowing them to utilize the approved token amount without limitations." +msgstr "Das Aktivieren des \"Infinite Advisval\"-Modus gewährt uneingeschränkten Zugriff auf zugrunde liegende Smart-Verträge, was es ihnen erlaubt, den genehmigten Tokenbetrag uneingeschränkt zu nutzen." + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:266 +msgid "Theme" +msgstr "Thema" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:39 +msgid "Duplicate Token" +msgstr "Duplicate Token" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:40 +msgid "The address you entered is duplicate, please enter a new address." +msgstr "Die eingegebene Adresse ist doppelt, bitte geben Sie eine neue Adresse ein." + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:46 +msgid "Token Already Exists" +msgstr "Token existiert bereits" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:47 +msgid "There's no need to add this token again because it already exists and is supported by us." +msgstr "Es ist nicht nötig, dieses Token erneut hinzuzufügen, da es bereits existiert und von uns unterstützt wird." + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:53 +msgid "Token Not Found" +msgstr "Token nicht gefunden" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:54 +msgid "Sorry, no token was found on {blockchain} chain with the provided address. please make sure you have entered the right token address." +msgstr "Leider wurde kein Token in der {blockchain} Kette mit der angegebenen Adresse gefunden. Bitte stellen Sie sicher, dass Sie die richtige Token-Adresse eingegeben haben." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:78 +msgid "Network Error" +msgstr "Netzwerkfehler" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:109 +#: widget/embedded/src/pages/CustomTokensPage.tsx:149 +msgid "Add Custom Token" +msgstr "Token hinzufügen" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:127 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:128 +msgid "Select chain" +msgstr "Kette auswählen" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:132 +msgid "Enter Address" +msgstr "Adresse eingeben" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:139 +msgid "Enter token address" +msgstr "Token Adresse eingeben" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:176 +msgid "Failed Network, Please retry." +msgstr "Fehlgeschlagenes Netzwerk, bitte erneut versuchen." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:192 +msgid "Add another custom token" +msgstr "Neues benutzerdefiniertes Token hinzufügen" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:236 +msgid "Confirm Swap" +msgstr "Swap bestätigen" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:254 +msgid "Start Swap" +msgstr "Swap starten" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:282 +msgid "You get" +msgstr "Du bekommst" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:102 +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:90 +msgid "Search Token" +msgstr "Such-Token" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:134 +msgid "No custom tokens" +msgstr "Keine benutzerdefinierten Token" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:135 +msgid "press the button to add your custom token" +msgstr "drücken Sie die Schaltfläche, um Ihr benutzerdefiniertes Token hinzuzufügen" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:158 +msgid "Delete Custom Token" +msgstr "Benutzerdefiniertes Token löschen" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:160 +msgid "Are you sure you want to Delete this Token?" +msgstr "Sind Sie sicher, dass Sie dieses Token löschen möchten?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:59 +msgid "Complete" +msgstr "Complete" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:63 +msgid "Running" +msgstr "Laufend" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:65 +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:8 +msgid "Failed" +msgstr "Fehler" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:149 +msgid "Clear" +msgstr "Leeren" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:161 +msgid "Search Transaction" +msgstr "Transaktion durchsuchen" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:187 +msgid "No transactions" +msgstr "Keine Transaktionen" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:194 +msgid "Your transaction history is stored locally and will appear here after you start a swap" +msgstr "Ihr Transaktionsverlauf wird lokal gespeichert und erscheint hier, nachdem Sie einen Swap gestartet haben" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:218 +msgid "Clear Transaction History" +msgstr "Transaktionsverlauf löschen" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:222 +msgid "Proceeding will remove all successful and failed transactions from the widget. Do you want to continue?" +msgstr "Fortfahren wird alle erfolgreichen und fehlgeschlagenen Transaktionen vom Widget entfernen. Möchten Sie fortfahren?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:229 +msgid "Note: This does not erase your transaction history on the chain; it only removes them here." +msgstr "Hinweis: Dies löscht nicht Ihren Transaktionsverlauf auf der Kette, sondern entfernt ihn nur hier." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:243 +msgid "Yes, Clear the history" +msgstr "Ja, den Verlauf löschen" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LanguagePage.tsx:56 +msgid "language" +msgstr "sprache" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:121 +msgid "Deselect all" +msgstr "Alle abwählen" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:121 +msgid "Select all" +msgstr "Alles auswählen" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:133 +msgid "Search {sourceType}" +msgstr "Suche {sourceType}" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectBlockchainPage.tsx:60 +msgid "Search Chain" +msgstr "Suchkette" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:67 +msgid "Source" +msgstr "Quelle" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:68 +msgid "Destination" +msgstr "Ziel" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:74 +msgid "Swap {type}" +msgstr "{type} tauschen" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SettingsPage.tsx:45 +msgid "Currently, you're in campaign mode with restrictions on liquidity sources. Would you like to switch out of this mode and make use of all available liquidity sources?" +msgstr "Derzeit sind Sie im Kampagnenmodus mit Beschränkungen für Liquiditätsquellen. Möchten Sie aus diesem Modus ausschalten und alle verfügbaren Liquiditätsquellen nutzen?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SwapDetailsPage.tsx:27 +msgid "The request ID is necessary to display the swap details." +msgstr "Die Request-ID ist notwendig, um die Swap-Details anzuzeigen." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/WalletsPage.tsx:67 +#: widget/ui/src/containers/ConnectWalletsModal/ConnectWalletsModal.tsx:15 +msgid "Connect Wallets" +msgstr "Wallets verbinden" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/WalletsPage.tsx:82 +msgid "Choose a wallet to connect." +msgstr "Wallet zum Verbinden auswählen." + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:25 +msgid "This week" +msgstr "Diese Woche" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:32 +msgid "This month" +msgstr "Diesen Monat" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:39 +msgid "This year" +msgstr "Dieses Jahr" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:129 +msgid "Required: >= {min} {symbol}" +msgstr "Erforderlich: >= {min} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:142 +msgid "Required: > {min} {symbol}" +msgstr "Erforderlich: > {min} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:157 +msgid "Required: <= {max} {symbol}" +msgstr "Erforderlich: <= {max} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:170 +msgid "Required: < {max} {symbol}" +msgstr "Erforderlich: < {max} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:601 +msgid " for network fee" +msgstr " für Netzwerkgebühr" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:604 +msgid " for swap" +msgstr " für Tausch" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:607 +msgid " for input and network fee" +msgstr " für Eingabe und Netzwerkgebühr" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:609 +msgid "Needs ≈ {requiredAmount} {symbol}{reason}, but you have {currentAmount} {symbol} in your {blockchain} wallet." +msgstr "Benötigt {requiredAmount} {symbol}{reason}, aber Sie haben {currentAmount} {symbol} in Ihrem {blockchain} Wallet." + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:669 +msgid "Waiting for connecting wallet" +msgstr "Warte auf Verbindung der Brieftasche" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:673 +msgid "Waiting for other running tasks to be finished" +msgstr "Warte auf Beendigung anderer laufender Aufgaben" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:676 +msgid "Waiting for changing wallet network" +msgstr "Warte auf Änderung des Wallet-Netzwerks" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:6 +msgid "Sunday" +msgstr "Sonntag" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:7 +msgid "Monday" +msgstr "Montag" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:8 +msgid "Tuesday" +msgstr "Dienstag" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:9 +msgid "Wednesday" +msgstr "Mittwoch" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:10 +msgid "Thursday" +msgstr "Donnerstag" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:11 +msgid "Friday" +msgstr "Freitag" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:12 +msgid "Saturday" +msgstr "Samstag" + +#. js-lingui-explicit-id +#: widget/ui/src/components/BottomLogo/BottomLogo.tsx:14 +msgid "Powered By" +msgstr "Powered by" + +#. js-lingui-explicit-id +#: widget/ui/src/components/FullExpandedQuote/FullExpandedQuote.Tooltip.tsx:37 +msgid "Aggregated Transaction" +msgstr "Gesamte Transaktion" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SelectableCategoryList/SelectableCategoryList.tsx:63 +msgid "{blockchainCategory}" +msgstr "{blockchainCategory}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/StepDetails/StepDetails.tsx:75 +#: widget/ui/src/components/StepDetails/StepDetails.tsx:102 +msgid "Swap on {fromChain} via {swapper}" +msgstr "Tausch auf {fromChain} über {swapper}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/StepDetails/StepDetails.tsx:109 +msgid "Bridge to {toChain} via {swapper}" +msgstr "Brücke zu {toChain} über {swapper}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:10 +msgid "Completed" +msgstr "Abgeschlossen" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:12 +msgid "In progress" +msgstr "In Bearbeitung" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapToken.tsx:122 +msgid "Waiting for bridge transaction" +msgstr "Warte auf Bridge-Transaktion" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:12 +msgid "Connected" +msgstr "Verbunden" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:13 +msgid "Disconnect" +msgstr "Verbindung trennen" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:18 +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:19 +msgid "Install" +msgstr "Installieren" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:24 +msgid "Connecting ..." +msgstr "Verbinde ..." + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:25 +msgid "Connecting" +msgstr "Verbinden" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:30 +msgid "Disconnected" +msgstr "Verbindung getrennt" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:34 +msgid "you need to pass a correct state to Wallet." +msgstr "Sie müssen einen korrekten Zustand an Wallet übergeben." + +#. js-lingui-explicit-id +#: widget/ui/src/containers/Notifications/NotificationNotFound.tsx:15 +msgid "There are no notifications." +msgstr "Keine Benachrichtigungen vorhanden." + +#. js-lingui-explicit-id +#: widget/ui/src/containers/Notifications/Notifications.tsx:39 +msgid "Clear all" +msgstr "Alles löschen" + +#. js-lingui-explicit-id +#: widget/ui/src/containers/SwapInput/SwapInput.tsx:65 +msgid "Balance" +msgstr "Saldo" + +#. js-lingui-explicit-id +#: widget/ui/src/containers/SwapInput/SwapInput.tsx:73 +msgid "Max" +msgstr "Max." + diff --git a/translations/el.po b/translations/el.po new file mode 100644 index 0000000000..aaa2900ef4 --- /dev/null +++ b/translations/el.po @@ -0,0 +1,1339 @@ +msgid "" +msgstr "" +"POT-Creation-Date: 2023-11-06 17:24+0330\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: @lingui/cli\n" +"Language: el\n" +"Project-Id-Version: rango\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2024-11-27 15:57\n" +"Last-Translator: \n" +"Language-Team: Greek\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Crowdin-Project: rango\n" +"X-Crowdin-Project-ID: 622238\n" +"X-Crowdin-Language: el\n" +"X-Crowdin-File: en.po\n" +"X-Crowdin-File-ID: 30\n" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SameTokensWarning/SameTokensWarning.tsx:21 +msgid "No Routes Found" +msgstr "Δεν βρέθηκαν διαδρομές" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SameTokensWarning/SameTokensWarning.tsx:25 +msgid "You cannot use the same token for From and To." +msgstr "Δεν μπορείτε να χρησιμοποιήσετε το ίδιο διακριτικό για Από και Προς." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:41 +#: widget/embedded/src/components/TokenList/TokenList.tsx:286 +#: widget/embedded/src/pages/HistoryPage.tsx:186 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:143 +msgid "No results found" +msgstr "Δεν βρέθηκαν αποτελέσματα" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:42 +#: widget/embedded/src/components/TokenList/TokenList.tsx:287 +#: widget/embedded/src/pages/HistoryPage.tsx:193 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:144 +msgid "Try using different keywords" +msgstr "Δοκιμάστε να χρησιμοποιήσετε διαφορετικές λέξεις-κλειδιά" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:72 +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:46 +#: widget/embedded/src/pages/SelectBlockchainPage.tsx:42 +#: widget/ui/src/containers/SwapInput/TokenSection.tsx:61 +msgid "Select Chain" +msgstr "Επιλογή Αλυσίδας" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:66 +msgid "All" +msgstr "Όλα" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:100 +msgid "More +{count}" +msgstr "Περισσότερα +{count}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabAlert/ActivateTabAlert.tsx:17 +msgid "Activate this tab" +msgstr "Ενεργοποίηση αυτής της καρτέλας" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabAlert/ActivateTabAlert.tsx:22 +msgid "Another tab is open and handles transactions." +msgstr "Μια άλλη καρτέλα είναι ανοιχτή και χειρίζεται συναλλαγές." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:20 +msgid "Activate current tab" +msgstr "Ενεργοποίηση τρέχουσας καρτέλας" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:22 +msgid "Currently, some transactions are running and being handled by other browser tab. If you activate this tab, all transactions that are already in the transaction sign step will expire." +msgstr "Επί του παρόντος, ορισμένες συναλλαγές εκτελούνται και αντιμετωπίζονται από άλλη καρτέλα περιηγητή. Εάν ενεργοποιήσετε αυτήν την καρτέλα, όλες οι συναλλαγές που βρίσκονται ήδη στο βήμα του σήματος συναλλαγής θα λήξουν." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:33 +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:349 +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:152 +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:33 +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:116 +msgid "Confirm" +msgstr "Επιβεβαίωση" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:365 +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:447 +msgid "Your {blockchainName} wallets" +msgstr "Τα {blockchainName} πορτοφόλια σας" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:384 +msgid "Insufficient account balance" +msgstr "Ανεπαρκές υπόλοιπο λογαριασμού" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:394 +msgid "Proceed anyway" +msgstr "Συνεχίστε ούτως ή άλλως" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:456 +msgid "You need to connect a {blockchainName} wallet." +msgstr "Πρέπει να συνδέσετε ένα {blockchainName} πορτοφόλι." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/WalletList.tsx:143 +msgid "Add {chain} chain" +msgstr "Προσθήκη {chain} αλυσίδας" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/WalletList.tsx:244 +msgid "Show more wallets" +msgstr "Εμφάνιση περισσότερων πορτοφολιών" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:113 +msgid "Send to a different address" +msgstr "Αποστολή σε διαφορετική διεύθυνση" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:129 +msgid "Enter {blockchainName} address" +msgstr "Εισάγετε {blockchainName} διεύθυνση" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:147 +msgid "Address {destination} doesn't match the blockchain address pattern." +msgstr "Διεύθυνση {destination} δεν ταιριάζει με το μοτίβο διευθύνσεων blockchain." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:59 +msgid "via" +msgstr "μέσω" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:74 +msgid "This token doesn't appear on the active token list(s). Make sure this is the token that you want to trade." +msgstr "Αυτό το διακριτικό δεν εμφανίζεται στη λίστα ενεργών συμβόλων. Βεβαιωθείτε ότι αυτό είναι το διακριτικό που θέλετε να ανταλλάξετε." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:89 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:164 +msgid "Import" +msgstr "Εισαγωγή" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/FilterSelector/FilterSelectorContent.tsx:26 +msgid "Status" +msgstr "Κατάσταση" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/FilterSelector/FilterSelectorContent.tsx:33 +#: widget/embedded/src/components/NoResult/NoResult.helpers.ts:37 +#: widget/embedded/src/pages/SettingsPage.tsx:55 +msgid "Reset" +msgstr "Reset" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/CancelButton.tsx:18 +msgid "Cancel" +msgstr "Ακύρωση" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:46 +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:34 +msgid "Refresh" +msgstr "Ανανέωση" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:63 +#: widget/ui/src/containers/Notifications/Notifications.tsx:35 +msgid "Notifications" +msgstr "Ειδοποιήσεις" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:79 +#: widget/embedded/src/pages/SettingsPage.tsx:38 +msgid "Settings" +msgstr "Ρυθμίσεις" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:93 +#: widget/embedded/src/pages/HistoryPage.tsx:139 +msgid "History" +msgstr "Ιστορικό" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/WalletButton.tsx:22 +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:16 +#: widget/embedded/src/constants/messages.ts:5 +msgid "Connect Wallet" +msgstr "Σύνδεση Πορτοφολιού" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HistoryGroupedList/HistoryGroupedList.tsx:118 +#: widget/embedded/src/utils/date.ts:18 +#: widget/embedded/src/utils/time.ts:22 +msgid "Today" +msgstr "Σήμερα" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/LoadingSwapDetails/LoadingSwapDetails.tsx:20 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:424 +msgid "Swaps steps" +msgstr "Βήματα swaps" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/NoResult/NoResult.helpers.ts:25 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:191 +msgid "Retry" +msgstr "Επανάληψη" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:149 +msgid "Slippage Error" +msgstr "Σφάλμα Ολίσθησης" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:150 +msgid "Slippage Warning" +msgstr "Προειδοποίηση Ολίσθησης" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:153 +msgid "Bridge Limit Error" +msgstr "Σφάλμα Ορίου Γέφυρας" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:240 +msgid "Yours: {amount} {symbol}" +msgstr "Δικά σας: {amount} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:261 +msgid "Minimum required slippage: {minRequiredSlippage}" +msgstr "Ελάχιστη απαιτούμενη ολίσθηση: {minRequiredSlippage}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:282 +msgid "Yours: {userSlippage}" +msgstr "Δικά σας: {userSlippage}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:395 +msgid "See All Routes" +msgstr "Δείτε Όλες Τις Διαδρομές" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:81 +msgid "View more info" +msgstr "Δείτε περισσότερες πληροφορίες" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:91 +msgid "Gas & Fee Explanation" +msgstr "Εξήγηση Αερίου & Χρέους" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:107 +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:103 +msgid "Details" +msgstr "Λεπτομέρειες" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:146 +msgid "Total Payable Fee" +msgstr "Συνολική Πληρωτέα Χρέωση" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:166 +msgid "Hide non-payable fees" +msgstr "Απόκρυψη μη πληρωτέων τελών" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:167 +msgid "Show non-payable fees" +msgstr "Εμφάνιση μη πληρωτέων τελών" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:177 +msgid "Description" +msgstr "Περιγραφή" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:181 +msgid "The following fees are considered in the transaction output and\n" +" you won’t need to pay extra gas for them." +msgstr "Οι ακόλουθες χρεώσεις λαμβάνονται υπόψη στην παραγωγή συναλλαγής και\n" +" δεν θα χρειαστεί να πληρώσετε επιπλέον φυσικό αέριο για αυτούς." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteSummary.tsx:25 +msgid "Swap input" +msgstr "Swap input" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteSummary.tsx:44 +msgid "Estimated output" +msgstr "Εκτιμώμενη έξοδος" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteTrigger.tsx:65 +msgid "Via:" +msgstr "Βιέννη:" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteTrigger.tsx:150 +msgid "Chains:" +msgstr "Αλυσίδες:" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/Quotes.tsx:77 +msgid "Sort by" +msgstr "Ταξινόμηση κατά" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:17 +msgid "Smart Routing" +msgstr "Έξυπνη Δρομολόγηση" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:21 +msgid "Lowest Fee" +msgstr "Χαμηλότερη Χρέωση" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:25 +msgid "Fastest Transfer" +msgstr "Ταχύτερη Μεταφορά" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:29 +msgid "Maximum Return" +msgstr "Μέγιστη Επιστροφή" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:33 +msgid "Maximum Output" +msgstr "Μέγιστη Έξοδος" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:43 +msgid "Swapping" +msgstr "Swapping" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:51 +msgid "Gas cost" +msgstr "Κόστος αερίου" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:59 +msgid "Receiving" +msgstr "Λήψη" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:67 +msgid "Price impact" +msgstr "Αντίκτυπος τιμής" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:35 +msgid "You need to increase slippage to at least {minRequiredSlippage} for this route." +msgstr "Πρέπει να αυξήσετε την ολίσθηση σε τουλάχιστον {minRequiredSlippage} για αυτήν τη διαδρομή." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:59 +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:61 +msgid "We recommend you to increase slippage to at least {minRequiredSlippage} for this route." +msgstr "Σας συνιστούμε να αυξήσετε την ολίσθηση σε τουλάχιστον {minRequiredSlippage} για αυτή τη διαδρομή." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:68 +msgid "Caution, your slippage is high." +msgstr "Προσοχή, η ολίσθηση σας είναι υψηλή." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.tsx:78 +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.Warning.tsx:26 +msgid "Change" +msgstr "Αλλαγή" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:42 +msgid "Change settings" +msgstr "Αλλαγή ρυθμίσεων" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:52 +msgid "High slippage" +msgstr "Υψηλή ολίσθηση" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:53 +msgid "Low slippage" +msgstr "Χαμηλή ολίσθηση" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:57 +msgid " Caution, your slippage is high (={userSlippage}). Your trade may be front run." +msgstr " Προσοχή, η ολίσθησή σας είναι υψηλή (={userSlippage}). Η συναλλαγή σας μπορεί να είναι μπροστινή." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:78 +msgid "Confirm anyway" +msgstr "Επιβεβαίωση ούτως ή άλλως" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:22 +msgid "Something went wrong" +msgstr "Κάτι πήγε στραβά" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:24 +msgid "Something went wrong. Please refresh the app." +msgstr "Κάτι πήγε στραβά. Παρακαλώ ανανεώστε την εφαρμογή." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/Slippage.tsx:38 +msgid "Slippage tolerance per swap" +msgstr "Ανοχή ολίσθησης ανά ανταλλαγή" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/Slippage.tsx:91 +msgid "Custom" +msgstr "Προσαρμοσμένο" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:11 +msgid "Your transaction will be reverted if the price changes unfavorably by more than this percentage." +msgstr "Η συναλλαγή σας θα επανέλθει αν η τιμή αλλάξει δυσμενώς περισσότερο από αυτό το ποσοστό." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:16 +#: widget/embedded/src/containers/Settings/Lists.tsx:245 +msgid "Warning" +msgstr "Προειδοποίηση" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:17 +msgid "This setting is applied to each step (e.g. 1Inch, Thorchain, etc.), meaning only that specific step will be reverted, not the entire route." +msgstr "Αυτή η ρύθμιση εφαρμόζεται σε κάθε βήμα (π.χ. 1Inch, Thorchain, κλπ.), που σημαίνει ότι μόνο το συγκεκριμένο βήμα θα επανέλθει, όχι ολόκληρη η διαδρομή." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:25 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:269 +msgid "Swap Details" +msgstr "Λεπτομέρειες Ανταλλαγής" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:33 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:312 +msgid "Request ID" +msgstr "Αναγνωριστικό Αίτησης" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:64 +msgid "Not found" +msgstr "Δε βρέθηκε" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:65 +msgid "Swap with request ID = {requestId} not found." +msgstr "Ανταλλαγή με το αναγνωριστικό αιτήματος = {requestId} δεν βρέθηκε." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:219 +msgid "You have received {amount} {token} in {conciseAddress} wallet on {chain} chain." +msgstr "Έχετε λάβει {amount} {token} στο {conciseAddress} πορτοφόλι στο {chain} chain." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:242 +msgid "Transaction was not sent." +msgstr "Η συναλλαγή δεν στάλθηκε." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:244 +msgid "{amount} {symbol} on {blockchain} remains in your wallet." +msgstr "{amount} {symbol} στο {blockchain} παραμένει στο πορτοφόλι σας." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:281 +msgid "Delete" +msgstr "Διαγραφή" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:304 +msgid "Try again" +msgstr "Προσπαθήστε ξανά" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:322 +msgid "Copied To Clipboard" +msgstr "Αντιγράφηκε Στο Πρόχειρο" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:323 +msgid "Copy Request ID" +msgstr "Αντιγραφή Αναγνωριστικού Αιτήματος" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:346 +msgid "View on Rango Explorer" +msgstr "Προβολή στον Εξερευνητή του Rango" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:355 +msgid "Finished at" +msgstr "Ολοκληρώθηκε στις" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:355 +msgid "Created at" +msgstr "Δημιουργήθηκε στις" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.tsx:50 +msgid "View transaction" +msgstr "Προβολή συναλλαγής" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.Warning.tsx:49 +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:31 +msgid "Connect" +msgstr "Σύνδεση" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:43 +msgid "Swap Successful" +msgstr "Swap Επιτυχής" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:71 +msgid "Transaction Failed" +msgstr "Η Συναλλαγή Απέτυχε" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:87 +msgid "Done" +msgstr "Ολοκληρώθηκε" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:100 +msgid "Diagnosis" +msgstr "Διάγνωση" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:112 +msgid "See Details" +msgstr "Δείτε Λεπτομέρειες" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:13 +msgid "Cancel Swap" +msgstr "Ακύρωση Εναλλαγής" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:14 +msgid "Are you sure you want to cancel this swap?" +msgstr "Είστε βέβαιοι ότι θέλετε να ακυρώσετε αυτό το swap?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:23 +msgid "Yes, Cancel it" +msgstr "Ναι, Ακύρωση" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:32 +#: widget/embedded/src/pages/CustomTokensPage.tsx:181 +msgid "No, Continue" +msgstr "Όχι, Συνέχεια" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:13 +msgid "Delete Transaction" +msgstr "Διαγραφή Συναλλαγής" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:14 +msgid "Are you sure you want to delete this swap?" +msgstr "Είστε βέβαιοι ότι θέλετε να διαγράψετε αυτό το swap?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:23 +#: widget/embedded/src/pages/CustomTokensPage.tsx:171 +msgid "Yes, Delete it" +msgstr "Ναι, να διαγραφούν" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:33 +#: widget/embedded/src/pages/HistoryPage.tsx:253 +msgid "No, Cancel" +msgstr "Όχι, Ακύρωση" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:12 +msgid "Change Network" +msgstr "Αλλαγή Δικτύου" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:20 +msgid "Network Changed" +msgstr "Το Δίκτυο Άλλαξε" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/TokenList/TokenList.tsx:271 +#: widget/ui/src/containers/SwapInput/TokenSection.tsx:54 +msgid "Select Token" +msgstr "Επιλογή Διακριτικού" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:27 +msgid "Wallet Connected" +msgstr "Συνδεδεμένο Πορτοφόλι" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:28 +msgid "Your wallet is connected, you can use it to swap." +msgstr "Το πορτοφόλι σας είναι συνδεδεμένο, μπορείτε να το χρησιμοποιήσετε για ανταλλαγή." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:39 +msgid "Failed to Connect" +msgstr "Αποτυχία σύνδεσης" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:41 +msgid "Your wallet is not connected. Please try again." +msgstr "Το πορτοφόλι σας δεν είναι συνδεδεμένο. Παρακαλώ δοκιμάστε ξανά." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:50 +msgid "Connecting to your wallet" +msgstr "Σύνδεση στο πορτοφόλι σας" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:51 +msgid "Click connect in your wallet popup." +msgstr "Κάντε κλικ στη σύνδεση στο αναδυόμενο παράθυρο του πορτοφολιού." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:99 +msgid "Select Derivation Path" +msgstr "Επιλέξτε Διαδρομή Παραγωγής" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:100 +msgid "In order to connect to {type}, you must first select a Derivation Path" +msgstr "Για να συνδεθείτε στο {type}, πρέπει πρώτα να επιλέξετε μια Διαδρομή Παραγωγής" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:118 +msgid "Choose Derivation Path Template" +msgstr "Επιλέξτε Πρότυπο Διαδρομής Παραγωγής" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:133 +msgid "Enter Path" +msgstr "Εισαγωγή Διαδρομής" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:134 +msgid "Enter Index" +msgstr "Εισαγωγή Ευρετηρίου" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:15 +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:18 +msgid "Add {blockchainDisplayName} Chain" +msgstr "Προσθήκη {blockchainDisplayName} Αλυσίδα" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:20 +msgid "Would you like to add the {blockchainDisplayName} experimental chain to your wallet?" +msgstr "Θα θέλατε να προσθέσετε το {blockchainDisplayName} πειραματική αλυσίδα στο πορτοφόλι σας?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:22 +msgid "Please approve the experimental chain pop-up in your wallet." +msgstr "Παρακαλούμε να εγκρίνετε το αναδυόμενο παράθυρο της πειραματικής αλυσίδας στο πορτοφόλι σας." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:30 +msgid "{blockchainDisplayName} Chain Added" +msgstr "Προστέθηκε {blockchainDisplayName} Αλυσίδα" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:34 +msgid "The {blockchainDisplayName} chain has been successfully added to your wallet." +msgstr "Η αλυσίδα {blockchainDisplayName} προστέθηκε με επιτυχία στο πορτοφόλι σας." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:42 +msgid "Request Rejected" +msgstr "Αίτηση Απορρίφθηκε" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:43 +msgid "You've rejected adding {blockchainDisplayName} chain to your wallet." +msgstr "Απορρίψατε την προσθήκη αλυσίδας {blockchainDisplayName} στο πορτοφόλι σας." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:70 +msgid "Select chain types" +msgstr "Επιλέξτε τύπους αλυσίδας" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:71 +msgid "This wallet supports multiple chains. Select which chain you'd like to connect to." +msgstr "Αυτό το πορτοφόλι υποστηρίζει πολλαπλές αλυσίδες. Επιλέξτε σε ποια αλυσίδα θα θέλατε να συνδεθείτε." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:9 +msgid "Failed Network, Please retry your swap." +msgstr "Αποτυχία δικτύου, Παρακαλώ δοκιμάστε ξανά το swap." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:11 +msgid "Please reset your liquidity sources." +msgstr "Παρακαλώ επαναφέρετε τις πηγές ρευστότητας." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:12 +msgid "You have limited the liquidity sources and this might result in Rango finding no routes. Please consider resetting your liquidity sources." +msgstr "Έχετε περιορίσει τις πηγές ρευστότητας και αυτό μπορεί να οδηγήσει σε Rango εύρεση καμία διαδρομή. Παρακαλώ σκεφτείτε να επαναφέρετε τις πηγές ρευστότητας." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:17 +msgid "No Routes Found." +msgstr "Δεν Βρέθηκαν Διαδρομές." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:18 +msgid "Reasons why Rango couldn't find a route: low liquidity on token, very low input amount or no routes available for the selected input/output token combination." +msgstr "Λόγοι για τους οποίους το Rango δεν μπόρεσε να βρει μια διαδρομή: χαμηλή ρευστότητα στο token, πολύ χαμηλό ποσό εισαγωγής ή καμία διαθέσιμη διαδρομή για τον επιλεγμένο συνδυασμό εισόδου/εξόδου token." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:23 +msgid "Bridge Limit Error: Please increase your amount." +msgstr "Σφάλμα ορίου γέφυρας: Παρακαλώ αυξήστε το ποσό σας." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:26 +msgid "Bridge Limit Error: Please decrease your amount." +msgstr "Σφάλμα ορίου γέφυρας: Παρακαλώ μειώστε το ποσό σας." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:31 +msgid "High Price Impact" +msgstr "Επιπτώσεις Υψηλής Τιμής" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:32 +msgid "Price impact is too high!" +msgstr "Ο αντίκτυπος στην τιμή είναι πολύ υψηλός!" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:33 +msgid "The price impact is significantly higher than the allowed amount." +msgstr "Ο αντίκτυπος στην τιμή είναι σημαντικά υψηλότερος από το επιτρεπόμενο ποσό." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:36 +msgid "Confirm high price impact" +msgstr "Επιβεβαιώστε την επίδραση υψηλής τιμής" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:39 +msgid "Route updated and price impact is too high, try again later!" +msgstr "Η διαδρομή ενημερώθηκε και ο αντίκτυπος των τιμών είναι πολύ υψηλός, δοκιμάστε ξανά αργότερα!" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:44 +msgid "USD Price Unknown" +msgstr "Τιμή USD Άγνωστη" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:45 +msgid "USD Price Unknown, Cannot calculate Price Impact." +msgstr "Τιμή USD Άγνωστο, δεν μπορεί να υπολογίσει την επίπτωση της τιμής." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:46 +msgid "USD Price Unknown, Cannot calculate Price Impact. The price impact may be higher than usual. Are you sure to continue the Swap?" +msgstr "Τιμή USD Άγνωστο, δεν μπορεί να υπολογίσει την επίπτωση της τιμής. Ο αντίκτυπος της τιμής μπορεί να είναι υψηλότερη από το συνηθισμένο. Είστε βέβαιοι να συνεχίσετε την Swap?" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:49 +msgid "Confirm USD Price Unknown" +msgstr "Επιβεβαίωση Τιμής Usd Άγνωστο" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:6 +#: widget/embedded/src/pages/Home.tsx:163 +msgid "Swap" +msgstr "Εναλλαγή" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:7 +msgid "Swap anyway" +msgstr "Εναλλαγή ούτως ή άλλως" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:8 +msgid "The route goes through Ethereum. Continue?" +msgstr "Η διαδρομή περνάει από το Ethereum. Συνέχεια?" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:10 +msgid "Route has been updated." +msgstr "Η διαδρομή έχει ενημερωθεί." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:12 +msgid "Output amount changed to {newOutputAmount} ({percentageChange}% change)." +msgstr "Το ποσό εξόδου άλλαξε σε {newOutputAmount} ({percentageChange}% αλλαγή)." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:20 +msgid "Route swappers has been updated." +msgstr "Τα swappers διαδρομών έχουν ενημερωθεί." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:22 +msgid "Route internal coins has been updated." +msgstr "Τα εσωτερικά νομίσματα διαδρομής έχουν ενημερωθεί." + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/ExpandedQuotes/ExpandedQuotes.tsx:53 +#: widget/embedded/src/pages/Routes.tsx:48 +msgid "Routes" +msgstr "Διαδρομές" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Inputs/Inputs.tsx:76 +msgid "From" +msgstr "Από" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Inputs/Inputs.tsx:118 +msgid "To" +msgstr "Προς" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:49 +msgid "Light" +msgstr "Φωτεινό" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:58 +msgid "Dark" +msgstr "Σκοτεινό" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:67 +msgid "Auto" +msgstr "Αυτόματο" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:140 +msgid "Loading failed" +msgstr "Αποτυχία φόρτωσης" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:156 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:41 +msgid "Bridges" +msgstr "Γέφυρες" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:174 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:41 +msgid "Exchanges" +msgstr "Ανταλλαγές" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:195 +#: widget/embedded/src/pages/CustomTokensPage.tsx:90 +msgid "Custom Tokens" +msgstr "Προσαρμοσμένα Tokens" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:214 +#: widget/embedded/src/pages/LanguagePage.tsx:43 +msgid "Language" +msgstr "Γλώσσα" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:235 +msgid "Infinite approval" +msgstr "Άπειρη έγκριση" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:246 +msgid "Enabling the 'Infinite approval' mode grants unrestricted access to underlying smart contracts, allowing them to utilize the approved token amount without limitations." +msgstr "Η ενεργοποίηση της λειτουργίας 'Άπειρη έγκριση' παρέχει απεριόριστη πρόσβαση σε υποκείμενες έξυπνες συμβάσεις, επιτρέποντάς τους να χρησιμοποιούν το εγκεκριμένο ποσό συμβολαίων χωρίς περιορισμούς." + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:266 +msgid "Theme" +msgstr "Θέμα" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:39 +msgid "Duplicate Token" +msgstr "Duplicate Token" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:40 +msgid "The address you entered is duplicate, please enter a new address." +msgstr "Η διεύθυνση που εισάγατε είναι διπλότυπη, παρακαλώ εισάγετε μια νέα διεύθυνση." + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:46 +msgid "Token Already Exists" +msgstr "Το διακριτικό Υπάρχει Ήδη" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:47 +msgid "There's no need to add this token again because it already exists and is supported by us." +msgstr "Δεν χρειάζεται να προσθέσετε αυτό το διακριτικό ξανά επειδή υπάρχει ήδη και υποστηρίζεται από εμάς." + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:53 +msgid "Token Not Found" +msgstr "Το Διακριτικό Δεν Βρέθηκε" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:54 +msgid "Sorry, no token was found on {blockchain} chain with the provided address. please make sure you have entered the right token address." +msgstr "Λυπούμαστε, δεν βρέθηκε κανένα διακριτικό στην αλυσίδα {blockchain} με την παρεχόμενη διεύθυνση. Παρακαλώ βεβαιωθείτε ότι έχετε εισέλθει στη σωστή διεύθυνση διακριτικού." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:78 +msgid "Network Error" +msgstr "Σφάλμα Δικτύου" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:109 +#: widget/embedded/src/pages/CustomTokensPage.tsx:149 +msgid "Add Custom Token" +msgstr "Προσθήκη Προσαρμοσμένου Διακριτικού" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:127 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:128 +msgid "Select chain" +msgstr "Επιλογή αλυσίδας" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:132 +msgid "Enter Address" +msgstr "Εισαγωγή Διεύθυνσης" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:139 +msgid "Enter token address" +msgstr "Εισάγετε διεύθυνση διακριτικού" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:176 +msgid "Failed Network, Please retry." +msgstr "Αποτυχημένο Δίκτυο, Παρακαλώ προσπαθήστε ξανά." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:192 +msgid "Add another custom token" +msgstr "Προσθέστε ένα άλλο προσαρμοσμένο διακριτικό" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:236 +msgid "Confirm Swap" +msgstr "Επιβεβαίωση Ανταλλαγής" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:254 +msgid "Start Swap" +msgstr "Έναρξη Εναλλαγής" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:282 +msgid "You get" +msgstr "Παίρνετε" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:102 +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:90 +msgid "Search Token" +msgstr "Διακριτικό Αναζήτησης" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:134 +msgid "No custom tokens" +msgstr "Δεν υπάρχουν προσαρμοσμένα σημεία" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:135 +msgid "press the button to add your custom token" +msgstr "πατήστε το κουμπί για να προσθέσετε το προσαρμοσμένο διακριτικό σας" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:158 +msgid "Delete Custom Token" +msgstr "Διαγραφή Προσαρμοσμένου Διακριτικού" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:160 +msgid "Are you sure you want to Delete this Token?" +msgstr "Είστε βέβαιοι ότι θέλετε να διαγράψετε αυτό το Token?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:59 +msgid "Complete" +msgstr "Complete" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:63 +msgid "Running" +msgstr "Εκτελείται" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:65 +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:8 +msgid "Failed" +msgstr "Απέτυχε" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:149 +msgid "Clear" +msgstr "Εκκαθάριση" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:161 +msgid "Search Transaction" +msgstr "Αναζήτηση Συναλλαγής" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:187 +msgid "No transactions" +msgstr "Δεν υπάρχουν συναλλαγές" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:194 +msgid "Your transaction history is stored locally and will appear here after you start a swap" +msgstr "Το ιστορικό συναλλαγών σας αποθηκεύεται τοπικά και θα εμφανιστεί εδώ μετά την έναρξη της ανταλλαγής" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:218 +msgid "Clear Transaction History" +msgstr "Εκκαθάριση Ιστορικού Συναλλαγών" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:222 +msgid "Proceeding will remove all successful and failed transactions from the widget. Do you want to continue?" +msgstr "Η διαδικασία θα καταργήσει όλες τις επιτυχημένες και αποτυχημένες συναλλαγές από το widget. Θέλετε να συνεχίσετε?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:229 +msgid "Note: This does not erase your transaction history on the chain; it only removes them here." +msgstr "Σημείωση: Αυτό δεν διαγράφει το ιστορικό συναλλαγών σας στην αλυσίδα, αλλά τις αφαιρεί μόνο εδώ." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:243 +msgid "Yes, Clear the history" +msgstr "Ναι, Καθαρισμός ιστορικού" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LanguagePage.tsx:56 +msgid "language" +msgstr "γλώσσα" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:121 +msgid "Deselect all" +msgstr "Αποεπιλογή όλων" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:121 +msgid "Select all" +msgstr "Επιλογή όλων" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:133 +msgid "Search {sourceType}" +msgstr "Αναζήτηση {sourceType}" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectBlockchainPage.tsx:60 +msgid "Search Chain" +msgstr "Αλυσίδα Αναζήτησης" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:67 +msgid "Source" +msgstr "Πηγή" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:68 +msgid "Destination" +msgstr "Προορισμός" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:74 +msgid "Swap {type}" +msgstr "Ανταλλαγή {type}" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SettingsPage.tsx:45 +msgid "Currently, you're in campaign mode with restrictions on liquidity sources. Would you like to switch out of this mode and make use of all available liquidity sources?" +msgstr "Επί του παρόντος, είστε σε λειτουργία καμπάνιας με περιορισμούς στις πηγές ρευστότητας. Θα θέλατε να βγείτε από αυτή τη λειτουργία και να χρησιμοποιήσετε όλες τις διαθέσιμες πηγές ρευστότητας?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SwapDetailsPage.tsx:27 +msgid "The request ID is necessary to display the swap details." +msgstr "Το αναγνωριστικό αιτήματος είναι απαραίτητο για την εμφάνιση των λεπτομερειών ανταλλαγής." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/WalletsPage.tsx:67 +#: widget/ui/src/containers/ConnectWalletsModal/ConnectWalletsModal.tsx:15 +msgid "Connect Wallets" +msgstr "Σύνδεση Πορτοφολιών" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/WalletsPage.tsx:82 +msgid "Choose a wallet to connect." +msgstr "Επιλέξτε ένα πορτοφόλι για σύνδεση." + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:25 +msgid "This week" +msgstr "Αυτή την εβδομάδα" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:32 +msgid "This month" +msgstr "Αυτό το μήνα" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:39 +msgid "This year" +msgstr "Αυτό το έτος" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:129 +msgid "Required: >= {min} {symbol}" +msgstr "Απαιτείται: >= {min} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:142 +msgid "Required: > {min} {symbol}" +msgstr "Απαιτείται: > {min} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:157 +msgid "Required: <= {max} {symbol}" +msgstr "Απαιτείται: <= {max} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:170 +msgid "Required: < {max} {symbol}" +msgstr "Απαιτείται: < {max} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:601 +msgid " for network fee" +msgstr " για τέλη δικτύου" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:604 +msgid " for swap" +msgstr " για ανταλλαγή" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:607 +msgid " for input and network fee" +msgstr " για εισροή και τέλη δικτύου" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:609 +msgid "Needs ≈ {requiredAmount} {symbol}{reason}, but you have {currentAmount} {symbol} in your {blockchain} wallet." +msgstr "Χρειάζεται ≈ {requiredAmount} {symbol}{reason}, αλλά έχετε {currentAmount} {symbol} στο {blockchain} πορτοφόλι σας." + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:669 +msgid "Waiting for connecting wallet" +msgstr "Αναμονή για συνδεδεμένο πορτοφόλι" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:673 +msgid "Waiting for other running tasks to be finished" +msgstr "Αναμονή για να ολοκληρωθούν άλλες εκτελούμενες εργασίες" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:676 +msgid "Waiting for changing wallet network" +msgstr "Αναμονή για αλλαγή δικτύου πορτοφολιού" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:6 +msgid "Sunday" +msgstr "Κυριακή" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:7 +msgid "Monday" +msgstr "Δευτέρα" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:8 +msgid "Tuesday" +msgstr "Τρίτη" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:9 +msgid "Wednesday" +msgstr "Τετάρτη" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:10 +msgid "Thursday" +msgstr "Πέμπτη" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:11 +msgid "Friday" +msgstr "Παρασκευή" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:12 +msgid "Saturday" +msgstr "Σάββατο" + +#. js-lingui-explicit-id +#: widget/ui/src/components/BottomLogo/BottomLogo.tsx:14 +msgid "Powered By" +msgstr "Τροφοδοτείται Από" + +#. js-lingui-explicit-id +#: widget/ui/src/components/FullExpandedQuote/FullExpandedQuote.Tooltip.tsx:37 +msgid "Aggregated Transaction" +msgstr "Συγκεντρωτική Συναλλαγή" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SelectableCategoryList/SelectableCategoryList.tsx:63 +msgid "{blockchainCategory}" +msgstr "{blockchainCategory}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/StepDetails/StepDetails.tsx:75 +#: widget/ui/src/components/StepDetails/StepDetails.tsx:102 +msgid "Swap on {fromChain} via {swapper}" +msgstr "Εναλλαγή στο {fromChain} μέσω {swapper}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/StepDetails/StepDetails.tsx:109 +msgid "Bridge to {toChain} via {swapper}" +msgstr "Γέφυρα στο {toChain} μέσω {swapper}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:10 +msgid "Completed" +msgstr "Ολοκληρώθηκε" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:12 +msgid "In progress" +msgstr "Σε εξέλιξη" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapToken.tsx:122 +msgid "Waiting for bridge transaction" +msgstr "Αναμονή για συναλλαγή γέφυρας" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:12 +msgid "Connected" +msgstr "Συνδεδεμένο" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:13 +msgid "Disconnect" +msgstr "Αποσύνδεση" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:18 +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:19 +msgid "Install" +msgstr "Εγκατάσταση" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:24 +msgid "Connecting ..." +msgstr "Σύνδεση..." + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:25 +msgid "Connecting" +msgstr "Σύνδεση" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:30 +msgid "Disconnected" +msgstr "Αποσυνδέθηκε" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:34 +msgid "you need to pass a correct state to Wallet." +msgstr "πρέπει να περάσετε μια σωστή κατάσταση στο Πορτοφόλι." + +#. js-lingui-explicit-id +#: widget/ui/src/containers/Notifications/NotificationNotFound.tsx:15 +msgid "There are no notifications." +msgstr "Δεν υπάρχουν ειδοποιήσεις." + +#. js-lingui-explicit-id +#: widget/ui/src/containers/Notifications/Notifications.tsx:39 +msgid "Clear all" +msgstr "Εκκαθάριση όλων" + +#. js-lingui-explicit-id +#: widget/ui/src/containers/SwapInput/SwapInput.tsx:65 +msgid "Balance" +msgstr "Υπόλοιπο" + +#. js-lingui-explicit-id +#: widget/ui/src/containers/SwapInput/SwapInput.tsx:73 +msgid "Max" +msgstr "Μέγιστο" + diff --git a/translations/en.po b/translations/en.po new file mode 100644 index 0000000000..3fd2887f5b --- /dev/null +++ b/translations/en.po @@ -0,0 +1,1335 @@ +msgid "" +msgstr "" +"POT-Creation-Date: 2023-11-06 17:24+0330\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: @lingui/cli\n" +"Language: en\n" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: \n" +"Last-Translator: \n" +"Language-Team: \n" +"Plural-Forms: \n" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SameTokensWarning/SameTokensWarning.tsx:21 +msgid "No Routes Found" +msgstr "No Routes Found" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SameTokensWarning/SameTokensWarning.tsx:25 +msgid "You cannot use the same token for From and To." +msgstr "You cannot use the same token for From and To." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:41 +#: widget/embedded/src/components/TokenList/TokenList.tsx:286 +#: widget/embedded/src/pages/HistoryPage.tsx:186 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:143 +msgid "No results found" +msgstr "No results found" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:42 +#: widget/embedded/src/components/TokenList/TokenList.tsx:287 +#: widget/embedded/src/pages/HistoryPage.tsx:193 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:144 +msgid "Try using different keywords" +msgstr "Try using different keywords" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:72 +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:46 +#: widget/embedded/src/pages/SelectBlockchainPage.tsx:42 +#: widget/ui/src/containers/SwapInput/TokenSection.tsx:61 +msgid "Select Chain" +msgstr "Select Chain" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:66 +msgid "All" +msgstr "All" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:100 +msgid "More +{count}" +msgstr "More +{count}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabAlert/ActivateTabAlert.tsx:17 +msgid "Activate this tab" +msgstr "Activate this tab" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabAlert/ActivateTabAlert.tsx:22 +msgid "Another tab is open and handles transactions." +msgstr "Another tab is open and handles transactions." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:20 +msgid "Activate current tab" +msgstr "Activate current tab" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:22 +msgid "Currently, some transactions are running and being handled by other browser tab. If you activate this tab, all transactions that are already in the transaction sign step will expire." +msgstr "Currently, some transactions are running and being handled by other browser tab. If you activate this tab, all transactions that are already in the transaction sign step will expire." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:33 +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:349 +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:152 +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:33 +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:116 +msgid "Confirm" +msgstr "Confirm" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:365 +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:447 +msgid "Your {blockchainName} wallets" +msgstr "Your {blockchainName} wallets" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:384 +msgid "Insufficient account balance" +msgstr "Insufficient account balance" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:394 +msgid "Proceed anyway" +msgstr "Proceed anyway" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:456 +msgid "You need to connect a {blockchainName} wallet." +msgstr "You need to connect a {blockchainName} wallet." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/WalletList.tsx:143 +msgid "Add {chain} chain" +msgstr "Add {chain} chain" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/WalletList.tsx:244 +msgid "Show more wallets" +msgstr "Show more wallets" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:113 +msgid "Send to a different address" +msgstr "Send to a different address" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:129 +msgid "Enter {blockchainName} address" +msgstr "Enter {blockchainName} address" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:147 +msgid "Address {destination} doesn't match the blockchain address pattern." +msgstr "Address {destination} doesn't match the blockchain address pattern." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:59 +msgid "via" +msgstr "via" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:74 +msgid "This token doesn't appear on the active token list(s). Make sure this is the token that you want to trade." +msgstr "This token doesn't appear on the active token list(s). Make sure this is the token that you want to trade." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:89 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:164 +msgid "Import" +msgstr "Import" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/FilterSelector/FilterSelectorContent.tsx:26 +msgid "Status" +msgstr "Status" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/FilterSelector/FilterSelectorContent.tsx:33 +#: widget/embedded/src/components/NoResult/NoResult.helpers.ts:37 +#: widget/embedded/src/pages/SettingsPage.tsx:55 +msgid "Reset" +msgstr "Reset" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/CancelButton.tsx:18 +msgid "Cancel" +msgstr "Cancel" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:46 +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:34 +msgid "Refresh" +msgstr "Refresh" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:63 +#: widget/ui/src/containers/Notifications/Notifications.tsx:35 +msgid "Notifications" +msgstr "Notifications" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:79 +#: widget/embedded/src/pages/SettingsPage.tsx:38 +msgid "Settings" +msgstr "Settings" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:93 +#: widget/embedded/src/pages/HistoryPage.tsx:139 +msgid "History" +msgstr "History" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/WalletButton.tsx:22 +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:16 +#: widget/embedded/src/constants/messages.ts:5 +msgid "Connect Wallet" +msgstr "Connect Wallet" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HistoryGroupedList/HistoryGroupedList.tsx:118 +#: widget/embedded/src/utils/date.ts:18 +#: widget/embedded/src/utils/time.ts:22 +msgid "Today" +msgstr "Today" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/LoadingSwapDetails/LoadingSwapDetails.tsx:20 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:424 +msgid "Swaps steps" +msgstr "Swaps steps" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/NoResult/NoResult.helpers.ts:25 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:191 +msgid "Retry" +msgstr "Retry" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:149 +msgid "Slippage Error" +msgstr "Slippage Error" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:150 +msgid "Slippage Warning" +msgstr "Slippage Warning" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:153 +msgid "Bridge Limit Error" +msgstr "Bridge Limit Error" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:240 +msgid "Yours: {amount} {symbol}" +msgstr "Yours: {amount} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:261 +msgid "Minimum required slippage: {minRequiredSlippage}" +msgstr "Minimum required slippage: {minRequiredSlippage}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:282 +msgid "Yours: {userSlippage}" +msgstr "Yours: {userSlippage}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:395 +msgid "See All Routes" +msgstr "See All Routes" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:81 +msgid "View more info" +msgstr "View more info" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:91 +msgid "Gas & Fee Explanation" +msgstr "Gas & Fee Explanation" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:107 +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:103 +msgid "Details" +msgstr "Details" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:146 +msgid "Total Payable Fee" +msgstr "Total Payable Fee" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:166 +msgid "Hide non-payable fees" +msgstr "Hide non-payable fees" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:167 +msgid "Show non-payable fees" +msgstr "Show non-payable fees" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:177 +msgid "Description" +msgstr "Description" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:181 +msgid "" +"The following fees are considered in the transaction output and\n" +" you won’t need to pay extra gas for them." +msgstr "" +"The following fees are considered in the transaction output and\n" +" you won’t need to pay extra gas for them." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteSummary.tsx:25 +msgid "Swap input" +msgstr "Swap input" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteSummary.tsx:44 +msgid "Estimated output" +msgstr "Estimated output" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteTrigger.tsx:65 +msgid "Via:" +msgstr "Via:" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteTrigger.tsx:150 +msgid "Chains:" +msgstr "Chains:" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/Quotes.tsx:77 +msgid "Sort by" +msgstr "Sort by" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:17 +msgid "Smart Routing" +msgstr "Smart Routing" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:21 +msgid "Lowest Fee" +msgstr "Lowest Fee" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:25 +msgid "Fastest Transfer" +msgstr "Fastest Transfer" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:29 +msgid "Maximum Return" +msgstr "Maximum Return" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:33 +msgid "Maximum Output" +msgstr "Maximum Output" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:43 +msgid "Swapping" +msgstr "Swapping" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:51 +msgid "Gas cost" +msgstr "Gas cost" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:59 +msgid "Receiving" +msgstr "Receiving" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:67 +msgid "Price impact" +msgstr "Price impact" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:35 +msgid "You need to increase slippage to at least {minRequiredSlippage} for this route." +msgstr "You need to increase slippage to at least {minRequiredSlippage} for this route." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:59 +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:61 +msgid "We recommend you to increase slippage to at least {minRequiredSlippage} for this route." +msgstr "We recommend you to increase slippage to at least {minRequiredSlippage} for this route." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:68 +msgid "Caution, your slippage is high." +msgstr "Caution, your slippage is high." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.tsx:78 +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.Warning.tsx:26 +msgid "Change" +msgstr "Change" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:42 +msgid "Change settings" +msgstr "Change settings" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:52 +msgid "High slippage" +msgstr "High slippage" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:53 +msgid "Low slippage" +msgstr "Low slippage" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:57 +msgid " Caution, your slippage is high (={userSlippage}). Your trade may be front run." +msgstr " Caution, your slippage is high (={userSlippage}). Your trade may be front run." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:78 +msgid "Confirm anyway" +msgstr "Confirm anyway" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:22 +msgid "Something went wrong" +msgstr "Something went wrong" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:24 +msgid "Something went wrong. Please refresh the app." +msgstr "Something went wrong. Please refresh the app." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/Slippage.tsx:38 +msgid "Slippage tolerance per swap" +msgstr "Slippage tolerance per swap" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/Slippage.tsx:91 +msgid "Custom" +msgstr "Custom" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:11 +msgid "Your transaction will be reverted if the price changes unfavorably by more than this percentage." +msgstr "Your transaction will be reverted if the price changes unfavorably by more than this percentage." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:16 +#: widget/embedded/src/containers/Settings/Lists.tsx:245 +msgid "Warning" +msgstr "Warning" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:17 +msgid "This setting is applied to each step (e.g. 1Inch, Thorchain, etc.), meaning only that specific step will be reverted, not the entire route." +msgstr "This setting is applied to each step (e.g. 1Inch, Thorchain, etc.), meaning only that specific step will be reverted, not the entire route." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:25 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:269 +msgid "Swap Details" +msgstr "Swap Details" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:33 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:312 +msgid "Request ID" +msgstr "Request ID" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:64 +msgid "Not found" +msgstr "Not found" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:65 +msgid "Swap with request ID = {requestId} not found." +msgstr "Swap with request ID = {requestId} not found." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:219 +msgid "You have received {amount} {token} in {conciseAddress} wallet on {chain} chain." +msgstr "You have received {amount} {token} in {conciseAddress} wallet on {chain} chain." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:242 +msgid "Transaction was not sent." +msgstr "Transaction was not sent." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:244 +msgid "{amount} {symbol} on {blockchain} remains in your wallet." +msgstr "{amount} {symbol} on {blockchain} remains in your wallet." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:281 +msgid "Delete" +msgstr "Delete" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:304 +msgid "Try again" +msgstr "Try again" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:322 +msgid "Copied To Clipboard" +msgstr "Copied To Clipboard" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:323 +msgid "Copy Request ID" +msgstr "Copy Request ID" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:346 +msgid "View on Rango Explorer" +msgstr "View on Rango Explorer" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:355 +msgid "Finished at" +msgstr "Finished at" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:355 +msgid "Created at" +msgstr "Created at" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.tsx:50 +msgid "View transaction" +msgstr "View transaction" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.Warning.tsx:49 +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:31 +msgid "Connect" +msgstr "Connect" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:43 +msgid "Swap Successful" +msgstr "Swap Successful" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:71 +msgid "Transaction Failed" +msgstr "Transaction Failed" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:87 +msgid "Done" +msgstr "Done" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:100 +msgid "Diagnosis" +msgstr "Diagnosis" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:112 +msgid "See Details" +msgstr "See Details" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:13 +msgid "Cancel Swap" +msgstr "Cancel Swap" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:14 +msgid "Are you sure you want to cancel this swap?" +msgstr "Are you sure you want to cancel this swap?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:23 +msgid "Yes, Cancel it" +msgstr "Yes, Cancel it" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:32 +#: widget/embedded/src/pages/CustomTokensPage.tsx:181 +msgid "No, Continue" +msgstr "No, Continue" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:13 +msgid "Delete Transaction" +msgstr "Delete Transaction" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:14 +msgid "Are you sure you want to delete this swap?" +msgstr "Are you sure you want to delete this swap?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:23 +#: widget/embedded/src/pages/CustomTokensPage.tsx:171 +msgid "Yes, Delete it" +msgstr "Yes, Delete it" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:33 +#: widget/embedded/src/pages/HistoryPage.tsx:253 +msgid "No, Cancel" +msgstr "No, Cancel" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:12 +msgid "Change Network" +msgstr "Change Network" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:20 +msgid "Network Changed" +msgstr "Network Changed" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/TokenList/TokenList.tsx:271 +#: widget/ui/src/containers/SwapInput/TokenSection.tsx:54 +msgid "Select Token" +msgstr "Select Token" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:27 +msgid "Wallet Connected" +msgstr "Wallet Connected" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:28 +msgid "Your wallet is connected, you can use it to swap." +msgstr "Your wallet is connected, you can use it to swap." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:39 +msgid "Failed to Connect" +msgstr "Failed to Connect" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:41 +msgid "Your wallet is not connected. Please try again." +msgstr "Your wallet is not connected. Please try again." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:50 +msgid "Connecting to your wallet" +msgstr "Connecting to your wallet" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:51 +msgid "Click connect in your wallet popup." +msgstr "Click connect in your wallet popup." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:99 +msgid "Select Derivation Path" +msgstr "Select Derivation Path" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:100 +msgid "In order to connect to {type}, you must first select a Derivation Path" +msgstr "In order to connect to {type}, you must first select a Derivation Path" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:118 +msgid "Choose Derivation Path Template" +msgstr "Choose Derivation Path Template" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:133 +msgid "Enter Path" +msgstr "Enter Path" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:134 +msgid "Enter Index" +msgstr "Enter Index" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:15 +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:18 +msgid "Add {blockchainDisplayName} Chain" +msgstr "Add {blockchainDisplayName} Chain" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:20 +msgid "Would you like to add the {blockchainDisplayName} experimental chain to your wallet?" +msgstr "Would you like to add the {blockchainDisplayName} experimental chain to your wallet?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:22 +msgid "Please approve the experimental chain pop-up in your wallet." +msgstr "Please approve the experimental chain pop-up in your wallet." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:30 +msgid "{blockchainDisplayName} Chain Added" +msgstr "{blockchainDisplayName} Chain Added" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:34 +msgid "The {blockchainDisplayName} chain has been successfully added to your wallet." +msgstr "The {blockchainDisplayName} chain has been successfully added to your wallet." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:42 +msgid "Request Rejected" +msgstr "Request Rejected" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:43 +msgid "You've rejected adding {blockchainDisplayName} chain to your wallet." +msgstr "You've rejected adding {blockchainDisplayName} chain to your wallet." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:70 +msgid "Select chain types" +msgstr "Select chain types" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:71 +msgid "This wallet supports multiple chains. Select which chain you'd like to connect to." +msgstr "This wallet supports multiple chains. Select which chain you'd like to connect to." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:9 +msgid "Failed Network, Please retry your swap." +msgstr "Failed Network, Please retry your swap." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:11 +msgid "Please reset your liquidity sources." +msgstr "Please reset your liquidity sources." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:12 +msgid "You have limited the liquidity sources and this might result in Rango finding no routes. Please consider resetting your liquidity sources." +msgstr "You have limited the liquidity sources and this might result in Rango finding no routes. Please consider resetting your liquidity sources." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:17 +msgid "No Routes Found." +msgstr "No Routes Found." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:18 +msgid "Reasons why Rango couldn't find a route: low liquidity on token, very low input amount or no routes available for the selected input/output token combination." +msgstr "Reasons why Rango couldn't find a route: low liquidity on token, very low input amount or no routes available for the selected input/output token combination." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:23 +msgid "Bridge Limit Error: Please increase your amount." +msgstr "Bridge Limit Error: Please increase your amount." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:26 +msgid "Bridge Limit Error: Please decrease your amount." +msgstr "Bridge Limit Error: Please decrease your amount." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:31 +msgid "High Price Impact" +msgstr "High Price Impact" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:32 +msgid "Price impact is too high!" +msgstr "Price impact is too high!" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:33 +msgid "The price impact is significantly higher than the allowed amount." +msgstr "The price impact is significantly higher than the allowed amount." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:36 +msgid "Confirm high price impact" +msgstr "Confirm high price impact" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:39 +msgid "Route updated and price impact is too high, try again later!" +msgstr "Route updated and price impact is too high, try again later!" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:44 +msgid "USD Price Unknown" +msgstr "USD Price Unknown" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:45 +msgid "USD Price Unknown, Cannot calculate Price Impact." +msgstr "USD Price Unknown, Cannot calculate Price Impact." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:46 +msgid "USD Price Unknown, Cannot calculate Price Impact. The price impact may be higher than usual. Are you sure to continue the Swap?" +msgstr "USD Price Unknown, Cannot calculate Price Impact. The price impact may be higher than usual. Are you sure to continue the Swap?" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:49 +msgid "Confirm USD Price Unknown" +msgstr "Confirm USD Price Unknown" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:6 +#: widget/embedded/src/pages/Home.tsx:163 +msgid "Swap" +msgstr "Swap" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:7 +msgid "Swap anyway" +msgstr "Swap anyway" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:8 +msgid "The route goes through Ethereum. Continue?" +msgstr "The route goes through Ethereum. Continue?" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:10 +msgid "Route has been updated." +msgstr "Route has been updated." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:12 +msgid "Output amount changed to {newOutputAmount} ({percentageChange}% change)." +msgstr "Output amount changed to {newOutputAmount} ({percentageChange}% change)." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:20 +msgid "Route swappers has been updated." +msgstr "Route swappers has been updated." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:22 +msgid "Route internal coins has been updated." +msgstr "Route internal coins has been updated." + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/ExpandedQuotes/ExpandedQuotes.tsx:53 +#: widget/embedded/src/pages/Routes.tsx:48 +msgid "Routes" +msgstr "Routes" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Inputs/Inputs.tsx:76 +msgid "From" +msgstr "From" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Inputs/Inputs.tsx:118 +msgid "To" +msgstr "To" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:49 +msgid "Light" +msgstr "Light" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:58 +msgid "Dark" +msgstr "Dark" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:67 +msgid "Auto" +msgstr "Auto" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:140 +msgid "Loading failed" +msgstr "Loading failed" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:156 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:41 +msgid "Bridges" +msgstr "Bridges" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:174 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:41 +msgid "Exchanges" +msgstr "Exchanges" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:195 +#: widget/embedded/src/pages/CustomTokensPage.tsx:90 +msgid "Custom Tokens" +msgstr "Custom Tokens" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:214 +#: widget/embedded/src/pages/LanguagePage.tsx:43 +msgid "Language" +msgstr "Language" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:235 +msgid "Infinite approval" +msgstr "Infinite approval" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:246 +msgid "Enabling the 'Infinite approval' mode grants unrestricted access to underlying smart contracts, allowing them to utilize the approved token amount without limitations." +msgstr "Enabling the 'Infinite approval' mode grants unrestricted access to underlying smart contracts, allowing them to utilize the approved token amount without limitations." + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:266 +msgid "Theme" +msgstr "Theme" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:39 +msgid "Duplicate Token" +msgstr "Duplicate Token" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:40 +msgid "The address you entered is duplicate, please enter a new address." +msgstr "The address you entered is duplicate, please enter a new address." + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:46 +msgid "Token Already Exists" +msgstr "Token Already Exists" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:47 +msgid "There's no need to add this token again because it already exists and is supported by us." +msgstr "There's no need to add this token again because it already exists and is supported by us." + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:53 +msgid "Token Not Found" +msgstr "Token Not Found" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:54 +msgid "Sorry, no token was found on {blockchain} chain with the provided address. please make sure you have entered the right token address." +msgstr "Sorry, no token was found on {blockchain} chain with the provided address. please make sure you have entered the right token address." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:78 +msgid "Network Error" +msgstr "Network Error" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:109 +#: widget/embedded/src/pages/CustomTokensPage.tsx:149 +msgid "Add Custom Token" +msgstr "Add Custom Token" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:127 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:128 +msgid "Select chain" +msgstr "Select chain" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:132 +msgid "Enter Address" +msgstr "Enter Address" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:139 +msgid "Enter token address" +msgstr "Enter token address" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:176 +msgid "Failed Network, Please retry." +msgstr "Failed Network, Please retry." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:192 +msgid "Add another custom token" +msgstr "Add another custom token" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:236 +msgid "Confirm Swap" +msgstr "Confirm Swap" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:254 +msgid "Start Swap" +msgstr "Start Swap" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:282 +msgid "You get" +msgstr "You get" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:102 +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:90 +msgid "Search Token" +msgstr "Search Token" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:134 +msgid "No custom tokens" +msgstr "No custom tokens" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:135 +msgid "press the button to add your custom token" +msgstr "press the button to add your custom token" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:158 +msgid "Delete Custom Token" +msgstr "Delete Custom Token" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:160 +msgid "Are you sure you want to Delete this Token?" +msgstr "Are you sure you want to Delete this Token?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:59 +msgid "Complete" +msgstr "Complete" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:63 +msgid "Running" +msgstr "Running" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:65 +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:8 +msgid "Failed" +msgstr "Failed" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:149 +msgid "Clear" +msgstr "Clear" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:161 +msgid "Search Transaction" +msgstr "Search Transaction" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:187 +msgid "No transactions" +msgstr "No transactions" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:194 +msgid "Your transaction history is stored locally and will appear here after you start a swap" +msgstr "Your transaction history is stored locally and will appear here after you start a swap" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:218 +msgid "Clear Transaction History" +msgstr "Clear Transaction History" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:222 +msgid "Proceeding will remove all successful and failed transactions from the widget. Do you want to continue?" +msgstr "Proceeding will remove all successful and failed transactions from the widget. Do you want to continue?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:229 +msgid "Note: This does not erase your transaction history on the chain; it only removes them here." +msgstr "Note: This does not erase your transaction history on the chain; it only removes them here." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:243 +msgid "Yes, Clear the history" +msgstr "Yes, Clear the history" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LanguagePage.tsx:56 +msgid "language" +msgstr "language" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:121 +msgid "Deselect all" +msgstr "Deselect all" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:121 +msgid "Select all" +msgstr "Select all" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:133 +msgid "Search {sourceType}" +msgstr "Search {sourceType}" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectBlockchainPage.tsx:60 +msgid "Search Chain" +msgstr "Search Chain" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:67 +msgid "Source" +msgstr "Source" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:68 +msgid "Destination" +msgstr "Destination" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:74 +msgid "Swap {type}" +msgstr "Swap {type}" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SettingsPage.tsx:45 +msgid "Currently, you're in campaign mode with restrictions on liquidity sources. Would you like to switch out of this mode and make use of all available liquidity sources?" +msgstr "Currently, you're in campaign mode with restrictions on liquidity sources. Would you like to switch out of this mode and make use of all available liquidity sources?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SwapDetailsPage.tsx:27 +msgid "The request ID is necessary to display the swap details." +msgstr "The request ID is necessary to display the swap details." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/WalletsPage.tsx:67 +#: widget/ui/src/containers/ConnectWalletsModal/ConnectWalletsModal.tsx:15 +msgid "Connect Wallets" +msgstr "Connect Wallets" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/WalletsPage.tsx:82 +msgid "Choose a wallet to connect." +msgstr "Choose a wallet to connect." + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:25 +msgid "This week" +msgstr "This week" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:32 +msgid "This month" +msgstr "This month" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:39 +msgid "This year" +msgstr "This year" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:129 +msgid "Required: >= {min} {symbol}" +msgstr "Required: >= {min} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:142 +msgid "Required: > {min} {symbol}" +msgstr "Required: > {min} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:157 +msgid "Required: <= {max} {symbol}" +msgstr "Required: <= {max} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:170 +msgid "Required: < {max} {symbol}" +msgstr "Required: < {max} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:601 +msgid " for network fee" +msgstr " for network fee" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:604 +msgid " for swap" +msgstr " for swap" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:607 +msgid " for input and network fee" +msgstr " for input and network fee" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:609 +msgid "Needs ≈ {requiredAmount} {symbol}{reason}, but you have {currentAmount} {symbol} in your {blockchain} wallet." +msgstr "Needs ≈ {requiredAmount} {symbol}{reason}, but you have {currentAmount} {symbol} in your {blockchain} wallet." + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:669 +msgid "Waiting for connecting wallet" +msgstr "Waiting for connecting wallet" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:673 +msgid "Waiting for other running tasks to be finished" +msgstr "Waiting for other running tasks to be finished" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:676 +msgid "Waiting for changing wallet network" +msgstr "Waiting for changing wallet network" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:6 +msgid "Sunday" +msgstr "Sunday" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:7 +msgid "Monday" +msgstr "Monday" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:8 +msgid "Tuesday" +msgstr "Tuesday" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:9 +msgid "Wednesday" +msgstr "Wednesday" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:10 +msgid "Thursday" +msgstr "Thursday" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:11 +msgid "Friday" +msgstr "Friday" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:12 +msgid "Saturday" +msgstr "Saturday" + +#. js-lingui-explicit-id +#: widget/ui/src/components/BottomLogo/BottomLogo.tsx:14 +msgid "Powered By" +msgstr "Powered By" + +#. js-lingui-explicit-id +#: widget/ui/src/components/FullExpandedQuote/FullExpandedQuote.Tooltip.tsx:37 +msgid "Aggregated Transaction" +msgstr "Aggregated Transaction" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SelectableCategoryList/SelectableCategoryList.tsx:63 +msgid "{blockchainCategory}" +msgstr "{blockchainCategory}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/StepDetails/StepDetails.tsx:75 +#: widget/ui/src/components/StepDetails/StepDetails.tsx:102 +msgid "Swap on {fromChain} via {swapper}" +msgstr "Swap on {fromChain} via {swapper}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/StepDetails/StepDetails.tsx:109 +msgid "Bridge to {toChain} via {swapper}" +msgstr "Bridge to {toChain} via {swapper}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:10 +msgid "Completed" +msgstr "Completed" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:12 +msgid "In progress" +msgstr "In progress" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapToken.tsx:122 +msgid "Waiting for bridge transaction" +msgstr "Waiting for bridge transaction" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:12 +msgid "Connected" +msgstr "Connected" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:13 +msgid "Disconnect" +msgstr "Disconnect" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:18 +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:19 +msgid "Install" +msgstr "Install" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:24 +msgid "Connecting ..." +msgstr "Connecting ..." + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:25 +msgid "Connecting" +msgstr "Connecting" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:30 +msgid "Disconnected" +msgstr "Disconnected" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:34 +msgid "you need to pass a correct state to Wallet." +msgstr "you need to pass a correct state to Wallet." + +#. js-lingui-explicit-id +#: widget/ui/src/containers/Notifications/NotificationNotFound.tsx:15 +msgid "There are no notifications." +msgstr "There are no notifications." + +#. js-lingui-explicit-id +#: widget/ui/src/containers/Notifications/Notifications.tsx:39 +msgid "Clear all" +msgstr "Clear all" + +#. js-lingui-explicit-id +#: widget/ui/src/containers/SwapInput/SwapInput.tsx:65 +msgid "Balance" +msgstr "Balance" + +#. js-lingui-explicit-id +#: widget/ui/src/containers/SwapInput/SwapInput.tsx:73 +msgid "Max" +msgstr "Max" diff --git a/translations/es.po b/translations/es.po new file mode 100644 index 0000000000..512a8082fe --- /dev/null +++ b/translations/es.po @@ -0,0 +1,1339 @@ +msgid "" +msgstr "" +"POT-Creation-Date: 2023-11-06 17:24+0330\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: @lingui/cli\n" +"Language: es\n" +"Project-Id-Version: rango\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2024-11-27 15:57\n" +"Last-Translator: \n" +"Language-Team: Spanish\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Crowdin-Project: rango\n" +"X-Crowdin-Project-ID: 622238\n" +"X-Crowdin-Language: es-ES\n" +"X-Crowdin-File: en.po\n" +"X-Crowdin-File-ID: 30\n" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SameTokensWarning/SameTokensWarning.tsx:21 +msgid "No Routes Found" +msgstr "No se encontraron rutas" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SameTokensWarning/SameTokensWarning.tsx:25 +msgid "You cannot use the same token for From and To." +msgstr "No puedes utilizar el mismo token para Desde y Hasta." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:41 +#: widget/embedded/src/components/TokenList/TokenList.tsx:286 +#: widget/embedded/src/pages/HistoryPage.tsx:186 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:143 +msgid "No results found" +msgstr "No hay resultados" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:42 +#: widget/embedded/src/components/TokenList/TokenList.tsx:287 +#: widget/embedded/src/pages/HistoryPage.tsx:193 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:144 +msgid "Try using different keywords" +msgstr "Intenta usar diferentes palabras clave" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:72 +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:46 +#: widget/embedded/src/pages/SelectBlockchainPage.tsx:42 +#: widget/ui/src/containers/SwapInput/TokenSection.tsx:61 +msgid "Select Chain" +msgstr "Seleccionar cadena" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:66 +msgid "All" +msgstr "Todos" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:100 +msgid "More +{count}" +msgstr "Más +{count}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabAlert/ActivateTabAlert.tsx:17 +msgid "Activate this tab" +msgstr "Activar esta pestaña" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabAlert/ActivateTabAlert.tsx:22 +msgid "Another tab is open and handles transactions." +msgstr "Otra pestaña es abierta y maneja transacciones." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:20 +msgid "Activate current tab" +msgstr "Activar pestaña actual" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:22 +msgid "Currently, some transactions are running and being handled by other browser tab. If you activate this tab, all transactions that are already in the transaction sign step will expire." +msgstr "Actualmente, algunas transacciones se están ejecutando y siendo manejadas por otra pestaña del navegador. Si activa esta pestaña, todas las transacciones que ya están en el paso del signo de transacción caducarán." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:33 +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:349 +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:152 +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:33 +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:116 +msgid "Confirm" +msgstr "Confirmar" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:365 +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:447 +msgid "Your {blockchainName} wallets" +msgstr "Tus billeteras {blockchainName}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:384 +msgid "Insufficient account balance" +msgstr "Saldo insuficiente de la cuenta" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:394 +msgid "Proceed anyway" +msgstr "Proceda de todos modos" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:456 +msgid "You need to connect a {blockchainName} wallet." +msgstr "Necesitas conectar un monedero {blockchainName}." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/WalletList.tsx:143 +msgid "Add {chain} chain" +msgstr "Añadir cadena {chain}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/WalletList.tsx:244 +msgid "Show more wallets" +msgstr "Mostrar más carteras" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:113 +msgid "Send to a different address" +msgstr "Enviar a una dirección diferente" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:129 +msgid "Enter {blockchainName} address" +msgstr "Introduzca la dirección {blockchainName}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:147 +msgid "Address {destination} doesn't match the blockchain address pattern." +msgstr "La dirección {destination} no coincide con el patrón de dirección de la cadena de bloques." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:59 +msgid "via" +msgstr "vía" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:74 +msgid "This token doesn't appear on the active token list(s). Make sure this is the token that you want to trade." +msgstr "Este token no aparece en la lista de tokens activa. Asegúrese de que es el token que desea intercambiar." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:89 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:164 +msgid "Import" +msgstr "Importar" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/FilterSelector/FilterSelectorContent.tsx:26 +msgid "Status" +msgstr "Estado" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/FilterSelector/FilterSelectorContent.tsx:33 +#: widget/embedded/src/components/NoResult/NoResult.helpers.ts:37 +#: widget/embedded/src/pages/SettingsPage.tsx:55 +msgid "Reset" +msgstr "Reset" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/CancelButton.tsx:18 +msgid "Cancel" +msgstr "Cancelar" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:46 +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:34 +msgid "Refresh" +msgstr "Refrescar" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:63 +#: widget/ui/src/containers/Notifications/Notifications.tsx:35 +msgid "Notifications" +msgstr "Notificaciones" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:79 +#: widget/embedded/src/pages/SettingsPage.tsx:38 +msgid "Settings" +msgstr "Ajustes" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:93 +#: widget/embedded/src/pages/HistoryPage.tsx:139 +msgid "History" +msgstr "Historial" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/WalletButton.tsx:22 +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:16 +#: widget/embedded/src/constants/messages.ts:5 +msgid "Connect Wallet" +msgstr "Conectar cartera" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HistoryGroupedList/HistoryGroupedList.tsx:118 +#: widget/embedded/src/utils/date.ts:18 +#: widget/embedded/src/utils/time.ts:22 +msgid "Today" +msgstr "Hoy" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/LoadingSwapDetails/LoadingSwapDetails.tsx:20 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:424 +msgid "Swaps steps" +msgstr "Intercambiar pasos" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/NoResult/NoResult.helpers.ts:25 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:191 +msgid "Retry" +msgstr "Reintentar" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:149 +msgid "Slippage Error" +msgstr "Error de deslizamiento" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:150 +msgid "Slippage Warning" +msgstr "Advertencia de deslizamiento" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:153 +msgid "Bridge Limit Error" +msgstr "Error de límite del puente" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:240 +msgid "Yours: {amount} {symbol}" +msgstr "Tu: {amount} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:261 +msgid "Minimum required slippage: {minRequiredSlippage}" +msgstr "Mínimo deslizamiento requerido: {minRequiredSlippage}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:282 +msgid "Yours: {userSlippage}" +msgstr "Tu: {userSlippage}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:395 +msgid "See All Routes" +msgstr "Ver todas las rutas" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:81 +msgid "View more info" +msgstr "Ver más información" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:91 +msgid "Gas & Fee Explanation" +msgstr "Explicación de gas y comisión" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:107 +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:103 +msgid "Details" +msgstr "Detalles" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:146 +msgid "Total Payable Fee" +msgstr "Tarifa total a pagar" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:166 +msgid "Hide non-payable fees" +msgstr "Ocultar tarifas no pagables" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:167 +msgid "Show non-payable fees" +msgstr "Mostrar tarifas no pagables" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:177 +msgid "Description" +msgstr "Descripción" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:181 +msgid "The following fees are considered in the transaction output and\n" +" you won’t need to pay extra gas for them." +msgstr "Las siguientes comisiones se consideran en la salida de la transacción y\n" +" no necesitarás pagar gas adicional por ellas." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteSummary.tsx:25 +msgid "Swap input" +msgstr "Swap input" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteSummary.tsx:44 +msgid "Estimated output" +msgstr "Salida estimada" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteTrigger.tsx:65 +msgid "Via:" +msgstr "Vía:" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteTrigger.tsx:150 +msgid "Chains:" +msgstr "Cadenas:" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/Quotes.tsx:77 +msgid "Sort by" +msgstr "Ordenar por" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:17 +msgid "Smart Routing" +msgstr "Ruta inteligente" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:21 +msgid "Lowest Fee" +msgstr "Tarifa más baja" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:25 +msgid "Fastest Transfer" +msgstr "Transferencia más rápida" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:29 +msgid "Maximum Return" +msgstr "Devolución máxima" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:33 +msgid "Maximum Output" +msgstr "Salida máxima" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:43 +msgid "Swapping" +msgstr "Swapping" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:51 +msgid "Gas cost" +msgstr "Coste de gas" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:59 +msgid "Receiving" +msgstr "Recibiendo" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:67 +msgid "Price impact" +msgstr "Impacto del precio" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:35 +msgid "You need to increase slippage to at least {minRequiredSlippage} for this route." +msgstr "Necesitas aumentar el deslizamiento a al menos {minRequiredSlippage} para esta ruta." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:59 +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:61 +msgid "We recommend you to increase slippage to at least {minRequiredSlippage} for this route." +msgstr "Te recomendamos que aumentes el deslizamiento a al menos {minRequiredSlippage} para esta ruta." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:68 +msgid "Caution, your slippage is high." +msgstr "Precaución, tu deslizamiento es alto." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.tsx:78 +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.Warning.tsx:26 +msgid "Change" +msgstr "Cambiar" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:42 +msgid "Change settings" +msgstr "Cambiar configuración" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:52 +msgid "High slippage" +msgstr "Deslizar alto" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:53 +msgid "Low slippage" +msgstr "Deslizamiento bajo" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:57 +msgid " Caution, your slippage is high (={userSlippage}). Your trade may be front run." +msgstr " Precaución, su deslizamiento es alto (={userSlippage}). Su operación puede ser inicial." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:78 +msgid "Confirm anyway" +msgstr "Confirmar de todos modos" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:22 +msgid "Something went wrong" +msgstr "Algo salió mal" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:24 +msgid "Something went wrong. Please refresh the app." +msgstr "Algo salió mal. Por favor, actualiza la aplicación." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/Slippage.tsx:38 +msgid "Slippage tolerance per swap" +msgstr "Tolerancia de deslizamiento por intercambio" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/Slippage.tsx:91 +msgid "Custom" +msgstr "Personalizado" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:11 +msgid "Your transaction will be reverted if the price changes unfavorably by more than this percentage." +msgstr "Su transacción será revertida si el precio cambia desfavorablemente más de este porcentaje." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:16 +#: widget/embedded/src/containers/Settings/Lists.tsx:245 +msgid "Warning" +msgstr "Advertencia" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:17 +msgid "This setting is applied to each step (e.g. 1Inch, Thorchain, etc.), meaning only that specific step will be reverted, not the entire route." +msgstr "Este ajuste se aplica a cada paso (por ejemplo, 1Inch, Thorchain, etc.), lo que significa que sólo se revertirá un paso específico, no toda la ruta." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:25 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:269 +msgid "Swap Details" +msgstr "Detalles de intercambio" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:33 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:312 +msgid "Request ID" +msgstr "ID de Solicitud" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:64 +msgid "Not found" +msgstr "No encontrado" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:65 +msgid "Swap with request ID = {requestId} not found." +msgstr "Intercambio con ID de solicitud = {requestId} no encontrado." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:219 +msgid "You have received {amount} {token} in {conciseAddress} wallet on {chain} chain." +msgstr "Ha recibido {amount} {token} en el monedero {conciseAddress} de la cadena {chain}." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:242 +msgid "Transaction was not sent." +msgstr "La transacción no fue enviada." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:244 +msgid "{amount} {symbol} on {blockchain} remains in your wallet." +msgstr "{amount} {symbol} en {blockchain} permanece en tu cartera." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:281 +msgid "Delete" +msgstr "Eliminar" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:304 +msgid "Try again" +msgstr "Inténtalo de nuevo" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:322 +msgid "Copied To Clipboard" +msgstr "Copiado al portapapeles" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:323 +msgid "Copy Request ID" +msgstr "Copiar ID de Solicitud" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:346 +msgid "View on Rango Explorer" +msgstr "Ver en Rango Explorer" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:355 +msgid "Finished at" +msgstr "Terminado el" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:355 +msgid "Created at" +msgstr "Creado el" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.tsx:50 +msgid "View transaction" +msgstr "Ver transacción" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.Warning.tsx:49 +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:31 +msgid "Connect" +msgstr "Conectar" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:43 +msgid "Swap Successful" +msgstr "Intercambio exitoso" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:71 +msgid "Transaction Failed" +msgstr "Transacción fallida" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:87 +msgid "Done" +msgstr "Hecho" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:100 +msgid "Diagnosis" +msgstr "Diagnóstico" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:112 +msgid "See Details" +msgstr "Ver detalles" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:13 +msgid "Cancel Swap" +msgstr "Cancelar intercambio" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:14 +msgid "Are you sure you want to cancel this swap?" +msgstr "¿Está seguro de que desea cancelar este intercambio?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:23 +msgid "Yes, Cancel it" +msgstr "Sí, cancelarlo" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:32 +#: widget/embedded/src/pages/CustomTokensPage.tsx:181 +msgid "No, Continue" +msgstr "No, continuar" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:13 +msgid "Delete Transaction" +msgstr "Eliminar transacción" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:14 +msgid "Are you sure you want to delete this swap?" +msgstr "¿Está seguro de que desea eliminar este intercambio?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:23 +#: widget/embedded/src/pages/CustomTokensPage.tsx:171 +msgid "Yes, Delete it" +msgstr "Sí, eliminarlo" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:33 +#: widget/embedded/src/pages/HistoryPage.tsx:253 +msgid "No, Cancel" +msgstr "No, cancelar" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:12 +msgid "Change Network" +msgstr "Cambiar red" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:20 +msgid "Network Changed" +msgstr "Red cambiada" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/TokenList/TokenList.tsx:271 +#: widget/ui/src/containers/SwapInput/TokenSection.tsx:54 +msgid "Select Token" +msgstr "Seleccionar token" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:27 +msgid "Wallet Connected" +msgstr "Cartera conectada" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:28 +msgid "Your wallet is connected, you can use it to swap." +msgstr "Su cartera está conectada, puede usarla para intercambiar." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:39 +msgid "Failed to Connect" +msgstr "Error al conectar" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:41 +msgid "Your wallet is not connected. Please try again." +msgstr "Su cartera no está conectada. Por favor, inténtelo de nuevo." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:50 +msgid "Connecting to your wallet" +msgstr "Conectando a su cartera" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:51 +msgid "Click connect in your wallet popup." +msgstr "Haga clic en conectar en su ventana emergente." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:99 +msgid "Select Derivation Path" +msgstr "Seleccionar ruta de derivación" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:100 +msgid "In order to connect to {type}, you must first select a Derivation Path" +msgstr "Para conectarse a {type}, primero debe seleccionar una Ruta de Derivación" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:118 +msgid "Choose Derivation Path Template" +msgstr "Elegir plantilla de ruta de derivación" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:133 +msgid "Enter Path" +msgstr "Introducir ruta" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:134 +msgid "Enter Index" +msgstr "Introducir índice" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:15 +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:18 +msgid "Add {blockchainDisplayName} Chain" +msgstr "Añadir cadena {blockchainDisplayName}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:20 +msgid "Would you like to add the {blockchainDisplayName} experimental chain to your wallet?" +msgstr "¿Quieres añadir la cadena experimental {blockchainDisplayName} a tu cartera?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:22 +msgid "Please approve the experimental chain pop-up in your wallet." +msgstr "Por favor, apruebe la cadena experimental emergente en su cartera." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:30 +msgid "{blockchainDisplayName} Chain Added" +msgstr "Cadena {blockchainDisplayName} añadida" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:34 +msgid "The {blockchainDisplayName} chain has been successfully added to your wallet." +msgstr "La cadena {blockchainDisplayName} se ha añadido correctamente a tu cartera." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:42 +msgid "Request Rejected" +msgstr "Solicitud rechazada" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:43 +msgid "You've rejected adding {blockchainDisplayName} chain to your wallet." +msgstr "Has rechazado añadir la cadena {blockchainDisplayName} a tu cartera." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:70 +msgid "Select chain types" +msgstr "Seleccionar tipos de cadena" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:71 +msgid "This wallet supports multiple chains. Select which chain you'd like to connect to." +msgstr "Esta cartera soporta múltiples cadenas. Selecciona a qué cadena quieres conectar." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:9 +msgid "Failed Network, Please retry your swap." +msgstr "Red fallida, vuelva a intentar su intercambio." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:11 +msgid "Please reset your liquidity sources." +msgstr "Por favor, reinicie sus fuentes de liquidez." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:12 +msgid "You have limited the liquidity sources and this might result in Rango finding no routes. Please consider resetting your liquidity sources." +msgstr "Usted ha limitado las fuentes de liquidez y esto puede resultar en que Rango no encuentre rutas. Por favor considere restablecer sus fuentes de liquidez." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:17 +msgid "No Routes Found." +msgstr "No se encontraron Rutas." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:18 +msgid "Reasons why Rango couldn't find a route: low liquidity on token, very low input amount or no routes available for the selected input/output token combination." +msgstr "Razones por las que Rango no pudo encontrar una ruta: baja liquidez en el token, muy baja cantidad de entrada o ninguna ruta disponible para la combinación de entrada/salida seleccionada." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:23 +msgid "Bridge Limit Error: Please increase your amount." +msgstr "Error en el límite del puente. Por favor, aumente su cantidad." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:26 +msgid "Bridge Limit Error: Please decrease your amount." +msgstr "Error en el límite del puente. Por favor disminuya su cantidad." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:31 +msgid "High Price Impact" +msgstr "Impacto de precios altos" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:32 +msgid "Price impact is too high!" +msgstr "¡El impacto de los precios es demasiado alto!" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:33 +msgid "The price impact is significantly higher than the allowed amount." +msgstr "El impacto de los precios es significativamente más alto que la cantidad permitida." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:36 +msgid "Confirm high price impact" +msgstr "Confirmar alto impacto de precio" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:39 +msgid "Route updated and price impact is too high, try again later!" +msgstr "Ruta actualizada y el impacto de los precios es demasiado alto, inténtalo de nuevo más tarde!" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:44 +msgid "USD Price Unknown" +msgstr "Precio desconocido USD" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:45 +msgid "USD Price Unknown, Cannot calculate Price Impact." +msgstr "Precio USD Desconocido, no se puede calcular el impacto del precio." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:46 +msgid "USD Price Unknown, Cannot calculate Price Impact. The price impact may be higher than usual. Are you sure to continue the Swap?" +msgstr "Precio USD Desconocido, no se puede calcular el impacto del precio. El impacto del precio puede ser mayor de lo habitual. ¿Está seguro de continuar el swap?" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:49 +msgid "Confirm USD Price Unknown" +msgstr "Confirmar el precio de USD desconocido" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:6 +#: widget/embedded/src/pages/Home.tsx:163 +msgid "Swap" +msgstr "Intercambiar" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:7 +msgid "Swap anyway" +msgstr "Intercambiar de todos modos" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:8 +msgid "The route goes through Ethereum. Continue?" +msgstr "La ruta pasa por Ethereum. ¿Continuar?" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:10 +msgid "Route has been updated." +msgstr "La ruta ha sido actualizada." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:12 +msgid "Output amount changed to {newOutputAmount} ({percentageChange}% change)." +msgstr "Cantidad de salida cambiada a {newOutputAmount} ( cambio{percentageChange}%)." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:20 +msgid "Route swappers has been updated." +msgstr "Los swappers de rutas han sido actualizados." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:22 +msgid "Route internal coins has been updated." +msgstr "Se han actualizado las monedas internas de la ruta." + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/ExpandedQuotes/ExpandedQuotes.tsx:53 +#: widget/embedded/src/pages/Routes.tsx:48 +msgid "Routes" +msgstr "Rutas" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Inputs/Inputs.tsx:76 +msgid "From" +msgstr "De" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Inputs/Inputs.tsx:118 +msgid "To" +msgstr "A" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:49 +msgid "Light" +msgstr "Claro" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:58 +msgid "Dark" +msgstr "Oscuro" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:67 +msgid "Auto" +msgstr "Auto" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:140 +msgid "Loading failed" +msgstr "Error al cargar" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:156 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:41 +msgid "Bridges" +msgstr "Puentes" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:174 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:41 +msgid "Exchanges" +msgstr "Intercambios" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:195 +#: widget/embedded/src/pages/CustomTokensPage.tsx:90 +msgid "Custom Tokens" +msgstr "Tokens personalizados" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:214 +#: widget/embedded/src/pages/LanguagePage.tsx:43 +msgid "Language" +msgstr "Idioma" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:235 +msgid "Infinite approval" +msgstr "Aprobación infinita" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:246 +msgid "Enabling the 'Infinite approval' mode grants unrestricted access to underlying smart contracts, allowing them to utilize the approved token amount without limitations." +msgstr "Habilitar el modo 'Aprobación infinita' otorga acceso sin restricciones a los contratos inteligentes subyacentes, permitiéndoles utilizar la cantidad de token aprobada sin limitaciones." + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:266 +msgid "Theme" +msgstr "Tema" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:39 +msgid "Duplicate Token" +msgstr "Duplicate Token" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:40 +msgid "The address you entered is duplicate, please enter a new address." +msgstr "La dirección introducida es duplicada, por favor ingrese una nueva dirección." + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:46 +msgid "Token Already Exists" +msgstr "El token ya existe" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:47 +msgid "There's no need to add this token again because it already exists and is supported by us." +msgstr "No hay necesidad de añadir este token de nuevo porque ya existe y está soportado por nosotros." + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:53 +msgid "Token Not Found" +msgstr "Token no encontrado" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:54 +msgid "Sorry, no token was found on {blockchain} chain with the provided address. please make sure you have entered the right token address." +msgstr "Lo sentimos, no se ha encontrado ningún token en la cadena {blockchain} con la dirección proporcionada. Por favor, asegúrese de que ha introducido la dirección correcta del token." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:78 +msgid "Network Error" +msgstr "Error de red" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:109 +#: widget/embedded/src/pages/CustomTokensPage.tsx:149 +msgid "Add Custom Token" +msgstr "Añadir token personalizado" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:127 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:128 +msgid "Select chain" +msgstr "Seleccionar cadena" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:132 +msgid "Enter Address" +msgstr "Introducir dirección" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:139 +msgid "Enter token address" +msgstr "Introducir dirección de token" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:176 +msgid "Failed Network, Please retry." +msgstr "Red fallida, vuelva a intentarlo." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:192 +msgid "Add another custom token" +msgstr "Añadir otro token personalizado" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:236 +msgid "Confirm Swap" +msgstr "Confirmar intercambio" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:254 +msgid "Start Swap" +msgstr "Iniciar intercambio" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:282 +msgid "You get" +msgstr "Obtienes" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:102 +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:90 +msgid "Search Token" +msgstr "Buscar token" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:134 +msgid "No custom tokens" +msgstr "No hay tokens personalizados" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:135 +msgid "press the button to add your custom token" +msgstr "pulsa el botón para añadir tu token personalizado" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:158 +msgid "Delete Custom Token" +msgstr "Eliminar token personalizado" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:160 +msgid "Are you sure you want to Delete this Token?" +msgstr "¿Está seguro de que desea eliminar este token?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:59 +msgid "Complete" +msgstr "Complete" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:63 +msgid "Running" +msgstr "Ejecutando" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:65 +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:8 +msgid "Failed" +msgstr "Fallo" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:149 +msgid "Clear" +msgstr "Claro" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:161 +msgid "Search Transaction" +msgstr "Buscar transacción" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:187 +msgid "No transactions" +msgstr "No hay transacciones" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:194 +msgid "Your transaction history is stored locally and will appear here after you start a swap" +msgstr "Su historial de transacciones se almacena localmente y aparecerá aquí después de iniciar un intercambio" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:218 +msgid "Clear Transaction History" +msgstr "Borrar historial de transacciones" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:222 +msgid "Proceeding will remove all successful and failed transactions from the widget. Do you want to continue?" +msgstr "Continuar eliminará todas las transacciones exitosas y fallidas del widget. ¿Desea continuar?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:229 +msgid "Note: This does not erase your transaction history on the chain; it only removes them here." +msgstr "Nota: Esto no borra tu historial de transacciones en la cadena; sólo los elimina aquí." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:243 +msgid "Yes, Clear the history" +msgstr "Sí, borrar el historial" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LanguagePage.tsx:56 +msgid "language" +msgstr "idioma" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:121 +msgid "Deselect all" +msgstr "Deseleccionar todo" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:121 +msgid "Select all" +msgstr "Seleccionar todo" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:133 +msgid "Search {sourceType}" +msgstr "Buscar {sourceType}" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectBlockchainPage.tsx:60 +msgid "Search Chain" +msgstr "Buscar Cadena" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:67 +msgid "Source" +msgstr "Fuente" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:68 +msgid "Destination" +msgstr "Destino" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:74 +msgid "Swap {type}" +msgstr "Intercambiar {type}" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SettingsPage.tsx:45 +msgid "Currently, you're in campaign mode with restrictions on liquidity sources. Would you like to switch out of this mode and make use of all available liquidity sources?" +msgstr "Actualmente estás en modo campaña con restricciones sobre las fuentes de liquidez. ¿Le gustaría desconectar de este modo y hacer uso de todas las fuentes de liquidez disponibles?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SwapDetailsPage.tsx:27 +msgid "The request ID is necessary to display the swap details." +msgstr "El ID de solicitud es necesario para mostrar los detalles del intercambio." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/WalletsPage.tsx:67 +#: widget/ui/src/containers/ConnectWalletsModal/ConnectWalletsModal.tsx:15 +msgid "Connect Wallets" +msgstr "Conectar billeteras" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/WalletsPage.tsx:82 +msgid "Choose a wallet to connect." +msgstr "Elija una cartera para conectar." + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:25 +msgid "This week" +msgstr "Esta semana" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:32 +msgid "This month" +msgstr "Este mes" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:39 +msgid "This year" +msgstr "Este año" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:129 +msgid "Required: >= {min} {symbol}" +msgstr "Requerido: >= {min} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:142 +msgid "Required: > {min} {symbol}" +msgstr "Requerido: > {min} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:157 +msgid "Required: <= {max} {symbol}" +msgstr "Requerido: <= {max} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:170 +msgid "Required: < {max} {symbol}" +msgstr "Requerido: < {max} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:601 +msgid " for network fee" +msgstr " por comisión de red" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:604 +msgid " for swap" +msgstr " para intercambio" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:607 +msgid " for input and network fee" +msgstr " por entrada y tarifa de red" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:609 +msgid "Needs ≈ {requiredAmount} {symbol}{reason}, but you have {currentAmount} {symbol} in your {blockchain} wallet." +msgstr "Necesitas {requiredAmount} {symbol}{reason}, pero tienes {currentAmount} {symbol} en tu monedero {blockchain}." + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:669 +msgid "Waiting for connecting wallet" +msgstr "Esperando por conectar cartera" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:673 +msgid "Waiting for other running tasks to be finished" +msgstr "Esperando a que finalicen otras tareas en ejecución" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:676 +msgid "Waiting for changing wallet network" +msgstr "Esperando a cambiar la red del monedero" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:6 +msgid "Sunday" +msgstr "Domingo" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:7 +msgid "Monday" +msgstr "Lunes" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:8 +msgid "Tuesday" +msgstr "Martes" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:9 +msgid "Wednesday" +msgstr "Miércoles" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:10 +msgid "Thursday" +msgstr "Jueves" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:11 +msgid "Friday" +msgstr "Viernes" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:12 +msgid "Saturday" +msgstr "Sábado" + +#. js-lingui-explicit-id +#: widget/ui/src/components/BottomLogo/BottomLogo.tsx:14 +msgid "Powered By" +msgstr "Desarrollado por" + +#. js-lingui-explicit-id +#: widget/ui/src/components/FullExpandedQuote/FullExpandedQuote.Tooltip.tsx:37 +msgid "Aggregated Transaction" +msgstr "Transacción agregada" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SelectableCategoryList/SelectableCategoryList.tsx:63 +msgid "{blockchainCategory}" +msgstr "{blockchainCategory}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/StepDetails/StepDetails.tsx:75 +#: widget/ui/src/components/StepDetails/StepDetails.tsx:102 +msgid "Swap on {fromChain} via {swapper}" +msgstr "Intercambiar por {fromChain} vía {swapper}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/StepDetails/StepDetails.tsx:109 +msgid "Bridge to {toChain} via {swapper}" +msgstr "Puente a {toChain} a través de {swapper}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:10 +msgid "Completed" +msgstr "Completado" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:12 +msgid "In progress" +msgstr "En progreso" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapToken.tsx:122 +msgid "Waiting for bridge transaction" +msgstr "Esperando una transacción de puente" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:12 +msgid "Connected" +msgstr "Conectado" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:13 +msgid "Disconnect" +msgstr "Desconectar" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:18 +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:19 +msgid "Install" +msgstr "Instalar" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:24 +msgid "Connecting ..." +msgstr "Conectando..." + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:25 +msgid "Connecting" +msgstr "Conectando" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:30 +msgid "Disconnected" +msgstr "Desconectado" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:34 +msgid "you need to pass a correct state to Wallet." +msgstr "necesita pasar un estado correcto a Wallet." + +#. js-lingui-explicit-id +#: widget/ui/src/containers/Notifications/NotificationNotFound.tsx:15 +msgid "There are no notifications." +msgstr "No hay notificaciones." + +#. js-lingui-explicit-id +#: widget/ui/src/containers/Notifications/Notifications.tsx:39 +msgid "Clear all" +msgstr "Limpiar todo" + +#. js-lingui-explicit-id +#: widget/ui/src/containers/SwapInput/SwapInput.tsx:65 +msgid "Balance" +msgstr "Saldo" + +#. js-lingui-explicit-id +#: widget/ui/src/containers/SwapInput/SwapInput.tsx:73 +msgid "Max" +msgstr "Máx" + diff --git a/translations/fi.po b/translations/fi.po new file mode 100644 index 0000000000..9cd8e97c12 --- /dev/null +++ b/translations/fi.po @@ -0,0 +1,1339 @@ +msgid "" +msgstr "" +"POT-Creation-Date: 2023-11-06 17:24+0330\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: @lingui/cli\n" +"Language: fi\n" +"Project-Id-Version: rango\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2024-11-27 15:57\n" +"Last-Translator: \n" +"Language-Team: Finnish\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Crowdin-Project: rango\n" +"X-Crowdin-Project-ID: 622238\n" +"X-Crowdin-Language: fi\n" +"X-Crowdin-File: en.po\n" +"X-Crowdin-File-ID: 30\n" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SameTokensWarning/SameTokensWarning.tsx:21 +msgid "No Routes Found" +msgstr "Reittejä ei löytynyt" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SameTokensWarning/SameTokensWarning.tsx:25 +msgid "You cannot use the same token for From and To." +msgstr "Et voi käyttää samaa merkkiä Lähteestä ja Vastaanottajalle." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:41 +#: widget/embedded/src/components/TokenList/TokenList.tsx:286 +#: widget/embedded/src/pages/HistoryPage.tsx:186 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:143 +msgid "No results found" +msgstr "Tuloksia ei löytynyt" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:42 +#: widget/embedded/src/components/TokenList/TokenList.tsx:287 +#: widget/embedded/src/pages/HistoryPage.tsx:193 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:144 +msgid "Try using different keywords" +msgstr "Kokeile käyttää eri avainsanoja" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:72 +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:46 +#: widget/embedded/src/pages/SelectBlockchainPage.tsx:42 +#: widget/ui/src/containers/SwapInput/TokenSection.tsx:61 +msgid "Select Chain" +msgstr "Valitse Ketju" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:66 +msgid "All" +msgstr "Kaikki" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:100 +msgid "More +{count}" +msgstr "Enemmän +{count}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabAlert/ActivateTabAlert.tsx:17 +msgid "Activate this tab" +msgstr "Aktivoi tämä välilehti" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabAlert/ActivateTabAlert.tsx:22 +msgid "Another tab is open and handles transactions." +msgstr "Toinen välilehti on avoin ja käsittelee tapahtumia." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:20 +msgid "Activate current tab" +msgstr "Aktivoi nykyinen välilehti" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:22 +msgid "Currently, some transactions are running and being handled by other browser tab. If you activate this tab, all transactions that are already in the transaction sign step will expire." +msgstr "Tällä hetkellä jotkin tapahtumat ovat käynnissä ja niitä käsitellään muilla selainvälilehdillä. Jos aktivoit tämän välilehden, kaikki tapahtumat, jotka ovat jo tapahtumakirjautumisvaiheessa, vanhenevat." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:33 +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:349 +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:152 +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:33 +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:116 +msgid "Confirm" +msgstr "Vahvista" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:365 +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:447 +msgid "Your {blockchainName} wallets" +msgstr "{blockchainName} lompakkoasi" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:384 +msgid "Insufficient account balance" +msgstr "Tilin saldo ei riitä" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:394 +msgid "Proceed anyway" +msgstr "Jatka joka tapauksessa" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:456 +msgid "You need to connect a {blockchainName} wallet." +msgstr "Sinun on yhdistettävä {blockchainName} lompakko." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/WalletList.tsx:143 +msgid "Add {chain} chain" +msgstr "Lisää {chain} ketju" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/WalletList.tsx:244 +msgid "Show more wallets" +msgstr "Näytä lisää lompakkoja" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:113 +msgid "Send to a different address" +msgstr "Lähetä toiseen osoitteeseen" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:129 +msgid "Enter {blockchainName} address" +msgstr "Syötä {blockchainName} osoite" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:147 +msgid "Address {destination} doesn't match the blockchain address pattern." +msgstr "Osoite {destination} ei vastaa lohkoketjun osoitekuviota." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:59 +msgid "via" +msgstr "kautta" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:74 +msgid "This token doesn't appear on the active token list(s). Make sure this is the token that you want to trade." +msgstr "Tämä tunnus ei näy aktiivisessa token listassa. Varmista, että tämä on token jonka haluat vaihtaa." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:89 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:164 +msgid "Import" +msgstr "Tuo" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/FilterSelector/FilterSelectorContent.tsx:26 +msgid "Status" +msgstr "Tila" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/FilterSelector/FilterSelectorContent.tsx:33 +#: widget/embedded/src/components/NoResult/NoResult.helpers.ts:37 +#: widget/embedded/src/pages/SettingsPage.tsx:55 +msgid "Reset" +msgstr "Reset" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/CancelButton.tsx:18 +msgid "Cancel" +msgstr "Peruuta" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:46 +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:34 +msgid "Refresh" +msgstr "Päivitä" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:63 +#: widget/ui/src/containers/Notifications/Notifications.tsx:35 +msgid "Notifications" +msgstr "Ilmoitukset" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:79 +#: widget/embedded/src/pages/SettingsPage.tsx:38 +msgid "Settings" +msgstr "Asetukset" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:93 +#: widget/embedded/src/pages/HistoryPage.tsx:139 +msgid "History" +msgstr "Historia" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/WalletButton.tsx:22 +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:16 +#: widget/embedded/src/constants/messages.ts:5 +msgid "Connect Wallet" +msgstr "Yhdistä Lompakko" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HistoryGroupedList/HistoryGroupedList.tsx:118 +#: widget/embedded/src/utils/date.ts:18 +#: widget/embedded/src/utils/time.ts:22 +msgid "Today" +msgstr "Tänään" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/LoadingSwapDetails/LoadingSwapDetails.tsx:20 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:424 +msgid "Swaps steps" +msgstr "Swapin vaiheet" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/NoResult/NoResult.helpers.ts:25 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:191 +msgid "Retry" +msgstr "Yritä Uudelleen" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:149 +msgid "Slippage Error" +msgstr "Virhe lipasivulla" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:150 +msgid "Slippage Warning" +msgstr "lipasivun Varoitus" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:153 +msgid "Bridge Limit Error" +msgstr "Sillan Rajoitus Virhe" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:240 +msgid "Yours: {amount} {symbol}" +msgstr "Sinun: {amount} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:261 +msgid "Minimum required slippage: {minRequiredSlippage}" +msgstr "Pienin vaadittu slippa: {minRequiredSlippage}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:282 +msgid "Yours: {userSlippage}" +msgstr "Sinut: {userSlippage}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:395 +msgid "See All Routes" +msgstr "Katso Kaikki Reitit" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:81 +msgid "View more info" +msgstr "Näytä lisätiedot" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:91 +msgid "Gas & Fee Explanation" +msgstr "Kaasun Ja Maksun Selitys" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:107 +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:103 +msgid "Details" +msgstr "Yksityiskohdat" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:146 +msgid "Total Payable Fee" +msgstr "Maksettu Maksu Yhteensä" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:166 +msgid "Hide non-payable fees" +msgstr "Piilota muut kuin maksetut maksut" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:167 +msgid "Show non-payable fees" +msgstr "Näytä maksamattomat maksut" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:177 +msgid "Description" +msgstr "Kuvaus" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:181 +msgid "The following fees are considered in the transaction output and\n" +" you won’t need to pay extra gas for them." +msgstr "Seuraavat maksut otetaan huomioon liiketoimen tuotos, ja\n" +" sinun ei tarvitse maksaa ylimääräistä kaasua niistä." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteSummary.tsx:25 +msgid "Swap input" +msgstr "Swap input" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteSummary.tsx:44 +msgid "Estimated output" +msgstr "Arvioitu tuotos" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteTrigger.tsx:65 +msgid "Via:" +msgstr "Via:" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteTrigger.tsx:150 +msgid "Chains:" +msgstr "Ketjut:" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/Quotes.tsx:77 +msgid "Sort by" +msgstr "Järjestä" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:17 +msgid "Smart Routing" +msgstr "Älykäs Reititys" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:21 +msgid "Lowest Fee" +msgstr "Alin Maksu" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:25 +msgid "Fastest Transfer" +msgstr "Nopein Siirto" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:29 +msgid "Maximum Return" +msgstr "Suurin Palautus" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:33 +msgid "Maximum Output" +msgstr "Suurin Ulostulo" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:43 +msgid "Swapping" +msgstr "Swapping" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:51 +msgid "Gas cost" +msgstr "Kaasun hinta" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:59 +msgid "Receiving" +msgstr "Vastaanotetaan" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:67 +msgid "Price impact" +msgstr "Hinnan vaikutus" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:35 +msgid "You need to increase slippage to at least {minRequiredSlippage} for this route." +msgstr "Sinun täytyy lisätä lipsumissivua vähintään {minRequiredSlippage} tälle reitille." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:59 +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:61 +msgid "We recommend you to increase slippage to at least {minRequiredSlippage} for this route." +msgstr "Suosittelemme, että nostat lipsumisen vähintään {minRequiredSlippage} tälle reitille." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:68 +msgid "Caution, your slippage is high." +msgstr "Varoitus, lipsumisesi on korkea." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.tsx:78 +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.Warning.tsx:26 +msgid "Change" +msgstr "Muuta" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:42 +msgid "Change settings" +msgstr "Muuta asetuksia" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:52 +msgid "High slippage" +msgstr "Korkea lipsahdus" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:53 +msgid "Low slippage" +msgstr "Alhainen lipsahdus" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:57 +msgid " Caution, your slippage is high (={userSlippage}). Your trade may be front run." +msgstr " Varoitus, lipsumisesi on korkea (={userSlippage}). Kaupasi voi olla etu." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:78 +msgid "Confirm anyway" +msgstr "Vahvista joka tapauksessa" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:22 +msgid "Something went wrong" +msgstr "Jokin meni pieleen" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:24 +msgid "Something went wrong. Please refresh the app." +msgstr "Jokin meni pieleen. Päivitä sovellus." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/Slippage.tsx:38 +msgid "Slippage tolerance per swap" +msgstr "Liu'utuksen toleranssi swapia kohti" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/Slippage.tsx:91 +msgid "Custom" +msgstr "Mukautettu" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:11 +msgid "Your transaction will be reverted if the price changes unfavorably by more than this percentage." +msgstr "Tapahtumasi palautetaan, jos hinta muuttuu epäsuotuisasti enemmän kuin tämä prosenttiosuus." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:16 +#: widget/embedded/src/containers/Settings/Lists.tsx:245 +msgid "Warning" +msgstr "Varoitus" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:17 +msgid "This setting is applied to each step (e.g. 1Inch, Thorchain, etc.), meaning only that specific step will be reverted, not the entire route." +msgstr "Tätä asetusta sovelletaan jokaiseen vaiheeseen (esim. 1Inch, Thorchain, jne.), mikä tarkoittaa vain sitä, että tietty vaihe peruutetaan, ei koko reittiä." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:25 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:269 +msgid "Swap Details" +msgstr "Vaihda Tiedot" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:33 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:312 +msgid "Request ID" +msgstr "Pyydä ID" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:64 +msgid "Not found" +msgstr "Ei löydy" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:65 +msgid "Swap with request ID = {requestId} not found." +msgstr "Vaihda pyynnön ID = {requestId} ei löytynyt." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:219 +msgid "You have received {amount} {token} in {conciseAddress} wallet on {chain} chain." +msgstr "Olet saanut {amount} {token} {conciseAddress} -lompakossa {chain} -ketjussa." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:242 +msgid "Transaction was not sent." +msgstr "Tapahtumaa ei lähetetty." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:244 +msgid "{amount} {symbol} on {blockchain} remains in your wallet." +msgstr "{amount} {symbol} {blockchain} jää lompakkoosi." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:281 +msgid "Delete" +msgstr "Poista" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:304 +msgid "Try again" +msgstr "Yritä uudelleen" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:322 +msgid "Copied To Clipboard" +msgstr "Kopioitu Leikepöydälle" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:323 +msgid "Copy Request ID" +msgstr "Kopioi Pyyntö ID" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:346 +msgid "View on Rango Explorer" +msgstr "Näytä Rango Explorerissa" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:355 +msgid "Finished at" +msgstr "Valmis klo" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:355 +msgid "Created at" +msgstr "Luotu klo" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.tsx:50 +msgid "View transaction" +msgstr "Näytä tapahtuma" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.Warning.tsx:49 +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:31 +msgid "Connect" +msgstr "Yhdistä" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:43 +msgid "Swap Successful" +msgstr "Vaihto Onnistui" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:71 +msgid "Transaction Failed" +msgstr "Tapahtuma Epäonnistui" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:87 +msgid "Done" +msgstr "Valmis" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:100 +msgid "Diagnosis" +msgstr "Diagnoosi" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:112 +msgid "See Details" +msgstr "Näytä Yksityiskohdat" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:13 +msgid "Cancel Swap" +msgstr "Peruuta Vaihda" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:14 +msgid "Are you sure you want to cancel this swap?" +msgstr "Oletko varma, että haluat peruuttaa tämän swapin?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:23 +msgid "Yes, Cancel it" +msgstr "Kyllä, peruuta se" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:32 +#: widget/embedded/src/pages/CustomTokensPage.tsx:181 +msgid "No, Continue" +msgstr "Ei, Jatka" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:13 +msgid "Delete Transaction" +msgstr "Poista Tapahtuma" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:14 +msgid "Are you sure you want to delete this swap?" +msgstr "Oletko varma, että haluat poistaa tämän swapin?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:23 +#: widget/embedded/src/pages/CustomTokensPage.tsx:171 +msgid "Yes, Delete it" +msgstr "Kyllä, poista se" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:33 +#: widget/embedded/src/pages/HistoryPage.tsx:253 +msgid "No, Cancel" +msgstr "Ei, Peruuta" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:12 +msgid "Change Network" +msgstr "Vaihda Verkkoa" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:20 +msgid "Network Changed" +msgstr "Verkko Muutettu" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/TokenList/TokenList.tsx:271 +#: widget/ui/src/containers/SwapInput/TokenSection.tsx:54 +msgid "Select Token" +msgstr "Valitse Tunnus" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:27 +msgid "Wallet Connected" +msgstr "Lompakko Yhdistetty" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:28 +msgid "Your wallet is connected, you can use it to swap." +msgstr "Lompakkosi on yhdistetty, voit käyttää sitä vaihtaaksesi." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:39 +msgid "Failed to Connect" +msgstr "Yhteyden muodostaminen epäonnistui" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:41 +msgid "Your wallet is not connected. Please try again." +msgstr "Lompakkosi ei ole yhdistetty. Yritä uudelleen." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:50 +msgid "Connecting to your wallet" +msgstr "Yhdistetään lompakkoon" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:51 +msgid "Click connect in your wallet popup." +msgstr "Valitse yhdistä lompakon ponnahdusikkuna." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:99 +msgid "Select Derivation Path" +msgstr "Valitse Derivation Polku" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:100 +msgid "In order to connect to {type}, you must first select a Derivation Path" +msgstr "Jotta voit muodostaa yhteyden {type}, sinun täytyy ensin valita Derivation Path" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:118 +msgid "Choose Derivation Path Template" +msgstr "Valitse Derivation Polku Malli" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:133 +msgid "Enter Path" +msgstr "Syötä Polku" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:134 +msgid "Enter Index" +msgstr "Syötä Hakemisto" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:15 +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:18 +msgid "Add {blockchainDisplayName} Chain" +msgstr "Lisää {blockchainDisplayName} Ketju" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:20 +msgid "Would you like to add the {blockchainDisplayName} experimental chain to your wallet?" +msgstr "Haluatko lisätä lompakkoon {blockchainDisplayName} kokeellinen ketju?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:22 +msgid "Please approve the experimental chain pop-up in your wallet." +msgstr "Ole hyvä ja hyväksy kokeellinen ketju ponnahdusikkuna lompakossa." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:30 +msgid "{blockchainDisplayName} Chain Added" +msgstr "{blockchainDisplayName} Ketju Lisätty" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:34 +msgid "The {blockchainDisplayName} chain has been successfully added to your wallet." +msgstr "{blockchainDisplayName} ketju on onnistuneesti lisätty lompakkoon." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:42 +msgid "Request Rejected" +msgstr "Pyyntö Hylätty" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:43 +msgid "You've rejected adding {blockchainDisplayName} chain to your wallet." +msgstr "Olet hylännyt {blockchainDisplayName} ketjun lisäämisen lompakkoon." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:70 +msgid "Select chain types" +msgstr "Valitse ketjutyypit" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:71 +msgid "This wallet supports multiple chains. Select which chain you'd like to connect to." +msgstr "Tämä lompakko tukee useita ketjuja. Valitse mihin ketjuun, johon haluat yhdistää." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:9 +msgid "Failed Network, Please retry your swap." +msgstr "Epäonnistunut verkko, yritä swapisi uudelleen." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:11 +msgid "Please reset your liquidity sources." +msgstr "Ole hyvä ja nollaa likviditeetin lähteet." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:12 +msgid "You have limited the liquidity sources and this might result in Rango finding no routes. Please consider resetting your liquidity sources." +msgstr "Olet rajoittanut likviditeettilähteitä ja tämä saattaa johtaa Rangon löytämiseen ilman reittejä. Harkitse likviditeetin lähteiden uudelleenasettamista." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:17 +msgid "No Routes Found." +msgstr "Reittejä Ei Löytynyt." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:18 +msgid "Reasons why Rango couldn't find a route: low liquidity on token, very low input amount or no routes available for the selected input/output token combination." +msgstr "Syyt miksi Rango ei löytänyt reittiä: alhainen likviditeetti token, hyvin alhainen syöte määrä tai ei reittejä käytettävissä valitun sisään- / ulostulo token yhdistelmä." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:23 +msgid "Bridge Limit Error: Please increase your amount." +msgstr "Bridge Limit virhe: Ole hyvä ja lisää summaasi." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:26 +msgid "Bridge Limit Error: Please decrease your amount." +msgstr "Bridge Limit virhe: pienennä summaasi." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:31 +msgid "High Price Impact" +msgstr "Korkean Hinnan Vaikutus" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:32 +msgid "Price impact is too high!" +msgstr "Hintavaikutus on liian suuri!" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:33 +msgid "The price impact is significantly higher than the allowed amount." +msgstr "Hintavaikutus on huomattavasti suurempi kuin sallittu määrä." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:36 +msgid "Confirm high price impact" +msgstr "Vahvista hintavaikutus" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:39 +msgid "Route updated and price impact is too high, try again later!" +msgstr "Reitti päivitetty ja hintavaikutus on liian korkea, yritä myöhemmin uudelleen!" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:44 +msgid "USD Price Unknown" +msgstr "Yhdysvaltain Hinta Tuntematon" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:45 +msgid "USD Price Unknown, Cannot calculate Price Impact." +msgstr "USD Hinta tuntematon, Ei voida laskea Hintavaikutusta." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:46 +msgid "USD Price Unknown, Cannot calculate Price Impact. The price impact may be higher than usual. Are you sure to continue the Swap?" +msgstr "USD Hinta tuntematon, Ei voida laskea hintavaikutusta. Hintavaikutus voi olla tavallista suurempi. Oletko varma jatkamaan swap?" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:49 +msgid "Confirm USD Price Unknown" +msgstr "Vahvista USD Hinta Tuntematon" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:6 +#: widget/embedded/src/pages/Home.tsx:163 +msgid "Swap" +msgstr "Vaihda" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:7 +msgid "Swap anyway" +msgstr "Vaihda joka tapauksessa" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:8 +msgid "The route goes through Ethereum. Continue?" +msgstr "Reitti kulkee Ethereumin kautta. Jatketaanko?" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:10 +msgid "Route has been updated." +msgstr "Reitti on päivitetty." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:12 +msgid "Output amount changed to {newOutputAmount} ({percentageChange}% change)." +msgstr "Lähtömääräksi muutettiin {newOutputAmount} ({percentageChange}% muutos)." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:20 +msgid "Route swappers has been updated." +msgstr "Reitin vaihtajat on päivitetty." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:22 +msgid "Route internal coins has been updated." +msgstr "Reitin sisäiset kolikot on päivitetty." + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/ExpandedQuotes/ExpandedQuotes.tsx:53 +#: widget/embedded/src/pages/Routes.tsx:48 +msgid "Routes" +msgstr "Reitit" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Inputs/Inputs.tsx:76 +msgid "From" +msgstr "Alkaen" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Inputs/Inputs.tsx:118 +msgid "To" +msgstr "Vastaanottaja" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:49 +msgid "Light" +msgstr "Vaalea" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:58 +msgid "Dark" +msgstr "Tumma" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:67 +msgid "Auto" +msgstr "Automaattinen" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:140 +msgid "Loading failed" +msgstr "Lataus epäonnistui" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:156 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:41 +msgid "Bridges" +msgstr "Sillat" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:174 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:41 +msgid "Exchanges" +msgstr "Pörssit" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:195 +#: widget/embedded/src/pages/CustomTokensPage.tsx:90 +msgid "Custom Tokens" +msgstr "Mukautetut Tokenit" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:214 +#: widget/embedded/src/pages/LanguagePage.tsx:43 +msgid "Language" +msgstr "Kieli" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:235 +msgid "Infinite approval" +msgstr "Loputon hyväksyntä" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:246 +msgid "Enabling the 'Infinite approval' mode grants unrestricted access to underlying smart contracts, allowing them to utilize the approved token amount without limitations." +msgstr "Päällekkäisen hyväksynnän käyttöönotto mahdollistaa rajoittamattoman pääsyn taustalla oleviin älykkäisiin sopimuksiin, jolloin ne voivat käyttää hyväksyttyä symbolin määrää rajoituksetta." + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:266 +msgid "Theme" +msgstr "Teema" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:39 +msgid "Duplicate Token" +msgstr "Duplicate Token" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:40 +msgid "The address you entered is duplicate, please enter a new address." +msgstr "Antamasi osoite on kaksoiskappale, kirjoita uusi osoite." + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:46 +msgid "Token Already Exists" +msgstr "Token Jo Olemassa" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:47 +msgid "There's no need to add this token again because it already exists and is supported by us." +msgstr "Tämän tunnuksen lisääminen uudelleen ei ole tarpeen, koska se on jo olemassa ja sitä tukee meidät." + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:53 +msgid "Token Not Found" +msgstr "Tunnistetta Ei Löytynyt" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:54 +msgid "Sorry, no token was found on {blockchain} chain with the provided address. please make sure you have entered the right token address." +msgstr "Anteeksi, tunnus ei löytynyt {blockchain} ketjusta annetun osoitteen kanssa. Varmista, että olet syöttänyt oikeanlaisen token osoitteen." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:78 +msgid "Network Error" +msgstr "Verkon Virhe" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:109 +#: widget/embedded/src/pages/CustomTokensPage.tsx:149 +msgid "Add Custom Token" +msgstr "Lisää Mukautettu Tunnus" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:127 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:128 +msgid "Select chain" +msgstr "Valitse ketju" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:132 +msgid "Enter Address" +msgstr "Syötä Osoite" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:139 +msgid "Enter token address" +msgstr "Syötä tunnisteen osoite" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:176 +msgid "Failed Network, Please retry." +msgstr "Epäonnistunut verkko, yritä uudelleen." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:192 +msgid "Add another custom token" +msgstr "Lisää toinen mukautettu tunnus" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:236 +msgid "Confirm Swap" +msgstr "Vahvista Vaihda" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:254 +msgid "Start Swap" +msgstr "Käynnistä Vaihda" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:282 +msgid "You get" +msgstr "Sinä saat" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:102 +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:90 +msgid "Search Token" +msgstr "Etsi Pääsymerkki" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:134 +msgid "No custom tokens" +msgstr "Ei omia tunnuksia" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:135 +msgid "press the button to add your custom token" +msgstr "paina painiketta lisätäksesi mukautetun tunnuksen" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:158 +msgid "Delete Custom Token" +msgstr "Poista Mukautettu Tunnus" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:160 +msgid "Are you sure you want to Delete this Token?" +msgstr "Oletko varma, että haluat poistaa tämän polkun?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:59 +msgid "Complete" +msgstr "Complete" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:63 +msgid "Running" +msgstr "Käynnissä" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:65 +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:8 +msgid "Failed" +msgstr "Epäonnistui" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:149 +msgid "Clear" +msgstr "Tyhjennä" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:161 +msgid "Search Transaction" +msgstr "Etsi Tapahtuma" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:187 +msgid "No transactions" +msgstr "Ei tapahtumia" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:194 +msgid "Your transaction history is stored locally and will appear here after you start a swap" +msgstr "Tapahtumahistoriasi on tallennettu paikallisesti ja se tulee näkymään täällä swapin käynnistymisen jälkeen" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:218 +msgid "Clear Transaction History" +msgstr "Tyhjennä Tapahtuman Historia" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:222 +msgid "Proceeding will remove all successful and failed transactions from the widget. Do you want to continue?" +msgstr "Jatkaminen poistaa kaikki onnistuneet ja epäonnistuneet tapahtumat widgetistä. Haluatko jatkaa?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:229 +msgid "Note: This does not erase your transaction history on the chain; it only removes them here." +msgstr "Huom: Tämä ei poista tapahtumahistoriaasi ketjussa, vaan se poistaa ne vain täältä." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:243 +msgid "Yes, Clear the history" +msgstr "Kyllä, Tyhjennä historia" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LanguagePage.tsx:56 +msgid "language" +msgstr "kieli" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:121 +msgid "Deselect all" +msgstr "Poista kaikki valinnat" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:121 +msgid "Select all" +msgstr "Valitse kaikki" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:133 +msgid "Search {sourceType}" +msgstr "Hae {sourceType}" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectBlockchainPage.tsx:60 +msgid "Search Chain" +msgstr "Etsi Ketju" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:67 +msgid "Source" +msgstr "Lähde" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:68 +msgid "Destination" +msgstr "Kohde" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:74 +msgid "Swap {type}" +msgstr "Vaihda {type}" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SettingsPage.tsx:45 +msgid "Currently, you're in campaign mode with restrictions on liquidity sources. Would you like to switch out of this mode and make use of all available liquidity sources?" +msgstr "Tällä hetkellä olet kampanjatilassa, jossa on rajoituksia likviditeetin lähteitä. Haluatko vaihtaa pois tästä tilasta ja hyödyntää kaikkia käytettävissä olevia likviditeetin lähteitä?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SwapDetailsPage.tsx:27 +msgid "The request ID is necessary to display the swap details." +msgstr "Pyyntö ID on tarpeen näyttää swapin tiedot." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/WalletsPage.tsx:67 +#: widget/ui/src/containers/ConnectWalletsModal/ConnectWalletsModal.tsx:15 +msgid "Connect Wallets" +msgstr "Yhdistä Lompakot" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/WalletsPage.tsx:82 +msgid "Choose a wallet to connect." +msgstr "Valitse yhdistävä lompakko" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:25 +msgid "This week" +msgstr "Tällä viikolla" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:32 +msgid "This month" +msgstr "Tässä kuussa" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:39 +msgid "This year" +msgstr "Tänä vuonna" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:129 +msgid "Required: >= {min} {symbol}" +msgstr "Pakollinen: >= {min} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:142 +msgid "Required: > {min} {symbol}" +msgstr "Pakollinen: > {min} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:157 +msgid "Required: <= {max} {symbol}" +msgstr "Pakollinen: <= {max} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:170 +msgid "Required: < {max} {symbol}" +msgstr "Pakollinen: < {max} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:601 +msgid " for network fee" +msgstr " verkkomaksua varten" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:604 +msgid " for swap" +msgstr " vaihtamista varten" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:607 +msgid " for input and network fee" +msgstr " syöttö- ja verkkomaksu" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:609 +msgid "Needs ≈ {requiredAmount} {symbol}{reason}, but you have {currentAmount} {symbol} in your {blockchain} wallet." +msgstr "Tarvitsee ≈ {requiredAmount} {symbol}{reason}, mutta sinulla on {currentAmount} {symbol} lompakossasi {blockchain} ." + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:669 +msgid "Waiting for connecting wallet" +msgstr "Odotetaan lompakon yhdistämistä" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:673 +msgid "Waiting for other running tasks to be finished" +msgstr "Odotetaan, että muut käynnissä olevat tehtävät valmistuvat" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:676 +msgid "Waiting for changing wallet network" +msgstr "Odotetaan lompakon verkon vaihtamista" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:6 +msgid "Sunday" +msgstr "Sunnuntai" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:7 +msgid "Monday" +msgstr "Maanantai" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:8 +msgid "Tuesday" +msgstr "Tiistai" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:9 +msgid "Wednesday" +msgstr "Keskiviikko" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:10 +msgid "Thursday" +msgstr "Torstai" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:11 +msgid "Friday" +msgstr "Perjantai" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:12 +msgid "Saturday" +msgstr "Lauantai" + +#. js-lingui-explicit-id +#: widget/ui/src/components/BottomLogo/BottomLogo.tsx:14 +msgid "Powered By" +msgstr "Palvelun Toimittaja" + +#. js-lingui-explicit-id +#: widget/ui/src/components/FullExpandedQuote/FullExpandedQuote.Tooltip.tsx:37 +msgid "Aggregated Transaction" +msgstr "Yhdistetty Tapahtuma" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SelectableCategoryList/SelectableCategoryList.tsx:63 +msgid "{blockchainCategory}" +msgstr "{blockchainCategory}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/StepDetails/StepDetails.tsx:75 +#: widget/ui/src/components/StepDetails/StepDetails.tsx:102 +msgid "Swap on {fromChain} via {swapper}" +msgstr "Vaihda kohtaan {fromChain} kautta {swapper}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/StepDetails/StepDetails.tsx:109 +msgid "Bridge to {toChain} via {swapper}" +msgstr "Silta {toChain} :n kautta {swapper}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:10 +msgid "Completed" +msgstr "Valmis" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:12 +msgid "In progress" +msgstr "Toiminto käynnissä" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapToken.tsx:122 +msgid "Waiting for bridge transaction" +msgstr "Odotetaan siltatapahtumaa" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:12 +msgid "Connected" +msgstr "Yhdistetty" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:13 +msgid "Disconnect" +msgstr "Katkaise" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:18 +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:19 +msgid "Install" +msgstr "Asenna" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:24 +msgid "Connecting ..." +msgstr "Yhdistetään ..." + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:25 +msgid "Connecting" +msgstr "Yhdistetään" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:30 +msgid "Disconnected" +msgstr "Yhteys Katkaistu" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:34 +msgid "you need to pass a correct state to Wallet." +msgstr "sinun täytyy siirtää oikea tila Walletiin." + +#. js-lingui-explicit-id +#: widget/ui/src/containers/Notifications/NotificationNotFound.tsx:15 +msgid "There are no notifications." +msgstr "Ilmoituksia ei ole." + +#. js-lingui-explicit-id +#: widget/ui/src/containers/Notifications/Notifications.tsx:39 +msgid "Clear all" +msgstr "Tyhjennä kaikki" + +#. js-lingui-explicit-id +#: widget/ui/src/containers/SwapInput/SwapInput.tsx:65 +msgid "Balance" +msgstr "Saldo" + +#. js-lingui-explicit-id +#: widget/ui/src/containers/SwapInput/SwapInput.tsx:73 +msgid "Max" +msgstr "Maksimi" + diff --git a/translations/fil.po b/translations/fil.po new file mode 100644 index 0000000000..f6820ddab7 --- /dev/null +++ b/translations/fil.po @@ -0,0 +1,1339 @@ +msgid "" +msgstr "" +"POT-Creation-Date: 2023-11-06 17:24+0330\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: @lingui/cli\n" +"Language: fil\n" +"Project-Id-Version: rango\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2024-11-27 15:57\n" +"Last-Translator: \n" +"Language-Team: Filipino\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" +"X-Crowdin-Project: rango\n" +"X-Crowdin-Project-ID: 622238\n" +"X-Crowdin-Language: fil\n" +"X-Crowdin-File: en.po\n" +"X-Crowdin-File-ID: 30\n" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SameTokensWarning/SameTokensWarning.tsx:21 +msgid "No Routes Found" +msgstr "Walang Nahanap na Ruta" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SameTokensWarning/SameTokensWarning.tsx:25 +msgid "You cannot use the same token for From and To." +msgstr "Hindi mo maaaring gamitin ang parehong token para sa From and To." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:41 +#: widget/embedded/src/components/TokenList/TokenList.tsx:286 +#: widget/embedded/src/pages/HistoryPage.tsx:186 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:143 +msgid "No results found" +msgstr "Walang nakitang resulta" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:42 +#: widget/embedded/src/components/TokenList/TokenList.tsx:287 +#: widget/embedded/src/pages/HistoryPage.tsx:193 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:144 +msgid "Try using different keywords" +msgstr "Subukang gumamit ng iba't ibang mga keyword" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:72 +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:46 +#: widget/embedded/src/pages/SelectBlockchainPage.tsx:42 +#: widget/ui/src/containers/SwapInput/TokenSection.tsx:61 +msgid "Select Chain" +msgstr "Piliin ang Chain" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:66 +msgid "All" +msgstr "Lahat" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:100 +msgid "More +{count}" +msgstr "Higit pa +{count}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabAlert/ActivateTabAlert.tsx:17 +msgid "Activate this tab" +msgstr "I-activate ang tab na ito" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabAlert/ActivateTabAlert.tsx:22 +msgid "Another tab is open and handles transactions." +msgstr "Ang isa pang tab ay bukas at pinangangasiwaan ang mga transaksyon." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:20 +msgid "Activate current tab" +msgstr "I-activate ang kasalukuyang tab" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:22 +msgid "Currently, some transactions are running and being handled by other browser tab. If you activate this tab, all transactions that are already in the transaction sign step will expire." +msgstr "Sa kasalukuyan, ang ilang mga transaksyon ay tumatakbo at pinangangasiwaan ng ibang tab ng browser. Kung i-activate mo ang tab na ito, mag-e-expire ang lahat ng transaksyon na nasa hakbang sa pag-sign ng transaksyon." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:33 +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:349 +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:152 +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:33 +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:116 +msgid "Confirm" +msgstr "Kumpirmahin" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:365 +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:447 +msgid "Your {blockchainName} wallets" +msgstr "Ang iyong {blockchainName} wallet" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:384 +msgid "Insufficient account balance" +msgstr "Hindi sapat na balanse sa account" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:394 +msgid "Proceed anyway" +msgstr "Magpatuloy pa rin" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:456 +msgid "You need to connect a {blockchainName} wallet." +msgstr "Kailangan mong magkonekta ng {blockchainName} wallet." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/WalletList.tsx:143 +msgid "Add {chain} chain" +msgstr "Magdagdag ng {chain} chain" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/WalletList.tsx:244 +msgid "Show more wallets" +msgstr "Magpakita ng higit pang mga wallet" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:113 +msgid "Send to a different address" +msgstr "Ipadala sa ibang address" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:129 +msgid "Enter {blockchainName} address" +msgstr "Ilagay ang {blockchainName} address" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:147 +msgid "Address {destination} doesn't match the blockchain address pattern." +msgstr "Ang address {destination} ay hindi tumutugma sa pattern ng address ng blockchain." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:59 +msgid "via" +msgstr "sa pamamagitan ng" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:74 +msgid "This token doesn't appear on the active token list(s). Make sure this is the token that you want to trade." +msgstr "Hindi lumalabas ang token na ito sa (mga) aktibong listahan ng token. Tiyaking ito ang token na gusto mong i-trade." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:89 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:164 +msgid "Import" +msgstr "Mag-import" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/FilterSelector/FilterSelectorContent.tsx:26 +msgid "Status" +msgstr "Katayuan" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/FilterSelector/FilterSelectorContent.tsx:33 +#: widget/embedded/src/components/NoResult/NoResult.helpers.ts:37 +#: widget/embedded/src/pages/SettingsPage.tsx:55 +msgid "Reset" +msgstr "I-reset" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/CancelButton.tsx:18 +msgid "Cancel" +msgstr "Kanselahin" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:46 +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:34 +msgid "Refresh" +msgstr "I-refresh" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:63 +#: widget/ui/src/containers/Notifications/Notifications.tsx:35 +msgid "Notifications" +msgstr "Mga abiso" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:79 +#: widget/embedded/src/pages/SettingsPage.tsx:38 +msgid "Settings" +msgstr "Mga setting" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:93 +#: widget/embedded/src/pages/HistoryPage.tsx:139 +msgid "History" +msgstr "Kasaysayan" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/WalletButton.tsx:22 +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:16 +#: widget/embedded/src/constants/messages.ts:5 +msgid "Connect Wallet" +msgstr "Ikonekta ang Wallet" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HistoryGroupedList/HistoryGroupedList.tsx:118 +#: widget/embedded/src/utils/date.ts:18 +#: widget/embedded/src/utils/time.ts:22 +msgid "Today" +msgstr "Ngayong araw" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/LoadingSwapDetails/LoadingSwapDetails.tsx:20 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:424 +msgid "Swaps steps" +msgstr "Nagpapalitan ng mga hakbang" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/NoResult/NoResult.helpers.ts:25 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:191 +msgid "Retry" +msgstr "Subukan muli" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:149 +msgid "Slippage Error" +msgstr "Slippage Error" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:150 +msgid "Slippage Warning" +msgstr "Babala ng slippage" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:153 +msgid "Bridge Limit Error" +msgstr "Error sa Limitasyon ng Tulay" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:240 +msgid "Yours: {amount} {symbol}" +msgstr "Sa iyo: {amount} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:261 +msgid "Minimum required slippage: {minRequiredSlippage}" +msgstr "Minimum na kinakailangang slippage: {minRequiredSlippage}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:282 +msgid "Yours: {userSlippage}" +msgstr "Sa iyo: {userSlippage}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:395 +msgid "See All Routes" +msgstr "Tingnan ang Lahat ng Ruta" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:81 +msgid "View more info" +msgstr "Tingnan ang higit pang impormasyon" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:91 +msgid "Gas & Fee Explanation" +msgstr "Paliwanag ng Gas at Bayad" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:107 +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:103 +msgid "Details" +msgstr "Mga Detalye" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:146 +msgid "Total Payable Fee" +msgstr "Kabuuang Bayad na Bayad" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:166 +msgid "Hide non-payable fees" +msgstr "Itago ang mga hindi mababayarang bayarin" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:167 +msgid "Show non-payable fees" +msgstr "Ipakita ang mga hindi nababayarang bayarin" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:177 +msgid "Description" +msgstr "Paglalarawan" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:181 +msgid "The following fees are considered in the transaction output and\n" +" you won’t need to pay extra gas for them." +msgstr "Ang mga sumusunod na bayarin ay isinasaalang-alang sa output ng transaksyon at\n" +" hindi mo na kailangang magbayad ng dagdag na gas para sa kanila." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteSummary.tsx:25 +msgid "Swap input" +msgstr "Magpalit ng input" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteSummary.tsx:44 +msgid "Estimated output" +msgstr "Tinantyang output" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteTrigger.tsx:65 +msgid "Via:" +msgstr "sa pamamagitan ng:" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteTrigger.tsx:150 +msgid "Chains:" +msgstr "Mga tanikala:" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/Quotes.tsx:77 +msgid "Sort by" +msgstr "Pagbukud-bukurin ayon sa" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:17 +msgid "Smart Routing" +msgstr "Smart Routing" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:21 +msgid "Lowest Fee" +msgstr "Pinakamababang Bayad" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:25 +msgid "Fastest Transfer" +msgstr "Pinakamabilis na Paglipat" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:29 +msgid "Maximum Return" +msgstr "Pinakamataas na Pagbabalik" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:33 +msgid "Maximum Output" +msgstr "Pinakamataas na Output" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:43 +msgid "Swapping" +msgstr "Pagpapalit" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:51 +msgid "Gas cost" +msgstr "Gastos sa gas" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:59 +msgid "Receiving" +msgstr "Pagtanggap" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:67 +msgid "Price impact" +msgstr "Epekto sa presyo" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:35 +msgid "You need to increase slippage to at least {minRequiredSlippage} for this route." +msgstr "Kailangan mong pataasin ang pagdulas sa hindi bababa sa {minRequiredSlippage} para sa rutang ito." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:59 +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:61 +msgid "We recommend you to increase slippage to at least {minRequiredSlippage} for this route." +msgstr "Inirerekomenda namin sa iyo na taasan ang pagdulas sa hindi bababa sa {minRequiredSlippage} para sa rutang ito." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:68 +msgid "Caution, your slippage is high." +msgstr "Mag-ingat, mataas ang iyong pagkadulas." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.tsx:78 +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.Warning.tsx:26 +msgid "Change" +msgstr "Baguhin" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:42 +msgid "Change settings" +msgstr "Baguhin ang mga setting" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:52 +msgid "High slippage" +msgstr "Mataas na pagdulas" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:53 +msgid "Low slippage" +msgstr "Mababang slippage" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:57 +msgid " Caution, your slippage is high (={userSlippage}). Your trade may be front run." +msgstr " Mag-ingat, mataas ang iyong pagkadulas (={userSlippage}). Maaaring front run ang iyong trade." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:78 +msgid "Confirm anyway" +msgstr "Kumpirmahin pa rin" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:22 +msgid "Something went wrong" +msgstr "Nagkaproblema" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:24 +msgid "Something went wrong. Please refresh the app." +msgstr "Nagkaproblema. Paki-refresh ang app." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/Slippage.tsx:38 +msgid "Slippage tolerance per swap" +msgstr "Pagpapahintulot sa slippage bawat swap" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/Slippage.tsx:91 +msgid "Custom" +msgstr "Custom" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:11 +msgid "Your transaction will be reverted if the price changes unfavorably by more than this percentage." +msgstr "Ibabalik ang iyong transaksyon kung hindi maganda ang pagbabago sa presyo ng higit sa porsyentong ito." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:16 +#: widget/embedded/src/containers/Settings/Lists.tsx:245 +msgid "Warning" +msgstr "Babala" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:17 +msgid "This setting is applied to each step (e.g. 1Inch, Thorchain, etc.), meaning only that specific step will be reverted, not the entire route." +msgstr "Inilapat ang setting na ito sa bawat hakbang (hal. 1Inch, Thorchain, atbp.), ibig sabihin, ang partikular na hakbang lang ang ibabalik, hindi ang buong ruta." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:25 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:269 +msgid "Swap Details" +msgstr "Pagpalitin ang mga Detalye" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:33 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:312 +msgid "Request ID" +msgstr "Humiling ng ID" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:64 +msgid "Not found" +msgstr "Hindi nahanap" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:65 +msgid "Swap with request ID = {requestId} not found." +msgstr "Magpalit gamit ang request ID = {requestId} hindi nahanap." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:219 +msgid "You have received {amount} {token} in {conciseAddress} wallet on {chain} chain." +msgstr "Nakatanggap ka ng {amount} {token} sa {conciseAddress} wallet sa {chain} chain." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:242 +msgid "Transaction was not sent." +msgstr "Hindi naipadala ang transaksyon." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:244 +msgid "{amount} {symbol} on {blockchain} remains in your wallet." +msgstr "{amount} {symbol} sa {blockchain} nananatili sa iyong wallet." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:281 +msgid "Delete" +msgstr "Tanggalin" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:304 +msgid "Try again" +msgstr "Subukan muli" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:322 +msgid "Copied To Clipboard" +msgstr "Kinopya Sa Clipboard" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:323 +msgid "Copy Request ID" +msgstr "Kopyahin ang Request ID" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:346 +msgid "View on Rango Explorer" +msgstr "Tingnan sa Rango Explorer" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:355 +msgid "Finished at" +msgstr "Natapos sa" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:355 +msgid "Created at" +msgstr "Nilikha sa" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.tsx:50 +msgid "View transaction" +msgstr "Tingnan ang transaksyon" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.Warning.tsx:49 +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:31 +msgid "Connect" +msgstr "Kumonekta" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:43 +msgid "Swap Successful" +msgstr "Matagumpay na Pagpalit" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:71 +msgid "Transaction Failed" +msgstr "Nabigo ang Transaksyon" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:87 +msgid "Done" +msgstr "Tapos na" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:100 +msgid "Diagnosis" +msgstr "Diagnosis" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:112 +msgid "See Details" +msgstr "Tingnan ang Mga Detalye" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:13 +msgid "Cancel Swap" +msgstr "Kanselahin ang Pagpalit" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:14 +msgid "Are you sure you want to cancel this swap?" +msgstr "Sigurado ka bang gusto mong kanselahin ang swap na ito?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:23 +msgid "Yes, Cancel it" +msgstr "Oo, Kanselahin ito" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:32 +#: widget/embedded/src/pages/CustomTokensPage.tsx:181 +msgid "No, Continue" +msgstr "Hindi, Magpatuloy" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:13 +msgid "Delete Transaction" +msgstr "Tanggalin ang Transaksyon" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:14 +msgid "Are you sure you want to delete this swap?" +msgstr "Sigurado ka bang gusto mong tanggalin ang swap na ito?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:23 +#: widget/embedded/src/pages/CustomTokensPage.tsx:171 +msgid "Yes, Delete it" +msgstr "Oo, Tanggalin ito" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:33 +#: widget/embedded/src/pages/HistoryPage.tsx:253 +msgid "No, Cancel" +msgstr "Hindi, Kanselahin" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:12 +msgid "Change Network" +msgstr "Baguhin ang Network" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:20 +msgid "Network Changed" +msgstr "Binago ang Network" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/TokenList/TokenList.tsx:271 +#: widget/ui/src/containers/SwapInput/TokenSection.tsx:54 +msgid "Select Token" +msgstr "Piliin ang Token" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:27 +msgid "Wallet Connected" +msgstr "Nakakonekta ang Wallet" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:28 +msgid "Your wallet is connected, you can use it to swap." +msgstr "Ang iyong wallet ay konektado, maaari mo itong gamitin upang makipagpalitan." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:39 +msgid "Failed to Connect" +msgstr "Nabigong Kumonekta" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:41 +msgid "Your wallet is not connected. Please try again." +msgstr "Hindi konektado ang iyong wallet. Pakisubukang muli." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:50 +msgid "Connecting to your wallet" +msgstr "Kumokonekta sa iyong wallet" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:51 +msgid "Click connect in your wallet popup." +msgstr "I-click ang kumonekta sa popup ng iyong wallet." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:99 +msgid "Select Derivation Path" +msgstr "Piliin ang Derivation Path" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:100 +msgid "In order to connect to {type}, you must first select a Derivation Path" +msgstr "Para makakonekta sa {type}, kailangan mo munang pumili ng Derivation Path" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:118 +msgid "Choose Derivation Path Template" +msgstr "Piliin ang Template ng Derivation Path" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:133 +msgid "Enter Path" +msgstr "Ipasok ang Path" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:134 +msgid "Enter Index" +msgstr "Ipasok ang Index" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:15 +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:18 +msgid "Add {blockchainDisplayName} Chain" +msgstr "Magdagdag ng {blockchainDisplayName} Chain" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:20 +msgid "Would you like to add the {blockchainDisplayName} experimental chain to your wallet?" +msgstr "Gusto mo bang idagdag ang {blockchainDisplayName} pang-eksperimentong chain sa iyong wallet?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:22 +msgid "Please approve the experimental chain pop-up in your wallet." +msgstr "Mangyaring aprubahan ang pang-eksperimentong chain pop-up sa iyong wallet." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:30 +msgid "{blockchainDisplayName} Chain Added" +msgstr "{blockchainDisplayName} Naidagdag ang Chain" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:34 +msgid "The {blockchainDisplayName} chain has been successfully added to your wallet." +msgstr "Ang {blockchainDisplayName} chain ay matagumpay na naidagdag sa iyong wallet." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:42 +msgid "Request Rejected" +msgstr "Tinanggihan ang Kahilingan" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:43 +msgid "You've rejected adding {blockchainDisplayName} chain to your wallet." +msgstr "Tinanggihan mo ang pagdaragdag ng {blockchainDisplayName} chain sa iyong wallet." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:70 +msgid "Select chain types" +msgstr "Pumili ng mga uri ng chain" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:71 +msgid "This wallet supports multiple chains. Select which chain you'd like to connect to." +msgstr "Sinusuportahan ng wallet na ito ang maraming chain. Piliin kung saang chain mo gustong kumonekta." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:9 +msgid "Failed Network, Please retry your swap." +msgstr "Nabigong Network, Pakisubukang muli ang iyong swap." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:11 +msgid "Please reset your liquidity sources." +msgstr "Paki-reset ang iyong mga mapagkukunan ng pagkatubig." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:12 +msgid "You have limited the liquidity sources and this might result in Rango finding no routes. Please consider resetting your liquidity sources." +msgstr "Nilimitahan mo ang mga mapagkukunan ng pagkatubig at maaaring magresulta ito sa Rango na walang mahanap na mga ruta. Mangyaring isaalang-alang ang pag-reset ng iyong mga mapagkukunan ng pagkatubig." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:17 +msgid "No Routes Found." +msgstr "Walang Nahanap na Ruta." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:18 +msgid "Reasons why Rango couldn't find a route: low liquidity on token, very low input amount or no routes available for the selected input/output token combination." +msgstr "Mga dahilan kung bakit hindi makahanap ng ruta ang Rango: mababang liquidity sa token, napakababang halaga ng input o walang available na ruta para sa napiling kumbinasyon ng input/output token." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:23 +msgid "Bridge Limit Error: Please increase your amount." +msgstr "Bridge Limit Error: Pakidagdagan ang iyong halaga." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:26 +msgid "Bridge Limit Error: Please decrease your amount." +msgstr "Bridge Limit Error: Mangyaring bawasan ang iyong halaga." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:31 +msgid "High Price Impact" +msgstr "Mataas na Epekto sa Presyo" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:32 +msgid "Price impact is too high!" +msgstr "Masyadong mataas ang epekto sa presyo!" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:33 +msgid "The price impact is significantly higher than the allowed amount." +msgstr "Ang epekto sa presyo ay makabuluhang mas mataas kaysa sa pinapayagang halaga." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:36 +msgid "Confirm high price impact" +msgstr "Kumpirmahin ang epekto ng mataas na presyo" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:39 +msgid "Route updated and price impact is too high, try again later!" +msgstr "Na-update ang ruta at masyadong mataas ang epekto sa presyo, subukang muli sa ibang pagkakataon!" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:44 +msgid "USD Price Unknown" +msgstr "Hindi Alam ang Presyo ng USD" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:45 +msgid "USD Price Unknown, Cannot calculate Price Impact." +msgstr "Hindi Alam ang Presyo ng USD, Hindi makalkula ang Epekto sa Presyo." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:46 +msgid "USD Price Unknown, Cannot calculate Price Impact. The price impact may be higher than usual. Are you sure to continue the Swap?" +msgstr "Hindi Alam ang Presyo ng USD, Hindi makalkula ang Epekto sa Presyo. Maaaring mas mataas ang epekto sa presyo kaysa karaniwan. Sigurado ka bang ipagpapatuloy ang Swap?" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:49 +msgid "Confirm USD Price Unknown" +msgstr "Kumpirmahin ang Presyong USD Hindi Alam" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:6 +#: widget/embedded/src/pages/Home.tsx:163 +msgid "Swap" +msgstr "Magpalit" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:7 +msgid "Swap anyway" +msgstr "Magpalit pa rin" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:8 +msgid "The route goes through Ethereum. Continue?" +msgstr "Ang ruta ay dumadaan sa Ethereum. Magpatuloy?" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:10 +msgid "Route has been updated." +msgstr "Na-update ang ruta." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:12 +msgid "Output amount changed to {newOutputAmount} ({percentageChange}% change)." +msgstr "Ang halaga ng output ay ginawang {newOutputAmount} ({percentageChange}% pagbabago)." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:20 +msgid "Route swappers has been updated." +msgstr "Ang mga nagpapalit ng ruta ay na-update." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:22 +msgid "Route internal coins has been updated." +msgstr "Ang mga panloob na barya ng ruta ay na-update." + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/ExpandedQuotes/ExpandedQuotes.tsx:53 +#: widget/embedded/src/pages/Routes.tsx:48 +msgid "Routes" +msgstr "Mga Ruta" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Inputs/Inputs.tsx:76 +msgid "From" +msgstr "Mula sa" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Inputs/Inputs.tsx:118 +msgid "To" +msgstr "Upang" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:49 +msgid "Light" +msgstr "Liwanag" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:58 +msgid "Dark" +msgstr "Madilim" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:67 +msgid "Auto" +msgstr "Auto" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:140 +msgid "Loading failed" +msgstr "Nabigo ang paglo-load" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:156 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:41 +msgid "Bridges" +msgstr "Mga tulay" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:174 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:41 +msgid "Exchanges" +msgstr "Mga palitan" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:195 +#: widget/embedded/src/pages/CustomTokensPage.tsx:90 +msgid "Custom Tokens" +msgstr "Mga Custom na Token" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:214 +#: widget/embedded/src/pages/LanguagePage.tsx:43 +msgid "Language" +msgstr "Wika" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:235 +msgid "Infinite approval" +msgstr "Walang katapusang pag-apruba" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:246 +msgid "Enabling the 'Infinite approval' mode grants unrestricted access to underlying smart contracts, allowing them to utilize the approved token amount without limitations." +msgstr "Ang pag-enable sa 'Infinite approval' na mode ay nagbibigay ng hindi pinaghihigpitang access sa mga pinagbabatayan na smart contract, na nagpapahintulot sa kanila na gamitin ang naaprubahang halaga ng token nang walang limitasyon." + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:266 +msgid "Theme" +msgstr "Tema" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:39 +msgid "Duplicate Token" +msgstr "Duplicate na Token" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:40 +msgid "The address you entered is duplicate, please enter a new address." +msgstr "Ang address na iyong inilagay ay duplicate, mangyaring magpasok ng bagong address." + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:46 +msgid "Token Already Exists" +msgstr "Umiiral na ang Token" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:47 +msgid "There's no need to add this token again because it already exists and is supported by us." +msgstr "Hindi na kailangang idagdag muli ang token na ito dahil mayroon na ito at sinusuportahan namin." + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:53 +msgid "Token Not Found" +msgstr "Hindi Natagpuan ang Token" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:54 +msgid "Sorry, no token was found on {blockchain} chain with the provided address. please make sure you have entered the right token address." +msgstr "Paumanhin, walang nakitang token sa {blockchain} chain na may ibinigay na address. pakitiyak na naipasok mo ang tamang token address." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:78 +msgid "Network Error" +msgstr "Error sa Network" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:109 +#: widget/embedded/src/pages/CustomTokensPage.tsx:149 +msgid "Add Custom Token" +msgstr "Magdagdag ng Custom Token" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:127 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:128 +msgid "Select chain" +msgstr "Pumili ng chain" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:132 +msgid "Enter Address" +msgstr "Ilagay ang Address" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:139 +msgid "Enter token address" +msgstr "Ilagay ang token address" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:176 +msgid "Failed Network, Please retry." +msgstr "Nabigong Network, Pakisubukang muli." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:192 +msgid "Add another custom token" +msgstr "Magdagdag ng isa pang custom na token" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:236 +msgid "Confirm Swap" +msgstr "Kumpirmahin ang Swap" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:254 +msgid "Start Swap" +msgstr "Simulan ang Swap" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:282 +msgid "You get" +msgstr "Nakukuha mo" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:102 +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:90 +msgid "Search Token" +msgstr "Maghanap ng Token" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:134 +msgid "No custom tokens" +msgstr "Walang custom na token" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:135 +msgid "press the button to add your custom token" +msgstr "pindutin ang button para idagdag ang iyong custom na token" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:158 +msgid "Delete Custom Token" +msgstr "Tanggalin ang Custom Token" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:160 +msgid "Are you sure you want to Delete this Token?" +msgstr "Sigurado ka bang gusto mong Tanggalin ang Token na ito?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:59 +msgid "Complete" +msgstr "Kumpleto" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:63 +msgid "Running" +msgstr "Tumatakbo" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:65 +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:8 +msgid "Failed" +msgstr "Nabigo" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:149 +msgid "Clear" +msgstr "Maaliwalas" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:161 +msgid "Search Transaction" +msgstr "Transaksyon sa Paghahanap" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:187 +msgid "No transactions" +msgstr "Walang transaksyon" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:194 +msgid "Your transaction history is stored locally and will appear here after you start a swap" +msgstr "Ang iyong kasaysayan ng transaksyon ay lokal na naka-imbak at lalabas dito pagkatapos mong simulan ang isang swap" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:218 +msgid "Clear Transaction History" +msgstr "I-clear ang History ng Transaksyon" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:222 +msgid "Proceeding will remove all successful and failed transactions from the widget. Do you want to continue?" +msgstr "Aalisin ng pagpapatuloy ang lahat ng matagumpay at nabigong transaksyon mula sa widget. Gusto mo bang magpatuloy?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:229 +msgid "Note: This does not erase your transaction history on the chain; it only removes them here." +msgstr "Tandaan: Hindi nito binubura ang iyong history ng transaksyon sa chain; inaalis lang sila dito." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:243 +msgid "Yes, Clear the history" +msgstr "Oo, I-clear ang kasaysayan" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LanguagePage.tsx:56 +msgid "language" +msgstr "wika" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:121 +msgid "Deselect all" +msgstr "Alisin sa pagkakapili ang lahat" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:121 +msgid "Select all" +msgstr "Piliin lahat" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:133 +msgid "Search {sourceType}" +msgstr "Maghanap {sourceType}" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectBlockchainPage.tsx:60 +msgid "Search Chain" +msgstr "Chain ng Paghahanap" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:67 +msgid "Source" +msgstr "Pinagmulan" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:68 +msgid "Destination" +msgstr "Patutunguhan" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:74 +msgid "Swap {type}" +msgstr "Magpalit ng {type}" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SettingsPage.tsx:45 +msgid "Currently, you're in campaign mode with restrictions on liquidity sources. Would you like to switch out of this mode and make use of all available liquidity sources?" +msgstr "Sa kasalukuyan, nasa campaign mode ka na may mga paghihigpit sa mga source ng liquidity. Gusto mo bang umalis sa mode na ito at gamitin ang lahat ng available na mapagkukunan ng pagkatubig?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SwapDetailsPage.tsx:27 +msgid "The request ID is necessary to display the swap details." +msgstr "Kinakailangan ang request ID para ipakita ang mga detalye ng swap." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/WalletsPage.tsx:67 +#: widget/ui/src/containers/ConnectWalletsModal/ConnectWalletsModal.tsx:15 +msgid "Connect Wallets" +msgstr "Ikonekta ang mga Wallets" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/WalletsPage.tsx:82 +msgid "Choose a wallet to connect." +msgstr "Pumili ng wallet upang kumonekta." + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:25 +msgid "This week" +msgstr "Ngayong linggo" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:32 +msgid "This month" +msgstr "Ngayong buwan" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:39 +msgid "This year" +msgstr "Ngayong taon" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:129 +msgid "Required: >= {min} {symbol}" +msgstr "Kinakailangan: >= {min} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:142 +msgid "Required: > {min} {symbol}" +msgstr "Kinakailangan: > {min} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:157 +msgid "Required: <= {max} {symbol}" +msgstr "Kinakailangan: <= {max} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:170 +msgid "Required: < {max} {symbol}" +msgstr "Kinakailangan: < {max} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:601 +msgid " for network fee" +msgstr " para sa bayad sa network" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:604 +msgid " for swap" +msgstr " para sa swap" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:607 +msgid " for input and network fee" +msgstr " para sa input at bayad sa network" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:609 +msgid "Needs ≈ {requiredAmount} {symbol}{reason}, but you have {currentAmount} {symbol} in your {blockchain} wallet." +msgstr "Kailangan ng ≈ {requiredAmount} {symbol}{reason}, ngunit mayroon kang {currentAmount} {symbol} sa iyong {blockchain} wallet." + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:669 +msgid "Waiting for connecting wallet" +msgstr "Naghihintay para sa pagkonekta ng wallet" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:673 +msgid "Waiting for other running tasks to be finished" +msgstr "Naghihintay na matapos ang iba pang tumatakbong gawain" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:676 +msgid "Waiting for changing wallet network" +msgstr "Naghihintay para sa pagpapalit ng network ng wallet" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:6 +msgid "Sunday" +msgstr "Linggo" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:7 +msgid "Monday" +msgstr "Lunes" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:8 +msgid "Tuesday" +msgstr "Martes" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:9 +msgid "Wednesday" +msgstr "Miyerkules" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:10 +msgid "Thursday" +msgstr "Huwebes" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:11 +msgid "Friday" +msgstr "Biyernes" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:12 +msgid "Saturday" +msgstr "Sabado" + +#. js-lingui-explicit-id +#: widget/ui/src/components/BottomLogo/BottomLogo.tsx:14 +msgid "Powered By" +msgstr "Pinapatakbo ng" + +#. js-lingui-explicit-id +#: widget/ui/src/components/FullExpandedQuote/FullExpandedQuote.Tooltip.tsx:37 +msgid "Aggregated Transaction" +msgstr "Pinagsama-samang Transaksyon" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SelectableCategoryList/SelectableCategoryList.tsx:63 +msgid "{blockchainCategory}" +msgstr "{blockchainCategory}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/StepDetails/StepDetails.tsx:75 +#: widget/ui/src/components/StepDetails/StepDetails.tsx:102 +msgid "Swap on {fromChain} via {swapper}" +msgstr "Magpalit sa {fromChain} sa pamamagitan ng {swapper}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/StepDetails/StepDetails.tsx:109 +msgid "Bridge to {toChain} via {swapper}" +msgstr "Tulay sa {toChain} sa pamamagitan ng {swapper}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:10 +msgid "Completed" +msgstr "Nakumpleto" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:12 +msgid "In progress" +msgstr "Isinasagawa" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapToken.tsx:122 +msgid "Waiting for bridge transaction" +msgstr "Naghihintay ng bridge transaction" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:12 +msgid "Connected" +msgstr "Nakakonekta" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:13 +msgid "Disconnect" +msgstr "Idiskonekta" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:18 +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:19 +msgid "Install" +msgstr "I-install" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:24 +msgid "Connecting ..." +msgstr "Kumokonekta..." + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:25 +msgid "Connecting" +msgstr "Kumokonekta" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:30 +msgid "Disconnected" +msgstr "Nadiskonekta" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:34 +msgid "you need to pass a correct state to Wallet." +msgstr "kailangan mong ipasa ang tamang estado sa Wallet." + +#. js-lingui-explicit-id +#: widget/ui/src/containers/Notifications/NotificationNotFound.tsx:15 +msgid "There are no notifications." +msgstr "Walang mga notification." + +#. js-lingui-explicit-id +#: widget/ui/src/containers/Notifications/Notifications.tsx:39 +msgid "Clear all" +msgstr "I-clear lahat" + +#. js-lingui-explicit-id +#: widget/ui/src/containers/SwapInput/SwapInput.tsx:65 +msgid "Balance" +msgstr "Balanse" + +#. js-lingui-explicit-id +#: widget/ui/src/containers/SwapInput/SwapInput.tsx:73 +msgid "Max" +msgstr "Max" + diff --git a/translations/fr.po b/translations/fr.po new file mode 100644 index 0000000000..563a83a10e --- /dev/null +++ b/translations/fr.po @@ -0,0 +1,1339 @@ +msgid "" +msgstr "" +"POT-Creation-Date: 2023-11-06 17:24+0330\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: @lingui/cli\n" +"Language: fr\n" +"Project-Id-Version: rango\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2024-11-27 15:57\n" +"Last-Translator: \n" +"Language-Team: French\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" +"X-Crowdin-Project: rango\n" +"X-Crowdin-Project-ID: 622238\n" +"X-Crowdin-Language: fr\n" +"X-Crowdin-File: en.po\n" +"X-Crowdin-File-ID: 30\n" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SameTokensWarning/SameTokensWarning.tsx:21 +msgid "No Routes Found" +msgstr "Aucun itinéraire trouvé" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SameTokensWarning/SameTokensWarning.tsx:25 +msgid "You cannot use the same token for From and To." +msgstr "Vous ne pouvez pas utiliser le même jeton pour De et À." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:41 +#: widget/embedded/src/components/TokenList/TokenList.tsx:286 +#: widget/embedded/src/pages/HistoryPage.tsx:186 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:143 +msgid "No results found" +msgstr "Aucun résultat trouvé" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:42 +#: widget/embedded/src/components/TokenList/TokenList.tsx:287 +#: widget/embedded/src/pages/HistoryPage.tsx:193 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:144 +msgid "Try using different keywords" +msgstr "Essayez d'utiliser différents mots-clés" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:72 +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:46 +#: widget/embedded/src/pages/SelectBlockchainPage.tsx:42 +#: widget/ui/src/containers/SwapInput/TokenSection.tsx:61 +msgid "Select Chain" +msgstr "Sélectionner une chaîne" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:66 +msgid "All" +msgstr "Tous" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:100 +msgid "More +{count}" +msgstr "Plus +{count}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabAlert/ActivateTabAlert.tsx:17 +msgid "Activate this tab" +msgstr "Activer cet onglet" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabAlert/ActivateTabAlert.tsx:22 +msgid "Another tab is open and handles transactions." +msgstr "Un autre onglet est ouvert et gère les transactions." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:20 +msgid "Activate current tab" +msgstr "Activer l'onglet actuel" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:22 +msgid "Currently, some transactions are running and being handled by other browser tab. If you activate this tab, all transactions that are already in the transaction sign step will expire." +msgstr "Actuellement, certaines transactions sont en cours d'exécution et sont gérées par un autre onglet du navigateur. Si vous activez cet onglet, toutes les transactions qui sont déjà dans l'étape de signature de la transaction expireront." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:33 +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:349 +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:152 +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:33 +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:116 +msgid "Confirm" +msgstr "Valider" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:365 +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:447 +msgid "Your {blockchainName} wallets" +msgstr "Vos portefeuilles {blockchainName}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:384 +msgid "Insufficient account balance" +msgstr "Solde du compte insuffisant" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:394 +msgid "Proceed anyway" +msgstr "Continuer quand même" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:456 +msgid "You need to connect a {blockchainName} wallet." +msgstr "Vous devez connecter un portefeuille {blockchainName}." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/WalletList.tsx:143 +msgid "Add {chain} chain" +msgstr "Ajouter une chaîne {chain}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/WalletList.tsx:244 +msgid "Show more wallets" +msgstr "Afficher plus de portefeuilles" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:113 +msgid "Send to a different address" +msgstr "Envoyer à une autre adresse" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:129 +msgid "Enter {blockchainName} address" +msgstr "Entrez l'adresse {blockchainName}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:147 +msgid "Address {destination} doesn't match the blockchain address pattern." +msgstr "L'adresse {destination} ne correspond pas au modèle d'adresse blockchain." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:59 +msgid "via" +msgstr "via" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:74 +msgid "This token doesn't appear on the active token list(s). Make sure this is the token that you want to trade." +msgstr "Ce jeton n'apparaît pas dans la liste de jetons actifs. Assurez-vous qu'il s'agit du jeton que vous voulez échanger." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:89 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:164 +msgid "Import" +msgstr "Importation" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/FilterSelector/FilterSelectorContent.tsx:26 +msgid "Status" +msgstr "Statut" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/FilterSelector/FilterSelectorContent.tsx:33 +#: widget/embedded/src/components/NoResult/NoResult.helpers.ts:37 +#: widget/embedded/src/pages/SettingsPage.tsx:55 +msgid "Reset" +msgstr "Reset" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/CancelButton.tsx:18 +msgid "Cancel" +msgstr "Abandonner" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:46 +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:34 +msgid "Refresh" +msgstr "Rafraîchir" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:63 +#: widget/ui/src/containers/Notifications/Notifications.tsx:35 +msgid "Notifications" +msgstr "Notifications" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:79 +#: widget/embedded/src/pages/SettingsPage.tsx:38 +msgid "Settings" +msgstr "Réglages" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:93 +#: widget/embedded/src/pages/HistoryPage.tsx:139 +msgid "History" +msgstr "Historique" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/WalletButton.tsx:22 +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:16 +#: widget/embedded/src/constants/messages.ts:5 +msgid "Connect Wallet" +msgstr "Connecter le portefeuille" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HistoryGroupedList/HistoryGroupedList.tsx:118 +#: widget/embedded/src/utils/date.ts:18 +#: widget/embedded/src/utils/time.ts:22 +msgid "Today" +msgstr "Aujourd'hui" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/LoadingSwapDetails/LoadingSwapDetails.tsx:20 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:424 +msgid "Swaps steps" +msgstr "Étapes d'échange" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/NoResult/NoResult.helpers.ts:25 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:191 +msgid "Retry" +msgstr "Réessayer" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:149 +msgid "Slippage Error" +msgstr "Erreur de Slippage" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:150 +msgid "Slippage Warning" +msgstr "Avertissement de Slippage" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:153 +msgid "Bridge Limit Error" +msgstr "Erreur de limite de pont" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:240 +msgid "Yours: {amount} {symbol}" +msgstr "Vous: {amount} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:261 +msgid "Minimum required slippage: {minRequiredSlippage}" +msgstr "Slippage minimum requis : {minRequiredSlippage}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:282 +msgid "Yours: {userSlippage}" +msgstr "Votre: {userSlippage}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:395 +msgid "See All Routes" +msgstr "Voir toutes les routes" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:81 +msgid "View more info" +msgstr "Voir plus d'infos" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:91 +msgid "Gas & Fee Explanation" +msgstr "Explication du gaz et des frais" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:107 +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:103 +msgid "Details" +msgstr "Détails du produit" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:146 +msgid "Total Payable Fee" +msgstr "Total des frais payables" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:166 +msgid "Hide non-payable fees" +msgstr "Masquer les frais non payables" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:167 +msgid "Show non-payable fees" +msgstr "Afficher les frais non payants" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:177 +msgid "Description" +msgstr "Libellé" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:181 +msgid "The following fees are considered in the transaction output and\n" +" you won’t need to pay extra gas for them." +msgstr "Les frais suivants sont pris en compte dans la production de la transaction et\n" +" vous n'aurez pas besoin de payer du gaz supplémentaire pour eux." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteSummary.tsx:25 +msgid "Swap input" +msgstr "Swap input" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteSummary.tsx:44 +msgid "Estimated output" +msgstr "Sortie estimée" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteTrigger.tsx:65 +msgid "Via:" +msgstr "Via:" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteTrigger.tsx:150 +msgid "Chains:" +msgstr "Chaînes :" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/Quotes.tsx:77 +msgid "Sort by" +msgstr "Trier par" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:17 +msgid "Smart Routing" +msgstr "Routage intelligent" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:21 +msgid "Lowest Fee" +msgstr "Frais les plus bas" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:25 +msgid "Fastest Transfer" +msgstr "Transfert le plus rapide" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:29 +msgid "Maximum Return" +msgstr "Retour maximum" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:33 +msgid "Maximum Output" +msgstr "Sortie maximale" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:43 +msgid "Swapping" +msgstr "Swapping" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:51 +msgid "Gas cost" +msgstr "Coût du gaz" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:59 +msgid "Receiving" +msgstr "Réception en cours" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:67 +msgid "Price impact" +msgstr "Impact des prix" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:35 +msgid "You need to increase slippage to at least {minRequiredSlippage} for this route." +msgstr "Vous devez augmenter le slippage à au moins {minRequiredSlippage} pour cette route." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:59 +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:61 +msgid "We recommend you to increase slippage to at least {minRequiredSlippage} for this route." +msgstr "Nous vous recommandons d'augmenter le slippage à au moins {minRequiredSlippage} pour cette route." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:68 +msgid "Caution, your slippage is high." +msgstr "Attention, votre slippage est élevé." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.tsx:78 +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.Warning.tsx:26 +msgid "Change" +msgstr "Changement" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:42 +msgid "Change settings" +msgstr "Modifier les paramètres" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:52 +msgid "High slippage" +msgstr "Haut slippage" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:53 +msgid "Low slippage" +msgstr "Slippage bas" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:57 +msgid " Caution, your slippage is high (={userSlippage}). Your trade may be front run." +msgstr " Attention, votre slippage est élevé (={userSlippage}). Votre échange peut être frontal." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:78 +msgid "Confirm anyway" +msgstr "Confirmer quand même" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:22 +msgid "Something went wrong" +msgstr "Quelque chose s'est mal passé" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:24 +msgid "Something went wrong. Please refresh the app." +msgstr "Une erreur s'est produite. Veuillez actualiser l'application." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/Slippage.tsx:38 +msgid "Slippage tolerance per swap" +msgstr "Tolérance avec glissement par swap" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/Slippage.tsx:91 +msgid "Custom" +msgstr "Personnalisé" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:11 +msgid "Your transaction will be reverted if the price changes unfavorably by more than this percentage." +msgstr "Votre transaction sera annulée si le prix change défavorablement de plus de ce pourcentage." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:16 +#: widget/embedded/src/containers/Settings/Lists.tsx:245 +msgid "Warning" +msgstr "Avertissement" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:17 +msgid "This setting is applied to each step (e.g. 1Inch, Thorchain, etc.), meaning only that specific step will be reverted, not the entire route." +msgstr "Ce paramètre est appliqué à chaque étape (par exemple, 1Inch, Thorchain, etc.), ce qui signifie que seule cette étape spécifique sera annulée, pas la route entière." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:25 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:269 +msgid "Swap Details" +msgstr "Permuter les détails" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:33 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:312 +msgid "Request ID" +msgstr "ID de la requête" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:64 +msgid "Not found" +msgstr "Non trouvé" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:65 +msgid "Swap with request ID = {requestId} not found." +msgstr "L'échange avec la requête ID = {requestId} est introuvable." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:219 +msgid "You have received {amount} {token} in {conciseAddress} wallet on {chain} chain." +msgstr "Vous avez reçu {amount} {token} dans un portefeuille {conciseAddress} sur la chaîne {chain}." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:242 +msgid "Transaction was not sent." +msgstr "La transaction n'a pas été envoyée." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:244 +msgid "{amount} {symbol} on {blockchain} remains in your wallet." +msgstr "{amount} {symbol} sur {blockchain} reste dans votre portefeuille." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:281 +msgid "Delete" +msgstr "Supprimez" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:304 +msgid "Try again" +msgstr "Réessayez" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:322 +msgid "Copied To Clipboard" +msgstr "Copié dans le presse-papiers" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:323 +msgid "Copy Request ID" +msgstr "Copier l'ID de la requête" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:346 +msgid "View on Rango Explorer" +msgstr "Voir sur Rango Explorer" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:355 +msgid "Finished at" +msgstr "Terminé à" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:355 +msgid "Created at" +msgstr "Créé le" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.tsx:50 +msgid "View transaction" +msgstr "Voir la transaction" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.Warning.tsx:49 +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:31 +msgid "Connect" +msgstr "Connecter" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:43 +msgid "Swap Successful" +msgstr "Echange Réussi" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:71 +msgid "Transaction Failed" +msgstr "La transaction a échoué" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:87 +msgid "Done" +msgstr "Fait" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:100 +msgid "Diagnosis" +msgstr "Diagnostic" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:112 +msgid "See Details" +msgstr "Voir les détails" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:13 +msgid "Cancel Swap" +msgstr "Annuler l'échange" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:14 +msgid "Are you sure you want to cancel this swap?" +msgstr "Êtes-vous sûr de vouloir annuler cet échange ?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:23 +msgid "Yes, Cancel it" +msgstr "Oui, annuler" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:32 +#: widget/embedded/src/pages/CustomTokensPage.tsx:181 +msgid "No, Continue" +msgstr "Non, continuer" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:13 +msgid "Delete Transaction" +msgstr "Supprimer la transaction" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:14 +msgid "Are you sure you want to delete this swap?" +msgstr "Êtes-vous sûr de vouloir supprimer cet échange ?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:23 +#: widget/embedded/src/pages/CustomTokensPage.tsx:171 +msgid "Yes, Delete it" +msgstr "Oui, supprimer" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:33 +#: widget/embedded/src/pages/HistoryPage.tsx:253 +msgid "No, Cancel" +msgstr "Non, Annuler" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:12 +msgid "Change Network" +msgstr "Changer de réseau" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:20 +msgid "Network Changed" +msgstr "Réseau modifié" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/TokenList/TokenList.tsx:271 +#: widget/ui/src/containers/SwapInput/TokenSection.tsx:54 +msgid "Select Token" +msgstr "Sélectionner un jeton" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:27 +msgid "Wallet Connected" +msgstr "Portefeuille connecté" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:28 +msgid "Your wallet is connected, you can use it to swap." +msgstr "Votre portefeuille est connecté, vous pouvez l'utiliser pour échanger." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:39 +msgid "Failed to Connect" +msgstr "Échec de la connexion" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:41 +msgid "Your wallet is not connected. Please try again." +msgstr "Votre portefeuille n'est pas connecté. Veuillez réessayer." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:50 +msgid "Connecting to your wallet" +msgstr "Connexion à votre portefeuille" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:51 +msgid "Click connect in your wallet popup." +msgstr "Cliquez sur se connecter dans la fenêtre pop-up de votre portefeuille." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:99 +msgid "Select Derivation Path" +msgstr "Sélectionner le chemin de dérivation" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:100 +msgid "In order to connect to {type}, you must first select a Derivation Path" +msgstr "Pour vous connecter à {type}, vous devez d'abord sélectionner un chemin de dérivation" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:118 +msgid "Choose Derivation Path Template" +msgstr "Choisir le modèle de chemin de dérivation" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:133 +msgid "Enter Path" +msgstr "Entrez le chemin d'accès" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:134 +msgid "Enter Index" +msgstr "Entrer l'index" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:15 +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:18 +msgid "Add {blockchainDisplayName} Chain" +msgstr "Ajouter une chaîne {blockchainDisplayName}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:20 +msgid "Would you like to add the {blockchainDisplayName} experimental chain to your wallet?" +msgstr "Voulez-vous ajouter la chaîne expérimentale {blockchainDisplayName} à votre portefeuille?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:22 +msgid "Please approve the experimental chain pop-up in your wallet." +msgstr "Veuillez approuver la popup de la chaîne expérimentale dans votre portefeuille." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:30 +msgid "{blockchainDisplayName} Chain Added" +msgstr "Chaîne {blockchainDisplayName} ajoutée" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:34 +msgid "The {blockchainDisplayName} chain has been successfully added to your wallet." +msgstr "La chaîne {blockchainDisplayName} a été ajoutée avec succès à votre portefeuille." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:42 +msgid "Request Rejected" +msgstr "Demande rejetée" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:43 +msgid "You've rejected adding {blockchainDisplayName} chain to your wallet." +msgstr "Vous avez rejeté l'ajout de la chaîne {blockchainDisplayName} à votre portefeuille." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:70 +msgid "Select chain types" +msgstr "Sélectionnez les types de chaînes" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:71 +msgid "This wallet supports multiple chains. Select which chain you'd like to connect to." +msgstr "Ce portefeuille prend en charge plusieurs chaînes. Sélectionnez la chaîne à laquelle vous souhaitez vous connecter." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:9 +msgid "Failed Network, Please retry your swap." +msgstr "Réseau échoué, veuillez réessayer votre swap." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:11 +msgid "Please reset your liquidity sources." +msgstr "Veuillez réinitialiser vos sources de liquidités." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:12 +msgid "You have limited the liquidity sources and this might result in Rango finding no routes. Please consider resetting your liquidity sources." +msgstr "Vous avez limité les sources de liquidités et cela pourrait conduire à ce que Rango ne trouve aucune voie. Veuillez envisager de réinitialiser vos sources de liquidité." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:17 +msgid "No Routes Found." +msgstr "Aucune route trouvée." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:18 +msgid "Reasons why Rango couldn't find a route: low liquidity on token, very low input amount or no routes available for the selected input/output token combination." +msgstr "Raison pour laquelle Rango n'a pas pu trouver de route : faible liquidité sur jeton, très faible quantité d'entrée ou aucune route disponible pour la combinaison de jeton d'entrée/sortie sélectionnée." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:23 +msgid "Bridge Limit Error: Please increase your amount." +msgstr "Erreur de limite de pont : veuillez augmenter votre montant." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:26 +msgid "Bridge Limit Error: Please decrease your amount." +msgstr "Erreur de limite de pont : veuillez réduire votre montant." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:31 +msgid "High Price Impact" +msgstr "Impact sur les prix élevés" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:32 +msgid "Price impact is too high!" +msgstr "L'impact sur les prix est trop élevé!" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:33 +msgid "The price impact is significantly higher than the allowed amount." +msgstr "L'impact sur les prix est nettement plus élevé que le montant autorisé." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:36 +msgid "Confirm high price impact" +msgstr "Confirmer l'impact élevé du prix" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:39 +msgid "Route updated and price impact is too high, try again later!" +msgstr "La mise à jour de la route et l'impact des prix est trop élevé, réessayez plus tard!" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:44 +msgid "USD Price Unknown" +msgstr "Prix USD inconnu" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:45 +msgid "USD Price Unknown, Cannot calculate Price Impact." +msgstr "Prix USD inconnu, impossible de calculer l'impact des prix." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:46 +msgid "USD Price Unknown, Cannot calculate Price Impact. The price impact may be higher than usual. Are you sure to continue the Swap?" +msgstr "Prix USD inconnu, impossible de calculer l'impact des prix. L'impact sur le prix peut être plus élevé que d'habitude. Êtes-vous sûr de vouloir continuer le swap?" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:49 +msgid "Confirm USD Price Unknown" +msgstr "Confirmer le prix en USD inconnu" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:6 +#: widget/embedded/src/pages/Home.tsx:163 +msgid "Swap" +msgstr "Permuter" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:7 +msgid "Swap anyway" +msgstr "Permuter quand même" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:8 +msgid "The route goes through Ethereum. Continue?" +msgstr "L'itinéraire passe par Ethereum. Continuer ?" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:10 +msgid "Route has been updated." +msgstr "La route a été mise à jour." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:12 +msgid "Output amount changed to {newOutputAmount} ({percentageChange}% change)." +msgstr "La quantité de sortie a été modifiée à {newOutputAmount} ({percentageChange}%)." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:20 +msgid "Route swappers has been updated." +msgstr "Les swappers de route ont été mis à jour." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:22 +msgid "Route internal coins has been updated." +msgstr "Les pièces internes de la route ont été mises à jour." + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/ExpandedQuotes/ExpandedQuotes.tsx:53 +#: widget/embedded/src/pages/Routes.tsx:48 +msgid "Routes" +msgstr "Routes" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Inputs/Inputs.tsx:76 +msgid "From" +msgstr "A partir de" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Inputs/Inputs.tsx:118 +msgid "To" +msgstr "À" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:49 +msgid "Light" +msgstr "Lumière" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:58 +msgid "Dark" +msgstr "Sombre" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:67 +msgid "Auto" +msgstr "Automatique" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:140 +msgid "Loading failed" +msgstr "Échec du chargement" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:156 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:41 +msgid "Bridges" +msgstr "Ponts de connexion" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:174 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:41 +msgid "Exchanges" +msgstr "Échanges" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:195 +#: widget/embedded/src/pages/CustomTokensPage.tsx:90 +msgid "Custom Tokens" +msgstr "Jetons personnalisés" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:214 +#: widget/embedded/src/pages/LanguagePage.tsx:43 +msgid "Language" +msgstr "Langue" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:235 +msgid "Infinite approval" +msgstr "Approbation infinie" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:246 +msgid "Enabling the 'Infinite approval' mode grants unrestricted access to underlying smart contracts, allowing them to utilize the approved token amount without limitations." +msgstr "L'activation du mode \"Approbation infinie\" donne un accès illimité aux contrats intelligents sous-jacents, leur permettant d'utiliser le montant de jeton approuvé sans restrictions." + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:266 +msgid "Theme" +msgstr "Thème" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:39 +msgid "Duplicate Token" +msgstr "Duplicate Token" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:40 +msgid "The address you entered is duplicate, please enter a new address." +msgstr "L'adresse que vous avez saisie est dupliquée, veuillez entrer une nouvelle adresse." + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:46 +msgid "Token Already Exists" +msgstr "Le jeton existe déjà" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:47 +msgid "There's no need to add this token again because it already exists and is supported by us." +msgstr "Il n'y a pas besoin d'ajouter ce jeton à nouveau car il existe déjà et est supporté par nous." + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:53 +msgid "Token Not Found" +msgstr "Jeton introuvable" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:54 +msgid "Sorry, no token was found on {blockchain} chain with the provided address. please make sure you have entered the right token address." +msgstr "Désolé, aucun jeton n'a été trouvé sur la chaîne {blockchain} avec l'adresse fournie. Veuillez vous assurer que vous avez entré la bonne adresse de jeton." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:78 +msgid "Network Error" +msgstr "Erreur réseau" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:109 +#: widget/embedded/src/pages/CustomTokensPage.tsx:149 +msgid "Add Custom Token" +msgstr "Ajouter un jeton personnalisé" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:127 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:128 +msgid "Select chain" +msgstr "Sélectionner une chaîne" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:132 +msgid "Enter Address" +msgstr "Entrer une adresse" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:139 +msgid "Enter token address" +msgstr "Entrez l'adresse du jeton" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:176 +msgid "Failed Network, Please retry." +msgstr "Réseau échoué, veuillez réessayer." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:192 +msgid "Add another custom token" +msgstr "Ajouter un autre jeton personnalisé" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:236 +msgid "Confirm Swap" +msgstr "Confirmer l'échange" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:254 +msgid "Start Swap" +msgstr "Début de l'échange" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:282 +msgid "You get" +msgstr "Vous obtenez" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:102 +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:90 +msgid "Search Token" +msgstr "Jeton de recherche" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:134 +msgid "No custom tokens" +msgstr "Aucun jeton personnalisé" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:135 +msgid "press the button to add your custom token" +msgstr "appuyez sur le bouton pour ajouter votre jeton personnalisé" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:158 +msgid "Delete Custom Token" +msgstr "Supprimer le jeton personnalisé" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:160 +msgid "Are you sure you want to Delete this Token?" +msgstr "Êtes-vous sûr de vouloir supprimer ce jeton ?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:59 +msgid "Complete" +msgstr "Complete" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:63 +msgid "Running" +msgstr "En cours d'exécution" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:65 +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:8 +msgid "Failed" +msgstr "Echoué" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:149 +msgid "Clear" +msgstr "Nettoyer" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:161 +msgid "Search Transaction" +msgstr "Rechercher une transaction" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:187 +msgid "No transactions" +msgstr "Aucune transaction" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:194 +msgid "Your transaction history is stored locally and will appear here after you start a swap" +msgstr "Votre historique de transaction est stocké localement et apparaîtra ici après avoir démarré un swap" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:218 +msgid "Clear Transaction History" +msgstr "Effacer l'historique des transactions" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:222 +msgid "Proceeding will remove all successful and failed transactions from the widget. Do you want to continue?" +msgstr "Continuer supprimera toutes les transactions réussies et échouées du widget. Voulez-vous continuer ?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:229 +msgid "Note: This does not erase your transaction history on the chain; it only removes them here." +msgstr "Note: Cela n'efface pas votre historique de transactions dans la chaîne; cela ne les supprime que ici." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:243 +msgid "Yes, Clear the history" +msgstr "Oui, effacer l'historique" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LanguagePage.tsx:56 +msgid "language" +msgstr "Langue" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:121 +msgid "Deselect all" +msgstr "Désélectionner tout" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:121 +msgid "Select all" +msgstr "Tout sélectionner" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:133 +msgid "Search {sourceType}" +msgstr "Rechercher dans {sourceType}" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectBlockchainPage.tsx:60 +msgid "Search Chain" +msgstr "Chaîne de recherche" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:67 +msgid "Source" +msgstr "Source" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:68 +msgid "Destination" +msgstr "Destination" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:74 +msgid "Swap {type}" +msgstr "Échanger {type}" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SettingsPage.tsx:45 +msgid "Currently, you're in campaign mode with restrictions on liquidity sources. Would you like to switch out of this mode and make use of all available liquidity sources?" +msgstr "Actuellement, vous êtes en mode campagne avec des restrictions sur les sources de liquidités. Voulez-vous sortir de ce mode et utiliser toutes les sources de liquidités disponibles ?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SwapDetailsPage.tsx:27 +msgid "The request ID is necessary to display the swap details." +msgstr "L'identifiant de la requête est nécessaire pour afficher les détails du swap." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/WalletsPage.tsx:67 +#: widget/ui/src/containers/ConnectWalletsModal/ConnectWalletsModal.tsx:15 +msgid "Connect Wallets" +msgstr "Connecter les portefeuilles" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/WalletsPage.tsx:82 +msgid "Choose a wallet to connect." +msgstr "Choisissez un portefeuille à connecter." + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:25 +msgid "This week" +msgstr "Cette semaine" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:32 +msgid "This month" +msgstr "Ce mois-ci" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:39 +msgid "This year" +msgstr "Cette année" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:129 +msgid "Required: >= {min} {symbol}" +msgstr "Requis: >= {min} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:142 +msgid "Required: > {min} {symbol}" +msgstr "Requis: > {min} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:157 +msgid "Required: <= {max} {symbol}" +msgstr "Requis: <= {max} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:170 +msgid "Required: < {max} {symbol}" +msgstr "Requis: < {max} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:601 +msgid " for network fee" +msgstr " pour frais de réseau" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:604 +msgid " for swap" +msgstr " pour swap" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:607 +msgid " for input and network fee" +msgstr " pour les frais d'entrée et de réseau" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:609 +msgid "Needs ≈ {requiredAmount} {symbol}{reason}, but you have {currentAmount} {symbol} in your {blockchain} wallet." +msgstr "Nécessite ≈ {requiredAmount} {symbol}{reason}, mais vous avez {currentAmount} {symbol} dans votre portefeuille {blockchain} ." + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:669 +msgid "Waiting for connecting wallet" +msgstr "En attente de connexion au portefeuille" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:673 +msgid "Waiting for other running tasks to be finished" +msgstr "En attente de la fin des autres tâches en cours" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:676 +msgid "Waiting for changing wallet network" +msgstr "En attente de changement de réseau du portefeuille" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:6 +msgid "Sunday" +msgstr "Dimanche" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:7 +msgid "Monday" +msgstr "Lundi" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:8 +msgid "Tuesday" +msgstr "Mardi" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:9 +msgid "Wednesday" +msgstr "Mercredi" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:10 +msgid "Thursday" +msgstr "Jeudi" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:11 +msgid "Friday" +msgstr "Vendredi" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:12 +msgid "Saturday" +msgstr "Samedi" + +#. js-lingui-explicit-id +#: widget/ui/src/components/BottomLogo/BottomLogo.tsx:14 +msgid "Powered By" +msgstr "Propulsé par" + +#. js-lingui-explicit-id +#: widget/ui/src/components/FullExpandedQuote/FullExpandedQuote.Tooltip.tsx:37 +msgid "Aggregated Transaction" +msgstr "Transaction agrégée" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SelectableCategoryList/SelectableCategoryList.tsx:63 +msgid "{blockchainCategory}" +msgstr "{blockchainCategory}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/StepDetails/StepDetails.tsx:75 +#: widget/ui/src/components/StepDetails/StepDetails.tsx:102 +msgid "Swap on {fromChain} via {swapper}" +msgstr "Échanger sur {fromChain} via {swapper}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/StepDetails/StepDetails.tsx:109 +msgid "Bridge to {toChain} via {swapper}" +msgstr "Pont vers {toChain} via {swapper}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:10 +msgid "Completed" +msgstr "Terminé" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:12 +msgid "In progress" +msgstr "En cours" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapToken.tsx:122 +msgid "Waiting for bridge transaction" +msgstr "En attente de la transaction de pont" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:12 +msgid "Connected" +msgstr "Connecté" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:13 +msgid "Disconnect" +msgstr "Déconnecter" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:18 +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:19 +msgid "Install" +msgstr "Installer" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:24 +msgid "Connecting ..." +msgstr "Connexion en cours..." + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:25 +msgid "Connecting" +msgstr "Connexion en cours" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:30 +msgid "Disconnected" +msgstr "Déconnecté" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:34 +msgid "you need to pass a correct state to Wallet." +msgstr "vous devez passer un état correct à Wallet." + +#. js-lingui-explicit-id +#: widget/ui/src/containers/Notifications/NotificationNotFound.tsx:15 +msgid "There are no notifications." +msgstr "Il n'y a pas de notifications." + +#. js-lingui-explicit-id +#: widget/ui/src/containers/Notifications/Notifications.tsx:39 +msgid "Clear all" +msgstr "Effacer tout" + +#. js-lingui-explicit-id +#: widget/ui/src/containers/SwapInput/SwapInput.tsx:65 +msgid "Balance" +msgstr "Solde" + +#. js-lingui-explicit-id +#: widget/ui/src/containers/SwapInput/SwapInput.tsx:73 +msgid "Max" +msgstr "Max." + diff --git a/translations/hi.po b/translations/hi.po new file mode 100644 index 0000000000..947ea026c7 --- /dev/null +++ b/translations/hi.po @@ -0,0 +1,1339 @@ +msgid "" +msgstr "" +"POT-Creation-Date: 2023-11-06 17:24+0330\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: @lingui/cli\n" +"Language: hi\n" +"Project-Id-Version: rango\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2024-11-27 15:57\n" +"Last-Translator: \n" +"Language-Team: Hindi\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Crowdin-Project: rango\n" +"X-Crowdin-Project-ID: 622238\n" +"X-Crowdin-Language: hi\n" +"X-Crowdin-File: en.po\n" +"X-Crowdin-File-ID: 30\n" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SameTokensWarning/SameTokensWarning.tsx:21 +msgid "No Routes Found" +msgstr "कोई मार्ग नहीं मिला" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SameTokensWarning/SameTokensWarning.tsx:25 +msgid "You cannot use the same token for From and To." +msgstr "आप From और To के लिए समान टोकन का उपयोग नहीं कर सकते." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:41 +#: widget/embedded/src/components/TokenList/TokenList.tsx:286 +#: widget/embedded/src/pages/HistoryPage.tsx:186 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:143 +msgid "No results found" +msgstr "कोई परिणाम नहीं मिला" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:42 +#: widget/embedded/src/components/TokenList/TokenList.tsx:287 +#: widget/embedded/src/pages/HistoryPage.tsx:193 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:144 +msgid "Try using different keywords" +msgstr "अलग-अलग कीवर्ड का उपयोग करके देखें" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:72 +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:46 +#: widget/embedded/src/pages/SelectBlockchainPage.tsx:42 +#: widget/ui/src/containers/SwapInput/TokenSection.tsx:61 +msgid "Select Chain" +msgstr "चेन चुनें" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:66 +msgid "All" +msgstr "सभी" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:100 +msgid "More +{count}" +msgstr "अधिक +{count}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabAlert/ActivateTabAlert.tsx:17 +msgid "Activate this tab" +msgstr "इस टैब को सक्रिय करें" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabAlert/ActivateTabAlert.tsx:22 +msgid "Another tab is open and handles transactions." +msgstr "एक अन्य टैब खुला है जो लेनदेन को संभालता है।" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:20 +msgid "Activate current tab" +msgstr "वर्तमान टैब सक्रिय करें" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:22 +msgid "Currently, some transactions are running and being handled by other browser tab. If you activate this tab, all transactions that are already in the transaction sign step will expire." +msgstr "वर्तमान में, कुछ लेनदेन चल रहे हैं और अन्य ब्राउज़र टैब द्वारा संभाले जा रहे हैं। यदि आप इस टैब को सक्रिय करते हैं, तो लेनदेन साइन चरण में पहले से मौजूद सभी लेनदेन समाप्त हो जाएंगे।" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:33 +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:349 +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:152 +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:33 +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:116 +msgid "Confirm" +msgstr "पुष्टि करना" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:365 +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:447 +msgid "Your {blockchainName} wallets" +msgstr "आपके {blockchainName} वॉलेट" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:384 +msgid "Insufficient account balance" +msgstr "खाता शेष अपर्याप्त है" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:394 +msgid "Proceed anyway" +msgstr "वैसे भी आगे बढ़े" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:456 +msgid "You need to connect a {blockchainName} wallet." +msgstr "आपको {blockchainName} वॉलेट कनेक्ट करना होगा।" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/WalletList.tsx:143 +msgid "Add {chain} chain" +msgstr "{chain} श्रृंखला जोड़ें" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/WalletList.tsx:244 +msgid "Show more wallets" +msgstr "अधिक वॉलेट दिखाएं" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:113 +msgid "Send to a different address" +msgstr "किसी दूसरे पते पर भेजें" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:129 +msgid "Enter {blockchainName} address" +msgstr "{blockchainName} पता दर्ज करें" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:147 +msgid "Address {destination} doesn't match the blockchain address pattern." +msgstr "पता {destination} ब्लॉकचेन पता पैटर्न से मेल नहीं खाता।" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:59 +msgid "via" +msgstr "के जरिए" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:74 +msgid "This token doesn't appear on the active token list(s). Make sure this is the token that you want to trade." +msgstr "यह टोकन सक्रिय टोकन सूची(ओं) में दिखाई नहीं देता है। सुनिश्चित करें कि यह वही टोकन है जिसका आप व्यापार करना चाहते हैं।" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:89 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:164 +msgid "Import" +msgstr "आयात" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/FilterSelector/FilterSelectorContent.tsx:26 +msgid "Status" +msgstr "स्थिति" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/FilterSelector/FilterSelectorContent.tsx:33 +#: widget/embedded/src/components/NoResult/NoResult.helpers.ts:37 +#: widget/embedded/src/pages/SettingsPage.tsx:55 +msgid "Reset" +msgstr "रीसेट करें" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/CancelButton.tsx:18 +msgid "Cancel" +msgstr "रद्द करना" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:46 +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:34 +msgid "Refresh" +msgstr "ताज़ा करना" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:63 +#: widget/ui/src/containers/Notifications/Notifications.tsx:35 +msgid "Notifications" +msgstr "सूचनाएं" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:79 +#: widget/embedded/src/pages/SettingsPage.tsx:38 +msgid "Settings" +msgstr "सेटिंग्स" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:93 +#: widget/embedded/src/pages/HistoryPage.tsx:139 +msgid "History" +msgstr "इतिहास" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/WalletButton.tsx:22 +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:16 +#: widget/embedded/src/constants/messages.ts:5 +msgid "Connect Wallet" +msgstr "वॉलेट कनेक्ट करें" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HistoryGroupedList/HistoryGroupedList.tsx:118 +#: widget/embedded/src/utils/date.ts:18 +#: widget/embedded/src/utils/time.ts:22 +msgid "Today" +msgstr "आज" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/LoadingSwapDetails/LoadingSwapDetails.tsx:20 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:424 +msgid "Swaps steps" +msgstr "कदम बदलता है" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/NoResult/NoResult.helpers.ts:25 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:191 +msgid "Retry" +msgstr "पुन: प्रयास करें" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:149 +msgid "Slippage Error" +msgstr "फिसलन त्रुटि" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:150 +msgid "Slippage Warning" +msgstr "फिसलन चेतावनी" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:153 +msgid "Bridge Limit Error" +msgstr "ब्रिज सीमा त्रुटि" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:240 +msgid "Yours: {amount} {symbol}" +msgstr "आपका: {amount} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:261 +msgid "Minimum required slippage: {minRequiredSlippage}" +msgstr "न्यूनतम आवश्यक स्लिपेज: {minRequiredSlippage}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:282 +msgid "Yours: {userSlippage}" +msgstr "आपका: {userSlippage}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:395 +msgid "See All Routes" +msgstr "सभी रूट देखें" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:81 +msgid "View more info" +msgstr "अधिक जानकारी देखें" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:91 +msgid "Gas & Fee Explanation" +msgstr "गैस एवं शुल्क स्पष्टीकरण" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:107 +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:103 +msgid "Details" +msgstr "विवरण" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:146 +msgid "Total Payable Fee" +msgstr "कुल देय शुल्क" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:166 +msgid "Hide non-payable fees" +msgstr "गैर-भुगतान योग्य शुल्क छिपाएँ" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:167 +msgid "Show non-payable fees" +msgstr "गैर-देय शुल्क दिखाएं" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:177 +msgid "Description" +msgstr "विवरण" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:181 +msgid "The following fees are considered in the transaction output and\n" +" you won’t need to pay extra gas for them." +msgstr "लेनदेन आउटपुट में निम्नलिखित शुल्कों पर विचार किया जाता है और\n" +" आपको उनके लिए अतिरिक्त गैस का भुगतान करने की आवश्यकता नहीं होगी।" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteSummary.tsx:25 +msgid "Swap input" +msgstr "इनपुट स्वैप करें" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteSummary.tsx:44 +msgid "Estimated output" +msgstr "अनुमानित उत्पादन" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteTrigger.tsx:65 +msgid "Via:" +msgstr "के जरिए:" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteTrigger.tsx:150 +msgid "Chains:" +msgstr "जंजीरें:" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/Quotes.tsx:77 +msgid "Sort by" +msgstr "इसके अनुसार क्रमबद्ध करें" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:17 +msgid "Smart Routing" +msgstr "स्मार्ट रूटिंग" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:21 +msgid "Lowest Fee" +msgstr "सबसे कम शुल्क" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:25 +msgid "Fastest Transfer" +msgstr "सबसे तेज़ स्थानांतरण" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:29 +msgid "Maximum Return" +msgstr "अधिकतम रिटर्न" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:33 +msgid "Maximum Output" +msgstr "अधिकतम आउटपुट" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:43 +msgid "Swapping" +msgstr "अदला-बदली" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:51 +msgid "Gas cost" +msgstr "गैस की लागत" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:59 +msgid "Receiving" +msgstr "प्राप्त" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:67 +msgid "Price impact" +msgstr "मूल्य प्रभाव" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:35 +msgid "You need to increase slippage to at least {minRequiredSlippage} for this route." +msgstr "आपको इस मार्ग के लिए स्लिपेज को कम से कम {minRequiredSlippage} तक बढ़ाने की आवश्यकता है।" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:59 +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:61 +msgid "We recommend you to increase slippage to at least {minRequiredSlippage} for this route." +msgstr "हम आपको इस मार्ग के लिए स्लिपेज को कम से कम {minRequiredSlippage} तक बढ़ाने की सलाह देते हैं।" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:68 +msgid "Caution, your slippage is high." +msgstr "सावधान, आपकी फिसलन अधिक है।" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.tsx:78 +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.Warning.tsx:26 +msgid "Change" +msgstr "परिवर्तन" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:42 +msgid "Change settings" +msgstr "सेटिंग्स परिवर्तित करना" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:52 +msgid "High slippage" +msgstr "उच्च फिसलन" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:53 +msgid "Low slippage" +msgstr "कम फिसलन" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:57 +msgid " Caution, your slippage is high (={userSlippage}). Your trade may be front run." +msgstr " सावधान, आपकी स्लिपेज अधिक है (={userSlippage})। आपका ट्रेड फ्रंट रन हो सकता है।" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:78 +msgid "Confirm anyway" +msgstr "फिर भी पुष्टि करें" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:22 +msgid "Something went wrong" +msgstr "कुछ गलत हो गया" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:24 +msgid "Something went wrong. Please refresh the app." +msgstr "कुछ गड़बड़ हो गई है। कृपया ऐप को रीफ़्रेश करें।" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/Slippage.tsx:38 +msgid "Slippage tolerance per swap" +msgstr "प्रति स्वैप स्लिपेज सहनशीलता" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/Slippage.tsx:91 +msgid "Custom" +msgstr "रिवाज़" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:11 +msgid "Your transaction will be reverted if the price changes unfavorably by more than this percentage." +msgstr "यदि मूल्य में इस प्रतिशत से अधिक प्रतिकूल परिवर्तन होता है तो आपका लेनदेन वापस कर दिया जाएगा।" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:16 +#: widget/embedded/src/containers/Settings/Lists.tsx:245 +msgid "Warning" +msgstr "चेतावनी" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:17 +msgid "This setting is applied to each step (e.g. 1Inch, Thorchain, etc.), meaning only that specific step will be reverted, not the entire route." +msgstr "यह सेटिंग प्रत्येक चरण पर लागू होती है (जैसे 1इंच, थोरचेन, आदि), जिसका अर्थ है कि केवल विशिष्ट चरण ही पूर्ववत किया जाएगा, संपूर्ण मार्ग नहीं।" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:25 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:269 +msgid "Swap Details" +msgstr "स्वैप विवरण" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:33 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:312 +msgid "Request ID" +msgstr "अनुरोध आईडी" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:64 +msgid "Not found" +msgstr "नहीं मिला" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:65 +msgid "Swap with request ID = {requestId} not found." +msgstr "अनुरोध आईडी = {requestId} के साथ स्वैप नहीं मिला." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:219 +msgid "You have received {amount} {token} in {conciseAddress} wallet on {chain} chain." +msgstr "आपको {chain} चेन पर {conciseAddress} वॉलेट में {amount} {token} प्राप्त हुआ है।" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:242 +msgid "Transaction was not sent." +msgstr "लेन-देन नहीं भेजा गया." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:244 +msgid "{amount} {symbol} on {blockchain} remains in your wallet." +msgstr "{amount} {symbol} पर {blockchain} आपके वॉलेट में रहता है।" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:281 +msgid "Delete" +msgstr "मिटाना" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:304 +msgid "Try again" +msgstr "पुनः प्रयास करें" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:322 +msgid "Copied To Clipboard" +msgstr "क्लिपबोर्ड पर कॉपी किया गया" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:323 +msgid "Copy Request ID" +msgstr "अनुरोध आईडी कॉपी करें" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:346 +msgid "View on Rango Explorer" +msgstr "रैंगो एक्सप्लोरर पर देखें" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:355 +msgid "Finished at" +msgstr "पर समाप्त" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:355 +msgid "Created at" +msgstr "पर बनाया गया" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.tsx:50 +msgid "View transaction" +msgstr "लेन-देन देखें" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.Warning.tsx:49 +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:31 +msgid "Connect" +msgstr "जोड़ना" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:43 +msgid "Swap Successful" +msgstr "स्वैप सफल" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:71 +msgid "Transaction Failed" +msgstr "लेन - देन विफल" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:87 +msgid "Done" +msgstr "हो गया" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:100 +msgid "Diagnosis" +msgstr "निदान" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:112 +msgid "See Details" +msgstr "विस्तृत जानकारी देखें" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:13 +msgid "Cancel Swap" +msgstr "स्वैप रद्द करें" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:14 +msgid "Are you sure you want to cancel this swap?" +msgstr "क्या आप वाकई इस स्वैप को रद्द करना चाहते हैं?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:23 +msgid "Yes, Cancel it" +msgstr "हां, इसे रद्द करें" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:32 +#: widget/embedded/src/pages/CustomTokensPage.tsx:181 +msgid "No, Continue" +msgstr "नहीं, जारी रखें" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:13 +msgid "Delete Transaction" +msgstr "लेनदेन हटाएं" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:14 +msgid "Are you sure you want to delete this swap?" +msgstr "क्या आप वाकई इस स्वैप को हटाना चाहते हैं?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:23 +#: widget/embedded/src/pages/CustomTokensPage.tsx:171 +msgid "Yes, Delete it" +msgstr "हां, इसे हटा दें" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:33 +#: widget/embedded/src/pages/HistoryPage.tsx:253 +msgid "No, Cancel" +msgstr "नहीं, रद्द करें" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:12 +msgid "Change Network" +msgstr "नेटवर्क बदलें" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:20 +msgid "Network Changed" +msgstr "नेटवर्क परिवर्तित" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/TokenList/TokenList.tsx:271 +#: widget/ui/src/containers/SwapInput/TokenSection.tsx:54 +msgid "Select Token" +msgstr "टोकन चुनें" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:27 +msgid "Wallet Connected" +msgstr "वॉलेट कनेक्टेड" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:28 +msgid "Your wallet is connected, you can use it to swap." +msgstr "आपका वॉलेट कनेक्ट हो गया है, आप इसका उपयोग स्वैप करने के लिए कर सकते हैं।" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:39 +msgid "Failed to Connect" +msgstr "जोडने में विफल" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:41 +msgid "Your wallet is not connected. Please try again." +msgstr "आपका वॉलेट कनेक्ट नहीं है। कृपया पुनः प्रयास करें।" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:50 +msgid "Connecting to your wallet" +msgstr "अपने वॉलेट से कनेक्ट करना" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:51 +msgid "Click connect in your wallet popup." +msgstr "अपने वॉलेट पॉपअप में कनेक्ट पर क्लिक करें।" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:99 +msgid "Select Derivation Path" +msgstr "व्युत्पत्ति पथ चुनें" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:100 +msgid "In order to connect to {type}, you must first select a Derivation Path" +msgstr "{type}से कनेक्ट करने के लिए, आपको पहले एक व्युत्पन्न पथ चुनना होगा" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:118 +msgid "Choose Derivation Path Template" +msgstr "व्युत्पत्ति पथ टेम्पलेट चुनें" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:133 +msgid "Enter Path" +msgstr "पथ दर्ज करें" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:134 +msgid "Enter Index" +msgstr "सूचकांक दर्ज करें" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:15 +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:18 +msgid "Add {blockchainDisplayName} Chain" +msgstr "{blockchainDisplayName} चेन जोड़ें" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:20 +msgid "Would you like to add the {blockchainDisplayName} experimental chain to your wallet?" +msgstr "क्या आप अपने वॉलेट में {blockchainDisplayName} प्रायोगिक श्रृंखला जोड़ना चाहेंगे?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:22 +msgid "Please approve the experimental chain pop-up in your wallet." +msgstr "कृपया अपने वॉलेट में प्रायोगिक श्रृंखला पॉप-अप को अनुमोदित करें।" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:30 +msgid "{blockchainDisplayName} Chain Added" +msgstr "{blockchainDisplayName} श्रृंखला जोड़ी गई" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:34 +msgid "The {blockchainDisplayName} chain has been successfully added to your wallet." +msgstr "{blockchainDisplayName} श्रृंखला आपके वॉलेट में सफलतापूर्वक जोड़ दी गई है।" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:42 +msgid "Request Rejected" +msgstr "अनुरोध अस्वीकृत" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:43 +msgid "You've rejected adding {blockchainDisplayName} chain to your wallet." +msgstr "आपने अपने वॉलेट में {blockchainDisplayName} चेन जोड़ने को अस्वीकार कर दिया है।" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:70 +msgid "Select chain types" +msgstr "चेन प्रकार चुनें" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:71 +msgid "This wallet supports multiple chains. Select which chain you'd like to connect to." +msgstr "यह वॉलेट कई चेन को सपोर्ट करता है। चुनें कि आप किस चेन से कनेक्ट करना चाहते हैं।" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:9 +msgid "Failed Network, Please retry your swap." +msgstr "नेटवर्क विफल, कृपया अपना स्वैप पुनः प्रयास करें." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:11 +msgid "Please reset your liquidity sources." +msgstr "कृपया अपने तरलता स्रोतों को रीसेट करें।" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:12 +msgid "You have limited the liquidity sources and this might result in Rango finding no routes. Please consider resetting your liquidity sources." +msgstr "आपने लिक्विडिटी स्रोतों को सीमित कर दिया है और इसके परिणामस्वरूप Rango को कोई मार्ग नहीं मिल सकता है। कृपया अपने लिक्विडिटी स्रोतों को रीसेट करने पर विचार करें।" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:17 +msgid "No Routes Found." +msgstr "कोई मार्ग नहीं मिला." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:18 +msgid "Reasons why Rango couldn't find a route: low liquidity on token, very low input amount or no routes available for the selected input/output token combination." +msgstr "रैंगो को मार्ग न मिल पाने के कारण: टोकन पर कम तरलता, बहुत कम इनपुट राशि या चयनित इनपुट/आउटपुट टोकन संयोजन के लिए कोई मार्ग उपलब्ध नहीं होना।" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:23 +msgid "Bridge Limit Error: Please increase your amount." +msgstr "ब्रिज लिमिट त्रुटि: कृपया अपनी राशि बढ़ाएँ।" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:26 +msgid "Bridge Limit Error: Please decrease your amount." +msgstr "ब्रिज लिमिट त्रुटि: कृपया अपनी राशि कम करें।" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:31 +msgid "High Price Impact" +msgstr "उच्च मूल्य प्रभाव" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:32 +msgid "Price impact is too high!" +msgstr "मूल्य प्रभाव बहुत अधिक है!" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:33 +msgid "The price impact is significantly higher than the allowed amount." +msgstr "मूल्य प्रभाव अनुमत राशि से काफी अधिक है।" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:36 +msgid "Confirm high price impact" +msgstr "उच्च मूल्य प्रभाव की पुष्टि करें" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:39 +msgid "Route updated and price impact is too high, try again later!" +msgstr "मार्ग अपडेट किया गया और मूल्य प्रभाव बहुत अधिक है, बाद में पुनः प्रयास करें!" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:44 +msgid "USD Price Unknown" +msgstr "USD मूल्य अज्ञात" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:45 +msgid "USD Price Unknown, Cannot calculate Price Impact." +msgstr "USD मूल्य अज्ञात, मूल्य प्रभाव की गणना नहीं की जा सकती." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:46 +msgid "USD Price Unknown, Cannot calculate Price Impact. The price impact may be higher than usual. Are you sure to continue the Swap?" +msgstr "USD मूल्य अज्ञात है, मूल्य प्रभाव की गणना नहीं की जा सकती। मूल्य प्रभाव सामान्य से अधिक हो सकता है। क्या आप स्वैप जारी रखना चाहते हैं?" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:49 +msgid "Confirm USD Price Unknown" +msgstr "USD मूल्य की पुष्टि करें अज्ञात" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:6 +#: widget/embedded/src/pages/Home.tsx:163 +msgid "Swap" +msgstr "बदलना" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:7 +msgid "Swap anyway" +msgstr "वैसे भी स्वैप करें" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:8 +msgid "The route goes through Ethereum. Continue?" +msgstr "यह मार्ग एथेरियम से होकर जाता है। आगे बढ़ें?" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:10 +msgid "Route has been updated." +msgstr "मार्ग अद्यतन कर दिया गया है." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:12 +msgid "Output amount changed to {newOutputAmount} ({percentageChange}% change)." +msgstr "आउटपुट राशि {newOutputAmount} ({percentageChange}% परिवर्तन) में परिवर्तित हुई।" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:20 +msgid "Route swappers has been updated." +msgstr "रूट स्वैपर्स को अद्यतन कर दिया गया है।" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:22 +msgid "Route internal coins has been updated." +msgstr "रूट आंतरिक सिक्कों को अद्यतन किया गया है।" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/ExpandedQuotes/ExpandedQuotes.tsx:53 +#: widget/embedded/src/pages/Routes.tsx:48 +msgid "Routes" +msgstr "मार्गों" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Inputs/Inputs.tsx:76 +msgid "From" +msgstr "से" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Inputs/Inputs.tsx:118 +msgid "To" +msgstr "को" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:49 +msgid "Light" +msgstr "रोशनी" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:58 +msgid "Dark" +msgstr "अँधेरा" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:67 +msgid "Auto" +msgstr "ऑटो" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:140 +msgid "Loading failed" +msgstr "लोडिंग विफल" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:156 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:41 +msgid "Bridges" +msgstr "पुलों" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:174 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:41 +msgid "Exchanges" +msgstr "एक्सचेंजों" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:195 +#: widget/embedded/src/pages/CustomTokensPage.tsx:90 +msgid "Custom Tokens" +msgstr "कस्टम टोकन" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:214 +#: widget/embedded/src/pages/LanguagePage.tsx:43 +msgid "Language" +msgstr "भाषा" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:235 +msgid "Infinite approval" +msgstr "अनंत स्वीकृति" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:246 +msgid "Enabling the 'Infinite approval' mode grants unrestricted access to underlying smart contracts, allowing them to utilize the approved token amount without limitations." +msgstr "'अनंत अनुमोदन' मोड को सक्षम करने से अंतर्निहित स्मार्ट अनुबंधों तक अप्रतिबंधित पहुंच मिलती है, जिससे उन्हें बिना किसी सीमा के अनुमोदित टोकन राशि का उपयोग करने की अनुमति मिलती है।" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:266 +msgid "Theme" +msgstr "विषय" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:39 +msgid "Duplicate Token" +msgstr "डुप्लिकेट टोकन" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:40 +msgid "The address you entered is duplicate, please enter a new address." +msgstr "आपके द्वारा दर्ज किया गया पता डुप्लिकेट है, कृपया नया पता दर्ज करें।" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:46 +msgid "Token Already Exists" +msgstr "टोकन पहले से मौजूद है" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:47 +msgid "There's no need to add this token again because it already exists and is supported by us." +msgstr "इस टोकन को दोबारा जोड़ने की कोई आवश्यकता नहीं है क्योंकि यह पहले से मौजूद है और हमारे द्वारा समर्थित है।" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:53 +msgid "Token Not Found" +msgstr "टोकन नहीं मिला" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:54 +msgid "Sorry, no token was found on {blockchain} chain with the provided address. please make sure you have entered the right token address." +msgstr "क्षमा करें, दिए गए पते के साथ {blockchain} श्रृंखला पर कोई टोकन नहीं मिला। कृपया सुनिश्चित करें कि आपने सही टोकन पता दर्ज किया है।" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:78 +msgid "Network Error" +msgstr "नेटवर्क त्रुटि" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:109 +#: widget/embedded/src/pages/CustomTokensPage.tsx:149 +msgid "Add Custom Token" +msgstr "कस्टम टोकन जोड़ें" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:127 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:128 +msgid "Select chain" +msgstr "चेन चुनें" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:132 +msgid "Enter Address" +msgstr "पता दर्ज करें" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:139 +msgid "Enter token address" +msgstr "टोकन पता दर्ज करें" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:176 +msgid "Failed Network, Please retry." +msgstr "नेटवर्क विफल, कृपया पुनः प्रयास करें." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:192 +msgid "Add another custom token" +msgstr "एक और कस्टम टोकन जोड़ें" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:236 +msgid "Confirm Swap" +msgstr "स्वैप की पुष्टि करें" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:254 +msgid "Start Swap" +msgstr "स्वैप प्रारंभ करें" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:282 +msgid "You get" +msgstr "आपको मिला" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:102 +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:90 +msgid "Search Token" +msgstr "खोज टोकन" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:134 +msgid "No custom tokens" +msgstr "कोई कस्टम टोकन नहीं" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:135 +msgid "press the button to add your custom token" +msgstr "अपना कस्टम टोकन जोड़ने के लिए बटन दबाएँ" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:158 +msgid "Delete Custom Token" +msgstr "कस्टम टोकन हटाएं" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:160 +msgid "Are you sure you want to Delete this Token?" +msgstr "क्या आप वाकई इस टोकन को हटाना चाहते हैं?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:59 +msgid "Complete" +msgstr "पूरा" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:63 +msgid "Running" +msgstr "दौड़ना" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:65 +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:8 +msgid "Failed" +msgstr "असफल" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:149 +msgid "Clear" +msgstr "स्पष्ट" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:161 +msgid "Search Transaction" +msgstr "लेनदेन खोजें" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:187 +msgid "No transactions" +msgstr "कोई लेनदेन नहीं" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:194 +msgid "Your transaction history is stored locally and will appear here after you start a swap" +msgstr "आपका लेन-देन इतिहास स्थानीय रूप से संग्रहीत है और आपके द्वारा स्वैप शुरू करने के बाद यहां दिखाई देगा" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:218 +msgid "Clear Transaction History" +msgstr "लेन-देन इतिहास साफ़ करें" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:222 +msgid "Proceeding will remove all successful and failed transactions from the widget. Do you want to continue?" +msgstr "आगे बढ़ने से विजेट से सभी सफल और असफल लेनदेन हटा दिए जाएंगे। क्या आप जारी रखना चाहते हैं?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:229 +msgid "Note: This does not erase your transaction history on the chain; it only removes them here." +msgstr "ध्यान दें: इससे चेन पर आपके लेन-देन का इतिहास नहीं मिटता; यह केवल उन्हें यहां से हटाता है।" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:243 +msgid "Yes, Clear the history" +msgstr "हां, इतिहास साफ़ करें" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LanguagePage.tsx:56 +msgid "language" +msgstr "भाषा" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:121 +msgid "Deselect all" +msgstr "सबको अचयनित करो" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:121 +msgid "Select all" +msgstr "सबका चयन करें" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:133 +msgid "Search {sourceType}" +msgstr "खोज {sourceType}" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectBlockchainPage.tsx:60 +msgid "Search Chain" +msgstr "खोज श्रृंखला" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:67 +msgid "Source" +msgstr "स्रोत" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:68 +msgid "Destination" +msgstr "गंतव्य" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:74 +msgid "Swap {type}" +msgstr "स्वैप {type}" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SettingsPage.tsx:45 +msgid "Currently, you're in campaign mode with restrictions on liquidity sources. Would you like to switch out of this mode and make use of all available liquidity sources?" +msgstr "वर्तमान में, आप नकदी स्रोतों पर प्रतिबंधों के साथ अभियान मोड में हैं। क्या आप इस मोड से बाहर निकलना चाहेंगे और सभी उपलब्ध नकदी स्रोतों का उपयोग करना चाहेंगे?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SwapDetailsPage.tsx:27 +msgid "The request ID is necessary to display the swap details." +msgstr "स्वैप विवरण प्रदर्शित करने के लिए अनुरोध आईडी आवश्यक है।" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/WalletsPage.tsx:67 +#: widget/ui/src/containers/ConnectWalletsModal/ConnectWalletsModal.tsx:15 +msgid "Connect Wallets" +msgstr "वॉलेट कनेक्ट करें" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/WalletsPage.tsx:82 +msgid "Choose a wallet to connect." +msgstr "कनेक्ट करने के लिए एक वॉलेट चुनें." + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:25 +msgid "This week" +msgstr "इस सप्ताह" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:32 +msgid "This month" +msgstr "इस महीने" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:39 +msgid "This year" +msgstr "इस साल" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:129 +msgid "Required: >= {min} {symbol}" +msgstr "आवश्यक: >= {min} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:142 +msgid "Required: > {min} {symbol}" +msgstr "आवश्यक: > {min} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:157 +msgid "Required: <= {max} {symbol}" +msgstr "आवश्यक: <= {max} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:170 +msgid "Required: < {max} {symbol}" +msgstr "आवश्यक: < {max} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:601 +msgid " for network fee" +msgstr " नेटवर्क शुल्क के लिए" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:604 +msgid " for swap" +msgstr " अदला-बदली के लिए" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:607 +msgid " for input and network fee" +msgstr " इनपुट और नेटवर्क शुल्क के लिए" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:609 +msgid "Needs ≈ {requiredAmount} {symbol}{reason}, but you have {currentAmount} {symbol} in your {blockchain} wallet." +msgstr "≈ {requiredAmount} {symbol}{reason}की आवश्यकता है, लेकिन आपके {blockchain} वॉलेट में {currentAmount} {symbol} है।" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:669 +msgid "Waiting for connecting wallet" +msgstr "वॉलेट कनेक्ट होने की प्रतीक्षा की जा रही है" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:673 +msgid "Waiting for other running tasks to be finished" +msgstr "अन्य चल रहे कार्यों के समाप्त होने की प्रतीक्षा कर रहा हूँ" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:676 +msgid "Waiting for changing wallet network" +msgstr "वॉलेट नेटवर्क बदलने का इंतजार" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:6 +msgid "Sunday" +msgstr "रविवार" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:7 +msgid "Monday" +msgstr "सोमवार" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:8 +msgid "Tuesday" +msgstr "मंगलवार" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:9 +msgid "Wednesday" +msgstr "बुधवार" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:10 +msgid "Thursday" +msgstr "गुरुवार" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:11 +msgid "Friday" +msgstr "शुक्रवार" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:12 +msgid "Saturday" +msgstr "शनिवार" + +#. js-lingui-explicit-id +#: widget/ui/src/components/BottomLogo/BottomLogo.tsx:14 +msgid "Powered By" +msgstr "द्वारा संचालित" + +#. js-lingui-explicit-id +#: widget/ui/src/components/FullExpandedQuote/FullExpandedQuote.Tooltip.tsx:37 +msgid "Aggregated Transaction" +msgstr "समेकित लेनदेन" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SelectableCategoryList/SelectableCategoryList.tsx:63 +msgid "{blockchainCategory}" +msgstr "" + +#. js-lingui-explicit-id +#: widget/ui/src/components/StepDetails/StepDetails.tsx:75 +#: widget/ui/src/components/StepDetails/StepDetails.tsx:102 +msgid "Swap on {fromChain} via {swapper}" +msgstr "{fromChain} से {swapper}पर स्वैप करें" + +#. js-lingui-explicit-id +#: widget/ui/src/components/StepDetails/StepDetails.tsx:109 +msgid "Bridge to {toChain} via {swapper}" +msgstr "{swapper}से होकर {toChain} तक का पुल" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:10 +msgid "Completed" +msgstr "पुरा होना।" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:12 +msgid "In progress" +msgstr "प्रगति पर है" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapToken.tsx:122 +msgid "Waiting for bridge transaction" +msgstr "ब्रिज लेनदेन की प्रतीक्षा में" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:12 +msgid "Connected" +msgstr "जुड़े हुए" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:13 +msgid "Disconnect" +msgstr "डिस्कनेक्ट" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:18 +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:19 +msgid "Install" +msgstr "स्थापित करना" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:24 +msgid "Connecting ..." +msgstr "कनेक्ट कर रहा हूँ..." + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:25 +msgid "Connecting" +msgstr "कनेक्ट" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:30 +msgid "Disconnected" +msgstr "डिस्कनेक्ट किया गया" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:34 +msgid "you need to pass a correct state to Wallet." +msgstr "आपको वॉलेट को सही स्थिति पास करनी होगी।" + +#. js-lingui-explicit-id +#: widget/ui/src/containers/Notifications/NotificationNotFound.tsx:15 +msgid "There are no notifications." +msgstr "कोई सूचना नहीं है." + +#. js-lingui-explicit-id +#: widget/ui/src/containers/Notifications/Notifications.tsx:39 +msgid "Clear all" +msgstr "सभी साफ करें" + +#. js-lingui-explicit-id +#: widget/ui/src/containers/SwapInput/SwapInput.tsx:65 +msgid "Balance" +msgstr "संतुलन" + +#. js-lingui-explicit-id +#: widget/ui/src/containers/SwapInput/SwapInput.tsx:73 +msgid "Max" +msgstr "अधिकतम" + diff --git a/translations/hu.po b/translations/hu.po new file mode 100644 index 0000000000..23c823a949 --- /dev/null +++ b/translations/hu.po @@ -0,0 +1,1339 @@ +msgid "" +msgstr "" +"POT-Creation-Date: 2023-11-06 17:24+0330\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: @lingui/cli\n" +"Language: hu\n" +"Project-Id-Version: rango\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2024-11-27 15:57\n" +"Last-Translator: \n" +"Language-Team: Hungarian\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Crowdin-Project: rango\n" +"X-Crowdin-Project-ID: 622238\n" +"X-Crowdin-Language: hu\n" +"X-Crowdin-File: en.po\n" +"X-Crowdin-File-ID: 30\n" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SameTokensWarning/SameTokensWarning.tsx:21 +msgid "No Routes Found" +msgstr "Nem található útvonal" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SameTokensWarning/SameTokensWarning.tsx:25 +msgid "You cannot use the same token for From and To." +msgstr "Nem használhatja ugyanazt a tokent a Kezdő és a Címzett számára." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:41 +#: widget/embedded/src/components/TokenList/TokenList.tsx:286 +#: widget/embedded/src/pages/HistoryPage.tsx:186 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:143 +msgid "No results found" +msgstr "Nincs találat" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:42 +#: widget/embedded/src/components/TokenList/TokenList.tsx:287 +#: widget/embedded/src/pages/HistoryPage.tsx:193 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:144 +msgid "Try using different keywords" +msgstr "Próbáljon meg más kulcsszavakat használni" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:72 +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:46 +#: widget/embedded/src/pages/SelectBlockchainPage.tsx:42 +#: widget/ui/src/containers/SwapInput/TokenSection.tsx:61 +msgid "Select Chain" +msgstr "Válassza a Lánc lehetőséget" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:66 +msgid "All" +msgstr "Minden" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:100 +msgid "More +{count}" +msgstr "Továbbiak +{count}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabAlert/ActivateTabAlert.tsx:17 +msgid "Activate this tab" +msgstr "Aktiválja ezt a lapot" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabAlert/ActivateTabAlert.tsx:22 +msgid "Another tab is open and handles transactions." +msgstr "Egy másik lap nyitva van, és a tranzakciókat kezeli." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:20 +msgid "Activate current tab" +msgstr "Az aktuális lap aktiválása" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:22 +msgid "Currently, some transactions are running and being handled by other browser tab. If you activate this tab, all transactions that are already in the transaction sign step will expire." +msgstr "Jelenleg néhány tranzakció fut, és más böngészőlap kezeli őket. Ha aktiválja ezt a lapot, minden olyan tranzakció lejár, amely már benne van a tranzakció aláírási lépésében." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:33 +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:349 +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:152 +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:33 +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:116 +msgid "Confirm" +msgstr "Erősítse meg" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:365 +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:447 +msgid "Your {blockchainName} wallets" +msgstr "Az Ön {blockchainName} pénztárcája" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:384 +msgid "Insufficient account balance" +msgstr "Elégtelen számlaegyenleg" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:394 +msgid "Proceed anyway" +msgstr "Mindenképpen folytassa" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:456 +msgid "You need to connect a {blockchainName} wallet." +msgstr "Egy {blockchainName} pénztárcát kell csatlakoztatnia." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/WalletList.tsx:143 +msgid "Add {chain} chain" +msgstr "Add hozzá a {chain} láncot" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/WalletList.tsx:244 +msgid "Show more wallets" +msgstr "További pénztárcák megjelenítése" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:113 +msgid "Send to a different address" +msgstr "Küldje el egy másik címre" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:129 +msgid "Enter {blockchainName} address" +msgstr "Írja be a {blockchainName} címet" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:147 +msgid "Address {destination} doesn't match the blockchain address pattern." +msgstr "A {destination} cím nem egyezik a blokklánc címmintájával." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:59 +msgid "via" +msgstr "keresztül" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:74 +msgid "This token doesn't appear on the active token list(s). Make sure this is the token that you want to trade." +msgstr "Ez a token nem jelenik meg az aktív token listákon. Győződjön meg arról, hogy ez az a token, amellyel kereskedni szeretne." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:89 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:164 +msgid "Import" +msgstr "Importálás" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/FilterSelector/FilterSelectorContent.tsx:26 +msgid "Status" +msgstr "Állapot" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/FilterSelector/FilterSelectorContent.tsx:33 +#: widget/embedded/src/components/NoResult/NoResult.helpers.ts:37 +#: widget/embedded/src/pages/SettingsPage.tsx:55 +msgid "Reset" +msgstr "Reset" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/CancelButton.tsx:18 +msgid "Cancel" +msgstr "Mégsem" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:46 +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:34 +msgid "Refresh" +msgstr "Frissítés" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:63 +#: widget/ui/src/containers/Notifications/Notifications.tsx:35 +msgid "Notifications" +msgstr "Értesítések" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:79 +#: widget/embedded/src/pages/SettingsPage.tsx:38 +msgid "Settings" +msgstr "Beállítások elemre" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:93 +#: widget/embedded/src/pages/HistoryPage.tsx:139 +msgid "History" +msgstr "Történelem" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/WalletButton.tsx:22 +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:16 +#: widget/embedded/src/constants/messages.ts:5 +msgid "Connect Wallet" +msgstr "Wallet csatlakoztatása" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HistoryGroupedList/HistoryGroupedList.tsx:118 +#: widget/embedded/src/utils/date.ts:18 +#: widget/embedded/src/utils/time.ts:22 +msgid "Today" +msgstr "Ma" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/LoadingSwapDetails/LoadingSwapDetails.tsx:20 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:424 +msgid "Swaps steps" +msgstr "Felcseréli a lépéseket" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/NoResult/NoResult.helpers.ts:25 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:191 +msgid "Retry" +msgstr "Próbálja újra" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:149 +msgid "Slippage Error" +msgstr "Csúszási hiba" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:150 +msgid "Slippage Warning" +msgstr "Csúszásra figyelmeztetés" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:153 +msgid "Bridge Limit Error" +msgstr "Bridge Limit hiba" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:240 +msgid "Yours: {amount} {symbol}" +msgstr "A tiéd: {amount} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:261 +msgid "Minimum required slippage: {minRequiredSlippage}" +msgstr "Minimális szükséges csúszás: {minRequiredSlippage}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:282 +msgid "Yours: {userSlippage}" +msgstr "A tiéd: {userSlippage}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:395 +msgid "See All Routes" +msgstr "Lásd: Összes útvonal" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:81 +msgid "View more info" +msgstr "További információk megtekintése" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:91 +msgid "Gas & Fee Explanation" +msgstr "Gáz és díj magyarázata" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:107 +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:103 +msgid "Details" +msgstr "Részletek" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:146 +msgid "Total Payable Fee" +msgstr "Teljes fizetendő díj" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:166 +msgid "Hide non-payable fees" +msgstr "A nem fizetendő díjak elrejtése" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:167 +msgid "Show non-payable fees" +msgstr "Mutassa meg a nem fizetendő díjakat" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:177 +msgid "Description" +msgstr "Leírás" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:181 +msgid "The following fees are considered in the transaction output and\n" +" you won’t need to pay extra gas for them." +msgstr "Az alábbi díjak figyelembe vételre kerülnek a tranzakció kimeneténél, és\n" +" ezekért nem kell külön gázt fizetni." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteSummary.tsx:25 +msgid "Swap input" +msgstr "Cserélje ki a bemenetet" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteSummary.tsx:44 +msgid "Estimated output" +msgstr "Becsült teljesítmény" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteTrigger.tsx:65 +msgid "Via:" +msgstr "Keresztül:" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteTrigger.tsx:150 +msgid "Chains:" +msgstr "Láncok:" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/Quotes.tsx:77 +msgid "Sort by" +msgstr "Rendezés" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:17 +msgid "Smart Routing" +msgstr "Intelligens útválasztás" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:21 +msgid "Lowest Fee" +msgstr "Legalacsonyabb díj" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:25 +msgid "Fastest Transfer" +msgstr "Leggyorsabb átvitel" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:29 +msgid "Maximum Return" +msgstr "Maximális megtérülés" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:33 +msgid "Maximum Output" +msgstr "Maximális kimenet" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:43 +msgid "Swapping" +msgstr "Csere" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:51 +msgid "Gas cost" +msgstr "Gáz költség" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:59 +msgid "Receiving" +msgstr "Fogadás" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:67 +msgid "Price impact" +msgstr "Árhatás" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:35 +msgid "You need to increase slippage to at least {minRequiredSlippage} for this route." +msgstr "Ehhez az útvonalhoz legalább {minRequiredSlippage} -ra kell növelnie a csúszást." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:59 +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:61 +msgid "We recommend you to increase slippage to at least {minRequiredSlippage} for this route." +msgstr "Javasoljuk, hogy ezen az útvonalon növelje a csúszást legalább {minRequiredSlippage} -ra." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:68 +msgid "Caution, your slippage is high." +msgstr "Vigyázat, nagy a csúszásod." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.tsx:78 +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.Warning.tsx:26 +msgid "Change" +msgstr "Változás" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:42 +msgid "Change settings" +msgstr "Módosítsa a beállításokat" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:52 +msgid "High slippage" +msgstr "Magas csúszás" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:53 +msgid "Low slippage" +msgstr "Alacsony csúszás" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:57 +msgid " Caution, your slippage is high (={userSlippage}). Your trade may be front run." +msgstr " Vigyázat, a csúszása nagy (={userSlippage}). Előfordulhat, hogy a kereskedelme előfut." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:78 +msgid "Confirm anyway" +msgstr "Mindenképpen erősítsd meg" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:22 +msgid "Something went wrong" +msgstr "Valami elromlott" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:24 +msgid "Something went wrong. Please refresh the app." +msgstr "Valami elromlott. Kérjük, frissítse az alkalmazást." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/Slippage.tsx:38 +msgid "Slippage tolerance per swap" +msgstr "Csúszási tűrés cserénként" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/Slippage.tsx:91 +msgid "Custom" +msgstr "Szokás" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:11 +msgid "Your transaction will be reverted if the price changes unfavorably by more than this percentage." +msgstr "Tranzakciója visszaáll, ha az ár ennél a százaléknál nagyobb mértékben változik kedvezőtlenül." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:16 +#: widget/embedded/src/containers/Settings/Lists.tsx:245 +msgid "Warning" +msgstr "Figyelmeztetés" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:17 +msgid "This setting is applied to each step (e.g. 1Inch, Thorchain, etc.), meaning only that specific step will be reverted, not the entire route." +msgstr "Ez a beállítás minden lépésre vonatkozik (pl. 1 hüvelyk, Thorchain stb.), ami azt jelenti, hogy csak az adott lépés kerül visszaállításra, nem a teljes útvonal." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:25 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:269 +msgid "Swap Details" +msgstr "Csere részletei" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:33 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:312 +msgid "Request ID" +msgstr "Kérjen azonosítót" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:64 +msgid "Not found" +msgstr "Nem található" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:65 +msgid "Swap with request ID = {requestId} not found." +msgstr "Csere kérésazonosítóval = {requestId} nem található." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:219 +msgid "You have received {amount} {token} in {conciseAddress} wallet on {chain} chain." +msgstr "{amount} {token} kapott {conciseAddress} pénztárcában a {chain} láncon." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:242 +msgid "Transaction was not sent." +msgstr "A tranzakció nem lett elküldve." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:244 +msgid "{amount} {symbol} on {blockchain} remains in your wallet." +msgstr "A {amount} {symbol} {blockchain} a pénztárcájában marad." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:281 +msgid "Delete" +msgstr "Töröl" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:304 +msgid "Try again" +msgstr "Próbáld újra" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:322 +msgid "Copied To Clipboard" +msgstr "Vágólapra másolva" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:323 +msgid "Copy Request ID" +msgstr "Kérésazonosító másolása" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:346 +msgid "View on Rango Explorer" +msgstr "Megtekintés a Rango Exploreren" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:355 +msgid "Finished at" +msgstr "Készült:" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:355 +msgid "Created at" +msgstr "Létrehozva:" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.tsx:50 +msgid "View transaction" +msgstr "Tranzakció megtekintése" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.Warning.tsx:49 +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:31 +msgid "Connect" +msgstr "Csatlakozás" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:43 +msgid "Swap Successful" +msgstr "A csere sikeres" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:71 +msgid "Transaction Failed" +msgstr "A tranzakció sikertelen" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:87 +msgid "Done" +msgstr "Kész" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:100 +msgid "Diagnosis" +msgstr "Diagnózis" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:112 +msgid "See Details" +msgstr "Lásd Részletek" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:13 +msgid "Cancel Swap" +msgstr "Csere lemondása" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:14 +msgid "Are you sure you want to cancel this swap?" +msgstr "Biztosan megszakítja ezt a cserét?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:23 +msgid "Yes, Cancel it" +msgstr "Igen, mégse" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:32 +#: widget/embedded/src/pages/CustomTokensPage.tsx:181 +msgid "No, Continue" +msgstr "Nem, folytasd" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:13 +msgid "Delete Transaction" +msgstr "Tranzakció törlése" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:14 +msgid "Are you sure you want to delete this swap?" +msgstr "Biztosan törli ezt a cserét?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:23 +#: widget/embedded/src/pages/CustomTokensPage.tsx:171 +msgid "Yes, Delete it" +msgstr "Igen, törölje" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:33 +#: widget/embedded/src/pages/HistoryPage.tsx:253 +msgid "No, Cancel" +msgstr "Nem, Mégsem" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:12 +msgid "Change Network" +msgstr "Hálózat módosítása" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:20 +msgid "Network Changed" +msgstr "Hálózat megváltozott" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/TokenList/TokenList.tsx:271 +#: widget/ui/src/containers/SwapInput/TokenSection.tsx:54 +msgid "Select Token" +msgstr "Válassza a Token lehetőséget" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:27 +msgid "Wallet Connected" +msgstr "Wallet csatlakoztatva" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:28 +msgid "Your wallet is connected, you can use it to swap." +msgstr "A pénztárcája csatlakoztatva van, használhatja cserére." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:39 +msgid "Failed to Connect" +msgstr "Nem sikerült csatlakozni" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:41 +msgid "Your wallet is not connected. Please try again." +msgstr "A pénztárca nincs csatlakoztatva. Kérjük, próbálja újra." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:50 +msgid "Connecting to your wallet" +msgstr "Csatlakozás a pénztárcához" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:51 +msgid "Click connect in your wallet popup." +msgstr "Kattintson a Connect gombra a pénztárca előugró ablakában." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:99 +msgid "Select Derivation Path" +msgstr "Válassza ki a származtatási útvonalat" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:100 +msgid "In order to connect to {type}, you must first select a Derivation Path" +msgstr "A {type}-hoz való csatlakozáshoz először ki kell választania egy származási útvonalat" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:118 +msgid "Choose Derivation Path Template" +msgstr "Válassza a származtatási útvonal sablont" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:133 +msgid "Enter Path" +msgstr "Írja be az útvonalat" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:134 +msgid "Enter Index" +msgstr "Írja be az indexet" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:15 +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:18 +msgid "Add {blockchainDisplayName} Chain" +msgstr "Add hozzá a {blockchainDisplayName} láncot" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:20 +msgid "Would you like to add the {blockchainDisplayName} experimental chain to your wallet?" +msgstr "Szeretné hozzáadni a {blockchainDisplayName} kísérleti láncot a pénztárcájához?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:22 +msgid "Please approve the experimental chain pop-up in your wallet." +msgstr "Kérjük, hagyja jóvá a kísérleti lánc előugró ablakát a pénztárcájában." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:30 +msgid "{blockchainDisplayName} Chain Added" +msgstr "{blockchainDisplayName} Lánc hozzáadva" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:34 +msgid "The {blockchainDisplayName} chain has been successfully added to your wallet." +msgstr "A {blockchainDisplayName} láncot sikeresen hozzáadtuk pénztárcájához." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:42 +msgid "Request Rejected" +msgstr "Kérelem elutasítva" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:43 +msgid "You've rejected adding {blockchainDisplayName} chain to your wallet." +msgstr "Ön elutasította a {blockchainDisplayName} lánc hozzáadását pénztárcájához." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:70 +msgid "Select chain types" +msgstr "Válasszon lánctípusokat" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:71 +msgid "This wallet supports multiple chains. Select which chain you'd like to connect to." +msgstr "Ez a pénztárca több láncot is támogat. Válassza ki, melyik lánchoz szeretne csatlakozni." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:9 +msgid "Failed Network, Please retry your swap." +msgstr "Sikertelen hálózat. Kérjük, próbálja újra a cserét." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:11 +msgid "Please reset your liquidity sources." +msgstr "Kérjük, állítsa vissza likviditási forrásait." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:12 +msgid "You have limited the liquidity sources and this might result in Rango finding no routes. Please consider resetting your liquidity sources." +msgstr "Korlátozta a likviditási forrásokat, és ez azt eredményezheti, hogy Rango nem talál útvonalat. Kérjük, fontolja meg likviditási forrásai visszaállítását." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:17 +msgid "No Routes Found." +msgstr "Nem található útvonal." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:18 +msgid "Reasons why Rango couldn't find a route: low liquidity on token, very low input amount or no routes available for the selected input/output token combination." +msgstr "Okok, amelyek miatt a Rango nem talált útvonalat: alacsony a token likviditása, nagyon alacsony a bemeneti mennyiség, vagy nincsenek elérhető útvonalak a kiválasztott bemeneti/kimeneti token kombinációhoz." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:23 +msgid "Bridge Limit Error: Please increase your amount." +msgstr "Bridge Limit hiba: Kérjük, növelje az összeget." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:26 +msgid "Bridge Limit Error: Please decrease your amount." +msgstr "Bridge Limit Error: Kérjük, csökkentse az összeget." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:31 +msgid "High Price Impact" +msgstr "Magas árhatás" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:32 +msgid "Price impact is too high!" +msgstr "Az árhatás túl nagy!" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:33 +msgid "The price impact is significantly higher than the allowed amount." +msgstr "Az árhatás lényegesen nagyobb a megengedettnél." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:36 +msgid "Confirm high price impact" +msgstr "Erősítse meg a magas árhatást" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:39 +msgid "Route updated and price impact is too high, try again later!" +msgstr "Az útvonal frissítve, és az árhatás túl nagy, próbálkozzon újra később!" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:44 +msgid "USD Price Unknown" +msgstr "USD Ár Ismeretlen" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:45 +msgid "USD Price Unknown, Cannot calculate Price Impact." +msgstr "USD Ár Ismeretlen, Nem lehet kiszámítani az árhatást." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:46 +msgid "USD Price Unknown, Cannot calculate Price Impact. The price impact may be higher than usual. Are you sure to continue the Swap?" +msgstr "USD Ár Ismeretlen, Nem lehet kiszámítani az árhatást. Az árhatás a szokásosnál nagyobb lehet. Biztos, hogy folytatja a cserét?" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:49 +msgid "Confirm USD Price Unknown" +msgstr "Erősítse USD Ár Ismeretlen" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:6 +#: widget/embedded/src/pages/Home.tsx:163 +msgid "Swap" +msgstr "Csere" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:7 +msgid "Swap anyway" +msgstr "Cserélj amúgy" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:8 +msgid "The route goes through Ethereum. Continue?" +msgstr "Az út az Ethereumon keresztül vezet. Folytatja?" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:10 +msgid "Route has been updated." +msgstr "Az útvonal frissítve." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:12 +msgid "Output amount changed to {newOutputAmount} ({percentageChange}% change)." +msgstr "A kimeneti mennyiség {newOutputAmount} értékre módosult ({percentageChange}% változás)." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:20 +msgid "Route swappers has been updated." +msgstr "Az útvonalcserélők frissítve." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:22 +msgid "Route internal coins has been updated." +msgstr "Az útvonal belső érméi frissítve lettek." + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/ExpandedQuotes/ExpandedQuotes.tsx:53 +#: widget/embedded/src/pages/Routes.tsx:48 +msgid "Routes" +msgstr "Útvonalak" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Inputs/Inputs.tsx:76 +msgid "From" +msgstr "Tól" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Inputs/Inputs.tsx:118 +msgid "To" +msgstr "To" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:49 +msgid "Light" +msgstr "Fény" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:58 +msgid "Dark" +msgstr "Sötét" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:67 +msgid "Auto" +msgstr "Auto" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:140 +msgid "Loading failed" +msgstr "A betöltés nem sikerült" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:156 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:41 +msgid "Bridges" +msgstr "Hidak" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:174 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:41 +msgid "Exchanges" +msgstr "Cserék" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:195 +#: widget/embedded/src/pages/CustomTokensPage.tsx:90 +msgid "Custom Tokens" +msgstr "Egyedi tokenek" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:214 +#: widget/embedded/src/pages/LanguagePage.tsx:43 +msgid "Language" +msgstr "Nyelv" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:235 +msgid "Infinite approval" +msgstr "Végtelen jóváhagyás" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:246 +msgid "Enabling the 'Infinite approval' mode grants unrestricted access to underlying smart contracts, allowing them to utilize the approved token amount without limitations." +msgstr "A „Végtelen jóváhagyás” mód engedélyezése korlátlan hozzáférést biztosít az alapul szolgáló intelligens szerződésekhez, lehetővé téve számukra a jóváhagyott token mennyiségének korlátozások nélküli felhasználását." + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:266 +msgid "Theme" +msgstr "Téma" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:39 +msgid "Duplicate Token" +msgstr "Duplicate Token" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:40 +msgid "The address you entered is duplicate, please enter a new address." +msgstr "A megadott cím ismétlődő, kérjük, adjon meg egy új címet." + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:46 +msgid "Token Already Exists" +msgstr "A token már létezik" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:47 +msgid "There's no need to add this token again because it already exists and is supported by us." +msgstr "Nem szükséges újra hozzáadni ezt a tokent, mert már létezik, és mi is támogatjuk." + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:53 +msgid "Token Not Found" +msgstr "Token nem található" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:54 +msgid "Sorry, no token was found on {blockchain} chain with the provided address. please make sure you have entered the right token address." +msgstr "Sajnáljuk, nem található token a {blockchain} láncon a megadott címmel. kérjük, ellenőrizze, hogy a megfelelő token címet adta-e meg." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:78 +msgid "Network Error" +msgstr "Hálózati hiba" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:109 +#: widget/embedded/src/pages/CustomTokensPage.tsx:149 +msgid "Add Custom Token" +msgstr "Adjon hozzá egyéni tokent" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:127 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:128 +msgid "Select chain" +msgstr "Válassza ki a láncot" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:132 +msgid "Enter Address" +msgstr "Adja meg a címet" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:139 +msgid "Enter token address" +msgstr "Írja be a token címét" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:176 +msgid "Failed Network, Please retry." +msgstr "Sikertelen hálózat, próbálkozzon újra." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:192 +msgid "Add another custom token" +msgstr "Adjon hozzá egy másik egyéni tokent" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:236 +msgid "Confirm Swap" +msgstr "Erősítse meg a cserét" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:254 +msgid "Start Swap" +msgstr "Indítsa el a Swapot" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:282 +msgid "You get" +msgstr "Megkapod" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:102 +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:90 +msgid "Search Token" +msgstr "Token keresése" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:134 +msgid "No custom tokens" +msgstr "Nincsenek egyéni tokenek" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:135 +msgid "press the button to add your custom token" +msgstr "nyomja meg a gombot az egyéni token hozzáadásához" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:158 +msgid "Delete Custom Token" +msgstr "Egyéni token törlése" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:160 +msgid "Are you sure you want to Delete this Token?" +msgstr "Biztosan törli ezt a tokent?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:59 +msgid "Complete" +msgstr "Teljes" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:63 +msgid "Running" +msgstr "Futás" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:65 +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:8 +msgid "Failed" +msgstr "Sikertelen" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:149 +msgid "Clear" +msgstr "Világos" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:161 +msgid "Search Transaction" +msgstr "Tranzakció keresése" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:187 +msgid "No transactions" +msgstr "Nincsenek tranzakciók" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:194 +msgid "Your transaction history is stored locally and will appear here after you start a swap" +msgstr "A tranzakciós előzményeket helyben tároljuk, és a csere elindítása után itt jelennek meg" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:218 +msgid "Clear Transaction History" +msgstr "Tranzakciós előzmények törlése" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:222 +msgid "Proceeding will remove all successful and failed transactions from the widget. Do you want to continue?" +msgstr "A folytatás eltávolítja az összes sikeres és sikertelen tranzakciót a widgetből. Folytatja?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:229 +msgid "Note: This does not erase your transaction history on the chain; it only removes them here." +msgstr "Megjegyzés: Ez nem törli a tranzakciós előzményeket a láncon; csak itt távolítja el őket." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:243 +msgid "Yes, Clear the history" +msgstr "Igen, törölje az előzményeket" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LanguagePage.tsx:56 +msgid "language" +msgstr "nyelv" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:121 +msgid "Deselect all" +msgstr "Törölje az összes kijelölését" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:121 +msgid "Select all" +msgstr "Válassza ki az összeset" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:133 +msgid "Search {sourceType}" +msgstr "Keresés {sourceType}" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectBlockchainPage.tsx:60 +msgid "Search Chain" +msgstr "Keresőlánc" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:67 +msgid "Source" +msgstr "Forrás" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:68 +msgid "Destination" +msgstr "Rendeltetési hely" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:74 +msgid "Swap {type}" +msgstr "Csere {type}" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SettingsPage.tsx:45 +msgid "Currently, you're in campaign mode with restrictions on liquidity sources. Would you like to switch out of this mode and make use of all available liquidity sources?" +msgstr "Jelenleg kampánymódban van, a likviditási forrásokra vonatkozó korlátozásokkal. Szeretne kilépni ebből a módból, és kihasználni az összes rendelkezésre álló likviditási forrást?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SwapDetailsPage.tsx:27 +msgid "The request ID is necessary to display the swap details." +msgstr "A kérelem azonosítója szükséges a csere részleteinek megjelenítéséhez." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/WalletsPage.tsx:67 +#: widget/ui/src/containers/ConnectWalletsModal/ConnectWalletsModal.tsx:15 +msgid "Connect Wallets" +msgstr "Csatlakoztassa a pénztárcákat" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/WalletsPage.tsx:82 +msgid "Choose a wallet to connect." +msgstr "Válasszon egy pénztárcát a csatlakoztatáshoz." + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:25 +msgid "This week" +msgstr "Ezen a héten" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:32 +msgid "This month" +msgstr "Ebben a hónapban" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:39 +msgid "This year" +msgstr "Idén" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:129 +msgid "Required: >= {min} {symbol}" +msgstr "Kötelező: >= {min} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:142 +msgid "Required: > {min} {symbol}" +msgstr "Kötelező: > {min} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:157 +msgid "Required: <= {max} {symbol}" +msgstr "Kötelező: <= {max} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:170 +msgid "Required: < {max} {symbol}" +msgstr "Kötelező: < {max} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:601 +msgid " for network fee" +msgstr " hálózati díj ellenében" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:604 +msgid " for swap" +msgstr " cserére" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:607 +msgid " for input and network fee" +msgstr " bemeneti és hálózati díjért" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:609 +msgid "Needs ≈ {requiredAmount} {symbol}{reason}, but you have {currentAmount} {symbol} in your {blockchain} wallet." +msgstr "≈ {requiredAmount} {symbol}{reason}kell, de {currentAmount} {symbol} van a {blockchain} pénztárcájában." + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:669 +msgid "Waiting for connecting wallet" +msgstr "Várakozás a pénztárca csatlakoztatására" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:673 +msgid "Waiting for other running tasks to be finished" +msgstr "Várakozás a többi futó feladat befejezésére" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:676 +msgid "Waiting for changing wallet network" +msgstr "Várakozás a pénztárcahálózat megváltoztatására" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:6 +msgid "Sunday" +msgstr "vasárnap" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:7 +msgid "Monday" +msgstr "hétfő" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:8 +msgid "Tuesday" +msgstr "kedd" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:9 +msgid "Wednesday" +msgstr "szerda" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:10 +msgid "Thursday" +msgstr "csütörtök" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:11 +msgid "Friday" +msgstr "péntek" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:12 +msgid "Saturday" +msgstr "szombat" + +#. js-lingui-explicit-id +#: widget/ui/src/components/BottomLogo/BottomLogo.tsx:14 +msgid "Powered By" +msgstr "Powered by" + +#. js-lingui-explicit-id +#: widget/ui/src/components/FullExpandedQuote/FullExpandedQuote.Tooltip.tsx:37 +msgid "Aggregated Transaction" +msgstr "Összesített Tranzakció" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SelectableCategoryList/SelectableCategoryList.tsx:63 +msgid "{blockchainCategory}" +msgstr "{blockchainCategory}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/StepDetails/StepDetails.tsx:75 +#: widget/ui/src/components/StepDetails/StepDetails.tsx:102 +msgid "Swap on {fromChain} via {swapper}" +msgstr "Csere a {fromChain} -ra {swapper}-n keresztül" + +#. js-lingui-explicit-id +#: widget/ui/src/components/StepDetails/StepDetails.tsx:109 +msgid "Bridge to {toChain} via {swapper}" +msgstr "Híd a {toChain} felé a {swapper}-n keresztül" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:10 +msgid "Completed" +msgstr "Befejezve" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:12 +msgid "In progress" +msgstr "Folyamatban van" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapToken.tsx:122 +msgid "Waiting for bridge transaction" +msgstr "Várakozás a híd tranzakcióra" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:12 +msgid "Connected" +msgstr "Csatlakozva" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:13 +msgid "Disconnect" +msgstr "Leválasztás" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:18 +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:19 +msgid "Install" +msgstr "Telepítés" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:24 +msgid "Connecting ..." +msgstr "Csatlakozás..." + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:25 +msgid "Connecting" +msgstr "Csatlakozás" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:30 +msgid "Disconnected" +msgstr "Szétkapcsolt" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:34 +msgid "you need to pass a correct state to Wallet." +msgstr "helyes állapotot kell átadnia a Walletnek." + +#. js-lingui-explicit-id +#: widget/ui/src/containers/Notifications/NotificationNotFound.tsx:15 +msgid "There are no notifications." +msgstr "Nincsenek értesítések." + +#. js-lingui-explicit-id +#: widget/ui/src/containers/Notifications/Notifications.tsx:39 +msgid "Clear all" +msgstr "Minden törlése" + +#. js-lingui-explicit-id +#: widget/ui/src/containers/SwapInput/SwapInput.tsx:65 +msgid "Balance" +msgstr "Egyensúly" + +#. js-lingui-explicit-id +#: widget/ui/src/containers/SwapInput/SwapInput.tsx:73 +msgid "Max" +msgstr "Max" + diff --git a/translations/id.po b/translations/id.po new file mode 100644 index 0000000000..1ee1bcaa1d --- /dev/null +++ b/translations/id.po @@ -0,0 +1,1339 @@ +msgid "" +msgstr "" +"POT-Creation-Date: 2023-11-06 17:24+0330\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: @lingui/cli\n" +"Language: id\n" +"Project-Id-Version: rango\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2024-11-27 15:57\n" +"Last-Translator: \n" +"Language-Team: Indonesian\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Crowdin-Project: rango\n" +"X-Crowdin-Project-ID: 622238\n" +"X-Crowdin-Language: id\n" +"X-Crowdin-File: en.po\n" +"X-Crowdin-File-ID: 30\n" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SameTokensWarning/SameTokensWarning.tsx:21 +msgid "No Routes Found" +msgstr "Tidak Ada Rute Ditemukan" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SameTokensWarning/SameTokensWarning.tsx:25 +msgid "You cannot use the same token for From and To." +msgstr "Anda tidak dapat menggunakan token yang sama untuk Dari dan Ke." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:41 +#: widget/embedded/src/components/TokenList/TokenList.tsx:286 +#: widget/embedded/src/pages/HistoryPage.tsx:186 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:143 +msgid "No results found" +msgstr "Tidak ada hasil ditemukan" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:42 +#: widget/embedded/src/components/TokenList/TokenList.tsx:287 +#: widget/embedded/src/pages/HistoryPage.tsx:193 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:144 +msgid "Try using different keywords" +msgstr "Coba gunakan kata kunci yang berbeda" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:72 +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:46 +#: widget/embedded/src/pages/SelectBlockchainPage.tsx:42 +#: widget/ui/src/containers/SwapInput/TokenSection.tsx:61 +msgid "Select Chain" +msgstr "Pilih Rantai" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:66 +msgid "All" +msgstr "Semua" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:100 +msgid "More +{count}" +msgstr "Lebih lanjut +{count}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabAlert/ActivateTabAlert.tsx:17 +msgid "Activate this tab" +msgstr "Aktifkan tab ini" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabAlert/ActivateTabAlert.tsx:22 +msgid "Another tab is open and handles transactions." +msgstr "Tab lain terbuka dan menangani transaksi." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:20 +msgid "Activate current tab" +msgstr "Aktifkan tab saat ini" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:22 +msgid "Currently, some transactions are running and being handled by other browser tab. If you activate this tab, all transactions that are already in the transaction sign step will expire." +msgstr "Saat ini, beberapa transaksi sedang berjalan dan ditangani oleh tab browser lain. Jika Anda mengaktifkan tab ini, semua transaksi yang sudah ada dalam langkah tanda tangan transaksi akan kedaluwarsa." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:33 +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:349 +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:152 +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:33 +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:116 +msgid "Confirm" +msgstr "Mengonfirmasi" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:365 +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:447 +msgid "Your {blockchainName} wallets" +msgstr "Dompet {blockchainName} Anda" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:384 +msgid "Insufficient account balance" +msgstr "Saldo akun tidak mencukupi" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:394 +msgid "Proceed anyway" +msgstr "Tetap lanjutkan saja" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:456 +msgid "You need to connect a {blockchainName} wallet." +msgstr "Anda perlu menghubungkan dompet {blockchainName} ." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/WalletList.tsx:143 +msgid "Add {chain} chain" +msgstr "Tambahkan rantai {chain}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/WalletList.tsx:244 +msgid "Show more wallets" +msgstr "Tampilkan lebih banyak dompet" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:113 +msgid "Send to a different address" +msgstr "Kirim ke alamat lain" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:129 +msgid "Enter {blockchainName} address" +msgstr "Masukkan alamat {blockchainName}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:147 +msgid "Address {destination} doesn't match the blockchain address pattern." +msgstr "Alamat {destination} tidak cocok dengan pola alamat blockchain." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:59 +msgid "via" +msgstr "melalui" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:74 +msgid "This token doesn't appear on the active token list(s). Make sure this is the token that you want to trade." +msgstr "Token ini tidak muncul pada daftar token aktif. Pastikan ini adalah token yang ingin Anda perdagangkan." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:89 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:164 +msgid "Import" +msgstr "Impor" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/FilterSelector/FilterSelectorContent.tsx:26 +msgid "Status" +msgstr "Status" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/FilterSelector/FilterSelectorContent.tsx:33 +#: widget/embedded/src/components/NoResult/NoResult.helpers.ts:37 +#: widget/embedded/src/pages/SettingsPage.tsx:55 +msgid "Reset" +msgstr "Mengatur ulang" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/CancelButton.tsx:18 +msgid "Cancel" +msgstr "Membatalkan" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:46 +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:34 +msgid "Refresh" +msgstr "Menyegarkan" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:63 +#: widget/ui/src/containers/Notifications/Notifications.tsx:35 +msgid "Notifications" +msgstr "Pemberitahuan" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:79 +#: widget/embedded/src/pages/SettingsPage.tsx:38 +msgid "Settings" +msgstr "Pengaturan" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:93 +#: widget/embedded/src/pages/HistoryPage.tsx:139 +msgid "History" +msgstr "Sejarah" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/WalletButton.tsx:22 +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:16 +#: widget/embedded/src/constants/messages.ts:5 +msgid "Connect Wallet" +msgstr "Hubungkan Dompet" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HistoryGroupedList/HistoryGroupedList.tsx:118 +#: widget/embedded/src/utils/date.ts:18 +#: widget/embedded/src/utils/time.ts:22 +msgid "Today" +msgstr "Hari ini" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/LoadingSwapDetails/LoadingSwapDetails.tsx:20 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:424 +msgid "Swaps steps" +msgstr "Langkah-langkah pertukaran" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/NoResult/NoResult.helpers.ts:25 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:191 +msgid "Retry" +msgstr "Mencoba kembali" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:149 +msgid "Slippage Error" +msgstr "Kesalahan Tergelincir" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:150 +msgid "Slippage Warning" +msgstr "Peringatan Tergelincir" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:153 +msgid "Bridge Limit Error" +msgstr "Kesalahan Batas Jembatan" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:240 +msgid "Yours: {amount} {symbol}" +msgstr "Milik Anda: {amount} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:261 +msgid "Minimum required slippage: {minRequiredSlippage}" +msgstr "Slippage minimum yang dibutuhkan: {minRequiredSlippage}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:282 +msgid "Yours: {userSlippage}" +msgstr "Milik Anda: {userSlippage}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:395 +msgid "See All Routes" +msgstr "Lihat Semua Rute" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:81 +msgid "View more info" +msgstr "Lihat info lebih lanjut" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:91 +msgid "Gas & Fee Explanation" +msgstr "Penjelasan Gas & Biaya" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:107 +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:103 +msgid "Details" +msgstr "Rincian" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:146 +msgid "Total Payable Fee" +msgstr "Total Biaya yang Harus Dibayar" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:166 +msgid "Hide non-payable fees" +msgstr "Sembunyikan biaya yang tidak dibayarkan" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:167 +msgid "Show non-payable fees" +msgstr "Tampilkan biaya yang tidak dibayarkan" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:177 +msgid "Description" +msgstr "Keterangan" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:181 +msgid "The following fees are considered in the transaction output and\n" +" you won’t need to pay extra gas for them." +msgstr "Biaya-biaya berikut dipertimbangkan dalam hasil transaksi dan\n" +" Anda tidak perlu membayar biaya gas tambahan untuk biaya-biaya tersebut." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteSummary.tsx:25 +msgid "Swap input" +msgstr "Tukar masukan" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteSummary.tsx:44 +msgid "Estimated output" +msgstr "Perkiraan keluaran" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteTrigger.tsx:65 +msgid "Via:" +msgstr "Melalui:" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteTrigger.tsx:150 +msgid "Chains:" +msgstr "Rantai:" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/Quotes.tsx:77 +msgid "Sort by" +msgstr "Urutkan berdasarkan" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:17 +msgid "Smart Routing" +msgstr "Rute Cerdas" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:21 +msgid "Lowest Fee" +msgstr "Biaya Terendah" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:25 +msgid "Fastest Transfer" +msgstr "Transfer Tercepat" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:29 +msgid "Maximum Return" +msgstr "Hasil Maksimal" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:33 +msgid "Maximum Output" +msgstr "Output Maksimum" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:43 +msgid "Swapping" +msgstr "Pertukaran" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:51 +msgid "Gas cost" +msgstr "Biaya gas" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:59 +msgid "Receiving" +msgstr "Menerima" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:67 +msgid "Price impact" +msgstr "Dampak harga" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:35 +msgid "You need to increase slippage to at least {minRequiredSlippage} for this route." +msgstr "Anda perlu meningkatkan slippage setidaknya hingga {minRequiredSlippage} untuk rute ini." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:59 +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:61 +msgid "We recommend you to increase slippage to at least {minRequiredSlippage} for this route." +msgstr "Kami sarankan Anda meningkatkan slippage minimal hingga {minRequiredSlippage} untuk rute ini." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:68 +msgid "Caution, your slippage is high." +msgstr "Perhatian, slip Anda tinggi." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.tsx:78 +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.Warning.tsx:26 +msgid "Change" +msgstr "Mengubah" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:42 +msgid "Change settings" +msgstr "Ubah pengaturan" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:52 +msgid "High slippage" +msgstr "Slip yang tinggi" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:53 +msgid "Low slippage" +msgstr "Selip rendah" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:57 +msgid " Caution, your slippage is high (={userSlippage}). Your trade may be front run." +msgstr " Perhatian, slippage Anda tinggi (={userSlippage}). Perdagangan Anda mungkin akan mengalami front run." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:78 +msgid "Confirm anyway" +msgstr "Konfirmasi saja" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:22 +msgid "Something went wrong" +msgstr "Ada yang salah" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:24 +msgid "Something went wrong. Please refresh the app." +msgstr "Terjadi kesalahan. Harap segarkan aplikasi." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/Slippage.tsx:38 +msgid "Slippage tolerance per swap" +msgstr "Toleransi selip per swap" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/Slippage.tsx:91 +msgid "Custom" +msgstr "Kebiasaan" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:11 +msgid "Your transaction will be reverted if the price changes unfavorably by more than this percentage." +msgstr "Transaksi Anda akan dibatalkan jika harga berubah tidak menguntungkan lebih dari persentase ini." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:16 +#: widget/embedded/src/containers/Settings/Lists.tsx:245 +msgid "Warning" +msgstr "Peringatan" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:17 +msgid "This setting is applied to each step (e.g. 1Inch, Thorchain, etc.), meaning only that specific step will be reverted, not the entire route." +msgstr "Pengaturan ini diterapkan pada setiap langkah (misalnya 1Inch, Thorchain, dll.), artinya hanya langkah spesifik tersebut yang akan dikembalikan, bukan keseluruhan rute." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:25 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:269 +msgid "Swap Details" +msgstr "Rincian Tukar" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:33 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:312 +msgid "Request ID" +msgstr "ID Permintaan" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:64 +msgid "Not found" +msgstr "Tidak ditemukan" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:65 +msgid "Swap with request ID = {requestId} not found." +msgstr "Penukaran dengan ID permintaan = {requestId} tidak ditemukan." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:219 +msgid "You have received {amount} {token} in {conciseAddress} wallet on {chain} chain." +msgstr "Anda telah menerima {amount} {token} di dompet {conciseAddress} di rantai {chain} ." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:242 +msgid "Transaction was not sent." +msgstr "Transaksi tidak terkirim." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:244 +msgid "{amount} {symbol} on {blockchain} remains in your wallet." +msgstr "{amount} {symbol} pada {blockchain} tetap ada di dompet Anda." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:281 +msgid "Delete" +msgstr "Menghapus" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:304 +msgid "Try again" +msgstr "Coba lagi" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:322 +msgid "Copied To Clipboard" +msgstr "Disalin ke Papan Klip" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:323 +msgid "Copy Request ID" +msgstr "Salin ID Permintaan" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:346 +msgid "View on Rango Explorer" +msgstr "Lihat di Rango Explorer" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:355 +msgid "Finished at" +msgstr "Selesai di" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:355 +msgid "Created at" +msgstr "Dibuat di" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.tsx:50 +msgid "View transaction" +msgstr "Lihat transaksi" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.Warning.tsx:49 +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:31 +msgid "Connect" +msgstr "Menghubungkan" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:43 +msgid "Swap Successful" +msgstr "Pertukaran Berhasil" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:71 +msgid "Transaction Failed" +msgstr "Transaksi Gagal" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:87 +msgid "Done" +msgstr "Selesai" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:100 +msgid "Diagnosis" +msgstr "Diagnosa" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:112 +msgid "See Details" +msgstr "Lihat Detail" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:13 +msgid "Cancel Swap" +msgstr "Batalkan Tukar" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:14 +msgid "Are you sure you want to cancel this swap?" +msgstr "Apakah Anda yakin ingin membatalkan pertukaran ini?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:23 +msgid "Yes, Cancel it" +msgstr "Ya, Batalkan" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:32 +#: widget/embedded/src/pages/CustomTokensPage.tsx:181 +msgid "No, Continue" +msgstr "Tidak, Lanjutkan" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:13 +msgid "Delete Transaction" +msgstr "Hapus Transaksi" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:14 +msgid "Are you sure you want to delete this swap?" +msgstr "Apakah Anda yakin ingin menghapus pertukaran ini?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:23 +#: widget/embedded/src/pages/CustomTokensPage.tsx:171 +msgid "Yes, Delete it" +msgstr "Ya, Hapus itu" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:33 +#: widget/embedded/src/pages/HistoryPage.tsx:253 +msgid "No, Cancel" +msgstr "Tidak, Batal" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:12 +msgid "Change Network" +msgstr "Ubah Jaringan" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:20 +msgid "Network Changed" +msgstr "Jaringan Berubah" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/TokenList/TokenList.tsx:271 +#: widget/ui/src/containers/SwapInput/TokenSection.tsx:54 +msgid "Select Token" +msgstr "Pilih Token" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:27 +msgid "Wallet Connected" +msgstr "Dompet Terhubung" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:28 +msgid "Your wallet is connected, you can use it to swap." +msgstr "Dompet Anda terhubung, Anda dapat menggunakannya untuk bertukar." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:39 +msgid "Failed to Connect" +msgstr "Gagal Terhubung" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:41 +msgid "Your wallet is not connected. Please try again." +msgstr "Dompet Anda tidak terhubung. Silakan coba lagi." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:50 +msgid "Connecting to your wallet" +msgstr "Menghubungkan ke dompet Anda" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:51 +msgid "Click connect in your wallet popup." +msgstr "Klik sambungkan pada popup dompet Anda." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:99 +msgid "Select Derivation Path" +msgstr "Pilih Jalur Derivasi" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:100 +msgid "In order to connect to {type}, you must first select a Derivation Path" +msgstr "Untuk terhubung ke {type}, Anda harus terlebih dahulu memilih Jalur Derivasi" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:118 +msgid "Choose Derivation Path Template" +msgstr "Pilih Template Jalur Derivasi" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:133 +msgid "Enter Path" +msgstr "Masukkan Jalur" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:134 +msgid "Enter Index" +msgstr "Masukkan Indeks" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:15 +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:18 +msgid "Add {blockchainDisplayName} Chain" +msgstr "Tambahkan {blockchainDisplayName} Rantai" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:20 +msgid "Would you like to add the {blockchainDisplayName} experimental chain to your wallet?" +msgstr "Apakah Anda ingin menambahkan rantai eksperimental {blockchainDisplayName} ke dompet Anda?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:22 +msgid "Please approve the experimental chain pop-up in your wallet." +msgstr "Harap setujui pop-up rantai eksperimental di dompet Anda." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:30 +msgid "{blockchainDisplayName} Chain Added" +msgstr "{blockchainDisplayName} Rantai Ditambahkan" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:34 +msgid "The {blockchainDisplayName} chain has been successfully added to your wallet." +msgstr "Rantai {blockchainDisplayName} telah berhasil ditambahkan ke dompet Anda." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:42 +msgid "Request Rejected" +msgstr "Permintaan Ditolak" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:43 +msgid "You've rejected adding {blockchainDisplayName} chain to your wallet." +msgstr "Anda telah menolak penambahan rantai {blockchainDisplayName} ke dompet Anda." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:70 +msgid "Select chain types" +msgstr "Pilih jenis rantai" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:71 +msgid "This wallet supports multiple chains. Select which chain you'd like to connect to." +msgstr "Dompet ini mendukung beberapa rantai. Pilih rantai yang ingin Anda sambungkan." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:9 +msgid "Failed Network, Please retry your swap." +msgstr "Jaringan Gagal, Silakan coba lagi pertukaran Anda." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:11 +msgid "Please reset your liquidity sources." +msgstr "Harap atur ulang sumber likuiditas Anda." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:12 +msgid "You have limited the liquidity sources and this might result in Rango finding no routes. Please consider resetting your liquidity sources." +msgstr "Anda telah membatasi sumber likuiditas dan ini dapat mengakibatkan Rango tidak menemukan rute. Harap pertimbangkan untuk mengatur ulang sumber likuiditas Anda." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:17 +msgid "No Routes Found." +msgstr "Tidak Ada Rute Ditemukan." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:18 +msgid "Reasons why Rango couldn't find a route: low liquidity on token, very low input amount or no routes available for the selected input/output token combination." +msgstr "Alasan mengapa Rango tidak dapat menemukan rute: likuiditas rendah pada token, jumlah input sangat rendah atau tidak ada rute yang tersedia untuk kombinasi token input/output yang dipilih." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:23 +msgid "Bridge Limit Error: Please increase your amount." +msgstr "Kesalahan Batas Jembatan: Harap tingkatkan jumlah Anda." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:26 +msgid "Bridge Limit Error: Please decrease your amount." +msgstr "Kesalahan Batas Jembatan: Harap kurangi jumlah Anda." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:31 +msgid "High Price Impact" +msgstr "Dampak Harga Tinggi" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:32 +msgid "Price impact is too high!" +msgstr "Dampak harga terlalu tinggi!" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:33 +msgid "The price impact is significantly higher than the allowed amount." +msgstr "Dampak harga secara signifikan lebih tinggi daripada jumlah yang diizinkan." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:36 +msgid "Confirm high price impact" +msgstr "Konfirmasi dampak harga tinggi" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:39 +msgid "Route updated and price impact is too high, try again later!" +msgstr "Rute diperbarui dan dampak harga terlalu tinggi, coba lagi nanti!" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:44 +msgid "USD Price Unknown" +msgstr "Harga USD Tidak Diketahui" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:45 +msgid "USD Price Unknown, Cannot calculate Price Impact." +msgstr "Harga USD Tidak Diketahui, Tidak dapat menghitung Dampak Harga." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:46 +msgid "USD Price Unknown, Cannot calculate Price Impact. The price impact may be higher than usual. Are you sure to continue the Swap?" +msgstr "Harga USD Tidak Diketahui, Dampak Harga Tidak Dapat Dihitung. Dampak harga mungkin lebih tinggi dari biasanya. Apakah Anda yakin untuk melanjutkan Swap?" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:49 +msgid "Confirm USD Price Unknown" +msgstr "Konfirmasi Harga USD Tidak Diketahui" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:6 +#: widget/embedded/src/pages/Home.tsx:163 +msgid "Swap" +msgstr "Menukar" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:7 +msgid "Swap anyway" +msgstr "Tukar saja" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:8 +msgid "The route goes through Ethereum. Continue?" +msgstr "Rutenya melewati Ethereum. Lanjutkan?" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:10 +msgid "Route has been updated." +msgstr "Rute telah diperbarui." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:12 +msgid "Output amount changed to {newOutputAmount} ({percentageChange}% change)." +msgstr "Jumlah keluaran berubah menjadi {newOutputAmount} ({percentageChange}% perubahan)." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:20 +msgid "Route swappers has been updated." +msgstr "Penukar rute telah diperbarui." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:22 +msgid "Route internal coins has been updated." +msgstr "Koin internal rute telah diperbarui." + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/ExpandedQuotes/ExpandedQuotes.tsx:53 +#: widget/embedded/src/pages/Routes.tsx:48 +msgid "Routes" +msgstr "Rute" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Inputs/Inputs.tsx:76 +msgid "From" +msgstr "Dari" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Inputs/Inputs.tsx:118 +msgid "To" +msgstr "Ke" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:49 +msgid "Light" +msgstr "Lampu" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:58 +msgid "Dark" +msgstr "Gelap" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:67 +msgid "Auto" +msgstr "Mobil" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:140 +msgid "Loading failed" +msgstr "Pemuatan gagal" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:156 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:41 +msgid "Bridges" +msgstr "Jembatan" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:174 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:41 +msgid "Exchanges" +msgstr "Pertukaran" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:195 +#: widget/embedded/src/pages/CustomTokensPage.tsx:90 +msgid "Custom Tokens" +msgstr "Token Kustom" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:214 +#: widget/embedded/src/pages/LanguagePage.tsx:43 +msgid "Language" +msgstr "Bahasa" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:235 +msgid "Infinite approval" +msgstr "Persetujuan tak terbatas" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:246 +msgid "Enabling the 'Infinite approval' mode grants unrestricted access to underlying smart contracts, allowing them to utilize the approved token amount without limitations." +msgstr "Mengaktifkan mode 'Persetujuan Tak Terbatas' memberikan akses tak terbatas ke kontrak pintar yang mendasarinya, yang memungkinkan mereka memanfaatkan jumlah token yang disetujui tanpa batasan." + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:266 +msgid "Theme" +msgstr "Tema" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:39 +msgid "Duplicate Token" +msgstr "Token Duplikat" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:40 +msgid "The address you entered is duplicate, please enter a new address." +msgstr "Alamat yang Anda masukkan duplikat, silakan masukkan alamat baru." + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:46 +msgid "Token Already Exists" +msgstr "Token Sudah Ada" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:47 +msgid "There's no need to add this token again because it already exists and is supported by us." +msgstr "Tidak perlu menambahkan token ini lagi karena sudah ada dan didukung oleh kami." + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:53 +msgid "Token Not Found" +msgstr "Token Tidak Ditemukan" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:54 +msgid "Sorry, no token was found on {blockchain} chain with the provided address. please make sure you have entered the right token address." +msgstr "Maaf, tidak ada token yang ditemukan pada rantai {blockchain} dengan alamat yang diberikan. Pastikan Anda telah memasukkan alamat token yang benar." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:78 +msgid "Network Error" +msgstr "Kesalahan Jaringan" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:109 +#: widget/embedded/src/pages/CustomTokensPage.tsx:149 +msgid "Add Custom Token" +msgstr "Tambahkan Token Kustom" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:127 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:128 +msgid "Select chain" +msgstr "Pilih rantai" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:132 +msgid "Enter Address" +msgstr "Masukkan Alamat" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:139 +msgid "Enter token address" +msgstr "Masukkan alamat token" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:176 +msgid "Failed Network, Please retry." +msgstr "Jaringan Gagal, Silakan coba lagi." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:192 +msgid "Add another custom token" +msgstr "Tambahkan token kustom lainnya" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:236 +msgid "Confirm Swap" +msgstr "Konfirmasi Penukaran" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:254 +msgid "Start Swap" +msgstr "Mulai Tukar" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:282 +msgid "You get" +msgstr "Kamu mendapatkan" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:102 +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:90 +msgid "Search Token" +msgstr "Pencarian Token" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:134 +msgid "No custom tokens" +msgstr "Tidak ada token khusus" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:135 +msgid "press the button to add your custom token" +msgstr "tekan tombol untuk menambahkan token khusus Anda" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:158 +msgid "Delete Custom Token" +msgstr "Hapus Token Kustom" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:160 +msgid "Are you sure you want to Delete this Token?" +msgstr "Apakah Anda yakin ingin Menghapus Token ini?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:59 +msgid "Complete" +msgstr "Menyelesaikan" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:63 +msgid "Running" +msgstr "Berlari" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:65 +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:8 +msgid "Failed" +msgstr "Gagal" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:149 +msgid "Clear" +msgstr "Jernih" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:161 +msgid "Search Transaction" +msgstr "Pencarian Transaksi" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:187 +msgid "No transactions" +msgstr "Tidak ada transaksi" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:194 +msgid "Your transaction history is stored locally and will appear here after you start a swap" +msgstr "Riwayat transaksi Anda disimpan secara lokal dan akan muncul di sini setelah Anda memulai swap" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:218 +msgid "Clear Transaction History" +msgstr "Hapus Riwayat Transaksi" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:222 +msgid "Proceeding will remove all successful and failed transactions from the widget. Do you want to continue?" +msgstr "Proses ini akan menghapus semua transaksi yang berhasil dan gagal dari widget. Apakah Anda ingin melanjutkan?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:229 +msgid "Note: This does not erase your transaction history on the chain; it only removes them here." +msgstr "Catatan: Ini tidak menghapus riwayat transaksi Anda di rantai; tetapi hanya menghapusnya di sini." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:243 +msgid "Yes, Clear the history" +msgstr "Ya, Hapus riwayat" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LanguagePage.tsx:56 +msgid "language" +msgstr "bahasa" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:121 +msgid "Deselect all" +msgstr "Batalkan pilihan semua" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:121 +msgid "Select all" +msgstr "Pilih semua" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:133 +msgid "Search {sourceType}" +msgstr "Pencarian {sourceType}" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectBlockchainPage.tsx:60 +msgid "Search Chain" +msgstr "Rantai Pencarian" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:67 +msgid "Source" +msgstr "Sumber" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:68 +msgid "Destination" +msgstr "Tujuan" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:74 +msgid "Swap {type}" +msgstr "Tukar {type}" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SettingsPage.tsx:45 +msgid "Currently, you're in campaign mode with restrictions on liquidity sources. Would you like to switch out of this mode and make use of all available liquidity sources?" +msgstr "Saat ini, Anda sedang dalam mode kampanye dengan pembatasan sumber likuiditas. Apakah Anda ingin keluar dari mode ini dan memanfaatkan semua sumber likuiditas yang tersedia?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SwapDetailsPage.tsx:27 +msgid "The request ID is necessary to display the swap details." +msgstr "ID permintaan diperlukan untuk menampilkan rincian pertukaran." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/WalletsPage.tsx:67 +#: widget/ui/src/containers/ConnectWalletsModal/ConnectWalletsModal.tsx:15 +msgid "Connect Wallets" +msgstr "Hubungkan Dompet" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/WalletsPage.tsx:82 +msgid "Choose a wallet to connect." +msgstr "Pilih dompet untuk dihubungkan." + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:25 +msgid "This week" +msgstr "Minggu ini" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:32 +msgid "This month" +msgstr "Bulan ini" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:39 +msgid "This year" +msgstr "tahun ini" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:129 +msgid "Required: >= {min} {symbol}" +msgstr "Diperlukan: >= {min} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:142 +msgid "Required: > {min} {symbol}" +msgstr "Diperlukan: > {min} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:157 +msgid "Required: <= {max} {symbol}" +msgstr "Diperlukan: <= {max} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:170 +msgid "Required: < {max} {symbol}" +msgstr "Diperlukan: < {max} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:601 +msgid " for network fee" +msgstr " untuk biaya jaringan" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:604 +msgid " for swap" +msgstr " untuk tukar" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:607 +msgid " for input and network fee" +msgstr " untuk biaya input dan jaringan" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:609 +msgid "Needs ≈ {requiredAmount} {symbol}{reason}, but you have {currentAmount} {symbol} in your {blockchain} wallet." +msgstr "Membutuhkan ≈ {requiredAmount} {symbol}{reason}, tetapi Anda memiliki {currentAmount} {symbol} di dompet {blockchain} Anda." + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:669 +msgid "Waiting for connecting wallet" +msgstr "Menunggu dompet penghubung" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:673 +msgid "Waiting for other running tasks to be finished" +msgstr "Menunggu tugas lain yang sedang berjalan untuk diselesaikan" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:676 +msgid "Waiting for changing wallet network" +msgstr "Menunggu perubahan jaringan dompet" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:6 +msgid "Sunday" +msgstr "Minggu" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:7 +msgid "Monday" +msgstr "Senin" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:8 +msgid "Tuesday" +msgstr "Selasa" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:9 +msgid "Wednesday" +msgstr "Rabu" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:10 +msgid "Thursday" +msgstr "Kamis" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:11 +msgid "Friday" +msgstr "Jumat" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:12 +msgid "Saturday" +msgstr "Sabtu" + +#. js-lingui-explicit-id +#: widget/ui/src/components/BottomLogo/BottomLogo.tsx:14 +msgid "Powered By" +msgstr "Didukung Oleh" + +#. js-lingui-explicit-id +#: widget/ui/src/components/FullExpandedQuote/FullExpandedQuote.Tooltip.tsx:37 +msgid "Aggregated Transaction" +msgstr "Transaksi Agregat" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SelectableCategoryList/SelectableCategoryList.tsx:63 +msgid "{blockchainCategory}" +msgstr "{blockchainCategory}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/StepDetails/StepDetails.tsx:75 +#: widget/ui/src/components/StepDetails/StepDetails.tsx:102 +msgid "Swap on {fromChain} via {swapper}" +msgstr "Tukar pada {fromChain} melalui {swapper}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/StepDetails/StepDetails.tsx:109 +msgid "Bridge to {toChain} via {swapper}" +msgstr "Jembatan menuju {toChain} melalui {swapper}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:10 +msgid "Completed" +msgstr "Selesai" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:12 +msgid "In progress" +msgstr "Sedang berlangsung" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapToken.tsx:122 +msgid "Waiting for bridge transaction" +msgstr "Menunggu transaksi jembatan" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:12 +msgid "Connected" +msgstr "Terhubung" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:13 +msgid "Disconnect" +msgstr "Memutuskan" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:18 +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:19 +msgid "Install" +msgstr "Memasang" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:24 +msgid "Connecting ..." +msgstr "Menghubungkan ..." + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:25 +msgid "Connecting" +msgstr "Menghubungkan" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:30 +msgid "Disconnected" +msgstr "Terputus" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:34 +msgid "you need to pass a correct state to Wallet." +msgstr "Anda perlu memberikan status yang benar ke Wallet." + +#. js-lingui-explicit-id +#: widget/ui/src/containers/Notifications/NotificationNotFound.tsx:15 +msgid "There are no notifications." +msgstr "Tidak ada pemberitahuan." + +#. js-lingui-explicit-id +#: widget/ui/src/containers/Notifications/Notifications.tsx:39 +msgid "Clear all" +msgstr "Hapus semuanya" + +#. js-lingui-explicit-id +#: widget/ui/src/containers/SwapInput/SwapInput.tsx:65 +msgid "Balance" +msgstr "Keseimbangan" + +#. js-lingui-explicit-id +#: widget/ui/src/containers/SwapInput/SwapInput.tsx:73 +msgid "Max" +msgstr "Maksimal" + diff --git a/translations/it.po b/translations/it.po new file mode 100644 index 0000000000..35b3935d13 --- /dev/null +++ b/translations/it.po @@ -0,0 +1,1339 @@ +msgid "" +msgstr "" +"POT-Creation-Date: 2023-11-06 17:24+0330\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: @lingui/cli\n" +"Language: it\n" +"Project-Id-Version: rango\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2024-11-27 15:57\n" +"Last-Translator: \n" +"Language-Team: Italian\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Crowdin-Project: rango\n" +"X-Crowdin-Project-ID: 622238\n" +"X-Crowdin-Language: it\n" +"X-Crowdin-File: en.po\n" +"X-Crowdin-File-ID: 30\n" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SameTokensWarning/SameTokensWarning.tsx:21 +msgid "No Routes Found" +msgstr "Nessun percorso trovato" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SameTokensWarning/SameTokensWarning.tsx:25 +msgid "You cannot use the same token for From and To." +msgstr "Non è possibile utilizzare lo stesso token per Da e A." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:41 +#: widget/embedded/src/components/TokenList/TokenList.tsx:286 +#: widget/embedded/src/pages/HistoryPage.tsx:186 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:143 +msgid "No results found" +msgstr "Nessun risultato trovato" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:42 +#: widget/embedded/src/components/TokenList/TokenList.tsx:287 +#: widget/embedded/src/pages/HistoryPage.tsx:193 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:144 +msgid "Try using different keywords" +msgstr "Prova a usare parole chiave diverse" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:72 +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:46 +#: widget/embedded/src/pages/SelectBlockchainPage.tsx:42 +#: widget/ui/src/containers/SwapInput/TokenSection.tsx:61 +msgid "Select Chain" +msgstr "Seleziona Catena" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:66 +msgid "All" +msgstr "Tutti" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:100 +msgid "More +{count}" +msgstr "Altro +{count}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabAlert/ActivateTabAlert.tsx:17 +msgid "Activate this tab" +msgstr "Attiva questa scheda" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabAlert/ActivateTabAlert.tsx:22 +msgid "Another tab is open and handles transactions." +msgstr "Un'altra scheda è aperta e gestisce le transazioni." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:20 +msgid "Activate current tab" +msgstr "Attiva la scheda corrente" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:22 +msgid "Currently, some transactions are running and being handled by other browser tab. If you activate this tab, all transactions that are already in the transaction sign step will expire." +msgstr "Attualmente, alcune transazioni sono in esecuzione e vengono gestite da un'altra scheda del browser. Se attivi questa scheda, tutte le transazioni che sono già nella fase del segno di transazione scadranno." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:33 +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:349 +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:152 +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:33 +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:116 +msgid "Confirm" +msgstr "Conferma" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:365 +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:447 +msgid "Your {blockchainName} wallets" +msgstr "I tuoi portafogli {blockchainName}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:384 +msgid "Insufficient account balance" +msgstr "Saldo del conto insufficiente" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:394 +msgid "Proceed anyway" +msgstr "Procedere comunque" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:456 +msgid "You need to connect a {blockchainName} wallet." +msgstr "Devi collegare un portafoglio {blockchainName}." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/WalletList.tsx:143 +msgid "Add {chain} chain" +msgstr "Aggiungi catena {chain}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/WalletList.tsx:244 +msgid "Show more wallets" +msgstr "Mostra altri portafogli" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:113 +msgid "Send to a different address" +msgstr "Invia a un indirizzo diverso" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:129 +msgid "Enter {blockchainName} address" +msgstr "Inserisci l'indirizzo {blockchainName}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:147 +msgid "Address {destination} doesn't match the blockchain address pattern." +msgstr "L'indirizzo {destination} non corrisponde al modello di indirizzo blockchain." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:59 +msgid "via" +msgstr "via" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:74 +msgid "This token doesn't appear on the active token list(s). Make sure this is the token that you want to trade." +msgstr "Questo token non appare nella lista dei token attivi. Assicurati che questo sia il token che vuoi scambiare." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:89 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:164 +msgid "Import" +msgstr "Importa" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/FilterSelector/FilterSelectorContent.tsx:26 +msgid "Status" +msgstr "Stato" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/FilterSelector/FilterSelectorContent.tsx:33 +#: widget/embedded/src/components/NoResult/NoResult.helpers.ts:37 +#: widget/embedded/src/pages/SettingsPage.tsx:55 +msgid "Reset" +msgstr "Reset" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/CancelButton.tsx:18 +msgid "Cancel" +msgstr "Annulla" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:46 +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:34 +msgid "Refresh" +msgstr "Aggiorna" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:63 +#: widget/ui/src/containers/Notifications/Notifications.tsx:35 +msgid "Notifications" +msgstr "Notifiche" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:79 +#: widget/embedded/src/pages/SettingsPage.tsx:38 +msgid "Settings" +msgstr "Impostazioni" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:93 +#: widget/embedded/src/pages/HistoryPage.tsx:139 +msgid "History" +msgstr "Storico" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/WalletButton.tsx:22 +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:16 +#: widget/embedded/src/constants/messages.ts:5 +msgid "Connect Wallet" +msgstr "Connetti Portafoglio" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HistoryGroupedList/HistoryGroupedList.tsx:118 +#: widget/embedded/src/utils/date.ts:18 +#: widget/embedded/src/utils/time.ts:22 +msgid "Today" +msgstr "Oggi" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/LoadingSwapDetails/LoadingSwapDetails.tsx:20 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:424 +msgid "Swaps steps" +msgstr "Passaggi degli swap" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/NoResult/NoResult.helpers.ts:25 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:191 +msgid "Retry" +msgstr "Riprova" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:149 +msgid "Slippage Error" +msgstr "Errore Slippage" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:150 +msgid "Slippage Warning" +msgstr "Avviso Slippage" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:153 +msgid "Bridge Limit Error" +msgstr "Errore Limite Ponte" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:240 +msgid "Yours: {amount} {symbol}" +msgstr "Tuo: {amount} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:261 +msgid "Minimum required slippage: {minRequiredSlippage}" +msgstr "Scivolo minimo richiesto: {minRequiredSlippage}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:282 +msgid "Yours: {userSlippage}" +msgstr "Tuo: {userSlippage}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:395 +msgid "See All Routes" +msgstr "Vedi Tutte Le Itinerari" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:81 +msgid "View more info" +msgstr "Vedi maggiori informazioni" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:91 +msgid "Gas & Fee Explanation" +msgstr "Spiegazione Di Gas E Commissioni" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:107 +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:103 +msgid "Details" +msgstr "Dettagli" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:146 +msgid "Total Payable Fee" +msgstr "Commissioni Pagabili Totali" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:166 +msgid "Hide non-payable fees" +msgstr "Nascondi commissioni non pagabili" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:167 +msgid "Show non-payable fees" +msgstr "Mostra commissioni non pagabili" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:177 +msgid "Description" +msgstr "Descrizione" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:181 +msgid "The following fees are considered in the transaction output and\n" +" you won’t need to pay extra gas for them." +msgstr "Le seguenti commissioni sono prese in considerazione nell'output della transazione e\n" +" non sarà necessario pagare gas extra per loro." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteSummary.tsx:25 +msgid "Swap input" +msgstr "Swap input" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteSummary.tsx:44 +msgid "Estimated output" +msgstr "Risultato stimato" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteTrigger.tsx:65 +msgid "Via:" +msgstr "Via:" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteTrigger.tsx:150 +msgid "Chains:" +msgstr "Catene:" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/Quotes.tsx:77 +msgid "Sort by" +msgstr "Ordina per" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:17 +msgid "Smart Routing" +msgstr "Routing Intelligente" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:21 +msgid "Lowest Fee" +msgstr "Tariffa Più Bassa" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:25 +msgid "Fastest Transfer" +msgstr "Trasferimento Più Veloce" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:29 +msgid "Maximum Return" +msgstr "Ritorno Massimo" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:33 +msgid "Maximum Output" +msgstr "Output Massimo" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:43 +msgid "Swapping" +msgstr "Swapping" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:51 +msgid "Gas cost" +msgstr "Costo del gas" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:59 +msgid "Receiving" +msgstr "Ricezione" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:67 +msgid "Price impact" +msgstr "Impatto sui prezzi" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:35 +msgid "You need to increase slippage to at least {minRequiredSlippage} for this route." +msgstr "È necessario aumentare lo slittamento ad almeno {minRequiredSlippage} per questo percorso." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:59 +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:61 +msgid "We recommend you to increase slippage to at least {minRequiredSlippage} for this route." +msgstr "Ti consigliamo di aumentare lo slittamento ad almeno {minRequiredSlippage} per questo percorso." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:68 +msgid "Caution, your slippage is high." +msgstr "Attenzione, il tuo slittamento è alto." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.tsx:78 +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.Warning.tsx:26 +msgid "Change" +msgstr "Cambia" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:42 +msgid "Change settings" +msgstr "Cambia impostazioni" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:52 +msgid "High slippage" +msgstr "Scivolo alto" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:53 +msgid "Low slippage" +msgstr "Scivolo basso" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:57 +msgid " Caution, your slippage is high (={userSlippage}). Your trade may be front run." +msgstr " Attenzione, il tuo slippage è alto (={userSlippage}). Il tuo trade può essere eseguito in anticipo." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:78 +msgid "Confirm anyway" +msgstr "Conferma comunque" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:22 +msgid "Something went wrong" +msgstr "Qualcosa è andato storto" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:24 +msgid "Something went wrong. Please refresh the app." +msgstr "Qualcosa è andato storto. Si prega di aggiornare l'app." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/Slippage.tsx:38 +msgid "Slippage tolerance per swap" +msgstr "Tolleranza slippage per swap" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/Slippage.tsx:91 +msgid "Custom" +msgstr "Personalizzato" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:11 +msgid "Your transaction will be reverted if the price changes unfavorably by more than this percentage." +msgstr "La tua transazione verrà ripristinata se il prezzo cambia sfavorevolmente di più di questa percentuale." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:16 +#: widget/embedded/src/containers/Settings/Lists.tsx:245 +msgid "Warning" +msgstr "Attenzione" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:17 +msgid "This setting is applied to each step (e.g. 1Inch, Thorchain, etc.), meaning only that specific step will be reverted, not the entire route." +msgstr "Questa impostazione viene applicata ad ogni passo (ad esempio 1Inch, Thorchain, ecc.), il che significa solo che il passaggio specifico sarà invertito, non l'intero percorso." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:25 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:269 +msgid "Swap Details" +msgstr "Scambia Dettagli" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:33 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:312 +msgid "Request ID" +msgstr "Richiedi Id" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:64 +msgid "Not found" +msgstr "Non trovato" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:65 +msgid "Swap with request ID = {requestId} not found." +msgstr "Scambia con ID richiesta = {requestId} non trovato." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:219 +msgid "You have received {amount} {token} in {conciseAddress} wallet on {chain} chain." +msgstr "Hai ricevuto {amount} {token} in {conciseAddress} portafoglio nella catena {chain}." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:242 +msgid "Transaction was not sent." +msgstr "La transazione non è stata inviata." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:244 +msgid "{amount} {symbol} on {blockchain} remains in your wallet." +msgstr "{amount} {symbol} su {blockchain} rimane nel tuo portafoglio." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:281 +msgid "Delete" +msgstr "Elimina" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:304 +msgid "Try again" +msgstr "Riprova" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:322 +msgid "Copied To Clipboard" +msgstr "Copiato Negli Appunti" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:323 +msgid "Copy Request ID" +msgstr "Copia Id Richiesta" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:346 +msgid "View on Rango Explorer" +msgstr "Visualizza su Rango Explorer" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:355 +msgid "Finished at" +msgstr "Terminato il" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:355 +msgid "Created at" +msgstr "Creato il" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.tsx:50 +msgid "View transaction" +msgstr "Visualizza transazione" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.Warning.tsx:49 +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:31 +msgid "Connect" +msgstr "Connetti" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:43 +msgid "Swap Successful" +msgstr "Scambia Riuscito" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:71 +msgid "Transaction Failed" +msgstr "Transazione Non Riuscita" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:87 +msgid "Done" +msgstr "Fatto" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:100 +msgid "Diagnosis" +msgstr "Diagnosi" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:112 +msgid "See Details" +msgstr "Vedi Dettagli" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:13 +msgid "Cancel Swap" +msgstr "Annulla Scambia" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:14 +msgid "Are you sure you want to cancel this swap?" +msgstr "Sei sicuro di voler annullare questo swap?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:23 +msgid "Yes, Cancel it" +msgstr "Sì, annullalo" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:32 +#: widget/embedded/src/pages/CustomTokensPage.tsx:181 +msgid "No, Continue" +msgstr "No, Continua" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:13 +msgid "Delete Transaction" +msgstr "Elimina Transazione" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:14 +msgid "Are you sure you want to delete this swap?" +msgstr "Sei sicuro di voler eliminare questo swap?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:23 +#: widget/embedded/src/pages/CustomTokensPage.tsx:171 +msgid "Yes, Delete it" +msgstr "Sì, eliminalo" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:33 +#: widget/embedded/src/pages/HistoryPage.tsx:253 +msgid "No, Cancel" +msgstr "No, Annulla" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:12 +msgid "Change Network" +msgstr "Cambia Rete" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:20 +msgid "Network Changed" +msgstr "Rete Modificata" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/TokenList/TokenList.tsx:271 +#: widget/ui/src/containers/SwapInput/TokenSection.tsx:54 +msgid "Select Token" +msgstr "Seleziona Token" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:27 +msgid "Wallet Connected" +msgstr "Portafoglio Connesso" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:28 +msgid "Your wallet is connected, you can use it to swap." +msgstr "Il tuo portafoglio è connesso, puoi usarlo per scambiare." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:39 +msgid "Failed to Connect" +msgstr "Impossibile connettersi" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:41 +msgid "Your wallet is not connected. Please try again." +msgstr "Il tuo portafoglio non è connesso. Riprova." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:50 +msgid "Connecting to your wallet" +msgstr "Connessione al tuo portafoglio" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:51 +msgid "Click connect in your wallet popup." +msgstr "Fare clic su Connetti nel tuo portafoglio popup." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:99 +msgid "Select Derivation Path" +msgstr "Seleziona Percorso Di Derivazione" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:100 +msgid "In order to connect to {type}, you must first select a Derivation Path" +msgstr "Per connetterti a {type}, devi prima selezionare un percorso di derivazione" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:118 +msgid "Choose Derivation Path Template" +msgstr "Scegli Modello Percorso Derivazione" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:133 +msgid "Enter Path" +msgstr "Inserisci Percorso" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:134 +msgid "Enter Index" +msgstr "Inserisci Indice" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:15 +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:18 +msgid "Add {blockchainDisplayName} Chain" +msgstr "Aggiungi Catena {blockchainDisplayName}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:20 +msgid "Would you like to add the {blockchainDisplayName} experimental chain to your wallet?" +msgstr "Vuoi aggiungere la catena sperimentale {blockchainDisplayName} al tuo portafoglio?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:22 +msgid "Please approve the experimental chain pop-up in your wallet." +msgstr "Si prega di approvare il pop-up della catena sperimentale nel portafoglio." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:30 +msgid "{blockchainDisplayName} Chain Added" +msgstr "{blockchainDisplayName} Catena Aggiunta" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:34 +msgid "The {blockchainDisplayName} chain has been successfully added to your wallet." +msgstr "La catena {blockchainDisplayName} è stata aggiunta con successo al tuo portafoglio." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:42 +msgid "Request Rejected" +msgstr "Richiesta Rifiutata" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:43 +msgid "You've rejected adding {blockchainDisplayName} chain to your wallet." +msgstr "Hai rifiutato l'aggiunta di una catena {blockchainDisplayName} al tuo portafoglio." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:70 +msgid "Select chain types" +msgstr "Seleziona tipi di catena" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:71 +msgid "This wallet supports multiple chains. Select which chain you'd like to connect to." +msgstr "Questo portafoglio supporta più catene. Seleziona a quale catena vuoi connetterti." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:9 +msgid "Failed Network, Please retry your swap." +msgstr "Rete fallita, riprova il tuo swap." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:11 +msgid "Please reset your liquidity sources." +msgstr "Reimposta le tue fonti di liquidità." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:12 +msgid "You have limited the liquidity sources and this might result in Rango finding no routes. Please consider resetting your liquidity sources." +msgstr "Hai limitato le fonti di liquidità e questo potrebbe portare a Rango a non trovare nessuna rotta. Si prega di considerare la possibilità di ripristinare le fonti di liquidità." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:17 +msgid "No Routes Found." +msgstr "Nessuna Rotta Trovata." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:18 +msgid "Reasons why Rango couldn't find a route: low liquidity on token, very low input amount or no routes available for the selected input/output token combination." +msgstr "Motivi per cui Rango non ha trovato un percorso: bassa liquidità sul token, quantità di input molto bassa o nessun percorso disponibile per la combinazione di token input/output selezionata." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:23 +msgid "Bridge Limit Error: Please increase your amount." +msgstr "Errore limite ponte: aumenta il tuo importo." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:26 +msgid "Bridge Limit Error: Please decrease your amount." +msgstr "Errore limite ponte: si prega di diminuire l'importo." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:31 +msgid "High Price Impact" +msgstr "Impatto Ad Alto Prezzo" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:32 +msgid "Price impact is too high!" +msgstr "L'impatto sui prezzi è troppo alto!" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:33 +msgid "The price impact is significantly higher than the allowed amount." +msgstr "L’impatto sui prezzi è significativamente superiore all’importo consentito." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:36 +msgid "Confirm high price impact" +msgstr "Conferma un impatto sui prezzi elevato" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:39 +msgid "Route updated and price impact is too high, try again later!" +msgstr "Percorso aggiornato e impatto prezzo è troppo alto, riprova più tardi!" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:44 +msgid "USD Price Unknown" +msgstr "Prezzo USD Sconosciuto" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:45 +msgid "USD Price Unknown, Cannot calculate Price Impact." +msgstr "USD Prezzo Sconosciuto, non è possibile calcolare il prezzo impatto." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:46 +msgid "USD Price Unknown, Cannot calculate Price Impact. The price impact may be higher than usual. Are you sure to continue the Swap?" +msgstr "USD Price Unknown, Cannot calculate Price Impact. The price impact may be higher than usual. Are you sure to continue the Swap?" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:49 +msgid "Confirm USD Price Unknown" +msgstr "Conferma Il Prezzo Usd Sconosciuto" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:6 +#: widget/embedded/src/pages/Home.tsx:163 +msgid "Swap" +msgstr "Scambia" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:7 +msgid "Swap anyway" +msgstr "Scambia comunque" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:8 +msgid "The route goes through Ethereum. Continue?" +msgstr "Il percorso passa attraverso Ethereum. Continuare?" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:10 +msgid "Route has been updated." +msgstr "Il percorso è stato aggiornato." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:12 +msgid "Output amount changed to {newOutputAmount} ({percentageChange}% change)." +msgstr "Importo output cambiato in {newOutputAmount} ({percentageChange}% cambio)." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:20 +msgid "Route swappers has been updated." +msgstr "Gli swappers del percorso sono stati aggiornati." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:22 +msgid "Route internal coins has been updated." +msgstr "Il percorso delle monete interne è stato aggiornato." + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/ExpandedQuotes/ExpandedQuotes.tsx:53 +#: widget/embedded/src/pages/Routes.tsx:48 +msgid "Routes" +msgstr "Itinerari" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Inputs/Inputs.tsx:76 +msgid "From" +msgstr "Da" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Inputs/Inputs.tsx:118 +msgid "To" +msgstr "A" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:49 +msgid "Light" +msgstr "Chiaro" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:58 +msgid "Dark" +msgstr "Scuro" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:67 +msgid "Auto" +msgstr "Automatico" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:140 +msgid "Loading failed" +msgstr "Caricamento fallito" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:156 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:41 +msgid "Bridges" +msgstr "Ponti" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:174 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:41 +msgid "Exchanges" +msgstr "Scambi" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:195 +#: widget/embedded/src/pages/CustomTokensPage.tsx:90 +msgid "Custom Tokens" +msgstr "Token Personalizzati" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:214 +#: widget/embedded/src/pages/LanguagePage.tsx:43 +msgid "Language" +msgstr "Lingua" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:235 +msgid "Infinite approval" +msgstr "Approvazione infinita" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:246 +msgid "Enabling the 'Infinite approval' mode grants unrestricted access to underlying smart contracts, allowing them to utilize the approved token amount without limitations." +msgstr "Abilitando la modalità 'Approvazione infinita' si concede l'accesso illimitato agli smart contract sottostanti, consentendo loro di utilizzare l'importo del token approvato senza limitazioni." + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:266 +msgid "Theme" +msgstr "Tema" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:39 +msgid "Duplicate Token" +msgstr "Duplicate Token" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:40 +msgid "The address you entered is duplicate, please enter a new address." +msgstr "L'indirizzo inserito è duplicato, inserisci un nuovo indirizzo." + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:46 +msgid "Token Already Exists" +msgstr "Token Esiste Già" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:47 +msgid "There's no need to add this token again because it already exists and is supported by us." +msgstr "Non c'è bisogno di aggiungere questo token di nuovo perché esiste già ed è supportato da noi." + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:53 +msgid "Token Not Found" +msgstr "Token Non Trovato" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:54 +msgid "Sorry, no token was found on {blockchain} chain with the provided address. please make sure you have entered the right token address." +msgstr "Siamo spiacenti, nessun token è stato trovato sulla catena {blockchain} con l'indirizzo fornito. Assicurati di aver inserito l'indirizzo del token giusto." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:78 +msgid "Network Error" +msgstr "Errore Di Rete" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:109 +#: widget/embedded/src/pages/CustomTokensPage.tsx:149 +msgid "Add Custom Token" +msgstr "Aggiungi Token Personalizzato" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:127 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:128 +msgid "Select chain" +msgstr "Seleziona catena" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:132 +msgid "Enter Address" +msgstr "Inserisci Indirizzo" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:139 +msgid "Enter token address" +msgstr "Inserisci indirizzo token" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:176 +msgid "Failed Network, Please retry." +msgstr "Rete non riuscita, riprova." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:192 +msgid "Add another custom token" +msgstr "Aggiungi un altro token personalizzato" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:236 +msgid "Confirm Swap" +msgstr "Conferma Scambio" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:254 +msgid "Start Swap" +msgstr "Inizia Scambia" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:282 +msgid "You get" +msgstr "Si ottiene" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:102 +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:90 +msgid "Search Token" +msgstr "Token Di Ricerca" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:134 +msgid "No custom tokens" +msgstr "Nessun token personalizzato" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:135 +msgid "press the button to add your custom token" +msgstr "premi il pulsante per aggiungere il tuo token personalizzato" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:158 +msgid "Delete Custom Token" +msgstr "Elimina Token Personalizzato" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:160 +msgid "Are you sure you want to Delete this Token?" +msgstr "Sei sicuro di voler eliminare questo Token?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:59 +msgid "Complete" +msgstr "Complete" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:63 +msgid "Running" +msgstr "Esecuzione" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:65 +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:8 +msgid "Failed" +msgstr "Fallito" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:149 +msgid "Clear" +msgstr "Pulisci" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:161 +msgid "Search Transaction" +msgstr "Ricerca Transazione" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:187 +msgid "No transactions" +msgstr "Nessuna transazione" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:194 +msgid "Your transaction history is stored locally and will appear here after you start a swap" +msgstr "La cronologia delle transazioni è memorizzata localmente e apparirà qui dopo aver avviato uno swap" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:218 +msgid "Clear Transaction History" +msgstr "Cancella Cronologia Transazioni" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:222 +msgid "Proceeding will remove all successful and failed transactions from the widget. Do you want to continue?" +msgstr "Procedere rimuoverà dal widget tutte le transazioni fallite e non riuscite. Vuoi continuare?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:229 +msgid "Note: This does not erase your transaction history on the chain; it only removes them here." +msgstr "Nota: Questo non cancella la cronologia delle transazioni nella catena; le rimuove solo qui." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:243 +msgid "Yes, Clear the history" +msgstr "Sì, Cancella la cronologia" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LanguagePage.tsx:56 +msgid "language" +msgstr "lingua" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:121 +msgid "Deselect all" +msgstr "Deseleziona tutto" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:121 +msgid "Select all" +msgstr "Seleziona tutto" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:133 +msgid "Search {sourceType}" +msgstr "Cerca {sourceType}" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectBlockchainPage.tsx:60 +msgid "Search Chain" +msgstr "Catena Di Ricerca" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:67 +msgid "Source" +msgstr "Fonte" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:68 +msgid "Destination" +msgstr "Destinazione" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:74 +msgid "Swap {type}" +msgstr "Scambia {type}" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SettingsPage.tsx:45 +msgid "Currently, you're in campaign mode with restrictions on liquidity sources. Would you like to switch out of this mode and make use of all available liquidity sources?" +msgstr "Attualmente, sei in modalità campagna con restrizioni sulle fonti di liquidità. Vuoi disattivare questa modalità e utilizzare tutte le fonti di liquidità disponibili?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SwapDetailsPage.tsx:27 +msgid "The request ID is necessary to display the swap details." +msgstr "L'ID della richiesta è necessario per visualizzare i dettagli dello swap." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/WalletsPage.tsx:67 +#: widget/ui/src/containers/ConnectWalletsModal/ConnectWalletsModal.tsx:15 +msgid "Connect Wallets" +msgstr "Collega Portafogli" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/WalletsPage.tsx:82 +msgid "Choose a wallet to connect." +msgstr "Scegli un portafoglio da collegare." + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:25 +msgid "This week" +msgstr "Questa settimana" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:32 +msgid "This month" +msgstr "Questo mese" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:39 +msgid "This year" +msgstr "Quest'anno" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:129 +msgid "Required: >= {min} {symbol}" +msgstr "Richiesto: >= {min} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:142 +msgid "Required: > {min} {symbol}" +msgstr "Richiesto: > {min} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:157 +msgid "Required: <= {max} {symbol}" +msgstr "Richiesto: <= {max} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:170 +msgid "Required: < {max} {symbol}" +msgstr "Richiesto: < {max} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:601 +msgid " for network fee" +msgstr " per commissione di rete" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:604 +msgid " for swap" +msgstr " per swap" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:607 +msgid " for input and network fee" +msgstr " per input e canone di rete" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:609 +msgid "Needs ≈ {requiredAmount} {symbol}{reason}, but you have {currentAmount} {symbol} in your {blockchain} wallet." +msgstr "Servono ≈ {requiredAmount} {symbol}{reason}, ma hai {currentAmount} {symbol} nel tuo portafoglio {blockchain} ." + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:669 +msgid "Waiting for connecting wallet" +msgstr "In attesa della connessione del portafoglio" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:673 +msgid "Waiting for other running tasks to be finished" +msgstr "In attesa che altre attività in esecuzione siano terminate" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:676 +msgid "Waiting for changing wallet network" +msgstr "In attesa di cambiare la rete del portafoglio" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:6 +msgid "Sunday" +msgstr "Domenica" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:7 +msgid "Monday" +msgstr "Lunedì" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:8 +msgid "Tuesday" +msgstr "Martedì" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:9 +msgid "Wednesday" +msgstr "Mercoledì" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:10 +msgid "Thursday" +msgstr "Giovedì" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:11 +msgid "Friday" +msgstr "Venerdì" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:12 +msgid "Saturday" +msgstr "Sabato" + +#. js-lingui-explicit-id +#: widget/ui/src/components/BottomLogo/BottomLogo.tsx:14 +msgid "Powered By" +msgstr "Powered By" + +#. js-lingui-explicit-id +#: widget/ui/src/components/FullExpandedQuote/FullExpandedQuote.Tooltip.tsx:37 +msgid "Aggregated Transaction" +msgstr "Transazione Aggregata" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SelectableCategoryList/SelectableCategoryList.tsx:63 +msgid "{blockchainCategory}" +msgstr "{blockchainCategory}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/StepDetails/StepDetails.tsx:75 +#: widget/ui/src/components/StepDetails/StepDetails.tsx:102 +msgid "Swap on {fromChain} via {swapper}" +msgstr "Scambia su {fromChain} via {swapper}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/StepDetails/StepDetails.tsx:109 +msgid "Bridge to {toChain} via {swapper}" +msgstr "Bridge to {toChain} via {swapper}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:10 +msgid "Completed" +msgstr "Completato" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:12 +msgid "In progress" +msgstr "In corso" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapToken.tsx:122 +msgid "Waiting for bridge transaction" +msgstr "In attesa di transazione bridge" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:12 +msgid "Connected" +msgstr "Connesso" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:13 +msgid "Disconnect" +msgstr "Disconnetti" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:18 +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:19 +msgid "Install" +msgstr "Installa" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:24 +msgid "Connecting ..." +msgstr "Connessione..." + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:25 +msgid "Connecting" +msgstr "Connessione" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:30 +msgid "Disconnected" +msgstr "Disconnesso" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:34 +msgid "you need to pass a correct state to Wallet." +msgstr "devi passare uno stato corretto a Wallet." + +#. js-lingui-explicit-id +#: widget/ui/src/containers/Notifications/NotificationNotFound.tsx:15 +msgid "There are no notifications." +msgstr "Non ci sono notifiche." + +#. js-lingui-explicit-id +#: widget/ui/src/containers/Notifications/Notifications.tsx:39 +msgid "Clear all" +msgstr "Cancella tutto" + +#. js-lingui-explicit-id +#: widget/ui/src/containers/SwapInput/SwapInput.tsx:65 +msgid "Balance" +msgstr "Saldo" + +#. js-lingui-explicit-id +#: widget/ui/src/containers/SwapInput/SwapInput.tsx:73 +msgid "Max" +msgstr "Max" + diff --git a/translations/ja.po b/translations/ja.po new file mode 100644 index 0000000000..8f9c609e6f --- /dev/null +++ b/translations/ja.po @@ -0,0 +1,1339 @@ +msgid "" +msgstr "" +"POT-Creation-Date: 2023-11-06 17:24+0330\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: @lingui/cli\n" +"Language: ja\n" +"Project-Id-Version: rango\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2024-11-27 15:57\n" +"Last-Translator: \n" +"Language-Team: Japanese\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Crowdin-Project: rango\n" +"X-Crowdin-Project-ID: 622238\n" +"X-Crowdin-Language: ja\n" +"X-Crowdin-File: en.po\n" +"X-Crowdin-File-ID: 30\n" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SameTokensWarning/SameTokensWarning.tsx:21 +msgid "No Routes Found" +msgstr "ルートが見つかりません" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SameTokensWarning/SameTokensWarning.tsx:25 +msgid "You cannot use the same token for From and To." +msgstr "From と To に同じトークンを使用することはできません。" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:41 +#: widget/embedded/src/components/TokenList/TokenList.tsx:286 +#: widget/embedded/src/pages/HistoryPage.tsx:186 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:143 +msgid "No results found" +msgstr "結果が見つかりませんでした" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:42 +#: widget/embedded/src/components/TokenList/TokenList.tsx:287 +#: widget/embedded/src/pages/HistoryPage.tsx:193 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:144 +msgid "Try using different keywords" +msgstr "別のキーワードを使用してみてください" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:72 +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:46 +#: widget/embedded/src/pages/SelectBlockchainPage.tsx:42 +#: widget/ui/src/containers/SwapInput/TokenSection.tsx:61 +msgid "Select Chain" +msgstr "チェーンを選択" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:66 +msgid "All" +msgstr "すべて" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:100 +msgid "More +{count}" +msgstr "その他 +{count}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabAlert/ActivateTabAlert.tsx:17 +msgid "Activate this tab" +msgstr "このタブを有効にする" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabAlert/ActivateTabAlert.tsx:22 +msgid "Another tab is open and handles transactions." +msgstr "別のタブはオープンでトランザクションを処理します。" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:20 +msgid "Activate current tab" +msgstr "現在のタブを有効にする" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:22 +msgid "Currently, some transactions are running and being handled by other browser tab. If you activate this tab, all transactions that are already in the transaction sign step will expire." +msgstr "現在、一部のトランザクションが実行され、他のブラウザタブで処理されています。 このタブを有効にすると、すでにトランザクション記号のステップにあるすべてのトランザクションが期限切れになります。" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:33 +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:349 +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:152 +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:33 +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:116 +msgid "Confirm" +msgstr "確認する" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:365 +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:447 +msgid "Your {blockchainName} wallets" +msgstr "あなたの {blockchainName} ウォレット" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:384 +msgid "Insufficient account balance" +msgstr "アカウント残高が不足しています" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:394 +msgid "Proceed anyway" +msgstr "とにかく続行する" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:456 +msgid "You need to connect a {blockchainName} wallet." +msgstr "{blockchainName} ウォレットに接続する必要があります。" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/WalletList.tsx:143 +msgid "Add {chain} chain" +msgstr "{chain} チェーンを追加" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/WalletList.tsx:244 +msgid "Show more wallets" +msgstr "ウォレットをもっと表示" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:113 +msgid "Send to a different address" +msgstr "別のアドレスに送る" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:129 +msgid "Enter {blockchainName} address" +msgstr "{blockchainName} アドレスを入力してください" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:147 +msgid "Address {destination} doesn't match the blockchain address pattern." +msgstr "アドレス {destination} はブロックチェーンアドレスパターンと一致しません。" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:59 +msgid "via" +msgstr "経由:" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:74 +msgid "This token doesn't appear on the active token list(s). Make sure this is the token that you want to trade." +msgstr "このトークンはアクティブなトークンリストに表示されません。これが取引したいトークンであることを確認してください。" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:89 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:164 +msgid "Import" +msgstr "インポート" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/FilterSelector/FilterSelectorContent.tsx:26 +msgid "Status" +msgstr "ステータス" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/FilterSelector/FilterSelectorContent.tsx:33 +#: widget/embedded/src/components/NoResult/NoResult.helpers.ts:37 +#: widget/embedded/src/pages/SettingsPage.tsx:55 +msgid "Reset" +msgstr "Reset" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/CancelButton.tsx:18 +msgid "Cancel" +msgstr "キャンセル" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:46 +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:34 +msgid "Refresh" +msgstr "更新" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:63 +#: widget/ui/src/containers/Notifications/Notifications.tsx:35 +msgid "Notifications" +msgstr "通知" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:79 +#: widget/embedded/src/pages/SettingsPage.tsx:38 +msgid "Settings" +msgstr "設定" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:93 +#: widget/embedded/src/pages/HistoryPage.tsx:139 +msgid "History" +msgstr "沿革" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/WalletButton.tsx:22 +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:16 +#: widget/embedded/src/constants/messages.ts:5 +msgid "Connect Wallet" +msgstr "ウォレットに接続" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HistoryGroupedList/HistoryGroupedList.tsx:118 +#: widget/embedded/src/utils/date.ts:18 +#: widget/embedded/src/utils/time.ts:22 +msgid "Today" +msgstr "今日" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/LoadingSwapDetails/LoadingSwapDetails.tsx:20 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:424 +msgid "Swaps steps" +msgstr "ステップを入れ替えます" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/NoResult/NoResult.helpers.ts:25 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:191 +msgid "Retry" +msgstr "再試行する" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:149 +msgid "Slippage Error" +msgstr "スライドページエラー" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:150 +msgid "Slippage Warning" +msgstr "滑り止めの警告" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:153 +msgid "Bridge Limit Error" +msgstr "ブリッジ制限エラー" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:240 +msgid "Yours: {amount} {symbol}" +msgstr "あなたの: {amount} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:261 +msgid "Minimum required slippage: {minRequiredSlippage}" +msgstr "最小必要なスリップ: {minRequiredSlippage}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:282 +msgid "Yours: {userSlippage}" +msgstr "あなたの: {userSlippage}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:395 +msgid "See All Routes" +msgstr "すべてのルートを見る" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:81 +msgid "View more info" +msgstr "詳細情報を表示" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:91 +msgid "Gas & Fee Explanation" +msgstr "ガス&料金の説明" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:107 +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:103 +msgid "Details" +msgstr "詳細" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:146 +msgid "Total Payable Fee" +msgstr "合計支払手数料" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:166 +msgid "Hide non-payable fees" +msgstr "支払い不可能な手数料を非表示" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:167 +msgid "Show non-payable fees" +msgstr "未払い手数料を表示" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:177 +msgid "Description" +msgstr "説明" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:181 +msgid "The following fees are considered in the transaction output and\n" +" you won’t need to pay extra gas for them." +msgstr "以下の手数料は取引の出力で考慮され、\n" +" 余分なガスを支払う必要はありません。" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteSummary.tsx:25 +msgid "Swap input" +msgstr "Swap input" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteSummary.tsx:44 +msgid "Estimated output" +msgstr "推定された出力" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteTrigger.tsx:65 +msgid "Via:" +msgstr "ビア:" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteTrigger.tsx:150 +msgid "Chains:" +msgstr "チェーン:" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/Quotes.tsx:77 +msgid "Sort by" +msgstr "並び替え" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:17 +msgid "Smart Routing" +msgstr "スマートルーティング" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:21 +msgid "Lowest Fee" +msgstr "最低手数料" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:25 +msgid "Fastest Transfer" +msgstr "最速送金" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:29 +msgid "Maximum Return" +msgstr "最大返品数" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:33 +msgid "Maximum Output" +msgstr "最大出力" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:43 +msgid "Swapping" +msgstr "Swapping" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:51 +msgid "Gas cost" +msgstr "ガスコスト" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:59 +msgid "Receiving" +msgstr "受信中" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:67 +msgid "Price impact" +msgstr "価格への影響" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:35 +msgid "You need to increase slippage to at least {minRequiredSlippage} for this route." +msgstr "このルートについては、少なくとも {minRequiredSlippage} まで滑りやすくする必要があります。" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:59 +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:61 +msgid "We recommend you to increase slippage to at least {minRequiredSlippage} for this route." +msgstr "このルートについては、少なくとも {minRequiredSlippage} への滑りを増やすことをお勧めします。" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:68 +msgid "Caution, your slippage is high." +msgstr "注意、あなたの滑りは高いです。" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.tsx:78 +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.Warning.tsx:26 +msgid "Change" +msgstr "変更" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:42 +msgid "Change settings" +msgstr "設定の変更" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:52 +msgid "High slippage" +msgstr "ハイスリップページ" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:53 +msgid "Low slippage" +msgstr "すべり低い順" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:57 +msgid " Caution, your slippage is high (={userSlippage}). Your trade may be front run." +msgstr " 注意、あなたの滑りが高いです (={userSlippage}). あなたの取引は、前払いされる可能性があります。" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:78 +msgid "Confirm anyway" +msgstr "確認する" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:22 +msgid "Something went wrong" +msgstr "問題が発生しました" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:24 +msgid "Something went wrong. Please refresh the app." +msgstr "問題が発生しました。アプリを更新してください。" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/Slippage.tsx:38 +msgid "Slippage tolerance per swap" +msgstr "スワップごとの滑り止め許容差" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/Slippage.tsx:91 +msgid "Custom" +msgstr "カスタム" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:11 +msgid "Your transaction will be reverted if the price changes unfavorably by more than this percentage." +msgstr "価格がこのパーセンテージよりも不利に変更された場合、取引は元に戻されます。" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:16 +#: widget/embedded/src/containers/Settings/Lists.tsx:245 +msgid "Warning" +msgstr "警告" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:17 +msgid "This setting is applied to each step (e.g. 1Inch, Thorchain, etc.), meaning only that specific step will be reverted, not the entire route." +msgstr "この設定は各ステップに適用されます (例: 1Inch、Thorchainなど)。 これは、特定のステップがルート全体ではなく、元に戻されることを意味します。" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:25 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:269 +msgid "Swap Details" +msgstr "スワップの詳細" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:33 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:312 +msgid "Request ID" +msgstr "要求ID" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:64 +msgid "Not found" +msgstr "見つかりません" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:65 +msgid "Swap with request ID = {requestId} not found." +msgstr "リクエスト ID = {requestId} でスワップが見つかりません。" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:219 +msgid "You have received {amount} {token} in {conciseAddress} wallet on {chain} chain." +msgstr "{amount} チェーンの {token} ウォレットで {conciseAddress} {chain} Anamed@@4 を受け取りました。" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:242 +msgid "Transaction was not sent." +msgstr "トランザクションは送信されませんでした。" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:244 +msgid "{amount} {symbol} on {blockchain} remains in your wallet." +msgstr "{amount} の {symbol} {blockchain} はウォレットに残ります。" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:281 +msgid "Delete" +msgstr "削除" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:304 +msgid "Try again" +msgstr "もう一度やり直してください" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:322 +msgid "Copied To Clipboard" +msgstr "クリップボードにコピーしました" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:323 +msgid "Copy Request ID" +msgstr "リクエストIDをコピー" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:346 +msgid "View on Rango Explorer" +msgstr "Rangoエクスプローラーで表示" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:355 +msgid "Finished at" +msgstr "終了日時" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:355 +msgid "Created at" +msgstr "作成日時" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.tsx:50 +msgid "View transaction" +msgstr "取引を表示" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.Warning.tsx:49 +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:31 +msgid "Connect" +msgstr "接続する" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:43 +msgid "Swap Successful" +msgstr "交代成功" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:71 +msgid "Transaction Failed" +msgstr "トランザクション失敗" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:87 +msgid "Done" +msgstr "完了" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:100 +msgid "Diagnosis" +msgstr "診断" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:112 +msgid "See Details" +msgstr "詳細を見る" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:13 +msgid "Cancel Swap" +msgstr "交換をキャンセル" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:14 +msgid "Are you sure you want to cancel this swap?" +msgstr "このスワップをキャンセルしてもよろしいですか?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:23 +msgid "Yes, Cancel it" +msgstr "はい、キャンセルします" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:32 +#: widget/embedded/src/pages/CustomTokensPage.tsx:181 +msgid "No, Continue" +msgstr "いいえ、続行します" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:13 +msgid "Delete Transaction" +msgstr "取引を削除" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:14 +msgid "Are you sure you want to delete this swap?" +msgstr "このスワップを削除してもよろしいですか?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:23 +#: widget/embedded/src/pages/CustomTokensPage.tsx:171 +msgid "Yes, Delete it" +msgstr "はい、削除します" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:33 +#: widget/embedded/src/pages/HistoryPage.tsx:253 +msgid "No, Cancel" +msgstr "いいえ、キャンセル" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:12 +msgid "Change Network" +msgstr "ネットワークを変更" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:20 +msgid "Network Changed" +msgstr "ネットワークを変更しました" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/TokenList/TokenList.tsx:271 +#: widget/ui/src/containers/SwapInput/TokenSection.tsx:54 +msgid "Select Token" +msgstr "トークンを選択" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:27 +msgid "Wallet Connected" +msgstr "ウォレットが接続されました" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:28 +msgid "Your wallet is connected, you can use it to swap." +msgstr "ウォレットが接続されています。交換に使用できます。" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:39 +msgid "Failed to Connect" +msgstr "接続に失敗しました" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:41 +msgid "Your wallet is not connected. Please try again." +msgstr "ウォレットが接続されていません。もう一度やり直してください。" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:50 +msgid "Connecting to your wallet" +msgstr "ウォレットに接続中" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:51 +msgid "Click connect in your wallet popup." +msgstr "ウォレットのポップアップでformat@@0をクリックします。" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:99 +msgid "Select Derivation Path" +msgstr "派生パスの選択" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:100 +msgid "In order to connect to {type}, you must first select a Derivation Path" +msgstr "{type}に接続するには、先に派生パスを選択する必要があります" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:118 +msgid "Choose Derivation Path Template" +msgstr "派生パステンプレートを選択" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:133 +msgid "Enter Path" +msgstr "パスを入力" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:134 +msgid "Enter Index" +msgstr "インデックスを入力" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:15 +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:18 +msgid "Add {blockchainDisplayName} Chain" +msgstr "{blockchainDisplayName} チェーンを追加" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:20 +msgid "Would you like to add the {blockchainDisplayName} experimental chain to your wallet?" +msgstr "{blockchainDisplayName} 実験チェーンをウォレットに追加しますか?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:22 +msgid "Please approve the experimental chain pop-up in your wallet." +msgstr "ウォレットの実験的な連鎖ポップアップを承認してください。" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:30 +msgid "{blockchainDisplayName} Chain Added" +msgstr "{blockchainDisplayName} チェーンが追加されました" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:34 +msgid "The {blockchainDisplayName} chain has been successfully added to your wallet." +msgstr "{blockchainDisplayName} チェーンがウォレットに追加されました。" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:42 +msgid "Request Rejected" +msgstr "リクエストが拒否されました" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:43 +msgid "You've rejected adding {blockchainDisplayName} chain to your wallet." +msgstr "{blockchainDisplayName} チェーンをあなたのウォレットに追加することを拒否しました。" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:70 +msgid "Select chain types" +msgstr "チェーンタイプを選択" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:71 +msgid "This wallet supports multiple chains. Select which chain you'd like to connect to." +msgstr "このウォレットは複数のチェーンをサポートしています。接続したいチェーンを選択してください。" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:9 +msgid "Failed Network, Please retry your swap." +msgstr "ネットワークに失敗しました。スワップを再試行してください。" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:11 +msgid "Please reset your liquidity sources." +msgstr "流動性情報をリセットしてください。" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:12 +msgid "You have limited the liquidity sources and this might result in Rango finding no routes. Please consider resetting your liquidity sources." +msgstr "流動性源が制限されているため、Rangoにルートが見つからない可能性があります。流動性源のリセットを検討してください。" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:17 +msgid "No Routes Found." +msgstr "ルートが見つかりません。" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:18 +msgid "Reasons why Rango couldn't find a route: low liquidity on token, very low input amount or no routes available for the selected input/output token combination." +msgstr "Rangoがルートを見つけられなかった理由: トークンの流動性が低く、非常に低い入力量、または選択された入力/出力トークンの組み合わせで利用可能なルートがありません。" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:23 +msgid "Bridge Limit Error: Please increase your amount." +msgstr "ブリッジ制限エラー: 金額を増やしてください。" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:26 +msgid "Bridge Limit Error: Please decrease your amount." +msgstr "ブリッジ制限エラー: 金額を減らしてください。" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:31 +msgid "High Price Impact" +msgstr "価格への影響" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:32 +msgid "Price impact is too high!" +msgstr "価格の影響が高すぎます!" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:33 +msgid "The price impact is significantly higher than the allowed amount." +msgstr "価格への影響は、許容額よりも大幅に高くなります。" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:36 +msgid "Confirm high price impact" +msgstr "高価格の影響を確認する" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:39 +msgid "Route updated and price impact is too high, try again later!" +msgstr "ルートの更新と価格への影響が高すぎます。後でもう一度お試しください!" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:44 +msgid "USD Price Unknown" +msgstr "USD価格不明" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:45 +msgid "USD Price Unknown, Cannot calculate Price Impact." +msgstr "USD価格が不明です。価格の影響を計算できません。" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:46 +msgid "USD Price Unknown, Cannot calculate Price Impact. The price impact may be higher than usual. Are you sure to continue the Swap?" +msgstr "USD価格が不明です。価格の影響を計算できません。価格の影響は通常よりも高くなる可能性があります。スワップを続行してもよろしいですか?" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:49 +msgid "Confirm USD Price Unknown" +msgstr "不明なUSD価格を確認" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:6 +#: widget/embedded/src/pages/Home.tsx:163 +msgid "Swap" +msgstr "入れ替え" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:7 +msgid "Swap anyway" +msgstr "とにかく入れ替え" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:8 +msgid "The route goes through Ethereum. Continue?" +msgstr "ルートはEthereumを通過します。続行しますか?" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:10 +msgid "Route has been updated." +msgstr "ルートが更新されました。" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:12 +msgid "Output amount changed to {newOutputAmount} ({percentageChange}% change)." +msgstr "出力量が {newOutputAmount} に変更されました({percentageChange}%変更)。" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:20 +msgid "Route swappers has been updated." +msgstr "ルートスワッパーを更新しました。" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:22 +msgid "Route internal coins has been updated." +msgstr "ルート内部コインが更新されました。" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/ExpandedQuotes/ExpandedQuotes.tsx:53 +#: widget/embedded/src/pages/Routes.tsx:48 +msgid "Routes" +msgstr "ルート" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Inputs/Inputs.tsx:76 +msgid "From" +msgstr "差出人:" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Inputs/Inputs.tsx:118 +msgid "To" +msgstr "終了日" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:49 +msgid "Light" +msgstr "ライト" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:58 +msgid "Dark" +msgstr "ダーク" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:67 +msgid "Auto" +msgstr "自動" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:140 +msgid "Loading failed" +msgstr "読み込みに失敗しました" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:156 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:41 +msgid "Bridges" +msgstr "ブリッジ" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:174 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:41 +msgid "Exchanges" +msgstr "交換" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:195 +#: widget/embedded/src/pages/CustomTokensPage.tsx:90 +msgid "Custom Tokens" +msgstr "カスタムトークン" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:214 +#: widget/embedded/src/pages/LanguagePage.tsx:43 +msgid "Language" +msgstr "言語" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:235 +msgid "Infinite approval" +msgstr "永久承認" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:246 +msgid "Enabling the 'Infinite approval' mode grants unrestricted access to underlying smart contracts, allowing them to utilize the approved token amount without limitations." +msgstr "「無限承認」モードを有効にすると、基盤となるスマートコントラクトへの無制限のアクセスが許可され、承認されたトークンの量を制限なく利用できます。" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:266 +msgid "Theme" +msgstr "テーマ" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:39 +msgid "Duplicate Token" +msgstr "Duplicate Token" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:40 +msgid "The address you entered is duplicate, please enter a new address." +msgstr "入力したアドレスが重複しています。新しいアドレスを入力してください。" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:46 +msgid "Token Already Exists" +msgstr "トークンは既に存在します" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:47 +msgid "There's no need to add this token again because it already exists and is supported by us." +msgstr "すでに存在し、私たちがサポートしているため、このトークンをもう一度追加する必要はありません。" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:53 +msgid "Token Not Found" +msgstr "トークンが見つかりません" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:54 +msgid "Sorry, no token was found on {blockchain} chain with the provided address. please make sure you have entered the right token address." +msgstr "申し訳ありませんが、指定されたアドレスの {blockchain} チェーンでトークンが見つかりませんでした。正しいトークンアドレスを入力していることを確認してください。" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:78 +msgid "Network Error" +msgstr "ネットワークエラー" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:109 +#: widget/embedded/src/pages/CustomTokensPage.tsx:149 +msgid "Add Custom Token" +msgstr "カスタムトークンを追加" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:127 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:128 +msgid "Select chain" +msgstr "チェーンを選択" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:132 +msgid "Enter Address" +msgstr "住所を入力" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:139 +msgid "Enter token address" +msgstr "トークンアドレスを入力してください" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:176 +msgid "Failed Network, Please retry." +msgstr "ネットワークに失敗しました。再試行してください。" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:192 +msgid "Add another custom token" +msgstr "別のカスタムトークンを追加" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:236 +msgid "Confirm Swap" +msgstr "スワップの確認" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:254 +msgid "Start Swap" +msgstr "スワップを開始" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:282 +msgid "You get" +msgstr "あなたは" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:102 +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:90 +msgid "Search Token" +msgstr "トークンを検索" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:134 +msgid "No custom tokens" +msgstr "カスタムトークンはありません" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:135 +msgid "press the button to add your custom token" +msgstr "カスタムトークンを追加するにはボタンを押してください" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:158 +msgid "Delete Custom Token" +msgstr "カスタムトークンを削除" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:160 +msgid "Are you sure you want to Delete this Token?" +msgstr "このトークンを削除してもよろしいですか?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:59 +msgid "Complete" +msgstr "Complete" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:63 +msgid "Running" +msgstr "実行中" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:65 +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:8 +msgid "Failed" +msgstr "失敗しました" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:149 +msgid "Clear" +msgstr "クリア" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:161 +msgid "Search Transaction" +msgstr "トランザクションを検索" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:187 +msgid "No transactions" +msgstr "取引がありません" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:194 +msgid "Your transaction history is stored locally and will appear here after you start a swap" +msgstr "取引履歴はローカルに保存され、スワップを開始するとここに表示されます" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:218 +msgid "Clear Transaction History" +msgstr "取引履歴を消去" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:222 +msgid "Proceeding will remove all successful and failed transactions from the widget. Do you want to continue?" +msgstr "続行すると、成功したトランザクションと失敗したトランザクションがウィジェットから削除されます。続行しますか?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:229 +msgid "Note: This does not erase your transaction history on the chain; it only removes them here." +msgstr "注:チェーン上の取引履歴は消去されません。ここでのみ削除されます。" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:243 +msgid "Yes, Clear the history" +msgstr "はい、履歴を消去します" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LanguagePage.tsx:56 +msgid "language" +msgstr "言語" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:121 +msgid "Deselect all" +msgstr "すべての選択を解除" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:121 +msgid "Select all" +msgstr "すべて選択" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:133 +msgid "Search {sourceType}" +msgstr "{sourceType} を検索" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectBlockchainPage.tsx:60 +msgid "Search Chain" +msgstr "検索チェーン" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:67 +msgid "Source" +msgstr "ソース" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:68 +msgid "Destination" +msgstr "保存先" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:74 +msgid "Swap {type}" +msgstr "{type} を入れ替え" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SettingsPage.tsx:45 +msgid "Currently, you're in campaign mode with restrictions on liquidity sources. Would you like to switch out of this mode and make use of all available liquidity sources?" +msgstr "現在、流動性情報源に制限があるキャンペーンモードです。 このモードを切り替えて、利用可能なすべての流動性源を使用しますか?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SwapDetailsPage.tsx:27 +msgid "The request ID is necessary to display the swap details." +msgstr "スワップの詳細を表示するにはリクエスト ID が必要です。" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/WalletsPage.tsx:67 +#: widget/ui/src/containers/ConnectWalletsModal/ConnectWalletsModal.tsx:15 +msgid "Connect Wallets" +msgstr "ウォレットを接続" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/WalletsPage.tsx:82 +msgid "Choose a wallet to connect." +msgstr "接続するウォレットを選択してください。" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:25 +msgid "This week" +msgstr "今週中" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:32 +msgid "This month" +msgstr "今月の" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:39 +msgid "This year" +msgstr "年" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:129 +msgid "Required: >= {min} {symbol}" +msgstr "必須:>= {min} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:142 +msgid "Required: > {min} {symbol}" +msgstr "必須: > {min} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:157 +msgid "Required: <= {max} {symbol}" +msgstr "必須: <= {max} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:170 +msgid "Required: < {max} {symbol}" +msgstr "必須: < {max} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:601 +msgid " for network fee" +msgstr " ネットワーク料金で" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:604 +msgid " for swap" +msgstr " スワップ用" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:607 +msgid " for input and network fee" +msgstr " 入力とネットワーク料金について" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:609 +msgid "Needs ≈ {requiredAmount} {symbol}{reason}, but you have {currentAmount} {symbol} in your {blockchain} wallet." +msgstr "必要額は ≈ {requiredAmount} {symbol}{reason}ですが、あなたの {blockchain} ウォレットには {currentAmount} {symbol} があります。" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:669 +msgid "Waiting for connecting wallet" +msgstr "ウォレットの接続を待っています" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:673 +msgid "Waiting for other running tasks to be finished" +msgstr "他の実行中のタスクが完了するのを待っています" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:676 +msgid "Waiting for changing wallet network" +msgstr "ウォレットネットワークの変更を待っています" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:6 +msgid "Sunday" +msgstr "日曜日" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:7 +msgid "Monday" +msgstr "月曜日" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:8 +msgid "Tuesday" +msgstr "火曜日" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:9 +msgid "Wednesday" +msgstr "水曜日" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:10 +msgid "Thursday" +msgstr "木曜日" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:11 +msgid "Friday" +msgstr "金曜日" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:12 +msgid "Saturday" +msgstr "土曜日" + +#. js-lingui-explicit-id +#: widget/ui/src/components/BottomLogo/BottomLogo.tsx:14 +msgid "Powered By" +msgstr "Powered By" + +#. js-lingui-explicit-id +#: widget/ui/src/components/FullExpandedQuote/FullExpandedQuote.Tooltip.tsx:37 +msgid "Aggregated Transaction" +msgstr "集計取引" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SelectableCategoryList/SelectableCategoryList.tsx:63 +msgid "{blockchainCategory}" +msgstr "{blockchainCategory}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/StepDetails/StepDetails.tsx:75 +#: widget/ui/src/components/StepDetails/StepDetails.tsx:102 +msgid "Swap on {fromChain} via {swapper}" +msgstr "{fromChain} で {swapper}を入れ替え" + +#. js-lingui-explicit-id +#: widget/ui/src/components/StepDetails/StepDetails.tsx:109 +msgid "Bridge to {toChain} via {swapper}" +msgstr "{toChain} 経由で {swapper}に橋" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:10 +msgid "Completed" +msgstr "完了" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:12 +msgid "In progress" +msgstr "進行中" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapToken.tsx:122 +msgid "Waiting for bridge transaction" +msgstr "ブリッジトランザクションを待っています" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:12 +msgid "Connected" +msgstr "接続しました" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:13 +msgid "Disconnect" +msgstr "接続を解除" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:18 +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:19 +msgid "Install" +msgstr "インストール" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:24 +msgid "Connecting ..." +msgstr "接続中..." + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:25 +msgid "Connecting" +msgstr "接続中" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:30 +msgid "Disconnected" +msgstr "切断されました" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:34 +msgid "you need to pass a correct state to Wallet." +msgstr "ウォレットに正しい状態を渡す必要があります。" + +#. js-lingui-explicit-id +#: widget/ui/src/containers/Notifications/NotificationNotFound.tsx:15 +msgid "There are no notifications." +msgstr "通知はありません。" + +#. js-lingui-explicit-id +#: widget/ui/src/containers/Notifications/Notifications.tsx:39 +msgid "Clear all" +msgstr "すべてクリア" + +#. js-lingui-explicit-id +#: widget/ui/src/containers/SwapInput/SwapInput.tsx:65 +msgid "Balance" +msgstr "残高" + +#. js-lingui-explicit-id +#: widget/ui/src/containers/SwapInput/SwapInput.tsx:73 +msgid "Max" +msgstr "最大値" + diff --git a/translations/ko.po b/translations/ko.po new file mode 100644 index 0000000000..e97f7e2c89 --- /dev/null +++ b/translations/ko.po @@ -0,0 +1,1339 @@ +msgid "" +msgstr "" +"POT-Creation-Date: 2023-11-06 17:24+0330\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: @lingui/cli\n" +"Language: ko\n" +"Project-Id-Version: rango\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2024-11-27 15:57\n" +"Last-Translator: \n" +"Language-Team: Korean\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Crowdin-Project: rango\n" +"X-Crowdin-Project-ID: 622238\n" +"X-Crowdin-Language: ko\n" +"X-Crowdin-File: en.po\n" +"X-Crowdin-File-ID: 30\n" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SameTokensWarning/SameTokensWarning.tsx:21 +msgid "No Routes Found" +msgstr "경로를 찾을 수 없습니다" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SameTokensWarning/SameTokensWarning.tsx:25 +msgid "You cannot use the same token for From and To." +msgstr "From과 To에 동일한 토큰을 사용할 수 없습니다." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:41 +#: widget/embedded/src/components/TokenList/TokenList.tsx:286 +#: widget/embedded/src/pages/HistoryPage.tsx:186 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:143 +msgid "No results found" +msgstr "검색 결과가 없습니다" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:42 +#: widget/embedded/src/components/TokenList/TokenList.tsx:287 +#: widget/embedded/src/pages/HistoryPage.tsx:193 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:144 +msgid "Try using different keywords" +msgstr "다른 키워드를 사용해 보세요" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:72 +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:46 +#: widget/embedded/src/pages/SelectBlockchainPage.tsx:42 +#: widget/ui/src/containers/SwapInput/TokenSection.tsx:61 +msgid "Select Chain" +msgstr "체인 선택" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:66 +msgid "All" +msgstr "모두" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:100 +msgid "More +{count}" +msgstr "더 보기 +{count}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabAlert/ActivateTabAlert.tsx:17 +msgid "Activate this tab" +msgstr "이 탭을 활성화하세요" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabAlert/ActivateTabAlert.tsx:22 +msgid "Another tab is open and handles transactions." +msgstr "또 다른 탭이 열려 거래를 처리합니다." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:20 +msgid "Activate current tab" +msgstr "현재 탭 활성화" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:22 +msgid "Currently, some transactions are running and being handled by other browser tab. If you activate this tab, all transactions that are already in the transaction sign step will expire." +msgstr "현재 일부 거래가 실행 중이며 다른 브라우저 탭에서 처리되고 있습니다. 이 탭을 활성화하면 이미 거래 서명 단계에 있는 모든 거래가 만료됩니다." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:33 +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:349 +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:152 +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:33 +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:116 +msgid "Confirm" +msgstr "확인하다" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:365 +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:447 +msgid "Your {blockchainName} wallets" +msgstr "귀하의 {blockchainName} 지갑" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:384 +msgid "Insufficient account balance" +msgstr "계좌잔액이 부족합니다" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:394 +msgid "Proceed anyway" +msgstr "어쨌든 진행하세요" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:456 +msgid "You need to connect a {blockchainName} wallet." +msgstr "{blockchainName} 지갑을 연결해야 합니다." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/WalletList.tsx:143 +msgid "Add {chain} chain" +msgstr "{chain} 체인 추가" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/WalletList.tsx:244 +msgid "Show more wallets" +msgstr "더 많은 지갑 보기" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:113 +msgid "Send to a different address" +msgstr "다른 주소로 보내기" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:129 +msgid "Enter {blockchainName} address" +msgstr "{blockchainName} 주소를 입력하세요" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:147 +msgid "Address {destination} doesn't match the blockchain address pattern." +msgstr "주소 {destination} 가 블록체인 주소 패턴과 일치하지 않습니다." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:59 +msgid "via" +msgstr "~을 통해" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:74 +msgid "This token doesn't appear on the active token list(s). Make sure this is the token that you want to trade." +msgstr "이 토큰은 활성 토큰 목록에 나타나지 않습니다. 이것이 거래하려는 토큰인지 확인하세요." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:89 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:164 +msgid "Import" +msgstr "수입" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/FilterSelector/FilterSelectorContent.tsx:26 +msgid "Status" +msgstr "상태" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/FilterSelector/FilterSelectorContent.tsx:33 +#: widget/embedded/src/components/NoResult/NoResult.helpers.ts:37 +#: widget/embedded/src/pages/SettingsPage.tsx:55 +msgid "Reset" +msgstr "다시 놓기" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/CancelButton.tsx:18 +msgid "Cancel" +msgstr "취소" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:46 +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:34 +msgid "Refresh" +msgstr "새로 고치다" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:63 +#: widget/ui/src/containers/Notifications/Notifications.tsx:35 +msgid "Notifications" +msgstr "알림" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:79 +#: widget/embedded/src/pages/SettingsPage.tsx:38 +msgid "Settings" +msgstr "설정" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:93 +#: widget/embedded/src/pages/HistoryPage.tsx:139 +msgid "History" +msgstr "역사" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/WalletButton.tsx:22 +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:16 +#: widget/embedded/src/constants/messages.ts:5 +msgid "Connect Wallet" +msgstr "지갑 연결" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HistoryGroupedList/HistoryGroupedList.tsx:118 +#: widget/embedded/src/utils/date.ts:18 +#: widget/embedded/src/utils/time.ts:22 +msgid "Today" +msgstr "오늘" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/LoadingSwapDetails/LoadingSwapDetails.tsx:20 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:424 +msgid "Swaps steps" +msgstr "단계를 바꿉니다" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/NoResult/NoResult.helpers.ts:25 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:191 +msgid "Retry" +msgstr "다시 해 보다" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:149 +msgid "Slippage Error" +msgstr "미끄러짐 오류" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:150 +msgid "Slippage Warning" +msgstr "미끄러짐 경고" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:153 +msgid "Bridge Limit Error" +msgstr "브리지 한계 오류" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:240 +msgid "Yours: {amount} {symbol}" +msgstr "당신의: {amount} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:261 +msgid "Minimum required slippage: {minRequiredSlippage}" +msgstr "최소 필요 미끄러짐: {minRequiredSlippage}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:282 +msgid "Yours: {userSlippage}" +msgstr "당신의: {userSlippage}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:395 +msgid "See All Routes" +msgstr "모든 경로 보기" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:81 +msgid "View more info" +msgstr "더 많은 정보 보기" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:91 +msgid "Gas & Fee Explanation" +msgstr "가스 및 수수료 설명" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:107 +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:103 +msgid "Details" +msgstr "세부" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:146 +msgid "Total Payable Fee" +msgstr "총 지불 수수료" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:166 +msgid "Hide non-payable fees" +msgstr "지불 불가능한 수수료 숨기기" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:167 +msgid "Show non-payable fees" +msgstr "지불 불가능한 수수료 표시" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:177 +msgid "Description" +msgstr "설명" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:181 +msgid "The following fees are considered in the transaction output and\n" +" you won’t need to pay extra gas for them." +msgstr "다음 수수료는 거래 출력에 고려되며\n" +" 이에 대해 추가 가스를 지불할 필요가 없습니다." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteSummary.tsx:25 +msgid "Swap input" +msgstr "입력 바꾸기" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteSummary.tsx:44 +msgid "Estimated output" +msgstr "예상 출력" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteTrigger.tsx:65 +msgid "Via:" +msgstr "을 통해:" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteTrigger.tsx:150 +msgid "Chains:" +msgstr "쇠사슬:" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/Quotes.tsx:77 +msgid "Sort by" +msgstr "정렬 기준" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:17 +msgid "Smart Routing" +msgstr "스마트 라우팅" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:21 +msgid "Lowest Fee" +msgstr "가장 낮은 수수료" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:25 +msgid "Fastest Transfer" +msgstr "가장 빠른 전송" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:29 +msgid "Maximum Return" +msgstr "최대 수익" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:33 +msgid "Maximum Output" +msgstr "최대 출력" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:43 +msgid "Swapping" +msgstr "스와핑" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:51 +msgid "Gas cost" +msgstr "가스 비용" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:59 +msgid "Receiving" +msgstr "전수" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:67 +msgid "Price impact" +msgstr "가격 영향" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:35 +msgid "You need to increase slippage to at least {minRequiredSlippage} for this route." +msgstr "이 경로의 경우 미끄러짐을 최소한 {minRequiredSlippage} 까지 높여야 합니다." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:59 +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:61 +msgid "We recommend you to increase slippage to at least {minRequiredSlippage} for this route." +msgstr "이 경로의 경우 미끄러짐을 최소한 {minRequiredSlippage} 까지 높이는 것이 좋습니다." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:68 +msgid "Caution, your slippage is high." +msgstr "조심하세요, 미끄러짐이 심합니다." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.tsx:78 +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.Warning.tsx:26 +msgid "Change" +msgstr "변화" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:42 +msgid "Change settings" +msgstr "설정 변경" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:52 +msgid "High slippage" +msgstr "높은 미끄러짐" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:53 +msgid "Low slippage" +msgstr "낮은 미끄러짐" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:57 +msgid " Caution, your slippage is high (={userSlippage}). Your trade may be front run." +msgstr " 주의하세요, 당신의 슬리피지는 높습니다(={userSlippage}). 당신의 거래는 선두일 수 있습니다." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:78 +msgid "Confirm anyway" +msgstr "어쨌든 확인" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:22 +msgid "Something went wrong" +msgstr "문제가 발생했습니다" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:24 +msgid "Something went wrong. Please refresh the app." +msgstr "오류가 발생했습니다. 앱을 새로 고침하세요." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/Slippage.tsx:38 +msgid "Slippage tolerance per swap" +msgstr "스왑당 미끄러짐 허용 범위" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/Slippage.tsx:91 +msgid "Custom" +msgstr "관습" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:11 +msgid "Your transaction will be reverted if the price changes unfavorably by more than this percentage." +msgstr "가격이 이 비율 이상 불리하게 변동될 경우, 귀하의 거래는 취소됩니다." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:16 +#: widget/embedded/src/containers/Settings/Lists.tsx:245 +msgid "Warning" +msgstr "경고" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:17 +msgid "This setting is applied to each step (e.g. 1Inch, Thorchain, etc.), meaning only that specific step will be reverted, not the entire route." +msgstr "이 설정은 각 단계(예: 1인치, 토르체인 등)에 적용됩니다. 즉, 전체 경로가 아닌 해당 단계만 되돌려집니다." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:25 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:269 +msgid "Swap Details" +msgstr "스왑 세부 정보" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:33 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:312 +msgid "Request ID" +msgstr "요청 ID" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:64 +msgid "Not found" +msgstr "찾을 수 없음" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:65 +msgid "Swap with request ID = {requestId} not found." +msgstr "요청 ID = {requestId} 인 스왑을 찾을 수 없습니다." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:219 +msgid "You have received {amount} {token} in {conciseAddress} wallet on {chain} chain." +msgstr "{chain} 체인의 {conciseAddress} 지갑에서 {amount} {token} 을 받았습니다." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:242 +msgid "Transaction was not sent." +msgstr "거래가 전송되지 않았습니다." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:244 +msgid "{amount} {symbol} on {blockchain} remains in your wallet." +msgstr "{amount} {symbol} 의 {blockchain} 이(가) 지갑에 남아 있습니다." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:281 +msgid "Delete" +msgstr "삭제" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:304 +msgid "Try again" +msgstr "다시 시도하세요" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:322 +msgid "Copied To Clipboard" +msgstr "클립보드에 복사됨" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:323 +msgid "Copy Request ID" +msgstr "복사 요청 ID" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:346 +msgid "View on Rango Explorer" +msgstr "Rango Explorer에서 보기" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:355 +msgid "Finished at" +msgstr "완료됨" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:355 +msgid "Created at" +msgstr "생성됨" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.tsx:50 +msgid "View transaction" +msgstr "거래 보기" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.Warning.tsx:49 +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:31 +msgid "Connect" +msgstr "연결하다" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:43 +msgid "Swap Successful" +msgstr "스왑 성공" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:71 +msgid "Transaction Failed" +msgstr "거래 실패" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:87 +msgid "Done" +msgstr "완료" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:100 +msgid "Diagnosis" +msgstr "진단" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:112 +msgid "See Details" +msgstr "자세한 내용 보기" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:13 +msgid "Cancel Swap" +msgstr "스왑 취소" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:14 +msgid "Are you sure you want to cancel this swap?" +msgstr "이 교환을 취소하시겠습니까?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:23 +msgid "Yes, Cancel it" +msgstr "네, 취소합니다" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:32 +#: widget/embedded/src/pages/CustomTokensPage.tsx:181 +msgid "No, Continue" +msgstr "아니요, 계속하세요" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:13 +msgid "Delete Transaction" +msgstr "거래 삭제" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:14 +msgid "Are you sure you want to delete this swap?" +msgstr "이 스왑을 삭제하시겠습니까?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:23 +#: widget/embedded/src/pages/CustomTokensPage.tsx:171 +msgid "Yes, Delete it" +msgstr "네, 삭제합니다" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:33 +#: widget/embedded/src/pages/HistoryPage.tsx:253 +msgid "No, Cancel" +msgstr "아니요, 취소" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:12 +msgid "Change Network" +msgstr "네트워크 변경" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:20 +msgid "Network Changed" +msgstr "네트워크가 변경되었습니다" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/TokenList/TokenList.tsx:271 +#: widget/ui/src/containers/SwapInput/TokenSection.tsx:54 +msgid "Select Token" +msgstr "토큰 선택" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:27 +msgid "Wallet Connected" +msgstr "지갑 연결됨" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:28 +msgid "Your wallet is connected, you can use it to swap." +msgstr "귀하의 지갑이 연결되었으므로 이를 사용해 스왑을 진행하실 수 있습니다." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:39 +msgid "Failed to Connect" +msgstr "연결에 실패했습니다" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:41 +msgid "Your wallet is not connected. Please try again." +msgstr "지갑이 연결되지 않았습니다. 다시 시도해 주세요." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:50 +msgid "Connecting to your wallet" +msgstr "지갑에 연결하기" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:51 +msgid "Click connect in your wallet popup." +msgstr "지갑 팝업에서 연결을 클릭하세요." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:99 +msgid "Select Derivation Path" +msgstr "파생 경로 선택" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:100 +msgid "In order to connect to {type}, you must first select a Derivation Path" +msgstr "{type}에 연결하려면 먼저 파생 경로를 선택해야 합니다." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:118 +msgid "Choose Derivation Path Template" +msgstr "파생 경로 템플릿 선택" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:133 +msgid "Enter Path" +msgstr "경로 입력" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:134 +msgid "Enter Index" +msgstr "인덱스를 입력하세요" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:15 +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:18 +msgid "Add {blockchainDisplayName} Chain" +msgstr "{blockchainDisplayName} 체인 추가" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:20 +msgid "Would you like to add the {blockchainDisplayName} experimental chain to your wallet?" +msgstr "{blockchainDisplayName} 실험적 체인을 지갑에 추가하시겠습니까?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:22 +msgid "Please approve the experimental chain pop-up in your wallet." +msgstr "지갑에서 실험적 체인 팝업을 승인해 주세요." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:30 +msgid "{blockchainDisplayName} Chain Added" +msgstr "{blockchainDisplayName} 체인 추가됨" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:34 +msgid "The {blockchainDisplayName} chain has been successfully added to your wallet." +msgstr "{blockchainDisplayName} 체인이 지갑에 성공적으로 추가되었습니다." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:42 +msgid "Request Rejected" +msgstr "요청 거부됨" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:43 +msgid "You've rejected adding {blockchainDisplayName} chain to your wallet." +msgstr "지갑에 {blockchainDisplayName} 체인을 추가하는 것을 거부했습니다." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:70 +msgid "Select chain types" +msgstr "체인 유형 선택" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:71 +msgid "This wallet supports multiple chains. Select which chain you'd like to connect to." +msgstr "이 지갑은 여러 체인을 지원합니다. 연결하려는 체인을 선택하세요." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:9 +msgid "Failed Network, Please retry your swap." +msgstr "네트워크 오류입니다. 스왑을 다시 시도하세요." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:11 +msgid "Please reset your liquidity sources." +msgstr "유동성 소스를 재설정해 주세요." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:12 +msgid "You have limited the liquidity sources and this might result in Rango finding no routes. Please consider resetting your liquidity sources." +msgstr "유동성 소스를 제한했기 때문에 Rango가 경로를 찾지 못할 수 있습니다. 유동성 소스를 재설정하는 것을 고려해 보세요." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:17 +msgid "No Routes Found." +msgstr "경로를 찾을 수 없습니다." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:18 +msgid "Reasons why Rango couldn't find a route: low liquidity on token, very low input amount or no routes available for the selected input/output token combination." +msgstr "Rango가 경로를 찾을 수 없는 이유는 다음과 같습니다: 토큰의 유동성이 낮음, 입력 금액이 매우 낮음, 선택한 입력/출력 토큰 조합에 사용할 수 있는 경로가 없음." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:23 +msgid "Bridge Limit Error: Please increase your amount." +msgstr "브리지 한도 오류: 금액을 늘려주세요." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:26 +msgid "Bridge Limit Error: Please decrease your amount." +msgstr "브리지 한도 오류: 금액을 줄여 주세요." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:31 +msgid "High Price Impact" +msgstr "높은 가격의 영향" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:32 +msgid "Price impact is too high!" +msgstr "가격 영향이 너무 큽니다!" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:33 +msgid "The price impact is significantly higher than the allowed amount." +msgstr "가격에 미치는 영향이 허용 금액보다 훨씬 높습니다." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:36 +msgid "Confirm high price impact" +msgstr "높은 가격 영향 확인" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:39 +msgid "Route updated and price impact is too high, try again later!" +msgstr "경로가 업데이트되었고 가격 영향이 너무 큽니다. 나중에 다시 시도하세요!" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:44 +msgid "USD Price Unknown" +msgstr "USD 가격 미상" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:45 +msgid "USD Price Unknown, Cannot calculate Price Impact." +msgstr "USD 가격을 알 수 없으므로 가격 영향을 계산할 수 없습니다." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:46 +msgid "USD Price Unknown, Cannot calculate Price Impact. The price impact may be higher than usual. Are you sure to continue the Swap?" +msgstr "USD 가격 알 수 없음, 가격 영향을 계산할 수 없습니다. 가격 영향이 평소보다 더 높을 수 있습니다. 스왑을 계속하시겠습니까?" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:49 +msgid "Confirm USD Price Unknown" +msgstr "USD 가격 확인 불명" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:6 +#: widget/embedded/src/pages/Home.tsx:163 +msgid "Swap" +msgstr "교환" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:7 +msgid "Swap anyway" +msgstr "어쨌든 바꿔라" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:8 +msgid "The route goes through Ethereum. Continue?" +msgstr "이 경로는 Ethereum을 통과합니다. 계속하시겠습니까?" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:10 +msgid "Route has been updated." +msgstr "경로가 업데이트되었습니다." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:12 +msgid "Output amount changed to {newOutputAmount} ({percentageChange}% change)." +msgstr "출력량이 {newOutputAmount} ({percentageChange}% 변경)으로 변경되었습니다." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:20 +msgid "Route swappers has been updated." +msgstr "경로 변경 기능이 업데이트되었습니다." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:22 +msgid "Route internal coins has been updated." +msgstr "경로 내부 코인이 업데이트되었습니다." + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/ExpandedQuotes/ExpandedQuotes.tsx:53 +#: widget/embedded/src/pages/Routes.tsx:48 +msgid "Routes" +msgstr "경로" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Inputs/Inputs.tsx:76 +msgid "From" +msgstr "에서" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Inputs/Inputs.tsx:118 +msgid "To" +msgstr "에게" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:49 +msgid "Light" +msgstr "빛" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:58 +msgid "Dark" +msgstr "어두운" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:67 +msgid "Auto" +msgstr "자동차" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:140 +msgid "Loading failed" +msgstr "로딩 실패" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:156 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:41 +msgid "Bridges" +msgstr "다리" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:174 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:41 +msgid "Exchanges" +msgstr "교환" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:195 +#: widget/embedded/src/pages/CustomTokensPage.tsx:90 +msgid "Custom Tokens" +msgstr "사용자 정의 토큰" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:214 +#: widget/embedded/src/pages/LanguagePage.tsx:43 +msgid "Language" +msgstr "언어" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:235 +msgid "Infinite approval" +msgstr "무한한 승인" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:246 +msgid "Enabling the 'Infinite approval' mode grants unrestricted access to underlying smart contracts, allowing them to utilize the approved token amount without limitations." +msgstr "'무한 승인' 모드를 활성화하면 기본 스마트 계약에 제한 없이 액세스할 수 있으므로 승인된 토큰 금액을 제한 없이 활용할 수 있습니다." + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:266 +msgid "Theme" +msgstr "주제" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:39 +msgid "Duplicate Token" +msgstr "중복 토큰" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:40 +msgid "The address you entered is duplicate, please enter a new address." +msgstr "입력하신 주소가 중복됩니다. 새 주소를 입력하세요." + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:46 +msgid "Token Already Exists" +msgstr "토큰이 이미 존재합니다" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:47 +msgid "There's no need to add this token again because it already exists and is supported by us." +msgstr "이 토큰은 이미 존재하고 당사에서 지원하므로 다시 추가할 필요가 없습니다." + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:53 +msgid "Token Not Found" +msgstr "토큰을 찾을 수 없습니다" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:54 +msgid "Sorry, no token was found on {blockchain} chain with the provided address. please make sure you have entered the right token address." +msgstr "죄송합니다. 제공된 주소로 {blockchain} 체인에서 토큰을 찾을 수 없습니다. 올바른 토큰 주소를 입력했는지 확인하세요." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:78 +msgid "Network Error" +msgstr "네트워크 오류" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:109 +#: widget/embedded/src/pages/CustomTokensPage.tsx:149 +msgid "Add Custom Token" +msgstr "사용자 정의 토큰 추가" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:127 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:128 +msgid "Select chain" +msgstr "체인 선택" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:132 +msgid "Enter Address" +msgstr "주소를 입력하세요" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:139 +msgid "Enter token address" +msgstr "토큰 주소를 입력하세요" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:176 +msgid "Failed Network, Please retry." +msgstr "네트워크에 오류가 발생했습니다. 다시 시도해 주세요." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:192 +msgid "Add another custom token" +msgstr "다른 사용자 정의 토큰 추가" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:236 +msgid "Confirm Swap" +msgstr "스왑 확인" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:254 +msgid "Start Swap" +msgstr "스왑 시작" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:282 +msgid "You get" +msgstr "당신은 얻을" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:102 +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:90 +msgid "Search Token" +msgstr "검색 토큰" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:134 +msgid "No custom tokens" +msgstr "사용자 정의 토큰 없음" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:135 +msgid "press the button to add your custom token" +msgstr "버튼을 눌러 사용자 정의 토큰을 추가하세요" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:158 +msgid "Delete Custom Token" +msgstr "사용자 정의 토큰 삭제" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:160 +msgid "Are you sure you want to Delete this Token?" +msgstr "이 토큰을 삭제하시겠습니까?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:59 +msgid "Complete" +msgstr "완벽한" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:63 +msgid "Running" +msgstr "달리기" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:65 +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:8 +msgid "Failed" +msgstr "실패한" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:149 +msgid "Clear" +msgstr "분명한" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:161 +msgid "Search Transaction" +msgstr "거래 검색" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:187 +msgid "No transactions" +msgstr "거래 없음" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:194 +msgid "Your transaction history is stored locally and will appear here after you start a swap" +msgstr "거래 내역은 로컬에 저장되며 스왑을 시작하면 여기에 표시됩니다." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:218 +msgid "Clear Transaction History" +msgstr "거래 내역 지우기" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:222 +msgid "Proceeding will remove all successful and failed transactions from the widget. Do you want to continue?" +msgstr "진행하면 위젯에서 모든 성공 및 실패한 거래가 제거됩니다. 계속하시겠습니까?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:229 +msgid "Note: This does not erase your transaction history on the chain; it only removes them here." +msgstr "참고: 이렇게 해도 체인의 거래 내역은 지워지지 않습니다. 단지 여기서만 삭제됩니다." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:243 +msgid "Yes, Clear the history" +msgstr "네, 기록을 지웁니다." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LanguagePage.tsx:56 +msgid "language" +msgstr "언어" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:121 +msgid "Deselect all" +msgstr "모두 선택 해제" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:121 +msgid "Select all" +msgstr "모두 선택" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:133 +msgid "Search {sourceType}" +msgstr "검색 {sourceType}" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectBlockchainPage.tsx:60 +msgid "Search Chain" +msgstr "검색 체인" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:67 +msgid "Source" +msgstr "원천" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:68 +msgid "Destination" +msgstr "목적지" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:74 +msgid "Swap {type}" +msgstr "스왑 {type}" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SettingsPage.tsx:45 +msgid "Currently, you're in campaign mode with restrictions on liquidity sources. Would you like to switch out of this mode and make use of all available liquidity sources?" +msgstr "현재 유동성 소스에 제한이 있는 캠페인 모드에 있습니다. 이 모드에서 전환하여 사용 가능한 모든 유동성 소스를 활용하시겠습니까?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SwapDetailsPage.tsx:27 +msgid "The request ID is necessary to display the swap details." +msgstr "스왑 세부 정보를 표시하려면 요청 ID가 필요합니다." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/WalletsPage.tsx:67 +#: widget/ui/src/containers/ConnectWalletsModal/ConnectWalletsModal.tsx:15 +msgid "Connect Wallets" +msgstr "지갑 연결" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/WalletsPage.tsx:82 +msgid "Choose a wallet to connect." +msgstr "연결할 지갑을 선택하세요." + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:25 +msgid "This week" +msgstr "이번 주" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:32 +msgid "This month" +msgstr "이번 달" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:39 +msgid "This year" +msgstr "올해" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:129 +msgid "Required: >= {min} {symbol}" +msgstr "필수: >= {min} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:142 +msgid "Required: > {min} {symbol}" +msgstr "필수: > {min} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:157 +msgid "Required: <= {max} {symbol}" +msgstr "필수: <= {max} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:170 +msgid "Required: < {max} {symbol}" +msgstr "필수: < {max} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:601 +msgid " for network fee" +msgstr " 네트워크 수수료" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:604 +msgid " for swap" +msgstr " 스왑을 위해" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:607 +msgid " for input and network fee" +msgstr " 입력 및 네트워크 요금" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:609 +msgid "Needs ≈ {requiredAmount} {symbol}{reason}, but you have {currentAmount} {symbol} in your {blockchain} wallet." +msgstr "≈ {requiredAmount} {symbol}{reason}가 필요한데, {currentAmount} {symbol} 가 {blockchain} 지갑에 있습니다." + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:669 +msgid "Waiting for connecting wallet" +msgstr "지갑 연결을 기다리는 중" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:673 +msgid "Waiting for other running tasks to be finished" +msgstr "다른 실행 중인 작업이 완료될 때까지 기다리기" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:676 +msgid "Waiting for changing wallet network" +msgstr "지갑 네트워크 변경을 기다리는 중" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:6 +msgid "Sunday" +msgstr "일요일" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:7 +msgid "Monday" +msgstr "월요일" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:8 +msgid "Tuesday" +msgstr "화요일" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:9 +msgid "Wednesday" +msgstr "수요일" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:10 +msgid "Thursday" +msgstr "목요일" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:11 +msgid "Friday" +msgstr "금요일" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:12 +msgid "Saturday" +msgstr "토요일" + +#. js-lingui-explicit-id +#: widget/ui/src/components/BottomLogo/BottomLogo.tsx:14 +msgid "Powered By" +msgstr "제공자:" + +#. js-lingui-explicit-id +#: widget/ui/src/components/FullExpandedQuote/FullExpandedQuote.Tooltip.tsx:37 +msgid "Aggregated Transaction" +msgstr "집계된 거래" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SelectableCategoryList/SelectableCategoryList.tsx:63 +msgid "{blockchainCategory}" +msgstr "{blockchainCategory}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/StepDetails/StepDetails.tsx:75 +#: widget/ui/src/components/StepDetails/StepDetails.tsx:102 +msgid "Swap on {fromChain} via {swapper}" +msgstr "{fromChain} 을 {swapper}을 통해 바꿔주세요" + +#. js-lingui-explicit-id +#: widget/ui/src/components/StepDetails/StepDetails.tsx:109 +msgid "Bridge to {toChain} via {swapper}" +msgstr "{swapper}를 경유하여 {toChain} 로 연결" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:10 +msgid "Completed" +msgstr "완전한" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:12 +msgid "In progress" +msgstr "진행중" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapToken.tsx:122 +msgid "Waiting for bridge transaction" +msgstr "브릿지 거래를 기다리는 중" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:12 +msgid "Connected" +msgstr "연결됨" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:13 +msgid "Disconnect" +msgstr "연결 해제" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:18 +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:19 +msgid "Install" +msgstr "설치하다" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:24 +msgid "Connecting ..." +msgstr "연결 중..." + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:25 +msgid "Connecting" +msgstr "연결 중" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:30 +msgid "Disconnected" +msgstr "연결 끊김" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:34 +msgid "you need to pass a correct state to Wallet." +msgstr "Wallet에 올바른 상태를 전달해야 합니다." + +#. js-lingui-explicit-id +#: widget/ui/src/containers/Notifications/NotificationNotFound.tsx:15 +msgid "There are no notifications." +msgstr "알림이 없습니다." + +#. js-lingui-explicit-id +#: widget/ui/src/containers/Notifications/Notifications.tsx:39 +msgid "Clear all" +msgstr "모두 지우기" + +#. js-lingui-explicit-id +#: widget/ui/src/containers/SwapInput/SwapInput.tsx:65 +msgid "Balance" +msgstr "균형" + +#. js-lingui-explicit-id +#: widget/ui/src/containers/SwapInput/SwapInput.tsx:73 +msgid "Max" +msgstr "맥스" + diff --git a/translations/lt.po b/translations/lt.po new file mode 100644 index 0000000000..f5fbf14ea4 --- /dev/null +++ b/translations/lt.po @@ -0,0 +1,1339 @@ +msgid "" +msgstr "" +"POT-Creation-Date: 2023-11-06 17:24+0330\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: @lingui/cli\n" +"Language: lt\n" +"Project-Id-Version: rango\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2024-11-27 15:57\n" +"Last-Translator: \n" +"Language-Team: Lithuanian\n" +"Plural-Forms: nplurals=4; plural=(n%10==1 && (n%100>19 || n%100<11) ? 0 : (n%10>=2 && n%10<=9) && (n%100>19 || n%100<11) ? 1 : n%1!=0 ? 2: 3);\n" +"X-Crowdin-Project: rango\n" +"X-Crowdin-Project-ID: 622238\n" +"X-Crowdin-Language: lt\n" +"X-Crowdin-File: en.po\n" +"X-Crowdin-File-ID: 30\n" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SameTokensWarning/SameTokensWarning.tsx:21 +msgid "No Routes Found" +msgstr "Maršrutų nerasta" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SameTokensWarning/SameTokensWarning.tsx:25 +msgid "You cannot use the same token for From and To." +msgstr "Negalite naudoti to paties prieigos rakto nuo ir iki." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:41 +#: widget/embedded/src/components/TokenList/TokenList.tsx:286 +#: widget/embedded/src/pages/HistoryPage.tsx:186 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:143 +msgid "No results found" +msgstr "Rezultatų nerasta" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:42 +#: widget/embedded/src/components/TokenList/TokenList.tsx:287 +#: widget/embedded/src/pages/HistoryPage.tsx:193 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:144 +msgid "Try using different keywords" +msgstr "Pabandykite naudoti skirtingus raktinius žodžius" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:72 +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:46 +#: widget/embedded/src/pages/SelectBlockchainPage.tsx:42 +#: widget/ui/src/containers/SwapInput/TokenSection.tsx:61 +msgid "Select Chain" +msgstr "Pasirinkite Grandinė" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:66 +msgid "All" +msgstr "Visi" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:100 +msgid "More +{count}" +msgstr "Daugiau +{count}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabAlert/ActivateTabAlert.tsx:17 +msgid "Activate this tab" +msgstr "Suaktyvinkite šį skirtuką" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabAlert/ActivateTabAlert.tsx:22 +msgid "Another tab is open and handles transactions." +msgstr "Kitas skirtukas atidarytas ir tvarko operacijas." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:20 +msgid "Activate current tab" +msgstr "Suaktyvinti dabartinį skirtuką" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:22 +msgid "Currently, some transactions are running and being handled by other browser tab. If you activate this tab, all transactions that are already in the transaction sign step will expire." +msgstr "Šiuo metu kai kurios operacijos vykdomos ir tvarkomos kitame naršyklės skirtuke. Jei suaktyvinsite šį skirtuką, visos operacijos, kurios jau yra operacijos pasirašymo žingsnyje, baigs galioti." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:33 +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:349 +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:152 +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:33 +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:116 +msgid "Confirm" +msgstr "Patvirtinti" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:365 +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:447 +msgid "Your {blockchainName} wallets" +msgstr "Jūsų {blockchainName} piniginės" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:384 +msgid "Insufficient account balance" +msgstr "Nepakankamas sąskaitos likutis" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:394 +msgid "Proceed anyway" +msgstr "Vis tiek tęskite" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:456 +msgid "You need to connect a {blockchainName} wallet." +msgstr "Turite prijungti {blockchainName} piniginę." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/WalletList.tsx:143 +msgid "Add {chain} chain" +msgstr "Pridėkite {chain} grandinę" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/WalletList.tsx:244 +msgid "Show more wallets" +msgstr "Rodyti daugiau piniginių" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:113 +msgid "Send to a different address" +msgstr "Siųsti kitu adresu" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:129 +msgid "Enter {blockchainName} address" +msgstr "Įveskite {blockchainName} adresą" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:147 +msgid "Address {destination} doesn't match the blockchain address pattern." +msgstr "Adresas {destination} neatitinka blockchain adreso šablono." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:59 +msgid "via" +msgstr "per" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:74 +msgid "This token doesn't appear on the active token list(s). Make sure this is the token that you want to trade." +msgstr "Šis prieigos raktas nerodomas aktyvių žetonų sąraše (-uose). Įsitikinkite, kad tai yra ženklas, kuriuo norite prekiauti." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:89 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:164 +msgid "Import" +msgstr "Importuoti" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/FilterSelector/FilterSelectorContent.tsx:26 +msgid "Status" +msgstr "Būsena" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/FilterSelector/FilterSelectorContent.tsx:33 +#: widget/embedded/src/components/NoResult/NoResult.helpers.ts:37 +#: widget/embedded/src/pages/SettingsPage.tsx:55 +msgid "Reset" +msgstr "Nustatyti iš naujo" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/CancelButton.tsx:18 +msgid "Cancel" +msgstr "Atšaukti" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:46 +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:34 +msgid "Refresh" +msgstr "Atnaujinti" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:63 +#: widget/ui/src/containers/Notifications/Notifications.tsx:35 +msgid "Notifications" +msgstr "Pranešimai" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:79 +#: widget/embedded/src/pages/SettingsPage.tsx:38 +msgid "Settings" +msgstr "Nustatymai" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:93 +#: widget/embedded/src/pages/HistoryPage.tsx:139 +msgid "History" +msgstr "Istorija" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/WalletButton.tsx:22 +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:16 +#: widget/embedded/src/constants/messages.ts:5 +msgid "Connect Wallet" +msgstr "Prijunkite Piniginę" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HistoryGroupedList/HistoryGroupedList.tsx:118 +#: widget/embedded/src/utils/date.ts:18 +#: widget/embedded/src/utils/time.ts:22 +msgid "Today" +msgstr "Šiandien" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/LoadingSwapDetails/LoadingSwapDetails.tsx:20 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:424 +msgid "Swaps steps" +msgstr "Sukeičia žingsnius" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/NoResult/NoResult.helpers.ts:25 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:191 +msgid "Retry" +msgstr "Bandykite dar kartą" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:149 +msgid "Slippage Error" +msgstr "Paslydimo klaida" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:150 +msgid "Slippage Warning" +msgstr "Paslydimo įspėjimas" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:153 +msgid "Bridge Limit Error" +msgstr "Tilto ribos klaida" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:240 +msgid "Yours: {amount} {symbol}" +msgstr "Jūsų: {amount} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:261 +msgid "Minimum required slippage: {minRequiredSlippage}" +msgstr "Minimalus reikalingas slydimas: {minRequiredSlippage}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:282 +msgid "Yours: {userSlippage}" +msgstr "Jūsų: {userSlippage}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:395 +msgid "See All Routes" +msgstr "Žiūrėti visus maršrutus" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:81 +msgid "View more info" +msgstr "Žiūrėti daugiau informacijos" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:91 +msgid "Gas & Fee Explanation" +msgstr "Dujų ir mokesčių paaiškinimas" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:107 +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:103 +msgid "Details" +msgstr "Detalės" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:146 +msgid "Total Payable Fee" +msgstr "Visas mokėtinas mokestis" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:166 +msgid "Hide non-payable fees" +msgstr "Slėpti nemokamus mokesčius" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:167 +msgid "Show non-payable fees" +msgstr "Rodyti nemokamus mokesčius" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:177 +msgid "Description" +msgstr "Aprašymas" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:181 +msgid "The following fees are considered in the transaction output and\n" +" you won’t need to pay extra gas for them." +msgstr "Toliau nurodyti mokesčiai atsižvelgiama į operacijos išvestį ir\n" +" už juos nereikės mokėti papildomų dujų." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteSummary.tsx:25 +msgid "Swap input" +msgstr "Sukeisti įvestį" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteSummary.tsx:44 +msgid "Estimated output" +msgstr "Numatoma produkcija" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteTrigger.tsx:65 +msgid "Via:" +msgstr "Per:" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteTrigger.tsx:150 +msgid "Chains:" +msgstr "Grandinės:" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/Quotes.tsx:77 +msgid "Sort by" +msgstr "Rūšiuoti pagal" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:17 +msgid "Smart Routing" +msgstr "Išmanusis maršruto parinkimas" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:21 +msgid "Lowest Fee" +msgstr "Mažiausias mokestis" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:25 +msgid "Fastest Transfer" +msgstr "Greičiausias perkėlimas" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:29 +msgid "Maximum Return" +msgstr "Didžiausia grąža" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:33 +msgid "Maximum Output" +msgstr "Maksimali išvestis" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:43 +msgid "Swapping" +msgstr "Keitimas" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:51 +msgid "Gas cost" +msgstr "Dujų kaina" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:59 +msgid "Receiving" +msgstr "Priėmimas" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:67 +msgid "Price impact" +msgstr "Kainos poveikis" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:35 +msgid "You need to increase slippage to at least {minRequiredSlippage} for this route." +msgstr "Šiam maršrutui reikia padidinti slydimą bent iki {minRequiredSlippage} ." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:59 +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:61 +msgid "We recommend you to increase slippage to at least {minRequiredSlippage} for this route." +msgstr "Rekomenduojame padidinti šio maršruto slydimą bent iki {minRequiredSlippage} ." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:68 +msgid "Caution, your slippage is high." +msgstr "Atsargiai, jūsų paslydimas didelis." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.tsx:78 +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.Warning.tsx:26 +msgid "Change" +msgstr "Keisti" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:42 +msgid "Change settings" +msgstr "Pakeiskite nustatymus" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:52 +msgid "High slippage" +msgstr "Didelis slydimas" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:53 +msgid "Low slippage" +msgstr "Mažas slydimas" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:57 +msgid " Caution, your slippage is high (={userSlippage}). Your trade may be front run." +msgstr " Atsargiai, jūsų slydimas didelis (={userSlippage}). Jūsų prekyba gali būti vykdoma iš anksto." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:78 +msgid "Confirm anyway" +msgstr "Vis tiek patvirtinkite" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:22 +msgid "Something went wrong" +msgstr "Kažkas nutiko" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:24 +msgid "Something went wrong. Please refresh the app." +msgstr "Kažkas nutiko. Atnaujinkite programą." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/Slippage.tsx:38 +msgid "Slippage tolerance per swap" +msgstr "Slydimo tolerancija vienam apsikeitimui" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/Slippage.tsx:91 +msgid "Custom" +msgstr "Pasirinktinis" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:11 +msgid "Your transaction will be reverted if the price changes unfavorably by more than this percentage." +msgstr "Jūsų sandoris bus grąžintas, jei kaina nepalankiai pasikeis daugiau nei šis procentas." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:16 +#: widget/embedded/src/containers/Settings/Lists.tsx:245 +msgid "Warning" +msgstr "Įspėjimas" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:17 +msgid "This setting is applied to each step (e.g. 1Inch, Thorchain, etc.), meaning only that specific step will be reverted, not the entire route." +msgstr "Šis nustatymas taikomas kiekvienam žingsniui (pvz., 1 colis, Thorchain ir kt.), o tai reiškia, kad bus grąžintas tik konkretus žingsnis, o ne visas maršrutas." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:25 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:269 +msgid "Swap Details" +msgstr "Keitimo detalės" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:33 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:312 +msgid "Request ID" +msgstr "Prašyti ID" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:64 +msgid "Not found" +msgstr "Nerasta" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:65 +msgid "Swap with request ID = {requestId} not found." +msgstr "Sukeisti su užklausos ID = {requestId} nerasta." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:219 +msgid "You have received {amount} {token} in {conciseAddress} wallet on {chain} chain." +msgstr "Gavote {amount} {token} {conciseAddress} piniginėje grandinėje {chain} ." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:242 +msgid "Transaction was not sent." +msgstr "Sandoris nebuvo išsiųstas." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:244 +msgid "{amount} {symbol} on {blockchain} remains in your wallet." +msgstr "{amount} {symbol} {blockchain} lieka jūsų piniginėje." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:281 +msgid "Delete" +msgstr "Ištrinti" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:304 +msgid "Try again" +msgstr "Bandykite dar kartą" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:322 +msgid "Copied To Clipboard" +msgstr "Nukopijuota į mainų sritį" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:323 +msgid "Copy Request ID" +msgstr "Nukopijuokite užklausos ID" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:346 +msgid "View on Rango Explorer" +msgstr "Žiūrėti Rango Explorer" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:355 +msgid "Finished at" +msgstr "Baigta val" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:355 +msgid "Created at" +msgstr "Sukurta" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.tsx:50 +msgid "View transaction" +msgstr "Peržiūrėti operaciją" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.Warning.tsx:49 +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:31 +msgid "Connect" +msgstr "Prisijunkite" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:43 +msgid "Swap Successful" +msgstr "Swap sėkmingas" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:71 +msgid "Transaction Failed" +msgstr "Sandoris nepavyko" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:87 +msgid "Done" +msgstr "Atlikta" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:100 +msgid "Diagnosis" +msgstr "Diagnozė" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:112 +msgid "See Details" +msgstr "Žr. Išsamią informaciją" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:13 +msgid "Cancel Swap" +msgstr "Atšaukti apsikeitimą" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:14 +msgid "Are you sure you want to cancel this swap?" +msgstr "Ar tikrai norite atšaukti šį apsikeitimą?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:23 +msgid "Yes, Cancel it" +msgstr "Taip, atšaukti" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:32 +#: widget/embedded/src/pages/CustomTokensPage.tsx:181 +msgid "No, Continue" +msgstr "Ne, Tęsti" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:13 +msgid "Delete Transaction" +msgstr "Ištrinti operaciją" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:14 +msgid "Are you sure you want to delete this swap?" +msgstr "Ar tikrai norite ištrinti šį apsikeitimą?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:23 +#: widget/embedded/src/pages/CustomTokensPage.tsx:171 +msgid "Yes, Delete it" +msgstr "Taip, ištrinkite" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:33 +#: widget/embedded/src/pages/HistoryPage.tsx:253 +msgid "No, Cancel" +msgstr "Ne, atšaukti" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:12 +msgid "Change Network" +msgstr "Keisti tinklą" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:20 +msgid "Network Changed" +msgstr "Pakeistas tinklas" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/TokenList/TokenList.tsx:271 +#: widget/ui/src/containers/SwapInput/TokenSection.tsx:54 +msgid "Select Token" +msgstr "Pasirinkite Žetonas" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:27 +msgid "Wallet Connected" +msgstr "Piniginė prijungta" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:28 +msgid "Your wallet is connected, you can use it to swap." +msgstr "Jūsų piniginė prijungta, galite ją naudoti apsikeitimui." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:39 +msgid "Failed to Connect" +msgstr "Nepavyko prisijungti" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:41 +msgid "Your wallet is not connected. Please try again." +msgstr "Jūsų piniginė neprijungta. Bandykite dar kartą." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:50 +msgid "Connecting to your wallet" +msgstr "Prisijungimas prie piniginės" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:51 +msgid "Click connect in your wallet popup." +msgstr "Iššokančiajame piniginės lange spustelėkite prisijungti." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:99 +msgid "Select Derivation Path" +msgstr "Pasirinkite išvedimo kelią" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:100 +msgid "In order to connect to {type}, you must first select a Derivation Path" +msgstr "Norėdami prisijungti prie {type}, pirmiausia turite pasirinkti išvedimo kelią" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:118 +msgid "Choose Derivation Path Template" +msgstr "Pasirinkite išvedimo kelio šabloną" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:133 +msgid "Enter Path" +msgstr "Įveskite kelią" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:134 +msgid "Enter Index" +msgstr "Įveskite indeksą" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:15 +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:18 +msgid "Add {blockchainDisplayName} Chain" +msgstr "Pridėti {blockchainDisplayName} grandinę" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:20 +msgid "Would you like to add the {blockchainDisplayName} experimental chain to your wallet?" +msgstr "Ar norėtumėte pridėti {blockchainDisplayName} eksperimentinę grandinę prie savo piniginės?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:22 +msgid "Please approve the experimental chain pop-up in your wallet." +msgstr "Patvirtinkite eksperimentinės grandinės iššokantįjį langą savo piniginėje." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:30 +msgid "{blockchainDisplayName} Chain Added" +msgstr "{blockchainDisplayName} Pridėta grandinė" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:34 +msgid "The {blockchainDisplayName} chain has been successfully added to your wallet." +msgstr "Grandinė {blockchainDisplayName} sėkmingai pridėta prie jūsų piniginės." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:42 +msgid "Request Rejected" +msgstr "Užklausa atmesta" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:43 +msgid "You've rejected adding {blockchainDisplayName} chain to your wallet." +msgstr "Jūs atsisakėte pridėti {blockchainDisplayName} grandinę prie savo piniginės." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:70 +msgid "Select chain types" +msgstr "Pasirinkite grandinės tipus" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:71 +msgid "This wallet supports multiple chains. Select which chain you'd like to connect to." +msgstr "Ši piniginė palaiko kelias grandines. Pasirinkite, prie kurios grandinės norite prisijungti." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:9 +msgid "Failed Network, Please retry your swap." +msgstr "Nepavyko pakeisti tinklo. Bandykite dar kartą pakeisti." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:11 +msgid "Please reset your liquidity sources." +msgstr "Iš naujo nustatykite savo likvidumo šaltinius." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:12 +msgid "You have limited the liquidity sources and this might result in Rango finding no routes. Please consider resetting your liquidity sources." +msgstr "Apribojote likvidumo šaltinius, todėl Rango gali nerasti maršrutų. Apsvarstykite galimybę iš naujo nustatyti savo likvidumo šaltinius." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:17 +msgid "No Routes Found." +msgstr "Maršrutų nerasta." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:18 +msgid "Reasons why Rango couldn't find a route: low liquidity on token, very low input amount or no routes available for the selected input/output token combination." +msgstr "Priežastys, kodėl Rango negalėjo rasti maršruto: mažas prieigos rakto likvidumas, labai mažas įvesties kiekis arba nėra maršrutų pasirinktam įvesties / išvesties prieigos rakto deriniui." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:23 +msgid "Bridge Limit Error: Please increase your amount." +msgstr "Tilto limito klaida: padidinkite sumą." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:26 +msgid "Bridge Limit Error: Please decrease your amount." +msgstr "Tilto limito klaida: sumažinkite sumą." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:31 +msgid "High Price Impact" +msgstr "Didelės kainos poveikis" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:32 +msgid "Price impact is too high!" +msgstr "Kainos poveikis per didelis!" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:33 +msgid "The price impact is significantly higher than the allowed amount." +msgstr "Įtaka kainai yra žymiai didesnė nei leistina suma." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:36 +msgid "Confirm high price impact" +msgstr "Patvirtinkite didelės kainos poveikį" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:39 +msgid "Route updated and price impact is too high, try again later!" +msgstr "Maršrutas atnaujintas ir kainos poveikis per didelis, bandykite dar kartą vėliau!" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:44 +msgid "USD Price Unknown" +msgstr "USD Kaina Nežinoma" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:45 +msgid "USD Price Unknown, Cannot calculate Price Impact." +msgstr "USD Kaina nežinoma, negalima apskaičiuoti kainos poveikio." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:46 +msgid "USD Price Unknown, Cannot calculate Price Impact. The price impact may be higher than usual. Are you sure to continue the Swap?" +msgstr "USD Kaina nežinoma, negalima apskaičiuoti kainos poveikio. Kainos poveikis gali būti didesnis nei įprastai. Ar tikrai tęsite apsikeitimą?" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:49 +msgid "Confirm USD Price Unknown" +msgstr "Patvirtinti USD Kaina nežinoma" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:6 +#: widget/embedded/src/pages/Home.tsx:163 +msgid "Swap" +msgstr "Sukeisti" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:7 +msgid "Swap anyway" +msgstr "Vistiek sukeisk" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:8 +msgid "The route goes through Ethereum. Continue?" +msgstr "Maršrutas eina per Ethereum. Tęsti?" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:10 +msgid "Route has been updated." +msgstr "Maršrutas atnaujintas." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:12 +msgid "Output amount changed to {newOutputAmount} ({percentageChange}% change)." +msgstr "Išvesties kiekis pakeistas į {newOutputAmount} ({percentageChange}% pokytis)." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:20 +msgid "Route swappers has been updated." +msgstr "Atnaujinti maršrutų keitikliai." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:22 +msgid "Route internal coins has been updated." +msgstr "Maršruto vidinės monetos buvo atnaujintos." + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/ExpandedQuotes/ExpandedQuotes.tsx:53 +#: widget/embedded/src/pages/Routes.tsx:48 +msgid "Routes" +msgstr "Maršrutai" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Inputs/Inputs.tsx:76 +msgid "From" +msgstr "Iš" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Inputs/Inputs.tsx:118 +msgid "To" +msgstr "Į" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:49 +msgid "Light" +msgstr "Šviesa" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:58 +msgid "Dark" +msgstr "Tamsus" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:67 +msgid "Auto" +msgstr "Auto" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:140 +msgid "Loading failed" +msgstr "Įkelti nepavyko" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:156 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:41 +msgid "Bridges" +msgstr "Tiltai" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:174 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:41 +msgid "Exchanges" +msgstr "Mainai" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:195 +#: widget/embedded/src/pages/CustomTokensPage.tsx:90 +msgid "Custom Tokens" +msgstr "Pasirinktiniai žetonai" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:214 +#: widget/embedded/src/pages/LanguagePage.tsx:43 +msgid "Language" +msgstr "Kalba" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:235 +msgid "Infinite approval" +msgstr "Begalinis pritarimas" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:246 +msgid "Enabling the 'Infinite approval' mode grants unrestricted access to underlying smart contracts, allowing them to utilize the approved token amount without limitations." +msgstr "Įjungus „Begalinio patvirtinimo“ režimą, suteikiama neribota prieiga prie pagrindinių išmaniųjų sutarčių, leidžianti joms be apribojimų naudoti patvirtintą prieigos rakto sumą." + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:266 +msgid "Theme" +msgstr "tema" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:39 +msgid "Duplicate Token" +msgstr "Tokeno kopija" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:40 +msgid "The address you entered is duplicate, please enter a new address." +msgstr "Įvestas adresas pasikartoja, įveskite naują adresą." + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:46 +msgid "Token Already Exists" +msgstr "Žetonas jau egzistuoja" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:47 +msgid "There's no need to add this token again because it already exists and is supported by us." +msgstr "Nereikia dar kartą pridėti šio prieigos rakto, nes jis jau yra ir yra mūsų palaikomas." + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:53 +msgid "Token Not Found" +msgstr "Žetonas nerastas" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:54 +msgid "Sorry, no token was found on {blockchain} chain with the provided address. please make sure you have entered the right token address." +msgstr "Atsiprašome, grandinėje {blockchain} su nurodytu adresu žetonas nerastas. įsitikinkite, kad įvedėte tinkamą prieigos rakto adresą." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:78 +msgid "Network Error" +msgstr "Tinklo klaida" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:109 +#: widget/embedded/src/pages/CustomTokensPage.tsx:149 +msgid "Add Custom Token" +msgstr "Pridėti pasirinktinį prieigos raktą" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:127 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:128 +msgid "Select chain" +msgstr "Pasirinkite grandinę" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:132 +msgid "Enter Address" +msgstr "Įveskite adresą" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:139 +msgid "Enter token address" +msgstr "Įveskite žetono adresą" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:176 +msgid "Failed Network, Please retry." +msgstr "Nepavyko prisijungti prie tinklo, bandykite dar kartą." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:192 +msgid "Add another custom token" +msgstr "Pridėkite kitą tinkintą prieigos raktą" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:236 +msgid "Confirm Swap" +msgstr "Patvirtinkite apsikeitimą" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:254 +msgid "Start Swap" +msgstr "Pradėti Swap" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:282 +msgid "You get" +msgstr "Jūs gaunate" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:102 +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:90 +msgid "Search Token" +msgstr "Paieškos ženklas" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:134 +msgid "No custom tokens" +msgstr "Nėra tinkintų žetonų" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:135 +msgid "press the button to add your custom token" +msgstr "paspauskite mygtuką, kad pridėtumėte pasirinktinį prieigos raktą" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:158 +msgid "Delete Custom Token" +msgstr "Ištrinkite tinkintą prieigos raktą" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:160 +msgid "Are you sure you want to Delete this Token?" +msgstr "Ar tikrai norite ištrinti šį prieigos raktą?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:59 +msgid "Complete" +msgstr "Užbaigti" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:63 +msgid "Running" +msgstr "Bėgimas" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:65 +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:8 +msgid "Failed" +msgstr "Nepavyko" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:149 +msgid "Clear" +msgstr "Aišku" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:161 +msgid "Search Transaction" +msgstr "Paieškos sandoris" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:187 +msgid "No transactions" +msgstr "Jokių sandorių" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:194 +msgid "Your transaction history is stored locally and will appear here after you start a swap" +msgstr "Jūsų operacijų istorija saugoma vietoje ir bus rodoma čia, kai pradėsite apsikeitimą" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:218 +msgid "Clear Transaction History" +msgstr "Išvalyti operacijų istoriją" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:222 +msgid "Proceeding will remove all successful and failed transactions from the widget. Do you want to continue?" +msgstr "Tęsiant bus pašalintos visos sėkmingos ir nepavykusios operacijos iš valdiklio. Ar norite tęsti?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:229 +msgid "Note: This does not erase your transaction history on the chain; it only removes them here." +msgstr "Pastaba: tai neištrina jūsų operacijų istorijos grandinėje; tai tik pašalina juos čia." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:243 +msgid "Yes, Clear the history" +msgstr "Taip, išvalykite istoriją" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LanguagePage.tsx:56 +msgid "language" +msgstr "kalba" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:121 +msgid "Deselect all" +msgstr "Panaikinkite visų pasirinkimą" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:121 +msgid "Select all" +msgstr "Pasirinkite viską" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:133 +msgid "Search {sourceType}" +msgstr "Ieškoti {sourceType}" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectBlockchainPage.tsx:60 +msgid "Search Chain" +msgstr "Paieškos grandinė" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:67 +msgid "Source" +msgstr "Šaltinis" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:68 +msgid "Destination" +msgstr "Paskirties vieta" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:74 +msgid "Swap {type}" +msgstr "Sukeisti {type}" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SettingsPage.tsx:45 +msgid "Currently, you're in campaign mode with restrictions on liquidity sources. Would you like to switch out of this mode and make use of all available liquidity sources?" +msgstr "Šiuo metu veikiate kampanijos režimu su apribojimais likvidumo šaltiniams. Ar norėtumėte išjungti šį režimą ir pasinaudoti visais turimais likvidumo šaltiniais?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SwapDetailsPage.tsx:27 +msgid "The request ID is necessary to display the swap details." +msgstr "Užklausos ID būtinas norint parodyti apsikeitimo informaciją." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/WalletsPage.tsx:67 +#: widget/ui/src/containers/ConnectWalletsModal/ConnectWalletsModal.tsx:15 +msgid "Connect Wallets" +msgstr "Prijunkite pinigines" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/WalletsPage.tsx:82 +msgid "Choose a wallet to connect." +msgstr "Pasirinkite piniginę, kurią norite prijungti." + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:25 +msgid "This week" +msgstr "Šią savaitę" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:32 +msgid "This month" +msgstr "Šį mėnesį" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:39 +msgid "This year" +msgstr "Šiemet" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:129 +msgid "Required: >= {min} {symbol}" +msgstr "Būtina: >= {min} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:142 +msgid "Required: > {min} {symbol}" +msgstr "Būtina: > {min} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:157 +msgid "Required: <= {max} {symbol}" +msgstr "Būtina: <= {max} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:170 +msgid "Required: < {max} {symbol}" +msgstr "Būtina: < {max} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:601 +msgid " for network fee" +msgstr " už tinklo mokestį" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:604 +msgid " for swap" +msgstr " už mainus" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:607 +msgid " for input and network fee" +msgstr " už įvesties ir tinklo mokestį" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:609 +msgid "Needs ≈ {requiredAmount} {symbol}{reason}, but you have {currentAmount} {symbol} in your {blockchain} wallet." +msgstr "Reikia ≈ {requiredAmount} {symbol}{reason}, bet jūsų {blockchain} piniginėje yra {currentAmount} {symbol} ." + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:669 +msgid "Waiting for connecting wallet" +msgstr "Laukiama prijungiant piniginę" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:673 +msgid "Waiting for other running tasks to be finished" +msgstr "Laukiama, kol bus baigtos kitos bėgimo užduotys" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:676 +msgid "Waiting for changing wallet network" +msgstr "Laukiama, kol bus pakeistas piniginės tinklas" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:6 +msgid "Sunday" +msgstr "sekmadienis" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:7 +msgid "Monday" +msgstr "pirmadienis" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:8 +msgid "Tuesday" +msgstr "antradienis" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:9 +msgid "Wednesday" +msgstr "trečiadienį" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:10 +msgid "Thursday" +msgstr "ketvirtadienis" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:11 +msgid "Friday" +msgstr "penktadienis" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:12 +msgid "Saturday" +msgstr "šeštadienis" + +#. js-lingui-explicit-id +#: widget/ui/src/components/BottomLogo/BottomLogo.tsx:14 +msgid "Powered By" +msgstr "Maitinamas" + +#. js-lingui-explicit-id +#: widget/ui/src/components/FullExpandedQuote/FullExpandedQuote.Tooltip.tsx:37 +msgid "Aggregated Transaction" +msgstr "Suvestinė operacija" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SelectableCategoryList/SelectableCategoryList.tsx:63 +msgid "{blockchainCategory}" +msgstr "{blockchainCategory}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/StepDetails/StepDetails.tsx:75 +#: widget/ui/src/components/StepDetails/StepDetails.tsx:102 +msgid "Swap on {fromChain} via {swapper}" +msgstr "Pakeiskite į {fromChain} per {swapper}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/StepDetails/StepDetails.tsx:109 +msgid "Bridge to {toChain} via {swapper}" +msgstr "Tiltas į {toChain} per {swapper}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:10 +msgid "Completed" +msgstr "Užbaigta" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:12 +msgid "In progress" +msgstr "Vykdoma" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapToken.tsx:122 +msgid "Waiting for bridge transaction" +msgstr "Laukiama tilto sandorio" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:12 +msgid "Connected" +msgstr "Prisijungta" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:13 +msgid "Disconnect" +msgstr "Atsijungti" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:18 +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:19 +msgid "Install" +msgstr "Įdiegti" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:24 +msgid "Connecting ..." +msgstr "Jungiamasi..." + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:25 +msgid "Connecting" +msgstr "Prisijungimas" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:30 +msgid "Disconnected" +msgstr "Atjungtas" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:34 +msgid "you need to pass a correct state to Wallet." +msgstr "Piniginėje turite perduoti teisingą būseną." + +#. js-lingui-explicit-id +#: widget/ui/src/containers/Notifications/NotificationNotFound.tsx:15 +msgid "There are no notifications." +msgstr "Pranešimų nėra." + +#. js-lingui-explicit-id +#: widget/ui/src/containers/Notifications/Notifications.tsx:39 +msgid "Clear all" +msgstr "Išvalyti viską" + +#. js-lingui-explicit-id +#: widget/ui/src/containers/SwapInput/SwapInput.tsx:65 +msgid "Balance" +msgstr "Balansas" + +#. js-lingui-explicit-id +#: widget/ui/src/containers/SwapInput/SwapInput.tsx:73 +msgid "Max" +msgstr "Maks" + diff --git a/translations/ms.po b/translations/ms.po new file mode 100644 index 0000000000..b4f3c343b1 --- /dev/null +++ b/translations/ms.po @@ -0,0 +1,1339 @@ +msgid "" +msgstr "" +"POT-Creation-Date: 2023-11-06 17:24+0330\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: @lingui/cli\n" +"Language: ms\n" +"Project-Id-Version: rango\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2024-11-27 15:57\n" +"Last-Translator: \n" +"Language-Team: Malay\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Crowdin-Project: rango\n" +"X-Crowdin-Project-ID: 622238\n" +"X-Crowdin-Language: ms\n" +"X-Crowdin-File: en.po\n" +"X-Crowdin-File-ID: 30\n" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SameTokensWarning/SameTokensWarning.tsx:21 +msgid "No Routes Found" +msgstr "Tiada Laluan Ditemui" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SameTokensWarning/SameTokensWarning.tsx:25 +msgid "You cannot use the same token for From and To." +msgstr "Anda tidak boleh menggunakan token yang sama untuk Dari dan Kepada." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:41 +#: widget/embedded/src/components/TokenList/TokenList.tsx:286 +#: widget/embedded/src/pages/HistoryPage.tsx:186 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:143 +msgid "No results found" +msgstr "Tiada hasil ditemui" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:42 +#: widget/embedded/src/components/TokenList/TokenList.tsx:287 +#: widget/embedded/src/pages/HistoryPage.tsx:193 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:144 +msgid "Try using different keywords" +msgstr "Cuba gunakan kata kunci yang berbeza" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:72 +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:46 +#: widget/embedded/src/pages/SelectBlockchainPage.tsx:42 +#: widget/ui/src/containers/SwapInput/TokenSection.tsx:61 +msgid "Select Chain" +msgstr "Pilih Rantaian" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:66 +msgid "All" +msgstr "Semua" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:100 +msgid "More +{count}" +msgstr "Lagi +{count}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabAlert/ActivateTabAlert.tsx:17 +msgid "Activate this tab" +msgstr "Aktifkan tab ini" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabAlert/ActivateTabAlert.tsx:22 +msgid "Another tab is open and handles transactions." +msgstr "Tab lain dibuka dan mengendalikan transaksi." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:20 +msgid "Activate current tab" +msgstr "Aktifkan tab semasa" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:22 +msgid "Currently, some transactions are running and being handled by other browser tab. If you activate this tab, all transactions that are already in the transaction sign step will expire." +msgstr "Pada masa ini, beberapa transaksi sedang berjalan dan dikendalikan oleh tab penyemak imbas lain. Jika anda mengaktifkan tab ini, semua transaksi yang sudah berada dalam langkah tanda transaksi akan tamat tempoh." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:33 +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:349 +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:152 +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:33 +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:116 +msgid "Confirm" +msgstr "sahkan" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:365 +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:447 +msgid "Your {blockchainName} wallets" +msgstr "Dompet {blockchainName} anda" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:384 +msgid "Insufficient account balance" +msgstr "Baki akaun tidak mencukupi" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:394 +msgid "Proceed anyway" +msgstr "Teruskan juga" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:456 +msgid "You need to connect a {blockchainName} wallet." +msgstr "Anda perlu menyambung dompet {blockchainName} ." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/WalletList.tsx:143 +msgid "Add {chain} chain" +msgstr "Tambahkan rantai {chain}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/WalletList.tsx:244 +msgid "Show more wallets" +msgstr "Tunjukkan lebih banyak dompet" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:113 +msgid "Send to a different address" +msgstr "Hantar ke alamat lain" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:129 +msgid "Enter {blockchainName} address" +msgstr "Masukkan {blockchainName} alamat" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:147 +msgid "Address {destination} doesn't match the blockchain address pattern." +msgstr "Alamat {destination} tidak sepadan dengan corak alamat blockchain." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:59 +msgid "via" +msgstr "melalui" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:74 +msgid "This token doesn't appear on the active token list(s). Make sure this is the token that you want to trade." +msgstr "Token ini tidak muncul pada senarai token aktif. Pastikan ini adalah token yang anda ingin berdagang." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:89 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:164 +msgid "Import" +msgstr "Import" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/FilterSelector/FilterSelectorContent.tsx:26 +msgid "Status" +msgstr "Status" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/FilterSelector/FilterSelectorContent.tsx:33 +#: widget/embedded/src/components/NoResult/NoResult.helpers.ts:37 +#: widget/embedded/src/pages/SettingsPage.tsx:55 +msgid "Reset" +msgstr "Tetapkan semula" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/CancelButton.tsx:18 +msgid "Cancel" +msgstr "Batal" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:46 +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:34 +msgid "Refresh" +msgstr "Segarkan semula" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:63 +#: widget/ui/src/containers/Notifications/Notifications.tsx:35 +msgid "Notifications" +msgstr "Pemberitahuan" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:79 +#: widget/embedded/src/pages/SettingsPage.tsx:38 +msgid "Settings" +msgstr "tetapan" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:93 +#: widget/embedded/src/pages/HistoryPage.tsx:139 +msgid "History" +msgstr "Sejarah" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/WalletButton.tsx:22 +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:16 +#: widget/embedded/src/constants/messages.ts:5 +msgid "Connect Wallet" +msgstr "Sambung Wallet" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HistoryGroupedList/HistoryGroupedList.tsx:118 +#: widget/embedded/src/utils/date.ts:18 +#: widget/embedded/src/utils/time.ts:22 +msgid "Today" +msgstr "Hari ini" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/LoadingSwapDetails/LoadingSwapDetails.tsx:20 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:424 +msgid "Swaps steps" +msgstr "Bertukar langkah" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/NoResult/NoResult.helpers.ts:25 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:191 +msgid "Retry" +msgstr "Cuba semula" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:149 +msgid "Slippage Error" +msgstr "Ralat Gelinciran" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:150 +msgid "Slippage Warning" +msgstr "Amaran Gelinciran" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:153 +msgid "Bridge Limit Error" +msgstr "Ralat Had Jambatan" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:240 +msgid "Yours: {amount} {symbol}" +msgstr "Milik anda: {amount} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:261 +msgid "Minimum required slippage: {minRequiredSlippage}" +msgstr "Kegelinciran minimum yang diperlukan: {minRequiredSlippage}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:282 +msgid "Yours: {userSlippage}" +msgstr "Milik anda: {userSlippage}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:395 +msgid "See All Routes" +msgstr "Lihat Semua Laluan" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:81 +msgid "View more info" +msgstr "Lihat maklumat lanjut" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:91 +msgid "Gas & Fee Explanation" +msgstr "Penjelasan Gas & Yuran" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:107 +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:103 +msgid "Details" +msgstr "Butiran" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:146 +msgid "Total Payable Fee" +msgstr "Jumlah Yuran Yang Perlu Dibayar" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:166 +msgid "Hide non-payable fees" +msgstr "Sembunyikan yuran yang tidak perlu dibayar" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:167 +msgid "Show non-payable fees" +msgstr "Tunjukkan yuran yang tidak perlu dibayar" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:177 +msgid "Description" +msgstr "Penerangan" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:181 +msgid "The following fees are considered in the transaction output and\n" +" you won’t need to pay extra gas for them." +msgstr "Yuran berikut dipertimbangkan dalam output transaksi dan\n" +" anda tidak perlu membayar gas tambahan untuknya." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteSummary.tsx:25 +msgid "Swap input" +msgstr "Tukar input" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteSummary.tsx:44 +msgid "Estimated output" +msgstr "Anggaran keluaran" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteTrigger.tsx:65 +msgid "Via:" +msgstr "Melalui:" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteTrigger.tsx:150 +msgid "Chains:" +msgstr "rantai:" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/Quotes.tsx:77 +msgid "Sort by" +msgstr "Isih mengikut" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:17 +msgid "Smart Routing" +msgstr "Penghalaan Pintar" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:21 +msgid "Lowest Fee" +msgstr "Yuran Terendah" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:25 +msgid "Fastest Transfer" +msgstr "Pemindahan Terpantas" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:29 +msgid "Maximum Return" +msgstr "Pulangan Maksimum" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:33 +msgid "Maximum Output" +msgstr "Output Maksimum" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:43 +msgid "Swapping" +msgstr "Bertukar-tukar" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:51 +msgid "Gas cost" +msgstr "Kos gas" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:59 +msgid "Receiving" +msgstr "Menerima" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:67 +msgid "Price impact" +msgstr "Kesan harga" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:35 +msgid "You need to increase slippage to at least {minRequiredSlippage} for this route." +msgstr "Anda perlu meningkatkan gelinciran kepada sekurang-kurangnya {minRequiredSlippage} untuk laluan ini." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:59 +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:61 +msgid "We recommend you to increase slippage to at least {minRequiredSlippage} for this route." +msgstr "Kami mengesyorkan anda meningkatkan gelinciran kepada sekurang-kurangnya {minRequiredSlippage} untuk laluan ini." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:68 +msgid "Caution, your slippage is high." +msgstr "Awas, gelinciran anda tinggi." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.tsx:78 +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.Warning.tsx:26 +msgid "Change" +msgstr "Berubah" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:42 +msgid "Change settings" +msgstr "Tukar tetapan" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:52 +msgid "High slippage" +msgstr "gelinciran tinggi" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:53 +msgid "Low slippage" +msgstr "gelinciran rendah" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:57 +msgid " Caution, your slippage is high (={userSlippage}). Your trade may be front run." +msgstr " Awas, gelinciran anda tinggi (={userSlippage}). Dagangan anda mungkin dijalankan di hadapan." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:78 +msgid "Confirm anyway" +msgstr "Confirm pula" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:22 +msgid "Something went wrong" +msgstr "Sesuatu telah berlaku" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:24 +msgid "Something went wrong. Please refresh the app." +msgstr "Sesuatu telah berlaku. Sila muat semula apl." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/Slippage.tsx:38 +msgid "Slippage tolerance per swap" +msgstr "Toleransi gelinciran setiap pertukaran" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/Slippage.tsx:91 +msgid "Custom" +msgstr "Adat" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:11 +msgid "Your transaction will be reverted if the price changes unfavorably by more than this percentage." +msgstr "Urus niaga anda akan dikembalikan jika harga berubah secara tidak menguntungkan lebih daripada peratusan ini." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:16 +#: widget/embedded/src/containers/Settings/Lists.tsx:245 +msgid "Warning" +msgstr "Amaran" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:17 +msgid "This setting is applied to each step (e.g. 1Inch, Thorchain, etc.), meaning only that specific step will be reverted, not the entire route." +msgstr "Tetapan ini digunakan pada setiap langkah (cth. 1Inch, Thorchain, dsb.), bermakna hanya langkah tertentu itu akan dibalikkan, bukan keseluruhan laluan." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:25 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:269 +msgid "Swap Details" +msgstr "Swap Butiran" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:33 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:312 +msgid "Request ID" +msgstr "Minta ID" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:64 +msgid "Not found" +msgstr "Tidak dijumpai" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:65 +msgid "Swap with request ID = {requestId} not found." +msgstr "Tukar dengan ID permintaan = {requestId} tidak ditemui." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:219 +msgid "You have received {amount} {token} in {conciseAddress} wallet on {chain} chain." +msgstr "Anda telah menerima {amount} {token} dalam dompet {conciseAddress} pada rantai {chain} ." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:242 +msgid "Transaction was not sent." +msgstr "Urus niaga tidak dihantar." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:244 +msgid "{amount} {symbol} on {blockchain} remains in your wallet." +msgstr "{amount} {symbol} pada {blockchain} kekal dalam dompet anda." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:281 +msgid "Delete" +msgstr "Padam" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:304 +msgid "Try again" +msgstr "Cuba lagi" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:322 +msgid "Copied To Clipboard" +msgstr "Disalin Ke Papan Klip" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:323 +msgid "Copy Request ID" +msgstr "Salin ID Permintaan" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:346 +msgid "View on Rango Explorer" +msgstr "Lihat pada Rango Explorer" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:355 +msgid "Finished at" +msgstr "Selesai pada" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:355 +msgid "Created at" +msgstr "Dicipta pada" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.tsx:50 +msgid "View transaction" +msgstr "Lihat transaksi" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.Warning.tsx:49 +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:31 +msgid "Connect" +msgstr "Sambung" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:43 +msgid "Swap Successful" +msgstr "Tukar Berjaya" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:71 +msgid "Transaction Failed" +msgstr "Transaksi Gagal" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:87 +msgid "Done" +msgstr "Selesai" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:100 +msgid "Diagnosis" +msgstr "Diagnosis" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:112 +msgid "See Details" +msgstr "Lihat Butiran" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:13 +msgid "Cancel Swap" +msgstr "Batalkan Swap" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:14 +msgid "Are you sure you want to cancel this swap?" +msgstr "Adakah anda pasti mahu membatalkan pertukaran ini?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:23 +msgid "Yes, Cancel it" +msgstr "Ya, Batalkan" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:32 +#: widget/embedded/src/pages/CustomTokensPage.tsx:181 +msgid "No, Continue" +msgstr "Tidak, Teruskan" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:13 +msgid "Delete Transaction" +msgstr "Padamkan Transaksi" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:14 +msgid "Are you sure you want to delete this swap?" +msgstr "Adakah anda pasti mahu memadamkan pertukaran ini?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:23 +#: widget/embedded/src/pages/CustomTokensPage.tsx:171 +msgid "Yes, Delete it" +msgstr "Ya, Padamkannya" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:33 +#: widget/embedded/src/pages/HistoryPage.tsx:253 +msgid "No, Cancel" +msgstr "Tidak, Batal" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:12 +msgid "Change Network" +msgstr "Tukar Rangkaian" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:20 +msgid "Network Changed" +msgstr "Rangkaian Berubah" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/TokenList/TokenList.tsx:271 +#: widget/ui/src/containers/SwapInput/TokenSection.tsx:54 +msgid "Select Token" +msgstr "Pilih Token" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:27 +msgid "Wallet Connected" +msgstr "Dompet Disambungkan" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:28 +msgid "Your wallet is connected, you can use it to swap." +msgstr "Dompet anda disambungkan, anda boleh menggunakannya untuk menukar." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:39 +msgid "Failed to Connect" +msgstr "Gagal Bersambung" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:41 +msgid "Your wallet is not connected. Please try again." +msgstr "Dompet anda tidak disambungkan. Sila cuba lagi." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:50 +msgid "Connecting to your wallet" +msgstr "Menyambung ke dompet anda" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:51 +msgid "Click connect in your wallet popup." +msgstr "Klik sambung dalam pop timbul dompet anda." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:99 +msgid "Select Derivation Path" +msgstr "Pilih Laluan Derivasi" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:100 +msgid "In order to connect to {type}, you must first select a Derivation Path" +msgstr "Untuk menyambung ke {type}, anda mesti memilih Laluan Derivasi dahulu" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:118 +msgid "Choose Derivation Path Template" +msgstr "Pilih Templat Laluan Derivasi" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:133 +msgid "Enter Path" +msgstr "Masukkan Laluan" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:134 +msgid "Enter Index" +msgstr "Masukkan Indeks" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:15 +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:18 +msgid "Add {blockchainDisplayName} Chain" +msgstr "Tambah {blockchainDisplayName} Rantaian" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:20 +msgid "Would you like to add the {blockchainDisplayName} experimental chain to your wallet?" +msgstr "Adakah anda ingin menambahkan rantaian percubaan {blockchainDisplayName} pada dompet anda?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:22 +msgid "Please approve the experimental chain pop-up in your wallet." +msgstr "Sila luluskan tetingkap timbul rangkaian percubaan dalam dompet anda." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:30 +msgid "{blockchainDisplayName} Chain Added" +msgstr "{blockchainDisplayName} Rantaian Ditambah" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:34 +msgid "The {blockchainDisplayName} chain has been successfully added to your wallet." +msgstr "Rantaian {blockchainDisplayName} telah berjaya ditambahkan pada dompet anda." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:42 +msgid "Request Rejected" +msgstr "Permintaan Ditolak" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:43 +msgid "You've rejected adding {blockchainDisplayName} chain to your wallet." +msgstr "Anda telah menolak menambah rantai {blockchainDisplayName} pada dompet anda." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:70 +msgid "Select chain types" +msgstr "Pilih jenis rantai" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:71 +msgid "This wallet supports multiple chains. Select which chain you'd like to connect to." +msgstr "Dompet ini menyokong berbilang rantai. Pilih rangkaian yang anda ingin sambungkan." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:9 +msgid "Failed Network, Please retry your swap." +msgstr "Rangkaian Gagal, Sila cuba semula pertukaran anda." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:11 +msgid "Please reset your liquidity sources." +msgstr "Sila tetapkan semula sumber kecairan anda." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:12 +msgid "You have limited the liquidity sources and this might result in Rango finding no routes. Please consider resetting your liquidity sources." +msgstr "Anda telah mengehadkan sumber kecairan dan ini mungkin menyebabkan Rango tidak menemui laluan. Sila pertimbangkan untuk menetapkan semula sumber kecairan anda." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:17 +msgid "No Routes Found." +msgstr "Tiada Laluan Ditemui." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:18 +msgid "Reasons why Rango couldn't find a route: low liquidity on token, very low input amount or no routes available for the selected input/output token combination." +msgstr "Sebab Rango tidak menemui laluan: kecairan yang rendah pada token, jumlah input yang sangat rendah atau tiada laluan tersedia untuk gabungan token input/output yang dipilih." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:23 +msgid "Bridge Limit Error: Please increase your amount." +msgstr "Ralat Had Jambatan: Sila tingkatkan jumlah anda." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:26 +msgid "Bridge Limit Error: Please decrease your amount." +msgstr "Ralat Had Jambatan: Sila kurangkan jumlah anda." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:31 +msgid "High Price Impact" +msgstr "Kesan Harga Tinggi" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:32 +msgid "Price impact is too high!" +msgstr "Kesan harga terlalu tinggi!" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:33 +msgid "The price impact is significantly higher than the allowed amount." +msgstr "Kesan harga adalah jauh lebih tinggi daripada jumlah yang dibenarkan." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:36 +msgid "Confirm high price impact" +msgstr "Sahkan kesan harga yang tinggi" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:39 +msgid "Route updated and price impact is too high, try again later!" +msgstr "Laluan dikemas kini dan impak harga terlalu tinggi, cuba sebentar lagi!" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:44 +msgid "USD Price Unknown" +msgstr "Harga USD Tidak Diketahui" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:45 +msgid "USD Price Unknown, Cannot calculate Price Impact." +msgstr "Harga USD Tidak Diketahui, Tidak Dapat Mengira Kesan Harga." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:46 +msgid "USD Price Unknown, Cannot calculate Price Impact. The price impact may be higher than usual. Are you sure to continue the Swap?" +msgstr "Harga USD Tidak Diketahui, Tidak Dapat Mengira Kesan Harga. Kesan harga mungkin lebih tinggi daripada biasa. Adakah anda pasti untuk meneruskan Swap?" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:49 +msgid "Confirm USD Price Unknown" +msgstr "Sahkan Harga USD Tidak Diketahui" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:6 +#: widget/embedded/src/pages/Home.tsx:163 +msgid "Swap" +msgstr "Tukar" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:7 +msgid "Swap anyway" +msgstr "Tukar pula" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:8 +msgid "The route goes through Ethereum. Continue?" +msgstr "Laluan itu melalui Ethereum. teruskan?" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:10 +msgid "Route has been updated." +msgstr "Laluan telah dikemas kini." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:12 +msgid "Output amount changed to {newOutputAmount} ({percentageChange}% change)." +msgstr "Amaun output ditukar kepada {newOutputAmount} ({percentageChange}% perubahan)." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:20 +msgid "Route swappers has been updated." +msgstr "Penukar laluan telah dikemas kini." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:22 +msgid "Route internal coins has been updated." +msgstr "Syiling dalaman laluan telah dikemas kini." + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/ExpandedQuotes/ExpandedQuotes.tsx:53 +#: widget/embedded/src/pages/Routes.tsx:48 +msgid "Routes" +msgstr "Laluan" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Inputs/Inputs.tsx:76 +msgid "From" +msgstr "daripada" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Inputs/Inputs.tsx:118 +msgid "To" +msgstr "Kepada" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:49 +msgid "Light" +msgstr "Cahaya" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:58 +msgid "Dark" +msgstr "Gelap" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:67 +msgid "Auto" +msgstr "Auto" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:140 +msgid "Loading failed" +msgstr "Gagal memuatkan" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:156 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:41 +msgid "Bridges" +msgstr "Jambatan" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:174 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:41 +msgid "Exchanges" +msgstr "Pertukaran" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:195 +#: widget/embedded/src/pages/CustomTokensPage.tsx:90 +msgid "Custom Tokens" +msgstr "Token Tersuai" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:214 +#: widget/embedded/src/pages/LanguagePage.tsx:43 +msgid "Language" +msgstr "Bahasa" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:235 +msgid "Infinite approval" +msgstr "Kelulusan yang tidak terhingga" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:246 +msgid "Enabling the 'Infinite approval' mode grants unrestricted access to underlying smart contracts, allowing them to utilize the approved token amount without limitations." +msgstr "Mendayakan mod 'Kelulusan tidak terhingga' memberikan akses tanpa had kepada kontrak pintar asas, membolehkan mereka menggunakan jumlah token yang diluluskan tanpa had." + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:266 +msgid "Theme" +msgstr "Tema" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:39 +msgid "Duplicate Token" +msgstr "Token Pendua" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:40 +msgid "The address you entered is duplicate, please enter a new address." +msgstr "Alamat yang anda masukkan adalah pendua, sila masukkan alamat baharu." + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:46 +msgid "Token Already Exists" +msgstr "Token Sudah Wujud" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:47 +msgid "There's no need to add this token again because it already exists and is supported by us." +msgstr "Tidak perlu menambah token ini lagi kerana ia sudah wujud dan disokong oleh kami." + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:53 +msgid "Token Not Found" +msgstr "Token Tidak Ditemui" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:54 +msgid "Sorry, no token was found on {blockchain} chain with the provided address. please make sure you have entered the right token address." +msgstr "Maaf, tiada token ditemui pada rantai {blockchain} dengan alamat yang diberikan. sila pastikan anda telah memasukkan alamat token yang betul." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:78 +msgid "Network Error" +msgstr "Ralat Rangkaian" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:109 +#: widget/embedded/src/pages/CustomTokensPage.tsx:149 +msgid "Add Custom Token" +msgstr "Tambah Token Tersuai" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:127 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:128 +msgid "Select chain" +msgstr "Pilih rantai" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:132 +msgid "Enter Address" +msgstr "Masukkan Alamat" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:139 +msgid "Enter token address" +msgstr "Masukkan alamat token" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:176 +msgid "Failed Network, Please retry." +msgstr "Rangkaian Gagal, Sila cuba semula." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:192 +msgid "Add another custom token" +msgstr "Tambahkan satu lagi token tersuai" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:236 +msgid "Confirm Swap" +msgstr "Sahkan Tukar" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:254 +msgid "Start Swap" +msgstr "Mulakan Tukar" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:282 +msgid "You get" +msgstr "awak dapat" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:102 +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:90 +msgid "Search Token" +msgstr "Token Carian" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:134 +msgid "No custom tokens" +msgstr "Tiada token tersuai" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:135 +msgid "press the button to add your custom token" +msgstr "tekan butang untuk menambah token tersuai anda" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:158 +msgid "Delete Custom Token" +msgstr "Padamkan Token Tersuai" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:160 +msgid "Are you sure you want to Delete this Token?" +msgstr "Adakah anda pasti mahu Memadam Token ini?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:59 +msgid "Complete" +msgstr "lengkap" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:63 +msgid "Running" +msgstr "Berlari" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:65 +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:8 +msgid "Failed" +msgstr "gagal" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:149 +msgid "Clear" +msgstr "Jelas" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:161 +msgid "Search Transaction" +msgstr "Transaksi Carian" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:187 +msgid "No transactions" +msgstr "Tiada transaksi" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:194 +msgid "Your transaction history is stored locally and will appear here after you start a swap" +msgstr "Sejarah transaksi anda disimpan secara setempat dan akan dipaparkan di sini selepas anda memulakan pertukaran" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:218 +msgid "Clear Transaction History" +msgstr "Kosongkan Sejarah Transaksi" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:222 +msgid "Proceeding will remove all successful and failed transactions from the widget. Do you want to continue?" +msgstr "Prosiding akan mengalih keluar semua transaksi yang berjaya dan gagal daripada widget. Adakah anda mahu meneruskan?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:229 +msgid "Note: This does not erase your transaction history on the chain; it only removes them here." +msgstr "Nota: Ini tidak memadamkan sejarah transaksi anda pada rantaian; ia hanya membuang mereka di sini." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:243 +msgid "Yes, Clear the history" +msgstr "Ya, Kosongkan sejarah" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LanguagePage.tsx:56 +msgid "language" +msgstr "bahasa" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:121 +msgid "Deselect all" +msgstr "Nyahpilih semua" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:121 +msgid "Select all" +msgstr "Pilih semua" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:133 +msgid "Search {sourceType}" +msgstr "Cari {sourceType}" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectBlockchainPage.tsx:60 +msgid "Search Chain" +msgstr "Rantaian Carian" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:67 +msgid "Source" +msgstr "Sumber" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:68 +msgid "Destination" +msgstr "Destinasi" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:74 +msgid "Swap {type}" +msgstr "Tukar {type}" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SettingsPage.tsx:45 +msgid "Currently, you're in campaign mode with restrictions on liquidity sources. Would you like to switch out of this mode and make use of all available liquidity sources?" +msgstr "Pada masa ini, anda berada dalam mod kempen dengan sekatan pada sumber kecairan. Adakah anda ingin keluar daripada mod ini dan menggunakan semua sumber kecairan yang tersedia?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SwapDetailsPage.tsx:27 +msgid "The request ID is necessary to display the swap details." +msgstr "ID permintaan diperlukan untuk memaparkan butiran swap." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/WalletsPage.tsx:67 +#: widget/ui/src/containers/ConnectWalletsModal/ConnectWalletsModal.tsx:15 +msgid "Connect Wallets" +msgstr "Sambungkan Dompet" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/WalletsPage.tsx:82 +msgid "Choose a wallet to connect." +msgstr "Pilih dompet untuk disambungkan." + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:25 +msgid "This week" +msgstr "minggu ini" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:32 +msgid "This month" +msgstr "bulan ini" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:39 +msgid "This year" +msgstr "tahun ini" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:129 +msgid "Required: >= {min} {symbol}" +msgstr "Diperlukan: >= {min} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:142 +msgid "Required: > {min} {symbol}" +msgstr "Diperlukan: > {min} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:157 +msgid "Required: <= {max} {symbol}" +msgstr "Diperlukan: <= {max} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:170 +msgid "Required: < {max} {symbol}" +msgstr "Diperlukan: < {max} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:601 +msgid " for network fee" +msgstr " untuk bayaran rangkaian" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:604 +msgid " for swap" +msgstr " untuk pertukaran" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:607 +msgid " for input and network fee" +msgstr " untuk input dan bayaran rangkaian" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:609 +msgid "Needs ≈ {requiredAmount} {symbol}{reason}, but you have {currentAmount} {symbol} in your {blockchain} wallet." +msgstr "Memerlukan ≈ {requiredAmount} {symbol}{reason}, tetapi anda mempunyai {currentAmount} {symbol} dalam dompet {blockchain} anda." + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:669 +msgid "Waiting for connecting wallet" +msgstr "Menunggu untuk menyambung dompet" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:673 +msgid "Waiting for other running tasks to be finished" +msgstr "Menunggu tugasan lain yang sedang dijalankan selesai" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:676 +msgid "Waiting for changing wallet network" +msgstr "Menunggu untuk menukar rangkaian dompet" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:6 +msgid "Sunday" +msgstr "Ahad" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:7 +msgid "Monday" +msgstr "Isnin" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:8 +msgid "Tuesday" +msgstr "Selasa" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:9 +msgid "Wednesday" +msgstr "Rabu" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:10 +msgid "Thursday" +msgstr "Khamis" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:11 +msgid "Friday" +msgstr "Jumaat" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:12 +msgid "Saturday" +msgstr "Sabtu" + +#. js-lingui-explicit-id +#: widget/ui/src/components/BottomLogo/BottomLogo.tsx:14 +msgid "Powered By" +msgstr "Dikuasakan Oleh" + +#. js-lingui-explicit-id +#: widget/ui/src/components/FullExpandedQuote/FullExpandedQuote.Tooltip.tsx:37 +msgid "Aggregated Transaction" +msgstr "Transaksi Agregat" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SelectableCategoryList/SelectableCategoryList.tsx:63 +msgid "{blockchainCategory}" +msgstr "{blockchainCategory}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/StepDetails/StepDetails.tsx:75 +#: widget/ui/src/components/StepDetails/StepDetails.tsx:102 +msgid "Swap on {fromChain} via {swapper}" +msgstr "Tukar pada {fromChain} melalui {swapper}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/StepDetails/StepDetails.tsx:109 +msgid "Bridge to {toChain} via {swapper}" +msgstr "Jambatan ke {toChain} melalui {swapper}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:10 +msgid "Completed" +msgstr "Selesai" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:12 +msgid "In progress" +msgstr "Sedang berlangsung" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapToken.tsx:122 +msgid "Waiting for bridge transaction" +msgstr "Menunggu transaksi jambatan" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:12 +msgid "Connected" +msgstr "Bersambung" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:13 +msgid "Disconnect" +msgstr "Putuskan sambungan" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:18 +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:19 +msgid "Install" +msgstr "Pasang" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:24 +msgid "Connecting ..." +msgstr "Menyambung..." + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:25 +msgid "Connecting" +msgstr "Menyambung" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:30 +msgid "Disconnected" +msgstr "Terputus sambungan" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:34 +msgid "you need to pass a correct state to Wallet." +msgstr "anda perlu menghantar keadaan yang betul kepada Wallet." + +#. js-lingui-explicit-id +#: widget/ui/src/containers/Notifications/NotificationNotFound.tsx:15 +msgid "There are no notifications." +msgstr "Tiada pemberitahuan." + +#. js-lingui-explicit-id +#: widget/ui/src/containers/Notifications/Notifications.tsx:39 +msgid "Clear all" +msgstr "Kosongkan semua" + +#. js-lingui-explicit-id +#: widget/ui/src/containers/SwapInput/SwapInput.tsx:65 +msgid "Balance" +msgstr "Baki" + +#. js-lingui-explicit-id +#: widget/ui/src/containers/SwapInput/SwapInput.tsx:73 +msgid "Max" +msgstr "Maks" + diff --git a/translations/nl.po b/translations/nl.po new file mode 100644 index 0000000000..112a5705e4 --- /dev/null +++ b/translations/nl.po @@ -0,0 +1,1339 @@ +msgid "" +msgstr "" +"POT-Creation-Date: 2023-11-06 17:24+0330\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: @lingui/cli\n" +"Language: nl\n" +"Project-Id-Version: rango\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2024-11-27 15:57\n" +"Last-Translator: \n" +"Language-Team: Dutch\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Crowdin-Project: rango\n" +"X-Crowdin-Project-ID: 622238\n" +"X-Crowdin-Language: nl\n" +"X-Crowdin-File: en.po\n" +"X-Crowdin-File-ID: 30\n" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SameTokensWarning/SameTokensWarning.tsx:21 +msgid "No Routes Found" +msgstr "Geen routes gevonden" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SameTokensWarning/SameTokensWarning.tsx:25 +msgid "You cannot use the same token for From and To." +msgstr "U kunt niet hetzelfde token gebruiken voor Van en Aan." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:41 +#: widget/embedded/src/components/TokenList/TokenList.tsx:286 +#: widget/embedded/src/pages/HistoryPage.tsx:186 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:143 +msgid "No results found" +msgstr "Geen resultaten gevonden" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:42 +#: widget/embedded/src/components/TokenList/TokenList.tsx:287 +#: widget/embedded/src/pages/HistoryPage.tsx:193 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:144 +msgid "Try using different keywords" +msgstr "Probeer andere trefwoorden te gebruiken" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:72 +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:46 +#: widget/embedded/src/pages/SelectBlockchainPage.tsx:42 +#: widget/ui/src/containers/SwapInput/TokenSection.tsx:61 +msgid "Select Chain" +msgstr "Selecteer Ketting" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:66 +msgid "All" +msgstr "Allemaal" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:100 +msgid "More +{count}" +msgstr "Meer +{count}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabAlert/ActivateTabAlert.tsx:17 +msgid "Activate this tab" +msgstr "Dit tabblad activeren" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabAlert/ActivateTabAlert.tsx:22 +msgid "Another tab is open and handles transactions." +msgstr "Een ander tabblad is open en behandelt transacties." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:20 +msgid "Activate current tab" +msgstr "Actief tabblad" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:22 +msgid "Currently, some transactions are running and being handled by other browser tab. If you activate this tab, all transactions that are already in the transaction sign step will expire." +msgstr "Op dit moment worden sommige transacties uitgevoerd en behandeld door een ander browsertabblad. Als u dit tabblad activeert, zullen alle transacties die al in de transactie tekenen staan verlopen." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:33 +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:349 +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:152 +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:33 +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:116 +msgid "Confirm" +msgstr "Bevestigen" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:365 +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:447 +msgid "Your {blockchainName} wallets" +msgstr "Uw {blockchainName} portemonnees" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:384 +msgid "Insufficient account balance" +msgstr "Onvoldoende saldo" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:394 +msgid "Proceed anyway" +msgstr "Toch doorgaan" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:456 +msgid "You need to connect a {blockchainName} wallet." +msgstr "Je moet een {blockchainName} portemonnee verbinden." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/WalletList.tsx:143 +msgid "Add {chain} chain" +msgstr "Voeg {chain} keten toe" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/WalletList.tsx:244 +msgid "Show more wallets" +msgstr "Toon meer portefeuilles" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:113 +msgid "Send to a different address" +msgstr "Stuur naar een ander adres" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:129 +msgid "Enter {blockchainName} address" +msgstr "Voer {blockchainName} adres in" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:147 +msgid "Address {destination} doesn't match the blockchain address pattern." +msgstr "Adres {destination} komt niet overeen met het blockchainadrespatroon." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:59 +msgid "via" +msgstr "via" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:74 +msgid "This token doesn't appear on the active token list(s). Make sure this is the token that you want to trade." +msgstr "Dit token verschijnt niet op de actieve tokenlijsten. Zorg ervoor dat dit het token is dat je wilt verhandelen." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:89 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:164 +msgid "Import" +msgstr "Importeren" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/FilterSelector/FilterSelectorContent.tsx:26 +msgid "Status" +msgstr "status" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/FilterSelector/FilterSelectorContent.tsx:33 +#: widget/embedded/src/components/NoResult/NoResult.helpers.ts:37 +#: widget/embedded/src/pages/SettingsPage.tsx:55 +msgid "Reset" +msgstr "Reset" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/CancelButton.tsx:18 +msgid "Cancel" +msgstr "annuleren" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:46 +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:34 +msgid "Refresh" +msgstr "Vernieuwen" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:63 +#: widget/ui/src/containers/Notifications/Notifications.tsx:35 +msgid "Notifications" +msgstr "Notificaties" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:79 +#: widget/embedded/src/pages/SettingsPage.tsx:38 +msgid "Settings" +msgstr "Instellingen" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:93 +#: widget/embedded/src/pages/HistoryPage.tsx:139 +msgid "History" +msgstr "Geschiedenis" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/WalletButton.tsx:22 +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:16 +#: widget/embedded/src/constants/messages.ts:5 +msgid "Connect Wallet" +msgstr "Verbind Portemonnee" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HistoryGroupedList/HistoryGroupedList.tsx:118 +#: widget/embedded/src/utils/date.ts:18 +#: widget/embedded/src/utils/time.ts:22 +msgid "Today" +msgstr "vandaag" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/LoadingSwapDetails/LoadingSwapDetails.tsx:20 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:424 +msgid "Swaps steps" +msgstr "Swaps stappen" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/NoResult/NoResult.helpers.ts:25 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:191 +msgid "Retry" +msgstr "Opnieuw" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:149 +msgid "Slippage Error" +msgstr "Slippage Fout" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:150 +msgid "Slippage Warning" +msgstr "Slippage Waarschuwing" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:153 +msgid "Bridge Limit Error" +msgstr "Brug limiet fout" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:240 +msgid "Yours: {amount} {symbol}" +msgstr "Jours: {amount} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:261 +msgid "Minimum required slippage: {minRequiredSlippage}" +msgstr "Minimum vereiste slippage: {minRequiredSlippage}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:282 +msgid "Yours: {userSlippage}" +msgstr "Jouw: {userSlippage}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:395 +msgid "See All Routes" +msgstr "Alle routes bekijken" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:81 +msgid "View more info" +msgstr "Bekijk meer informatie" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:91 +msgid "Gas & Fee Explanation" +msgstr "Gas & Fee Uitleg" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:107 +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:103 +msgid "Details" +msgstr "Beschrijving" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:146 +msgid "Total Payable Fee" +msgstr "Totale te betalen vergoeding" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:166 +msgid "Hide non-payable fees" +msgstr "Verberg onbetaalbare vergoedingen" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:167 +msgid "Show non-payable fees" +msgstr "Toon onbetaalbare kosten" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:177 +msgid "Description" +msgstr "Beschrijving" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:181 +msgid "The following fees are considered in the transaction output and\n" +" you won’t need to pay extra gas for them." +msgstr "De volgende kosten worden in rekening gebracht in de transactieuitvoer en\n" +" je hoeft er geen extra gas voor te betalen." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteSummary.tsx:25 +msgid "Swap input" +msgstr "Swap input" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteSummary.tsx:44 +msgid "Estimated output" +msgstr "Geschatte uitvoer" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteTrigger.tsx:65 +msgid "Via:" +msgstr "Via:" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteTrigger.tsx:150 +msgid "Chains:" +msgstr "Kettingen:" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/Quotes.tsx:77 +msgid "Sort by" +msgstr "Sorteren op" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:17 +msgid "Smart Routing" +msgstr "Slimme routering" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:21 +msgid "Lowest Fee" +msgstr "Laagste kosten" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:25 +msgid "Fastest Transfer" +msgstr "Snelste overdracht" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:29 +msgid "Maximum Return" +msgstr "Maximale retour" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:33 +msgid "Maximum Output" +msgstr "Maximale uitvoer" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:43 +msgid "Swapping" +msgstr "Swapping" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:51 +msgid "Gas cost" +msgstr "Gas kosten" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:59 +msgid "Receiving" +msgstr "Ontvangen" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:67 +msgid "Price impact" +msgstr "Prijs impact" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:35 +msgid "You need to increase slippage to at least {minRequiredSlippage} for this route." +msgstr "Je moet slippage verhogen naar tenminste {minRequiredSlippage} voor deze route." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:59 +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:61 +msgid "We recommend you to increase slippage to at least {minRequiredSlippage} for this route." +msgstr "We raden je aan om slippage ten minste {minRequiredSlippage} voor deze route te verhogen." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:68 +msgid "Caution, your slippage is high." +msgstr "Let op, je slippage is hoog." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.tsx:78 +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.Warning.tsx:26 +msgid "Change" +msgstr "Veranderen" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:42 +msgid "Change settings" +msgstr "Instellingen wijzigen" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:52 +msgid "High slippage" +msgstr "Hoge slippage" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:53 +msgid "Low slippage" +msgstr "Lage slippage" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:57 +msgid " Caution, your slippage is high (={userSlippage}). Your trade may be front run." +msgstr " Let op, uw slippage is hoog (={userSlippage}). Uw transactie kan vooraf worden uitgevoerd." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:78 +msgid "Confirm anyway" +msgstr "Toch bevestigen" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:22 +msgid "Something went wrong" +msgstr "Er ging iets mis" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:24 +msgid "Something went wrong. Please refresh the app." +msgstr "Er is iets fout gegaan. Vernieuw de app." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/Slippage.tsx:38 +msgid "Slippage tolerance per swap" +msgstr "Slippage tolerantie per swap" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/Slippage.tsx:91 +msgid "Custom" +msgstr "Aangepaste" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:11 +msgid "Your transaction will be reverted if the price changes unfavorably by more than this percentage." +msgstr "Uw transactie zal worden teruggedraaid als de prijs onvoordelig verandert met meer dan dit percentage." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:16 +#: widget/embedded/src/containers/Settings/Lists.tsx:245 +msgid "Warning" +msgstr "Waarschuwing" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:17 +msgid "This setting is applied to each step (e.g. 1Inch, Thorchain, etc.), meaning only that specific step will be reverted, not the entire route." +msgstr "Deze instelling wordt toegepast op elke stap (bijvoorbeeld 1Inch, Thorchain, etc.), wat betekent dat alleen de specifieke stap wordt teruggedraaid, niet de hele route." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:25 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:269 +msgid "Swap Details" +msgstr "Details omwisselen" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:33 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:312 +msgid "Request ID" +msgstr "ID aanvragen" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:64 +msgid "Not found" +msgstr "Niet gevonden" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:65 +msgid "Swap with request ID = {requestId} not found." +msgstr "Wissel met verzoek-ID = {requestId} niet gevonden." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:219 +msgid "You have received {amount} {token} in {conciseAddress} wallet on {chain} chain." +msgstr "Je hebt {amount} {token} ontvangen in de {conciseAddress} portemonnee in {chain} keten." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:242 +msgid "Transaction was not sent." +msgstr "Transactie is niet verzonden." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:244 +msgid "{amount} {symbol} on {blockchain} remains in your wallet." +msgstr "{amount} {symbol} op {blockchain} blijft in jouw portemonnee." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:281 +msgid "Delete" +msgstr "Verwijderen" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:304 +msgid "Try again" +msgstr "Opnieuw proberen" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:322 +msgid "Copied To Clipboard" +msgstr "Gekopieerd naar klembord" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:323 +msgid "Copy Request ID" +msgstr "Aanvraag-ID kopiëren" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:346 +msgid "View on Rango Explorer" +msgstr "Bekijk op Rango Explorer" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:355 +msgid "Finished at" +msgstr "Afgerond op" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:355 +msgid "Created at" +msgstr "Aangemaakt op" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.tsx:50 +msgid "View transaction" +msgstr "Transactie weergeven" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.Warning.tsx:49 +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:31 +msgid "Connect" +msgstr "Verbinden" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:43 +msgid "Swap Successful" +msgstr "Wissel succesvol" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:71 +msgid "Transaction Failed" +msgstr "Transactie mislukt" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:87 +msgid "Done" +msgstr "Voltooid" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:100 +msgid "Diagnosis" +msgstr "Diagnose" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:112 +msgid "See Details" +msgstr "Details bekijken" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:13 +msgid "Cancel Swap" +msgstr "Verwissel annuleren" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:14 +msgid "Are you sure you want to cancel this swap?" +msgstr "Weet u zeker dat u deze swap wilt annuleren?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:23 +msgid "Yes, Cancel it" +msgstr "Ja, annuleren" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:32 +#: widget/embedded/src/pages/CustomTokensPage.tsx:181 +msgid "No, Continue" +msgstr "Nee, ga verder" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:13 +msgid "Delete Transaction" +msgstr "Verwijder transactie" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:14 +msgid "Are you sure you want to delete this swap?" +msgstr "Weet u zeker dat u deze swap wilt verwijderen?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:23 +#: widget/embedded/src/pages/CustomTokensPage.tsx:171 +msgid "Yes, Delete it" +msgstr "Ja, verwijder het" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:33 +#: widget/embedded/src/pages/HistoryPage.tsx:253 +msgid "No, Cancel" +msgstr "Nee, annuleer" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:12 +msgid "Change Network" +msgstr "Netwerk wijzigen" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:20 +msgid "Network Changed" +msgstr "Netwerk gewijzigd" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/TokenList/TokenList.tsx:271 +#: widget/ui/src/containers/SwapInput/TokenSection.tsx:54 +msgid "Select Token" +msgstr "Selecteer Token" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:27 +msgid "Wallet Connected" +msgstr "Portemonnee verbonden" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:28 +msgid "Your wallet is connected, you can use it to swap." +msgstr "Uw portemonnee is verbonden, u kunt deze omwisselen." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:39 +msgid "Failed to Connect" +msgstr "Verbinden mislukt" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:41 +msgid "Your wallet is not connected. Please try again." +msgstr "Uw portemonnee is niet verbonden. Probeer het opnieuw." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:50 +msgid "Connecting to your wallet" +msgstr "Verbinding maken met uw portemonnee" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:51 +msgid "Click connect in your wallet popup." +msgstr "Klik op verbinden met uw portemonnee popup." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:99 +msgid "Select Derivation Path" +msgstr "Selecteer Afgeleidespad" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:100 +msgid "In order to connect to {type}, you must first select a Derivation Path" +msgstr "Om verbinding te maken met {type}moet u eerst een afleidingspad selecteren" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:118 +msgid "Choose Derivation Path Template" +msgstr "Kies Derivatie Pad sjabloon" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:133 +msgid "Enter Path" +msgstr "Pad invoeren" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:134 +msgid "Enter Index" +msgstr "Index invoeren" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:15 +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:18 +msgid "Add {blockchainDisplayName} Chain" +msgstr "{blockchainDisplayName} Ketting toevoegen" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:20 +msgid "Would you like to add the {blockchainDisplayName} experimental chain to your wallet?" +msgstr "Wilt u de {blockchainDisplayName} experimentele keten aan uw portemonnee toevoegen?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:22 +msgid "Please approve the experimental chain pop-up in your wallet." +msgstr "Gelieve de experimentele keten pop-up in uw portemonnee goed te keuren." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:30 +msgid "{blockchainDisplayName} Chain Added" +msgstr "{blockchainDisplayName} Ketting toegevoegd" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:34 +msgid "The {blockchainDisplayName} chain has been successfully added to your wallet." +msgstr "De {blockchainDisplayName} keten is met succes aan uw portemonnee toegevoegd." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:42 +msgid "Request Rejected" +msgstr "Verzoek afgewezen" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:43 +msgid "You've rejected adding {blockchainDisplayName} chain to your wallet." +msgstr "Je hebt geweigerd om {blockchainDisplayName} -keten toe te voegen aan je portemonnee." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:70 +msgid "Select chain types" +msgstr "Selecteer chain types" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:71 +msgid "This wallet supports multiple chains. Select which chain you'd like to connect to." +msgstr "Deze portemonnee ondersteunt meerdere chains. Selecteer met welke keten u verbinding wilt maken." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:9 +msgid "Failed Network, Please retry your swap." +msgstr "Mislukt netwerk. Probeer het opnieuw." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:11 +msgid "Please reset your liquidity sources." +msgstr "Gelieve uw liquiditeitsbronnen te resetten." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:12 +msgid "You have limited the liquidity sources and this might result in Rango finding no routes. Please consider resetting your liquidity sources." +msgstr "U hebt de liquiditeitsbronnen beperkt en dit kan ertoe leiden dat Rango geen routes vindt. Overweeg om uw liquiditeitsbronnen opnieuw in te stellen." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:17 +msgid "No Routes Found." +msgstr "Geen routes gevonden." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:18 +msgid "Reasons why Rango couldn't find a route: low liquidity on token, very low input amount or no routes available for the selected input/output token combination." +msgstr "Redenen waarom Rango geen route kon vinden: lage liquiditeit op token, zeer lage invoerhoeveelheid of geen routes beschikbaar voor de geselecteerde combinatie van invoer/output token." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:23 +msgid "Bridge Limit Error: Please increase your amount." +msgstr "Bridge Limiet Fout: Verhoog uw bedrag." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:26 +msgid "Bridge Limit Error: Please decrease your amount." +msgstr "Bridge Limiet Fout: Verminder je bedrag." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:31 +msgid "High Price Impact" +msgstr "Hoge prijs impact" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:32 +msgid "Price impact is too high!" +msgstr "De prijsimpact is te hoog!" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:33 +msgid "The price impact is significantly higher than the allowed amount." +msgstr "Het prijseffect is beduidend hoger dan het toegestane bedrag." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:36 +msgid "Confirm high price impact" +msgstr "hoge prijsimpact bevestigen" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:39 +msgid "Route updated and price impact is too high, try again later!" +msgstr "Route bijgewerkt en prijseffect is te hoog, probeer het later opnieuw!" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:44 +msgid "USD Price Unknown" +msgstr "USD prijs onbekend" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:45 +msgid "USD Price Unknown, Cannot calculate Price Impact." +msgstr "USD prijs onbekend, kan de Impact niet berekenen." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:46 +msgid "USD Price Unknown, Cannot calculate Price Impact. The price impact may be higher than usual. Are you sure to continue the Swap?" +msgstr "USD prijs onbekend, kan de Impact niet berekenen. Mogelijk is de prijs hoger dan normaal. Weet u zeker dat u door wilt gaan met de Swap?" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:49 +msgid "Confirm USD Price Unknown" +msgstr "Onbekende USD prijs bevestigen" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:6 +#: widget/embedded/src/pages/Home.tsx:163 +msgid "Swap" +msgstr "Wisselen" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:7 +msgid "Swap anyway" +msgstr "Wissel toch" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:8 +msgid "The route goes through Ethereum. Continue?" +msgstr "De route loopt door Ethereum. Doorgaan?" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:10 +msgid "Route has been updated." +msgstr "De route is bijgewerkt." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:12 +msgid "Output amount changed to {newOutputAmount} ({percentageChange}% change)." +msgstr "Uitgangsbedrag gewijzigd naar {newOutputAmount} ({percentageChange}% wijziging)." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:20 +msgid "Route swappers has been updated." +msgstr "Route swappers zijn bijgewerkt." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:22 +msgid "Route internal coins has been updated." +msgstr "Route interne munten zijn bijgewerkt." + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/ExpandedQuotes/ExpandedQuotes.tsx:53 +#: widget/embedded/src/pages/Routes.tsx:48 +msgid "Routes" +msgstr "Routes" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Inputs/Inputs.tsx:76 +msgid "From" +msgstr "van" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Inputs/Inputs.tsx:118 +msgid "To" +msgstr "tot" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:49 +msgid "Light" +msgstr "Licht" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:58 +msgid "Dark" +msgstr "Donker" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:67 +msgid "Auto" +msgstr "Automatisch" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:140 +msgid "Loading failed" +msgstr "Laden mislukt" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:156 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:41 +msgid "Bridges" +msgstr "Bruggen" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:174 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:41 +msgid "Exchanges" +msgstr "Uitwisselingen" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:195 +#: widget/embedded/src/pages/CustomTokensPage.tsx:90 +msgid "Custom Tokens" +msgstr "Aangepaste Tokens" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:214 +#: widget/embedded/src/pages/LanguagePage.tsx:43 +msgid "Language" +msgstr "Taal" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:235 +msgid "Infinite approval" +msgstr "Oneindige goedkeuring" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:246 +msgid "Enabling the 'Infinite approval' mode grants unrestricted access to underlying smart contracts, allowing them to utilize the approved token amount without limitations." +msgstr "Het inschakelen van de 'Oneindige goedkeuring' modus verleent onbeperkte toegang tot onderliggende slimme contracten, waardoor ze het goedgekeurde token bedrag zonder beperkingen kunnen gebruiken." + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:266 +msgid "Theme" +msgstr "Thema" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:39 +msgid "Duplicate Token" +msgstr "Duplicate Token" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:40 +msgid "The address you entered is duplicate, please enter a new address." +msgstr "Het opgegeven adres is dubbel, voer een nieuw adres in." + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:46 +msgid "Token Already Exists" +msgstr "Token bestaat al" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:47 +msgid "There's no need to add this token again because it already exists and is supported by us." +msgstr "Het is niet nodig om dit token opnieuw toe te voegen omdat het al bestaat en door ons wordt ondersteund." + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:53 +msgid "Token Not Found" +msgstr "Token niet gevonden" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:54 +msgid "Sorry, no token was found on {blockchain} chain with the provided address. please make sure you have entered the right token address." +msgstr "Sorry, er is geen token gevonden op {blockchain} keten met het opgegeven adres. Zorg ervoor dat u het juiste token adres hebt ingevoerd." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:78 +msgid "Network Error" +msgstr "Netwerk fout" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:109 +#: widget/embedded/src/pages/CustomTokensPage.tsx:149 +msgid "Add Custom Token" +msgstr "Aangepaste Token toevoegen" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:127 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:128 +msgid "Select chain" +msgstr "Selecteer keten" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:132 +msgid "Enter Address" +msgstr "Voer adres in" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:139 +msgid "Enter token address" +msgstr "Voer token adres in" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:176 +msgid "Failed Network, Please retry." +msgstr "Mislukt netwerk, probeer het opnieuw." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:192 +msgid "Add another custom token" +msgstr "Nog een aangepast token toevoegen" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:236 +msgid "Confirm Swap" +msgstr "Bevestig verwisselen" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:254 +msgid "Start Swap" +msgstr "Start omwisselen" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:282 +msgid "You get" +msgstr "Je krijgt" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:102 +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:90 +msgid "Search Token" +msgstr "Zoek Token" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:134 +msgid "No custom tokens" +msgstr "Geen aangepaste tokens" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:135 +msgid "press the button to add your custom token" +msgstr "druk op de knop om je eigen token toe te voegen" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:158 +msgid "Delete Custom Token" +msgstr "Aangepaste token verwijderen" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:160 +msgid "Are you sure you want to Delete this Token?" +msgstr "Weet u zeker dat u deze token wilt verwijderen?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:59 +msgid "Complete" +msgstr "Complete" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:63 +msgid "Running" +msgstr "Lopend" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:65 +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:8 +msgid "Failed" +msgstr "Mislukt" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:149 +msgid "Clear" +msgstr "Verwijderen" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:161 +msgid "Search Transaction" +msgstr "Zoek transactie" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:187 +msgid "No transactions" +msgstr "Geen transacties" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:194 +msgid "Your transaction history is stored locally and will appear here after you start a swap" +msgstr "Uw transactiegeschiedenis is lokaal opgeslagen en zal hier verschijnen nadat u een swap heeft gestart" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:218 +msgid "Clear Transaction History" +msgstr "Wis transactiegeschiedenis" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:222 +msgid "Proceeding will remove all successful and failed transactions from the widget. Do you want to continue?" +msgstr "Doorgaan zal alle succesvolle en mislukte transacties van de widget verwijderen. Wilt u doorgaan?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:229 +msgid "Note: This does not erase your transaction history on the chain; it only removes them here." +msgstr "Opmerking: Dit wist uw transactiegeschiedenis op de keten niet; het verwijdert ze alleen hier." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:243 +msgid "Yes, Clear the history" +msgstr "Ja, de geschiedenis wissen" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LanguagePage.tsx:56 +msgid "language" +msgstr "Taal" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:121 +msgid "Deselect all" +msgstr "Deselecteer alles" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:121 +msgid "Select all" +msgstr "Alles selecteren" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:133 +msgid "Search {sourceType}" +msgstr "Zoek {sourceType}" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectBlockchainPage.tsx:60 +msgid "Search Chain" +msgstr "Zoek ketting" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:67 +msgid "Source" +msgstr "Bron" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:68 +msgid "Destination" +msgstr "Doelstelling" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:74 +msgid "Swap {type}" +msgstr "Wissel {type}" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SettingsPage.tsx:45 +msgid "Currently, you're in campaign mode with restrictions on liquidity sources. Would you like to switch out of this mode and make use of all available liquidity sources?" +msgstr "Momenteel bent u in campagnemodus met beperkingen op liquiditeitsbronnen. Wilt u uit deze modus schakelen en gebruik maken van alle beschikbare liquiditeitsbronnen?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SwapDetailsPage.tsx:27 +msgid "The request ID is necessary to display the swap details." +msgstr "Het verzoek-ID is nodig om de swap-gegevens weer te geven." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/WalletsPage.tsx:67 +#: widget/ui/src/containers/ConnectWalletsModal/ConnectWalletsModal.tsx:15 +msgid "Connect Wallets" +msgstr "Verbind Portemonnees" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/WalletsPage.tsx:82 +msgid "Choose a wallet to connect." +msgstr "Kies een portemonnee om te verbinden." + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:25 +msgid "This week" +msgstr "Deze week" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:32 +msgid "This month" +msgstr "Deze maand" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:39 +msgid "This year" +msgstr "Dit jaar" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:129 +msgid "Required: >= {min} {symbol}" +msgstr "Vereist: >= {min} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:142 +msgid "Required: > {min} {symbol}" +msgstr "Vereist: > {min} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:157 +msgid "Required: <= {max} {symbol}" +msgstr "Vereist: <= {max} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:170 +msgid "Required: < {max} {symbol}" +msgstr "Vereist: < {max} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:601 +msgid " for network fee" +msgstr " voor netwerkheffing" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:604 +msgid " for swap" +msgstr " voor swap" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:607 +msgid " for input and network fee" +msgstr " voor invoer en netwerk vergoeding" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:609 +msgid "Needs ≈ {requiredAmount} {symbol}{reason}, but you have {currentAmount} {symbol} in your {blockchain} wallet." +msgstr "Moet {requiredAmount} {symbol}{reason}, maar je hebt {currentAmount} {symbol} in je {blockchain} portemonnee nodig." + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:669 +msgid "Waiting for connecting wallet" +msgstr "Wachten op verbinding met portemonnee" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:673 +msgid "Waiting for other running tasks to be finished" +msgstr "Wachten tot andere lopende taken zijn voltooid" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:676 +msgid "Waiting for changing wallet network" +msgstr "Wachten op het wijzigen van wallet netwerk" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:6 +msgid "Sunday" +msgstr "zondag" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:7 +msgid "Monday" +msgstr "maandag" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:8 +msgid "Tuesday" +msgstr "dinsdag" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:9 +msgid "Wednesday" +msgstr "woensdag" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:10 +msgid "Thursday" +msgstr "donderdag" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:11 +msgid "Friday" +msgstr "vrijdag" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:12 +msgid "Saturday" +msgstr "zaterdag" + +#. js-lingui-explicit-id +#: widget/ui/src/components/BottomLogo/BottomLogo.tsx:14 +msgid "Powered By" +msgstr "Mogelijk gemaakt door" + +#. js-lingui-explicit-id +#: widget/ui/src/components/FullExpandedQuote/FullExpandedQuote.Tooltip.tsx:37 +msgid "Aggregated Transaction" +msgstr "Geaggregeerde transactie" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SelectableCategoryList/SelectableCategoryList.tsx:63 +msgid "{blockchainCategory}" +msgstr "{blockchainCategory}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/StepDetails/StepDetails.tsx:75 +#: widget/ui/src/components/StepDetails/StepDetails.tsx:102 +msgid "Swap on {fromChain} via {swapper}" +msgstr "Wissel op {fromChain} via {swapper}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/StepDetails/StepDetails.tsx:109 +msgid "Bridge to {toChain} via {swapper}" +msgstr "Brug naar {toChain} via {swapper}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:10 +msgid "Completed" +msgstr "Voltooid" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:12 +msgid "In progress" +msgstr "In behandeling" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapToken.tsx:122 +msgid "Waiting for bridge transaction" +msgstr "Wachten op bridge transactie" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:12 +msgid "Connected" +msgstr "Verbonden" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:13 +msgid "Disconnect" +msgstr "Verbreek" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:18 +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:19 +msgid "Install" +msgstr "Installeren" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:24 +msgid "Connecting ..." +msgstr "Verbinden ..." + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:25 +msgid "Connecting" +msgstr "Verbinden" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:30 +msgid "Disconnected" +msgstr "Losgekoppeld" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:34 +msgid "you need to pass a correct state to Wallet." +msgstr "u moet een juiste status doorgeven aan Wallet." + +#. js-lingui-explicit-id +#: widget/ui/src/containers/Notifications/NotificationNotFound.tsx:15 +msgid "There are no notifications." +msgstr "Er zijn geen meldingen." + +#. js-lingui-explicit-id +#: widget/ui/src/containers/Notifications/Notifications.tsx:39 +msgid "Clear all" +msgstr "Alles wissen" + +#. js-lingui-explicit-id +#: widget/ui/src/containers/SwapInput/SwapInput.tsx:65 +msgid "Balance" +msgstr "Saldo" + +#. js-lingui-explicit-id +#: widget/ui/src/containers/SwapInput/SwapInput.tsx:73 +msgid "Max" +msgstr "Max." + diff --git a/translations/pl.po b/translations/pl.po new file mode 100644 index 0000000000..63fcc89f84 --- /dev/null +++ b/translations/pl.po @@ -0,0 +1,1339 @@ +msgid "" +msgstr "" +"POT-Creation-Date: 2023-11-06 17:24+0330\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: @lingui/cli\n" +"Language: pl\n" +"Project-Id-Version: rango\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2024-11-27 15:57\n" +"Last-Translator: \n" +"Language-Team: Polish\n" +"Plural-Forms: nplurals=4; plural=(n==1 ? 0 : (n%10>=2 && n%10<=4) && (n%100<12 || n%100>14) ? 1 : n!=1 && (n%10>=0 && n%10<=1) || (n%10>=5 && n%10<=9) || (n%100>=12 && n%100<=14) ? 2 : 3);\n" +"X-Crowdin-Project: rango\n" +"X-Crowdin-Project-ID: 622238\n" +"X-Crowdin-Language: pl\n" +"X-Crowdin-File: en.po\n" +"X-Crowdin-File-ID: 30\n" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SameTokensWarning/SameTokensWarning.tsx:21 +msgid "No Routes Found" +msgstr "Nie znaleziono tras" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SameTokensWarning/SameTokensWarning.tsx:25 +msgid "You cannot use the same token for From and To." +msgstr "Nie można użyć tego samego tokena w polach Od i Do." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:41 +#: widget/embedded/src/components/TokenList/TokenList.tsx:286 +#: widget/embedded/src/pages/HistoryPage.tsx:186 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:143 +msgid "No results found" +msgstr "Nie znaleziono wyników" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:42 +#: widget/embedded/src/components/TokenList/TokenList.tsx:287 +#: widget/embedded/src/pages/HistoryPage.tsx:193 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:144 +msgid "Try using different keywords" +msgstr "Spróbuj użyć różnych słów kluczowych" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:72 +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:46 +#: widget/embedded/src/pages/SelectBlockchainPage.tsx:42 +#: widget/ui/src/containers/SwapInput/TokenSection.tsx:61 +msgid "Select Chain" +msgstr "Wybierz łańcuch" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:66 +msgid "All" +msgstr "Wszystkie" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:100 +msgid "More +{count}" +msgstr "Więcej +{count}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabAlert/ActivateTabAlert.tsx:17 +msgid "Activate this tab" +msgstr "Aktywuj tę kartę" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabAlert/ActivateTabAlert.tsx:22 +msgid "Another tab is open and handles transactions." +msgstr "Inna karta jest otwarta i obsługuje transakcje." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:20 +msgid "Activate current tab" +msgstr "Aktywuj bieżącą kartę" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:22 +msgid "Currently, some transactions are running and being handled by other browser tab. If you activate this tab, all transactions that are already in the transaction sign step will expire." +msgstr "Obecnie niektóre transakcje są uruchomione i są obsługiwane przez inną kartę przeglądarki. Jeśli aktywujesz tę kartę, wszystkie transakcje, które są już w kroku podpisu transakcji, wygasną." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:33 +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:349 +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:152 +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:33 +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:116 +msgid "Confirm" +msgstr "Potwierdź" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:365 +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:447 +msgid "Your {blockchainName} wallets" +msgstr "Twoje portfele {blockchainName}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:384 +msgid "Insufficient account balance" +msgstr "Niewystarczające saldo konta" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:394 +msgid "Proceed anyway" +msgstr "Kontynuuj mimo to" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:456 +msgid "You need to connect a {blockchainName} wallet." +msgstr "Musisz połączyć portfel {blockchainName}." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/WalletList.tsx:143 +msgid "Add {chain} chain" +msgstr "Dodaj łańcuch {chain}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/WalletList.tsx:244 +msgid "Show more wallets" +msgstr "Pokaż więcej portfeli" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:113 +msgid "Send to a different address" +msgstr "Wyślij na inny adres" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:129 +msgid "Enter {blockchainName} address" +msgstr "Wprowadź adres {blockchainName}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:147 +msgid "Address {destination} doesn't match the blockchain address pattern." +msgstr "Adres {destination} nie pasuje do wzoru adresu blockchain." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:59 +msgid "via" +msgstr "przez" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:74 +msgid "This token doesn't appear on the active token list(s). Make sure this is the token that you want to trade." +msgstr "Ten token nie pojawia się na listach aktywnych tokenów. Upewnij się, że to jest token, który chcesz wymienić." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:89 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:164 +msgid "Import" +msgstr "Importuj" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/FilterSelector/FilterSelectorContent.tsx:26 +msgid "Status" +msgstr "Status" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/FilterSelector/FilterSelectorContent.tsx:33 +#: widget/embedded/src/components/NoResult/NoResult.helpers.ts:37 +#: widget/embedded/src/pages/SettingsPage.tsx:55 +msgid "Reset" +msgstr "Reset" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/CancelButton.tsx:18 +msgid "Cancel" +msgstr "Anuluj" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:46 +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:34 +msgid "Refresh" +msgstr "Odśwież" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:63 +#: widget/ui/src/containers/Notifications/Notifications.tsx:35 +msgid "Notifications" +msgstr "Powiadomienia" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:79 +#: widget/embedded/src/pages/SettingsPage.tsx:38 +msgid "Settings" +msgstr "Ustawienia" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:93 +#: widget/embedded/src/pages/HistoryPage.tsx:139 +msgid "History" +msgstr "Historia" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/WalletButton.tsx:22 +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:16 +#: widget/embedded/src/constants/messages.ts:5 +msgid "Connect Wallet" +msgstr "Połącz portfel" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HistoryGroupedList/HistoryGroupedList.tsx:118 +#: widget/embedded/src/utils/date.ts:18 +#: widget/embedded/src/utils/time.ts:22 +msgid "Today" +msgstr "Dziś" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/LoadingSwapDetails/LoadingSwapDetails.tsx:20 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:424 +msgid "Swaps steps" +msgstr "Etapy swapów" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/NoResult/NoResult.helpers.ts:25 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:191 +msgid "Retry" +msgstr "Ponów próbę" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:149 +msgid "Slippage Error" +msgstr "Błąd poślizgu" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:150 +msgid "Slippage Warning" +msgstr "Ostrzeżenie poślizgu" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:153 +msgid "Bridge Limit Error" +msgstr "Błąd limitu mostu" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:240 +msgid "Yours: {amount} {symbol}" +msgstr "Nasz: {amount} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:261 +msgid "Minimum required slippage: {minRequiredSlippage}" +msgstr "Minimalny wymagany poślizg: {minRequiredSlippage}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:282 +msgid "Yours: {userSlippage}" +msgstr "Yours: {userSlippage}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:395 +msgid "See All Routes" +msgstr "Zobacz wszystkie trasy" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:81 +msgid "View more info" +msgstr "Zobacz więcej informacji" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:91 +msgid "Gas & Fee Explanation" +msgstr "Wyjaśnienie dotyczące gazu i opłat" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:107 +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:103 +msgid "Details" +msgstr "Szczegóły" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:146 +msgid "Total Payable Fee" +msgstr "Całkowita należna opłata" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:166 +msgid "Hide non-payable fees" +msgstr "Ukryj opłaty niepłatne" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:167 +msgid "Show non-payable fees" +msgstr "Pokaż opłaty bezpłatne" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:177 +msgid "Description" +msgstr "Opis" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:181 +msgid "The following fees are considered in the transaction output and\n" +" you won’t need to pay extra gas for them." +msgstr "Następujące opłaty są brane pod uwagę w wyjściu transakcji i\n" +" nie musisz za nie płacić dodatkowego gazu." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteSummary.tsx:25 +msgid "Swap input" +msgstr "Swap input" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteSummary.tsx:44 +msgid "Estimated output" +msgstr "Szacowane wyjście" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteTrigger.tsx:65 +msgid "Via:" +msgstr "Przelotka:" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteTrigger.tsx:150 +msgid "Chains:" +msgstr "Łańcuchy" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/Quotes.tsx:77 +msgid "Sort by" +msgstr "Sortuj według" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:17 +msgid "Smart Routing" +msgstr "Inteligentne Trasowanie" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:21 +msgid "Lowest Fee" +msgstr "Najniższa opłata" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:25 +msgid "Fastest Transfer" +msgstr "Najszybszy transfer" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:29 +msgid "Maximum Return" +msgstr "Maksymalny zwrot" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:33 +msgid "Maximum Output" +msgstr "Maksymalna wartość wyjściowa" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:43 +msgid "Swapping" +msgstr "Swapping" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:51 +msgid "Gas cost" +msgstr "Koszt gazu" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:59 +msgid "Receiving" +msgstr "Odbieranie" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:67 +msgid "Price impact" +msgstr "Wpływ cen" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:35 +msgid "You need to increase slippage to at least {minRequiredSlippage} for this route." +msgstr "Musisz zwiększyć poślizg do co najmniej {minRequiredSlippage} dla tej trasy." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:59 +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:61 +msgid "We recommend you to increase slippage to at least {minRequiredSlippage} for this route." +msgstr "Zalecamy zwiększenie poślizgu do co najmniej {minRequiredSlippage} dla tej trasy." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:68 +msgid "Caution, your slippage is high." +msgstr "Zachowaj ostrożność, twój poślizg jest wysoki." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.tsx:78 +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.Warning.tsx:26 +msgid "Change" +msgstr "Zmiana" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:42 +msgid "Change settings" +msgstr "Zmień ustawienia" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:52 +msgid "High slippage" +msgstr "Wysoki poślizg" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:53 +msgid "Low slippage" +msgstr "Niski poślizg" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:57 +msgid " Caution, your slippage is high (={userSlippage}). Your trade may be front run." +msgstr " Uwaga, Twój poślizg jest wysoki (={userSlippage}). Twoja transakcja może być aktywna." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:78 +msgid "Confirm anyway" +msgstr "Potwierdź mimo wszystko" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:22 +msgid "Something went wrong" +msgstr "Coś poszło nie tak" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:24 +msgid "Something went wrong. Please refresh the app." +msgstr "Coś poszło nie tak. Proszę odświeżyć aplikację." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/Slippage.tsx:38 +msgid "Slippage tolerance per swap" +msgstr "Tolerancja poślizgu na swap" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/Slippage.tsx:91 +msgid "Custom" +msgstr "Własny" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:11 +msgid "Your transaction will be reverted if the price changes unfavorably by more than this percentage." +msgstr "Twoja transakcja zostanie przywrócona, jeśli cena zmieni się niekorzystnie o więcej niż ten procent." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:16 +#: widget/embedded/src/containers/Settings/Lists.tsx:245 +msgid "Warning" +msgstr "Ostrzeżenie" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:17 +msgid "This setting is applied to each step (e.g. 1Inch, Thorchain, etc.), meaning only that specific step will be reverted, not the entire route." +msgstr "To ustawienie jest stosowane na każdym etapie (np. 1Inch, Thorchain itp.), co oznacza, że konkretny krok zostanie odwrócony, a nie na całej drodze." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:25 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:269 +msgid "Swap Details" +msgstr "Zamień szczegóły" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:33 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:312 +msgid "Request ID" +msgstr "Żądanie ID" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:64 +msgid "Not found" +msgstr "Nie znaleziono" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:65 +msgid "Swap with request ID = {requestId} not found." +msgstr "Zamień z ID żądania = {requestId} nie znaleziono." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:219 +msgid "You have received {amount} {token} in {conciseAddress} wallet on {chain} chain." +msgstr "Otrzymałeś {amount} {token} w portfelu {conciseAddress} w łańcuchu {chain}." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:242 +msgid "Transaction was not sent." +msgstr "Transakcja nie została wysłana." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:244 +msgid "{amount} {symbol} on {blockchain} remains in your wallet." +msgstr "{amount} {symbol} na {blockchain} pozostaje w Twoim portfelu." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:281 +msgid "Delete" +msgstr "Usuń" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:304 +msgid "Try again" +msgstr "Spróbuj ponownie" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:322 +msgid "Copied To Clipboard" +msgstr "Skopiowano do schowka" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:323 +msgid "Copy Request ID" +msgstr "Kopiuj ID żądania" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:346 +msgid "View on Rango Explorer" +msgstr "Zobacz w Eksploratorze Rango" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:355 +msgid "Finished at" +msgstr "Zakończono o" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:355 +msgid "Created at" +msgstr "Utworzono w" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.tsx:50 +msgid "View transaction" +msgstr "Zobacz transakcję" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.Warning.tsx:49 +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:31 +msgid "Connect" +msgstr "Połącz" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:43 +msgid "Swap Successful" +msgstr "Zamiana zakończona" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:71 +msgid "Transaction Failed" +msgstr "Transakcja nie powiodła się" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:87 +msgid "Done" +msgstr "Gotowe" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:100 +msgid "Diagnosis" +msgstr "Diagnoza" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:112 +msgid "See Details" +msgstr "Zobacz szczegóły" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:13 +msgid "Cancel Swap" +msgstr "Anuluj zamianę" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:14 +msgid "Are you sure you want to cancel this swap?" +msgstr "Czy na pewno chcesz anulować tę swap?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:23 +msgid "Yes, Cancel it" +msgstr "Tak, anuluj" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:32 +#: widget/embedded/src/pages/CustomTokensPage.tsx:181 +msgid "No, Continue" +msgstr "Nie, Kontynuuj" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:13 +msgid "Delete Transaction" +msgstr "Usuń transakcję" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:14 +msgid "Are you sure you want to delete this swap?" +msgstr "Czy na pewno chcesz usunąć tę swap?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:23 +#: widget/embedded/src/pages/CustomTokensPage.tsx:171 +msgid "Yes, Delete it" +msgstr "Tak, usuń" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:33 +#: widget/embedded/src/pages/HistoryPage.tsx:253 +msgid "No, Cancel" +msgstr "Nie, Anuluj" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:12 +msgid "Change Network" +msgstr "Zmień sieć" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:20 +msgid "Network Changed" +msgstr "Sieć zmieniona" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/TokenList/TokenList.tsx:271 +#: widget/ui/src/containers/SwapInput/TokenSection.tsx:54 +msgid "Select Token" +msgstr "Wybierz token" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:27 +msgid "Wallet Connected" +msgstr "Portfel połączony" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:28 +msgid "Your wallet is connected, you can use it to swap." +msgstr "Twój portfel jest połączony, możesz go użyć do zamiany." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:39 +msgid "Failed to Connect" +msgstr "Nie udało się połączyć" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:41 +msgid "Your wallet is not connected. Please try again." +msgstr "Twój portfel nie jest połączony. Spróbuj ponownie." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:50 +msgid "Connecting to your wallet" +msgstr "Łączenie z portfelem" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:51 +msgid "Click connect in your wallet popup." +msgstr "Kliknij połączenie w wyskakującym oknie portfela." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:99 +msgid "Select Derivation Path" +msgstr "Wybierz Ścieżkę Pochodną" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:100 +msgid "In order to connect to {type}, you must first select a Derivation Path" +msgstr "Aby połączyć się z {type}musisz najpierw wybrać Ścieżkę Pochodną" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:118 +msgid "Choose Derivation Path Template" +msgstr "Wybierz szablon ścieżki pochodnej" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:133 +msgid "Enter Path" +msgstr "Wprowadź ścieżkę" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:134 +msgid "Enter Index" +msgstr "Wprowadź indeks" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:15 +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:18 +msgid "Add {blockchainDisplayName} Chain" +msgstr "Dodaj łańcuch {blockchainDisplayName}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:20 +msgid "Would you like to add the {blockchainDisplayName} experimental chain to your wallet?" +msgstr "Czy chcesz dodać eksperymentalny łańcuch {blockchainDisplayName} do swojego portfela?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:22 +msgid "Please approve the experimental chain pop-up in your wallet." +msgstr "Proszę zatwierdzić eksperymentalne wyskakujące okienko łańcucha w portfelu." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:30 +msgid "{blockchainDisplayName} Chain Added" +msgstr "{blockchainDisplayName} Łańcuch dodany" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:34 +msgid "The {blockchainDisplayName} chain has been successfully added to your wallet." +msgstr "Łańcuch {blockchainDisplayName} został pomyślnie dodany do Twojego portfela." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:42 +msgid "Request Rejected" +msgstr "Żądanie odrzucone" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:43 +msgid "You've rejected adding {blockchainDisplayName} chain to your wallet." +msgstr "Odrzuciłeś dodanie łańcucha {blockchainDisplayName} do swojego portfela." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:70 +msgid "Select chain types" +msgstr "Wybierz typy łańcuchów" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:71 +msgid "This wallet supports multiple chains. Select which chain you'd like to connect to." +msgstr "Ten portfel obsługuje wiele łańcuchów. Wybierz łańcuch, z którym chcesz się połączyć." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:9 +msgid "Failed Network, Please retry your swap." +msgstr "Nieudana sieć, ponów próbę wymiany." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:11 +msgid "Please reset your liquidity sources." +msgstr "Proszę zresetować źródła płynności." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:12 +msgid "You have limited the liquidity sources and this might result in Rango finding no routes. Please consider resetting your liquidity sources." +msgstr "Ograniczyłeś źródła płynności, co może skutkować znalezieniem przez Rango żadnych tras. Rozważ zresetowanie źródeł płynności." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:17 +msgid "No Routes Found." +msgstr "Nie znaleziono trasy." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:18 +msgid "Reasons why Rango couldn't find a route: low liquidity on token, very low input amount or no routes available for the selected input/output token combination." +msgstr "Powody, dla których Rango nie mógł znaleźć trasy: niska płynność w tokenu, bardzo niska ilość wejściowa lub brak dostępnych tras dla wybranej kombinacji tokenu wejściowego/wyjściowego." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:23 +msgid "Bridge Limit Error: Please increase your amount." +msgstr "Błąd limitu mostka: Proszę zwiększyć swoją kwotę." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:26 +msgid "Bridge Limit Error: Please decrease your amount." +msgstr "Błąd limitu mostka: Proszę zmniejszyć swoją kwotę." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:31 +msgid "High Price Impact" +msgstr "Wpływ Wysokiej Ceny" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:32 +msgid "Price impact is too high!" +msgstr "Wpływ ceny jest zbyt wysoki!" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:33 +msgid "The price impact is significantly higher than the allowed amount." +msgstr "Wpływ na cenę jest znacznie wyższy niż dozwolona kwota." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:36 +msgid "Confirm high price impact" +msgstr "Potwierdź wysoki wpływ cen" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:39 +msgid "Route updated and price impact is too high, try again later!" +msgstr "Zaktualizowano trasę i wpływ ceny jest zbyt wysoki, spróbuj ponownie później!" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:44 +msgid "USD Price Unknown" +msgstr "Cena USD nieznana" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:45 +msgid "USD Price Unknown, Cannot calculate Price Impact." +msgstr "Cena USD Nieznana, nie można obliczyć wpływu na cenę." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:46 +msgid "USD Price Unknown, Cannot calculate Price Impact. The price impact may be higher than usual. Are you sure to continue the Swap?" +msgstr "Cena USD Nieznana, nie można obliczyć wpływu na cenę. Wpływ ceny może być wyższy niż zwykle. Czy na pewno chcesz kontynuować transakcję?" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:49 +msgid "Confirm USD Price Unknown" +msgstr "Potwierdź cenę USD nieznaną" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:6 +#: widget/embedded/src/pages/Home.tsx:163 +msgid "Swap" +msgstr "Zamień" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:7 +msgid "Swap anyway" +msgstr "Zamień mimo to" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:8 +msgid "The route goes through Ethereum. Continue?" +msgstr "Trasa przebiega przez Ethereum. Kontynuować?" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:10 +msgid "Route has been updated." +msgstr "Trasa została zaktualizowana." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:12 +msgid "Output amount changed to {newOutputAmount} ({percentageChange}% change)." +msgstr "Kwota wyjściowa zmieniona na {newOutputAmount} (zmiana{percentageChange}%)." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:20 +msgid "Route swappers has been updated." +msgstr "Zaktualizowano zamienniki tras." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:22 +msgid "Route internal coins has been updated." +msgstr "Trasa monet wewnętrznych została zaktualizowana." + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/ExpandedQuotes/ExpandedQuotes.tsx:53 +#: widget/embedded/src/pages/Routes.tsx:48 +msgid "Routes" +msgstr "Trasy" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Inputs/Inputs.tsx:76 +msgid "From" +msgstr "Od" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Inputs/Inputs.tsx:118 +msgid "To" +msgstr "Do" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:49 +msgid "Light" +msgstr "Światło" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:58 +msgid "Dark" +msgstr "Ciemny" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:67 +msgid "Auto" +msgstr "Auto" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:140 +msgid "Loading failed" +msgstr "Ładowanie nie powiodło się" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:156 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:41 +msgid "Bridges" +msgstr "Mosty" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:174 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:41 +msgid "Exchanges" +msgstr "Wymiana" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:195 +#: widget/embedded/src/pages/CustomTokensPage.tsx:90 +msgid "Custom Tokens" +msgstr "Niestandardowe tokeny" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:214 +#: widget/embedded/src/pages/LanguagePage.tsx:43 +msgid "Language" +msgstr "Język" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:235 +msgid "Infinite approval" +msgstr "Nieskończone zatwierdzenie" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:246 +msgid "Enabling the 'Infinite approval' mode grants unrestricted access to underlying smart contracts, allowing them to utilize the approved token amount without limitations." +msgstr "Włączenie trybu 'Nieskończone zatwierdzenie' zapewnia nieograniczony dostęp do podstawowych inteligentnych umów, umożliwiając im wykorzystanie zatwierdzonej ilości tokenów bez ograniczeń." + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:266 +msgid "Theme" +msgstr "Motyw" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:39 +msgid "Duplicate Token" +msgstr "Duplicate Token" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:40 +msgid "The address you entered is duplicate, please enter a new address." +msgstr "Podany adres jest zduplikowany, wprowadź nowy adres." + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:46 +msgid "Token Already Exists" +msgstr "Token już istnieje" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:47 +msgid "There's no need to add this token again because it already exists and is supported by us." +msgstr "Nie ma potrzeby dodawania tego tokenu ponownie, ponieważ już istnieje i jest obsługiwany przez nas." + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:53 +msgid "Token Not Found" +msgstr "Token nie znaleziony" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:54 +msgid "Sorry, no token was found on {blockchain} chain with the provided address. please make sure you have entered the right token address." +msgstr "Przepraszamy, nie znaleziono tokenu w łańcuchu {blockchain} z podanym adrem. Upewnij się, że wprowadziłeś odpowiedni adres tokena." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:78 +msgid "Network Error" +msgstr "Błąd sieci" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:109 +#: widget/embedded/src/pages/CustomTokensPage.tsx:149 +msgid "Add Custom Token" +msgstr "Dodaj własny token" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:127 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:128 +msgid "Select chain" +msgstr "Wybierz łańcuch" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:132 +msgid "Enter Address" +msgstr "Wprowadź adres" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:139 +msgid "Enter token address" +msgstr "Wprowadź adres tokenu" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:176 +msgid "Failed Network, Please retry." +msgstr "Nieudana sieć, spróbuj ponownie." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:192 +msgid "Add another custom token" +msgstr "Dodaj kolejny niestandardowy token" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:236 +msgid "Confirm Swap" +msgstr "Potwierdź wymianę" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:254 +msgid "Start Swap" +msgstr "Rozpocznij wymianę" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:282 +msgid "You get" +msgstr "Otrzymujesz" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:102 +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:90 +msgid "Search Token" +msgstr "Token wyszukiwania" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:134 +msgid "No custom tokens" +msgstr "Brak niestandardowych tokenów" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:135 +msgid "press the button to add your custom token" +msgstr "naciśnij przycisk, aby dodać własny token" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:158 +msgid "Delete Custom Token" +msgstr "Usuń własny token" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:160 +msgid "Are you sure you want to Delete this Token?" +msgstr "Czy na pewno chcesz usunąć ten token?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:59 +msgid "Complete" +msgstr "Complete" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:63 +msgid "Running" +msgstr "Uruchamianie" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:65 +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:8 +msgid "Failed" +msgstr "Niepowodzenie" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:149 +msgid "Clear" +msgstr "Wyczyść" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:161 +msgid "Search Transaction" +msgstr "Szukaj transakcji" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:187 +msgid "No transactions" +msgstr "Brak transakcji" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:194 +msgid "Your transaction history is stored locally and will appear here after you start a swap" +msgstr "Twoja historia transakcji jest przechowywana lokalnie i pojawi się tutaj po rozpoczęciu swapu" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:218 +msgid "Clear Transaction History" +msgstr "Wyczyść historię transakcji" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:222 +msgid "Proceeding will remove all successful and failed transactions from the widget. Do you want to continue?" +msgstr "Kontynuacja spowoduje usunięcie wszystkich udanych i nieudanych transakcji z widżetu. Czy chcesz kontynuować?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:229 +msgid "Note: This does not erase your transaction history on the chain; it only removes them here." +msgstr "Uwaga: To nie usuwa Twojej historii transakcji z łańcucha; usuwa ją tylko tutaj." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:243 +msgid "Yes, Clear the history" +msgstr "Tak, wyczyść historię" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LanguagePage.tsx:56 +msgid "language" +msgstr "język" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:121 +msgid "Deselect all" +msgstr "Odznacz wszystkie" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:121 +msgid "Select all" +msgstr "Zaznacz wszystkie" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:133 +msgid "Search {sourceType}" +msgstr "Szukaj {sourceType}" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectBlockchainPage.tsx:60 +msgid "Search Chain" +msgstr "Wyszukaj łańcuch" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:67 +msgid "Source" +msgstr "Źródło" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:68 +msgid "Destination" +msgstr "Miejsce przeznaczenia" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:74 +msgid "Swap {type}" +msgstr "Zamień {type}" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SettingsPage.tsx:45 +msgid "Currently, you're in campaign mode with restrictions on liquidity sources. Would you like to switch out of this mode and make use of all available liquidity sources?" +msgstr "Obecnie jesteś w trybie kampanii z ograniczeniami dotyczącymi źródeł płynności. Czy chcesz wyłączyć ten tryb i wykorzystać wszystkie dostępne źródła płynności?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SwapDetailsPage.tsx:27 +msgid "The request ID is necessary to display the swap details." +msgstr "Identyfikator żądania jest niezbędny do wyświetlania szczegółów swapu." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/WalletsPage.tsx:67 +#: widget/ui/src/containers/ConnectWalletsModal/ConnectWalletsModal.tsx:15 +msgid "Connect Wallets" +msgstr "Połącz portfele" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/WalletsPage.tsx:82 +msgid "Choose a wallet to connect." +msgstr "Wybierz portfel do połączenia." + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:25 +msgid "This week" +msgstr "W tym tygodniu" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:32 +msgid "This month" +msgstr "W tym miesiącu" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:39 +msgid "This year" +msgstr "W tym roku" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:129 +msgid "Required: >= {min} {symbol}" +msgstr "Wymagane: >= {min} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:142 +msgid "Required: > {min} {symbol}" +msgstr "Wymagane: > {min} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:157 +msgid "Required: <= {max} {symbol}" +msgstr "Wymagane: <= {max} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:170 +msgid "Required: < {max} {symbol}" +msgstr "Wymagane: < {max} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:601 +msgid " for network fee" +msgstr " za opłatę sieciową" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:604 +msgid " for swap" +msgstr " dla swapu" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:607 +msgid " for input and network fee" +msgstr " dla opłat wejściowych i opłat sieciowych" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:609 +msgid "Needs ≈ {requiredAmount} {symbol}{reason}, but you have {currentAmount} {symbol} in your {blockchain} wallet." +msgstr "Potrzebuje → {requiredAmount} {symbol}{reason}, ale masz {currentAmount} {symbol} w swoim portfelu {blockchain}." + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:669 +msgid "Waiting for connecting wallet" +msgstr "Oczekiwanie na połączenie portfela" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:673 +msgid "Waiting for other running tasks to be finished" +msgstr "Oczekiwanie na zakończenie innych uruchomionych zadań" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:676 +msgid "Waiting for changing wallet network" +msgstr "Oczekiwanie na zmianę sieci portfela" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:6 +msgid "Sunday" +msgstr "Niedziela" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:7 +msgid "Monday" +msgstr "Poniedziałek" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:8 +msgid "Tuesday" +msgstr "Wtorek" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:9 +msgid "Wednesday" +msgstr "Środa" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:10 +msgid "Thursday" +msgstr "Czwartek" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:11 +msgid "Friday" +msgstr "Piątek" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:12 +msgid "Saturday" +msgstr "Sobota" + +#. js-lingui-explicit-id +#: widget/ui/src/components/BottomLogo/BottomLogo.tsx:14 +msgid "Powered By" +msgstr "Wspierane przez" + +#. js-lingui-explicit-id +#: widget/ui/src/components/FullExpandedQuote/FullExpandedQuote.Tooltip.tsx:37 +msgid "Aggregated Transaction" +msgstr "Zbiorcza transakcja" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SelectableCategoryList/SelectableCategoryList.tsx:63 +msgid "{blockchainCategory}" +msgstr "{blockchainCategory}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/StepDetails/StepDetails.tsx:75 +#: widget/ui/src/components/StepDetails/StepDetails.tsx:102 +msgid "Swap on {fromChain} via {swapper}" +msgstr "Zamień na {fromChain} przez {swapper}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/StepDetails/StepDetails.tsx:109 +msgid "Bridge to {toChain} via {swapper}" +msgstr "Most do {toChain} przez {swapper}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:10 +msgid "Completed" +msgstr "Zakończone" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:12 +msgid "In progress" +msgstr "W toku" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapToken.tsx:122 +msgid "Waiting for bridge transaction" +msgstr "Oczekiwanie na transakcję mostu" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:12 +msgid "Connected" +msgstr "Połączono" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:13 +msgid "Disconnect" +msgstr "Rozłącz" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:18 +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:19 +msgid "Install" +msgstr "Zainstaluj" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:24 +msgid "Connecting ..." +msgstr "Łączenie..." + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:25 +msgid "Connecting" +msgstr "Łączenie" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:30 +msgid "Disconnected" +msgstr "Rozłączony" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:34 +msgid "you need to pass a correct state to Wallet." +msgstr "musisz przekazać poprawny stan Wallet." + +#. js-lingui-explicit-id +#: widget/ui/src/containers/Notifications/NotificationNotFound.tsx:15 +msgid "There are no notifications." +msgstr "Brak powiadomień." + +#. js-lingui-explicit-id +#: widget/ui/src/containers/Notifications/Notifications.tsx:39 +msgid "Clear all" +msgstr "Wyczyść wszystko" + +#. js-lingui-explicit-id +#: widget/ui/src/containers/SwapInput/SwapInput.tsx:65 +msgid "Balance" +msgstr "Saldo" + +#. js-lingui-explicit-id +#: widget/ui/src/containers/SwapInput/SwapInput.tsx:73 +msgid "Max" +msgstr "Maks." + diff --git a/translations/pt.po b/translations/pt.po new file mode 100644 index 0000000000..e9f292f302 --- /dev/null +++ b/translations/pt.po @@ -0,0 +1,1339 @@ +msgid "" +msgstr "" +"POT-Creation-Date: 2023-11-06 17:24+0330\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: @lingui/cli\n" +"Language: pt\n" +"Project-Id-Version: rango\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2024-11-27 15:57\n" +"Last-Translator: \n" +"Language-Team: Portuguese\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Crowdin-Project: rango\n" +"X-Crowdin-Project-ID: 622238\n" +"X-Crowdin-Language: pt-PT\n" +"X-Crowdin-File: en.po\n" +"X-Crowdin-File-ID: 30\n" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SameTokensWarning/SameTokensWarning.tsx:21 +msgid "No Routes Found" +msgstr "Nenhuma rota encontrada" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SameTokensWarning/SameTokensWarning.tsx:25 +msgid "You cannot use the same token for From and To." +msgstr "Você não pode usar o mesmo token para From e To." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:41 +#: widget/embedded/src/components/TokenList/TokenList.tsx:286 +#: widget/embedded/src/pages/HistoryPage.tsx:186 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:143 +msgid "No results found" +msgstr "Nenhum resultado encontrado" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:42 +#: widget/embedded/src/components/TokenList/TokenList.tsx:287 +#: widget/embedded/src/pages/HistoryPage.tsx:193 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:144 +msgid "Try using different keywords" +msgstr "Tente usar palavras-chave diferentes" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:72 +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:46 +#: widget/embedded/src/pages/SelectBlockchainPage.tsx:42 +#: widget/ui/src/containers/SwapInput/TokenSection.tsx:61 +msgid "Select Chain" +msgstr "Selecionar Cadeia" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:66 +msgid "All" +msgstr "TODOS" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:100 +msgid "More +{count}" +msgstr "Mais +{count}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabAlert/ActivateTabAlert.tsx:17 +msgid "Activate this tab" +msgstr "Ativar esta aba" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabAlert/ActivateTabAlert.tsx:22 +msgid "Another tab is open and handles transactions." +msgstr "Outra aba é aberta e lida com transações." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:20 +msgid "Activate current tab" +msgstr "Ativar a aba atual" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:22 +msgid "Currently, some transactions are running and being handled by other browser tab. If you activate this tab, all transactions that are already in the transaction sign step will expire." +msgstr "No momento, algumas transações estão sendo executadas e sendo tratadas por outra aba do navegador. Se você ativar essa aba, todas as transações que já estão na etapa de sinal de transação irão expirar." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:33 +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:349 +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:152 +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:33 +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:116 +msgid "Confirm" +msgstr "Confirmar" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:365 +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:447 +msgid "Your {blockchainName} wallets" +msgstr "Suas carteiras {blockchainName}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:384 +msgid "Insufficient account balance" +msgstr "Saldo de conta insuficiente" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:394 +msgid "Proceed anyway" +msgstr "Continuar mesmo assim" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:456 +msgid "You need to connect a {blockchainName} wallet." +msgstr "Você precisa conectar uma carteira {blockchainName}." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/WalletList.tsx:143 +msgid "Add {chain} chain" +msgstr "Adiciona cadeia {chain}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/WalletList.tsx:244 +msgid "Show more wallets" +msgstr "Mostrar mais carteiras" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:113 +msgid "Send to a different address" +msgstr "Enviar para outro endereço" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:129 +msgid "Enter {blockchainName} address" +msgstr "Digite o endereço {blockchainName}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:147 +msgid "Address {destination} doesn't match the blockchain address pattern." +msgstr "O endereço {destination} não corresponde ao padrão do endereço da blockchain." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:59 +msgid "via" +msgstr "através" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:74 +msgid "This token doesn't appear on the active token list(s). Make sure this is the token that you want to trade." +msgstr "Este token não aparece na lista de tokens ativos. Certifique-se de que este é o token que você deseja negociar." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:89 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:164 +msgid "Import" +msgstr "Importação" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/FilterSelector/FilterSelectorContent.tsx:26 +msgid "Status" +msgstr "SItuação" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/FilterSelector/FilterSelectorContent.tsx:33 +#: widget/embedded/src/components/NoResult/NoResult.helpers.ts:37 +#: widget/embedded/src/pages/SettingsPage.tsx:55 +msgid "Reset" +msgstr "Reset" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/CancelButton.tsx:18 +msgid "Cancel" +msgstr "cancelar" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:46 +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:34 +msgid "Refresh" +msgstr "atualizar" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:63 +#: widget/ui/src/containers/Notifications/Notifications.tsx:35 +msgid "Notifications" +msgstr "notificações" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:79 +#: widget/embedded/src/pages/SettingsPage.tsx:38 +msgid "Settings" +msgstr "Confirgurações" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:93 +#: widget/embedded/src/pages/HistoryPage.tsx:139 +msgid "History" +msgstr "Histórico" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/WalletButton.tsx:22 +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:16 +#: widget/embedded/src/constants/messages.ts:5 +msgid "Connect Wallet" +msgstr "Conectar Carteira" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HistoryGroupedList/HistoryGroupedList.tsx:118 +#: widget/embedded/src/utils/date.ts:18 +#: widget/embedded/src/utils/time.ts:22 +msgid "Today" +msgstr "hoje" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/LoadingSwapDetails/LoadingSwapDetails.tsx:20 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:424 +msgid "Swaps steps" +msgstr "Etapas de troca" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/NoResult/NoResult.helpers.ts:25 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:191 +msgid "Retry" +msgstr "Repetir" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:149 +msgid "Slippage Error" +msgstr "Erro Slippage" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:150 +msgid "Slippage Warning" +msgstr "Aviso Slippage" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:153 +msgid "Bridge Limit Error" +msgstr "Erro no limite da ponte" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:240 +msgid "Yours: {amount} {symbol}" +msgstr "Sua: {amount} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:261 +msgid "Minimum required slippage: {minRequiredSlippage}" +msgstr "Mínimo de slippage: {minRequiredSlippage}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:282 +msgid "Yours: {userSlippage}" +msgstr "Sua: {userSlippage}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:395 +msgid "See All Routes" +msgstr "Ver todas as rotas" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:81 +msgid "View more info" +msgstr "Ver mais informações" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:91 +msgid "Gas & Fee Explanation" +msgstr "Explicação de Gás e Taxa" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:107 +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:103 +msgid "Details" +msgstr "detalhes" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:146 +msgid "Total Payable Fee" +msgstr "Taxa total a pagar" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:166 +msgid "Hide non-payable fees" +msgstr "Ocultar taxas não-pagáveis" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:167 +msgid "Show non-payable fees" +msgstr "Mostrar tarifas não pagáveis" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:177 +msgid "Description" +msgstr "Descrição:" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:181 +msgid "The following fees are considered in the transaction output and\n" +" you won’t need to pay extra gas for them." +msgstr "As seguintes tarifas são consideradas no resultado da transação e\n" +" você não precisará pagar gás extra por elas." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteSummary.tsx:25 +msgid "Swap input" +msgstr "Swap input" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteSummary.tsx:44 +msgid "Estimated output" +msgstr "Saída estimada" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteTrigger.tsx:65 +msgid "Via:" +msgstr "Via:" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteTrigger.tsx:150 +msgid "Chains:" +msgstr "Correntas:" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/Quotes.tsx:77 +msgid "Sort by" +msgstr "Classificar por" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:17 +msgid "Smart Routing" +msgstr "Roteamento inteligente" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:21 +msgid "Lowest Fee" +msgstr "Taxa mais baixa" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:25 +msgid "Fastest Transfer" +msgstr "Mais Rápido" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:29 +msgid "Maximum Return" +msgstr "Retorno Máximo" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:33 +msgid "Maximum Output" +msgstr "Produção Máxima" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:43 +msgid "Swapping" +msgstr "Swapping" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:51 +msgid "Gas cost" +msgstr "Custo de gás" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:59 +msgid "Receiving" +msgstr "Recebimento" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:67 +msgid "Price impact" +msgstr "Impacto nos preços" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:35 +msgid "You need to increase slippage to at least {minRequiredSlippage} for this route." +msgstr "Você precisa aumentar o slippage para pelo menos {minRequiredSlippage} para esta rota." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:59 +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:61 +msgid "We recommend you to increase slippage to at least {minRequiredSlippage} for this route." +msgstr "Recomendamos que você aumente o slippage para pelo menos {minRequiredSlippage} para esta rota." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:68 +msgid "Caution, your slippage is high." +msgstr "Cuidado, seu slippage está alto." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.tsx:78 +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.Warning.tsx:26 +msgid "Change" +msgstr "Troca" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:42 +msgid "Change settings" +msgstr "Alterar configurações" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:52 +msgid "High slippage" +msgstr "Alto slide" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:53 +msgid "Low slippage" +msgstr "Slippage Baixo" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:57 +msgid " Caution, your slippage is high (={userSlippage}). Your trade may be front run." +msgstr " Cuidado, sua página de slippage está alta ={userSlippage}). Sua operação pode ser iniciada primeiro." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:78 +msgid "Confirm anyway" +msgstr "Confirmar mesmo assim" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:22 +msgid "Something went wrong" +msgstr "Algo deu errado" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:24 +msgid "Something went wrong. Please refresh the app." +msgstr "Ocorreu um erro. Por favor, atualize o aplicativo." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/Slippage.tsx:38 +msgid "Slippage tolerance per swap" +msgstr "Tolerância do slippage por swap" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/Slippage.tsx:91 +msgid "Custom" +msgstr "Personalizado" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:11 +msgid "Your transaction will be reverted if the price changes unfavorably by more than this percentage." +msgstr "Sua transação será revertida se o preço mudar desfavoravelmente, mais do que esta percentagem." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:16 +#: widget/embedded/src/containers/Settings/Lists.tsx:245 +msgid "Warning" +msgstr "ATENÇÃO" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:17 +msgid "This setting is applied to each step (e.g. 1Inch, Thorchain, etc.), meaning only that specific step will be reverted, not the entire route." +msgstr "Essa configuração é aplicada a cada etapa (por exemplo, 1Inch, Thorchain, etc.), significando apenas que a etapa específica será revertida, não a rota inteira." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:25 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:269 +msgid "Swap Details" +msgstr "Trocar detalhes" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:33 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:312 +msgid "Request ID" +msgstr "Solicitar ID" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:64 +msgid "Not found" +msgstr "Não encontrado" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:65 +msgid "Swap with request ID = {requestId} not found." +msgstr "Trocar com o ID de requisição = {requestId} não encontrado." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:219 +msgid "You have received {amount} {token} in {conciseAddress} wallet on {chain} chain." +msgstr "Você recebeu {amount} {token} em carteira {conciseAddress} na cadeia {chain}." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:242 +msgid "Transaction was not sent." +msgstr "Transação não foi enviada." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:244 +msgid "{amount} {symbol} on {blockchain} remains in your wallet." +msgstr "{amount} {symbol} em {blockchain} permanece em sua carteira." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:281 +msgid "Delete" +msgstr "excluir" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:304 +msgid "Try again" +msgstr "Tente novamente" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:322 +msgid "Copied To Clipboard" +msgstr "Copiado Para a Área de Transferência" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:323 +msgid "Copy Request ID" +msgstr "Copiar ID da Requisição" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:346 +msgid "View on Rango Explorer" +msgstr "Ver no Rango Explorer" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:355 +msgid "Finished at" +msgstr "Terminado em" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:355 +msgid "Created at" +msgstr "Criado em" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.tsx:50 +msgid "View transaction" +msgstr "Ver transação" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.Warning.tsx:49 +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:31 +msgid "Connect" +msgstr "Conectar" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:43 +msgid "Swap Successful" +msgstr "Troca bem sucedida" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:71 +msgid "Transaction Failed" +msgstr "Transação Falhou" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:87 +msgid "Done" +msgstr "Concluído" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:100 +msgid "Diagnosis" +msgstr "Diagnóstico" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:112 +msgid "See Details" +msgstr "Ver Detalhes" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:13 +msgid "Cancel Swap" +msgstr "Cancelar Swap" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:14 +msgid "Are you sure you want to cancel this swap?" +msgstr "Tem certeza que deseja cancelar este swap?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:23 +msgid "Yes, Cancel it" +msgstr "Sim, Cancele" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:32 +#: widget/embedded/src/pages/CustomTokensPage.tsx:181 +msgid "No, Continue" +msgstr "Não, continuar" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:13 +msgid "Delete Transaction" +msgstr "Excluir Transação" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:14 +msgid "Are you sure you want to delete this swap?" +msgstr "Tem certeza que deseja excluir esta troca?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:23 +#: widget/embedded/src/pages/CustomTokensPage.tsx:171 +msgid "Yes, Delete it" +msgstr "Sim, exclua-o" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:33 +#: widget/embedded/src/pages/HistoryPage.tsx:253 +msgid "No, Cancel" +msgstr "Não, cancele" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:12 +msgid "Change Network" +msgstr "Alterar rede" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:20 +msgid "Network Changed" +msgstr "Rede alterada" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/TokenList/TokenList.tsx:271 +#: widget/ui/src/containers/SwapInput/TokenSection.tsx:54 +msgid "Select Token" +msgstr "Selecione o Token" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:27 +msgid "Wallet Connected" +msgstr "Carteira conectada" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:28 +msgid "Your wallet is connected, you can use it to swap." +msgstr "Sua carteira está conectada, você pode usá-la para trocar." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:39 +msgid "Failed to Connect" +msgstr "Falha na conexão" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:41 +msgid "Your wallet is not connected. Please try again." +msgstr "Sua carteira não está conectada. Por favor, tente novamente." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:50 +msgid "Connecting to your wallet" +msgstr "Conectando-se à sua carteira" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:51 +msgid "Click connect in your wallet popup." +msgstr "Clique em conectar no pop-up da sua carteira." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:99 +msgid "Select Derivation Path" +msgstr "Selecionar Caminho de Derivação" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:100 +msgid "In order to connect to {type}, you must first select a Derivation Path" +msgstr "Para conectar a {type}, você deve primeiro selecionar um caminho de Derivação" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:118 +msgid "Choose Derivation Path Template" +msgstr "Escolher Modelo de Caminho de Derivação" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:133 +msgid "Enter Path" +msgstr "Insira o caminho" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:134 +msgid "Enter Index" +msgstr "Inserir índice" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:15 +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:18 +msgid "Add {blockchainDisplayName} Chain" +msgstr "Adicionar Corrente {blockchainDisplayName}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:20 +msgid "Would you like to add the {blockchainDisplayName} experimental chain to your wallet?" +msgstr "Você gostaria de adicionar a cadeia experimental {blockchainDisplayName} à sua carteira?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:22 +msgid "Please approve the experimental chain pop-up in your wallet." +msgstr "Por favor, aprove o pop-up experimental na sua carteira." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:30 +msgid "{blockchainDisplayName} Chain Added" +msgstr "{blockchainDisplayName} Cadeia Adicionada" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:34 +msgid "The {blockchainDisplayName} chain has been successfully added to your wallet." +msgstr "A cadeia {blockchainDisplayName} foi adicionada com sucesso à sua carteira." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:42 +msgid "Request Rejected" +msgstr "Pedido rejeitado" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:43 +msgid "You've rejected adding {blockchainDisplayName} chain to your wallet." +msgstr "Você rejeitou adicionar {blockchainDisplayName} corrente à sua carteira." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:70 +msgid "Select chain types" +msgstr "Selecione tipos de correntes" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:71 +msgid "This wallet supports multiple chains. Select which chain you'd like to connect to." +msgstr "Esta carteira suporta várias cadeias. Selecione a que cadeia você gostaria de se conectar." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:9 +msgid "Failed Network, Please retry your swap." +msgstr "Falha na Rede, tente novamente sua alternância." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:11 +msgid "Please reset your liquidity sources." +msgstr "Por favor, redefina suas fontes de liquidez." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:12 +msgid "You have limited the liquidity sources and this might result in Rango finding no routes. Please consider resetting your liquidity sources." +msgstr "Você limitou as fontes de liquidez e isso pode resultar em que o Rango não encontre nenhuma rota. Por favor, considere redefinir suas fontes de liquidez." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:17 +msgid "No Routes Found." +msgstr "Nenhuma rota encontrada." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:18 +msgid "Reasons why Rango couldn't find a route: low liquidity on token, very low input amount or no routes available for the selected input/output token combination." +msgstr "Motivos porque Rango não conseguiu encontrar uma rota: baixa liquidez no token, quantidade muito baixa de entrada ou nenhuma rota disponível para a combinação selecionada de entrada/saída do token." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:23 +msgid "Bridge Limit Error: Please increase your amount." +msgstr "Erro no limite da ponte: Por favor, aumente o seu valor." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:26 +msgid "Bridge Limit Error: Please decrease your amount." +msgstr "Erro no limite da ponte: Por favor, reduza seu montante." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:31 +msgid "High Price Impact" +msgstr "Impacto de preço alto" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:32 +msgid "Price impact is too high!" +msgstr "O impacto nos preços é muito alto!" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:33 +msgid "The price impact is significantly higher than the allowed amount." +msgstr "O impacto nos preços é significativamente mais alto do que a quantidade permitida." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:36 +msgid "Confirm high price impact" +msgstr "Confirmar alto impacto nos preços" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:39 +msgid "Route updated and price impact is too high, try again later!" +msgstr "A rota atualizada e o impacto nos preços é muito alto, tente novamente mais tarde!" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:44 +msgid "USD Price Unknown" +msgstr "Preço em USD desconhecido" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:45 +msgid "USD Price Unknown, Cannot calculate Price Impact." +msgstr "Preço em USD desconhecido, não é possível calcular o impacto de preços." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:46 +msgid "USD Price Unknown, Cannot calculate Price Impact. The price impact may be higher than usual. Are you sure to continue the Swap?" +msgstr "Preço em USD desconhecido, não é possível calcular o impacto do preço. O impacto do preço pode ser maior do que o normal. Tem certeza que deseja continuar o Swap?" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:49 +msgid "Confirm USD Price Unknown" +msgstr "Confirmar preço de USD desconhecido" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:6 +#: widget/embedded/src/pages/Home.tsx:163 +msgid "Swap" +msgstr "Trocar" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:7 +msgid "Swap anyway" +msgstr "Trocar mesmo assim" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:8 +msgid "The route goes through Ethereum. Continue?" +msgstr "A rota passa pelo Ethereum. Continuar?" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:10 +msgid "Route has been updated." +msgstr "Rota foi atualizada." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:12 +msgid "Output amount changed to {newOutputAmount} ({percentageChange}% change)." +msgstr "Valor de saída alterado para {newOutputAmount} ( Alteração de{percentageChange}%)." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:20 +msgid "Route swappers has been updated." +msgstr "Os trocadores de rota foram atualizados." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:22 +msgid "Route internal coins has been updated." +msgstr "Moedas internas do itinerário foram atualizadas." + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/ExpandedQuotes/ExpandedQuotes.tsx:53 +#: widget/embedded/src/pages/Routes.tsx:48 +msgid "Routes" +msgstr "Rotas" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Inputs/Inputs.tsx:76 +msgid "From" +msgstr "De" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Inputs/Inputs.tsx:118 +msgid "To" +msgstr "Para" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:49 +msgid "Light" +msgstr "Fino" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:58 +msgid "Dark" +msgstr "Escuro" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:67 +msgid "Auto" +msgstr "Automático" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:140 +msgid "Loading failed" +msgstr "Falha no carregamento" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:156 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:41 +msgid "Bridges" +msgstr "Pontes" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:174 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:41 +msgid "Exchanges" +msgstr "Trocas" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:195 +#: widget/embedded/src/pages/CustomTokensPage.tsx:90 +msgid "Custom Tokens" +msgstr "Tokens Personalizados" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:214 +#: widget/embedded/src/pages/LanguagePage.tsx:43 +msgid "Language" +msgstr "IDIOMA" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:235 +msgid "Infinite approval" +msgstr "Aprovação infinita" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:246 +msgid "Enabling the 'Infinite approval' mode grants unrestricted access to underlying smart contracts, allowing them to utilize the approved token amount without limitations." +msgstr "Habilitar o modo 'Aprovação infinita' concede acesso irrestrito aos contratos inteligentes subjacentes, permitindo-lhes usar o valor do token aprovado, sem limitações." + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:266 +msgid "Theme" +msgstr "Tema" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:39 +msgid "Duplicate Token" +msgstr "Duplicate Token" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:40 +msgid "The address you entered is duplicate, please enter a new address." +msgstr "O endereço inserido é duplicado, por favor insira um novo endereço." + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:46 +msgid "Token Already Exists" +msgstr "Token já existe" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:47 +msgid "There's no need to add this token again because it already exists and is supported by us." +msgstr "Não há necessidade de adicionar este token novamente porque ele já existe e é suportado por nós." + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:53 +msgid "Token Not Found" +msgstr "Token não encontrado" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:54 +msgid "Sorry, no token was found on {blockchain} chain with the provided address. please make sure you have entered the right token address." +msgstr "Desculpe, nenhum token foi encontrado na cadeia {blockchain} com o endereço fornecido. Por favor, certifique-se de ter inserido o endereço correto do token." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:78 +msgid "Network Error" +msgstr "Erro de rede" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:109 +#: widget/embedded/src/pages/CustomTokensPage.tsx:149 +msgid "Add Custom Token" +msgstr "Adicionar token personalizado" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:127 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:128 +msgid "Select chain" +msgstr "Selecione a cadeia" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:132 +msgid "Enter Address" +msgstr "Inserir Endereço" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:139 +msgid "Enter token address" +msgstr "Inserir endereço do token" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:176 +msgid "Failed Network, Please retry." +msgstr "Rede falhada, por favor, tente novamente." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:192 +msgid "Add another custom token" +msgstr "Adicionar outro token personalizado" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:236 +msgid "Confirm Swap" +msgstr "Confirmar troca" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:254 +msgid "Start Swap" +msgstr "Trocar de início" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:282 +msgid "You get" +msgstr "Você recebe" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:102 +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:90 +msgid "Search Token" +msgstr "Token de pesquisa" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:134 +msgid "No custom tokens" +msgstr "Sem tokens personalizados" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:135 +msgid "press the button to add your custom token" +msgstr "pressione o botão para adicionar seu token personalizado" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:158 +msgid "Delete Custom Token" +msgstr "Excluir token personalizado" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:160 +msgid "Are you sure you want to Delete this Token?" +msgstr "Tem certeza que deseja excluir este Token?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:59 +msgid "Complete" +msgstr "Complete" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:63 +msgid "Running" +msgstr "Executando" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:65 +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:8 +msgid "Failed" +msgstr "Falhou" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:149 +msgid "Clear" +msgstr "Limpar" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:161 +msgid "Search Transaction" +msgstr "Pesquisar transação" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:187 +msgid "No transactions" +msgstr "Nenhuma transação" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:194 +msgid "Your transaction history is stored locally and will appear here after you start a swap" +msgstr "Seu histórico de transações é armazenado localmente e aparecerá aqui depois que você começar uma troca" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:218 +msgid "Clear Transaction History" +msgstr "Limpar histórico de transações" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:222 +msgid "Proceeding will remove all successful and failed transactions from the widget. Do you want to continue?" +msgstr "O processo irá remover todas as transações com sucesso e falha do widget. Deseja continuar?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:229 +msgid "Note: This does not erase your transaction history on the chain; it only removes them here." +msgstr "Nota: Isso não apaga seu histórico de transações na cadeia; só os remove aqui." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:243 +msgid "Yes, Clear the history" +msgstr "Sim, limpar o histórico" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LanguagePage.tsx:56 +msgid "language" +msgstr "Idioma" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:121 +msgid "Deselect all" +msgstr "Desmarcar todos" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:121 +msgid "Select all" +msgstr "Selecionar todos" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:133 +msgid "Search {sourceType}" +msgstr "Pesquisar em {sourceType}" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectBlockchainPage.tsx:60 +msgid "Search Chain" +msgstr "Buscar Cadeia" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:67 +msgid "Source" +msgstr "fonte" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:68 +msgid "Destination" +msgstr "Destino" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:74 +msgid "Swap {type}" +msgstr "Trocar {type}" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SettingsPage.tsx:45 +msgid "Currently, you're in campaign mode with restrictions on liquidity sources. Would you like to switch out of this mode and make use of all available liquidity sources?" +msgstr "Atualmente, você está no modo campanha com restrições sobre fontes de liquidez. Gostaria de mudar este modo e usar todas as fontes de liquidez disponíveis?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SwapDetailsPage.tsx:27 +msgid "The request ID is necessary to display the swap details." +msgstr "O ID da requisição é necessário para exibir os detalhes do swap." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/WalletsPage.tsx:67 +#: widget/ui/src/containers/ConnectWalletsModal/ConnectWalletsModal.tsx:15 +msgid "Connect Wallets" +msgstr "Conectar Carteiras" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/WalletsPage.tsx:82 +msgid "Choose a wallet to connect." +msgstr "Escolha uma carteira para se conectar." + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:25 +msgid "This week" +msgstr "Esta semana" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:32 +msgid "This month" +msgstr "Este Mês" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:39 +msgid "This year" +msgstr "Esse ano" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:129 +msgid "Required: >= {min} {symbol}" +msgstr "Obrigatório: >= {min} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:142 +msgid "Required: > {min} {symbol}" +msgstr "Obrigatório: > {min} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:157 +msgid "Required: <= {max} {symbol}" +msgstr "Obrigatório: <= {max} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:170 +msgid "Required: < {max} {symbol}" +msgstr "Obrigatório: < {max} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:601 +msgid " for network fee" +msgstr " para taxa de rede" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:604 +msgid " for swap" +msgstr " para troca" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:607 +msgid " for input and network fee" +msgstr " por taxa de entrada e de rede" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:609 +msgid "Needs ≈ {requiredAmount} {symbol}{reason}, but you have {currentAmount} {symbol} in your {blockchain} wallet." +msgstr "Precisa de {requiredAmount} {symbol}{reason}, mas você tem {currentAmount} {symbol} na sua carteira {blockchain}." + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:669 +msgid "Waiting for connecting wallet" +msgstr "Aguardando conexão da carteira" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:673 +msgid "Waiting for other running tasks to be finished" +msgstr "Aguardando o término de outras tarefas em execução" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:676 +msgid "Waiting for changing wallet network" +msgstr "Aguardando mudança da rede de carteira" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:6 +msgid "Sunday" +msgstr "domingo" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:7 +msgid "Monday" +msgstr "Segunda-Feira" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:8 +msgid "Tuesday" +msgstr "Terça-feira" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:9 +msgid "Wednesday" +msgstr "quarta-feira" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:10 +msgid "Thursday" +msgstr "quinta-feira" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:11 +msgid "Friday" +msgstr "Sexta-feira" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:12 +msgid "Saturday" +msgstr "sábado" + +#. js-lingui-explicit-id +#: widget/ui/src/components/BottomLogo/BottomLogo.tsx:14 +msgid "Powered By" +msgstr "Desenvolvido por" + +#. js-lingui-explicit-id +#: widget/ui/src/components/FullExpandedQuote/FullExpandedQuote.Tooltip.tsx:37 +msgid "Aggregated Transaction" +msgstr "Transação Agregada" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SelectableCategoryList/SelectableCategoryList.tsx:63 +msgid "{blockchainCategory}" +msgstr "{blockchainCategory}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/StepDetails/StepDetails.tsx:75 +#: widget/ui/src/components/StepDetails/StepDetails.tsx:102 +msgid "Swap on {fromChain} via {swapper}" +msgstr "Trocar em {fromChain} via {swapper}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/StepDetails/StepDetails.tsx:109 +msgid "Bridge to {toChain} via {swapper}" +msgstr "Ponte para {toChain} via {swapper}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:10 +msgid "Completed" +msgstr "Concluído" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:12 +msgid "In progress" +msgstr "Em Execução" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapToken.tsx:122 +msgid "Waiting for bridge transaction" +msgstr "Aguardando a transação da bridge" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:12 +msgid "Connected" +msgstr "Conectado" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:13 +msgid "Disconnect" +msgstr "Desconectar" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:18 +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:19 +msgid "Install" +msgstr "Instale" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:24 +msgid "Connecting ..." +msgstr "Conectando ..." + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:25 +msgid "Connecting" +msgstr "Conectando" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:30 +msgid "Disconnected" +msgstr "Desconectado" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:34 +msgid "you need to pass a correct state to Wallet." +msgstr "você precisa passar um estado correto para o Wallet." + +#. js-lingui-explicit-id +#: widget/ui/src/containers/Notifications/NotificationNotFound.tsx:15 +msgid "There are no notifications." +msgstr "Não há notificações." + +#. js-lingui-explicit-id +#: widget/ui/src/containers/Notifications/Notifications.tsx:39 +msgid "Clear all" +msgstr "Limpar tudo" + +#. js-lingui-explicit-id +#: widget/ui/src/containers/SwapInput/SwapInput.tsx:65 +msgid "Balance" +msgstr "Saldo" + +#. js-lingui-explicit-id +#: widget/ui/src/containers/SwapInput/SwapInput.tsx:73 +msgid "Max" +msgstr "Máximo" + diff --git a/translations/ru.po b/translations/ru.po new file mode 100644 index 0000000000..30e8d719d6 --- /dev/null +++ b/translations/ru.po @@ -0,0 +1,1339 @@ +msgid "" +msgstr "" +"POT-Creation-Date: 2023-11-06 17:24+0330\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: @lingui/cli\n" +"Language: ru\n" +"Project-Id-Version: rango\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2024-11-27 15:57\n" +"Last-Translator: \n" +"Language-Team: Russian\n" +"Plural-Forms: nplurals=4; plural=((n%10==1 && n%100!=11) ? 0 : ((n%10 >= 2 && n%10 <=4 && (n%100 < 12 || n%100 > 14)) ? 1 : ((n%10 == 0 || (n%10 >= 5 && n%10 <=9)) || (n%100 >= 11 && n%100 <= 14)) ? 2 : 3));\n" +"X-Crowdin-Project: rango\n" +"X-Crowdin-Project-ID: 622238\n" +"X-Crowdin-Language: ru\n" +"X-Crowdin-File: en.po\n" +"X-Crowdin-File-ID: 30\n" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SameTokensWarning/SameTokensWarning.tsx:21 +msgid "No Routes Found" +msgstr "Маршруты не найдены" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SameTokensWarning/SameTokensWarning.tsx:25 +msgid "You cannot use the same token for From and To." +msgstr "Вы не можете использовать один и тот же токен для полей «От» и «До»." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:41 +#: widget/embedded/src/components/TokenList/TokenList.tsx:286 +#: widget/embedded/src/pages/HistoryPage.tsx:186 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:143 +msgid "No results found" +msgstr "Ничего не найдено" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:42 +#: widget/embedded/src/components/TokenList/TokenList.tsx:287 +#: widget/embedded/src/pages/HistoryPage.tsx:193 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:144 +msgid "Try using different keywords" +msgstr "Попробуйте использовать разные ключевые слова" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:72 +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:46 +#: widget/embedded/src/pages/SelectBlockchainPage.tsx:42 +#: widget/ui/src/containers/SwapInput/TokenSection.tsx:61 +msgid "Select Chain" +msgstr "Выберите цепь" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:66 +msgid "All" +msgstr "Все" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:100 +msgid "More +{count}" +msgstr "Больше +{count}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabAlert/ActivateTabAlert.tsx:17 +msgid "Activate this tab" +msgstr "Активировать эту вкладку" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabAlert/ActivateTabAlert.tsx:22 +msgid "Another tab is open and handles transactions." +msgstr "Еще одна вкладка открыта и обрабатывает транзакции." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:20 +msgid "Activate current tab" +msgstr "Активировать текущую вкладку" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:22 +msgid "Currently, some transactions are running and being handled by other browser tab. If you activate this tab, all transactions that are already in the transaction sign step will expire." +msgstr "В настоящее время некоторые транзакции выполняются и обрабатываются другой вкладкой браузера. Если вы активируете эту вкладку, все транзакции, которые уже находятся в шаге подписи транзакций, истекают." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:33 +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:349 +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:152 +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:33 +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:116 +msgid "Confirm" +msgstr "Подтвердить" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:365 +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:447 +msgid "Your {blockchainName} wallets" +msgstr "Ваши кошельки {blockchainName}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:384 +msgid "Insufficient account balance" +msgstr "Недостаточно средств на счете" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:394 +msgid "Proceed anyway" +msgstr "Все равно продолжить" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:456 +msgid "You need to connect a {blockchainName} wallet." +msgstr "Вам нужно подключить кошелек {blockchainName}." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/WalletList.tsx:143 +msgid "Add {chain} chain" +msgstr "Добавить цепочку {chain}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/WalletList.tsx:244 +msgid "Show more wallets" +msgstr "Показать больше кошельков" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:113 +msgid "Send to a different address" +msgstr "Отправить на другой адрес" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:129 +msgid "Enter {blockchainName} address" +msgstr "Введите адрес {blockchainName}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:147 +msgid "Address {destination} doesn't match the blockchain address pattern." +msgstr "{destination} не соответствует шаблону адреса блокчейна." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:59 +msgid "via" +msgstr "через" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:74 +msgid "This token doesn't appear on the active token list(s). Make sure this is the token that you want to trade." +msgstr "Этот токен не отображается в активных списках токенов. Убедитесь, что это токен, который вы хотите торговать." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:89 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:164 +msgid "Import" +msgstr "Импорт" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/FilterSelector/FilterSelectorContent.tsx:26 +msgid "Status" +msgstr "Статус" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/FilterSelector/FilterSelectorContent.tsx:33 +#: widget/embedded/src/components/NoResult/NoResult.helpers.ts:37 +#: widget/embedded/src/pages/SettingsPage.tsx:55 +msgid "Reset" +msgstr "Reset" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/CancelButton.tsx:18 +msgid "Cancel" +msgstr "Отмена" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:46 +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:34 +msgid "Refresh" +msgstr "Обновить" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:63 +#: widget/ui/src/containers/Notifications/Notifications.tsx:35 +msgid "Notifications" +msgstr "Уведомления" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:79 +#: widget/embedded/src/pages/SettingsPage.tsx:38 +msgid "Settings" +msgstr "Настройки" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:93 +#: widget/embedded/src/pages/HistoryPage.tsx:139 +msgid "History" +msgstr "История" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/WalletButton.tsx:22 +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:16 +#: widget/embedded/src/constants/messages.ts:5 +msgid "Connect Wallet" +msgstr "Подключить кошелек" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HistoryGroupedList/HistoryGroupedList.tsx:118 +#: widget/embedded/src/utils/date.ts:18 +#: widget/embedded/src/utils/time.ts:22 +msgid "Today" +msgstr "Сегодня" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/LoadingSwapDetails/LoadingSwapDetails.tsx:20 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:424 +msgid "Swaps steps" +msgstr "Меняет шаги" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/NoResult/NoResult.helpers.ts:25 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:191 +msgid "Retry" +msgstr "Повторить" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:149 +msgid "Slippage Error" +msgstr "Ошибка проскальзывания" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:150 +msgid "Slippage Warning" +msgstr "Предупреждение проскальзывания" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:153 +msgid "Bridge Limit Error" +msgstr "Ошибка ограничения моста" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:240 +msgid "Yours: {amount} {symbol}" +msgstr "Ваши: {amount} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:261 +msgid "Minimum required slippage: {minRequiredSlippage}" +msgstr "Минимальное требуемое проскальзывание: {minRequiredSlippage}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:282 +msgid "Yours: {userSlippage}" +msgstr "Ваши: {userSlippage}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:395 +msgid "See All Routes" +msgstr "Посмотреть все маршруты" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:81 +msgid "View more info" +msgstr "Подробнее" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:91 +msgid "Gas & Fee Explanation" +msgstr "Объяснение газа и платы" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:107 +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:103 +msgid "Details" +msgstr "Детали" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:146 +msgid "Total Payable Fee" +msgstr "Общая оплата" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:166 +msgid "Hide non-payable fees" +msgstr "Скрыть неоплачиваемые комиссии" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:167 +msgid "Show non-payable fees" +msgstr "Показать неоплачиваемые сборы" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:177 +msgid "Description" +msgstr "Описание" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:181 +msgid "The following fees are considered in the transaction output and\n" +" you won’t need to pay extra gas for them." +msgstr "Следующие комиссии учитываются при выводе транзакций, и\n" +" вам не придется платить за них дополнительный газ." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteSummary.tsx:25 +msgid "Swap input" +msgstr "Swap input" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteSummary.tsx:44 +msgid "Estimated output" +msgstr "Приблизительный выход" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteTrigger.tsx:65 +msgid "Via:" +msgstr "Виа:" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteTrigger.tsx:150 +msgid "Chains:" +msgstr "Цепочки:" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/Quotes.tsx:77 +msgid "Sort by" +msgstr "Сортировать по" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:17 +msgid "Smart Routing" +msgstr "Умная маршрутизация" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:21 +msgid "Lowest Fee" +msgstr "Самая низкая комиссия" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:25 +msgid "Fastest Transfer" +msgstr "Быстрый перевод" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:29 +msgid "Maximum Return" +msgstr "Максимальный возврат" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:33 +msgid "Maximum Output" +msgstr "Максимальный вывод" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:43 +msgid "Swapping" +msgstr "Swapping" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:51 +msgid "Gas cost" +msgstr "Затраты газа" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:59 +msgid "Receiving" +msgstr "Получение" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:67 +msgid "Price impact" +msgstr "Влияние цены" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:35 +msgid "You need to increase slippage to at least {minRequiredSlippage} for this route." +msgstr "Вам нужно увеличить проскальзывание по крайней мере до {minRequiredSlippage} для этого маршрута." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:59 +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:61 +msgid "We recommend you to increase slippage to at least {minRequiredSlippage} for this route." +msgstr "Мы рекомендуем вам увеличить проскальзывание по крайней мере до {minRequiredSlippage} для этого маршрута." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:68 +msgid "Caution, your slippage is high." +msgstr "Внимание, ваше проскальзывание высоко." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.tsx:78 +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.Warning.tsx:26 +msgid "Change" +msgstr "Изменить" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:42 +msgid "Change settings" +msgstr "Изменить настройки" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:52 +msgid "High slippage" +msgstr "Высокое проскальзывание" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:53 +msgid "Low slippage" +msgstr "Низкое проскальзывание" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:57 +msgid " Caution, your slippage is high (={userSlippage}). Your trade may be front run." +msgstr " Внимание, высокая проскальзывание (={userSlippage}). Ваша сделка может быть переднего запуска." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:78 +msgid "Confirm anyway" +msgstr "Все равно подтвердить" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:22 +msgid "Something went wrong" +msgstr "Что-то пошло не так" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:24 +msgid "Something went wrong. Please refresh the app." +msgstr "Что-то пошло не так. Пожалуйста, обновите приложение." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/Slippage.tsx:38 +msgid "Slippage tolerance per swap" +msgstr "Допустимость проскальзывания на смену" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/Slippage.tsx:91 +msgid "Custom" +msgstr "Свой" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:11 +msgid "Your transaction will be reverted if the price changes unfavorably by more than this percentage." +msgstr "Ваша транзакция будет отменена, если цена изменится более чем на этот процент." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:16 +#: widget/embedded/src/containers/Settings/Lists.tsx:245 +msgid "Warning" +msgstr "Предупреждение" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:17 +msgid "This setting is applied to each step (e.g. 1Inch, Thorchain, etc.), meaning only that specific step will be reverted, not the entire route." +msgstr "Этот параметр применяется к каждому шагу (например, 1Inch, Thorchain и т.д.). Это означает, что только тот конкретный шаг будет обращен, а не весь маршрут." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:25 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:269 +msgid "Swap Details" +msgstr "Детали обмена" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:33 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:312 +msgid "Request ID" +msgstr "ID запроса" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:64 +msgid "Not found" +msgstr "Не найдено" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:65 +msgid "Swap with request ID = {requestId} not found." +msgstr "Поменять на ID запроса = {requestId} не найдено." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:219 +msgid "You have received {amount} {token} in {conciseAddress} wallet on {chain} chain." +msgstr "Вы получили {amount} {token} на {conciseAddress} кошельке на цепочке {chain}." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:242 +msgid "Transaction was not sent." +msgstr "Транзакция не отправлена." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:244 +msgid "{amount} {symbol} on {blockchain} remains in your wallet." +msgstr "{amount} {symbol} на {blockchain} остается в вашем кошельке." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:281 +msgid "Delete" +msgstr "Удалить" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:304 +msgid "Try again" +msgstr "Попробовать еще раз" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:322 +msgid "Copied To Clipboard" +msgstr "Скопировано в буфер обмена" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:323 +msgid "Copy Request ID" +msgstr "Копировать ID запроса" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:346 +msgid "View on Rango Explorer" +msgstr "Просмотр в проводнике Rango" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:355 +msgid "Finished at" +msgstr "Завершено в" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:355 +msgid "Created at" +msgstr "Создано в" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.tsx:50 +msgid "View transaction" +msgstr "Просмотр транзакции" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.Warning.tsx:49 +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:31 +msgid "Connect" +msgstr "Подключиться" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:43 +msgid "Swap Successful" +msgstr "Поменяно успешно" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:71 +msgid "Transaction Failed" +msgstr "Транзакция не удалась" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:87 +msgid "Done" +msgstr "Готово" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:100 +msgid "Diagnosis" +msgstr "Диагностика" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:112 +msgid "See Details" +msgstr "Подробнее" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:13 +msgid "Cancel Swap" +msgstr "Отменить замену" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:14 +msgid "Are you sure you want to cancel this swap?" +msgstr "Вы уверены, что хотите отменить этот обмен?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:23 +msgid "Yes, Cancel it" +msgstr "Да, отменить" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:32 +#: widget/embedded/src/pages/CustomTokensPage.tsx:181 +msgid "No, Continue" +msgstr "Нет, Продолжить" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:13 +msgid "Delete Transaction" +msgstr "Удалить транзакцию" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:14 +msgid "Are you sure you want to delete this swap?" +msgstr "Вы уверены, что хотите удалить эту замену?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:23 +#: widget/embedded/src/pages/CustomTokensPage.tsx:171 +msgid "Yes, Delete it" +msgstr "Да, удалить" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:33 +#: widget/embedded/src/pages/HistoryPage.tsx:253 +msgid "No, Cancel" +msgstr "Нет, отменить" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:12 +msgid "Change Network" +msgstr "Изменить сеть" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:20 +msgid "Network Changed" +msgstr "Сеть изменена" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/TokenList/TokenList.tsx:271 +#: widget/ui/src/containers/SwapInput/TokenSection.tsx:54 +msgid "Select Token" +msgstr "Выбрать токен" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:27 +msgid "Wallet Connected" +msgstr "Кошелек подключен" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:28 +msgid "Your wallet is connected, you can use it to swap." +msgstr "Ваш кошелек подключен, вы можете использовать его для смены." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:39 +msgid "Failed to Connect" +msgstr "Не удалось подключиться" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:41 +msgid "Your wallet is not connected. Please try again." +msgstr "Ваш кошелек не подключен. Пожалуйста, попробуйте еще раз." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:50 +msgid "Connecting to your wallet" +msgstr "Подключение к кошельку" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:51 +msgid "Click connect in your wallet popup." +msgstr "Нажмите на подключение во всплывающем окне кошелька." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:99 +msgid "Select Derivation Path" +msgstr "Выберите путь деривации" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:100 +msgid "In order to connect to {type}, you must first select a Derivation Path" +msgstr "Чтобы подключиться к {type}, вы должны сначала выбрать путь к производству." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:118 +msgid "Choose Derivation Path Template" +msgstr "Выберите шаблон пути деривации" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:133 +msgid "Enter Path" +msgstr "Введите путь" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:134 +msgid "Enter Index" +msgstr "Введите индекс" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:15 +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:18 +msgid "Add {blockchainDisplayName} Chain" +msgstr "Добавить цепочку {blockchainDisplayName}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:20 +msgid "Would you like to add the {blockchainDisplayName} experimental chain to your wallet?" +msgstr "Добавить экспериментальную цепочку {blockchainDisplayName} в ваш кошелек?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:22 +msgid "Please approve the experimental chain pop-up in your wallet." +msgstr "Пожалуйста, подтвердите окно экспериментальной цепочки в вашем кошельке." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:30 +msgid "{blockchainDisplayName} Chain Added" +msgstr "{blockchainDisplayName} цепочка добавлена" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:34 +msgid "The {blockchainDisplayName} chain has been successfully added to your wallet." +msgstr "Цепочка {blockchainDisplayName} успешно добавлена в ваш кошелек." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:42 +msgid "Request Rejected" +msgstr "Запрос отклонен" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:43 +msgid "You've rejected adding {blockchainDisplayName} chain to your wallet." +msgstr "Вы отклонили добавление цепочки {blockchainDisplayName} в ваш кошелек." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:70 +msgid "Select chain types" +msgstr "Выберите типы цепочки" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:71 +msgid "This wallet supports multiple chains. Select which chain you'd like to connect to." +msgstr "Этот кошелек поддерживает несколько цепок. Выберите, к какой цепочке вы хотите подключиться." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:9 +msgid "Failed Network, Please retry your swap." +msgstr "Неудачная сеть, повторите замену." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:11 +msgid "Please reset your liquidity sources." +msgstr "Пожалуйста, сбросьте источники ликвидности." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:12 +msgid "You have limited the liquidity sources and this might result in Rango finding no routes. Please consider resetting your liquidity sources." +msgstr "Вы ограничены источниками ликвидности, и это может привести к Rango не найти маршрутов. Пожалуйста, подумайте о сбросе ваших источников ликвидности." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:17 +msgid "No Routes Found." +msgstr "Маршруты не найдены." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:18 +msgid "Reasons why Rango couldn't find a route: low liquidity on token, very low input amount or no routes available for the selected input/output token combination." +msgstr "Причины почему Rango не смог найти маршрут: низкая ликвидность на токене, очень низкая сумма ввода или нет маршрутов для выбранной комбинации токена ввода/вывода." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:23 +msgid "Bridge Limit Error: Please increase your amount." +msgstr "Ошибка лимита моста: Пожалуйста, увеличьте сумму." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:26 +msgid "Bridge Limit Error: Please decrease your amount." +msgstr "Ошибка лимита мостов. Пожалуйста, уменьшите сумму." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:31 +msgid "High Price Impact" +msgstr "Влияние высокой цены" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:32 +msgid "Price impact is too high!" +msgstr "Слишком большое влияние на цену!" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:33 +msgid "The price impact is significantly higher than the allowed amount." +msgstr "Влияние на цены значительно выше, чем разрешенная сумма." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:36 +msgid "Confirm high price impact" +msgstr "Подтвердите влияние высокой цены" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:39 +msgid "Route updated and price impact is too high, try again later!" +msgstr "Маршрут обновлён и цена слишком высока, попробуйте позже!" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:44 +msgid "USD Price Unknown" +msgstr "Цена USD неизвестна" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:45 +msgid "USD Price Unknown, Cannot calculate Price Impact." +msgstr "USD Цена неизвестна, невозможно рассчитать влияние на цену." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:46 +msgid "USD Price Unknown, Cannot calculate Price Impact. The price impact may be higher than usual. Are you sure to continue the Swap?" +msgstr "USD Цена неизвестна, невозможно рассчитать влияние на цену. Воздействие на цену может быть выше, чем обычно. Вы уверены, что хотите продолжить?" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:49 +msgid "Confirm USD Price Unknown" +msgstr "Подтвердите неизвестную цену в USD" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:6 +#: widget/embedded/src/pages/Home.tsx:163 +msgid "Swap" +msgstr "Поменять" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:7 +msgid "Swap anyway" +msgstr "Все равно поменять" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:8 +msgid "The route goes through Ethereum. Continue?" +msgstr "Маршрут проходит через Ethereum. Продолжить?" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:10 +msgid "Route has been updated." +msgstr "Маршрут был обновлен." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:12 +msgid "Output amount changed to {newOutputAmount} ({percentageChange}% change)." +msgstr "Сумма вывода изменена на {newOutputAmount} ({percentageChange}% изменено)." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:20 +msgid "Route swappers has been updated." +msgstr "Маршрут обмена был обновлен." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:22 +msgid "Route internal coins has been updated." +msgstr "Внутренние монеты маршрута обновлены." + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/ExpandedQuotes/ExpandedQuotes.tsx:53 +#: widget/embedded/src/pages/Routes.tsx:48 +msgid "Routes" +msgstr "Маршруты" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Inputs/Inputs.tsx:76 +msgid "From" +msgstr "От" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Inputs/Inputs.tsx:118 +msgid "To" +msgstr "Кому" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:49 +msgid "Light" +msgstr "Светлая" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:58 +msgid "Dark" +msgstr "Тёмная" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:67 +msgid "Auto" +msgstr "Авто" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:140 +msgid "Loading failed" +msgstr "Не удалось загрузить" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:156 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:41 +msgid "Bridges" +msgstr "Мосты" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:174 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:41 +msgid "Exchanges" +msgstr "Обмены" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:195 +#: widget/embedded/src/pages/CustomTokensPage.tsx:90 +msgid "Custom Tokens" +msgstr "Пользовательские токены" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:214 +#: widget/embedded/src/pages/LanguagePage.tsx:43 +msgid "Language" +msgstr "Язык" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:235 +msgid "Infinite approval" +msgstr "Бесконечное одобрение" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:246 +msgid "Enabling the 'Infinite approval' mode grants unrestricted access to underlying smart contracts, allowing them to utilize the approved token amount without limitations." +msgstr "Включение режима \"Бесконечное одобрение\" предоставляет неограниченный доступ к основным смарт-контрактам, позволяя им использовать одобренную сумму токена без ограничений." + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:266 +msgid "Theme" +msgstr "Тема" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:39 +msgid "Duplicate Token" +msgstr "Duplicate Token" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:40 +msgid "The address you entered is duplicate, please enter a new address." +msgstr "Введенный вами адрес дублируется, пожалуйста, введите новый адрес." + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:46 +msgid "Token Already Exists" +msgstr "Токен уже существует" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:47 +msgid "There's no need to add this token again because it already exists and is supported by us." +msgstr "Не нужно добавлять этот токен снова, потому что он уже существует и поддерживается нами." + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:53 +msgid "Token Not Found" +msgstr "Токен не найден" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:54 +msgid "Sorry, no token was found on {blockchain} chain with the provided address. please make sure you have entered the right token address." +msgstr "К сожалению, по цепочке {blockchain} не найдено токенов. Пожалуйста, убедитесь, что вы ввели правильный адрес токена." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:78 +msgid "Network Error" +msgstr "Ошибка сети" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:109 +#: widget/embedded/src/pages/CustomTokensPage.tsx:149 +msgid "Add Custom Token" +msgstr "Добавить пользовательский токен" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:127 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:128 +msgid "Select chain" +msgstr "Выберите цепочку" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:132 +msgid "Enter Address" +msgstr "Введите адрес" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:139 +msgid "Enter token address" +msgstr "Введите адрес токена" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:176 +msgid "Failed Network, Please retry." +msgstr "Ошибка сети, повторите попытку." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:192 +msgid "Add another custom token" +msgstr "Добавить другой пользовательский токен" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:236 +msgid "Confirm Swap" +msgstr "Подтверждение смены" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:254 +msgid "Start Swap" +msgstr "Начать обмен" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:282 +msgid "You get" +msgstr "Вы получаете" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:102 +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:90 +msgid "Search Token" +msgstr "Поиск токена" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:134 +msgid "No custom tokens" +msgstr "Нет пользовательских токенов" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:135 +msgid "press the button to add your custom token" +msgstr "нажмите кнопку, чтобы добавить свой пользовательский токен" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:158 +msgid "Delete Custom Token" +msgstr "Удалить пользовательский токен" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:160 +msgid "Are you sure you want to Delete this Token?" +msgstr "Вы уверены, что хотите удалить этот токен?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:59 +msgid "Complete" +msgstr "Complete" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:63 +msgid "Running" +msgstr "Выполняется" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:65 +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:8 +msgid "Failed" +msgstr "Неудачный" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:149 +msgid "Clear" +msgstr "Очистить" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:161 +msgid "Search Transaction" +msgstr "Поиск транзакций" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:187 +msgid "No transactions" +msgstr "Нет транзакций" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:194 +msgid "Your transaction history is stored locally and will appear here after you start a swap" +msgstr "Ваша история транзакций хранится локально и появится здесь после запуска обмена" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:218 +msgid "Clear Transaction History" +msgstr "Очистить историю транзакций" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:222 +msgid "Proceeding will remove all successful and failed transactions from the widget. Do you want to continue?" +msgstr "В процессе обработки все успешные и неудачные транзакции из виджета. Вы хотите продолжить?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:229 +msgid "Note: This does not erase your transaction history on the chain; it only removes them here." +msgstr "Примечание: Это не очищает историю транзакций в цепочке; она только удаляет их здесь." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:243 +msgid "Yes, Clear the history" +msgstr "Да, очистить историю" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LanguagePage.tsx:56 +msgid "language" +msgstr "язык" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:121 +msgid "Deselect all" +msgstr "Отменить выбор" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:121 +msgid "Select all" +msgstr "Выбрать все" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:133 +msgid "Search {sourceType}" +msgstr "Искать {sourceType}" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectBlockchainPage.tsx:60 +msgid "Search Chain" +msgstr "Поиск цепочки" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:67 +msgid "Source" +msgstr "Источник" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:68 +msgid "Destination" +msgstr "Назначение" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:74 +msgid "Swap {type}" +msgstr "Поменять на {type}" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SettingsPage.tsx:45 +msgid "Currently, you're in campaign mode with restrictions on liquidity sources. Would you like to switch out of this mode and make use of all available liquidity sources?" +msgstr "В настоящее время вы находитесь в режиме кампании с ограничениями на источники ликвидности. Выключить этот режим и использовать все доступные источники ликвидности?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SwapDetailsPage.tsx:27 +msgid "The request ID is necessary to display the swap details." +msgstr "Идентификатор запроса необходим для отображения сведений о swap." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/WalletsPage.tsx:67 +#: widget/ui/src/containers/ConnectWalletsModal/ConnectWalletsModal.tsx:15 +msgid "Connect Wallets" +msgstr "Подключить кошельки" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/WalletsPage.tsx:82 +msgid "Choose a wallet to connect." +msgstr "Выберите кошелек для подключения." + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:25 +msgid "This week" +msgstr "Эта неделя" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:32 +msgid "This month" +msgstr "Этот месяц" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:39 +msgid "This year" +msgstr "В этом году" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:129 +msgid "Required: >= {min} {symbol}" +msgstr "Обязательный: >= {min} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:142 +msgid "Required: > {min} {symbol}" +msgstr "Обязательный: > {min} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:157 +msgid "Required: <= {max} {symbol}" +msgstr "Обязательный: <= {max} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:170 +msgid "Required: < {max} {symbol}" +msgstr "Обязательный: < {max} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:601 +msgid " for network fee" +msgstr " за комиссию сети" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:604 +msgid " for swap" +msgstr " для подкачки" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:607 +msgid " for input and network fee" +msgstr " за ввод и сетевой сбор" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:609 +msgid "Needs ≈ {requiredAmount} {symbol}{reason}, but you have {currentAmount} {symbol} in your {blockchain} wallet." +msgstr "Нужно {requiredAmount} {symbol}{reason}, но у вас есть {currentAmount} {symbol} в кошельке {blockchain}." + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:669 +msgid "Waiting for connecting wallet" +msgstr "Ожидание подключения кошелька" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:673 +msgid "Waiting for other running tasks to be finished" +msgstr "Ожидание завершения других запущенных задач" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:676 +msgid "Waiting for changing wallet network" +msgstr "Ожидание изменения сети кошелька" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:6 +msgid "Sunday" +msgstr "Воскресенье" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:7 +msgid "Monday" +msgstr "Понедельник" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:8 +msgid "Tuesday" +msgstr "Вторник" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:9 +msgid "Wednesday" +msgstr "Среда" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:10 +msgid "Thursday" +msgstr "Четверг" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:11 +msgid "Friday" +msgstr "Пятница" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:12 +msgid "Saturday" +msgstr "Суббота" + +#. js-lingui-explicit-id +#: widget/ui/src/components/BottomLogo/BottomLogo.tsx:14 +msgid "Powered By" +msgstr "Работает на" + +#. js-lingui-explicit-id +#: widget/ui/src/components/FullExpandedQuote/FullExpandedQuote.Tooltip.tsx:37 +msgid "Aggregated Transaction" +msgstr "Агрегированная проводка" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SelectableCategoryList/SelectableCategoryList.tsx:63 +msgid "{blockchainCategory}" +msgstr "{blockchainCategory}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/StepDetails/StepDetails.tsx:75 +#: widget/ui/src/components/StepDetails/StepDetails.tsx:102 +msgid "Swap on {fromChain} via {swapper}" +msgstr "Поменять на {fromChain} через {swapper}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/StepDetails/StepDetails.tsx:109 +msgid "Bridge to {toChain} via {swapper}" +msgstr "Мост к {toChain} через {swapper}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:10 +msgid "Completed" +msgstr "Выполнено" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:12 +msgid "In progress" +msgstr "В процессе" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapToken.tsx:122 +msgid "Waiting for bridge transaction" +msgstr "Ожидание транзакции по мосту" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:12 +msgid "Connected" +msgstr "Подключено" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:13 +msgid "Disconnect" +msgstr "Отключиться" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:18 +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:19 +msgid "Install" +msgstr "Установить" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:24 +msgid "Connecting ..." +msgstr "Подключение..." + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:25 +msgid "Connecting" +msgstr "Подключение" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:30 +msgid "Disconnected" +msgstr "Отключено" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:34 +msgid "you need to pass a correct state to Wallet." +msgstr "необходимо передать Кошельку правильное состояние." + +#. js-lingui-explicit-id +#: widget/ui/src/containers/Notifications/NotificationNotFound.tsx:15 +msgid "There are no notifications." +msgstr "Нет уведомлений." + +#. js-lingui-explicit-id +#: widget/ui/src/containers/Notifications/Notifications.tsx:39 +msgid "Clear all" +msgstr "Очистить все" + +#. js-lingui-explicit-id +#: widget/ui/src/containers/SwapInput/SwapInput.tsx:65 +msgid "Balance" +msgstr "Баланс" + +#. js-lingui-explicit-id +#: widget/ui/src/containers/SwapInput/SwapInput.tsx:73 +msgid "Max" +msgstr "Макс" + diff --git a/translations/sk.po b/translations/sk.po new file mode 100644 index 0000000000..9d353bd3c2 --- /dev/null +++ b/translations/sk.po @@ -0,0 +1,1339 @@ +msgid "" +msgstr "" +"POT-Creation-Date: 2023-11-06 17:24+0330\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: @lingui/cli\n" +"Language: sk\n" +"Project-Id-Version: rango\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2024-11-27 15:57\n" +"Last-Translator: \n" +"Language-Team: Slovak\n" +"Plural-Forms: nplurals=4; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 3;\n" +"X-Crowdin-Project: rango\n" +"X-Crowdin-Project-ID: 622238\n" +"X-Crowdin-Language: sk\n" +"X-Crowdin-File: en.po\n" +"X-Crowdin-File-ID: 30\n" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SameTokensWarning/SameTokensWarning.tsx:21 +msgid "No Routes Found" +msgstr "Nenašli sa žiadne trasy" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SameTokensWarning/SameTokensWarning.tsx:25 +msgid "You cannot use the same token for From and To." +msgstr "Nemôžete použiť rovnaký token pre položky From a To." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:41 +#: widget/embedded/src/components/TokenList/TokenList.tsx:286 +#: widget/embedded/src/pages/HistoryPage.tsx:186 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:143 +msgid "No results found" +msgstr "Nenašli sa žiadne výsledky" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:42 +#: widget/embedded/src/components/TokenList/TokenList.tsx:287 +#: widget/embedded/src/pages/HistoryPage.tsx:193 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:144 +msgid "Try using different keywords" +msgstr "Skúste použiť iné kľúčové slová" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:72 +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:46 +#: widget/embedded/src/pages/SelectBlockchainPage.tsx:42 +#: widget/ui/src/containers/SwapInput/TokenSection.tsx:61 +msgid "Select Chain" +msgstr "Vyberte položku Reťaz" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:66 +msgid "All" +msgstr "Všetky" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:100 +msgid "More +{count}" +msgstr "Viac +{count}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabAlert/ActivateTabAlert.tsx:17 +msgid "Activate this tab" +msgstr "Aktivujte túto kartu" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabAlert/ActivateTabAlert.tsx:22 +msgid "Another tab is open and handles transactions." +msgstr "Ďalšia karta je otvorená a spracováva transakcie." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:20 +msgid "Activate current tab" +msgstr "Aktivovať aktuálnu kartu" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:22 +msgid "Currently, some transactions are running and being handled by other browser tab. If you activate this tab, all transactions that are already in the transaction sign step will expire." +msgstr "V súčasnosti sú niektoré transakcie spustené a spracovávané inou kartou prehliadača. Ak aktivujete túto kartu, platnosť všetkých transakcií, ktoré sa už nachádzajú v kroku podpisu transakcie, vyprší." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:33 +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:349 +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:152 +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:33 +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:116 +msgid "Confirm" +msgstr "Potvrďte" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:365 +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:447 +msgid "Your {blockchainName} wallets" +msgstr "Vaše {blockchainName} peňaženky" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:384 +msgid "Insufficient account balance" +msgstr "Nedostatočný zostatok na účte" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:394 +msgid "Proceed anyway" +msgstr "Aj tak pokračujte" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:456 +msgid "You need to connect a {blockchainName} wallet." +msgstr "Musíte pripojiť {blockchainName} peňaženku." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/WalletList.tsx:143 +msgid "Add {chain} chain" +msgstr "Pridajte reťazec {chain}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/WalletList.tsx:244 +msgid "Show more wallets" +msgstr "Zobraziť viac peňaženiek" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:113 +msgid "Send to a different address" +msgstr "Odoslať na inú adresu" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:129 +msgid "Enter {blockchainName} address" +msgstr "Zadajte {blockchainName} adresu" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:147 +msgid "Address {destination} doesn't match the blockchain address pattern." +msgstr "Adresa {destination} sa nezhoduje so vzorom adresy blockchain." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:59 +msgid "via" +msgstr "cez" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:74 +msgid "This token doesn't appear on the active token list(s). Make sure this is the token that you want to trade." +msgstr "Tento token sa nezobrazuje v aktívnych zoznamoch tokenov. Uistite sa, že ide o token, s ktorým chcete obchodovať." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:89 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:164 +msgid "Import" +msgstr "Importovať" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/FilterSelector/FilterSelectorContent.tsx:26 +msgid "Status" +msgstr "Stav" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/FilterSelector/FilterSelectorContent.tsx:33 +#: widget/embedded/src/components/NoResult/NoResult.helpers.ts:37 +#: widget/embedded/src/pages/SettingsPage.tsx:55 +msgid "Reset" +msgstr "Resetovať" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/CancelButton.tsx:18 +msgid "Cancel" +msgstr "Zrušiť" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:46 +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:34 +msgid "Refresh" +msgstr "Obnoviť" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:63 +#: widget/ui/src/containers/Notifications/Notifications.tsx:35 +msgid "Notifications" +msgstr "Upozornenia" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:79 +#: widget/embedded/src/pages/SettingsPage.tsx:38 +msgid "Settings" +msgstr "Nastavenia" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:93 +#: widget/embedded/src/pages/HistoryPage.tsx:139 +msgid "History" +msgstr "História" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/WalletButton.tsx:22 +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:16 +#: widget/embedded/src/constants/messages.ts:5 +msgid "Connect Wallet" +msgstr "Pripojiť Peňaženku" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HistoryGroupedList/HistoryGroupedList.tsx:118 +#: widget/embedded/src/utils/date.ts:18 +#: widget/embedded/src/utils/time.ts:22 +msgid "Today" +msgstr "Dnes" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/LoadingSwapDetails/LoadingSwapDetails.tsx:20 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:424 +msgid "Swaps steps" +msgstr "Vymieňa kroky" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/NoResult/NoResult.helpers.ts:25 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:191 +msgid "Retry" +msgstr "Skúste to znova" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:149 +msgid "Slippage Error" +msgstr "Chyba sklzu" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:150 +msgid "Slippage Warning" +msgstr "Upozornenie na sklz" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:153 +msgid "Bridge Limit Error" +msgstr "Chyba limitu mosta" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:240 +msgid "Yours: {amount} {symbol}" +msgstr "Váš: {amount} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:261 +msgid "Minimum required slippage: {minRequiredSlippage}" +msgstr "Minimálny požadovaný sklz: {minRequiredSlippage}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:282 +msgid "Yours: {userSlippage}" +msgstr "Váš: {userSlippage}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:395 +msgid "See All Routes" +msgstr "Pozrite si všetky trasy" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:81 +msgid "View more info" +msgstr "Zobraziť viac informácií" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:91 +msgid "Gas & Fee Explanation" +msgstr "Vysvetlenie plynu a poplatkov" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:107 +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:103 +msgid "Details" +msgstr "Podrobnosti" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:146 +msgid "Total Payable Fee" +msgstr "Celkový splatný poplatok" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:166 +msgid "Hide non-payable fees" +msgstr "Skryť neplatiteľné poplatky" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:167 +msgid "Show non-payable fees" +msgstr "Ukážte nezaplatiteľné poplatky" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:177 +msgid "Description" +msgstr "Popis" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:181 +msgid "The following fees are considered in the transaction output and\n" +" you won’t need to pay extra gas for them." +msgstr "Nasledujúce poplatky sú zohľadnené vo výstupe transakcie a\n" +" za ne nebudete musieť platiť extra plyn." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteSummary.tsx:25 +msgid "Swap input" +msgstr "Vymeňte vstup" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteSummary.tsx:44 +msgid "Estimated output" +msgstr "Odhadovaný výstup" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteTrigger.tsx:65 +msgid "Via:" +msgstr "cez:" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteTrigger.tsx:150 +msgid "Chains:" +msgstr "reťaze:" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/Quotes.tsx:77 +msgid "Sort by" +msgstr "Zoradiť podľa" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:17 +msgid "Smart Routing" +msgstr "Inteligentné smerovanie" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:21 +msgid "Lowest Fee" +msgstr "Najnižší poplatok" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:25 +msgid "Fastest Transfer" +msgstr "Najrýchlejší prevod" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:29 +msgid "Maximum Return" +msgstr "Maximálna návratnosť" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:33 +msgid "Maximum Output" +msgstr "Maximálny výkon" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:43 +msgid "Swapping" +msgstr "Výmena" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:51 +msgid "Gas cost" +msgstr "Náklady na plyn" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:59 +msgid "Receiving" +msgstr "Prijímanie" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:67 +msgid "Price impact" +msgstr "Vplyv na cenu" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:35 +msgid "You need to increase slippage to at least {minRequiredSlippage} for this route." +msgstr "Pre túto trasu musíte zvýšiť sklz aspoň na {minRequiredSlippage} ." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:59 +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:61 +msgid "We recommend you to increase slippage to at least {minRequiredSlippage} for this route." +msgstr "Na tejto trase vám odporúčame zvýšiť sklz aspoň na {minRequiredSlippage} ." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:68 +msgid "Caution, your slippage is high." +msgstr "Pozor, váš sklz je vysoký." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.tsx:78 +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.Warning.tsx:26 +msgid "Change" +msgstr "Zmeniť" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:42 +msgid "Change settings" +msgstr "Zmeňte nastavenia" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:52 +msgid "High slippage" +msgstr "Vysoký sklz" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:53 +msgid "Low slippage" +msgstr "Nízky sklz" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:57 +msgid " Caution, your slippage is high (={userSlippage}). Your trade may be front run." +msgstr " Pozor, váš sklz je vysoký (={userSlippage}). Váš obchod môže byť front run." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:78 +msgid "Confirm anyway" +msgstr "Napriek tomu potvrďte" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:22 +msgid "Something went wrong" +msgstr "Niečo sa pokazilo" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:24 +msgid "Something went wrong. Please refresh the app." +msgstr "Niečo sa pokazilo. Obnovte aplikáciu." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/Slippage.tsx:38 +msgid "Slippage tolerance per swap" +msgstr "Tolerancia sklzu na výmenu" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/Slippage.tsx:91 +msgid "Custom" +msgstr "Vlastné" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:11 +msgid "Your transaction will be reverted if the price changes unfavorably by more than this percentage." +msgstr "Vaša transakcia bude vrátená, ak sa cena nepriaznivo zmení o viac ako toto percento." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:16 +#: widget/embedded/src/containers/Settings/Lists.tsx:245 +msgid "Warning" +msgstr "POZOR" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:17 +msgid "This setting is applied to each step (e.g. 1Inch, Thorchain, etc.), meaning only that specific step will be reverted, not the entire route." +msgstr "Toto nastavenie sa aplikuje na každý krok (napr. 1Inch, Thorchain atď.), čo znamená, že sa vráti iba tento konkrétny krok, nie celá trasa." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:25 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:269 +msgid "Swap Details" +msgstr "Podrobnosti o výmene" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:33 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:312 +msgid "Request ID" +msgstr "ID žiadosti" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:64 +msgid "Not found" +msgstr "Nenájdené" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:65 +msgid "Swap with request ID = {requestId} not found." +msgstr "Zámena s ID požiadavky = {requestId} sa nenašla." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:219 +msgid "You have received {amount} {token} in {conciseAddress} wallet on {chain} chain." +msgstr "Dostali ste {amount} {token} do {conciseAddress} peňaženky v reťazci {chain} ." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:242 +msgid "Transaction was not sent." +msgstr "Transakcia nebola odoslaná." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:244 +msgid "{amount} {symbol} on {blockchain} remains in your wallet." +msgstr "{amount} {symbol} na {blockchain} zostáva vo vašej peňaženke." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:281 +msgid "Delete" +msgstr "Odstrániť" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:304 +msgid "Try again" +msgstr "Skúste to znova" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:322 +msgid "Copied To Clipboard" +msgstr "Skopírované do schránky" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:323 +msgid "Copy Request ID" +msgstr "Skopírovať ID žiadosti" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:346 +msgid "View on Rango Explorer" +msgstr "Zobraziť na Rango Explorer" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:355 +msgid "Finished at" +msgstr "Dokončené o" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:355 +msgid "Created at" +msgstr "Vytvorené o" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.tsx:50 +msgid "View transaction" +msgstr "Zobraziť transakciu" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.Warning.tsx:49 +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:31 +msgid "Connect" +msgstr "Pripojte sa" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:43 +msgid "Swap Successful" +msgstr "Výmena bola úspešná" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:71 +msgid "Transaction Failed" +msgstr "Transakcia zlyhala" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:87 +msgid "Done" +msgstr "Hotovo" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:100 +msgid "Diagnosis" +msgstr "Diagnóza" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:112 +msgid "See Details" +msgstr "Pozri Podrobnosti" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:13 +msgid "Cancel Swap" +msgstr "Zrušiť výmenu" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:14 +msgid "Are you sure you want to cancel this swap?" +msgstr "Naozaj chcete zrušiť túto výmenu?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:23 +msgid "Yes, Cancel it" +msgstr "Áno, zrušiť" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:32 +#: widget/embedded/src/pages/CustomTokensPage.tsx:181 +msgid "No, Continue" +msgstr "Nie, pokračovať" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:13 +msgid "Delete Transaction" +msgstr "Odstrániť transakciu" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:14 +msgid "Are you sure you want to delete this swap?" +msgstr "Naozaj chcete odstrániť túto výmenu?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:23 +#: widget/embedded/src/pages/CustomTokensPage.tsx:171 +msgid "Yes, Delete it" +msgstr "Áno, vymazať" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:33 +#: widget/embedded/src/pages/HistoryPage.tsx:253 +msgid "No, Cancel" +msgstr "Nie, zrušiť" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:12 +msgid "Change Network" +msgstr "Zmeniť sieť" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:20 +msgid "Network Changed" +msgstr "Sieť zmenená" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/TokenList/TokenList.tsx:271 +#: widget/ui/src/containers/SwapInput/TokenSection.tsx:54 +msgid "Select Token" +msgstr "Vyberte položku Token" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:27 +msgid "Wallet Connected" +msgstr "Peňaženka je pripojená" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:28 +msgid "Your wallet is connected, you can use it to swap." +msgstr "Vaša peňaženka je pripojená, môžete ju použiť na výmenu." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:39 +msgid "Failed to Connect" +msgstr "Nepodarilo sa pripojiť" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:41 +msgid "Your wallet is not connected. Please try again." +msgstr "Vaša peňaženka nie je pripojená. Skúste to znova." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:50 +msgid "Connecting to your wallet" +msgstr "Pripojenie k vašej peňaženke" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:51 +msgid "Click connect in your wallet popup." +msgstr "Vo vyskakovacom okne peňaženky kliknite na Pripojiť." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:99 +msgid "Select Derivation Path" +msgstr "Vyberte cestu odvodenia" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:100 +msgid "In order to connect to {type}, you must first select a Derivation Path" +msgstr "Ak sa chcete pripojiť k {type}, musíte najprv vybrať cestu odvodenia" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:118 +msgid "Choose Derivation Path Template" +msgstr "Vyberte možnosť Šablóna odvodenej cesty" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:133 +msgid "Enter Path" +msgstr "Zadajte cestu" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:134 +msgid "Enter Index" +msgstr "Zadajte index" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:15 +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:18 +msgid "Add {blockchainDisplayName} Chain" +msgstr "Pridajte reťazec {blockchainDisplayName}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:20 +msgid "Would you like to add the {blockchainDisplayName} experimental chain to your wallet?" +msgstr "Chceli by ste do svojej peňaženky pridať experimentálny reťazec {blockchainDisplayName} ?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:22 +msgid "Please approve the experimental chain pop-up in your wallet." +msgstr "Schváľte kontextové okno experimentálneho reťazca vo vašej peňaženke." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:30 +msgid "{blockchainDisplayName} Chain Added" +msgstr "{blockchainDisplayName} Pridaný reťazec" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:34 +msgid "The {blockchainDisplayName} chain has been successfully added to your wallet." +msgstr "Reťazec {blockchainDisplayName} bol úspešne pridaný do vašej peňaženky." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:42 +msgid "Request Rejected" +msgstr "Žiadosť zamietnutá" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:43 +msgid "You've rejected adding {blockchainDisplayName} chain to your wallet." +msgstr "Odmietli ste pridať reťazec {blockchainDisplayName} do vašej peňaženky." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:70 +msgid "Select chain types" +msgstr "Vyberte typy reťazí" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:71 +msgid "This wallet supports multiple chains. Select which chain you'd like to connect to." +msgstr "Táto peňaženka podporuje viacero reťazí. Vyberte reťazec, ku ktorému sa chcete pripojiť." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:9 +msgid "Failed Network, Please retry your swap." +msgstr "Sieť zlyhala, skúste výmenu zopakovať." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:11 +msgid "Please reset your liquidity sources." +msgstr "Obnovte zdroje likvidity." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:12 +msgid "You have limited the liquidity sources and this might result in Rango finding no routes. Please consider resetting your liquidity sources." +msgstr "Obmedzili ste zdroje likvidity a to môže viesť k tomu, že Rango nenájde žiadne cesty. Zvážte resetovanie zdrojov likvidity." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:17 +msgid "No Routes Found." +msgstr "Nenašli sa žiadne trasy." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:18 +msgid "Reasons why Rango couldn't find a route: low liquidity on token, very low input amount or no routes available for the selected input/output token combination." +msgstr "Dôvody, prečo Rango nemohol nájsť cestu: nízka likvidita tokenu, veľmi nízka vstupná suma alebo žiadne dostupné cesty pre zvolenú kombináciu vstupných/výstupných tokenov." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:23 +msgid "Bridge Limit Error: Please increase your amount." +msgstr "Chyba limitu mosta: Zvýšte svoju sumu." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:26 +msgid "Bridge Limit Error: Please decrease your amount." +msgstr "Chyba limitu mosta: Znížte sumu." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:31 +msgid "High Price Impact" +msgstr "Vysoký vplyv na cenu" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:32 +msgid "Price impact is too high!" +msgstr "Vplyv na cenu je príliš vysoký!" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:33 +msgid "The price impact is significantly higher than the allowed amount." +msgstr "Cenový vplyv je výrazne vyšší ako povolená suma." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:36 +msgid "Confirm high price impact" +msgstr "Potvrďte vysoký cenový vplyv" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:39 +msgid "Route updated and price impact is too high, try again later!" +msgstr "Trasa bola aktualizovaná a vplyv na cenu je príliš vysoký, skúste to znova neskôr!" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:44 +msgid "USD Price Unknown" +msgstr "Cena v USD neznáma" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:45 +msgid "USD Price Unknown, Cannot calculate Price Impact." +msgstr "Cena v USD nie je známa, vplyv na cenu sa nedá vypočítať." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:46 +msgid "USD Price Unknown, Cannot calculate Price Impact. The price impact may be higher than usual. Are you sure to continue the Swap?" +msgstr "Cena v USD nie je známa, nie je možné vypočítať vplyv na cenu. Cenový vplyv môže byť vyšší ako zvyčajne. Naozaj chcete pokračovať vo výmene?" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:49 +msgid "Confirm USD Price Unknown" +msgstr "Potvrdenie ceny v USD nie je známe" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:6 +#: widget/embedded/src/pages/Home.tsx:163 +msgid "Swap" +msgstr "Vymeňte" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:7 +msgid "Swap anyway" +msgstr "Aj tak vymeniť" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:8 +msgid "The route goes through Ethereum. Continue?" +msgstr "Trasa vedie cez Ethereum. Pokračovať?" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:10 +msgid "Route has been updated." +msgstr "Trasa bola aktualizovaná." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:12 +msgid "Output amount changed to {newOutputAmount} ({percentageChange}% change)." +msgstr "Výstupné množstvo zmenené na {newOutputAmount} ({percentageChange}% zmena)." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:20 +msgid "Route swappers has been updated." +msgstr "Výmenníky trás boli aktualizované." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:22 +msgid "Route internal coins has been updated." +msgstr "Trasa interných mincí bola aktualizovaná." + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/ExpandedQuotes/ExpandedQuotes.tsx:53 +#: widget/embedded/src/pages/Routes.tsx:48 +msgid "Routes" +msgstr "Trasy" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Inputs/Inputs.tsx:76 +msgid "From" +msgstr "Od" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Inputs/Inputs.tsx:118 +msgid "To" +msgstr "Komu" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:49 +msgid "Light" +msgstr "Svetlo" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:58 +msgid "Dark" +msgstr "Tmavý" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:67 +msgid "Auto" +msgstr "Auto" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:140 +msgid "Loading failed" +msgstr "Načítanie zlyhalo" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:156 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:41 +msgid "Bridges" +msgstr "Mosty" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:174 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:41 +msgid "Exchanges" +msgstr "Výmeny" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:195 +#: widget/embedded/src/pages/CustomTokensPage.tsx:90 +msgid "Custom Tokens" +msgstr "Vlastné tokeny" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:214 +#: widget/embedded/src/pages/LanguagePage.tsx:43 +msgid "Language" +msgstr "Jazyk" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:235 +msgid "Infinite approval" +msgstr "Nekonečný súhlas" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:246 +msgid "Enabling the 'Infinite approval' mode grants unrestricted access to underlying smart contracts, allowing them to utilize the approved token amount without limitations." +msgstr "Povolenie režimu „Nekonečné schválenie“ poskytuje neobmedzený prístup k základným inteligentným zmluvám, čo im umožňuje využívať schválenú sumu tokenu bez obmedzení." + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:266 +msgid "Theme" +msgstr "Téma" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:39 +msgid "Duplicate Token" +msgstr "Duplicitný token" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:40 +msgid "The address you entered is duplicate, please enter a new address." +msgstr "Zadaná adresa je duplicitná, zadajte novú adresu." + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:46 +msgid "Token Already Exists" +msgstr "Token už existuje" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:47 +msgid "There's no need to add this token again because it already exists and is supported by us." +msgstr "Tento token nie je potrebné znova pridávať, pretože už existuje a je nami podporovaný." + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:53 +msgid "Token Not Found" +msgstr "Token sa nenašiel" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:54 +msgid "Sorry, no token was found on {blockchain} chain with the provided address. please make sure you have entered the right token address." +msgstr "Ľutujeme, v reťazci {blockchain} so zadanou adresou sa nenašiel žiadny token. uistite sa, že ste zadali správnu adresu tokenu." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:78 +msgid "Network Error" +msgstr "Chyba siete" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:109 +#: widget/embedded/src/pages/CustomTokensPage.tsx:149 +msgid "Add Custom Token" +msgstr "Pridať vlastný token" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:127 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:128 +msgid "Select chain" +msgstr "Vyberte reťaz" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:132 +msgid "Enter Address" +msgstr "Zadajte adresu" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:139 +msgid "Enter token address" +msgstr "Zadajte adresu tokenu" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:176 +msgid "Failed Network, Please retry." +msgstr "Sieť zlyhala, skúste to znova." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:192 +msgid "Add another custom token" +msgstr "Pridajte ďalší vlastný token" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:236 +msgid "Confirm Swap" +msgstr "Potvrďte Výmenu" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:254 +msgid "Start Swap" +msgstr "Spustite výmenu" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:282 +msgid "You get" +msgstr "dostaneš" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:102 +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:90 +msgid "Search Token" +msgstr "Vyhľadávací token" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:134 +msgid "No custom tokens" +msgstr "Žiadne vlastné tokeny" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:135 +msgid "press the button to add your custom token" +msgstr "stlačte tlačidlo a pridajte svoj vlastný token" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:158 +msgid "Delete Custom Token" +msgstr "Odstrániť vlastný token" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:160 +msgid "Are you sure you want to Delete this Token?" +msgstr "Naozaj chcete odstrániť tento token?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:59 +msgid "Complete" +msgstr "Dokončiť" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:63 +msgid "Running" +msgstr "Beh" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:65 +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:8 +msgid "Failed" +msgstr "Nepodarilo sa" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:149 +msgid "Clear" +msgstr "Jasné" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:161 +msgid "Search Transaction" +msgstr "Vyhľadať transakciu" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:187 +msgid "No transactions" +msgstr "Žiadne transakcie" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:194 +msgid "Your transaction history is stored locally and will appear here after you start a swap" +msgstr "Vaša história transakcií je uložená lokálne a zobrazí sa tu po spustení swapu" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:218 +msgid "Clear Transaction History" +msgstr "Vymazať históriu transakcií" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:222 +msgid "Proceeding will remove all successful and failed transactions from the widget. Do you want to continue?" +msgstr "Pokračovaním sa z miniaplikácie odstránia všetky úspešné a neúspešné transakcie. Chcete pokračovať?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:229 +msgid "Note: This does not erase your transaction history on the chain; it only removes them here." +msgstr "Poznámka: Týmto sa nevymaže vaša história transakcií v reťazci; odstráni ich len tu." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:243 +msgid "Yes, Clear the history" +msgstr "Áno, vymazať históriu" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LanguagePage.tsx:56 +msgid "language" +msgstr "jazyk" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:121 +msgid "Deselect all" +msgstr "Zrušte výber všetkých" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:121 +msgid "Select all" +msgstr "Vybrať všetko" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:133 +msgid "Search {sourceType}" +msgstr "Hľadať {sourceType}" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectBlockchainPage.tsx:60 +msgid "Search Chain" +msgstr "Vyhľadávací reťazec" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:67 +msgid "Source" +msgstr "Zdroj" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:68 +msgid "Destination" +msgstr "Cieľ" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:74 +msgid "Swap {type}" +msgstr "Vymeňte {type}" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SettingsPage.tsx:45 +msgid "Currently, you're in campaign mode with restrictions on liquidity sources. Would you like to switch out of this mode and make use of all available liquidity sources?" +msgstr "Momentálne ste v režime kampane s obmedzeniami na zdroje likvidity. Chceli by ste z tohto režimu vypnúť a využiť všetky dostupné zdroje likvidity?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SwapDetailsPage.tsx:27 +msgid "The request ID is necessary to display the swap details." +msgstr "ID požiadavky je potrebné na zobrazenie podrobností o výmene." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/WalletsPage.tsx:67 +#: widget/ui/src/containers/ConnectWalletsModal/ConnectWalletsModal.tsx:15 +msgid "Connect Wallets" +msgstr "Pripojte Peňaženky" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/WalletsPage.tsx:82 +msgid "Choose a wallet to connect." +msgstr "Vyberte si peňaženku, ktorú chcete pripojiť." + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:25 +msgid "This week" +msgstr "Tento týždeň" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:32 +msgid "This month" +msgstr "Tento mesiac" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:39 +msgid "This year" +msgstr "Tento rok" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:129 +msgid "Required: >= {min} {symbol}" +msgstr "Povinné: >= {min} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:142 +msgid "Required: > {min} {symbol}" +msgstr "Povinné: > {min} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:157 +msgid "Required: <= {max} {symbol}" +msgstr "Povinné: <= {max} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:170 +msgid "Required: < {max} {symbol}" +msgstr "Povinné: < {max} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:601 +msgid " for network fee" +msgstr " za sieťový poplatok" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:604 +msgid " for swap" +msgstr " na výmenu" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:607 +msgid " for input and network fee" +msgstr " za vstupný a sieťový poplatok" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:609 +msgid "Needs ≈ {requiredAmount} {symbol}{reason}, but you have {currentAmount} {symbol} in your {blockchain} wallet." +msgstr "Potrebujete ≈ {requiredAmount} {symbol}{reason}, ale vo svojej {blockchain} peňaženke máte {currentAmount} {symbol} ." + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:669 +msgid "Waiting for connecting wallet" +msgstr "Čaká sa na pripojenie peňaženky" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:673 +msgid "Waiting for other running tasks to be finished" +msgstr "Čaká sa na dokončenie ostatných spustených úloh" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:676 +msgid "Waiting for changing wallet network" +msgstr "Čaká sa na zmenu siete peňaženky" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:6 +msgid "Sunday" +msgstr "nedeľu" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:7 +msgid "Monday" +msgstr "pondelok" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:8 +msgid "Tuesday" +msgstr "utorok" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:9 +msgid "Wednesday" +msgstr "streda" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:10 +msgid "Thursday" +msgstr "štvrtok" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:11 +msgid "Friday" +msgstr "piatok" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:12 +msgid "Saturday" +msgstr "sobota" + +#. js-lingui-explicit-id +#: widget/ui/src/components/BottomLogo/BottomLogo.tsx:14 +msgid "Powered By" +msgstr "Beží na" + +#. js-lingui-explicit-id +#: widget/ui/src/components/FullExpandedQuote/FullExpandedQuote.Tooltip.tsx:37 +msgid "Aggregated Transaction" +msgstr "Agregovaná transakcia" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SelectableCategoryList/SelectableCategoryList.tsx:63 +msgid "{blockchainCategory}" +msgstr "{blockchainCategory}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/StepDetails/StepDetails.tsx:75 +#: widget/ui/src/components/StepDetails/StepDetails.tsx:102 +msgid "Swap on {fromChain} via {swapper}" +msgstr "Vymeňte na {fromChain} cez {swapper}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/StepDetails/StepDetails.tsx:109 +msgid "Bridge to {toChain} via {swapper}" +msgstr "Most na {toChain} cez {swapper}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:10 +msgid "Completed" +msgstr "Dokončené" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:12 +msgid "In progress" +msgstr "Prebieha" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapToken.tsx:122 +msgid "Waiting for bridge transaction" +msgstr "Čaká sa na preklenovaciu transakciu" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:12 +msgid "Connected" +msgstr "Pripojené" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:13 +msgid "Disconnect" +msgstr "Odpojiť" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:18 +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:19 +msgid "Install" +msgstr "Inštalovať" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:24 +msgid "Connecting ..." +msgstr "Pripája sa..." + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:25 +msgid "Connecting" +msgstr "Pripája sa" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:30 +msgid "Disconnected" +msgstr "Odpojené" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:34 +msgid "you need to pass a correct state to Wallet." +msgstr "musíte do Peňaženky odovzdať správny stav." + +#. js-lingui-explicit-id +#: widget/ui/src/containers/Notifications/NotificationNotFound.tsx:15 +msgid "There are no notifications." +msgstr "Neexistujú žiadne upozornenia." + +#. js-lingui-explicit-id +#: widget/ui/src/containers/Notifications/Notifications.tsx:39 +msgid "Clear all" +msgstr "Vymazať všetko" + +#. js-lingui-explicit-id +#: widget/ui/src/containers/SwapInput/SwapInput.tsx:65 +msgid "Balance" +msgstr "Zostatok" + +#. js-lingui-explicit-id +#: widget/ui/src/containers/SwapInput/SwapInput.tsx:73 +msgid "Max" +msgstr "Max" + diff --git a/translations/sr.po b/translations/sr.po new file mode 100644 index 0000000000..ff8e9e601b --- /dev/null +++ b/translations/sr.po @@ -0,0 +1,1339 @@ +msgid "" +msgstr "" +"POT-Creation-Date: 2023-11-06 17:24+0330\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: @lingui/cli\n" +"Language: sr\n" +"Project-Id-Version: rango\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2024-11-27 15:57\n" +"Last-Translator: \n" +"Language-Team: Serbian (Cyrillic)\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" +"X-Crowdin-Project: rango\n" +"X-Crowdin-Project-ID: 622238\n" +"X-Crowdin-Language: sr\n" +"X-Crowdin-File: en.po\n" +"X-Crowdin-File-ID: 30\n" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SameTokensWarning/SameTokensWarning.tsx:21 +msgid "No Routes Found" +msgstr "Руте нису пронађене" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SameTokensWarning/SameTokensWarning.tsx:25 +msgid "You cannot use the same token for From and To." +msgstr "Не можете користити исти токен за Од и До." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:41 +#: widget/embedded/src/components/TokenList/TokenList.tsx:286 +#: widget/embedded/src/pages/HistoryPage.tsx:186 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:143 +msgid "No results found" +msgstr "Нема пронађених резултата" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:42 +#: widget/embedded/src/components/TokenList/TokenList.tsx:287 +#: widget/embedded/src/pages/HistoryPage.tsx:193 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:144 +msgid "Try using different keywords" +msgstr "Покушајте да користите различите кључне речи" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:72 +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:46 +#: widget/embedded/src/pages/SelectBlockchainPage.tsx:42 +#: widget/ui/src/containers/SwapInput/TokenSection.tsx:61 +msgid "Select Chain" +msgstr "Изаберите Ланац" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:66 +msgid "All" +msgstr "Све" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:100 +msgid "More +{count}" +msgstr "Још +{count}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabAlert/ActivateTabAlert.tsx:17 +msgid "Activate this tab" +msgstr "Активирајте ову картицу" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabAlert/ActivateTabAlert.tsx:22 +msgid "Another tab is open and handles transactions." +msgstr "Друга картица је отворена и управља трансакцијама." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:20 +msgid "Activate current tab" +msgstr "Активирајте тренутну картицу" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:22 +msgid "Currently, some transactions are running and being handled by other browser tab. If you activate this tab, all transactions that are already in the transaction sign step will expire." +msgstr "Тренутно су неке трансакције покренуте и њима управља друга картица претраживача. Ако активирате ову картицу, све трансакције које су већ у кораку потписивања трансакције ће истећи." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:33 +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:349 +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:152 +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:33 +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:116 +msgid "Confirm" +msgstr "Потврди" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:365 +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:447 +msgid "Your {blockchainName} wallets" +msgstr "Ваши {blockchainName} новчаници" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:384 +msgid "Insufficient account balance" +msgstr "Недовољно стање на рачуну" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:394 +msgid "Proceed anyway" +msgstr "Ипак наставите" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:456 +msgid "You need to connect a {blockchainName} wallet." +msgstr "Морате да повежете {blockchainName} новчаник." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/WalletList.tsx:143 +msgid "Add {chain} chain" +msgstr "Додајте {chain} ланац" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/WalletList.tsx:244 +msgid "Show more wallets" +msgstr "Прикажи још новчаника" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:113 +msgid "Send to a different address" +msgstr "Пошаљите на другу адресу" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:129 +msgid "Enter {blockchainName} address" +msgstr "Унесите {blockchainName} адресу" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:147 +msgid "Address {destination} doesn't match the blockchain address pattern." +msgstr "Адреса {destination} не одговара обрасцу адресе блок ланца." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:59 +msgid "via" +msgstr "преко" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:74 +msgid "This token doesn't appear on the active token list(s). Make sure this is the token that you want to trade." +msgstr "Овај токен се не појављује на листи активних токена. Уверите се да је ово жетон којим желите да тргујете." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:89 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:164 +msgid "Import" +msgstr "Увоз" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/FilterSelector/FilterSelectorContent.tsx:26 +msgid "Status" +msgstr "Статус" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/FilterSelector/FilterSelectorContent.tsx:33 +#: widget/embedded/src/components/NoResult/NoResult.helpers.ts:37 +#: widget/embedded/src/pages/SettingsPage.tsx:55 +msgid "Reset" +msgstr "Ресетуј" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/CancelButton.tsx:18 +msgid "Cancel" +msgstr "Откажи" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:46 +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:34 +msgid "Refresh" +msgstr "Освежи" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:63 +#: widget/ui/src/containers/Notifications/Notifications.tsx:35 +msgid "Notifications" +msgstr "Обавештења" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:79 +#: widget/embedded/src/pages/SettingsPage.tsx:38 +msgid "Settings" +msgstr "Подешавања" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:93 +#: widget/embedded/src/pages/HistoryPage.tsx:139 +msgid "History" +msgstr "Историја" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/WalletButton.tsx:22 +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:16 +#: widget/embedded/src/constants/messages.ts:5 +msgid "Connect Wallet" +msgstr "Повежите новчаник" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HistoryGroupedList/HistoryGroupedList.tsx:118 +#: widget/embedded/src/utils/date.ts:18 +#: widget/embedded/src/utils/time.ts:22 +msgid "Today" +msgstr "данас" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/LoadingSwapDetails/LoadingSwapDetails.tsx:20 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:424 +msgid "Swaps steps" +msgstr "Замењује кораке" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/NoResult/NoResult.helpers.ts:25 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:191 +msgid "Retry" +msgstr "Покушајте поново" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:149 +msgid "Slippage Error" +msgstr "Слиппаге Еррор" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:150 +msgid "Slippage Warning" +msgstr "Упозорење о проклизавању" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:153 +msgid "Bridge Limit Error" +msgstr "Грешка границе моста" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:240 +msgid "Yours: {amount} {symbol}" +msgstr "Ваш: {amount} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:261 +msgid "Minimum required slippage: {minRequiredSlippage}" +msgstr "Минимално потребно клизање: {minRequiredSlippage}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:282 +msgid "Yours: {userSlippage}" +msgstr "Ваш: {userSlippage}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:395 +msgid "See All Routes" +msgstr "Погледајте све руте" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:81 +msgid "View more info" +msgstr "Погледајте више информација" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:91 +msgid "Gas & Fee Explanation" +msgstr "Објашњење за гас и накнаду" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:107 +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:103 +msgid "Details" +msgstr "Детаљи" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:146 +msgid "Total Payable Fee" +msgstr "Укупна накнада за плаћање" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:166 +msgid "Hide non-payable fees" +msgstr "Сакријте неплативе накнаде" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:167 +msgid "Show non-payable fees" +msgstr "Прикажите неплативе накнаде" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:177 +msgid "Description" +msgstr "Опис" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:181 +msgid "The following fees are considered in the transaction output and\n" +" you won’t need to pay extra gas for them." +msgstr "Следеће накнаде се узимају у обзир у излазу трансакције и\n" +" нећете морати да плаћате додатни гас за њих." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteSummary.tsx:25 +msgid "Swap input" +msgstr "Замени улаз" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteSummary.tsx:44 +msgid "Estimated output" +msgstr "Процењени излаз" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteTrigger.tsx:65 +msgid "Via:" +msgstr "преко:" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteTrigger.tsx:150 +msgid "Chains:" +msgstr "Ланци:" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/Quotes.tsx:77 +msgid "Sort by" +msgstr "Сортирај по" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:17 +msgid "Smart Routing" +msgstr "Смарт Роутинг" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:21 +msgid "Lowest Fee" +msgstr "Најнижа накнада" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:25 +msgid "Fastest Transfer" +msgstr "Најбржи трансфер" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:29 +msgid "Maximum Return" +msgstr "Макимум Ретурн" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:33 +msgid "Maximum Output" +msgstr "Макимум Оутпут" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:43 +msgid "Swapping" +msgstr "Замена" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:51 +msgid "Gas cost" +msgstr "Трошак гаса" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:59 +msgid "Receiving" +msgstr "Примање" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:67 +msgid "Price impact" +msgstr "Утицај на цену" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:35 +msgid "You need to increase slippage to at least {minRequiredSlippage} for this route." +msgstr "Морате повећати клизање на најмање {minRequiredSlippage} за ову руту." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:59 +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:61 +msgid "We recommend you to increase slippage to at least {minRequiredSlippage} for this route." +msgstr "Препоручујемо вам да повећате клизање на најмање {minRequiredSlippage} за ову руту." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:68 +msgid "Caution, your slippage is high." +msgstr "Опрез, ваше клизање је велико." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.tsx:78 +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.Warning.tsx:26 +msgid "Change" +msgstr "Промена" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:42 +msgid "Change settings" +msgstr "Промените подешавања" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:52 +msgid "High slippage" +msgstr "Високо клизање" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:53 +msgid "Low slippage" +msgstr "Ниско клизање" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:57 +msgid " Caution, your slippage is high (={userSlippage}). Your trade may be front run." +msgstr " Пажња, ваше проклизавање је велико (={userSlippage}). Ваша трговина може бити почетна." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:78 +msgid "Confirm anyway" +msgstr "Свеједно потврди" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:22 +msgid "Something went wrong" +msgstr "Нешто је пошло по злу" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:24 +msgid "Something went wrong. Please refresh the app." +msgstr "Нешто је пошло по злу. Освежите апликацију." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/Slippage.tsx:38 +msgid "Slippage tolerance per swap" +msgstr "Толеранција клизања по замени" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/Slippage.tsx:91 +msgid "Custom" +msgstr "Цустом" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:11 +msgid "Your transaction will be reverted if the price changes unfavorably by more than this percentage." +msgstr "Ваша трансакција ће бити поништена ако се цена неповољно промени за више од овог процента." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:16 +#: widget/embedded/src/containers/Settings/Lists.tsx:245 +msgid "Warning" +msgstr "Упозорење" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:17 +msgid "This setting is applied to each step (e.g. 1Inch, Thorchain, etc.), meaning only that specific step will be reverted, not the entire route." +msgstr "Ово подешавање се примењује на сваки корак (нпр. 1 инч, Тхорцхаин, итд.), што значи да ће само тај одређени корак бити враћен, а не цела рута." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:25 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:269 +msgid "Swap Details" +msgstr "Свап Детаилс" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:33 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:312 +msgid "Request ID" +msgstr "ИД захтева" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:64 +msgid "Not found" +msgstr "Није пронађено" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:65 +msgid "Swap with request ID = {requestId} not found." +msgstr "Замена са ИД-ом захтева = {requestId} није пронађено." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:219 +msgid "You have received {amount} {token} in {conciseAddress} wallet on {chain} chain." +msgstr "Добили сте {amount} {token} у {conciseAddress} новчанику на {chain} ланцу." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:242 +msgid "Transaction was not sent." +msgstr "Трансакција није послата." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:244 +msgid "{amount} {symbol} on {blockchain} remains in your wallet." +msgstr "{amount} {symbol} на {blockchain} остаје у вашем новчанику." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:281 +msgid "Delete" +msgstr "Избриши" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:304 +msgid "Try again" +msgstr "Покушајте поново" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:322 +msgid "Copied To Clipboard" +msgstr "Копирано у међуспремник" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:323 +msgid "Copy Request ID" +msgstr "Копирај ИД захтева" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:346 +msgid "View on Rango Explorer" +msgstr "Поглед на Ранго Екплорер" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:355 +msgid "Finished at" +msgstr "Завршено у" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:355 +msgid "Created at" +msgstr "Цреатед ат" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.tsx:50 +msgid "View transaction" +msgstr "Погледајте трансакцију" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.Warning.tsx:49 +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:31 +msgid "Connect" +msgstr "Повежите се" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:43 +msgid "Swap Successful" +msgstr "Замена успела" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:71 +msgid "Transaction Failed" +msgstr "Трансакција није успела" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:87 +msgid "Done" +msgstr "Готово" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:100 +msgid "Diagnosis" +msgstr "Дијагноза" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:112 +msgid "See Details" +msgstr "Погледајте Детаљи" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:13 +msgid "Cancel Swap" +msgstr "Откажи замену" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:14 +msgid "Are you sure you want to cancel this swap?" +msgstr "Да ли сте сигурни да желите да откажете ову замену?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:23 +msgid "Yes, Cancel it" +msgstr "Да, откажи" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:32 +#: widget/embedded/src/pages/CustomTokensPage.tsx:181 +msgid "No, Continue" +msgstr "Не, настави" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:13 +msgid "Delete Transaction" +msgstr "Избриши трансакцију" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:14 +msgid "Are you sure you want to delete this swap?" +msgstr "Да ли сте сигурни да желите да избришете ову замену?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:23 +#: widget/embedded/src/pages/CustomTokensPage.tsx:171 +msgid "Yes, Delete it" +msgstr "Да, Избриши" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:33 +#: widget/embedded/src/pages/HistoryPage.tsx:253 +msgid "No, Cancel" +msgstr "Не, откажи" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:12 +msgid "Change Network" +msgstr "Промените мрежу" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:20 +msgid "Network Changed" +msgstr "Мрежа је промењена" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/TokenList/TokenList.tsx:271 +#: widget/ui/src/containers/SwapInput/TokenSection.tsx:54 +msgid "Select Token" +msgstr "Изаберите Токен" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:27 +msgid "Wallet Connected" +msgstr "Новчаник повезан" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:28 +msgid "Your wallet is connected, you can use it to swap." +msgstr "Ваш новчаник је повезан, можете га користити за замену." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:39 +msgid "Failed to Connect" +msgstr "Повезивање није успело" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:41 +msgid "Your wallet is not connected. Please try again." +msgstr "Ваш новчаник није повезан. Покушајте поново." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:50 +msgid "Connecting to your wallet" +msgstr "Повезивање са вашим новчаником" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:51 +msgid "Click connect in your wallet popup." +msgstr "Кликните на Повежи се у искачућем прозору новчаника." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:99 +msgid "Select Derivation Path" +msgstr "Изаберите Путања деривације" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:100 +msgid "In order to connect to {type}, you must first select a Derivation Path" +msgstr "Да бисте се повезали на {type}, прво морате да изаберете путању извођења" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:118 +msgid "Choose Derivation Path Template" +msgstr "Изаберите шаблон путање извођења" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:133 +msgid "Enter Path" +msgstr "Унесите путању" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:134 +msgid "Enter Index" +msgstr "Унесите индекс" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:15 +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:18 +msgid "Add {blockchainDisplayName} Chain" +msgstr "Додајте {blockchainDisplayName} ланац" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:20 +msgid "Would you like to add the {blockchainDisplayName} experimental chain to your wallet?" +msgstr "Да ли желите да додате {blockchainDisplayName} експериментални ланац у свој новчаник?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:22 +msgid "Please approve the experimental chain pop-up in your wallet." +msgstr "Одобрите искачући прозор експерименталног ланца у свом новчанику." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:30 +msgid "{blockchainDisplayName} Chain Added" +msgstr "{blockchainDisplayName} Додан ланац" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:34 +msgid "The {blockchainDisplayName} chain has been successfully added to your wallet." +msgstr "Ланац {blockchainDisplayName} је успешно додат у ваш новчаник." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:42 +msgid "Request Rejected" +msgstr "Захтев одбијен" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:43 +msgid "You've rejected adding {blockchainDisplayName} chain to your wallet." +msgstr "Одбили сте додавање {blockchainDisplayName} ланца у ваш новчаник." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:70 +msgid "Select chain types" +msgstr "Изаберите типове ланаца" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:71 +msgid "This wallet supports multiple chains. Select which chain you'd like to connect to." +msgstr "Овај новчаник подржава више ланаца. Изаберите на који ланац желите да се повежете." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:9 +msgid "Failed Network, Please retry your swap." +msgstr "Неуспела мрежа, покушајте поново да извршите замену." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:11 +msgid "Please reset your liquidity sources." +msgstr "Ресетујте своје изворе ликвидности." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:12 +msgid "You have limited the liquidity sources and this might result in Rango finding no routes. Please consider resetting your liquidity sources." +msgstr "Ограничили сте изворе ликвидности и то може довести до тога да Ранго не пронађе никакве руте. Размислите о ресетовању извора ликвидности." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:17 +msgid "No Routes Found." +msgstr "Руте нису пронађене." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:18 +msgid "Reasons why Rango couldn't find a route: low liquidity on token, very low input amount or no routes available for the selected input/output token combination." +msgstr "Разлози због којих Ранго није могао да пронађе руту: ниска ликвидност на токену, веома мали износ уноса или нема доступних рута за изабрану комбинацију улазно/излазних токена." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:23 +msgid "Bridge Limit Error: Please increase your amount." +msgstr "Грешка у ограничењу премошћавања: Повећајте износ." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:26 +msgid "Bridge Limit Error: Please decrease your amount." +msgstr "Грешка у ограничењу премошћавања: Смањите износ." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:31 +msgid "High Price Impact" +msgstr "Висок утицај на цену" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:32 +msgid "Price impact is too high!" +msgstr "Утицај на цену је превелик!" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:33 +msgid "The price impact is significantly higher than the allowed amount." +msgstr "Утицај на цену је знатно већи од дозвољеног износа." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:36 +msgid "Confirm high price impact" +msgstr "Потврдите утицај високе цене" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:39 +msgid "Route updated and price impact is too high, try again later!" +msgstr "Рута је ажурирана и утицај на цену је превелик, покушајте поново касније!" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:44 +msgid "USD Price Unknown" +msgstr "УСД Цена непозната" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:45 +msgid "USD Price Unknown, Cannot calculate Price Impact." +msgstr "Цена у УСД непозната, не може се израчунати утицај на цену." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:46 +msgid "USD Price Unknown, Cannot calculate Price Impact. The price impact may be higher than usual. Are you sure to continue the Swap?" +msgstr "Цена у УСД непозната, не може се израчунати утицај на цену. Утицај на цену може бити већи него иначе. Да ли сте сигурни да настављате Замену?" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:49 +msgid "Confirm USD Price Unknown" +msgstr "Потврдите цену у УСД непознато" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:6 +#: widget/embedded/src/pages/Home.tsx:163 +msgid "Swap" +msgstr "Свап" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:7 +msgid "Swap anyway" +msgstr "Замени у сваком случају" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:8 +msgid "The route goes through Ethereum. Continue?" +msgstr "Рута иде преко Етхереума. Наставити?" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:10 +msgid "Route has been updated." +msgstr "Рута је ажурирана." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:12 +msgid "Output amount changed to {newOutputAmount} ({percentageChange}% change)." +msgstr "Излазни износ је промењен у {newOutputAmount} ({percentageChange}% промена)." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:20 +msgid "Route swappers has been updated." +msgstr "Промена рута је ажурирана." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:22 +msgid "Route internal coins has been updated." +msgstr "Интерни новчићи руте су ажурирани." + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/ExpandedQuotes/ExpandedQuotes.tsx:53 +#: widget/embedded/src/pages/Routes.tsx:48 +msgid "Routes" +msgstr "Руте" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Inputs/Inputs.tsx:76 +msgid "From" +msgstr "Од" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Inputs/Inputs.tsx:118 +msgid "To" +msgstr "То" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:49 +msgid "Light" +msgstr "Светлост" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:58 +msgid "Dark" +msgstr "Дарк" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:67 +msgid "Auto" +msgstr "Ауто" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:140 +msgid "Loading failed" +msgstr "Учитавање није успело" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:156 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:41 +msgid "Bridges" +msgstr "Мостови" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:174 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:41 +msgid "Exchanges" +msgstr "Размене" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:195 +#: widget/embedded/src/pages/CustomTokensPage.tsx:90 +msgid "Custom Tokens" +msgstr "Прилагођени токени" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:214 +#: widget/embedded/src/pages/LanguagePage.tsx:43 +msgid "Language" +msgstr "Језик" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:235 +msgid "Infinite approval" +msgstr "Бесконачно одобрење" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:246 +msgid "Enabling the 'Infinite approval' mode grants unrestricted access to underlying smart contracts, allowing them to utilize the approved token amount without limitations." +msgstr "Омогућавање режима „Бесконачно одобрење“ даје неограничен приступ основним паметним уговорима, омогућавајући им да користе одобрени износ токена без ограничења." + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:266 +msgid "Theme" +msgstr "Тема" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:39 +msgid "Duplicate Token" +msgstr "Дупликат токена" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:40 +msgid "The address you entered is duplicate, please enter a new address." +msgstr "Адреса коју сте унели је дупликат, унесите нову адресу." + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:46 +msgid "Token Already Exists" +msgstr "Токен већ постоји" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:47 +msgid "There's no need to add this token again because it already exists and is supported by us." +msgstr "Нема потребе да поново додајете овај токен јер већ постоји и подржавамо га." + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:53 +msgid "Token Not Found" +msgstr "Токен није пронађен" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:54 +msgid "Sorry, no token was found on {blockchain} chain with the provided address. please make sure you have entered the right token address." +msgstr "Жао нам је, токен није пронађен у {blockchain} ланцу са наведеном адресом. уверите се да сте унели исправну адресу токена." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:78 +msgid "Network Error" +msgstr "Мрежна грешка" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:109 +#: widget/embedded/src/pages/CustomTokensPage.tsx:149 +msgid "Add Custom Token" +msgstr "Додајте прилагођени токен" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:127 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:128 +msgid "Select chain" +msgstr "Изаберите ланац" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:132 +msgid "Enter Address" +msgstr "Унесите адресу" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:139 +msgid "Enter token address" +msgstr "Унесите адресу токена" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:176 +msgid "Failed Network, Please retry." +msgstr "Мрежа није успела, покушајте поново." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:192 +msgid "Add another custom token" +msgstr "Додајте још један прилагођени токен" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:236 +msgid "Confirm Swap" +msgstr "Потврдите замену" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:254 +msgid "Start Swap" +msgstr "Старт Свап" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:282 +msgid "You get" +msgstr "Добијеш" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:102 +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:90 +msgid "Search Token" +msgstr "Сеарцх Токен" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:134 +msgid "No custom tokens" +msgstr "Нема прилагођених токена" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:135 +msgid "press the button to add your custom token" +msgstr "притисните дугме да додате свој прилагођени токен" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:158 +msgid "Delete Custom Token" +msgstr "Избришите прилагођени токен" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:160 +msgid "Are you sure you want to Delete this Token?" +msgstr "Да ли сте сигурни да желите да избришете овај токен?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:59 +msgid "Complete" +msgstr "Завршено" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:63 +msgid "Running" +msgstr "Трчање" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:65 +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:8 +msgid "Failed" +msgstr "Није успело" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:149 +msgid "Clear" +msgstr "Јасно" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:161 +msgid "Search Transaction" +msgstr "Трансакција претраге" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:187 +msgid "No transactions" +msgstr "Нема трансакција" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:194 +msgid "Your transaction history is stored locally and will appear here after you start a swap" +msgstr "Ваша историја трансакција се чува локално и појавиће се овде након што започнете замену" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:218 +msgid "Clear Transaction History" +msgstr "Обриши историју трансакција" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:222 +msgid "Proceeding will remove all successful and failed transactions from the widget. Do you want to continue?" +msgstr "Настављање ће уклонити све успешне и неуспеле трансакције из виџета. Да ли желите да наставите?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:229 +msgid "Note: This does not erase your transaction history on the chain; it only removes them here." +msgstr "Напомена: Ово не брише вашу историју трансакција у ланцу; само их овде уклања." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:243 +msgid "Yes, Clear the history" +msgstr "Да, обришите историју" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LanguagePage.tsx:56 +msgid "language" +msgstr "језик" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:121 +msgid "Deselect all" +msgstr "Опозови све" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:121 +msgid "Select all" +msgstr "Изаберите све" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:133 +msgid "Search {sourceType}" +msgstr "Претражите {sourceType}" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectBlockchainPage.tsx:60 +msgid "Search Chain" +msgstr "Сеарцх Цхаин" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:67 +msgid "Source" +msgstr "Извор" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:68 +msgid "Destination" +msgstr "Одредиште" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:74 +msgid "Swap {type}" +msgstr "Заменити {type}" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SettingsPage.tsx:45 +msgid "Currently, you're in campaign mode with restrictions on liquidity sources. Would you like to switch out of this mode and make use of all available liquidity sources?" +msgstr "Тренутно сте у режиму кампање са ограничењима извора ликвидности. Да ли желите да изађете из овог режима и искористите све доступне изворе ликвидности?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SwapDetailsPage.tsx:27 +msgid "The request ID is necessary to display the swap details." +msgstr "ИД захтева је неопходан за приказ детаља размене." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/WalletsPage.tsx:67 +#: widget/ui/src/containers/ConnectWalletsModal/ConnectWalletsModal.tsx:15 +msgid "Connect Wallets" +msgstr "Повежите новчанике" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/WalletsPage.tsx:82 +msgid "Choose a wallet to connect." +msgstr "Изаберите новчаник за повезивање." + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:25 +msgid "This week" +msgstr "Ове недеље" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:32 +msgid "This month" +msgstr "Овог месеца" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:39 +msgid "This year" +msgstr "Ове године" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:129 +msgid "Required: >= {min} {symbol}" +msgstr "Обавезно: >= {min} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:142 +msgid "Required: > {min} {symbol}" +msgstr "Обавезно: > {min} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:157 +msgid "Required: <= {max} {symbol}" +msgstr "Обавезно: <= {max} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:170 +msgid "Required: < {max} {symbol}" +msgstr "Обавезно: < {max} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:601 +msgid " for network fee" +msgstr " за мрежну накнаду" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:604 +msgid " for swap" +msgstr " за замену" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:607 +msgid " for input and network fee" +msgstr " за улазну и мрежну накнаду" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:609 +msgid "Needs ≈ {requiredAmount} {symbol}{reason}, but you have {currentAmount} {symbol} in your {blockchain} wallet." +msgstr "Потребно је ≈ {requiredAmount} {symbol}{reason}, али имате {currentAmount} {symbol} у свом {blockchain} новчанику." + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:669 +msgid "Waiting for connecting wallet" +msgstr "Чека се повезивање новчаника" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:673 +msgid "Waiting for other running tasks to be finished" +msgstr "Чека се да се заврше други задаци" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:676 +msgid "Waiting for changing wallet network" +msgstr "Чека се промена мреже новчаника" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:6 +msgid "Sunday" +msgstr "недеља" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:7 +msgid "Monday" +msgstr "понедељак" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:8 +msgid "Tuesday" +msgstr "уторак" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:9 +msgid "Wednesday" +msgstr "среда" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:10 +msgid "Thursday" +msgstr "четвртак" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:11 +msgid "Friday" +msgstr "петак" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:12 +msgid "Saturday" +msgstr "Субота" + +#. js-lingui-explicit-id +#: widget/ui/src/components/BottomLogo/BottomLogo.tsx:14 +msgid "Powered By" +msgstr "Поверед Би" + +#. js-lingui-explicit-id +#: widget/ui/src/components/FullExpandedQuote/FullExpandedQuote.Tooltip.tsx:37 +msgid "Aggregated Transaction" +msgstr "Збирна трансакција" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SelectableCategoryList/SelectableCategoryList.tsx:63 +msgid "{blockchainCategory}" +msgstr "{blockchainCategory}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/StepDetails/StepDetails.tsx:75 +#: widget/ui/src/components/StepDetails/StepDetails.tsx:102 +msgid "Swap on {fromChain} via {swapper}" +msgstr "Замените на {fromChain} преко {swapper}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/StepDetails/StepDetails.tsx:109 +msgid "Bridge to {toChain} via {swapper}" +msgstr "Мост до {toChain} преко {swapper}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:10 +msgid "Completed" +msgstr "Завршено" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:12 +msgid "In progress" +msgstr "У току" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapToken.tsx:122 +msgid "Waiting for bridge transaction" +msgstr "Чека се бридге трансакција" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:12 +msgid "Connected" +msgstr "Повезано" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:13 +msgid "Disconnect" +msgstr "Прекини везу" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:18 +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:19 +msgid "Install" +msgstr "Инсталирај" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:24 +msgid "Connecting ..." +msgstr "Повезивање..." + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:25 +msgid "Connecting" +msgstr "Повезивање" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:30 +msgid "Disconnected" +msgstr "Дисцоннецтед" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:34 +msgid "you need to pass a correct state to Wallet." +msgstr "потребно је да проследите исправно стање у Новчаник." + +#. js-lingui-explicit-id +#: widget/ui/src/containers/Notifications/NotificationNotFound.tsx:15 +msgid "There are no notifications." +msgstr "Нема обавештења." + +#. js-lingui-explicit-id +#: widget/ui/src/containers/Notifications/Notifications.tsx:39 +msgid "Clear all" +msgstr "Обриши све" + +#. js-lingui-explicit-id +#: widget/ui/src/containers/SwapInput/SwapInput.tsx:65 +msgid "Balance" +msgstr "Баланс" + +#. js-lingui-explicit-id +#: widget/ui/src/containers/SwapInput/SwapInput.tsx:73 +msgid "Max" +msgstr "Макс" + diff --git a/translations/sv.po b/translations/sv.po new file mode 100644 index 0000000000..85903e70fd --- /dev/null +++ b/translations/sv.po @@ -0,0 +1,1339 @@ +msgid "" +msgstr "" +"POT-Creation-Date: 2023-11-06 17:24+0330\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: @lingui/cli\n" +"Language: sv\n" +"Project-Id-Version: rango\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2024-11-27 15:57\n" +"Last-Translator: \n" +"Language-Team: Swedish\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Crowdin-Project: rango\n" +"X-Crowdin-Project-ID: 622238\n" +"X-Crowdin-Language: sv-SE\n" +"X-Crowdin-File: en.po\n" +"X-Crowdin-File-ID: 30\n" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SameTokensWarning/SameTokensWarning.tsx:21 +msgid "No Routes Found" +msgstr "Inga rutter hittades" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SameTokensWarning/SameTokensWarning.tsx:25 +msgid "You cannot use the same token for From and To." +msgstr "Du kan inte använda samma token för Från och Till." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:41 +#: widget/embedded/src/components/TokenList/TokenList.tsx:286 +#: widget/embedded/src/pages/HistoryPage.tsx:186 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:143 +msgid "No results found" +msgstr "Inga resultat hittades" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:42 +#: widget/embedded/src/components/TokenList/TokenList.tsx:287 +#: widget/embedded/src/pages/HistoryPage.tsx:193 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:144 +msgid "Try using different keywords" +msgstr "Prova att använda olika sökord" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:72 +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:46 +#: widget/embedded/src/pages/SelectBlockchainPage.tsx:42 +#: widget/ui/src/containers/SwapInput/TokenSection.tsx:61 +msgid "Select Chain" +msgstr "Välj kedja" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:66 +msgid "All" +msgstr "Alla" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:100 +msgid "More +{count}" +msgstr "Mer +{count}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabAlert/ActivateTabAlert.tsx:17 +msgid "Activate this tab" +msgstr "Aktivera denna flik" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabAlert/ActivateTabAlert.tsx:22 +msgid "Another tab is open and handles transactions." +msgstr "En annan flik är öppen och hanterar transaktioner." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:20 +msgid "Activate current tab" +msgstr "Aktivera aktuell flik" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:22 +msgid "Currently, some transactions are running and being handled by other browser tab. If you activate this tab, all transactions that are already in the transaction sign step will expire." +msgstr "För närvarande körs och hanteras vissa transaktioner av andra webbläsarfliken. Om du aktiverar den här fliken, kommer alla transaktioner som redan finns i transaktionssigneringssteget att upphöra." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:33 +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:349 +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:152 +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:33 +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:116 +msgid "Confirm" +msgstr "Bekräfta" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:365 +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:447 +msgid "Your {blockchainName} wallets" +msgstr "Dina {blockchainName} plånböcker" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:384 +msgid "Insufficient account balance" +msgstr "Otillräckligt saldo" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:394 +msgid "Proceed anyway" +msgstr "Fortsätt ändå" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:456 +msgid "You need to connect a {blockchainName} wallet." +msgstr "Du måste ansluta en {blockchainName} plånbok." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/WalletList.tsx:143 +msgid "Add {chain} chain" +msgstr "Lägg till {chain} kedja" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/WalletList.tsx:244 +msgid "Show more wallets" +msgstr "Visa fler plånböcker" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:113 +msgid "Send to a different address" +msgstr "Skicka till en annan adress" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:129 +msgid "Enter {blockchainName} address" +msgstr "Ange {blockchainName} adress" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:147 +msgid "Address {destination} doesn't match the blockchain address pattern." +msgstr "Adress {destination} matchar inte blockkedjans adressmönster." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:59 +msgid "via" +msgstr "via" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:74 +msgid "This token doesn't appear on the active token list(s). Make sure this is the token that you want to trade." +msgstr "Denna token visas inte på den aktiva token listan. Se till att detta är den token som du vill handla." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:89 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:164 +msgid "Import" +msgstr "Importera" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/FilterSelector/FilterSelectorContent.tsx:26 +msgid "Status" +msgstr "Status" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/FilterSelector/FilterSelectorContent.tsx:33 +#: widget/embedded/src/components/NoResult/NoResult.helpers.ts:37 +#: widget/embedded/src/pages/SettingsPage.tsx:55 +msgid "Reset" +msgstr "Reset" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/CancelButton.tsx:18 +msgid "Cancel" +msgstr "Avbryt" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:46 +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:34 +msgid "Refresh" +msgstr "Uppdatera" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:63 +#: widget/ui/src/containers/Notifications/Notifications.tsx:35 +msgid "Notifications" +msgstr "Aviseringar" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:79 +#: widget/embedded/src/pages/SettingsPage.tsx:38 +msgid "Settings" +msgstr "Inställningar" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:93 +#: widget/embedded/src/pages/HistoryPage.tsx:139 +msgid "History" +msgstr "Historik" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/WalletButton.tsx:22 +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:16 +#: widget/embedded/src/constants/messages.ts:5 +msgid "Connect Wallet" +msgstr "Anslut plånbok" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HistoryGroupedList/HistoryGroupedList.tsx:118 +#: widget/embedded/src/utils/date.ts:18 +#: widget/embedded/src/utils/time.ts:22 +msgid "Today" +msgstr "Idag" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/LoadingSwapDetails/LoadingSwapDetails.tsx:20 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:424 +msgid "Swaps steps" +msgstr "Växlar steg" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/NoResult/NoResult.helpers.ts:25 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:191 +msgid "Retry" +msgstr "Försök igen" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:149 +msgid "Slippage Error" +msgstr "Slippage Fel" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:150 +msgid "Slippage Warning" +msgstr "Slippage Varning" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:153 +msgid "Bridge Limit Error" +msgstr "Bridgegräns fel" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:240 +msgid "Yours: {amount} {symbol}" +msgstr "Yours: {amount} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:261 +msgid "Minimum required slippage: {minRequiredSlippage}" +msgstr "Minsta obligatoriska halkning: {minRequiredSlippage}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:282 +msgid "Yours: {userSlippage}" +msgstr "Er: {userSlippage}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:395 +msgid "See All Routes" +msgstr "Se alla rutter" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:81 +msgid "View more info" +msgstr "Visa mer information" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:91 +msgid "Gas & Fee Explanation" +msgstr "Förklaring av gas & avgift" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:107 +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:103 +msgid "Details" +msgstr "Detaljer" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:146 +msgid "Total Payable Fee" +msgstr "Total betalningskostnad" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:166 +msgid "Hide non-payable fees" +msgstr "Dölj icke-betalbara avgifter" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:167 +msgid "Show non-payable fees" +msgstr "Visa icke-betalbara avgifter" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:177 +msgid "Description" +msgstr "Beskrivning" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:181 +msgid "The following fees are considered in the transaction output and\n" +" you won’t need to pay extra gas for them." +msgstr "Följande avgifter beaktas i transaktionen utgång och\n" +" behöver du inte betala extra gas för dem." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteSummary.tsx:25 +msgid "Swap input" +msgstr "Swap input" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteSummary.tsx:44 +msgid "Estimated output" +msgstr "Uppskattad utdata" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteTrigger.tsx:65 +msgid "Via:" +msgstr "Via:" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteTrigger.tsx:150 +msgid "Chains:" +msgstr "Kedjor:" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/Quotes.tsx:77 +msgid "Sort by" +msgstr "Sortera efter" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:17 +msgid "Smart Routing" +msgstr "Smart routing" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:21 +msgid "Lowest Fee" +msgstr "Lägsta avgift" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:25 +msgid "Fastest Transfer" +msgstr "Snabbaste överföringen" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:29 +msgid "Maximum Return" +msgstr "Maximal retur" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:33 +msgid "Maximum Output" +msgstr "Maximal utdata" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:43 +msgid "Swapping" +msgstr "Swapping" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:51 +msgid "Gas cost" +msgstr "Gas kostnad" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:59 +msgid "Receiving" +msgstr "Tar emot" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:67 +msgid "Price impact" +msgstr "Pris inverkan" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:35 +msgid "You need to increase slippage to at least {minRequiredSlippage} for this route." +msgstr "Du måste öka halkningen till minst {minRequiredSlippage} för denna rutt." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:59 +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:61 +msgid "We recommend you to increase slippage to at least {minRequiredSlippage} for this route." +msgstr "Vi rekommenderar att du ökar halkningen till minst {minRequiredSlippage} för denna rutt." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:68 +msgid "Caution, your slippage is high." +msgstr "Varning, din glidning är hög." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.tsx:78 +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.Warning.tsx:26 +msgid "Change" +msgstr "Ändra" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:42 +msgid "Change settings" +msgstr "Ändra inställningar" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:52 +msgid "High slippage" +msgstr "Hög glidning" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:53 +msgid "Low slippage" +msgstr "Låg glidning" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:57 +msgid " Caution, your slippage is high (={userSlippage}). Your trade may be front run." +msgstr " Varning, din glidning är hög (={userSlippage}). Din handel kan köras framifrån." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:78 +msgid "Confirm anyway" +msgstr "Bekräfta ändå" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:22 +msgid "Something went wrong" +msgstr "Något gick fel" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:24 +msgid "Something went wrong. Please refresh the app." +msgstr "Något gick fel. Vänligen uppdatera appen." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/Slippage.tsx:38 +msgid "Slippage tolerance per swap" +msgstr "Slippage tolerans per swap" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/Slippage.tsx:91 +msgid "Custom" +msgstr "Anpassad" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:11 +msgid "Your transaction will be reverted if the price changes unfavorably by more than this percentage." +msgstr "Din transaktion kommer att återställas om priset ändras ogynnsamt med mer än denna procentsats." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:16 +#: widget/embedded/src/containers/Settings/Lists.tsx:245 +msgid "Warning" +msgstr "Varning" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:17 +msgid "This setting is applied to each step (e.g. 1Inch, Thorchain, etc.), meaning only that specific step will be reverted, not the entire route." +msgstr "Denna inställning tillämpas på varje steg (t.ex. 1Inch, Thorchain, etc.), vilket innebär endast att specifika steg kommer att återställas, inte hela vägen." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:25 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:269 +msgid "Swap Details" +msgstr "Växla detaljer" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:33 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:312 +msgid "Request ID" +msgstr "Begär ID" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:64 +msgid "Not found" +msgstr "Hittades inte" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:65 +msgid "Swap with request ID = {requestId} not found." +msgstr "Byt mot förfrågnings-ID = {requestId} hittades inte." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:219 +msgid "You have received {amount} {token} in {conciseAddress} wallet on {chain} chain." +msgstr "Du har fått {amount} {token} i {conciseAddress} plånboken på {chain} kedjan." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:242 +msgid "Transaction was not sent." +msgstr "Transaktionen skickades inte." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:244 +msgid "{amount} {symbol} on {blockchain} remains in your wallet." +msgstr "{amount} {symbol} på {blockchain} finns kvar i din plånbok." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:281 +msgid "Delete" +msgstr "Radera" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:304 +msgid "Try again" +msgstr "Försök igen" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:322 +msgid "Copied To Clipboard" +msgstr "Kopierad till urklipp" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:323 +msgid "Copy Request ID" +msgstr "Kopiera begäran ID" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:346 +msgid "View on Rango Explorer" +msgstr "Visa på Rango Explorer" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:355 +msgid "Finished at" +msgstr "Klart den" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:355 +msgid "Created at" +msgstr "Skapad den" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.tsx:50 +msgid "View transaction" +msgstr "Visa transaktion" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.Warning.tsx:49 +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:31 +msgid "Connect" +msgstr "Anslut" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:43 +msgid "Swap Successful" +msgstr "Byte lyckades" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:71 +msgid "Transaction Failed" +msgstr "Transaktionen misslyckades" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:87 +msgid "Done" +msgstr "Klar" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:100 +msgid "Diagnosis" +msgstr "Diagnos" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:112 +msgid "See Details" +msgstr "Se detaljer" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:13 +msgid "Cancel Swap" +msgstr "Avbryt Swap" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:14 +msgid "Are you sure you want to cancel this swap?" +msgstr "Är du säker på att du vill avbryta denna swap?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:23 +msgid "Yes, Cancel it" +msgstr "Ja, Avbryt det" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:32 +#: widget/embedded/src/pages/CustomTokensPage.tsx:181 +msgid "No, Continue" +msgstr "Nej, fortsätt" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:13 +msgid "Delete Transaction" +msgstr "Ta bort transaktion" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:14 +msgid "Are you sure you want to delete this swap?" +msgstr "Är du säker på att du vill ta bort denna swap?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:23 +#: widget/embedded/src/pages/CustomTokensPage.tsx:171 +msgid "Yes, Delete it" +msgstr "Ja, ta bort den" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:33 +#: widget/embedded/src/pages/HistoryPage.tsx:253 +msgid "No, Cancel" +msgstr "Nej, Avbryt" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:12 +msgid "Change Network" +msgstr "Ändra nätverk" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:20 +msgid "Network Changed" +msgstr "Nätverk ändrat" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/TokenList/TokenList.tsx:271 +#: widget/ui/src/containers/SwapInput/TokenSection.tsx:54 +msgid "Select Token" +msgstr "Välj token" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:27 +msgid "Wallet Connected" +msgstr "Plånbok ansluten" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:28 +msgid "Your wallet is connected, you can use it to swap." +msgstr "Din plånbok är ansluten, du kan använda den för att byta." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:39 +msgid "Failed to Connect" +msgstr "Anslutningen misslyckades" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:41 +msgid "Your wallet is not connected. Please try again." +msgstr "Din plånbok är inte ansluten. Försök igen." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:50 +msgid "Connecting to your wallet" +msgstr "Ansluter till din plånbok" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:51 +msgid "Click connect in your wallet popup." +msgstr "Klicka på anslut i din plånbok popup." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:99 +msgid "Select Derivation Path" +msgstr "Välj Derivations sökväg" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:100 +msgid "In order to connect to {type}, you must first select a Derivation Path" +msgstr "För att ansluta till {type}måste du först välja en Derivation sökväg" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:118 +msgid "Choose Derivation Path Template" +msgstr "Välj mall för Derivations sökväg" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:133 +msgid "Enter Path" +msgstr "Ange sökväg" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:134 +msgid "Enter Index" +msgstr "Ange index" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:15 +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:18 +msgid "Add {blockchainDisplayName} Chain" +msgstr "Lägg till {blockchainDisplayName} Chain" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:20 +msgid "Would you like to add the {blockchainDisplayName} experimental chain to your wallet?" +msgstr "Vill du lägga till den experimentella kedjan {blockchainDisplayName} i din plånbok?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:22 +msgid "Please approve the experimental chain pop-up in your wallet." +msgstr "Vänligen godkänn den experimentella kedjans pop-up i din plånbok." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:30 +msgid "{blockchainDisplayName} Chain Added" +msgstr "{blockchainDisplayName} kedja tillagd" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:34 +msgid "The {blockchainDisplayName} chain has been successfully added to your wallet." +msgstr "Kedjan {blockchainDisplayName} har lagts till i din plånbok." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:42 +msgid "Request Rejected" +msgstr "Begäran avvisad" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:43 +msgid "You've rejected adding {blockchainDisplayName} chain to your wallet." +msgstr "Du har avböjt att lägga till {blockchainDisplayName} kedjan i din plånbok." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:70 +msgid "Select chain types" +msgstr "Välj kedjetyper" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:71 +msgid "This wallet supports multiple chains. Select which chain you'd like to connect to." +msgstr "Denna plånbok stöder flera kedjor. Välj vilken kedja du vill ansluta till." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:9 +msgid "Failed Network, Please retry your swap." +msgstr "Det gick inte att nätverka, försök igen din swap." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:11 +msgid "Please reset your liquidity sources." +msgstr "Vänligen återställ dina likviditetskällor." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:12 +msgid "You have limited the liquidity sources and this might result in Rango finding no routes. Please consider resetting your liquidity sources." +msgstr "Du har begränsat likviditetskällorna och detta kan leda till att Rango inte hittar några rutter. Vänligen överväga att återställa dina likviditetskällor." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:17 +msgid "No Routes Found." +msgstr "Inga rutter hittade." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:18 +msgid "Reasons why Rango couldn't find a route: low liquidity on token, very low input amount or no routes available for the selected input/output token combination." +msgstr "Anledningar till varför Rango inte kunde hitta en väg: låg likviditet på token, mycket låg inmatningsbelopp eller inga rutter tillgängliga för den valda ingång/utmatningskombinationen." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:23 +msgid "Bridge Limit Error: Please increase your amount." +msgstr "Bridgegräns fel: öka ditt belopp." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:26 +msgid "Bridge Limit Error: Please decrease your amount." +msgstr "Brobegränsningsfel: Vänligen minska ditt belopp." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:31 +msgid "High Price Impact" +msgstr "Höga priseffekter" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:32 +msgid "Price impact is too high!" +msgstr "Priseffekten är för hög!" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:33 +msgid "The price impact is significantly higher than the allowed amount." +msgstr "Priseffekten är betydligt högre än det tillåtna beloppet." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:36 +msgid "Confirm high price impact" +msgstr "Bekräfta hög prispåverkan" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:39 +msgid "Route updated and price impact is too high, try again later!" +msgstr "Rutten uppdaterad och priseffekten är för hög, försök igen senare!" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:44 +msgid "USD Price Unknown" +msgstr "USD Pris Okänd" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:45 +msgid "USD Price Unknown, Cannot calculate Price Impact." +msgstr "USD Pris Okänd, Kan inte beräkna prispåverkan." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:46 +msgid "USD Price Unknown, Cannot calculate Price Impact. The price impact may be higher than usual. Are you sure to continue the Swap?" +msgstr "USD Pris Okänd, Kan inte beräkna prispåverkan. Prispåverkan kan vara högre än vanligt. Är du säker på att fortsätta Swap?" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:49 +msgid "Confirm USD Price Unknown" +msgstr "Bekräfta USD pris okänt" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:6 +#: widget/embedded/src/pages/Home.tsx:163 +msgid "Swap" +msgstr "Byt" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:7 +msgid "Swap anyway" +msgstr "Byt ändå" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:8 +msgid "The route goes through Ethereum. Continue?" +msgstr "Rutten går genom Ethereum. Fortsätt?" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:10 +msgid "Route has been updated." +msgstr "Rutten har uppdaterats." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:12 +msgid "Output amount changed to {newOutputAmount} ({percentageChange}% change)." +msgstr "Utdatabeloppet har ändrats till {newOutputAmount} ({percentageChange}% ändring)." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:20 +msgid "Route swappers has been updated." +msgstr "Utbytare av rutter har uppdaterats." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:22 +msgid "Route internal coins has been updated." +msgstr "Rutten interna mynt har uppdaterats." + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/ExpandedQuotes/ExpandedQuotes.tsx:53 +#: widget/embedded/src/pages/Routes.tsx:48 +msgid "Routes" +msgstr "Rutter" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Inputs/Inputs.tsx:76 +msgid "From" +msgstr "Från" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Inputs/Inputs.tsx:118 +msgid "To" +msgstr "Till" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:49 +msgid "Light" +msgstr "Ljus" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:58 +msgid "Dark" +msgstr "Mörk" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:67 +msgid "Auto" +msgstr "Automatiskt" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:140 +msgid "Loading failed" +msgstr "Laddningen misslyckades" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:156 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:41 +msgid "Bridges" +msgstr "Broar" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:174 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:41 +msgid "Exchanges" +msgstr "Byten" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:195 +#: widget/embedded/src/pages/CustomTokensPage.tsx:90 +msgid "Custom Tokens" +msgstr "Anpassade Tokens" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:214 +#: widget/embedded/src/pages/LanguagePage.tsx:43 +msgid "Language" +msgstr "Språk" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:235 +msgid "Infinite approval" +msgstr "Oändligt godkännande" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:246 +msgid "Enabling the 'Infinite approval' mode grants unrestricted access to underlying smart contracts, allowing them to utilize the approved token amount without limitations." +msgstr "Aktivering av Oändligt godkännande ger obegränsad åtkomst till underliggande smarta kontrakt, vilket ger dem möjlighet att använda det godkända tokenbeloppet utan begränsningar." + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:266 +msgid "Theme" +msgstr "Tema" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:39 +msgid "Duplicate Token" +msgstr "Duplicate Token" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:40 +msgid "The address you entered is duplicate, please enter a new address." +msgstr "Adressen du angav är dubblett, ange en ny adress." + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:46 +msgid "Token Already Exists" +msgstr "Token finns redan" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:47 +msgid "There's no need to add this token again because it already exists and is supported by us." +msgstr "Det finns ingen anledning att lägga till denna token igen eftersom den redan finns och stöds av oss." + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:53 +msgid "Token Not Found" +msgstr "Token hittades inte" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:54 +msgid "Sorry, no token was found on {blockchain} chain with the provided address. please make sure you have entered the right token address." +msgstr "Tyvärr, ingen token hittades på {blockchain} kedjan med den angivna adressen. Kontrollera att du har angett rätt token adress." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:78 +msgid "Network Error" +msgstr "Nätverksfel" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:109 +#: widget/embedded/src/pages/CustomTokensPage.tsx:149 +msgid "Add Custom Token" +msgstr "Lägg till anpassad token" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:127 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:128 +msgid "Select chain" +msgstr "Välj kedja" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:132 +msgid "Enter Address" +msgstr "Ange adress" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:139 +msgid "Enter token address" +msgstr "Ange token adress" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:176 +msgid "Failed Network, Please retry." +msgstr "Det gick inte att nätverka, försök igen." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:192 +msgid "Add another custom token" +msgstr "Lägg till en annan anpassad token" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:236 +msgid "Confirm Swap" +msgstr "Bekräfta byte" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:254 +msgid "Start Swap" +msgstr "Starta byte" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:282 +msgid "You get" +msgstr "Du får" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:102 +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:90 +msgid "Search Token" +msgstr "Sök Token" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:134 +msgid "No custom tokens" +msgstr "Inga anpassade tokens" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:135 +msgid "press the button to add your custom token" +msgstr "Tryck på knappen för att lägga till din anpassade token" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:158 +msgid "Delete Custom Token" +msgstr "Ta bort anpassad token" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:160 +msgid "Are you sure you want to Delete this Token?" +msgstr "Är du säker på att du vill ta bort detta token?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:59 +msgid "Complete" +msgstr "Complete" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:63 +msgid "Running" +msgstr "Körs" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:65 +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:8 +msgid "Failed" +msgstr "Misslyckades" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:149 +msgid "Clear" +msgstr "Rensa" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:161 +msgid "Search Transaction" +msgstr "Sök transaktion" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:187 +msgid "No transactions" +msgstr "Inga transaktioner" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:194 +msgid "Your transaction history is stored locally and will appear here after you start a swap" +msgstr "Din transaktionshistorik lagras lokalt och kommer att visas här när du startar ett byte" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:218 +msgid "Clear Transaction History" +msgstr "Rensa transaktionshistorik" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:222 +msgid "Proceeding will remove all successful and failed transactions from the widget. Do you want to continue?" +msgstr "Fortsättning kommer att ta bort alla lyckade och misslyckade transaktioner från widget. Vill du fortsätta?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:229 +msgid "Note: This does not erase your transaction history on the chain; it only removes them here." +msgstr "Obs: Detta raderar inte din transaktionshistorik i kedjan; det tar bara bort dem här." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:243 +msgid "Yes, Clear the history" +msgstr "Ja, Rensa historiken" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LanguagePage.tsx:56 +msgid "language" +msgstr "språk" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:121 +msgid "Deselect all" +msgstr "Avmarkera alla" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:121 +msgid "Select all" +msgstr "Markera alla" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:133 +msgid "Search {sourceType}" +msgstr "Sök {sourceType}" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectBlockchainPage.tsx:60 +msgid "Search Chain" +msgstr "Sök Kedja" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:67 +msgid "Source" +msgstr "Källa" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:68 +msgid "Destination" +msgstr "Mål" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:74 +msgid "Swap {type}" +msgstr "Byt {type}" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SettingsPage.tsx:45 +msgid "Currently, you're in campaign mode with restrictions on liquidity sources. Would you like to switch out of this mode and make use of all available liquidity sources?" +msgstr "För närvarande är du i kampanjläge med restriktioner för likviditetskällor. Vill du byta ut det här läget och utnyttja alla tillgängliga likviditetskällor?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SwapDetailsPage.tsx:27 +msgid "The request ID is necessary to display the swap details." +msgstr "Begäran ID är nödvändigt för att visa swap detaljer." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/WalletsPage.tsx:67 +#: widget/ui/src/containers/ConnectWalletsModal/ConnectWalletsModal.tsx:15 +msgid "Connect Wallets" +msgstr "Anslut plånböcker" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/WalletsPage.tsx:82 +msgid "Choose a wallet to connect." +msgstr "Välj en plånbok att ansluta." + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:25 +msgid "This week" +msgstr "Denna vecka" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:32 +msgid "This month" +msgstr "Denna månad" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:39 +msgid "This year" +msgstr "I år" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:129 +msgid "Required: >= {min} {symbol}" +msgstr "Krävs: >= {min} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:142 +msgid "Required: > {min} {symbol}" +msgstr "Krävs: > {min} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:157 +msgid "Required: <= {max} {symbol}" +msgstr "Krävs: <= {max} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:170 +msgid "Required: < {max} {symbol}" +msgstr "Krävs: < {max} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:601 +msgid " for network fee" +msgstr " för nätverksavgift" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:604 +msgid " for swap" +msgstr " för byte" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:607 +msgid " for input and network fee" +msgstr " för in- och nätverksavgift" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:609 +msgid "Needs ≈ {requiredAmount} {symbol}{reason}, but you have {currentAmount} {symbol} in your {blockchain} wallet." +msgstr "Behövs ↑ {requiredAmount} {symbol}{reason}, men du har {currentAmount} {symbol} i din {blockchain} plånbok." + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:669 +msgid "Waiting for connecting wallet" +msgstr "Väntar på att ansluta plånbok" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:673 +msgid "Waiting for other running tasks to be finished" +msgstr "Väntar på att andra pågående uppgifter ska vara klara" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:676 +msgid "Waiting for changing wallet network" +msgstr "Väntar på att byta plånboksnätverk" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:6 +msgid "Sunday" +msgstr "Söndag" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:7 +msgid "Monday" +msgstr "Måndag" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:8 +msgid "Tuesday" +msgstr "Tisdag" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:9 +msgid "Wednesday" +msgstr "Onsdag" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:10 +msgid "Thursday" +msgstr "Torsdag" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:11 +msgid "Friday" +msgstr "Fredag" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:12 +msgid "Saturday" +msgstr "Lördag" + +#. js-lingui-explicit-id +#: widget/ui/src/components/BottomLogo/BottomLogo.tsx:14 +msgid "Powered By" +msgstr "Drivs av" + +#. js-lingui-explicit-id +#: widget/ui/src/components/FullExpandedQuote/FullExpandedQuote.Tooltip.tsx:37 +msgid "Aggregated Transaction" +msgstr "Aggregerad transaktion" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SelectableCategoryList/SelectableCategoryList.tsx:63 +msgid "{blockchainCategory}" +msgstr "{blockchainCategory}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/StepDetails/StepDetails.tsx:75 +#: widget/ui/src/components/StepDetails/StepDetails.tsx:102 +msgid "Swap on {fromChain} via {swapper}" +msgstr "Byt på {fromChain} via {swapper}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/StepDetails/StepDetails.tsx:109 +msgid "Bridge to {toChain} via {swapper}" +msgstr "Bron till {toChain} via {swapper}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:10 +msgid "Completed" +msgstr "Slutförd" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:12 +msgid "In progress" +msgstr "pågår" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapToken.tsx:122 +msgid "Waiting for bridge transaction" +msgstr "Väntar på bryggtransaktion" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:12 +msgid "Connected" +msgstr "Ansluten" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:13 +msgid "Disconnect" +msgstr "Koppla från" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:18 +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:19 +msgid "Install" +msgstr "Installera" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:24 +msgid "Connecting ..." +msgstr "Ansluter ..." + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:25 +msgid "Connecting" +msgstr "Ansluter" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:30 +msgid "Disconnected" +msgstr "Frånkopplad" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:34 +msgid "you need to pass a correct state to Wallet." +msgstr "du måste skicka ett korrekt tillstånd till plånboken." + +#. js-lingui-explicit-id +#: widget/ui/src/containers/Notifications/NotificationNotFound.tsx:15 +msgid "There are no notifications." +msgstr "Det finns inga meddelanden." + +#. js-lingui-explicit-id +#: widget/ui/src/containers/Notifications/Notifications.tsx:39 +msgid "Clear all" +msgstr "Rensa alla" + +#. js-lingui-explicit-id +#: widget/ui/src/containers/SwapInput/SwapInput.tsx:65 +msgid "Balance" +msgstr "Saldo" + +#. js-lingui-explicit-id +#: widget/ui/src/containers/SwapInput/SwapInput.tsx:73 +msgid "Max" +msgstr "Max" + diff --git a/translations/sw.po b/translations/sw.po new file mode 100644 index 0000000000..48a1b265ae --- /dev/null +++ b/translations/sw.po @@ -0,0 +1,1339 @@ +msgid "" +msgstr "" +"POT-Creation-Date: 2023-11-06 17:24+0330\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: @lingui/cli\n" +"Language: sw\n" +"Project-Id-Version: rango\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2024-11-27 15:57\n" +"Last-Translator: \n" +"Language-Team: Swahili\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Crowdin-Project: rango\n" +"X-Crowdin-Project-ID: 622238\n" +"X-Crowdin-Language: sw\n" +"X-Crowdin-File: en.po\n" +"X-Crowdin-File-ID: 30\n" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SameTokensWarning/SameTokensWarning.tsx:21 +msgid "No Routes Found" +msgstr "Hakuna Njia Zilizopatikana" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SameTokensWarning/SameTokensWarning.tsx:25 +msgid "You cannot use the same token for From and To." +msgstr "Huwezi kutumia tokeni sawa kwa From na To." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:41 +#: widget/embedded/src/components/TokenList/TokenList.tsx:286 +#: widget/embedded/src/pages/HistoryPage.tsx:186 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:143 +msgid "No results found" +msgstr "Hakuna matokeo yaliyopatikana" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:42 +#: widget/embedded/src/components/TokenList/TokenList.tsx:287 +#: widget/embedded/src/pages/HistoryPage.tsx:193 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:144 +msgid "Try using different keywords" +msgstr "Jaribu kutumia maneno muhimu tofauti" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:72 +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:46 +#: widget/embedded/src/pages/SelectBlockchainPage.tsx:42 +#: widget/ui/src/containers/SwapInput/TokenSection.tsx:61 +msgid "Select Chain" +msgstr "Chagua Chain" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:66 +msgid "All" +msgstr "Wote" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:100 +msgid "More +{count}" +msgstr "Zaidi +{count}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabAlert/ActivateTabAlert.tsx:17 +msgid "Activate this tab" +msgstr "Amilisha kichupo hiki" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabAlert/ActivateTabAlert.tsx:22 +msgid "Another tab is open and handles transactions." +msgstr "Kichupo kingine kimefunguliwa na kinashughulikia shughuli." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:20 +msgid "Activate current tab" +msgstr "Washa kichupo cha sasa" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:22 +msgid "Currently, some transactions are running and being handled by other browser tab. If you activate this tab, all transactions that are already in the transaction sign step will expire." +msgstr "Hivi sasa, baadhi ya miamala inaendelea na inashughulikiwa na kichupo kingine cha kivinjari. Ukiwezesha kichupo hiki, miamala yote ambayo tayari iko katika hatua ya ishara ya muamala itaisha." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:33 +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:349 +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:152 +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:33 +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:116 +msgid "Confirm" +msgstr "Thibitisha" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:365 +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:447 +msgid "Your {blockchainName} wallets" +msgstr "Pochi zako {blockchainName}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:384 +msgid "Insufficient account balance" +msgstr "Salio la akaunti halitoshi" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:394 +msgid "Proceed anyway" +msgstr "Endelea hata hivyo" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:456 +msgid "You need to connect a {blockchainName} wallet." +msgstr "Unahitaji kuunganisha mkoba {blockchainName} ." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/WalletList.tsx:143 +msgid "Add {chain} chain" +msgstr "Ongeza {chain} mnyororo" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/WalletList.tsx:244 +msgid "Show more wallets" +msgstr "Onyesha pochi zaidi" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:113 +msgid "Send to a different address" +msgstr "Tuma kwa anwani tofauti" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:129 +msgid "Enter {blockchainName} address" +msgstr "Ingiza {blockchainName} anwani" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:147 +msgid "Address {destination} doesn't match the blockchain address pattern." +msgstr "Anwani {destination} hailingani na muundo wa anwani ya blockchain." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:59 +msgid "via" +msgstr "kupitia" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:74 +msgid "This token doesn't appear on the active token list(s). Make sure this is the token that you want to trade." +msgstr "Tokeni hii haionekani kwenye orodha ya tokeni inayotumika. Hakikisha kuwa hii ndiyo ishara unayotaka kufanya biashara." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:89 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:164 +msgid "Import" +msgstr "Ingiza" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/FilterSelector/FilterSelectorContent.tsx:26 +msgid "Status" +msgstr "Hali" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/FilterSelector/FilterSelectorContent.tsx:33 +#: widget/embedded/src/components/NoResult/NoResult.helpers.ts:37 +#: widget/embedded/src/pages/SettingsPage.tsx:55 +msgid "Reset" +msgstr "Weka upya" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/CancelButton.tsx:18 +msgid "Cancel" +msgstr "Ghairi" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:46 +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:34 +msgid "Refresh" +msgstr "Onyesha upya" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:63 +#: widget/ui/src/containers/Notifications/Notifications.tsx:35 +msgid "Notifications" +msgstr "Arifa" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:79 +#: widget/embedded/src/pages/SettingsPage.tsx:38 +msgid "Settings" +msgstr "Mipangilio" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:93 +#: widget/embedded/src/pages/HistoryPage.tsx:139 +msgid "History" +msgstr "Historia" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/WalletButton.tsx:22 +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:16 +#: widget/embedded/src/constants/messages.ts:5 +msgid "Connect Wallet" +msgstr "Unganisha Wallet" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HistoryGroupedList/HistoryGroupedList.tsx:118 +#: widget/embedded/src/utils/date.ts:18 +#: widget/embedded/src/utils/time.ts:22 +msgid "Today" +msgstr "Leo" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/LoadingSwapDetails/LoadingSwapDetails.tsx:20 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:424 +msgid "Swaps steps" +msgstr "Hubadilisha hatua" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/NoResult/NoResult.helpers.ts:25 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:191 +msgid "Retry" +msgstr "Jaribu tena" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:149 +msgid "Slippage Error" +msgstr "Hitilafu ya Kuteleza" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:150 +msgid "Slippage Warning" +msgstr "Onyo la Kuteleza" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:153 +msgid "Bridge Limit Error" +msgstr "Hitilafu ya Kikomo cha Daraja" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:240 +msgid "Yours: {amount} {symbol}" +msgstr "Wako: {amount} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:261 +msgid "Minimum required slippage: {minRequiredSlippage}" +msgstr "Kima cha chini cha utelezi kinachohitajika: {minRequiredSlippage}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:282 +msgid "Yours: {userSlippage}" +msgstr "Wako: {userSlippage}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:395 +msgid "See All Routes" +msgstr "Angalia Njia Zote" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:81 +msgid "View more info" +msgstr "Tazama maelezo zaidi" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:91 +msgid "Gas & Fee Explanation" +msgstr "Maelezo ya Gesi na Ada" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:107 +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:103 +msgid "Details" +msgstr "Maelezo" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:146 +msgid "Total Payable Fee" +msgstr "Ada ya Jumla Inayolipwa" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:166 +msgid "Hide non-payable fees" +msgstr "Ficha ada zisizolipiwa" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:167 +msgid "Show non-payable fees" +msgstr "Onyesha ada zisizolipiwa" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:177 +msgid "Description" +msgstr "Maelezo" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:181 +msgid "The following fees are considered in the transaction output and\n" +" you won’t need to pay extra gas for them." +msgstr "Ada zifuatazo zinazingatiwa katika matokeo ya muamala na\n" +" hutahitaji kuzilipia gesi ya ziada." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteSummary.tsx:25 +msgid "Swap input" +msgstr "Badilisha pembejeo" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteSummary.tsx:44 +msgid "Estimated output" +msgstr "Kadirio la matokeo" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteTrigger.tsx:65 +msgid "Via:" +msgstr "Kupitia:" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteTrigger.tsx:150 +msgid "Chains:" +msgstr "Minyororo:" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/Quotes.tsx:77 +msgid "Sort by" +msgstr "Panga kwa" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:17 +msgid "Smart Routing" +msgstr "Smart Routing" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:21 +msgid "Lowest Fee" +msgstr "Ada ya chini kabisa" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:25 +msgid "Fastest Transfer" +msgstr "Uhamisho wa haraka zaidi" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:29 +msgid "Maximum Return" +msgstr "Upeo wa Kurudi" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:33 +msgid "Maximum Output" +msgstr "Upeo wa Pato" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:43 +msgid "Swapping" +msgstr "Kubadilishana" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:51 +msgid "Gas cost" +msgstr "Gharama ya gesi" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:59 +msgid "Receiving" +msgstr "Kupokea" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:67 +msgid "Price impact" +msgstr "Athari ya bei" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:35 +msgid "You need to increase slippage to at least {minRequiredSlippage} for this route." +msgstr "Unahitaji kuongeza utelezi hadi angalau {minRequiredSlippage} kwa njia hii." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:59 +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:61 +msgid "We recommend you to increase slippage to at least {minRequiredSlippage} for this route." +msgstr "Tunapendekeza uongeze utelezi hadi angalau {minRequiredSlippage} kwa njia hii." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:68 +msgid "Caution, your slippage is high." +msgstr "Tahadhari, utelezi wako uko juu." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.tsx:78 +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.Warning.tsx:26 +msgid "Change" +msgstr "Badilika" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:42 +msgid "Change settings" +msgstr "Badilisha mipangilio" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:52 +msgid "High slippage" +msgstr "Utelezi wa hali ya juu" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:53 +msgid "Low slippage" +msgstr "Utelezi mdogo" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:57 +msgid " Caution, your slippage is high (={userSlippage}). Your trade may be front run." +msgstr " Tahadhari, utelezi wako uko juu (={userSlippage}). Biashara yako inaweza kuwa ya mbele." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:78 +msgid "Confirm anyway" +msgstr "Thibitisha hata hivyo" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:22 +msgid "Something went wrong" +msgstr "Hitilafu fulani imetokea" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:24 +msgid "Something went wrong. Please refresh the app." +msgstr "Hitilafu fulani imetokea. Tafadhali onyesha upya programu." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/Slippage.tsx:38 +msgid "Slippage tolerance per swap" +msgstr "Uvumilivu wa kuteleza kwa ubadilishaji" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/Slippage.tsx:91 +msgid "Custom" +msgstr "Desturi" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:11 +msgid "Your transaction will be reverted if the price changes unfavorably by more than this percentage." +msgstr "Muamala wako utarejeshwa ikiwa bei itabadilika isivyofaa kwa zaidi ya asilimia hii." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:16 +#: widget/embedded/src/containers/Settings/Lists.tsx:245 +msgid "Warning" +msgstr "Onyo" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:17 +msgid "This setting is applied to each step (e.g. 1Inch, Thorchain, etc.), meaning only that specific step will be reverted, not the entire route." +msgstr "Mpangilio huu unatumika kwa kila hatua (km 1Inch, Thorchain, n.k.), ikimaanisha tu hatua hiyo mahususi itarejeshwa, si njia nzima." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:25 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:269 +msgid "Swap Details" +msgstr "Badilisha Maelezo" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:33 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:312 +msgid "Request ID" +msgstr "Ombi la kitambulisho" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:64 +msgid "Not found" +msgstr "Haijapatikana" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:65 +msgid "Swap with request ID = {requestId} not found." +msgstr "Badili na ID ya ombi = {requestId} haijapatikana." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:219 +msgid "You have received {amount} {token} in {conciseAddress} wallet on {chain} chain." +msgstr "Umepokea {amount} {token} in {conciseAddress} wallet kwenye {chain} mnyororo." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:242 +msgid "Transaction was not sent." +msgstr "Muamala haukutumwa." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:244 +msgid "{amount} {symbol} on {blockchain} remains in your wallet." +msgstr "{amount} {symbol} on {blockchain} inabaki kwenye pochi yako." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:281 +msgid "Delete" +msgstr "Futa" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:304 +msgid "Try again" +msgstr "Jaribu tena" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:322 +msgid "Copied To Clipboard" +msgstr "Imenakiliwa kwenye Ubao wa kunakili" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:323 +msgid "Copy Request ID" +msgstr "Nakili Kitambulisho cha Ombi" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:346 +msgid "View on Rango Explorer" +msgstr "Tazama kwenye Rango Explorer" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:355 +msgid "Finished at" +msgstr "Imekamilika saa" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:355 +msgid "Created at" +msgstr "Imeundwa saa" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.tsx:50 +msgid "View transaction" +msgstr "Tazama muamala" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.Warning.tsx:49 +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:31 +msgid "Connect" +msgstr "Unganisha" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:43 +msgid "Swap Successful" +msgstr "Kubadilishana Kumefaulu" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:71 +msgid "Transaction Failed" +msgstr "Muamala Umeshindwa" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:87 +msgid "Done" +msgstr "Imekamilika" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:100 +msgid "Diagnosis" +msgstr "Utambuzi" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:112 +msgid "See Details" +msgstr "Tazama Maelezo" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:13 +msgid "Cancel Swap" +msgstr "Ghairi Ubadilishanaji" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:14 +msgid "Are you sure you want to cancel this swap?" +msgstr "Je, una uhakika unataka kughairi ubadilishaji huu?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:23 +msgid "Yes, Cancel it" +msgstr "Ndiyo, Ghairi" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:32 +#: widget/embedded/src/pages/CustomTokensPage.tsx:181 +msgid "No, Continue" +msgstr "Hapana, Endelea" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:13 +msgid "Delete Transaction" +msgstr "Futa Muamala" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:14 +msgid "Are you sure you want to delete this swap?" +msgstr "Je, una uhakika unataka kufuta ubadilishaji huu?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:23 +#: widget/embedded/src/pages/CustomTokensPage.tsx:171 +msgid "Yes, Delete it" +msgstr "Ndiyo, Futa" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:33 +#: widget/embedded/src/pages/HistoryPage.tsx:253 +msgid "No, Cancel" +msgstr "Hapana, Ghairi" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:12 +msgid "Change Network" +msgstr "Badilisha Mtandao" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:20 +msgid "Network Changed" +msgstr "Mtandao Umebadilishwa" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/TokenList/TokenList.tsx:271 +#: widget/ui/src/containers/SwapInput/TokenSection.tsx:54 +msgid "Select Token" +msgstr "Chagua Tokeni" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:27 +msgid "Wallet Connected" +msgstr "Wallet Imeunganishwa" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:28 +msgid "Your wallet is connected, you can use it to swap." +msgstr "Pochi yako imeunganishwa, unaweza kuitumia kubadilishana." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:39 +msgid "Failed to Connect" +msgstr "Imeshindwa Kuunganisha" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:41 +msgid "Your wallet is not connected. Please try again." +msgstr "Mkoba wako haujaunganishwa. Tafadhali jaribu tena." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:50 +msgid "Connecting to your wallet" +msgstr "Inaunganisha kwenye pochi yako" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:51 +msgid "Click connect in your wallet popup." +msgstr "Bofya unganisha kwenye dirisha ibukizi la mkoba wako." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:99 +msgid "Select Derivation Path" +msgstr "Chagua Njia ya Utoaji" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:100 +msgid "In order to connect to {type}, you must first select a Derivation Path" +msgstr "Ili kuunganisha kwa {type}, lazima kwanza uchague Njia ya Utokaji" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:118 +msgid "Choose Derivation Path Template" +msgstr "Chagua Kiolezo cha Njia ya Utoaji" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:133 +msgid "Enter Path" +msgstr "Ingiza Njia" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:134 +msgid "Enter Index" +msgstr "Ingiza Index" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:15 +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:18 +msgid "Add {blockchainDisplayName} Chain" +msgstr "Ongeza {blockchainDisplayName} Mnyororo" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:20 +msgid "Would you like to add the {blockchainDisplayName} experimental chain to your wallet?" +msgstr "Je, ungependa kuongeza msururu wa majaribio wa {blockchainDisplayName} kwenye pochi yako?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:22 +msgid "Please approve the experimental chain pop-up in your wallet." +msgstr "Tafadhali idhinisha msururu wa ibukizi wa majaribio kwenye pochi yako." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:30 +msgid "{blockchainDisplayName} Chain Added" +msgstr "{blockchainDisplayName} Mnyororo Umeongezwa" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:34 +msgid "The {blockchainDisplayName} chain has been successfully added to your wallet." +msgstr "Msururu wa {blockchainDisplayName} umeongezwa kwa mkoba wako." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:42 +msgid "Request Rejected" +msgstr "Ombi Limekataliwa" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:43 +msgid "You've rejected adding {blockchainDisplayName} chain to your wallet." +msgstr "Umekataa kuongeza {blockchainDisplayName} mnyororo kwenye pochi yako." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:70 +msgid "Select chain types" +msgstr "Chagua aina za mnyororo" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:71 +msgid "This wallet supports multiple chains. Select which chain you'd like to connect to." +msgstr "Mkoba huu unasaidia minyororo mingi. Chagua ni msururu gani ungependa kuunganisha." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:9 +msgid "Failed Network, Please retry your swap." +msgstr "Mtandao Umeshindwa, Tafadhali jaribu tena kubadilishana kwako." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:11 +msgid "Please reset your liquidity sources." +msgstr "Tafadhali weka upya vyanzo vyako vya ukwasi." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:12 +msgid "You have limited the liquidity sources and this might result in Rango finding no routes. Please consider resetting your liquidity sources." +msgstr "Umedhibiti vyanzo vya ukwasi na hii inaweza kusababisha Rango isipate njia. Tafadhali zingatia kuweka upya vyanzo vyako vya ukwasi." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:17 +msgid "No Routes Found." +msgstr "Hakuna Njia Zilizopatikana." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:18 +msgid "Reasons why Rango couldn't find a route: low liquidity on token, very low input amount or no routes available for the selected input/output token combination." +msgstr "Sababu kwa nini Rango haikuweza kupata njia: ukwasi mdogo kwenye tokeni, kiasi kidogo sana cha ingizo au hakuna njia zinazopatikana kwa mseto uliochaguliwa wa tokeni." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:23 +msgid "Bridge Limit Error: Please increase your amount." +msgstr "Hitilafu ya Kikomo cha Daraja: Tafadhali ongeza kiasi chako." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:26 +msgid "Bridge Limit Error: Please decrease your amount." +msgstr "Hitilafu ya Kikomo cha Daraja: Tafadhali punguza kiasi chako." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:31 +msgid "High Price Impact" +msgstr "Athari ya Bei ya Juu" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:32 +msgid "Price impact is too high!" +msgstr "Athari ya bei ni kubwa mno!" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:33 +msgid "The price impact is significantly higher than the allowed amount." +msgstr "Athari ya bei ni kubwa zaidi kuliko kiasi kinachoruhusiwa." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:36 +msgid "Confirm high price impact" +msgstr "Thibitisha athari ya bei ya juu" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:39 +msgid "Route updated and price impact is too high, try again later!" +msgstr "Njia imesasishwa na athari ya bei ni kubwa mno, jaribu tena baadaye!" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:44 +msgid "USD Price Unknown" +msgstr "Bei ya USD Haijulikani" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:45 +msgid "USD Price Unknown, Cannot calculate Price Impact." +msgstr "Bei ya USD Haijulikani, Haiwezi kukokotoa Athari ya Bei." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:46 +msgid "USD Price Unknown, Cannot calculate Price Impact. The price impact may be higher than usual. Are you sure to continue the Swap?" +msgstr "Bei ya USD Haijulikani, Haiwezi kukokotoa Athari ya Bei. Athari ya bei inaweza kuwa kubwa kuliko kawaida. Je, una uhakika kuendelea Kubadilishana?" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:49 +msgid "Confirm USD Price Unknown" +msgstr "Thibitisha Bei ya USD Haijulikani" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:6 +#: widget/embedded/src/pages/Home.tsx:163 +msgid "Swap" +msgstr "Badili" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:7 +msgid "Swap anyway" +msgstr "Badili hata hivyo" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:8 +msgid "The route goes through Ethereum. Continue?" +msgstr "Njia inapitia Ethereum. Ungependa kuendelea?" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:10 +msgid "Route has been updated." +msgstr "Njia imesasishwa." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:12 +msgid "Output amount changed to {newOutputAmount} ({percentageChange}% change)." +msgstr "Kiasi cha pato kimebadilishwa hadi {newOutputAmount} ({percentageChange}% badilisha)." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:20 +msgid "Route swappers has been updated." +msgstr "Vibadilishaji njia vimesasishwa." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:22 +msgid "Route internal coins has been updated." +msgstr "Sarafu za ndani za njia zimesasishwa." + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/ExpandedQuotes/ExpandedQuotes.tsx:53 +#: widget/embedded/src/pages/Routes.tsx:48 +msgid "Routes" +msgstr "Njia" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Inputs/Inputs.tsx:76 +msgid "From" +msgstr "Kutoka" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Inputs/Inputs.tsx:118 +msgid "To" +msgstr "Kwa" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:49 +msgid "Light" +msgstr "Mwanga" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:58 +msgid "Dark" +msgstr "Giza" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:67 +msgid "Auto" +msgstr "Otomatiki" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:140 +msgid "Loading failed" +msgstr "Imeshindwa kupakia" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:156 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:41 +msgid "Bridges" +msgstr "Madaraja" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:174 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:41 +msgid "Exchanges" +msgstr "Mabadilishano" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:195 +#: widget/embedded/src/pages/CustomTokensPage.tsx:90 +msgid "Custom Tokens" +msgstr "Ishara Maalum" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:214 +#: widget/embedded/src/pages/LanguagePage.tsx:43 +msgid "Language" +msgstr "Lugha" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:235 +msgid "Infinite approval" +msgstr "Idhini isiyo na kikomo" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:246 +msgid "Enabling the 'Infinite approval' mode grants unrestricted access to underlying smart contracts, allowing them to utilize the approved token amount without limitations." +msgstr "Kuwasha hali ya 'Uidhinishaji usio na kikomo' hutoa ufikiaji usio na kikomo kwa mikataba ya msingi mahiri, na kuwaruhusu kutumia kiasi cha tokeni kilichoidhinishwa bila vikwazo." + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:266 +msgid "Theme" +msgstr "Mandhari" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:39 +msgid "Duplicate Token" +msgstr "Tokeni Nakala" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:40 +msgid "The address you entered is duplicate, please enter a new address." +msgstr "Anwani uliyoweka ni nakala, tafadhali weka anwani mpya." + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:46 +msgid "Token Already Exists" +msgstr "Ishara Tayari Ipo" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:47 +msgid "There's no need to add this token again because it already exists and is supported by us." +msgstr "Hakuna haja ya kuongeza tokeni hii tena kwa sababu tayari ipo na tunaitumia." + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:53 +msgid "Token Not Found" +msgstr "Ishara Haijapatikana" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:54 +msgid "Sorry, no token was found on {blockchain} chain with the provided address. please make sure you have entered the right token address." +msgstr "Samahani, hakuna tokeni iliyopatikana kwenye mnyororo wa {blockchain} na anwani iliyotolewa. tafadhali hakikisha kuwa umeingiza anwani sahihi ya tokeni." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:78 +msgid "Network Error" +msgstr "Hitilafu ya Mtandao" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:109 +#: widget/embedded/src/pages/CustomTokensPage.tsx:149 +msgid "Add Custom Token" +msgstr "Ongeza Tokeni Maalum" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:127 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:128 +msgid "Select chain" +msgstr "Chagua mnyororo" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:132 +msgid "Enter Address" +msgstr "Weka Anwani" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:139 +msgid "Enter token address" +msgstr "Weka anwani ya ishara" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:176 +msgid "Failed Network, Please retry." +msgstr "Mtandao Umeshindwa, Tafadhali jaribu tena." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:192 +msgid "Add another custom token" +msgstr "Ongeza tokeni nyingine maalum" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:236 +msgid "Confirm Swap" +msgstr "Thibitisha Kubadilishana" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:254 +msgid "Start Swap" +msgstr "Anza Kubadilishana" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:282 +msgid "You get" +msgstr "Unapata" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:102 +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:90 +msgid "Search Token" +msgstr "Tafuta Tokeni" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:134 +msgid "No custom tokens" +msgstr "Hakuna tokeni maalum" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:135 +msgid "press the button to add your custom token" +msgstr "bonyeza kitufe ili kuongeza tokeni yako maalum" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:158 +msgid "Delete Custom Token" +msgstr "Futa Tokeni Maalum" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:160 +msgid "Are you sure you want to Delete this Token?" +msgstr "Je, una uhakika unataka Kufuta Tokeni hii?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:59 +msgid "Complete" +msgstr "Kamilisha" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:63 +msgid "Running" +msgstr "Kukimbia" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:65 +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:8 +msgid "Failed" +msgstr "Imeshindwa" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:149 +msgid "Clear" +msgstr "Wazi" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:161 +msgid "Search Transaction" +msgstr "Tafuta Muamala" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:187 +msgid "No transactions" +msgstr "Hakuna shughuli" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:194 +msgid "Your transaction history is stored locally and will appear here after you start a swap" +msgstr "Historia yako ya muamala imehifadhiwa ndani na itaonekana hapa baada ya kuanza kubadilishana" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:218 +msgid "Clear Transaction History" +msgstr "Futa Historia ya Muamala" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:222 +msgid "Proceeding will remove all successful and failed transactions from the widget. Do you want to continue?" +msgstr "Kuendelea kutaondoa miamala yote iliyofaulu na iliyofeli kwenye wijeti. Je, ungependa kuendelea?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:229 +msgid "Note: This does not erase your transaction history on the chain; it only removes them here." +msgstr "Kumbuka: Hii haifuti historia yako ya muamala kwenye msururu; inawaondoa hapa tu." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:243 +msgid "Yes, Clear the history" +msgstr "Ndiyo, Futa historia" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LanguagePage.tsx:56 +msgid "language" +msgstr "lugha" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:121 +msgid "Deselect all" +msgstr "Acha kuchagua zote" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:121 +msgid "Select all" +msgstr "Chagua zote" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:133 +msgid "Search {sourceType}" +msgstr "Tafuta {sourceType}" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectBlockchainPage.tsx:60 +msgid "Search Chain" +msgstr "Msururu wa Utafutaji" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:67 +msgid "Source" +msgstr "Chanzo" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:68 +msgid "Destination" +msgstr "Marudio" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:74 +msgid "Swap {type}" +msgstr "Badilisha {type}" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SettingsPage.tsx:45 +msgid "Currently, you're in campaign mode with restrictions on liquidity sources. Would you like to switch out of this mode and make use of all available liquidity sources?" +msgstr "Kwa sasa, uko katika hali ya kampeni na vikwazo kwenye vyanzo vya ukwasi. Je, ungependa kuondoka kwenye hali hii na kutumia vyanzo vyote vya ukwasi vinavyopatikana?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SwapDetailsPage.tsx:27 +msgid "The request ID is necessary to display the swap details." +msgstr "Kitambulisho cha ombi ni muhimu ili kuonyesha maelezo ya kubadilishana." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/WalletsPage.tsx:67 +#: widget/ui/src/containers/ConnectWalletsModal/ConnectWalletsModal.tsx:15 +msgid "Connect Wallets" +msgstr "Unganisha Pochi" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/WalletsPage.tsx:82 +msgid "Choose a wallet to connect." +msgstr "Chagua mkoba ili kuunganisha." + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:25 +msgid "This week" +msgstr "Wiki hii" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:32 +msgid "This month" +msgstr "Mwezi huu" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:39 +msgid "This year" +msgstr "Mwaka huu" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:129 +msgid "Required: >= {min} {symbol}" +msgstr "Inahitajika: >= {min} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:142 +msgid "Required: > {min} {symbol}" +msgstr "Inahitajika: > {min} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:157 +msgid "Required: <= {max} {symbol}" +msgstr "Inahitajika: <= {max} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:170 +msgid "Required: < {max} {symbol}" +msgstr "Inahitajika: < {max} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:601 +msgid " for network fee" +msgstr " kwa ada ya mtandao" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:604 +msgid " for swap" +msgstr " kwa kubadilishana" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:607 +msgid " for input and network fee" +msgstr " kwa pembejeo na ada ya mtandao" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:609 +msgid "Needs ≈ {requiredAmount} {symbol}{reason}, but you have {currentAmount} {symbol} in your {blockchain} wallet." +msgstr "Inahitaji ≈ {requiredAmount} {symbol}{reason}, lakini unayo {currentAmount} {symbol} kwenye mkoba wako wa {blockchain} ." + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:669 +msgid "Waiting for connecting wallet" +msgstr "Inasubiri kuunganisha pochi" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:673 +msgid "Waiting for other running tasks to be finished" +msgstr "Inasubiri kazi zingine zinazoendeshwa zikamilike" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:676 +msgid "Waiting for changing wallet network" +msgstr "Inasubiri kubadilisha mtandao wa pochi" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:6 +msgid "Sunday" +msgstr "Jumapili" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:7 +msgid "Monday" +msgstr "Jumatatu" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:8 +msgid "Tuesday" +msgstr "Jumanne" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:9 +msgid "Wednesday" +msgstr "Jumatano" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:10 +msgid "Thursday" +msgstr "Alhamisi" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:11 +msgid "Friday" +msgstr "Ijumaa" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:12 +msgid "Saturday" +msgstr "Jumamosi" + +#. js-lingui-explicit-id +#: widget/ui/src/components/BottomLogo/BottomLogo.tsx:14 +msgid "Powered By" +msgstr "Inaendeshwa Na" + +#. js-lingui-explicit-id +#: widget/ui/src/components/FullExpandedQuote/FullExpandedQuote.Tooltip.tsx:37 +msgid "Aggregated Transaction" +msgstr "Muamala Uliojumlishwa" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SelectableCategoryList/SelectableCategoryList.tsx:63 +msgid "{blockchainCategory}" +msgstr "{blockchainCategory}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/StepDetails/StepDetails.tsx:75 +#: widget/ui/src/components/StepDetails/StepDetails.tsx:102 +msgid "Swap on {fromChain} via {swapper}" +msgstr "Badili kwa {fromChain} kupitia {swapper}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/StepDetails/StepDetails.tsx:109 +msgid "Bridge to {toChain} via {swapper}" +msgstr "Daraja hadi {toChain} kupitia {swapper}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:10 +msgid "Completed" +msgstr "Imekamilika" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:12 +msgid "In progress" +msgstr "Inaendelea" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapToken.tsx:122 +msgid "Waiting for bridge transaction" +msgstr "Inasubiri muamala wa daraja" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:12 +msgid "Connected" +msgstr "Imeunganishwa" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:13 +msgid "Disconnect" +msgstr "Tenganisha" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:18 +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:19 +msgid "Install" +msgstr "Sakinisha" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:24 +msgid "Connecting ..." +msgstr "Inaunganisha..." + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:25 +msgid "Connecting" +msgstr "Inaunganisha" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:30 +msgid "Disconnected" +msgstr "Imetenganishwa" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:34 +msgid "you need to pass a correct state to Wallet." +msgstr "unahitaji kupitisha hali sahihi kwa Wallet." + +#. js-lingui-explicit-id +#: widget/ui/src/containers/Notifications/NotificationNotFound.tsx:15 +msgid "There are no notifications." +msgstr "Hakuna arifa." + +#. js-lingui-explicit-id +#: widget/ui/src/containers/Notifications/Notifications.tsx:39 +msgid "Clear all" +msgstr "Futa zote" + +#. js-lingui-explicit-id +#: widget/ui/src/containers/SwapInput/SwapInput.tsx:65 +msgid "Balance" +msgstr "Mizani" + +#. js-lingui-explicit-id +#: widget/ui/src/containers/SwapInput/SwapInput.tsx:73 +msgid "Max" +msgstr "Max" + diff --git a/translations/th.po b/translations/th.po new file mode 100644 index 0000000000..c9c3a05b58 --- /dev/null +++ b/translations/th.po @@ -0,0 +1,1339 @@ +msgid "" +msgstr "" +"POT-Creation-Date: 2023-11-06 17:24+0330\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: @lingui/cli\n" +"Language: th\n" +"Project-Id-Version: rango\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2024-11-27 15:57\n" +"Last-Translator: \n" +"Language-Team: Thai\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Crowdin-Project: rango\n" +"X-Crowdin-Project-ID: 622238\n" +"X-Crowdin-Language: th\n" +"X-Crowdin-File: en.po\n" +"X-Crowdin-File-ID: 30\n" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SameTokensWarning/SameTokensWarning.tsx:21 +msgid "No Routes Found" +msgstr "ไม่พบเส้นทาง" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SameTokensWarning/SameTokensWarning.tsx:25 +msgid "You cannot use the same token for From and To." +msgstr "คุณไม่สามารถใช้โทเค็นเดียวกันสำหรับจากและถึงได้" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:41 +#: widget/embedded/src/components/TokenList/TokenList.tsx:286 +#: widget/embedded/src/pages/HistoryPage.tsx:186 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:143 +msgid "No results found" +msgstr "ไม่พบผลลัพธ์" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:42 +#: widget/embedded/src/components/TokenList/TokenList.tsx:287 +#: widget/embedded/src/pages/HistoryPage.tsx:193 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:144 +msgid "Try using different keywords" +msgstr "ลองใช้คำสำคัญอื่น ๆ" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:72 +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:46 +#: widget/embedded/src/pages/SelectBlockchainPage.tsx:42 +#: widget/ui/src/containers/SwapInput/TokenSection.tsx:61 +msgid "Select Chain" +msgstr "เลือกโซ่" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:66 +msgid "All" +msgstr "ทั้งหมด" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:100 +msgid "More +{count}" +msgstr "เพิ่มเติม +{count}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabAlert/ActivateTabAlert.tsx:17 +msgid "Activate this tab" +msgstr "เปิดใช้งานแท็บนี้" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabAlert/ActivateTabAlert.tsx:22 +msgid "Another tab is open and handles transactions." +msgstr "มีแท็บอื่นเปิดอยู่และจัดการธุรกรรม" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:20 +msgid "Activate current tab" +msgstr "เปิดใช้งานแท็บปัจจุบัน" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:22 +msgid "Currently, some transactions are running and being handled by other browser tab. If you activate this tab, all transactions that are already in the transaction sign step will expire." +msgstr "ขณะนี้มีการดำเนินการธุรกรรมบางอย่างและถูกจัดการโดยแท็บเบราว์เซอร์อื่น หากคุณเปิดใช้งานแท็บนี้ ธุรกรรมทั้งหมดที่อยู่ในขั้นตอนการลงนามธุรกรรมจะหมดอายุ" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:33 +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:349 +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:152 +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:33 +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:116 +msgid "Confirm" +msgstr "ยืนยัน" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:365 +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:447 +msgid "Your {blockchainName} wallets" +msgstr "กระเป๋าสตางค์ {blockchainName} ของคุณ" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:384 +msgid "Insufficient account balance" +msgstr "ยอดเงินในบัญชีไม่เพียงพอ" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:394 +msgid "Proceed anyway" +msgstr "ดำเนินการต่อไป" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:456 +msgid "You need to connect a {blockchainName} wallet." +msgstr "คุณต้องเชื่อมต่อกระเป๋าเงิน {blockchainName}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/WalletList.tsx:143 +msgid "Add {chain} chain" +msgstr "เพิ่มโซ่ {chain}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/WalletList.tsx:244 +msgid "Show more wallets" +msgstr "แสดงกระเป๋าสตางค์เพิ่มเติม" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:113 +msgid "Send to a different address" +msgstr "ส่งไปยังที่อยู่อื่น" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:129 +msgid "Enter {blockchainName} address" +msgstr "กรอกที่อยู่ {blockchainName}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:147 +msgid "Address {destination} doesn't match the blockchain address pattern." +msgstr "ที่อยู่ {destination} ไม่ตรงกับรูปแบบที่อยู่บล็อคเชน" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:59 +msgid "via" +msgstr "ทาง" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:74 +msgid "This token doesn't appear on the active token list(s). Make sure this is the token that you want to trade." +msgstr "โทเค็นนี้จะไม่ปรากฏในรายการโทเค็นที่ใช้งาน โปรดตรวจสอบให้แน่ใจว่านี่คือโทเค็นที่คุณต้องการแลกเปลี่ยน" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:89 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:164 +msgid "Import" +msgstr "การนำเข้า" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/FilterSelector/FilterSelectorContent.tsx:26 +msgid "Status" +msgstr "สถานะ" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/FilterSelector/FilterSelectorContent.tsx:33 +#: widget/embedded/src/components/NoResult/NoResult.helpers.ts:37 +#: widget/embedded/src/pages/SettingsPage.tsx:55 +msgid "Reset" +msgstr "รีเซ็ต" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/CancelButton.tsx:18 +msgid "Cancel" +msgstr "ยกเลิก" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:46 +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:34 +msgid "Refresh" +msgstr "รีเฟรช" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:63 +#: widget/ui/src/containers/Notifications/Notifications.tsx:35 +msgid "Notifications" +msgstr "การแจ้งเตือน" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:79 +#: widget/embedded/src/pages/SettingsPage.tsx:38 +msgid "Settings" +msgstr "การตั้งค่า" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:93 +#: widget/embedded/src/pages/HistoryPage.tsx:139 +msgid "History" +msgstr "ประวัติศาสตร์" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/WalletButton.tsx:22 +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:16 +#: widget/embedded/src/constants/messages.ts:5 +msgid "Connect Wallet" +msgstr "เชื่อมต่อกระเป๋าสตางค์" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HistoryGroupedList/HistoryGroupedList.tsx:118 +#: widget/embedded/src/utils/date.ts:18 +#: widget/embedded/src/utils/time.ts:22 +msgid "Today" +msgstr "วันนี้" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/LoadingSwapDetails/LoadingSwapDetails.tsx:20 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:424 +msgid "Swaps steps" +msgstr "สลับขั้นตอน" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/NoResult/NoResult.helpers.ts:25 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:191 +msgid "Retry" +msgstr "ลองใหม่อีกครั้ง" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:149 +msgid "Slippage Error" +msgstr "ข้อผิดพลาดการลื่นไถล" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:150 +msgid "Slippage Warning" +msgstr "คำเตือนการลื่นไถล" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:153 +msgid "Bridge Limit Error" +msgstr "ข้อผิดพลาดการจำกัดสะพาน" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:240 +msgid "Yours: {amount} {symbol}" +msgstr "ของคุณ: {amount} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:261 +msgid "Minimum required slippage: {minRequiredSlippage}" +msgstr "ค่าสลิปเปจขั้นต่ำที่ต้องการ: {minRequiredSlippage}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:282 +msgid "Yours: {userSlippage}" +msgstr "ของคุณ: {userSlippage}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:395 +msgid "See All Routes" +msgstr "ดูเส้นทางทั้งหมด" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:81 +msgid "View more info" +msgstr "ดูข้อมูลเพิ่มเติม" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:91 +msgid "Gas & Fee Explanation" +msgstr "คำอธิบายเกี่ยวกับก๊าซและค่าธรรมเนียม" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:107 +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:103 +msgid "Details" +msgstr "รายละเอียด" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:146 +msgid "Total Payable Fee" +msgstr "ค่าธรรมเนียมรวมที่ต้องชำระ" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:166 +msgid "Hide non-payable fees" +msgstr "ซ่อนค่าธรรมเนียมที่ไม่ต้องชำระ" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:167 +msgid "Show non-payable fees" +msgstr "แสดงค่าธรรมเนียมที่ไม่ต้องชำระ" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:177 +msgid "Description" +msgstr "คำอธิบาย" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:181 +msgid "The following fees are considered in the transaction output and\n" +" you won’t need to pay extra gas for them." +msgstr "ค่าธรรมเนียมดังต่อไปนี้จะถูกนำมาพิจารณาในผลลัพธ์ของธุรกรรม และ\n" +" คุณไม่จำเป็นต้องจ่ายค่าก๊าซเพิ่มเติมสำหรับค่าธรรมเนียมเหล่านี้" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteSummary.tsx:25 +msgid "Swap input" +msgstr "สลับอินพุต" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteSummary.tsx:44 +msgid "Estimated output" +msgstr "ผลผลิตโดยประมาณ" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteTrigger.tsx:65 +msgid "Via:" +msgstr "ทาง:" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteTrigger.tsx:150 +msgid "Chains:" +msgstr "โซ่:" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/Quotes.tsx:77 +msgid "Sort by" +msgstr "จัดเรียงตาม" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:17 +msgid "Smart Routing" +msgstr "การกำหนดเส้นทางอัจฉริยะ" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:21 +msgid "Lowest Fee" +msgstr "ค่าธรรมเนียมต่ำสุด" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:25 +msgid "Fastest Transfer" +msgstr "โอนถ่ายข้อมูลได้รวดเร็วที่สุด" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:29 +msgid "Maximum Return" +msgstr "ผลตอบแทนสูงสุด" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:33 +msgid "Maximum Output" +msgstr "เอาท์พุตสูงสุด" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:43 +msgid "Swapping" +msgstr "การแลกเปลี่ยน" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:51 +msgid "Gas cost" +msgstr "ค่าแก๊ส" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:59 +msgid "Receiving" +msgstr "การรับ" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:67 +msgid "Price impact" +msgstr "ผลกระทบต่อราคา" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:35 +msgid "You need to increase slippage to at least {minRequiredSlippage} for this route." +msgstr "คุณจะต้องเพิ่มการลื่นไถลเป็นอย่างน้อย {minRequiredSlippage} สำหรับเส้นทางนี้" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:59 +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:61 +msgid "We recommend you to increase slippage to at least {minRequiredSlippage} for this route." +msgstr "เราขอแนะนำให้คุณเพิ่มการลื่นไถลเป็นอย่างน้อย {minRequiredSlippage} สำหรับเส้นทางนี้" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:68 +msgid "Caution, your slippage is high." +msgstr "ระวัง การลื่นไถลของคุณมีสูง" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.tsx:78 +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.Warning.tsx:26 +msgid "Change" +msgstr "เปลี่ยน" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:42 +msgid "Change settings" +msgstr "การเปลี่ยนแปลงการตั้งค่า" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:52 +msgid "High slippage" +msgstr "ความลื่นไถลสูง" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:53 +msgid "Low slippage" +msgstr "ความลื่นไถลต่ำ" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:57 +msgid " Caution, your slippage is high (={userSlippage}). Your trade may be front run." +msgstr " ระวัง สลิปเพจของคุณสูง (={userSlippage}) การซื้อขายของคุณอาจจะเกิดการฟรอนท์รัน" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:78 +msgid "Confirm anyway" +msgstr "ยืนยันต่อไป" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:22 +msgid "Something went wrong" +msgstr "มีบางอย่างผิดพลาดเกิดขึ้น" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:24 +msgid "Something went wrong. Please refresh the app." +msgstr "มีบางอย่างผิดพลาด กรุณารีเฟรชแอป" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/Slippage.tsx:38 +msgid "Slippage tolerance per swap" +msgstr "ความคลาดเคลื่อนของค่าสลิปต่อการสลับ" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/Slippage.tsx:91 +msgid "Custom" +msgstr "กำหนดเอง" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:11 +msgid "Your transaction will be reverted if the price changes unfavorably by more than this percentage." +msgstr "ธุรกรรมของคุณจะถูกกลับคืนหากราคามีการเปลี่ยนแปลงในทางลบมากกว่าเปอร์เซ็นต์นี้" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:16 +#: widget/embedded/src/containers/Settings/Lists.tsx:245 +msgid "Warning" +msgstr "คำเตือน" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:17 +msgid "This setting is applied to each step (e.g. 1Inch, Thorchain, etc.), meaning only that specific step will be reverted, not the entire route." +msgstr "การตั้งค่านี้ใช้กับแต่ละขั้นตอน (เช่น 1 นิ้ว, Thorchain เป็นต้น) ซึ่งหมายความว่าจะย้อนกลับเฉพาะขั้นตอนที่ระบุเท่านั้น ไม่ใช่เส้นทางทั้งหมด" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:25 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:269 +msgid "Swap Details" +msgstr "รายละเอียดการสลับ" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:33 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:312 +msgid "Request ID" +msgstr "ขอรหัส ID" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:64 +msgid "Not found" +msgstr "ไม่พบ" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:65 +msgid "Swap with request ID = {requestId} not found." +msgstr "สลับกับ ID คำขอ = {requestId} ไม่พบ." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:219 +msgid "You have received {amount} {token} in {conciseAddress} wallet on {chain} chain." +msgstr "คุณได้รับ {amount} {token} ในกระเป๋าเงิน {conciseAddress} บนเครือข่าย {chain}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:242 +msgid "Transaction was not sent." +msgstr "ไม่ได้ส่งธุรกรรม" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:244 +msgid "{amount} {symbol} on {blockchain} remains in your wallet." +msgstr "{amount} {symbol} บน {blockchain} ยังคงอยู่ในกระเป๋าเงินของคุณ" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:281 +msgid "Delete" +msgstr "ลบ" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:304 +msgid "Try again" +msgstr "ลองใหม่อีกครั้ง" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:322 +msgid "Copied To Clipboard" +msgstr "คัดลอกไปยังคลิปบอร์ด" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:323 +msgid "Copy Request ID" +msgstr "สำเนาคำขอ ID" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:346 +msgid "View on Rango Explorer" +msgstr "ดูบน Rango Explorer" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:355 +msgid "Finished at" +msgstr "เสร็จสิ้นแล้วที่" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:355 +msgid "Created at" +msgstr "สร้างขึ้นเมื่อ" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.tsx:50 +msgid "View transaction" +msgstr "ดูการทำธุรกรรม" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.Warning.tsx:49 +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:31 +msgid "Connect" +msgstr "เชื่อมต่อ" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:43 +msgid "Swap Successful" +msgstr "สลับสำเร็จ" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:71 +msgid "Transaction Failed" +msgstr "การทำธุรกรรมล้มเหลว" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:87 +msgid "Done" +msgstr "เสร็จแล้ว" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:100 +msgid "Diagnosis" +msgstr "การวินิจฉัย" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:112 +msgid "See Details" +msgstr "ดูรายละเอียด" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:13 +msgid "Cancel Swap" +msgstr "ยกเลิกการแลกเปลี่ยน" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:14 +msgid "Are you sure you want to cancel this swap?" +msgstr "คุณแน่ใจว่าต้องการยกเลิกการสลับนี้หรือไม่?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:23 +msgid "Yes, Cancel it" +msgstr "ใช่ ยกเลิกมัน" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:32 +#: widget/embedded/src/pages/CustomTokensPage.tsx:181 +msgid "No, Continue" +msgstr "ไม่ ดำเนินการต่อ" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:13 +msgid "Delete Transaction" +msgstr "ลบรายการธุรกรรม" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:14 +msgid "Are you sure you want to delete this swap?" +msgstr "คุณแน่ใจว่าต้องการลบการสลับนี้หรือไม่?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:23 +#: widget/embedded/src/pages/CustomTokensPage.tsx:171 +msgid "Yes, Delete it" +msgstr "ใช่ ลบมันซะ" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:33 +#: widget/embedded/src/pages/HistoryPage.tsx:253 +msgid "No, Cancel" +msgstr "ไม่ ยกเลิก" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:12 +msgid "Change Network" +msgstr "เปลี่ยนเครือข่าย" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:20 +msgid "Network Changed" +msgstr "เครือข่ายมีการเปลี่ยนแปลง" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/TokenList/TokenList.tsx:271 +#: widget/ui/src/containers/SwapInput/TokenSection.tsx:54 +msgid "Select Token" +msgstr "เลือกโทเค็น" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:27 +msgid "Wallet Connected" +msgstr "เชื่อมต่อกระเป๋าสตางค์" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:28 +msgid "Your wallet is connected, you can use it to swap." +msgstr "กระเป๋าเงินของคุณเชื่อมต่อแล้ว คุณสามารถใช้มันเพื่อแลกเปลี่ยนได้" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:39 +msgid "Failed to Connect" +msgstr "ไม่สามารถเชื่อมต่อได้" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:41 +msgid "Your wallet is not connected. Please try again." +msgstr "กระเป๋าสตางค์ของคุณไม่ได้เชื่อมต่อ กรุณาลองอีกครั้ง" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:50 +msgid "Connecting to your wallet" +msgstr "การเชื่อมต่อกับกระเป๋าสตางค์ของคุณ" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:51 +msgid "Click connect in your wallet popup." +msgstr "คลิกเชื่อมต่อในป๊อปอัปกระเป๋าเงินของคุณ" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:99 +msgid "Select Derivation Path" +msgstr "เลือกเส้นทางการอนุมาน" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:100 +msgid "In order to connect to {type}, you must first select a Derivation Path" +msgstr "ในการเชื่อมต่อกับ {type}คุณต้องเลือกเส้นทางการได้มาก่อน" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:118 +msgid "Choose Derivation Path Template" +msgstr "เลือกเทมเพลตเส้นทางการอนุมาน" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:133 +msgid "Enter Path" +msgstr "เข้าสู่เส้นทาง" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:134 +msgid "Enter Index" +msgstr "เข้าสู่ดัชนี" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:15 +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:18 +msgid "Add {blockchainDisplayName} Chain" +msgstr "เพิ่ม {blockchainDisplayName} เชน" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:20 +msgid "Would you like to add the {blockchainDisplayName} experimental chain to your wallet?" +msgstr "คุณต้องการเพิ่มโซ่ทดลอง {blockchainDisplayName} ลงในกระเป๋าเงินของคุณหรือไม่" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:22 +msgid "Please approve the experimental chain pop-up in your wallet." +msgstr "กรุณาอนุมัติให้ป๊อปอัปโซ่ทดลองอยู่ในกระเป๋าเงินของคุณ" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:30 +msgid "{blockchainDisplayName} Chain Added" +msgstr "{blockchainDisplayName} เพิ่มโซ่แล้ว" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:34 +msgid "The {blockchainDisplayName} chain has been successfully added to your wallet." +msgstr "เพิ่มโซ่ {blockchainDisplayName} ลงในกระเป๋าเงินของคุณเรียบร้อยแล้ว" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:42 +msgid "Request Rejected" +msgstr "คำขอถูกปฏิเสธ" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:43 +msgid "You've rejected adding {blockchainDisplayName} chain to your wallet." +msgstr "คุณปฏิเสธที่จะเพิ่มโซ่ {blockchainDisplayName} ลงในกระเป๋าเงินของคุณ" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:70 +msgid "Select chain types" +msgstr "เลือกประเภทโซ่" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:71 +msgid "This wallet supports multiple chains. Select which chain you'd like to connect to." +msgstr "กระเป๋าสตางค์นี้รองรับหลายเครือข่าย เลือกเครือข่ายที่คุณต้องการเชื่อมต่อ" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:9 +msgid "Failed Network, Please retry your swap." +msgstr "เครือข่ายล้มเหลว กรุณาลองสลับอีกครั้ง" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:11 +msgid "Please reset your liquidity sources." +msgstr "กรุณารีเซ็ตแหล่งสภาพคล่องของคุณ" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:12 +msgid "You have limited the liquidity sources and this might result in Rango finding no routes. Please consider resetting your liquidity sources." +msgstr "คุณได้จำกัดแหล่งสภาพคล่องไว้ ซึ่งอาจส่งผลให้ Rango ไม่พบเส้นทางใด ๆ โปรดพิจารณารีเซ็ตแหล่งสภาพคล่องของคุณ" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:17 +msgid "No Routes Found." +msgstr "ไม่พบเส้นทาง" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:18 +msgid "Reasons why Rango couldn't find a route: low liquidity on token, very low input amount or no routes available for the selected input/output token combination." +msgstr "สาเหตุที่ Rango ไม่สามารถค้นหาเส้นทางได้: สภาพคล่องของโทเค็นต่ำ, ปริมาณอินพุตต่ำมาก หรือไม่มีเส้นทางที่ใช้งานได้สำหรับชุดค่าผสมโทเค็นอินพุต/เอาต์พุตที่เลือก" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:23 +msgid "Bridge Limit Error: Please increase your amount." +msgstr "ข้อผิดพลาดการจำกัดสะพาน: กรุณาเพิ่มจำนวนของคุณ" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:26 +msgid "Bridge Limit Error: Please decrease your amount." +msgstr "ข้อผิดพลาดการจำกัดสะพาน: กรุณาลดจำนวนเงินของคุณ" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:31 +msgid "High Price Impact" +msgstr "ผลกระทบต่อราคาสูง" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:32 +msgid "Price impact is too high!" +msgstr "ผลกระทบต่อราคาสูงเกินไป!" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:33 +msgid "The price impact is significantly higher than the allowed amount." +msgstr "ผลกระทบต่อราคาจะสูงกว่าจำนวนที่อนุญาตอย่างมาก" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:36 +msgid "Confirm high price impact" +msgstr "ยืนยันผลกระทบต่อราคาสูง" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:39 +msgid "Route updated and price impact is too high, try again later!" +msgstr "เส้นทางได้รับการอัปเดตแล้วและมีผลกระทบต่อราคาสูงเกินไป โปรดลองอีกครั้งในภายหลัง!" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:44 +msgid "USD Price Unknown" +msgstr "ราคา USD ไม่ทราบ" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:45 +msgid "USD Price Unknown, Cannot calculate Price Impact." +msgstr "ราคา USD ไม่ทราบ ไม่สามารถคำนวณผลกระทบต่อราคาได้" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:46 +msgid "USD Price Unknown, Cannot calculate Price Impact. The price impact may be higher than usual. Are you sure to continue the Swap?" +msgstr "ราคา USD ไม่ทราบ ไม่สามารถคำนวณผลกระทบต่อราคาได้ ผลกระทบต่อราคาอาจสูงกว่าปกติ คุณแน่ใจหรือไม่ว่าจะดำเนินการ Swap ต่อ" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:49 +msgid "Confirm USD Price Unknown" +msgstr "ยืนยันราคา USD ไม่ทราบ" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:6 +#: widget/embedded/src/pages/Home.tsx:163 +msgid "Swap" +msgstr "แลกเปลี่ยน" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:7 +msgid "Swap anyway" +msgstr "สลับกัน" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:8 +msgid "The route goes through Ethereum. Continue?" +msgstr "เส้นทางจะผ่าน Ethereum ดำเนินการต่อหรือไม่?" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:10 +msgid "Route has been updated." +msgstr "เส้นทางได้รับการอัปเดตแล้ว" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:12 +msgid "Output amount changed to {newOutputAmount} ({percentageChange}% change)." +msgstr "ปริมาณผลลัพธ์ถูกเปลี่ยนเป็น {newOutputAmount} ({percentageChange}% เปลี่ยนแปลง)" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:20 +msgid "Route swappers has been updated." +msgstr "ตัวเปลี่ยนเส้นทางได้รับการอัปเดตแล้ว" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:22 +msgid "Route internal coins has been updated." +msgstr "เหรียญภายในเส้นทางได้รับการอัปเดตแล้ว" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/ExpandedQuotes/ExpandedQuotes.tsx:53 +#: widget/embedded/src/pages/Routes.tsx:48 +msgid "Routes" +msgstr "เส้นทาง" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Inputs/Inputs.tsx:76 +msgid "From" +msgstr "จาก" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Inputs/Inputs.tsx:118 +msgid "To" +msgstr "ถึง" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:49 +msgid "Light" +msgstr "แสงสว่าง" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:58 +msgid "Dark" +msgstr "มืด" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:67 +msgid "Auto" +msgstr "ออโต้" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:140 +msgid "Loading failed" +msgstr "การโหลดล้มเหลว" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:156 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:41 +msgid "Bridges" +msgstr "สะพาน" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:174 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:41 +msgid "Exchanges" +msgstr "การแลกเปลี่ยน" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:195 +#: widget/embedded/src/pages/CustomTokensPage.tsx:90 +msgid "Custom Tokens" +msgstr "โทเค็นที่กำหนดเอง" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:214 +#: widget/embedded/src/pages/LanguagePage.tsx:43 +msgid "Language" +msgstr "ภาษา" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:235 +msgid "Infinite approval" +msgstr "การอนุมัติที่ไม่มีที่สิ้นสุด" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:246 +msgid "Enabling the 'Infinite approval' mode grants unrestricted access to underlying smart contracts, allowing them to utilize the approved token amount without limitations." +msgstr "การเปิดใช้งานโหมด 'อนุมัติแบบไม่จำกัด' จะทำให้สามารถเข้าถึงสัญญาอัจฉริยะพื้นฐานได้อย่างไม่มีข้อจำกัด ช่วยให้สามารถใช้จำนวนโทเค็นที่ได้รับการอนุมัติโดยไม่มีข้อจำกัด" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:266 +msgid "Theme" +msgstr "ธีม" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:39 +msgid "Duplicate Token" +msgstr "โทเค็นซ้ำ" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:40 +msgid "The address you entered is duplicate, please enter a new address." +msgstr "ที่อยู่ที่คุณป้อนซ้ำ กรุณาป้อนที่อยู่ใหม่" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:46 +msgid "Token Already Exists" +msgstr "โทเค็นมีอยู่แล้ว" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:47 +msgid "There's no need to add this token again because it already exists and is supported by us." +msgstr "ไม่จำเป็นต้องเพิ่มโทเค็นนี้อีกครั้ง เนื่องจากโทเค็นนี้มีอยู่แล้วและได้รับการสนับสนุนจากเราแล้ว" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:53 +msgid "Token Not Found" +msgstr "ไม่พบโทเค็น" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:54 +msgid "Sorry, no token was found on {blockchain} chain with the provided address. please make sure you have entered the right token address." +msgstr "ขออภัย ไม่พบโทเค็นบนเชน {blockchain} ที่มีที่อยู่ที่ให้ไว้ โปรดตรวจสอบให้แน่ใจว่าคุณได้ป้อนที่อยู่โทเค็นที่ถูกต้อง" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:78 +msgid "Network Error" +msgstr "ข้อผิดพลาดของเครือข่าย" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:109 +#: widget/embedded/src/pages/CustomTokensPage.tsx:149 +msgid "Add Custom Token" +msgstr "เพิ่มโทเค็นที่กำหนดเอง" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:127 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:128 +msgid "Select chain" +msgstr "เลือกโซ่" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:132 +msgid "Enter Address" +msgstr "กรอกที่อยู่" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:139 +msgid "Enter token address" +msgstr "ป้อนที่อยู่โทเค็น" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:176 +msgid "Failed Network, Please retry." +msgstr "เครือข่ายล้มเหลว กรุณาลองอีกครั้ง" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:192 +msgid "Add another custom token" +msgstr "เพิ่มโทเค็นที่กำหนดเองอื่น" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:236 +msgid "Confirm Swap" +msgstr "ยืนยันการสลับ" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:254 +msgid "Start Swap" +msgstr "เริ่มการแลกเปลี่ยน" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:282 +msgid "You get" +msgstr "คุณจะได้รับ" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:102 +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:90 +msgid "Search Token" +msgstr "ค้นหาโทเค็น" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:134 +msgid "No custom tokens" +msgstr "ไม่มีโทเค็นที่กำหนดเอง" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:135 +msgid "press the button to add your custom token" +msgstr "กดปุ่มเพื่อเพิ่มโทเค็นที่กำหนดเองของคุณ" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:158 +msgid "Delete Custom Token" +msgstr "ลบโทเค็นที่กำหนดเอง" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:160 +msgid "Are you sure you want to Delete this Token?" +msgstr "คุณแน่ใจหรือไม่ว่าต้องการลบโทเค็นนี้?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:59 +msgid "Complete" +msgstr "สมบูรณ์" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:63 +msgid "Running" +msgstr "วิ่ง" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:65 +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:8 +msgid "Failed" +msgstr "ล้มเหลว" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:149 +msgid "Clear" +msgstr "ชัดเจน" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:161 +msgid "Search Transaction" +msgstr "ค้นหาธุรกรรม" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:187 +msgid "No transactions" +msgstr "ไม่มีการทำธุรกรรม" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:194 +msgid "Your transaction history is stored locally and will appear here after you start a swap" +msgstr "ประวัติการทำธุรกรรมของคุณจะถูกเก็บไว้ในเครื่องและจะปรากฏที่นี่หลังจากที่คุณเริ่มสลับ" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:218 +msgid "Clear Transaction History" +msgstr "ล้างประวัติการทำธุรกรรม" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:222 +msgid "Proceeding will remove all successful and failed transactions from the widget. Do you want to continue?" +msgstr "การดำเนินการต่อไปจะลบธุรกรรมที่สำเร็จและล้มเหลวทั้งหมดออกจากวิดเจ็ต คุณต้องการดำเนินการต่อหรือไม่" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:229 +msgid "Note: This does not erase your transaction history on the chain; it only removes them here." +msgstr "หมายเหตุ: การดำเนินการนี้จะไม่ลบประวัติการทำธุรกรรมของคุณบนเครือข่าย แต่จะลบออกที่นี่เท่านั้น" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:243 +msgid "Yes, Clear the history" +msgstr "ใช่ ล้างประวัติ" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LanguagePage.tsx:56 +msgid "language" +msgstr "ภาษา" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:121 +msgid "Deselect all" +msgstr "ยกเลิกการเลือกทั้งหมด" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:121 +msgid "Select all" +msgstr "เลือกทั้งหมด" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:133 +msgid "Search {sourceType}" +msgstr "ค้นหา {sourceType}" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectBlockchainPage.tsx:60 +msgid "Search Chain" +msgstr "การค้นหาแบบโซ่" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:67 +msgid "Source" +msgstr "แหล่งที่มา" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:68 +msgid "Destination" +msgstr "ปลายทาง" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:74 +msgid "Swap {type}" +msgstr "สลับ {type}" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SettingsPage.tsx:45 +msgid "Currently, you're in campaign mode with restrictions on liquidity sources. Would you like to switch out of this mode and make use of all available liquidity sources?" +msgstr "ขณะนี้ คุณอยู่ในโหมดแคมเปญซึ่งมีข้อจำกัดเกี่ยวกับแหล่งสภาพคล่อง คุณต้องการออกจากโหมดนี้และใช้แหล่งสภาพคล่องที่มีอยู่ทั้งหมดหรือไม่" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SwapDetailsPage.tsx:27 +msgid "The request ID is necessary to display the swap details." +msgstr "จำเป็นต้องมี ID คำขอเพื่อแสดงรายละเอียดการสลับ" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/WalletsPage.tsx:67 +#: widget/ui/src/containers/ConnectWalletsModal/ConnectWalletsModal.tsx:15 +msgid "Connect Wallets" +msgstr "เชื่อมต่อกระเป๋าสตางค์" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/WalletsPage.tsx:82 +msgid "Choose a wallet to connect." +msgstr "เลือกกระเป๋าสตางค์ที่จะเชื่อมต่อ" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:25 +msgid "This week" +msgstr "สัปดาห์นี้" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:32 +msgid "This month" +msgstr "เดือนนี้" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:39 +msgid "This year" +msgstr "ปีนี้" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:129 +msgid "Required: >= {min} {symbol}" +msgstr "จำเป็น: >= {min} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:142 +msgid "Required: > {min} {symbol}" +msgstr "จำเป็น: > {min} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:157 +msgid "Required: <= {max} {symbol}" +msgstr "จำเป็น: <= {max} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:170 +msgid "Required: < {max} {symbol}" +msgstr "จำเป็น: < {max} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:601 +msgid " for network fee" +msgstr " สำหรับค่าธรรมเนียมเครือข่าย" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:604 +msgid " for swap" +msgstr " สำหรับการแลกเปลี่ยน" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:607 +msgid " for input and network fee" +msgstr " สำหรับค่าอินพุทและค่าเน็ตเวิร์ค" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:609 +msgid "Needs ≈ {requiredAmount} {symbol}{reason}, but you have {currentAmount} {symbol} in your {blockchain} wallet." +msgstr "ต้องการ ≈ {requiredAmount} {symbol}{reason}แต่คุณมี {currentAmount} {symbol} ในกระเป๋าเงิน {blockchain} ของคุณ" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:669 +msgid "Waiting for connecting wallet" +msgstr "กำลังรอการเชื่อมต่อกระเป๋าสตางค์" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:673 +msgid "Waiting for other running tasks to be finished" +msgstr "กำลังรอให้งานอื่นที่กำลังดำเนินการเสร็จสิ้น" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:676 +msgid "Waiting for changing wallet network" +msgstr "กำลังรอเปลี่ยนเครือข่ายกระเป๋าเงิน" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:6 +msgid "Sunday" +msgstr "วันอาทิตย์" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:7 +msgid "Monday" +msgstr "วันจันทร์" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:8 +msgid "Tuesday" +msgstr "วันอังคาร" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:9 +msgid "Wednesday" +msgstr "วันพุธ" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:10 +msgid "Thursday" +msgstr "วันพฤหัสบดี" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:11 +msgid "Friday" +msgstr "วันศุกร์" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:12 +msgid "Saturday" +msgstr "วันเสาร์" + +#. js-lingui-explicit-id +#: widget/ui/src/components/BottomLogo/BottomLogo.tsx:14 +msgid "Powered By" +msgstr "ขับเคลื่อนโดย" + +#. js-lingui-explicit-id +#: widget/ui/src/components/FullExpandedQuote/FullExpandedQuote.Tooltip.tsx:37 +msgid "Aggregated Transaction" +msgstr "การทำธุรกรรมรวม" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SelectableCategoryList/SelectableCategoryList.tsx:63 +msgid "{blockchainCategory}" +msgstr "{blockchainCategory}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/StepDetails/StepDetails.tsx:75 +#: widget/ui/src/components/StepDetails/StepDetails.tsx:102 +msgid "Swap on {fromChain} via {swapper}" +msgstr "สลับ {fromChain} เป็น {swapper}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/StepDetails/StepDetails.tsx:109 +msgid "Bridge to {toChain} via {swapper}" +msgstr "สะพานไปยัง {toChain} ผ่าน {swapper}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:10 +msgid "Completed" +msgstr "สมบูรณ์" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:12 +msgid "In progress" +msgstr "อยู่ระหว่างดำเนินการ" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapToken.tsx:122 +msgid "Waiting for bridge transaction" +msgstr "กำลังรอการทำธุรกรรมสะพาน" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:12 +msgid "Connected" +msgstr "เชื่อมต่อ" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:13 +msgid "Disconnect" +msgstr "ตัดการเชื่อมต่อ" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:18 +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:19 +msgid "Install" +msgstr "ติดตั้ง" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:24 +msgid "Connecting ..." +msgstr "กำลังเชื่อมต่อ ..." + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:25 +msgid "Connecting" +msgstr "การเชื่อมต่อ" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:30 +msgid "Disconnected" +msgstr "ถูกตัดการเชื่อมต่อ" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:34 +msgid "you need to pass a correct state to Wallet." +msgstr "คุณต้องส่งสถานะที่ถูกต้องไปยัง Wallet" + +#. js-lingui-explicit-id +#: widget/ui/src/containers/Notifications/NotificationNotFound.tsx:15 +msgid "There are no notifications." +msgstr "ไม่มีการแจ้งเตือนใดๆ." + +#. js-lingui-explicit-id +#: widget/ui/src/containers/Notifications/Notifications.tsx:39 +msgid "Clear all" +msgstr "ล้างทั้งหมด" + +#. js-lingui-explicit-id +#: widget/ui/src/containers/SwapInput/SwapInput.tsx:65 +msgid "Balance" +msgstr "สมดุล" + +#. js-lingui-explicit-id +#: widget/ui/src/containers/SwapInput/SwapInput.tsx:73 +msgid "Max" +msgstr "แม็กซ์" + diff --git a/translations/tr.po b/translations/tr.po new file mode 100644 index 0000000000..3152058c43 --- /dev/null +++ b/translations/tr.po @@ -0,0 +1,1339 @@ +msgid "" +msgstr "" +"POT-Creation-Date: 2023-11-06 17:24+0330\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: @lingui/cli\n" +"Language: tr\n" +"Project-Id-Version: rango\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2024-11-27 15:57\n" +"Last-Translator: \n" +"Language-Team: Turkish\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Crowdin-Project: rango\n" +"X-Crowdin-Project-ID: 622238\n" +"X-Crowdin-Language: tr\n" +"X-Crowdin-File: en.po\n" +"X-Crowdin-File-ID: 30\n" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SameTokensWarning/SameTokensWarning.tsx:21 +msgid "No Routes Found" +msgstr "Hiçbir Rota Bulunamadı" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SameTokensWarning/SameTokensWarning.tsx:25 +msgid "You cannot use the same token for From and To." +msgstr "From ve To için aynı token'ı kullanamazsınız." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:41 +#: widget/embedded/src/components/TokenList/TokenList.tsx:286 +#: widget/embedded/src/pages/HistoryPage.tsx:186 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:143 +msgid "No results found" +msgstr "Hiçbir sonuç bulunamadı" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:42 +#: widget/embedded/src/components/TokenList/TokenList.tsx:287 +#: widget/embedded/src/pages/HistoryPage.tsx:193 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:144 +msgid "Try using different keywords" +msgstr "Farklı anahtar kelimeler kullanmayı deneyin" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:72 +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:46 +#: widget/embedded/src/pages/SelectBlockchainPage.tsx:42 +#: widget/ui/src/containers/SwapInput/TokenSection.tsx:61 +msgid "Select Chain" +msgstr "Zincir Seç" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:66 +msgid "All" +msgstr "Tüm" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:100 +msgid "More +{count}" +msgstr "Daha Fazla +{count}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabAlert/ActivateTabAlert.tsx:17 +msgid "Activate this tab" +msgstr "Bu sekmeyi etkinleştir" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabAlert/ActivateTabAlert.tsx:22 +msgid "Another tab is open and handles transactions." +msgstr "Başka bir sekme daha açık ve işlemleri yönetiyor." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:20 +msgid "Activate current tab" +msgstr "Mevcut sekmeyi etkinleştir" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:22 +msgid "Currently, some transactions are running and being handled by other browser tab. If you activate this tab, all transactions that are already in the transaction sign step will expire." +msgstr "Şu anda bazı işlemler çalışıyor ve başka bir tarayıcı sekmesi tarafından işleniyor. Bu sekmeyi etkinleştirirseniz, işlem imzalama adımında olan tüm işlemler sona erecektir." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:33 +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:349 +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:152 +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:33 +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:116 +msgid "Confirm" +msgstr "Onaylamak" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:365 +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:447 +msgid "Your {blockchainName} wallets" +msgstr "{blockchainName} cüzdanlarınız" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:384 +msgid "Insufficient account balance" +msgstr "Yetersiz hesap bakiyesi" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:394 +msgid "Proceed anyway" +msgstr "Yine de devam et" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:456 +msgid "You need to connect a {blockchainName} wallet." +msgstr "{blockchainName} cüzdanını bağlamanız gerekiyor." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/WalletList.tsx:143 +msgid "Add {chain} chain" +msgstr "{chain} zincirini ekle" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/WalletList.tsx:244 +msgid "Show more wallets" +msgstr "Daha fazla cüzdan göster" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:113 +msgid "Send to a different address" +msgstr "Farklı bir adrese gönder" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:129 +msgid "Enter {blockchainName} address" +msgstr "{blockchainName} adresini girin" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:147 +msgid "Address {destination} doesn't match the blockchain address pattern." +msgstr "{destination} adresi blockchain adres örüntüsüyle uyuşmuyor." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:59 +msgid "via" +msgstr "aracılığıyla" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:74 +msgid "This token doesn't appear on the active token list(s). Make sure this is the token that you want to trade." +msgstr "Bu token aktif token listesinde görünmüyor. Bunun işlem yapmak istediğiniz token olduğundan emin olun." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:89 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:164 +msgid "Import" +msgstr "İçe aktarmak" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/FilterSelector/FilterSelectorContent.tsx:26 +msgid "Status" +msgstr "Durum" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/FilterSelector/FilterSelectorContent.tsx:33 +#: widget/embedded/src/components/NoResult/NoResult.helpers.ts:37 +#: widget/embedded/src/pages/SettingsPage.tsx:55 +msgid "Reset" +msgstr "Sıfırla" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/CancelButton.tsx:18 +msgid "Cancel" +msgstr "İptal etmek" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:46 +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:34 +msgid "Refresh" +msgstr "Yenile" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:63 +#: widget/ui/src/containers/Notifications/Notifications.tsx:35 +msgid "Notifications" +msgstr "Bildirimler" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:79 +#: widget/embedded/src/pages/SettingsPage.tsx:38 +msgid "Settings" +msgstr "Ayarlar" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:93 +#: widget/embedded/src/pages/HistoryPage.tsx:139 +msgid "History" +msgstr "Tarih" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/WalletButton.tsx:22 +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:16 +#: widget/embedded/src/constants/messages.ts:5 +msgid "Connect Wallet" +msgstr "Cüzdanı Bağla" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HistoryGroupedList/HistoryGroupedList.tsx:118 +#: widget/embedded/src/utils/date.ts:18 +#: widget/embedded/src/utils/time.ts:22 +msgid "Today" +msgstr "Bugün" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/LoadingSwapDetails/LoadingSwapDetails.tsx:20 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:424 +msgid "Swaps steps" +msgstr "Değişim adımları" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/NoResult/NoResult.helpers.ts:25 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:191 +msgid "Retry" +msgstr "Tekrar dene" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:149 +msgid "Slippage Error" +msgstr "Kayma Hatası" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:150 +msgid "Slippage Warning" +msgstr "Kayma Uyarısı" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:153 +msgid "Bridge Limit Error" +msgstr "Köprü Sınır Hatası" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:240 +msgid "Yours: {amount} {symbol}" +msgstr "Sizin: {amount} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:261 +msgid "Minimum required slippage: {minRequiredSlippage}" +msgstr "Minimum gerekli kayma: {minRequiredSlippage}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:282 +msgid "Yours: {userSlippage}" +msgstr "Sizin: {userSlippage}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:395 +msgid "See All Routes" +msgstr "Tüm Rotaları Gör" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:81 +msgid "View more info" +msgstr "Daha fazla bilgi görüntüle" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:91 +msgid "Gas & Fee Explanation" +msgstr "Gaz ve Ücret Açıklaması" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:107 +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:103 +msgid "Details" +msgstr "Detaylar" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:146 +msgid "Total Payable Fee" +msgstr "Toplam Ödenecek Ücret" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:166 +msgid "Hide non-payable fees" +msgstr "Ödenmeyen ücretleri gizle" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:167 +msgid "Show non-payable fees" +msgstr "Ödenmeyen ücretleri göster" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:177 +msgid "Description" +msgstr "Tanım" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:181 +msgid "The following fees are considered in the transaction output and\n" +" you won’t need to pay extra gas for them." +msgstr "Aşağıdaki ücretler işlem çıktısına dahil edilir ve\n" +" bunlar için ekstra gas ödemenize gerek kalmaz." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteSummary.tsx:25 +msgid "Swap input" +msgstr "Girişi değiştir" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteSummary.tsx:44 +msgid "Estimated output" +msgstr "Tahmini çıktı" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteTrigger.tsx:65 +msgid "Via:" +msgstr "Aracılığıyla:" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteTrigger.tsx:150 +msgid "Chains:" +msgstr "Zincirler:" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/Quotes.tsx:77 +msgid "Sort by" +msgstr "Göre sırala" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:17 +msgid "Smart Routing" +msgstr "Akıllı Yönlendirme" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:21 +msgid "Lowest Fee" +msgstr "En Düşük Ücret" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:25 +msgid "Fastest Transfer" +msgstr "En Hızlı Transfer" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:29 +msgid "Maximum Return" +msgstr "Maksimum Getiri" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:33 +msgid "Maximum Output" +msgstr "Maksimum Çıktı" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:43 +msgid "Swapping" +msgstr "Takaslama" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:51 +msgid "Gas cost" +msgstr "Gaz maliyeti" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:59 +msgid "Receiving" +msgstr "Alma" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:67 +msgid "Price impact" +msgstr "Fiyat etkisi" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:35 +msgid "You need to increase slippage to at least {minRequiredSlippage} for this route." +msgstr "Bu rota için kaymayı en az {minRequiredSlippage} 'a çıkarmanız gerekiyor." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:59 +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:61 +msgid "We recommend you to increase slippage to at least {minRequiredSlippage} for this route." +msgstr "Bu rota için kaymayı en az {minRequiredSlippage} seviyesine çıkarmanızı öneririz." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:68 +msgid "Caution, your slippage is high." +msgstr "Dikkat, kaymanız yüksek." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.tsx:78 +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.Warning.tsx:26 +msgid "Change" +msgstr "Değiştirmek" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:42 +msgid "Change settings" +msgstr "Ayarları değiştir" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:52 +msgid "High slippage" +msgstr "Yüksek kayma" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:53 +msgid "Low slippage" +msgstr "Düşük kayma" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:57 +msgid " Caution, your slippage is high (={userSlippage}). Your trade may be front run." +msgstr " Dikkat, kaymanız yüksek (={userSlippage}). İşleminiz önden koşu olabilir." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:78 +msgid "Confirm anyway" +msgstr "Yine de onayla" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:22 +msgid "Something went wrong" +msgstr "Bir şeyler ters gitti" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:24 +msgid "Something went wrong. Please refresh the app." +msgstr "Bir şeyler ters gitti. Lütfen uygulamayı yenileyin." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/Slippage.tsx:38 +msgid "Slippage tolerance per swap" +msgstr "Swap başına kayma toleransı" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/Slippage.tsx:91 +msgid "Custom" +msgstr "Gelenek" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:11 +msgid "Your transaction will be reverted if the price changes unfavorably by more than this percentage." +msgstr "Fiyatta bu orandan fazla olumsuz değişim olması durumunda işleminiz geri alınacaktır." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:16 +#: widget/embedded/src/containers/Settings/Lists.tsx:245 +msgid "Warning" +msgstr "Uyarı" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:17 +msgid "This setting is applied to each step (e.g. 1Inch, Thorchain, etc.), meaning only that specific step will be reverted, not the entire route." +msgstr "Bu ayar her bir adıma uygulanır (örneğin 1Inch, Thorchain, vb.), yani yalnızca o belirli adım geri alınır, tüm rota geri alınmaz." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:25 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:269 +msgid "Swap Details" +msgstr "Takas Detayları" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:33 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:312 +msgid "Request ID" +msgstr "İstek Kimliği" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:64 +msgid "Not found" +msgstr "Bulunamadı" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:65 +msgid "Swap with request ID = {requestId} not found." +msgstr "İstek ID'si = {requestId} olan takas bulunamadı." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:219 +msgid "You have received {amount} {token} in {conciseAddress} wallet on {chain} chain." +msgstr "{chain} zincirindeki {conciseAddress} cüzdanında {amount} {token} aldınız." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:242 +msgid "Transaction was not sent." +msgstr "İşlem gönderilemedi." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:244 +msgid "{amount} {symbol} on {blockchain} remains in your wallet." +msgstr "{amount} {symbol} on {blockchain} cüzdanınızda kalır." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:281 +msgid "Delete" +msgstr "Silmek" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:304 +msgid "Try again" +msgstr "Tekrar deneyin" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:322 +msgid "Copied To Clipboard" +msgstr "Panoya Kopyalandı" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:323 +msgid "Copy Request ID" +msgstr "Kopyalama İstek Kimliği" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:346 +msgid "View on Rango Explorer" +msgstr "Rango Explorer'da görüntüle" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:355 +msgid "Finished at" +msgstr "Bitirildi" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:355 +msgid "Created at" +msgstr "Oluşturuldu" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.tsx:50 +msgid "View transaction" +msgstr "İşlemi görüntüle" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.Warning.tsx:49 +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:31 +msgid "Connect" +msgstr "Bağlamak" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:43 +msgid "Swap Successful" +msgstr "Takas Başarılı" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:71 +msgid "Transaction Failed" +msgstr "İşlem Başarısız" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:87 +msgid "Done" +msgstr "Tamamlamak" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:100 +msgid "Diagnosis" +msgstr "Tanı" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:112 +msgid "See Details" +msgstr "Ayrıntıları Gör" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:13 +msgid "Cancel Swap" +msgstr "Takas İptali" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:14 +msgid "Are you sure you want to cancel this swap?" +msgstr "Bu takası iptal etmek istediğinizden emin misiniz?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:23 +msgid "Yes, Cancel it" +msgstr "Evet, İptal Et" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:32 +#: widget/embedded/src/pages/CustomTokensPage.tsx:181 +msgid "No, Continue" +msgstr "Hayır, Devam Et" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:13 +msgid "Delete Transaction" +msgstr "İşlemi Sil" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:14 +msgid "Are you sure you want to delete this swap?" +msgstr "Bu takası silmek istediğinizden emin misiniz?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:23 +#: widget/embedded/src/pages/CustomTokensPage.tsx:171 +msgid "Yes, Delete it" +msgstr "Evet, Sil" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:33 +#: widget/embedded/src/pages/HistoryPage.tsx:253 +msgid "No, Cancel" +msgstr "Hayır, İptal" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:12 +msgid "Change Network" +msgstr "Ağ Değiştir" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:20 +msgid "Network Changed" +msgstr "Ağ Değişti" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/TokenList/TokenList.tsx:271 +#: widget/ui/src/containers/SwapInput/TokenSection.tsx:54 +msgid "Select Token" +msgstr "Jeton Seç" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:27 +msgid "Wallet Connected" +msgstr "Cüzdan Bağlandı" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:28 +msgid "Your wallet is connected, you can use it to swap." +msgstr "Cüzdanınız bağlandı, takas yapmak için kullanabilirsiniz." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:39 +msgid "Failed to Connect" +msgstr "Bağlantı başarısız oldu" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:41 +msgid "Your wallet is not connected. Please try again." +msgstr "Cüzdanınız bağlı değil. Lütfen tekrar deneyin." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:50 +msgid "Connecting to your wallet" +msgstr "Cüzdanınıza bağlanılıyor" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:51 +msgid "Click connect in your wallet popup." +msgstr "Cüzdanınızdaki açılır pencerede bağlan'a tıklayın." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:99 +msgid "Select Derivation Path" +msgstr "Türetme Yolunu Seçin" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:100 +msgid "In order to connect to {type}, you must first select a Derivation Path" +msgstr "{type}'a bağlanmak için öncelikle bir Türetme Yolu seçmelisiniz" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:118 +msgid "Choose Derivation Path Template" +msgstr "Türetme Yolu Şablonunu Seçin" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:133 +msgid "Enter Path" +msgstr "Yola Girin" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:134 +msgid "Enter Index" +msgstr "Dizin'e Girin" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:15 +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:18 +msgid "Add {blockchainDisplayName} Chain" +msgstr "{blockchainDisplayName} Zinciri Ekle" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:20 +msgid "Would you like to add the {blockchainDisplayName} experimental chain to your wallet?" +msgstr "{blockchainDisplayName} deneysel zincirini cüzdanınıza eklemek ister misiniz?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:22 +msgid "Please approve the experimental chain pop-up in your wallet." +msgstr "Lütfen cüzdanınızdaki deneysel zincir açılır penceresini onaylayın." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:30 +msgid "{blockchainDisplayName} Chain Added" +msgstr "{blockchainDisplayName} Zincir Eklendi" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:34 +msgid "The {blockchainDisplayName} chain has been successfully added to your wallet." +msgstr "{blockchainDisplayName} zinciri cüzdanınıza başarıyla eklendi." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:42 +msgid "Request Rejected" +msgstr "İstek Reddedildi" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:43 +msgid "You've rejected adding {blockchainDisplayName} chain to your wallet." +msgstr "Cüzdanınıza {blockchainDisplayName} zincirinin eklenmesini reddettiniz." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:70 +msgid "Select chain types" +msgstr "Zincir tiplerini seçin" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:71 +msgid "This wallet supports multiple chains. Select which chain you'd like to connect to." +msgstr "Bu cüzdan birden fazla zinciri destekler. Hangi zincire bağlanmak istediğinizi seçin." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:9 +msgid "Failed Network, Please retry your swap." +msgstr "Ağ başarısız oldu. Lütfen takasınızı tekrar deneyin." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:11 +msgid "Please reset your liquidity sources." +msgstr "Lütfen likidite kaynaklarınızı sıfırlayın." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:12 +msgid "You have limited the liquidity sources and this might result in Rango finding no routes. Please consider resetting your liquidity sources." +msgstr "Likidite kaynaklarını sınırladınız ve bu Rango'nun rota bulamamasına neden olabilir. Lütfen likidite kaynaklarınızı sıfırlamayı düşünün." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:17 +msgid "No Routes Found." +msgstr "Rota Bulunamadı." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:18 +msgid "Reasons why Rango couldn't find a route: low liquidity on token, very low input amount or no routes available for the selected input/output token combination." +msgstr "Rango'nun bir rota bulamamasının nedenleri: token'da düşük likidite, çok düşük girdi miktarı veya seçilen girdi/çıktı token kombinasyonu için kullanılabilir rota olmaması." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:23 +msgid "Bridge Limit Error: Please increase your amount." +msgstr "Köprü Limit Hatası: Lütfen tutarınızı artırın." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:26 +msgid "Bridge Limit Error: Please decrease your amount." +msgstr "Köprü Limit Hatası: Lütfen tutarınızı azaltın." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:31 +msgid "High Price Impact" +msgstr "Yüksek Fiyat Etkisi" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:32 +msgid "Price impact is too high!" +msgstr "Fiyat etkisi çok yüksek!" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:33 +msgid "The price impact is significantly higher than the allowed amount." +msgstr "Fiyat etkisi izin verilen miktarın önemli ölçüde üzerindedir." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:36 +msgid "Confirm high price impact" +msgstr "Yüksek fiyat etkisini doğrulayın" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:39 +msgid "Route updated and price impact is too high, try again later!" +msgstr "Rota güncellendi ve fiyat etkisi çok yüksek, daha sonra tekrar deneyin!" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:44 +msgid "USD Price Unknown" +msgstr "USD Fiyatı Bilinmiyor" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:45 +msgid "USD Price Unknown, Cannot calculate Price Impact." +msgstr "USD Fiyatı Bilinmiyor, Fiyat Etkisi Hesaplanamıyor." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:46 +msgid "USD Price Unknown, Cannot calculate Price Impact. The price impact may be higher than usual. Are you sure to continue the Swap?" +msgstr "USD Fiyatı Bilinmiyor, Fiyat Etkisi Hesaplanamıyor. Fiyat etkisi normalden daha yüksek olabilir. Swap'a devam etmek istediğinizden emin misiniz?" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:49 +msgid "Confirm USD Price Unknown" +msgstr "USD Fiyatını Onaylayın Bilinmiyor" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:6 +#: widget/embedded/src/pages/Home.tsx:163 +msgid "Swap" +msgstr "Takas" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:7 +msgid "Swap anyway" +msgstr "Her neyse takas et" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:8 +msgid "The route goes through Ethereum. Continue?" +msgstr "Rota Ethereum'dan geçiyor. Devam etmek istiyor musunuz?" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:10 +msgid "Route has been updated." +msgstr "Rota güncellendi." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:12 +msgid "Output amount changed to {newOutputAmount} ({percentageChange}% change)." +msgstr "Çıktı miktarı {newOutputAmount} ({percentageChange}% değişim) olarak değiştirildi." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:20 +msgid "Route swappers has been updated." +msgstr "Rota değiştiriciler güncellendi." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:22 +msgid "Route internal coins has been updated." +msgstr "Rota içi coinler güncellendi." + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/ExpandedQuotes/ExpandedQuotes.tsx:53 +#: widget/embedded/src/pages/Routes.tsx:48 +msgid "Routes" +msgstr "Rotalar" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Inputs/Inputs.tsx:76 +msgid "From" +msgstr "İtibaren" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Inputs/Inputs.tsx:118 +msgid "To" +msgstr "İle" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:49 +msgid "Light" +msgstr "Işık" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:58 +msgid "Dark" +msgstr "Karanlık" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:67 +msgid "Auto" +msgstr "Otomatik" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:140 +msgid "Loading failed" +msgstr "Yükleme başarısız oldu" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:156 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:41 +msgid "Bridges" +msgstr "Köprüler" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:174 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:41 +msgid "Exchanges" +msgstr "Borsalar" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:195 +#: widget/embedded/src/pages/CustomTokensPage.tsx:90 +msgid "Custom Tokens" +msgstr "Özel Jetonlar" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:214 +#: widget/embedded/src/pages/LanguagePage.tsx:43 +msgid "Language" +msgstr "Dil" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:235 +msgid "Infinite approval" +msgstr "Sonsuz onay" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:246 +msgid "Enabling the 'Infinite approval' mode grants unrestricted access to underlying smart contracts, allowing them to utilize the approved token amount without limitations." +msgstr "'Sonsuz onay' modunun etkinleştirilmesi, temeldeki akıllı sözleşmelere sınırsız erişim sağlar ve onaylanan token miktarını sınırlama olmaksızın kullanmalarına olanak tanır." + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:266 +msgid "Theme" +msgstr "Tema" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:39 +msgid "Duplicate Token" +msgstr "Çift Jeton" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:40 +msgid "The address you entered is duplicate, please enter a new address." +msgstr "Girdiğiniz adres aynı değil, lütfen yeni bir adres girin." + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:46 +msgid "Token Already Exists" +msgstr "Jeton Zaten Mevcut" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:47 +msgid "There's no need to add this token again because it already exists and is supported by us." +msgstr "Bu token'ı tekrar eklemenize gerek yok çünkü zaten mevcut ve tarafımızca destekleniyor." + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:53 +msgid "Token Not Found" +msgstr "Jeton Bulunamadı" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:54 +msgid "Sorry, no token was found on {blockchain} chain with the provided address. please make sure you have entered the right token address." +msgstr "Üzgünüz, {blockchain} zincirinde belirtilen adresle bir token bulunamadı. Lütfen doğru token adresini girdiğinizden emin olun." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:78 +msgid "Network Error" +msgstr "Ağ Hatası" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:109 +#: widget/embedded/src/pages/CustomTokensPage.tsx:149 +msgid "Add Custom Token" +msgstr "Özel Token Ekle" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:127 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:128 +msgid "Select chain" +msgstr "Zinciri seçin" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:132 +msgid "Enter Address" +msgstr "Adresi Girin" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:139 +msgid "Enter token address" +msgstr "Jeton adresini girin" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:176 +msgid "Failed Network, Please retry." +msgstr "Ağ başarısız, lütfen tekrar deneyin." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:192 +msgid "Add another custom token" +msgstr "Başka bir özel belirteç ekle" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:236 +msgid "Confirm Swap" +msgstr "Takası Onayla" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:254 +msgid "Start Swap" +msgstr "Takas Başlat" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:282 +msgid "You get" +msgstr "Sen alırsın" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:102 +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:90 +msgid "Search Token" +msgstr "Arama Simgesi" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:134 +msgid "No custom tokens" +msgstr "Özel token yok" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:135 +msgid "press the button to add your custom token" +msgstr "özel tokeninizi eklemek için düğmeye basın" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:158 +msgid "Delete Custom Token" +msgstr "Özel Token'ı Sil" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:160 +msgid "Are you sure you want to Delete this Token?" +msgstr "Bu Token'ı Silmek istediğinizden emin misiniz?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:59 +msgid "Complete" +msgstr "Tamamlamak" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:63 +msgid "Running" +msgstr "Koşma" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:65 +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:8 +msgid "Failed" +msgstr "Arızalı" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:149 +msgid "Clear" +msgstr "Temizlemek" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:161 +msgid "Search Transaction" +msgstr "Arama İşlemi" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:187 +msgid "No transactions" +msgstr "Hiçbir işlem yok" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:194 +msgid "Your transaction history is stored locally and will appear here after you start a swap" +msgstr "İşlem geçmişiniz yerel olarak saklanır ve bir takas başlattıktan sonra burada görünür" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:218 +msgid "Clear Transaction History" +msgstr "İşlem Geçmişini Temizle" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:222 +msgid "Proceeding will remove all successful and failed transactions from the widget. Do you want to continue?" +msgstr "Devam etmek, widget'tan tüm başarılı ve başarısız işlemleri kaldıracaktır. Devam etmek istiyor musunuz?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:229 +msgid "Note: This does not erase your transaction history on the chain; it only removes them here." +msgstr "Not: Bu, zincirdeki işlem geçmişinizi silmez; yalnızca buradan kaldırır." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:243 +msgid "Yes, Clear the history" +msgstr "Evet, geçmişi temizle" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LanguagePage.tsx:56 +msgid "language" +msgstr "dil" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:121 +msgid "Deselect all" +msgstr "Tümünü seçimi kaldır" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:121 +msgid "Select all" +msgstr "Tümünü seç" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:133 +msgid "Search {sourceType}" +msgstr "Ara {sourceType}" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectBlockchainPage.tsx:60 +msgid "Search Chain" +msgstr "Arama Zinciri" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:67 +msgid "Source" +msgstr "Kaynak" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:68 +msgid "Destination" +msgstr "Varış noktası" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:74 +msgid "Swap {type}" +msgstr "Takas {type}" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SettingsPage.tsx:45 +msgid "Currently, you're in campaign mode with restrictions on liquidity sources. Would you like to switch out of this mode and make use of all available liquidity sources?" +msgstr "Şu anda, likidite kaynaklarında kısıtlamalar olan kampanya modundasınız. Bu moddan çıkıp tüm mevcut likidite kaynaklarını kullanmak ister misiniz?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SwapDetailsPage.tsx:27 +msgid "The request ID is necessary to display the swap details." +msgstr "Takas detaylarının görüntülenebilmesi için istek ID'si gereklidir." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/WalletsPage.tsx:67 +#: widget/ui/src/containers/ConnectWalletsModal/ConnectWalletsModal.tsx:15 +msgid "Connect Wallets" +msgstr "Cüzdanları Bağlayın" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/WalletsPage.tsx:82 +msgid "Choose a wallet to connect." +msgstr "Bağlanmak için bir cüzdan seçin." + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:25 +msgid "This week" +msgstr "Bu hafta" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:32 +msgid "This month" +msgstr "Bu ay" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:39 +msgid "This year" +msgstr "Bu yıl" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:129 +msgid "Required: >= {min} {symbol}" +msgstr "Gerekli: >= {min} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:142 +msgid "Required: > {min} {symbol}" +msgstr "Gerekli: > {min} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:157 +msgid "Required: <= {max} {symbol}" +msgstr "Gerekli: <= {max} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:170 +msgid "Required: < {max} {symbol}" +msgstr "Gerekli: < {max} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:601 +msgid " for network fee" +msgstr " ağ ücreti için" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:604 +msgid " for swap" +msgstr " takas için" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:607 +msgid " for input and network fee" +msgstr " giriş ve ağ ücreti için" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:609 +msgid "Needs ≈ {requiredAmount} {symbol}{reason}, but you have {currentAmount} {symbol} in your {blockchain} wallet." +msgstr "≈ {requiredAmount} {symbol}{reason}gerekiyor, ancak cüzdanınızda {blockchain} {currentAmount} {symbol} var." + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:669 +msgid "Waiting for connecting wallet" +msgstr "Cüzdanın bağlanmasını bekliyorum" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:673 +msgid "Waiting for other running tasks to be finished" +msgstr "Diğer çalışan görevlerin bitmesini bekliyorum" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:676 +msgid "Waiting for changing wallet network" +msgstr "Cüzdan ağının değiştirilmesi bekleniyor" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:6 +msgid "Sunday" +msgstr "Pazar" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:7 +msgid "Monday" +msgstr "Pazartesi" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:8 +msgid "Tuesday" +msgstr "Salı" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:9 +msgid "Wednesday" +msgstr "Çarşamba" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:10 +msgid "Thursday" +msgstr "Perşembe" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:11 +msgid "Friday" +msgstr "Cuma" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:12 +msgid "Saturday" +msgstr "Cumartesi" + +#. js-lingui-explicit-id +#: widget/ui/src/components/BottomLogo/BottomLogo.tsx:14 +msgid "Powered By" +msgstr "Tarafından desteklenmektedir" + +#. js-lingui-explicit-id +#: widget/ui/src/components/FullExpandedQuote/FullExpandedQuote.Tooltip.tsx:37 +msgid "Aggregated Transaction" +msgstr "Toplu İşlem" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SelectableCategoryList/SelectableCategoryList.tsx:63 +msgid "{blockchainCategory}" +msgstr "{blockchainCategory}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/StepDetails/StepDetails.tsx:75 +#: widget/ui/src/components/StepDetails/StepDetails.tsx:102 +msgid "Swap on {fromChain} via {swapper}" +msgstr "{fromChain} üzerinden {swapper}ile takas yapın" + +#. js-lingui-explicit-id +#: widget/ui/src/components/StepDetails/StepDetails.tsx:109 +msgid "Bridge to {toChain} via {swapper}" +msgstr "{swapper}üzerinden {toChain} 'a köprü" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:10 +msgid "Completed" +msgstr "Tamamlanmış" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:12 +msgid "In progress" +msgstr "Devam etmekte" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapToken.tsx:122 +msgid "Waiting for bridge transaction" +msgstr "Köprü işlemi bekleniyor" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:12 +msgid "Connected" +msgstr "Bağlı" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:13 +msgid "Disconnect" +msgstr "Bağlantıyı kes" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:18 +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:19 +msgid "Install" +msgstr "Düzenlemek" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:24 +msgid "Connecting ..." +msgstr "Bağlanıyor..." + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:25 +msgid "Connecting" +msgstr "Bağlanma" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:30 +msgid "Disconnected" +msgstr "Bağlantısı kesildi" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:34 +msgid "you need to pass a correct state to Wallet." +msgstr "Cüzdan'a doğru bir durum geçirmeniz gerekiyor." + +#. js-lingui-explicit-id +#: widget/ui/src/containers/Notifications/NotificationNotFound.tsx:15 +msgid "There are no notifications." +msgstr "Bildirim yok." + +#. js-lingui-explicit-id +#: widget/ui/src/containers/Notifications/Notifications.tsx:39 +msgid "Clear all" +msgstr "Hepsini temizle" + +#. js-lingui-explicit-id +#: widget/ui/src/containers/SwapInput/SwapInput.tsx:65 +msgid "Balance" +msgstr "Denge" + +#. js-lingui-explicit-id +#: widget/ui/src/containers/SwapInput/SwapInput.tsx:73 +msgid "Max" +msgstr "Maksimum" + diff --git a/translations/uk.po b/translations/uk.po new file mode 100644 index 0000000000..19434fb5c6 --- /dev/null +++ b/translations/uk.po @@ -0,0 +1,1339 @@ +msgid "" +msgstr "" +"POT-Creation-Date: 2023-11-06 17:24+0330\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: @lingui/cli\n" +"Language: uk\n" +"Project-Id-Version: rango\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2024-11-27 15:57\n" +"Last-Translator: \n" +"Language-Team: Ukrainian\n" +"Plural-Forms: nplurals=4; plural=((n%10==1 && n%100!=11) ? 0 : ((n%10 >= 2 && n%10 <=4 && (n%100 < 12 || n%100 > 14)) ? 1 : ((n%10 == 0 || (n%10 >= 5 && n%10 <=9)) || (n%100 >= 11 && n%100 <= 14)) ? 2 : 3));\n" +"X-Crowdin-Project: rango\n" +"X-Crowdin-Project-ID: 622238\n" +"X-Crowdin-Language: uk\n" +"X-Crowdin-File: en.po\n" +"X-Crowdin-File-ID: 30\n" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SameTokensWarning/SameTokensWarning.tsx:21 +msgid "No Routes Found" +msgstr "Маршрути не знайдено" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SameTokensWarning/SameTokensWarning.tsx:25 +msgid "You cannot use the same token for From and To." +msgstr "Ви не можете використовувати той самий маркер для «Від» і «Кому»." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:41 +#: widget/embedded/src/components/TokenList/TokenList.tsx:286 +#: widget/embedded/src/pages/HistoryPage.tsx:186 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:143 +msgid "No results found" +msgstr "Нічого не знайдено" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:42 +#: widget/embedded/src/components/TokenList/TokenList.tsx:287 +#: widget/embedded/src/pages/HistoryPage.tsx:193 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:144 +msgid "Try using different keywords" +msgstr "Спробуйте використовувати інші ключові слова" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:72 +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:46 +#: widget/embedded/src/pages/SelectBlockchainPage.tsx:42 +#: widget/ui/src/containers/SwapInput/TokenSection.tsx:61 +msgid "Select Chain" +msgstr "Обрати ланцюжок" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:66 +msgid "All" +msgstr "Всі" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:100 +msgid "More +{count}" +msgstr "Більше +{count}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabAlert/ActivateTabAlert.tsx:17 +msgid "Activate this tab" +msgstr "Активувати цю вкладку" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabAlert/ActivateTabAlert.tsx:22 +msgid "Another tab is open and handles transactions." +msgstr "Інша вкладка - відкриті і обробка транзакцій." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:20 +msgid "Activate current tab" +msgstr "Активувати поточну вкладку" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:22 +msgid "Currently, some transactions are running and being handled by other browser tab. If you activate this tab, all transactions that are already in the transaction sign step will expire." +msgstr "В даний час деякі операції виконуються і обробляються іншою вкладкою браузера. Якщо ви активуєте цю вкладку, всі транзакції, що вже знаходяться в етапі підпису транзакцій, закінчуються." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:33 +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:349 +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:152 +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:33 +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:116 +msgid "Confirm" +msgstr "Підтвердити" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:365 +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:447 +msgid "Your {blockchainName} wallets" +msgstr "Ваші гаманці {blockchainName}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:384 +msgid "Insufficient account balance" +msgstr "Недостатньо грошей на балансі" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:394 +msgid "Proceed anyway" +msgstr "Все одно" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:456 +msgid "You need to connect a {blockchainName} wallet." +msgstr "Ви повинні підключити {blockchainName} гаманець." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/WalletList.tsx:143 +msgid "Add {chain} chain" +msgstr "Додати ланцюжок {chain}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/WalletList.tsx:244 +msgid "Show more wallets" +msgstr "Показати більше гаманців" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:113 +msgid "Send to a different address" +msgstr "Надсилати на іншу адресу" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:129 +msgid "Enter {blockchainName} address" +msgstr "Введіть {blockchainName} адресу" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:147 +msgid "Address {destination} doesn't match the blockchain address pattern." +msgstr "Адреса {destination} не відповідає шаблону адреси блокчейн." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:59 +msgid "via" +msgstr "через" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:74 +msgid "This token doesn't appear on the active token list(s). Make sure this is the token that you want to trade." +msgstr "Цей токен не відображається у списку активних токенів. Переконайтеся, що це маркер який ви хочете торгувати." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:89 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:164 +msgid "Import" +msgstr "Імпорт" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/FilterSelector/FilterSelectorContent.tsx:26 +msgid "Status" +msgstr "Статус" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/FilterSelector/FilterSelectorContent.tsx:33 +#: widget/embedded/src/components/NoResult/NoResult.helpers.ts:37 +#: widget/embedded/src/pages/SettingsPage.tsx:55 +msgid "Reset" +msgstr "Reset" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/CancelButton.tsx:18 +msgid "Cancel" +msgstr "Скасувати" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:46 +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:34 +msgid "Refresh" +msgstr "Оновити" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:63 +#: widget/ui/src/containers/Notifications/Notifications.tsx:35 +msgid "Notifications" +msgstr "Сповіщення" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:79 +#: widget/embedded/src/pages/SettingsPage.tsx:38 +msgid "Settings" +msgstr "Налаштування" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:93 +#: widget/embedded/src/pages/HistoryPage.tsx:139 +msgid "History" +msgstr "Історія" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/WalletButton.tsx:22 +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:16 +#: widget/embedded/src/constants/messages.ts:5 +msgid "Connect Wallet" +msgstr "Підключіть Wallet" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HistoryGroupedList/HistoryGroupedList.tsx:118 +#: widget/embedded/src/utils/date.ts:18 +#: widget/embedded/src/utils/time.ts:22 +msgid "Today" +msgstr "Сьогодні" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/LoadingSwapDetails/LoadingSwapDetails.tsx:20 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:424 +msgid "Swaps steps" +msgstr "Кроки зміни" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/NoResult/NoResult.helpers.ts:25 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:191 +msgid "Retry" +msgstr "Повторити спробу" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:149 +msgid "Slippage Error" +msgstr "Помилка прокручування" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:150 +msgid "Slippage Warning" +msgstr "Попередження про Slippage" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:153 +msgid "Bridge Limit Error" +msgstr "Помилка обмеження мосту" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:240 +msgid "Yours: {amount} {symbol}" +msgstr "Ваш: {amount} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:261 +msgid "Minimum required slippage: {minRequiredSlippage}" +msgstr "Мінімальна необхідна повзунка: {minRequiredSlippage}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:282 +msgid "Yours: {userSlippage}" +msgstr "Ваш: {userSlippage}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:395 +msgid "See All Routes" +msgstr "Побачити всі маршрути" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:81 +msgid "View more info" +msgstr "Показати більше" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:91 +msgid "Gas & Fee Explanation" +msgstr "Газ і комісія" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:107 +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:103 +msgid "Details" +msgstr "Подробиці" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:146 +msgid "Total Payable Fee" +msgstr "Загальна сума виплат" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:166 +msgid "Hide non-payable fees" +msgstr "Приховати неоплачені платежі" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:167 +msgid "Show non-payable fees" +msgstr "Показати платні платежі" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:177 +msgid "Description" +msgstr "Опис" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:181 +msgid "The following fees are considered in the transaction output and\n" +" you won’t need to pay extra gas for them." +msgstr "Наступні комісії враховуються у вихідних даних транзакції, і\n" +" вам не потрібно буде платити за них додатковий газ." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteSummary.tsx:25 +msgid "Swap input" +msgstr "Swap input" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteSummary.tsx:44 +msgid "Estimated output" +msgstr "Розрахунковий вихід" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteTrigger.tsx:65 +msgid "Via:" +msgstr "Через:" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteTrigger.tsx:150 +msgid "Chains:" +msgstr "Ланцюги:" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/Quotes.tsx:77 +msgid "Sort by" +msgstr "Сортувати за" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:17 +msgid "Smart Routing" +msgstr "Розумна маршрутизація" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:21 +msgid "Lowest Fee" +msgstr "Найнижча комісія" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:25 +msgid "Fastest Transfer" +msgstr "Найшвидша передача" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:29 +msgid "Maximum Return" +msgstr "Максимальне повернення" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:33 +msgid "Maximum Output" +msgstr "Максимальний вихід" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:43 +msgid "Swapping" +msgstr "Swapping" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:51 +msgid "Gas cost" +msgstr "Вартість газу" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:59 +msgid "Receiving" +msgstr "Отримання" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:67 +msgid "Price impact" +msgstr "Вплив ціни" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:35 +msgid "You need to increase slippage to at least {minRequiredSlippage} for this route." +msgstr "Вам потрібно збільшити слайд принаймні {minRequiredSlippage} для цього маршруту." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:59 +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:61 +msgid "We recommend you to increase slippage to at least {minRequiredSlippage} for this route." +msgstr "Ми рекомендуємо вам збільшити слайд принаймні {minRequiredSlippage} для цього маршруту." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:68 +msgid "Caution, your slippage is high." +msgstr "Обережно, твоя схованка висока." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.tsx:78 +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.Warning.tsx:26 +msgid "Change" +msgstr "Змінити" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:42 +msgid "Change settings" +msgstr "Змінити параметри" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:52 +msgid "High slippage" +msgstr "Висока слизька" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:53 +msgid "Low slippage" +msgstr "Низька заливка" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:57 +msgid " Caution, your slippage is high (={userSlippage}). Your trade may be front run." +msgstr " Обережно, ваш слайд високий (={userSlippage}). Ваша торгівля може бути запущена." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:78 +msgid "Confirm anyway" +msgstr "Підтвердити все одно" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:22 +msgid "Something went wrong" +msgstr "Сталася помилка" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:24 +msgid "Something went wrong. Please refresh the app." +msgstr "Щось пішло не так. Будь ласка, оновіть програму." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/Slippage.tsx:38 +msgid "Slippage tolerance per swap" +msgstr "Допустимість спуску на своп" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/Slippage.tsx:91 +msgid "Custom" +msgstr "Користувацька" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:11 +msgid "Your transaction will be reverted if the price changes unfavorably by more than this percentage." +msgstr "Вашу транзакцію буде повернуто, якщо ця ціна зміниться більш ніж на цей відсоток." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:16 +#: widget/embedded/src/containers/Settings/Lists.tsx:245 +msgid "Warning" +msgstr "Застереження" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:17 +msgid "This setting is applied to each step (e.g. 1Inch, Thorchain, etc.), meaning only that specific step will be reverted, not the entire route." +msgstr "Цей параметр застосовано до кожного кроку (наприклад. 1Inch, Торчейн і т.п.), що означає, що тільки певний крок буде відновлено, а не весь маршрут." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:25 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:269 +msgid "Swap Details" +msgstr "Деталі свопи" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:33 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:312 +msgid "Request ID" +msgstr "Номер запиту" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:64 +msgid "Not found" +msgstr "Не знайдено" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:65 +msgid "Swap with request ID = {requestId} not found." +msgstr "Своп з RequestID = {requestId} не знайдено." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:219 +msgid "You have received {amount} {token} in {conciseAddress} wallet on {chain} chain." +msgstr "Ви отримали {amount} {token} в гаманці {conciseAddress} на {chain} ланцюжку." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:242 +msgid "Transaction was not sent." +msgstr "Транзакцію не надіслано." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:244 +msgid "{amount} {symbol} on {blockchain} remains in your wallet." +msgstr "{amount} {symbol} на {blockchain} залишиться в вашому гаманці." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:281 +msgid "Delete" +msgstr "Видалити" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:304 +msgid "Try again" +msgstr "Спробуйте ще раз" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:322 +msgid "Copied To Clipboard" +msgstr "Скопійовано в буфер обміну" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:323 +msgid "Copy Request ID" +msgstr "Копіювати ID запиту" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:346 +msgid "View on Rango Explorer" +msgstr "Переглянути в Rango Explorer" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:355 +msgid "Finished at" +msgstr "Завершено о" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:355 +msgid "Created at" +msgstr "Створений в" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.tsx:50 +msgid "View transaction" +msgstr "Переглянути операцію" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.Warning.tsx:49 +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:31 +msgid "Connect" +msgstr "Підключитися" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:43 +msgid "Swap Successful" +msgstr "Зміна успішна" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:71 +msgid "Transaction Failed" +msgstr "Невдала транзакція" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:87 +msgid "Done" +msgstr "Виконано" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:100 +msgid "Diagnosis" +msgstr "Діагноз" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:112 +msgid "See Details" +msgstr "Див. докладніше" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:13 +msgid "Cancel Swap" +msgstr "Скасувати зміни" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:14 +msgid "Are you sure you want to cancel this swap?" +msgstr "Ви впевнені, що хочете скасувати це відображення?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:23 +msgid "Yes, Cancel it" +msgstr "Так, скасувати" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:32 +#: widget/embedded/src/pages/CustomTokensPage.tsx:181 +msgid "No, Continue" +msgstr "Ні, продовжити" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:13 +msgid "Delete Transaction" +msgstr "Видалити транзакцію" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:14 +msgid "Are you sure you want to delete this swap?" +msgstr "Ви впевнені, що бажаєте видалити це переміщення?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:23 +#: widget/embedded/src/pages/CustomTokensPage.tsx:171 +msgid "Yes, Delete it" +msgstr "Так, видалити його" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:33 +#: widget/embedded/src/pages/HistoryPage.tsx:253 +msgid "No, Cancel" +msgstr "Ні, скасувати" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:12 +msgid "Change Network" +msgstr "Змінити мережу" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:20 +msgid "Network Changed" +msgstr "Мережа змінена" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/TokenList/TokenList.tsx:271 +#: widget/ui/src/containers/SwapInput/TokenSection.tsx:54 +msgid "Select Token" +msgstr "Вибрати токен" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:27 +msgid "Wallet Connected" +msgstr "Підключено гаманець" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:28 +msgid "Your wallet is connected, you can use it to swap." +msgstr "Ваш гаманець підключений, ви можете використовувати його для обміну." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:39 +msgid "Failed to Connect" +msgstr "Не вдалося з'єднатися" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:41 +msgid "Your wallet is not connected. Please try again." +msgstr "Ваш гаманець не підключений. Будь ласка, спробуйте ще раз." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:50 +msgid "Connecting to your wallet" +msgstr "Підключення до вашого гаманця" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:51 +msgid "Click connect in your wallet popup." +msgstr "Натисніть підключитися в спливаючому вікні вашого гаманця." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:99 +msgid "Select Derivation Path" +msgstr "Виберіть шлях до видачі" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:100 +msgid "In order to connect to {type}, you must first select a Derivation Path" +msgstr "Для того, щоб підключитися до {type}, необхідно спочатку вибрати шлях відділення" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:118 +msgid "Choose Derivation Path Template" +msgstr "Вибрати шаблон відхилення по шаблону" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:133 +msgid "Enter Path" +msgstr "Введіть шлях" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:134 +msgid "Enter Index" +msgstr "Введіть індекс" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:15 +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:18 +msgid "Add {blockchainDisplayName} Chain" +msgstr "Додати {blockchainDisplayName} ланцюжок" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:20 +msgid "Would you like to add the {blockchainDisplayName} experimental chain to your wallet?" +msgstr "Хочете додати експериментальний ланцюг {blockchainDisplayName} до вашого гаманця?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:22 +msgid "Please approve the experimental chain pop-up in your wallet." +msgstr "Будь ласка, підтвердіть експериментальний ланцюжок у вашому гаманці." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:30 +msgid "{blockchainDisplayName} Chain Added" +msgstr "Додано ланцюжок {blockchainDisplayName}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:34 +msgid "The {blockchainDisplayName} chain has been successfully added to your wallet." +msgstr "Ланцюжок {blockchainDisplayName} успішно додано до вашого гаманця." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:42 +msgid "Request Rejected" +msgstr "Запит відхилено" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:43 +msgid "You've rejected adding {blockchainDisplayName} chain to your wallet." +msgstr "Ви відхилили додавання {blockchainDisplayName} ланцюжка до вашого гаманця." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:70 +msgid "Select chain types" +msgstr "Оберіть типи ланцюжків" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:71 +msgid "This wallet supports multiple chains. Select which chain you'd like to connect to." +msgstr "Цей гаманець підтримує кілька ланцюжків. Оберіть, до якого ланцюга ви хотіли б підключитися." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:9 +msgid "Failed Network, Please retry your swap." +msgstr "Невдала мережа, будь ласка, спробуйте змінити своп." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:11 +msgid "Please reset your liquidity sources." +msgstr "Будь ласка, скиньте ваші джерела ліквідності." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:12 +msgid "You have limited the liquidity sources and this might result in Rango finding no routes. Please consider resetting your liquidity sources." +msgstr "Ви обмежили джерела ліквідності, і це може призвести до того, що Ранго не знаходить маршрутів. Будь ласка, подумайте про відновлення вашого джерела ліквідності." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:17 +msgid "No Routes Found." +msgstr "Маршрути не знайдено." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:18 +msgid "Reasons why Rango couldn't find a route: low liquidity on token, very low input amount or no routes available for the selected input/output token combination." +msgstr "Причина, чому Ранго не зміг знайти маршрут: низька ліквідність, дуже мала кількість вхідних даних або відсутність комбінації токену введення/вихідного тексту." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:23 +msgid "Bridge Limit Error: Please increase your amount." +msgstr "Помилка обмеження мосту. Будь ласка, збільшіть суму." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:26 +msgid "Bridge Limit Error: Please decrease your amount." +msgstr "Помилка обмеження мосту: Будь ласка, зменште суму." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:31 +msgid "High Price Impact" +msgstr "Високий вплив на ціну" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:32 +msgid "Price impact is too high!" +msgstr "Тарифний вплив надто високий!" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:33 +msgid "The price impact is significantly higher than the allowed amount." +msgstr "Вплив цін значно вищий, ніж дозволена сума." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:36 +msgid "Confirm high price impact" +msgstr "Підтвердити високий ціновий вплив" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:39 +msgid "Route updated and price impact is too high, try again later!" +msgstr "Зміна маршруту і вплив ціни занадто високий, спробуйте пізніше!" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:44 +msgid "USD Price Unknown" +msgstr "USD ціна невідома" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:45 +msgid "USD Price Unknown, Cannot calculate Price Impact." +msgstr "Невідома ціна USD не може обчислити вплив ціни." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:46 +msgid "USD Price Unknown, Cannot calculate Price Impact. The price impact may be higher than usual. Are you sure to continue the Swap?" +msgstr "Ціна США не відома, неможливо розрахувати вплив ціни. Вплив ціни може бути вищим, ніж зазвичай. Ви впевнені, що хочете продовжити плавання?" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:49 +msgid "Confirm USD Price Unknown" +msgstr "Підтвердіть невідому ціну USD" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:6 +#: widget/embedded/src/pages/Home.tsx:163 +msgid "Swap" +msgstr "Поміняти" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:7 +msgid "Swap anyway" +msgstr "Поміняти місцями все одно" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:8 +msgid "The route goes through Ethereum. Continue?" +msgstr "Маршрут проходить через Ethereum. Продовжити?" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:10 +msgid "Route has been updated." +msgstr "Маршрут було оновлено." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:12 +msgid "Output amount changed to {newOutputAmount} ({percentageChange}% change)." +msgstr "Сума виводу змінена на {newOutputAmount} ({percentageChange}% зміни)." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:20 +msgid "Route swappers has been updated." +msgstr "Маршрутні заміни були оновлені." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:22 +msgid "Route internal coins has been updated." +msgstr "Рейс внутрішніх монет був оновлений." + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/ExpandedQuotes/ExpandedQuotes.tsx:53 +#: widget/embedded/src/pages/Routes.tsx:48 +msgid "Routes" +msgstr "Маршрути" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Inputs/Inputs.tsx:76 +msgid "From" +msgstr "Від" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Inputs/Inputs.tsx:118 +msgid "To" +msgstr "На" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:49 +msgid "Light" +msgstr "Світла" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:58 +msgid "Dark" +msgstr "Темна" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:67 +msgid "Auto" +msgstr "Авто" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:140 +msgid "Loading failed" +msgstr "Помилка завантаження" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:156 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:41 +msgid "Bridges" +msgstr "Бріджес" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:174 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:41 +msgid "Exchanges" +msgstr "Обмін валют" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:195 +#: widget/embedded/src/pages/CustomTokensPage.tsx:90 +msgid "Custom Tokens" +msgstr "Користувацькі токени" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:214 +#: widget/embedded/src/pages/LanguagePage.tsx:43 +msgid "Language" +msgstr "Мова:" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:235 +msgid "Infinite approval" +msgstr "Нескінченне затвердження" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:246 +msgid "Enabling the 'Infinite approval' mode grants unrestricted access to underlying smart contracts, allowing them to utilize the approved token amount without limitations." +msgstr "Увімкнення режиму «Нескінченного затвердження» надає необмежений доступ до основних розумних контрактів, надаючи їм змогу використовувати затверджені кількості токенів без обмежень." + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:266 +msgid "Theme" +msgstr "Тема" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:39 +msgid "Duplicate Token" +msgstr "Duplicate Token" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:40 +msgid "The address you entered is duplicate, please enter a new address." +msgstr "Уведена вами адреса дублюється, будь ласка, введіть нову адресу." + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:46 +msgid "Token Already Exists" +msgstr "Токен вже існує" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:47 +msgid "There's no need to add this token again because it already exists and is supported by us." +msgstr "Немає потреби знову додавати цей токен, тому що він вже існує і підтримується нами." + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:53 +msgid "Token Not Found" +msgstr "Маркер не знайдено" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:54 +msgid "Sorry, no token was found on {blockchain} chain with the provided address. please make sure you have entered the right token address." +msgstr "На жаль, в ланцюжку {blockchain} не знайдено жодного токена. Переконайтеся, що ви ввели правильну адресу токену." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:78 +msgid "Network Error" +msgstr "Помилка мережі" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:109 +#: widget/embedded/src/pages/CustomTokensPage.tsx:149 +msgid "Add Custom Token" +msgstr "Додати користувацький токен" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:127 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:128 +msgid "Select chain" +msgstr "Виберіть ланцюжок" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:132 +msgid "Enter Address" +msgstr "Введіть адресу" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:139 +msgid "Enter token address" +msgstr "Введіть адресу маркера" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:176 +msgid "Failed Network, Please retry." +msgstr "Невдала мережа, спробуйте ще раз." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:192 +msgid "Add another custom token" +msgstr "Додати інший користувацький токен" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:236 +msgid "Confirm Swap" +msgstr "Підтвердити своп" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:254 +msgid "Start Swap" +msgstr "Почати поміняти" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:282 +msgid "You get" +msgstr "Ви отримуєте" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:102 +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:90 +msgid "Search Token" +msgstr "Пошук маркер" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:134 +msgid "No custom tokens" +msgstr "Немає власних токенів" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:135 +msgid "press the button to add your custom token" +msgstr "натисніть кнопку, щоб додати свій власний токен" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:158 +msgid "Delete Custom Token" +msgstr "Видалити користувацький токен" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:160 +msgid "Are you sure you want to Delete this Token?" +msgstr "Ви впевнені, що хочете видалити цей токен?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:59 +msgid "Complete" +msgstr "Complete" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:63 +msgid "Running" +msgstr "Біг" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:65 +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:8 +msgid "Failed" +msgstr "Не вдалося" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:149 +msgid "Clear" +msgstr "Очистити" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:161 +msgid "Search Transaction" +msgstr "Пошук транзакції" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:187 +msgid "No transactions" +msgstr "Операції відсутні" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:194 +msgid "Your transaction history is stored locally and will appear here after you start a swap" +msgstr "Історія ваших транзакцій зберігається локально і з'явиться тут після того, як ви почнете заміну" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:218 +msgid "Clear Transaction History" +msgstr "Очистити історію транзакцій" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:222 +msgid "Proceeding will remove all successful and failed transactions from the widget. Do you want to continue?" +msgstr "Продовжуючи, буде видалено всі успішні та невдалі транзакції з віджета. Бажаєте продовжити?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:229 +msgid "Note: This does not erase your transaction history on the chain; it only removes them here." +msgstr "Примітка: В ланцюжку історія ваших транзакцій не видаляється; він тільки видаляє їх тут." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:243 +msgid "Yes, Clear the history" +msgstr "Так, очистити історію" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LanguagePage.tsx:56 +msgid "language" +msgstr "мова" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:121 +msgid "Deselect all" +msgstr "Зняти всі виділення" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:121 +msgid "Select all" +msgstr "Виділити все" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:133 +msgid "Search {sourceType}" +msgstr "Шукати {sourceType}" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectBlockchainPage.tsx:60 +msgid "Search Chain" +msgstr "Шукати ланцюжок" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:67 +msgid "Source" +msgstr "Джерело" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:68 +msgid "Destination" +msgstr "Пункт призначення" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:74 +msgid "Swap {type}" +msgstr "Поміняти {type}" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SettingsPage.tsx:45 +msgid "Currently, you're in campaign mode with restrictions on liquidity sources. Would you like to switch out of this mode and make use of all available liquidity sources?" +msgstr "В даний час ви в режимі кампанії з обмеженнями джерел ліквідності. Ви хотіли б вийти з цього режиму і використати всі наявні джерела ліквідності?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SwapDetailsPage.tsx:27 +msgid "The request ID is necessary to display the swap details." +msgstr "Ідентифікатор запиту необхідний для відображення деталей своп." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/WalletsPage.tsx:67 +#: widget/ui/src/containers/ConnectWalletsModal/ConnectWalletsModal.tsx:15 +msgid "Connect Wallets" +msgstr "Підключення гаманців" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/WalletsPage.tsx:82 +msgid "Choose a wallet to connect." +msgstr "Виберіть гаманець для підключення." + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:25 +msgid "This week" +msgstr "Цього тижня" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:32 +msgid "This month" +msgstr "Цього місяця" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:39 +msgid "This year" +msgstr "Цього року" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:129 +msgid "Required: >= {min} {symbol}" +msgstr "Обов'язково: >= {min} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:142 +msgid "Required: > {min} {symbol}" +msgstr "Обов'язково: > {min} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:157 +msgid "Required: <= {max} {symbol}" +msgstr "Обов'язково: <= {max} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:170 +msgid "Required: < {max} {symbol}" +msgstr "Обов'язково: < {max} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:601 +msgid " for network fee" +msgstr " за збір мережі" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:604 +msgid " for swap" +msgstr " для свопа" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:607 +msgid " for input and network fee" +msgstr " за вхідний та мережевий збір" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:609 +msgid "Needs ≈ {requiredAmount} {symbol}{reason}, but you have {currentAmount} {symbol} in your {blockchain} wallet." +msgstr "Необхідний TrueCon {requiredAmount} {symbol}{reason}, але ви маєте {currentAmount} {symbol} в гаманці {blockchain}." + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:669 +msgid "Waiting for connecting wallet" +msgstr "Очікування підключення гаманця" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:673 +msgid "Waiting for other running tasks to be finished" +msgstr "Очікуємо завершення інших запущених задач" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:676 +msgid "Waiting for changing wallet network" +msgstr "Очікування зміни мережі гаманця" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:6 +msgid "Sunday" +msgstr "Неділя" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:7 +msgid "Monday" +msgstr "Понеділок" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:8 +msgid "Tuesday" +msgstr "Вівторок" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:9 +msgid "Wednesday" +msgstr "Середа" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:10 +msgid "Thursday" +msgstr "Четвер" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:11 +msgid "Friday" +msgstr "П'ятниця" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:12 +msgid "Saturday" +msgstr "Субота" + +#. js-lingui-explicit-id +#: widget/ui/src/components/BottomLogo/BottomLogo.tsx:14 +msgid "Powered By" +msgstr "Надано" + +#. js-lingui-explicit-id +#: widget/ui/src/components/FullExpandedQuote/FullExpandedQuote.Tooltip.tsx:37 +msgid "Aggregated Transaction" +msgstr "Сукупна транзакція" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SelectableCategoryList/SelectableCategoryList.tsx:63 +msgid "{blockchainCategory}" +msgstr "{blockchainCategory}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/StepDetails/StepDetails.tsx:75 +#: widget/ui/src/components/StepDetails/StepDetails.tsx:102 +msgid "Swap on {fromChain} via {swapper}" +msgstr "Поміняти на {fromChain} через {swapper}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/StepDetails/StepDetails.tsx:109 +msgid "Bridge to {toChain} via {swapper}" +msgstr "Міст до {toChain} через {swapper}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:10 +msgid "Completed" +msgstr "Завершені" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:12 +msgid "In progress" +msgstr "Обробка" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapToken.tsx:122 +msgid "Waiting for bridge transaction" +msgstr "Очікування операції з мостом" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:12 +msgid "Connected" +msgstr "Підключено" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:13 +msgid "Disconnect" +msgstr "Від'єднатись" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:18 +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:19 +msgid "Install" +msgstr "Інсталювати" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:24 +msgid "Connecting ..." +msgstr "Під'єднання..." + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:25 +msgid "Connecting" +msgstr "З’єднання" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:30 +msgid "Disconnected" +msgstr "Від’єднано" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:34 +msgid "you need to pass a correct state to Wallet." +msgstr "ви маєте передати правильний стан до Wallet." + +#. js-lingui-explicit-id +#: widget/ui/src/containers/Notifications/NotificationNotFound.tsx:15 +msgid "There are no notifications." +msgstr "Немає сповіщень." + +#. js-lingui-explicit-id +#: widget/ui/src/containers/Notifications/Notifications.tsx:39 +msgid "Clear all" +msgstr "Очистити все" + +#. js-lingui-explicit-id +#: widget/ui/src/containers/SwapInput/SwapInput.tsx:65 +msgid "Balance" +msgstr "Баланс" + +#. js-lingui-explicit-id +#: widget/ui/src/containers/SwapInput/SwapInput.tsx:73 +msgid "Max" +msgstr "Макс" + diff --git a/translations/ur.po b/translations/ur.po new file mode 100644 index 0000000000..fed66ed5d0 --- /dev/null +++ b/translations/ur.po @@ -0,0 +1,1339 @@ +msgid "" +msgstr "" +"POT-Creation-Date: 2023-11-06 17:24+0330\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: @lingui/cli\n" +"Language: ur\n" +"Project-Id-Version: rango\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2024-11-27 15:57\n" +"Last-Translator: \n" +"Language-Team: Urdu (Pakistan)\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Crowdin-Project: rango\n" +"X-Crowdin-Project-ID: 622238\n" +"X-Crowdin-Language: ur-PK\n" +"X-Crowdin-File: en.po\n" +"X-Crowdin-File-ID: 30\n" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SameTokensWarning/SameTokensWarning.tsx:21 +msgid "No Routes Found" +msgstr "کوئی راستہ نہیں ملا" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SameTokensWarning/SameTokensWarning.tsx:25 +msgid "You cannot use the same token for From and To." +msgstr "آپ From اور To کے لیے ایک ہی ٹوکن استعمال نہیں کر سکتے۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:41 +#: widget/embedded/src/components/TokenList/TokenList.tsx:286 +#: widget/embedded/src/pages/HistoryPage.tsx:186 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:143 +msgid "No results found" +msgstr "کوئی نتیجہ نہیں ملا" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:42 +#: widget/embedded/src/components/TokenList/TokenList.tsx:287 +#: widget/embedded/src/pages/HistoryPage.tsx:193 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:144 +msgid "Try using different keywords" +msgstr "مختلف مطلوبہ الفاظ استعمال کرنے کی کوشش کریں۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:72 +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:46 +#: widget/embedded/src/pages/SelectBlockchainPage.tsx:42 +#: widget/ui/src/containers/SwapInput/TokenSection.tsx:61 +msgid "Select Chain" +msgstr "چین منتخب کریں۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:66 +msgid "All" +msgstr "تمام" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:100 +msgid "More +{count}" +msgstr "مزید +{count}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabAlert/ActivateTabAlert.tsx:17 +msgid "Activate this tab" +msgstr "اس ٹیب کو چالو کریں۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabAlert/ActivateTabAlert.tsx:22 +msgid "Another tab is open and handles transactions." +msgstr "ایک اور ٹیب کھلا ہے اور لین دین کو ہینڈل کرتا ہے۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:20 +msgid "Activate current tab" +msgstr "موجودہ ٹیب کو چالو کریں۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:22 +msgid "Currently, some transactions are running and being handled by other browser tab. If you activate this tab, all transactions that are already in the transaction sign step will expire." +msgstr "فی الحال، کچھ لین دین چل رہے ہیں اور دوسرے براؤزر ٹیب کے ذریعے ہینڈل کیے جا رہے ہیں۔ اگر آپ اس ٹیب کو چالو کرتے ہیں، تو وہ تمام لین دین جو پہلے سے ہی لین دین کے نشان کے مرحلے میں ہیں ختم ہو جائیں گے۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:33 +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:349 +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:152 +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:33 +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:116 +msgid "Confirm" +msgstr "تصدیق کریں۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:365 +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:447 +msgid "Your {blockchainName} wallets" +msgstr "آپ کے {blockchainName} بٹوے" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:384 +msgid "Insufficient account balance" +msgstr "ناکافی اکاؤنٹ بیلنس" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:394 +msgid "Proceed anyway" +msgstr "بہرحال آگے بڑھیں۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:456 +msgid "You need to connect a {blockchainName} wallet." +msgstr "آپ کو ایک {blockchainName} والیٹ جوڑنے کی ضرورت ہے۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/WalletList.tsx:143 +msgid "Add {chain} chain" +msgstr "{chain} چین شامل کریں۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/WalletList.tsx:244 +msgid "Show more wallets" +msgstr "مزید بٹوے دکھائیں۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:113 +msgid "Send to a different address" +msgstr "کسی دوسرے ایڈریس پر بھیجیں۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:129 +msgid "Enter {blockchainName} address" +msgstr "{blockchainName} پتہ درج کریں۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:147 +msgid "Address {destination} doesn't match the blockchain address pattern." +msgstr "پتہ {destination} بلاکچین ایڈریس پیٹرن سے مماثل نہیں ہے۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:59 +msgid "via" +msgstr "کے ذریعے" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:74 +msgid "This token doesn't appear on the active token list(s). Make sure this is the token that you want to trade." +msgstr "یہ ٹوکن ایکٹو ٹوکن لسٹ پر ظاہر نہیں ہوتا ہے۔ یقینی بنائیں کہ یہ وہ ٹوکن ہے جس کی آپ تجارت کرنا چاہتے ہیں۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:89 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:164 +msgid "Import" +msgstr "درآمد کریں۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/FilterSelector/FilterSelectorContent.tsx:26 +msgid "Status" +msgstr "حیثیت" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/FilterSelector/FilterSelectorContent.tsx:33 +#: widget/embedded/src/components/NoResult/NoResult.helpers.ts:37 +#: widget/embedded/src/pages/SettingsPage.tsx:55 +msgid "Reset" +msgstr "دوبارہ ترتیب دیں۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/CancelButton.tsx:18 +msgid "Cancel" +msgstr "منسوخ کریں۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:46 +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:34 +msgid "Refresh" +msgstr "تازہ دم کریں۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:63 +#: widget/ui/src/containers/Notifications/Notifications.tsx:35 +msgid "Notifications" +msgstr "اطلاعات" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:79 +#: widget/embedded/src/pages/SettingsPage.tsx:38 +msgid "Settings" +msgstr "ترتیبات" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:93 +#: widget/embedded/src/pages/HistoryPage.tsx:139 +msgid "History" +msgstr "تاریخ" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/WalletButton.tsx:22 +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:16 +#: widget/embedded/src/constants/messages.ts:5 +msgid "Connect Wallet" +msgstr "والیٹ کو جوڑیں۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HistoryGroupedList/HistoryGroupedList.tsx:118 +#: widget/embedded/src/utils/date.ts:18 +#: widget/embedded/src/utils/time.ts:22 +msgid "Today" +msgstr "آج" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/LoadingSwapDetails/LoadingSwapDetails.tsx:20 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:424 +msgid "Swaps steps" +msgstr "قدموں کی تبدیلی" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/NoResult/NoResult.helpers.ts:25 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:191 +msgid "Retry" +msgstr "دوبارہ کوشش کریں۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:149 +msgid "Slippage Error" +msgstr "پھسلن کی خرابی۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:150 +msgid "Slippage Warning" +msgstr "پھسلن کی وارننگ" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:153 +msgid "Bridge Limit Error" +msgstr "پل کی حد کی خرابی۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:240 +msgid "Yours: {amount} {symbol}" +msgstr "آپ کا: {amount} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:261 +msgid "Minimum required slippage: {minRequiredSlippage}" +msgstr "کم از کم مطلوبہ slippage: {minRequiredSlippage}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:282 +msgid "Yours: {userSlippage}" +msgstr "آپ کا: {userSlippage}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:395 +msgid "See All Routes" +msgstr "تمام راستے دیکھیں" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:81 +msgid "View more info" +msgstr "مزید معلومات دیکھیں" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:91 +msgid "Gas & Fee Explanation" +msgstr "گیس اور فیس کی وضاحت" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:107 +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:103 +msgid "Details" +msgstr "تفصیلات" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:146 +msgid "Total Payable Fee" +msgstr "کل قابل ادائیگی فیس" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:166 +msgid "Hide non-payable fees" +msgstr "غیر قابل ادائیگی فیس چھپائیں۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:167 +msgid "Show non-payable fees" +msgstr "غیر قابل ادائیگی فیس دکھائیں۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:177 +msgid "Description" +msgstr "تفصیل" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:181 +msgid "The following fees are considered in the transaction output and\n" +" you won’t need to pay extra gas for them." +msgstr "لین دین کے آؤٹ پٹ میں درج ذیل فیسوں پر غور کیا جاتا ہے اور\n" +" آپ کو ان کے لیے اضافی گیس ادا کرنے کی ضرورت نہیں ہوگی۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteSummary.tsx:25 +msgid "Swap input" +msgstr "ان پٹ کو تبدیل کریں۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteSummary.tsx:44 +msgid "Estimated output" +msgstr "تخمینی پیداوار" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteTrigger.tsx:65 +msgid "Via:" +msgstr "بذریعہ:" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteTrigger.tsx:150 +msgid "Chains:" +msgstr "زنجیریں:" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/Quotes.tsx:77 +msgid "Sort by" +msgstr "ترتیب دیں" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:17 +msgid "Smart Routing" +msgstr "اسمارٹ روٹنگ" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:21 +msgid "Lowest Fee" +msgstr "سب سے کم فیس" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:25 +msgid "Fastest Transfer" +msgstr "تیز ترین ٹرانسفر" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:29 +msgid "Maximum Return" +msgstr "زیادہ سے زیادہ واپسی" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:33 +msgid "Maximum Output" +msgstr "زیادہ سے زیادہ آؤٹ پٹ" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:43 +msgid "Swapping" +msgstr "تبادلہ کرنا" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:51 +msgid "Gas cost" +msgstr "گیس کی قیمت" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:59 +msgid "Receiving" +msgstr "وصول کرنا" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:67 +msgid "Price impact" +msgstr "قیمت کا اثر" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:35 +msgid "You need to increase slippage to at least {minRequiredSlippage} for this route." +msgstr "اس راستے کے لیے آپ کو پھسلن کو کم از کم {minRequiredSlippage} تک بڑھانا ہوگا۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:59 +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:61 +msgid "We recommend you to increase slippage to at least {minRequiredSlippage} for this route." +msgstr "ہم آپ کو مشورہ دیتے ہیں کہ اس راستے کے لیے پھسلن کو کم از کم {minRequiredSlippage} تک بڑھا دیں۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:68 +msgid "Caution, your slippage is high." +msgstr "خبردار، آپ کی پھسلن زیادہ ہے۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.tsx:78 +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.Warning.tsx:26 +msgid "Change" +msgstr "تبدیلی" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:42 +msgid "Change settings" +msgstr "ترتیبات تبدیل کریں۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:52 +msgid "High slippage" +msgstr "اونچی پھسلن" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:53 +msgid "Low slippage" +msgstr "کم پھسلنا" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:57 +msgid " Caution, your slippage is high (={userSlippage}). Your trade may be front run." +msgstr " احتیاط، آپ کا پھسلنا زیادہ ہے (={userSlippage})۔ آپ کی تجارت آگے چل سکتی ہے۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:78 +msgid "Confirm anyway" +msgstr "بہرحال تصدیق کریں۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:22 +msgid "Something went wrong" +msgstr "کچھ غلط ہو گیا۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:24 +msgid "Something went wrong. Please refresh the app." +msgstr "کچھ غلط ہو گیا۔ براہ کرم ایپ کو ریفریش کریں۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/Slippage.tsx:38 +msgid "Slippage tolerance per swap" +msgstr "slippage رواداری فی سویپ" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/Slippage.tsx:91 +msgid "Custom" +msgstr "حسب ضرورت" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:11 +msgid "Your transaction will be reverted if the price changes unfavorably by more than this percentage." +msgstr "اگر قیمت اس فیصد سے زیادہ ناموافق طور پر تبدیل ہوتی ہے تو آپ کا لین دین واپس کر دیا جائے گا۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:16 +#: widget/embedded/src/containers/Settings/Lists.tsx:245 +msgid "Warning" +msgstr "وارننگ" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:17 +msgid "This setting is applied to each step (e.g. 1Inch, Thorchain, etc.), meaning only that specific step will be reverted, not the entire route." +msgstr "یہ ترتیب ہر قدم (مثلاً 1 انچ، تھورچین، وغیرہ) پر لاگو ہوتی ہے، یعنی صرف وہی مخصوص مرحلہ واپس کیا جائے گا، پورے راستے پر نہیں۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:25 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:269 +msgid "Swap Details" +msgstr "تفصیلات تبدیل کریں۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:33 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:312 +msgid "Request ID" +msgstr "ID کی درخواست کریں۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:64 +msgid "Not found" +msgstr "نہیں ملا" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:65 +msgid "Swap with request ID = {requestId} not found." +msgstr "درخواست ID = {requestId} کے ساتھ تبادلہ نہیں ملا۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:219 +msgid "You have received {amount} {token} in {conciseAddress} wallet on {chain} chain." +msgstr "آپ کو {chain} چین پر {conciseAddress} والیٹ میں {amount} {token} موصول ہوا ہے۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:242 +msgid "Transaction was not sent." +msgstr "لین دین نہیں بھیجا گیا تھا۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:244 +msgid "{amount} {symbol} on {blockchain} remains in your wallet." +msgstr "{amount} {symbol} پر {blockchain} آپ کے بٹوے میں رہتا ہے۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:281 +msgid "Delete" +msgstr "حذف کریں۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:304 +msgid "Try again" +msgstr "دوبارہ کوشش کریں۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:322 +msgid "Copied To Clipboard" +msgstr "کلپ بورڈ پر کاپی کیا گیا۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:323 +msgid "Copy Request ID" +msgstr "درخواست کی شناخت کاپی کریں۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:346 +msgid "View on Rango Explorer" +msgstr "رنگو ایکسپلورر پر دیکھیں" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:355 +msgid "Finished at" +msgstr "پر ختم ہوا۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:355 +msgid "Created at" +msgstr "پر تخلیق کیا گیا۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.tsx:50 +msgid "View transaction" +msgstr "لین دین دیکھیں" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.Warning.tsx:49 +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:31 +msgid "Connect" +msgstr "جڑیں" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:43 +msgid "Swap Successful" +msgstr "تبادلہ کامیاب" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:71 +msgid "Transaction Failed" +msgstr "لین دین ناکام ہو گیا۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:87 +msgid "Done" +msgstr "ہو گیا" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:100 +msgid "Diagnosis" +msgstr "تشخیص" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:112 +msgid "See Details" +msgstr "تفصیلات دیکھیں" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:13 +msgid "Cancel Swap" +msgstr "تبادلہ منسوخ کریں۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:14 +msgid "Are you sure you want to cancel this swap?" +msgstr "کیا آپ واقعی اس تبادلہ کو منسوخ کرنا چاہتے ہیں؟" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:23 +msgid "Yes, Cancel it" +msgstr "ہاں، اسے منسوخ کر دیں۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:32 +#: widget/embedded/src/pages/CustomTokensPage.tsx:181 +msgid "No, Continue" +msgstr "نہیں، جاری رکھیں" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:13 +msgid "Delete Transaction" +msgstr "لین دین کو حذف کریں۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:14 +msgid "Are you sure you want to delete this swap?" +msgstr "کیا آپ واقعی اس تبادلہ کو حذف کرنا چاہتے ہیں؟" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:23 +#: widget/embedded/src/pages/CustomTokensPage.tsx:171 +msgid "Yes, Delete it" +msgstr "ہاں، اسے حذف کریں۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:33 +#: widget/embedded/src/pages/HistoryPage.tsx:253 +msgid "No, Cancel" +msgstr "نہیں، منسوخ کریں۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:12 +msgid "Change Network" +msgstr "نیٹ ورک تبدیل کریں۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:20 +msgid "Network Changed" +msgstr "نیٹ ورک بدل گیا۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/TokenList/TokenList.tsx:271 +#: widget/ui/src/containers/SwapInput/TokenSection.tsx:54 +msgid "Select Token" +msgstr "ٹوکن منتخب کریں۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:27 +msgid "Wallet Connected" +msgstr "والیٹ منسلک ہے۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:28 +msgid "Your wallet is connected, you can use it to swap." +msgstr "آپ کا بٹوہ منسلک ہے، آپ اسے تبدیل کرنے کے لیے استعمال کر سکتے ہیں۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:39 +msgid "Failed to Connect" +msgstr "مربوط ہونے میں ناکام" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:41 +msgid "Your wallet is not connected. Please try again." +msgstr "آپ کا بٹوہ منسلک نہیں ہے۔ براہ کرم دوبارہ کوشش کریں۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:50 +msgid "Connecting to your wallet" +msgstr "آپ کے بٹوے سے منسلک ہو رہا ہے۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:51 +msgid "Click connect in your wallet popup." +msgstr "اپنے والٹ پاپ اپ میں کنیکٹ پر کلک کریں۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:99 +msgid "Select Derivation Path" +msgstr "اخذ کرنے کا راستہ منتخب کریں۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:100 +msgid "In order to connect to {type}, you must first select a Derivation Path" +msgstr "{type}سے جڑنے کے لیے، آپ کو پہلے اخذ کرنے کا راستہ منتخب کرنا ہوگا۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:118 +msgid "Choose Derivation Path Template" +msgstr "اخذ پاتھ ٹیمپلیٹ کا انتخاب کریں۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:133 +msgid "Enter Path" +msgstr "راستہ داخل کریں۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:134 +msgid "Enter Index" +msgstr "انڈیکس درج کریں۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:15 +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:18 +msgid "Add {blockchainDisplayName} Chain" +msgstr "{blockchainDisplayName} چین شامل کریں۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:20 +msgid "Would you like to add the {blockchainDisplayName} experimental chain to your wallet?" +msgstr "کیا آپ اپنے بٹوے میں {blockchainDisplayName} تجرباتی سلسلہ شامل کرنا چاہیں گے؟" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:22 +msgid "Please approve the experimental chain pop-up in your wallet." +msgstr "براہ کرم اپنے بٹوے میں تجرباتی چین کے پاپ اپ کو منظور کریں۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:30 +msgid "{blockchainDisplayName} Chain Added" +msgstr "{blockchainDisplayName} سلسلہ شامل کر دیا گیا۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:34 +msgid "The {blockchainDisplayName} chain has been successfully added to your wallet." +msgstr "{blockchainDisplayName} سلسلہ کامیابی کے ساتھ آپ کے بٹوے میں شامل کر دیا گیا ہے۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:42 +msgid "Request Rejected" +msgstr "درخواست مسترد کر دی گئی۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:43 +msgid "You've rejected adding {blockchainDisplayName} chain to your wallet." +msgstr "آپ نے اپنے بٹوے میں {blockchainDisplayName} چین شامل کرنے کو مسترد کر دیا ہے۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:70 +msgid "Select chain types" +msgstr "زنجیر کی اقسام منتخب کریں۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:71 +msgid "This wallet supports multiple chains. Select which chain you'd like to connect to." +msgstr "یہ پرس متعدد زنجیروں کو سپورٹ کرتا ہے۔ منتخب کریں کہ آپ کس سلسلہ سے جڑنا چاہتے ہیں۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:9 +msgid "Failed Network, Please retry your swap." +msgstr "ناکام نیٹ ورک، براہ کرم اپنے تبادلہ کی دوبارہ کوشش کریں۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:11 +msgid "Please reset your liquidity sources." +msgstr "براہ کرم اپنے لیکویڈیٹی ذرائع کو دوبارہ ترتیب دیں۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:12 +msgid "You have limited the liquidity sources and this might result in Rango finding no routes. Please consider resetting your liquidity sources." +msgstr "آپ نے لیکویڈیٹی ذرائع کو محدود کر دیا ہے اور اس کے نتیجے میں رنگو کو کوئی راستہ نہیں مل سکتا ہے۔ براہ کرم اپنے لیکویڈیٹی ذرائع کو دوبارہ ترتیب دینے پر غور کریں۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:17 +msgid "No Routes Found." +msgstr "کوئی راستہ نہیں ملا۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:18 +msgid "Reasons why Rango couldn't find a route: low liquidity on token, very low input amount or no routes available for the selected input/output token combination." +msgstr "Rango کو روٹ نہ ملنے کی وجوہات: ٹوکن پر کم لیکویڈیٹی، بہت کم ان پٹ رقم یا منتخب کردہ ان پٹ/آؤٹ پٹ ٹوکن امتزاج کے لیے کوئی روٹس دستیاب نہیں۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:23 +msgid "Bridge Limit Error: Please increase your amount." +msgstr "برج کی حد کی خرابی: براہ کرم اپنی رقم بڑھائیں۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:26 +msgid "Bridge Limit Error: Please decrease your amount." +msgstr "برج کی حد کی خرابی: براہ کرم اپنی رقم کم کریں۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:31 +msgid "High Price Impact" +msgstr "اعلی قیمت کا اثر" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:32 +msgid "Price impact is too high!" +msgstr "قیمت کا اثر بہت زیادہ ہے!" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:33 +msgid "The price impact is significantly higher than the allowed amount." +msgstr "قیمت کا اثر قابل اجازت رقم سے کافی زیادہ ہے۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:36 +msgid "Confirm high price impact" +msgstr "اعلی قیمت کے اثر کی تصدیق کریں۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:39 +msgid "Route updated and price impact is too high, try again later!" +msgstr "راستہ اپ ڈیٹ ہوا اور قیمت کا اثر بہت زیادہ ہے، بعد میں دوبارہ کوشش کریں!" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:44 +msgid "USD Price Unknown" +msgstr "USD قیمت نامعلوم ہے۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:45 +msgid "USD Price Unknown, Cannot calculate Price Impact." +msgstr "USD قیمت نامعلوم ہے، قیمت کے اثرات کا حساب نہیں لگایا جا سکتا۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:46 +msgid "USD Price Unknown, Cannot calculate Price Impact. The price impact may be higher than usual. Are you sure to continue the Swap?" +msgstr "USD قیمت نامعلوم ہے، قیمت کے اثرات کا حساب نہیں لگایا جا سکتا۔ قیمت کا اثر معمول سے زیادہ ہو سکتا ہے۔ کیا آپ کو تبادلہ جاری رکھنے کا یقین ہے؟" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:49 +msgid "Confirm USD Price Unknown" +msgstr "نامعلوم USD قیمت کی تصدیق کریں۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:6 +#: widget/embedded/src/pages/Home.tsx:163 +msgid "Swap" +msgstr "تبادلہ" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:7 +msgid "Swap anyway" +msgstr "بہرحال تبادلہ کریں۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:8 +msgid "The route goes through Ethereum. Continue?" +msgstr "راستہ Ethereum سے گزرتا ہے۔ جاری رکھیں؟" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:10 +msgid "Route has been updated." +msgstr "روٹ کو اپ ڈیٹ کر دیا گیا ہے۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:12 +msgid "Output amount changed to {newOutputAmount} ({percentageChange}% change)." +msgstr "آؤٹ پٹ کی رقم کو {newOutputAmount} میں تبدیل کر دیا گیا ({percentageChange}% تبدیلی)۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:20 +msgid "Route swappers has been updated." +msgstr "روٹ سویپرز کو اپ ڈیٹ کر دیا گیا ہے۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:22 +msgid "Route internal coins has been updated." +msgstr "راستے کے اندرونی سککوں کو اپ ڈیٹ کر دیا گیا ہے۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/ExpandedQuotes/ExpandedQuotes.tsx:53 +#: widget/embedded/src/pages/Routes.tsx:48 +msgid "Routes" +msgstr "راستے" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Inputs/Inputs.tsx:76 +msgid "From" +msgstr "سے" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Inputs/Inputs.tsx:118 +msgid "To" +msgstr "کو" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:49 +msgid "Light" +msgstr "روشنی" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:58 +msgid "Dark" +msgstr "اندھیرا" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:67 +msgid "Auto" +msgstr "آٹو" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:140 +msgid "Loading failed" +msgstr "لوڈنگ ناکام ہو گئی۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:156 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:41 +msgid "Bridges" +msgstr "پل" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:174 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:41 +msgid "Exchanges" +msgstr "تبادلہ" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:195 +#: widget/embedded/src/pages/CustomTokensPage.tsx:90 +msgid "Custom Tokens" +msgstr "حسب ضرورت ٹوکنز" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:214 +#: widget/embedded/src/pages/LanguagePage.tsx:43 +msgid "Language" +msgstr "زبان" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:235 +msgid "Infinite approval" +msgstr "لامحدود منظوری" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:246 +msgid "Enabling the 'Infinite approval' mode grants unrestricted access to underlying smart contracts, allowing them to utilize the approved token amount without limitations." +msgstr "'لامحدود منظوری' موڈ کو فعال کرنے سے بنیادی سمارٹ معاہدوں تک غیر محدود رسائی حاصل ہوتی ہے، جس سے وہ منظور شدہ ٹوکن رقم کو بغیر کسی پابندی کے استعمال کر سکتے ہیں۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:266 +msgid "Theme" +msgstr "تھیم" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:39 +msgid "Duplicate Token" +msgstr "ڈپلیکیٹ ٹوکن" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:40 +msgid "The address you entered is duplicate, please enter a new address." +msgstr "آپ نے جو پتہ درج کیا ہے وہ ڈپلیکیٹ ہے، براہ کرم ایک نیا پتہ درج کریں۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:46 +msgid "Token Already Exists" +msgstr "ٹوکن پہلے سے موجود ہے۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:47 +msgid "There's no need to add this token again because it already exists and is supported by us." +msgstr "اس ٹوکن کو دوبارہ شامل کرنے کی ضرورت نہیں ہے کیونکہ یہ پہلے سے موجود ہے اور ہمارے ذریعہ تعاون یافتہ ہے۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:53 +msgid "Token Not Found" +msgstr "ٹوکن نہیں ملا" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:54 +msgid "Sorry, no token was found on {blockchain} chain with the provided address. please make sure you have entered the right token address." +msgstr "معذرت، فراہم کردہ پتے کے ساتھ {blockchain} چین پر کوئی ٹوکن نہیں ملا۔ براہ کرم یقینی بنائیں کہ آپ نے صحیح ٹوکن ایڈریس درج کیا ہے۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:78 +msgid "Network Error" +msgstr "نیٹ ورک کی خرابی۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:109 +#: widget/embedded/src/pages/CustomTokensPage.tsx:149 +msgid "Add Custom Token" +msgstr "حسب ضرورت ٹوکن شامل کریں۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:127 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:128 +msgid "Select chain" +msgstr "سلسلہ منتخب کریں۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:132 +msgid "Enter Address" +msgstr "ایڈریس درج کریں۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:139 +msgid "Enter token address" +msgstr "ٹوکن ایڈریس درج کریں۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:176 +msgid "Failed Network, Please retry." +msgstr "ناکام نیٹ ورک، براہ کرم دوبارہ کوشش کریں۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:192 +msgid "Add another custom token" +msgstr "ایک اور حسب ضرورت ٹوکن شامل کریں۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:236 +msgid "Confirm Swap" +msgstr "تبادلہ کی تصدیق کریں۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:254 +msgid "Start Swap" +msgstr "تبادلہ شروع کریں۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:282 +msgid "You get" +msgstr "آپ حاصل کریں" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:102 +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:90 +msgid "Search Token" +msgstr "ٹوکن تلاش کریں۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:134 +msgid "No custom tokens" +msgstr "کوئی حسب ضرورت ٹوکن نہیں۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:135 +msgid "press the button to add your custom token" +msgstr "اپنا حسب ضرورت ٹوکن شامل کرنے کے لیے بٹن دبائیں۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:158 +msgid "Delete Custom Token" +msgstr "حسب ضرورت ٹوکن حذف کریں۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:160 +msgid "Are you sure you want to Delete this Token?" +msgstr "کیا آپ واقعی اس ٹوکن کو حذف کرنا چاہتے ہیں؟" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:59 +msgid "Complete" +msgstr "مکمل" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:63 +msgid "Running" +msgstr "چل رہا ہے۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:65 +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:8 +msgid "Failed" +msgstr "ناکام" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:149 +msgid "Clear" +msgstr "صاف" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:161 +msgid "Search Transaction" +msgstr "لین دین تلاش کریں۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:187 +msgid "No transactions" +msgstr "کوئی لین دین نہیں۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:194 +msgid "Your transaction history is stored locally and will appear here after you start a swap" +msgstr "آپ کی لین دین کی سرگزشت مقامی طور پر ذخیرہ کی جاتی ہے اور آپ کے تبادلہ شروع کرنے کے بعد یہاں ظاہر ہوگی۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:218 +msgid "Clear Transaction History" +msgstr "لین دین کی تاریخ صاف کریں۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:222 +msgid "Proceeding will remove all successful and failed transactions from the widget. Do you want to continue?" +msgstr "آگے بڑھنے سے ویجیٹ سے تمام کامیاب اور ناکام ٹرانزیکشنز ہٹ جائیں گی۔ کیا آپ جاری رکھنا چاہتے ہیں؟" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:229 +msgid "Note: This does not erase your transaction history on the chain; it only removes them here." +msgstr "نوٹ: یہ سلسلہ پر آپ کی لین دین کی تاریخ کو نہیں مٹاتا ہے۔ یہ صرف انہیں یہاں ہٹاتا ہے۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:243 +msgid "Yes, Clear the history" +msgstr "ہاں، تاریخ کو صاف کریں۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LanguagePage.tsx:56 +msgid "language" +msgstr "زبان" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:121 +msgid "Deselect all" +msgstr "سبھی کو غیر منتخب کریں۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:121 +msgid "Select all" +msgstr "سبھی کو منتخب کریں۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:133 +msgid "Search {sourceType}" +msgstr "{sourceType}تلاش کریں۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectBlockchainPage.tsx:60 +msgid "Search Chain" +msgstr "سرچ چین" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:67 +msgid "Source" +msgstr "ماخذ" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:68 +msgid "Destination" +msgstr "منزل" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:74 +msgid "Swap {type}" +msgstr "تبادلہ {type}" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SettingsPage.tsx:45 +msgid "Currently, you're in campaign mode with restrictions on liquidity sources. Would you like to switch out of this mode and make use of all available liquidity sources?" +msgstr "فی الحال، آپ لیکویڈیٹی ذرائع پر پابندیوں کے ساتھ مہم کے موڈ میں ہیں۔ کیا آپ اس موڈ سے باہر نکل کر تمام دستیاب لیکویڈیٹی ذرائع کو استعمال کرنا چاہیں گے؟" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SwapDetailsPage.tsx:27 +msgid "The request ID is necessary to display the swap details." +msgstr "تبادلہ کی تفصیلات ظاہر کرنے کے لیے درخواست کی شناخت ضروری ہے۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/WalletsPage.tsx:67 +#: widget/ui/src/containers/ConnectWalletsModal/ConnectWalletsModal.tsx:15 +msgid "Connect Wallets" +msgstr "بٹوے کو جوڑیں۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/WalletsPage.tsx:82 +msgid "Choose a wallet to connect." +msgstr "جڑنے کے لیے ایک پرس کا انتخاب کریں۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:25 +msgid "This week" +msgstr "اس ہفتے" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:32 +msgid "This month" +msgstr "اس مہینے" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:39 +msgid "This year" +msgstr "اس سال" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:129 +msgid "Required: >= {min} {symbol}" +msgstr "مطلوبہ: >= {min} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:142 +msgid "Required: > {min} {symbol}" +msgstr "مطلوبہ: > {min} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:157 +msgid "Required: <= {max} {symbol}" +msgstr "مطلوبہ: <= {max} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:170 +msgid "Required: < {max} {symbol}" +msgstr "مطلوبہ: < {max} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:601 +msgid " for network fee" +msgstr " نیٹ ورک فیس کے لیے" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:604 +msgid " for swap" +msgstr " تبادلہ کے لیے" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:607 +msgid " for input and network fee" +msgstr " ان پٹ اور نیٹ ورک فیس کے لیے" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:609 +msgid "Needs ≈ {requiredAmount} {symbol}{reason}, but you have {currentAmount} {symbol} in your {blockchain} wallet." +msgstr "ضرورت ہے ≈ {requiredAmount} {symbol}{reason}، لیکن آپ کے {blockchain} والیٹ میں {currentAmount} {symbol} ہے۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:669 +msgid "Waiting for connecting wallet" +msgstr "بٹوے کو جوڑنے کا انتظار کر رہا ہے۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:673 +msgid "Waiting for other running tasks to be finished" +msgstr "دوسرے چلنے والے کاموں کے مکمل ہونے کا انتظار کر رہے ہیں۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:676 +msgid "Waiting for changing wallet network" +msgstr "بٹوے کے نیٹ ورک کو تبدیل کرنے کا انتظار کر رہے ہیں۔" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:6 +msgid "Sunday" +msgstr "اتوار" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:7 +msgid "Monday" +msgstr "پیر" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:8 +msgid "Tuesday" +msgstr "منگل" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:9 +msgid "Wednesday" +msgstr "بدھ" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:10 +msgid "Thursday" +msgstr "جمعرات" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:11 +msgid "Friday" +msgstr "جمعہ" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:12 +msgid "Saturday" +msgstr "ہفتہ" + +#. js-lingui-explicit-id +#: widget/ui/src/components/BottomLogo/BottomLogo.tsx:14 +msgid "Powered By" +msgstr "کی طرف سے طاقت" + +#. js-lingui-explicit-id +#: widget/ui/src/components/FullExpandedQuote/FullExpandedQuote.Tooltip.tsx:37 +msgid "Aggregated Transaction" +msgstr "مجموعی لین دین" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SelectableCategoryList/SelectableCategoryList.tsx:63 +msgid "{blockchainCategory}" +msgstr "{blockchainCategory}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/StepDetails/StepDetails.tsx:75 +#: widget/ui/src/components/StepDetails/StepDetails.tsx:102 +msgid "Swap on {fromChain} via {swapper}" +msgstr "{swapper}کے ذریعے {fromChain} پر تبادلہ کریں۔" + +#. js-lingui-explicit-id +#: widget/ui/src/components/StepDetails/StepDetails.tsx:109 +msgid "Bridge to {toChain} via {swapper}" +msgstr "{swapper}کے ذریعے {toChain} پر پل" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:10 +msgid "Completed" +msgstr "مکمل" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:12 +msgid "In progress" +msgstr "جاری ہے۔" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapToken.tsx:122 +msgid "Waiting for bridge transaction" +msgstr "پل کے لین دین کا انتظار ہے۔" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:12 +msgid "Connected" +msgstr "جڑا ہوا" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:13 +msgid "Disconnect" +msgstr "منقطع کرنا" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:18 +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:19 +msgid "Install" +msgstr "انسٹال کریں۔" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:24 +msgid "Connecting ..." +msgstr "منسلک ہو رہا ہے..." + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:25 +msgid "Connecting" +msgstr "جڑ رہا ہے۔" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:30 +msgid "Disconnected" +msgstr "منقطع" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:34 +msgid "you need to pass a correct state to Wallet." +msgstr "آپ کو Wallet میں ایک درست حالت منتقل کرنے کی ضرورت ہے۔" + +#. js-lingui-explicit-id +#: widget/ui/src/containers/Notifications/NotificationNotFound.tsx:15 +msgid "There are no notifications." +msgstr "کوئی اطلاعات نہیں ہیں۔" + +#. js-lingui-explicit-id +#: widget/ui/src/containers/Notifications/Notifications.tsx:39 +msgid "Clear all" +msgstr "سب صاف کریں۔" + +#. js-lingui-explicit-id +#: widget/ui/src/containers/SwapInput/SwapInput.tsx:65 +msgid "Balance" +msgstr "توازن" + +#. js-lingui-explicit-id +#: widget/ui/src/containers/SwapInput/SwapInput.tsx:73 +msgid "Max" +msgstr "زیادہ سے زیادہ" + diff --git a/translations/vi.po b/translations/vi.po new file mode 100644 index 0000000000..fe099c2a96 --- /dev/null +++ b/translations/vi.po @@ -0,0 +1,1339 @@ +msgid "" +msgstr "" +"POT-Creation-Date: 2023-11-06 17:24+0330\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: @lingui/cli\n" +"Language: vi\n" +"Project-Id-Version: rango\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2024-11-27 15:57\n" +"Last-Translator: \n" +"Language-Team: Vietnamese\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Crowdin-Project: rango\n" +"X-Crowdin-Project-ID: 622238\n" +"X-Crowdin-Language: vi\n" +"X-Crowdin-File: en.po\n" +"X-Crowdin-File-ID: 30\n" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SameTokensWarning/SameTokensWarning.tsx:21 +msgid "No Routes Found" +msgstr "Không tìm thấy tuyến đường nào" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SameTokensWarning/SameTokensWarning.tsx:25 +msgid "You cannot use the same token for From and To." +msgstr "Bạn không thể sử dụng cùng một mã thông báo cho Từ và Đến." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:41 +#: widget/embedded/src/components/TokenList/TokenList.tsx:286 +#: widget/embedded/src/pages/HistoryPage.tsx:186 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:143 +msgid "No results found" +msgstr "Không tìm thấy kết quả nào" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:42 +#: widget/embedded/src/components/TokenList/TokenList.tsx:287 +#: widget/embedded/src/pages/HistoryPage.tsx:193 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:144 +msgid "Try using different keywords" +msgstr "Hãy thử sử dụng các từ khóa khác nhau" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:72 +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:46 +#: widget/embedded/src/pages/SelectBlockchainPage.tsx:42 +#: widget/ui/src/containers/SwapInput/TokenSection.tsx:61 +msgid "Select Chain" +msgstr "Chọn chuỗi" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:66 +msgid "All" +msgstr "Tất cả" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:100 +msgid "More +{count}" +msgstr "Thêm +{count}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabAlert/ActivateTabAlert.tsx:17 +msgid "Activate this tab" +msgstr "Kích hoạt tab này" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabAlert/ActivateTabAlert.tsx:22 +msgid "Another tab is open and handles transactions." +msgstr "Một tab khác đang mở và xử lý các giao dịch." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:20 +msgid "Activate current tab" +msgstr "Kích hoạt tab hiện tại" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:22 +msgid "Currently, some transactions are running and being handled by other browser tab. If you activate this tab, all transactions that are already in the transaction sign step will expire." +msgstr "Hiện tại, một số giao dịch đang chạy và được xử lý bởi tab trình duyệt khác. Nếu bạn kích hoạt tab này, tất cả các giao dịch đã ở bước ký giao dịch sẽ hết hạn." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:33 +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:349 +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:152 +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:33 +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:116 +msgid "Confirm" +msgstr "Xác nhận" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:365 +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:447 +msgid "Your {blockchainName} wallets" +msgstr "Ví {blockchainName} của bạn" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:384 +msgid "Insufficient account balance" +msgstr "Số dư tài khoản không đủ" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:394 +msgid "Proceed anyway" +msgstr "Tiến hành dù sao đi nữa" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:456 +msgid "You need to connect a {blockchainName} wallet." +msgstr "Bạn cần kết nối ví {blockchainName} ." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/WalletList.tsx:143 +msgid "Add {chain} chain" +msgstr "Thêm chuỗi {chain}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/WalletList.tsx:244 +msgid "Show more wallets" +msgstr "Hiển thị thêm ví" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:113 +msgid "Send to a different address" +msgstr "Gửi đến một địa chỉ khác" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:129 +msgid "Enter {blockchainName} address" +msgstr "Nhập địa chỉ {blockchainName}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:147 +msgid "Address {destination} doesn't match the blockchain address pattern." +msgstr "Địa chỉ {destination} không khớp với mẫu địa chỉ blockchain." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:59 +msgid "via" +msgstr "thông qua" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:74 +msgid "This token doesn't appear on the active token list(s). Make sure this is the token that you want to trade." +msgstr "Mã thông báo này không xuất hiện trong danh sách mã thông báo đang hoạt động. Hãy đảm bảo đây là mã thông báo mà bạn muốn giao dịch." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:89 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:164 +msgid "Import" +msgstr "Nhập khẩu" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/FilterSelector/FilterSelectorContent.tsx:26 +msgid "Status" +msgstr "Trạng thái" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/FilterSelector/FilterSelectorContent.tsx:33 +#: widget/embedded/src/components/NoResult/NoResult.helpers.ts:37 +#: widget/embedded/src/pages/SettingsPage.tsx:55 +msgid "Reset" +msgstr "Cài lại" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/CancelButton.tsx:18 +msgid "Cancel" +msgstr "Hủy bỏ" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:46 +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:34 +msgid "Refresh" +msgstr "Làm cho khỏe lại" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:63 +#: widget/ui/src/containers/Notifications/Notifications.tsx:35 +msgid "Notifications" +msgstr "Thông báo" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:79 +#: widget/embedded/src/pages/SettingsPage.tsx:38 +msgid "Settings" +msgstr "Cài đặt" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:93 +#: widget/embedded/src/pages/HistoryPage.tsx:139 +msgid "History" +msgstr "Lịch sử" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/WalletButton.tsx:22 +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:16 +#: widget/embedded/src/constants/messages.ts:5 +msgid "Connect Wallet" +msgstr "Kết nối ví" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HistoryGroupedList/HistoryGroupedList.tsx:118 +#: widget/embedded/src/utils/date.ts:18 +#: widget/embedded/src/utils/time.ts:22 +msgid "Today" +msgstr "Hôm nay" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/LoadingSwapDetails/LoadingSwapDetails.tsx:20 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:424 +msgid "Swaps steps" +msgstr "Các bước hoán đổi" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/NoResult/NoResult.helpers.ts:25 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:191 +msgid "Retry" +msgstr "Thử lại" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:149 +msgid "Slippage Error" +msgstr "Lỗi trượt" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:150 +msgid "Slippage Warning" +msgstr "Cảnh báo trượt" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:153 +msgid "Bridge Limit Error" +msgstr "Lỗi giới hạn cầu" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:240 +msgid "Yours: {amount} {symbol}" +msgstr "Của bạn: {amount} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:261 +msgid "Minimum required slippage: {minRequiredSlippage}" +msgstr "Độ trượt tối thiểu cần thiết: {minRequiredSlippage}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:282 +msgid "Yours: {userSlippage}" +msgstr "Của bạn: {userSlippage}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:395 +msgid "See All Routes" +msgstr "Xem tất cả các tuyến đường" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:81 +msgid "View more info" +msgstr "Xem thêm thông tin" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:91 +msgid "Gas & Fee Explanation" +msgstr "Giải thích về Gas & Phí" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:107 +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:103 +msgid "Details" +msgstr "Chi tiết" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:146 +msgid "Total Payable Fee" +msgstr "Tổng phí phải trả" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:166 +msgid "Hide non-payable fees" +msgstr "Ẩn các khoản phí không phải trả" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:167 +msgid "Show non-payable fees" +msgstr "Hiển thị các khoản phí không phải trả" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:177 +msgid "Description" +msgstr "Sự miêu tả" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:181 +msgid "The following fees are considered in the transaction output and\n" +" you won’t need to pay extra gas for them." +msgstr "Các loại phí sau đây được tính vào kết quả giao dịch và\n" +" bạn sẽ không cần phải trả thêm phí gas cho chúng." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteSummary.tsx:25 +msgid "Swap input" +msgstr "Hoán đổi đầu vào" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteSummary.tsx:44 +msgid "Estimated output" +msgstr "Sản lượng ước tính" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteTrigger.tsx:65 +msgid "Via:" +msgstr "Thông qua:" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteTrigger.tsx:150 +msgid "Chains:" +msgstr "Chuỗi:" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/Quotes.tsx:77 +msgid "Sort by" +msgstr "Sắp xếp theo" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:17 +msgid "Smart Routing" +msgstr "Lộ trình thông minh" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:21 +msgid "Lowest Fee" +msgstr "Phí thấp nhất" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:25 +msgid "Fastest Transfer" +msgstr "Chuyển khoản nhanh nhất" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:29 +msgid "Maximum Return" +msgstr "Lợi nhuận tối đa" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:33 +msgid "Maximum Output" +msgstr "Đầu ra tối đa" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:43 +msgid "Swapping" +msgstr "Trao đổi" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:51 +msgid "Gas cost" +msgstr "Chi phí gas" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:59 +msgid "Receiving" +msgstr "Nhận được" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:67 +msgid "Price impact" +msgstr "Tác động giá" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:35 +msgid "You need to increase slippage to at least {minRequiredSlippage} for this route." +msgstr "Bạn cần tăng độ trượt lên ít nhất {minRequiredSlippage} cho tuyến đường này." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:59 +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:61 +msgid "We recommend you to increase slippage to at least {minRequiredSlippage} for this route." +msgstr "Chúng tôi khuyên bạn nên tăng độ trượt lên ít nhất là {minRequiredSlippage} cho tuyến đường này." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:68 +msgid "Caution, your slippage is high." +msgstr "Cẩn thận, độ trượt của bạn khá cao." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.tsx:78 +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.Warning.tsx:26 +msgid "Change" +msgstr "Thay đổi" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:42 +msgid "Change settings" +msgstr "Thay đổi cài đặt" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:52 +msgid "High slippage" +msgstr "Độ trượt cao" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:53 +msgid "Low slippage" +msgstr "Độ trượt thấp" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:57 +msgid " Caution, your slippage is high (={userSlippage}). Your trade may be front run." +msgstr " Thận trọng, độ trượt giá của bạn cao (={userSlippage}). Giao dịch của bạn có thể bị chạy trước." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:78 +msgid "Confirm anyway" +msgstr "Xác nhận dù sao" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:22 +msgid "Something went wrong" +msgstr "Có gì đó không ổn" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:24 +msgid "Something went wrong. Please refresh the app." +msgstr "Có lỗi xảy ra. Vui lòng làm mới ứng dụng." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/Slippage.tsx:38 +msgid "Slippage tolerance per swap" +msgstr "Độ trượt cho mỗi lần hoán đổi" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/Slippage.tsx:91 +msgid "Custom" +msgstr "Phong tục" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:11 +msgid "Your transaction will be reverted if the price changes unfavorably by more than this percentage." +msgstr "Giao dịch của bạn sẽ bị hủy nếu giá thay đổi bất lợi hơn mức phần trăm này." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:16 +#: widget/embedded/src/containers/Settings/Lists.tsx:245 +msgid "Warning" +msgstr "Cảnh báo" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:17 +msgid "This setting is applied to each step (e.g. 1Inch, Thorchain, etc.), meaning only that specific step will be reverted, not the entire route." +msgstr "Cài đặt này được áp dụng cho từng bước (ví dụ: 1Inch, Thorchain, v.v.), nghĩa là chỉ bước cụ thể đó sẽ được hoàn nguyên chứ không phải toàn bộ lộ trình." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:25 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:269 +msgid "Swap Details" +msgstr "Chi tiết trao đổi" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:33 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:312 +msgid "Request ID" +msgstr "Yêu cầu ID" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:64 +msgid "Not found" +msgstr "Không tìm thấy" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:65 +msgid "Swap with request ID = {requestId} not found." +msgstr "Không tìm thấy hoán đổi với ID yêu cầu = {requestId} ." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:219 +msgid "You have received {amount} {token} in {conciseAddress} wallet on {chain} chain." +msgstr "Bạn đã nhận được {amount} {token} trong ví {conciseAddress} trên chuỗi {chain} ." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:242 +msgid "Transaction was not sent." +msgstr "Giao dịch không được gửi." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:244 +msgid "{amount} {symbol} on {blockchain} remains in your wallet." +msgstr "{amount} {symbol} trên {blockchain} vẫn còn trong ví của bạn." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:281 +msgid "Delete" +msgstr "Xóa bỏ" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:304 +msgid "Try again" +msgstr "Thử lại" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:322 +msgid "Copied To Clipboard" +msgstr "Đã sao chép vào bảng tạm" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:323 +msgid "Copy Request ID" +msgstr "Sao chép ID yêu cầu" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:346 +msgid "View on Rango Explorer" +msgstr "Xem trên Rango Explorer" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:355 +msgid "Finished at" +msgstr "Hoàn thành tại" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:355 +msgid "Created at" +msgstr "Được tạo ra tại" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.tsx:50 +msgid "View transaction" +msgstr "Xem giao dịch" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.Warning.tsx:49 +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:31 +msgid "Connect" +msgstr "Kết nối" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:43 +msgid "Swap Successful" +msgstr "Hoán đổi thành công" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:71 +msgid "Transaction Failed" +msgstr "Giao dịch không thành công" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:87 +msgid "Done" +msgstr "Xong" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:100 +msgid "Diagnosis" +msgstr "Chẩn đoán" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:112 +msgid "See Details" +msgstr "Xem chi tiết" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:13 +msgid "Cancel Swap" +msgstr "Hủy bỏ hoán đổi" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:14 +msgid "Are you sure you want to cancel this swap?" +msgstr "Bạn có chắc chắn muốn hủy giao dịch hoán đổi này không?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:23 +msgid "Yes, Cancel it" +msgstr "Có, Hủy nó" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:32 +#: widget/embedded/src/pages/CustomTokensPage.tsx:181 +msgid "No, Continue" +msgstr "Không, Tiếp tục" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:13 +msgid "Delete Transaction" +msgstr "Xóa giao dịch" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:14 +msgid "Are you sure you want to delete this swap?" +msgstr "Bạn có chắc chắn muốn xóa hoán đổi này không?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:23 +#: widget/embedded/src/pages/CustomTokensPage.tsx:171 +msgid "Yes, Delete it" +msgstr "Có, xóa nó đi" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:33 +#: widget/embedded/src/pages/HistoryPage.tsx:253 +msgid "No, Cancel" +msgstr "Không, Hủy bỏ" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:12 +msgid "Change Network" +msgstr "Thay đổi mạng" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:20 +msgid "Network Changed" +msgstr "Mạng đã thay đổi" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/TokenList/TokenList.tsx:271 +#: widget/ui/src/containers/SwapInput/TokenSection.tsx:54 +msgid "Select Token" +msgstr "Chọn Mã thông báo" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:27 +msgid "Wallet Connected" +msgstr "Ví đã kết nối" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:28 +msgid "Your wallet is connected, you can use it to swap." +msgstr "Ví của bạn đã được kết nối, bạn có thể sử dụng nó để hoán đổi." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:39 +msgid "Failed to Connect" +msgstr "Không thể kết nối" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:41 +msgid "Your wallet is not connected. Please try again." +msgstr "Ví của bạn chưa được kết nối. Vui lòng thử lại." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:50 +msgid "Connecting to your wallet" +msgstr "Kết nối với ví của bạn" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:51 +msgid "Click connect in your wallet popup." +msgstr "Nhấp vào kết nối trong cửa sổ bật lên của ví." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:99 +msgid "Select Derivation Path" +msgstr "Chọn Đường dẫn dẫn xuất" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:100 +msgid "In order to connect to {type}, you must first select a Derivation Path" +msgstr "Để kết nối với {type}, trước tiên bạn phải chọn Đường dẫn phái sinh" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:118 +msgid "Choose Derivation Path Template" +msgstr "Chọn mẫu đường dẫn dẫn xuất" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:133 +msgid "Enter Path" +msgstr "Nhập Đường dẫn" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:134 +msgid "Enter Index" +msgstr "Nhập chỉ mục" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:15 +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:18 +msgid "Add {blockchainDisplayName} Chain" +msgstr "Thêm {blockchainDisplayName} Chuỗi" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:20 +msgid "Would you like to add the {blockchainDisplayName} experimental chain to your wallet?" +msgstr "Bạn có muốn thêm chuỗi thử nghiệm {blockchainDisplayName} vào ví của mình không?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:22 +msgid "Please approve the experimental chain pop-up in your wallet." +msgstr "Vui lòng chấp thuận cửa sổ bật lên chuỗi thử nghiệm trong ví của bạn." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:30 +msgid "{blockchainDisplayName} Chain Added" +msgstr "{blockchainDisplayName} Đã thêm chuỗi" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:34 +msgid "The {blockchainDisplayName} chain has been successfully added to your wallet." +msgstr "Chuỗi {blockchainDisplayName} đã được thêm thành công vào ví của bạn." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:42 +msgid "Request Rejected" +msgstr "Yêu cầu bị từ chối" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:43 +msgid "You've rejected adding {blockchainDisplayName} chain to your wallet." +msgstr "Bạn đã từ chối thêm chuỗi {blockchainDisplayName} vào ví của mình." + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:70 +msgid "Select chain types" +msgstr "Chọn loại chuỗi" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:71 +msgid "This wallet supports multiple chains. Select which chain you'd like to connect to." +msgstr "Ví này hỗ trợ nhiều chuỗi. Chọn chuỗi bạn muốn kết nối." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:9 +msgid "Failed Network, Please retry your swap." +msgstr "Mạng bị lỗi, vui lòng thử lại việc hoán đổi." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:11 +msgid "Please reset your liquidity sources." +msgstr "Vui lòng thiết lập lại nguồn thanh khoản của bạn." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:12 +msgid "You have limited the liquidity sources and this might result in Rango finding no routes. Please consider resetting your liquidity sources." +msgstr "Bạn đã giới hạn các nguồn thanh khoản và điều này có thể khiến Rango không tìm thấy đường đi. Vui lòng cân nhắc thiết lập lại các nguồn thanh khoản của bạn." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:17 +msgid "No Routes Found." +msgstr "Không tìm thấy tuyến đường nào." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:18 +msgid "Reasons why Rango couldn't find a route: low liquidity on token, very low input amount or no routes available for the selected input/output token combination." +msgstr "Lý do Rango không tìm được tuyến đường: tính thanh khoản của token thấp, lượng đầu vào rất thấp hoặc không có tuyến đường nào khả dụng cho tổ hợp token đầu vào/đầu ra đã chọn." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:23 +msgid "Bridge Limit Error: Please increase your amount." +msgstr "Lỗi giới hạn cầu: Vui lòng tăng số tiền của bạn." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:26 +msgid "Bridge Limit Error: Please decrease your amount." +msgstr "Lỗi giới hạn cầu: Vui lòng giảm số tiền của bạn." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:31 +msgid "High Price Impact" +msgstr "Tác động giá cao" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:32 +msgid "Price impact is too high!" +msgstr "Tác động đến giá quá cao!" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:33 +msgid "The price impact is significantly higher than the allowed amount." +msgstr "Tác động đến giá cả cao hơn đáng kể so với mức cho phép." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:36 +msgid "Confirm high price impact" +msgstr "Xác nhận tác động giá cao" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:39 +msgid "Route updated and price impact is too high, try again later!" +msgstr "Tuyến đường đã được cập nhật và giá cả bị ảnh hưởng quá cao, hãy thử lại sau!" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:44 +msgid "USD Price Unknown" +msgstr "Giá USD Không rõ" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:45 +msgid "USD Price Unknown, Cannot calculate Price Impact." +msgstr "Giá USD không xác định, không thể tính được tác động giá." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:46 +msgid "USD Price Unknown, Cannot calculate Price Impact. The price impact may be higher than usual. Are you sure to continue the Swap?" +msgstr "Giá USD không xác định, Không thể tính tác động giá. Tác động giá có thể cao hơn bình thường. Bạn có chắc chắn muốn tiếp tục hoán đổi không?" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:49 +msgid "Confirm USD Price Unknown" +msgstr "Xác nhận giá USD Không rõ" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:6 +#: widget/embedded/src/pages/Home.tsx:163 +msgid "Swap" +msgstr "Tráo đổi" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:7 +msgid "Swap anyway" +msgstr "Dù sao thì cũng đổi" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:8 +msgid "The route goes through Ethereum. Continue?" +msgstr "Tuyến đường đi qua Ethereum. Tiếp tục?" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:10 +msgid "Route has been updated." +msgstr "Tuyến đường đã được cập nhật." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:12 +msgid "Output amount changed to {newOutputAmount} ({percentageChange}% change)." +msgstr "Lượng đầu ra đã thay đổi thành {newOutputAmount} ({percentageChange}% thay đổi)." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:20 +msgid "Route swappers has been updated." +msgstr "Công cụ hoán đổi tuyến đường đã được cập nhật." + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:22 +msgid "Route internal coins has been updated." +msgstr "Tuyến tiền nội bộ đã được cập nhật." + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/ExpandedQuotes/ExpandedQuotes.tsx:53 +#: widget/embedded/src/pages/Routes.tsx:48 +msgid "Routes" +msgstr "Tuyến đường" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Inputs/Inputs.tsx:76 +msgid "From" +msgstr "Từ" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Inputs/Inputs.tsx:118 +msgid "To" +msgstr "ĐẾN" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:49 +msgid "Light" +msgstr "Ánh sáng" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:58 +msgid "Dark" +msgstr "Tối tăm" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:67 +msgid "Auto" +msgstr "Tự động" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:140 +msgid "Loading failed" +msgstr "Tải không thành công" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:156 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:41 +msgid "Bridges" +msgstr "Cầu" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:174 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:41 +msgid "Exchanges" +msgstr "Trao đổi" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:195 +#: widget/embedded/src/pages/CustomTokensPage.tsx:90 +msgid "Custom Tokens" +msgstr "Mã thông báo tùy chỉnh" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:214 +#: widget/embedded/src/pages/LanguagePage.tsx:43 +msgid "Language" +msgstr "Ngôn ngữ" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:235 +msgid "Infinite approval" +msgstr "Sự chấp thuận vô hạn" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:246 +msgid "Enabling the 'Infinite approval' mode grants unrestricted access to underlying smart contracts, allowing them to utilize the approved token amount without limitations." +msgstr "Bật chế độ 'Phê duyệt vô hạn' sẽ cấp quyền truy cập không giới hạn vào các hợp đồng thông minh cơ bản, cho phép chúng sử dụng số lượng mã thông báo đã được phê duyệt mà không có giới hạn." + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:266 +msgid "Theme" +msgstr "Chủ đề" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:39 +msgid "Duplicate Token" +msgstr "Mã thông báo trùng lặp" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:40 +msgid "The address you entered is duplicate, please enter a new address." +msgstr "Địa chỉ bạn nhập bị trùng lặp, vui lòng nhập địa chỉ mới." + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:46 +msgid "Token Already Exists" +msgstr "Mã thông báo đã tồn tại" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:47 +msgid "There's no need to add this token again because it already exists and is supported by us." +msgstr "Không cần phải thêm mã thông báo này nữa vì nó đã tồn tại và được chúng tôi hỗ trợ." + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:53 +msgid "Token Not Found" +msgstr "Không tìm thấy mã thông báo" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:54 +msgid "Sorry, no token was found on {blockchain} chain with the provided address. please make sure you have entered the right token address." +msgstr "Xin lỗi, không tìm thấy mã thông báo nào trên chuỗi {blockchain} có địa chỉ được cung cấp. Vui lòng đảm bảo rằng bạn đã nhập đúng địa chỉ mã thông báo." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:78 +msgid "Network Error" +msgstr "Lỗi mạng" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:109 +#: widget/embedded/src/pages/CustomTokensPage.tsx:149 +msgid "Add Custom Token" +msgstr "Thêm Mã thông báo tùy chỉnh" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:127 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:128 +msgid "Select chain" +msgstr "Chọn chuỗi" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:132 +msgid "Enter Address" +msgstr "Nhập Địa Chỉ" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:139 +msgid "Enter token address" +msgstr "Nhập địa chỉ mã thông báo" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:176 +msgid "Failed Network, Please retry." +msgstr "Mạng bị lỗi, vui lòng thử lại." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:192 +msgid "Add another custom token" +msgstr "Thêm một mã thông báo tùy chỉnh khác" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:236 +msgid "Confirm Swap" +msgstr "Xác nhận hoán đổi" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:254 +msgid "Start Swap" +msgstr "Bắt đầu hoán đổi" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:282 +msgid "You get" +msgstr "Bạn nhận được" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:102 +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:90 +msgid "Search Token" +msgstr "Tìm kiếm Mã thông báo" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:134 +msgid "No custom tokens" +msgstr "Không có mã thông báo tùy chỉnh" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:135 +msgid "press the button to add your custom token" +msgstr "nhấn nút để thêm mã thông báo tùy chỉnh của bạn" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:158 +msgid "Delete Custom Token" +msgstr "Xóa Mã thông báo tùy chỉnh" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:160 +msgid "Are you sure you want to Delete this Token?" +msgstr "Bạn có chắc chắn muốn xóa mã thông báo này không?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:59 +msgid "Complete" +msgstr "Hoàn thành" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:63 +msgid "Running" +msgstr "Đang chạy" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:65 +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:8 +msgid "Failed" +msgstr "Thất bại" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:149 +msgid "Clear" +msgstr "Thông thoáng" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:161 +msgid "Search Transaction" +msgstr "Tìm kiếm giao dịch" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:187 +msgid "No transactions" +msgstr "Không có giao dịch" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:194 +msgid "Your transaction history is stored locally and will appear here after you start a swap" +msgstr "Lịch sử giao dịch của bạn được lưu trữ cục bộ và sẽ xuất hiện ở đây sau khi bạn bắt đầu hoán đổi" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:218 +msgid "Clear Transaction History" +msgstr "Xóa Lịch sử giao dịch" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:222 +msgid "Proceeding will remove all successful and failed transactions from the widget. Do you want to continue?" +msgstr "Tiến hành sẽ xóa tất cả các giao dịch thành công và thất bại khỏi tiện ích. Bạn có muốn tiếp tục không?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:229 +msgid "Note: This does not erase your transaction history on the chain; it only removes them here." +msgstr "Lưu ý: Thao tác này không xóa lịch sử giao dịch của bạn trên chuỗi; nó chỉ xóa chúng tại đây." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:243 +msgid "Yes, Clear the history" +msgstr "Có, Xóa lịch sử" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LanguagePage.tsx:56 +msgid "language" +msgstr "ngôn ngữ" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:121 +msgid "Deselect all" +msgstr "Bỏ chọn tất cả" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:121 +msgid "Select all" +msgstr "Chọn tất cả" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:133 +msgid "Search {sourceType}" +msgstr "Tìm kiếm {sourceType}" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectBlockchainPage.tsx:60 +msgid "Search Chain" +msgstr "Chuỗi tìm kiếm" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:67 +msgid "Source" +msgstr "Nguồn" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:68 +msgid "Destination" +msgstr "Điểm đến" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:74 +msgid "Swap {type}" +msgstr "Hoán đổi {type}" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SettingsPage.tsx:45 +msgid "Currently, you're in campaign mode with restrictions on liquidity sources. Would you like to switch out of this mode and make use of all available liquidity sources?" +msgstr "Hiện tại, bạn đang ở chế độ chiến dịch với các hạn chế về nguồn thanh khoản. Bạn có muốn thoát khỏi chế độ này và sử dụng tất cả các nguồn thanh khoản khả dụng không?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SwapDetailsPage.tsx:27 +msgid "The request ID is necessary to display the swap details." +msgstr "ID yêu cầu là cần thiết để hiển thị thông tin chi tiết về giao dịch hoán đổi." + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/WalletsPage.tsx:67 +#: widget/ui/src/containers/ConnectWalletsModal/ConnectWalletsModal.tsx:15 +msgid "Connect Wallets" +msgstr "Kết nối ví" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/WalletsPage.tsx:82 +msgid "Choose a wallet to connect." +msgstr "Chọn ví để kết nối." + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:25 +msgid "This week" +msgstr "Tuần này" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:32 +msgid "This month" +msgstr "Tháng này" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:39 +msgid "This year" +msgstr "Năm nay" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:129 +msgid "Required: >= {min} {symbol}" +msgstr "Bắt buộc: >= {min} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:142 +msgid "Required: > {min} {symbol}" +msgstr "Bắt buộc: > {min} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:157 +msgid "Required: <= {max} {symbol}" +msgstr "Bắt buộc: <= {max} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:170 +msgid "Required: < {max} {symbol}" +msgstr "Bắt buộc: < {max} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:601 +msgid " for network fee" +msgstr " cho phí mạng" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:604 +msgid " for swap" +msgstr " để trao đổi" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:607 +msgid " for input and network fee" +msgstr " cho phí đầu vào và phí mạng" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:609 +msgid "Needs ≈ {requiredAmount} {symbol}{reason}, but you have {currentAmount} {symbol} in your {blockchain} wallet." +msgstr "Cần ≈ {requiredAmount} {symbol}{reason}, nhưng bạn có {currentAmount} {symbol} trong ví {blockchain} của mình." + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:669 +msgid "Waiting for connecting wallet" +msgstr "Đang chờ kết nối ví" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:673 +msgid "Waiting for other running tasks to be finished" +msgstr "Đang chờ các tác vụ đang chạy khác hoàn tất" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:676 +msgid "Waiting for changing wallet network" +msgstr "Đang chờ thay đổi mạng ví" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:6 +msgid "Sunday" +msgstr "Chủ nhật" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:7 +msgid "Monday" +msgstr "Thứ hai" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:8 +msgid "Tuesday" +msgstr "Thứ ba" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:9 +msgid "Wednesday" +msgstr "Thứ Tư" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:10 +msgid "Thursday" +msgstr "Thứ năm" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:11 +msgid "Friday" +msgstr "Thứ sáu" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:12 +msgid "Saturday" +msgstr "Thứ bảy" + +#. js-lingui-explicit-id +#: widget/ui/src/components/BottomLogo/BottomLogo.tsx:14 +msgid "Powered By" +msgstr "Được cung cấp bởi" + +#. js-lingui-explicit-id +#: widget/ui/src/components/FullExpandedQuote/FullExpandedQuote.Tooltip.tsx:37 +msgid "Aggregated Transaction" +msgstr "Giao dịch tổng hợp" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SelectableCategoryList/SelectableCategoryList.tsx:63 +msgid "{blockchainCategory}" +msgstr "{blockchainCategory}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/StepDetails/StepDetails.tsx:75 +#: widget/ui/src/components/StepDetails/StepDetails.tsx:102 +msgid "Swap on {fromChain} via {swapper}" +msgstr "Đổi trên {fromChain} qua {swapper}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/StepDetails/StepDetails.tsx:109 +msgid "Bridge to {toChain} via {swapper}" +msgstr "Cầu nối đến {toChain} qua {swapper}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:10 +msgid "Completed" +msgstr "Hoàn thành" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:12 +msgid "In progress" +msgstr "Đang tiến hành" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapToken.tsx:122 +msgid "Waiting for bridge transaction" +msgstr "Đang chờ giao dịch cầu nối" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:12 +msgid "Connected" +msgstr "Đã kết nối" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:13 +msgid "Disconnect" +msgstr "Ngắt kết nối" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:18 +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:19 +msgid "Install" +msgstr "Cài đặt" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:24 +msgid "Connecting ..." +msgstr "Đang kết nối ..." + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:25 +msgid "Connecting" +msgstr "Kết nối" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:30 +msgid "Disconnected" +msgstr "Đã ngắt kết nối" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:34 +msgid "you need to pass a correct state to Wallet." +msgstr "bạn cần phải chuyển trạng thái chính xác cho Wallet." + +#. js-lingui-explicit-id +#: widget/ui/src/containers/Notifications/NotificationNotFound.tsx:15 +msgid "There are no notifications." +msgstr "Không có thông báo nào." + +#. js-lingui-explicit-id +#: widget/ui/src/containers/Notifications/Notifications.tsx:39 +msgid "Clear all" +msgstr "Xóa tất cả" + +#. js-lingui-explicit-id +#: widget/ui/src/containers/SwapInput/SwapInput.tsx:65 +msgid "Balance" +msgstr "Sự cân bằng" + +#. js-lingui-explicit-id +#: widget/ui/src/containers/SwapInput/SwapInput.tsx:73 +msgid "Max" +msgstr "Tối đa" + diff --git a/translations/zh-CN.po b/translations/zh-CN.po new file mode 100644 index 0000000000..f9cb690b58 --- /dev/null +++ b/translations/zh-CN.po @@ -0,0 +1,1339 @@ +msgid "" +msgstr "" +"POT-Creation-Date: 2023-11-06 17:24+0330\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: @lingui/cli\n" +"Language: zh\n" +"Project-Id-Version: rango\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2024-11-27 15:57\n" +"Last-Translator: \n" +"Language-Team: Chinese Simplified\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Crowdin-Project: rango\n" +"X-Crowdin-Project-ID: 622238\n" +"X-Crowdin-Language: zh-CN\n" +"X-Crowdin-File: en.po\n" +"X-Crowdin-File-ID: 30\n" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SameTokensWarning/SameTokensWarning.tsx:21 +msgid "No Routes Found" +msgstr "未找到路线" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SameTokensWarning/SameTokensWarning.tsx:25 +msgid "You cannot use the same token for From and To." +msgstr "您不能对“发件人”和“收件人”使用相同的令牌。" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:41 +#: widget/embedded/src/components/TokenList/TokenList.tsx:286 +#: widget/embedded/src/pages/HistoryPage.tsx:186 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:143 +msgid "No results found" +msgstr "未找到结果" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:42 +#: widget/embedded/src/components/TokenList/TokenList.tsx:287 +#: widget/embedded/src/pages/HistoryPage.tsx:193 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:144 +msgid "Try using different keywords" +msgstr "尝试使用不同的关键字" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:72 +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:46 +#: widget/embedded/src/pages/SelectBlockchainPage.tsx:42 +#: widget/ui/src/containers/SwapInput/TokenSection.tsx:61 +msgid "Select Chain" +msgstr "选择链条" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:66 +msgid "All" +msgstr "所有的" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:100 +msgid "More +{count}" +msgstr "更多 +{count}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabAlert/ActivateTabAlert.tsx:17 +msgid "Activate this tab" +msgstr "激活此标签" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabAlert/ActivateTabAlert.tsx:22 +msgid "Another tab is open and handles transactions." +msgstr "另一个标签是打开和处理交易。" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:20 +msgid "Activate current tab" +msgstr "激活当前标签" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:22 +msgid "Currently, some transactions are running and being handled by other browser tab. If you activate this tab, all transactions that are already in the transaction sign step will expire." +msgstr "目前,有些交易正在运行,正在由其他浏览器选项卡处理。 如果您激活此标签,所有已经在交易签名步骤中的交易都将过期。" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:33 +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:349 +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:152 +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:33 +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:116 +msgid "Confirm" +msgstr "确认" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:365 +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:447 +msgid "Your {blockchainName} wallets" +msgstr "您的 {blockchainName} 钱包" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:384 +msgid "Insufficient account balance" +msgstr "账户余额不足" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:394 +msgid "Proceed anyway" +msgstr "仍然继续" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:456 +msgid "You need to connect a {blockchainName} wallet." +msgstr "您需要连接一个 {blockchainName} 钱包。" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/WalletList.tsx:143 +msgid "Add {chain} chain" +msgstr "添加 {chain} 链" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/WalletList.tsx:244 +msgid "Show more wallets" +msgstr "显示更多钱包" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:113 +msgid "Send to a different address" +msgstr "发送到另一个地址" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:129 +msgid "Enter {blockchainName} address" +msgstr "输入 {blockchainName} 地址" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:147 +msgid "Address {destination} doesn't match the blockchain address pattern." +msgstr "地址 {destination} 与区块链地址模式不匹配。" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:59 +msgid "via" +msgstr "通过" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:74 +msgid "This token doesn't appear on the active token list(s). Make sure this is the token that you want to trade." +msgstr "此令牌不会出现在活动令牌列表中。请确保这是您想要交易的令牌。" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:89 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:164 +msgid "Import" +msgstr "导入" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/FilterSelector/FilterSelectorContent.tsx:26 +msgid "Status" +msgstr "状态" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/FilterSelector/FilterSelectorContent.tsx:33 +#: widget/embedded/src/components/NoResult/NoResult.helpers.ts:37 +#: widget/embedded/src/pages/SettingsPage.tsx:55 +msgid "Reset" +msgstr "Reset" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/CancelButton.tsx:18 +msgid "Cancel" +msgstr "取消" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:46 +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:34 +msgid "Refresh" +msgstr "刷新" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:63 +#: widget/ui/src/containers/Notifications/Notifications.tsx:35 +msgid "Notifications" +msgstr "通知" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:79 +#: widget/embedded/src/pages/SettingsPage.tsx:38 +msgid "Settings" +msgstr "设置" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:93 +#: widget/embedded/src/pages/HistoryPage.tsx:139 +msgid "History" +msgstr "历史记录" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/WalletButton.tsx:22 +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:16 +#: widget/embedded/src/constants/messages.ts:5 +msgid "Connect Wallet" +msgstr "连接钱包" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HistoryGroupedList/HistoryGroupedList.tsx:118 +#: widget/embedded/src/utils/date.ts:18 +#: widget/embedded/src/utils/time.ts:22 +msgid "Today" +msgstr "今日:" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/LoadingSwapDetails/LoadingSwapDetails.tsx:20 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:424 +msgid "Swaps steps" +msgstr "互换步骤" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/NoResult/NoResult.helpers.ts:25 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:191 +msgid "Retry" +msgstr "重试" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:149 +msgid "Slippage Error" +msgstr "翻转错误" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:150 +msgid "Slippage Warning" +msgstr "翻转警告" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:153 +msgid "Bridge Limit Error" +msgstr "桥接限制错误" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:240 +msgid "Yours: {amount} {symbol}" +msgstr "你的: {amount} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:261 +msgid "Minimum required slippage: {minRequiredSlippage}" +msgstr "最低要求滑点: {minRequiredSlippage}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:282 +msgid "Yours: {userSlippage}" +msgstr "你的: {userSlippage}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:395 +msgid "See All Routes" +msgstr "查看所有路由" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:81 +msgid "View more info" +msgstr "查看更多信息" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:91 +msgid "Gas & Fee Explanation" +msgstr "气体和费用解释" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:107 +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:103 +msgid "Details" +msgstr "详细信息" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:146 +msgid "Total Payable Fee" +msgstr "应支付费用总额" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:166 +msgid "Hide non-payable fees" +msgstr "隐藏非支付费用" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:167 +msgid "Show non-payable fees" +msgstr "显示非应支付费用" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:177 +msgid "Description" +msgstr "描述" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:181 +msgid "The following fees are considered in the transaction output and\n" +" you won’t need to pay extra gas for them." +msgstr "在交易输出中考虑到以下费用和\n" +" 您将不需要支付额外的气体。" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteSummary.tsx:25 +msgid "Swap input" +msgstr "Swap input" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteSummary.tsx:44 +msgid "Estimated output" +msgstr "估计输出" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteTrigger.tsx:65 +msgid "Via:" +msgstr "Via:" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteTrigger.tsx:150 +msgid "Chains:" +msgstr "链:" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/Quotes.tsx:77 +msgid "Sort by" +msgstr "排序方式" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:17 +msgid "Smart Routing" +msgstr "智能路由" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:21 +msgid "Lowest Fee" +msgstr "最低费用" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:25 +msgid "Fastest Transfer" +msgstr "最快的传输" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:29 +msgid "Maximum Return" +msgstr "最大返回" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:33 +msgid "Maximum Output" +msgstr "最大输出" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:43 +msgid "Swapping" +msgstr "Swapping" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:51 +msgid "Gas cost" +msgstr "煤气成本" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:59 +msgid "Receiving" +msgstr "接收中" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:67 +msgid "Price impact" +msgstr "价格影响" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:35 +msgid "You need to increase slippage to at least {minRequiredSlippage} for this route." +msgstr "您需要将此路线的滑移量至少增加到 {minRequiredSlippage} 。" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:59 +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:61 +msgid "We recommend you to increase slippage to at least {minRequiredSlippage} for this route." +msgstr "我们建议您将此路线的滑移量至少增加到 {minRequiredSlippage} 。" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:68 +msgid "Caution, your slippage is high." +msgstr "注意力,您的幻灯片很高。" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.tsx:78 +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.Warning.tsx:26 +msgid "Change" +msgstr "更改" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:42 +msgid "Change settings" +msgstr "更改设置" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:52 +msgid "High slippage" +msgstr "高滑块" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:53 +msgid "Low slippage" +msgstr "低滑块" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:57 +msgid " Caution, your slippage is high (={userSlippage}). Your trade may be front run." +msgstr " 小心,您的滑点很高 (={userSlippage})。您的交易可能被抢先执行。" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:78 +msgid "Confirm anyway" +msgstr "仍然确认" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:22 +msgid "Something went wrong" +msgstr "出了错。" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:24 +msgid "Something went wrong. Please refresh the app." +msgstr "出错了。请刷新应用程序。" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/Slippage.tsx:38 +msgid "Slippage tolerance per swap" +msgstr "每次交换时翻页范围" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/Slippage.tsx:91 +msgid "Custom" +msgstr "自定义" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:11 +msgid "Your transaction will be reverted if the price changes unfavorably by more than this percentage." +msgstr "如果价格变化大于此百分比,您的交易将会恢复。" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:16 +#: widget/embedded/src/containers/Settings/Lists.tsx:245 +msgid "Warning" +msgstr "警告" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:17 +msgid "This setting is applied to each step (e.g. 1Inch, Thorchain, etc.), meaning only that specific step will be reverted, not the entire route." +msgstr "此设置适用于每一步(例如1Inch、Thorchain等),只表示特定步骤将被还原,而不是整个路径。" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:25 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:269 +msgid "Swap Details" +msgstr "交换详情" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:33 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:312 +msgid "Request ID" +msgstr "请求ID" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:64 +msgid "Not found" +msgstr "找不到" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:65 +msgid "Swap with request ID = {requestId} not found." +msgstr "未找到请求 ID = {requestId} 的交换。" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:219 +msgid "You have received {amount} {token} in {conciseAddress} wallet on {chain} chain." +msgstr "您已在 {chain} 链上的 {conciseAddress} 钱包中收到 {amount} {token} 。" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:242 +msgid "Transaction was not sent." +msgstr "交易未发送。" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:244 +msgid "{amount} {symbol} on {blockchain} remains in your wallet." +msgstr "{amount} {symbol} 和 {blockchain} 仍留在您的钱包中。" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:281 +msgid "Delete" +msgstr "删除" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:304 +msgid "Try again" +msgstr "再试一次" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:322 +msgid "Copied To Clipboard" +msgstr "复制到剪贴板" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:323 +msgid "Copy Request ID" +msgstr "复制请求ID" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:346 +msgid "View on Rango Explorer" +msgstr "在Rango浏览器上查看" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:355 +msgid "Finished at" +msgstr "完成于" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:355 +msgid "Created at" +msgstr "创建于" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.tsx:50 +msgid "View transaction" +msgstr "查看交易" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.Warning.tsx:49 +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:31 +msgid "Connect" +msgstr "连接" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:43 +msgid "Swap Successful" +msgstr "交换成功" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:71 +msgid "Transaction Failed" +msgstr "交易失败" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:87 +msgid "Done" +msgstr "完成" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:100 +msgid "Diagnosis" +msgstr "诊断信息" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:112 +msgid "See Details" +msgstr "查看详细信息" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:13 +msgid "Cancel Swap" +msgstr "取消切换" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:14 +msgid "Are you sure you want to cancel this swap?" +msgstr "您确定要取消此交换吗?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:23 +msgid "Yes, Cancel it" +msgstr "是,取消它" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:32 +#: widget/embedded/src/pages/CustomTokensPage.tsx:181 +msgid "No, Continue" +msgstr "否,继续" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:13 +msgid "Delete Transaction" +msgstr "删除交易" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:14 +msgid "Are you sure you want to delete this swap?" +msgstr "您确定要删除这个交换吗?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:23 +#: widget/embedded/src/pages/CustomTokensPage.tsx:171 +msgid "Yes, Delete it" +msgstr "是,删除它" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:33 +#: widget/embedded/src/pages/HistoryPage.tsx:253 +msgid "No, Cancel" +msgstr "否,取消" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:12 +msgid "Change Network" +msgstr "更改网络" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:20 +msgid "Network Changed" +msgstr "网络已更改" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/TokenList/TokenList.tsx:271 +#: widget/ui/src/containers/SwapInput/TokenSection.tsx:54 +msgid "Select Token" +msgstr "选择令牌" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:27 +msgid "Wallet Connected" +msgstr "钱包已连接" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:28 +msgid "Your wallet is connected, you can use it to swap." +msgstr "您的钱包已连接,您可以使用它交换。" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:39 +msgid "Failed to Connect" +msgstr "连接失败" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:41 +msgid "Your wallet is not connected. Please try again." +msgstr "您的钱包未连接。请重试。" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:50 +msgid "Connecting to your wallet" +msgstr "正在连接你的钱包" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:51 +msgid "Click connect in your wallet popup." +msgstr "点击在你的钱包弹出窗口中连接。" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:99 +msgid "Select Derivation Path" +msgstr "选择派生路径" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:100 +msgid "In order to connect to {type}, you must first select a Derivation Path" +msgstr "为了连接到 {type},你必须首先选择一个派生路径" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:118 +msgid "Choose Derivation Path Template" +msgstr "选择派生路径模板" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:133 +msgid "Enter Path" +msgstr "输入路径" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:134 +msgid "Enter Index" +msgstr "输入索引" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:15 +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:18 +msgid "Add {blockchainDisplayName} Chain" +msgstr "添加 {blockchainDisplayName} 链" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:20 +msgid "Would you like to add the {blockchainDisplayName} experimental chain to your wallet?" +msgstr "您想将 {blockchainDisplayName} 实验链添加到您的钱包吗?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:22 +msgid "Please approve the experimental chain pop-up in your wallet." +msgstr "请批准您钱包中的实验性链弹出窗口。" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:30 +msgid "{blockchainDisplayName} Chain Added" +msgstr "{blockchainDisplayName} 已添加链" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:34 +msgid "The {blockchainDisplayName} chain has been successfully added to your wallet." +msgstr "{blockchainDisplayName} 链已成功添加到您的钱包。" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:42 +msgid "Request Rejected" +msgstr "请求被拒绝" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:43 +msgid "You've rejected adding {blockchainDisplayName} chain to your wallet." +msgstr "您拒绝将 {blockchainDisplayName} 链添加到您的钱包。" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:70 +msgid "Select chain types" +msgstr "选择链类型" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:71 +msgid "This wallet supports multiple chains. Select which chain you'd like to connect to." +msgstr "这个钱包支持多个链。选择你想要连接的链。" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:9 +msgid "Failed Network, Please retry your swap." +msgstr "网络失败,请重试您的交换。" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:11 +msgid "Please reset your liquidity sources." +msgstr "请重置您的流动资金来源。" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:12 +msgid "You have limited the liquidity sources and this might result in Rango finding no routes. Please consider resetting your liquidity sources." +msgstr "您限制了流动资金来源,这可能导致Rango找不到路径。请考虑重置您的流动资金来源。" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:17 +msgid "No Routes Found." +msgstr "未找到路由。" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:18 +msgid "Reasons why Rango couldn't find a route: low liquidity on token, very low input amount or no routes available for the selected input/output token combination." +msgstr "为什么Rango找不到路由:代币流动性低,输入量很低,或者没有选择的输入/输出代币组合可用的路由。" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:23 +msgid "Bridge Limit Error: Please increase your amount." +msgstr "桥接限制错误:请增加您的金额。" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:26 +msgid "Bridge Limit Error: Please decrease your amount." +msgstr "桥接限制错误:请减少您的金额。" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:31 +msgid "High Price Impact" +msgstr "高价格影响" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:32 +msgid "Price impact is too high!" +msgstr "价格影响过高!" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:33 +msgid "The price impact is significantly higher than the allowed amount." +msgstr "价格影响大大高于允许的数额。" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:36 +msgid "Confirm high price impact" +msgstr "确认高价格影响" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:39 +msgid "Route updated and price impact is too high, try again later!" +msgstr "路由更新且价格影响太大,请稍后再试" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:44 +msgid "USD Price Unknown" +msgstr "美元价格未知" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:45 +msgid "USD Price Unknown, Cannot calculate Price Impact." +msgstr "美元价格未知,不能计算价格影响。" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:46 +msgid "USD Price Unknown, Cannot calculate Price Impact. The price impact may be higher than usual. Are you sure to continue the Swap?" +msgstr "美元价格未知,不能计算价格影响。价格影响可能高于通常。您确定要继续掉期吗?" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:49 +msgid "Confirm USD Price Unknown" +msgstr "确认美元价格未知" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:6 +#: widget/embedded/src/pages/Home.tsx:163 +msgid "Swap" +msgstr "切换" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:7 +msgid "Swap anyway" +msgstr "仍然切换" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:8 +msgid "The route goes through Ethereum. Continue?" +msgstr "航线穿过太太空了。继续吗?" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:10 +msgid "Route has been updated." +msgstr "路由已更新。" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:12 +msgid "Output amount changed to {newOutputAmount} ({percentageChange}% change)." +msgstr "输出量变为 {newOutputAmount} ({percentageChange}% 变化)。" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:20 +msgid "Route swappers has been updated." +msgstr "路由交换器已更新。" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:22 +msgid "Route internal coins has been updated." +msgstr "内部硬币已更新。" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/ExpandedQuotes/ExpandedQuotes.tsx:53 +#: widget/embedded/src/pages/Routes.tsx:48 +msgid "Routes" +msgstr "路由" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Inputs/Inputs.tsx:76 +msgid "From" +msgstr "来自" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Inputs/Inputs.tsx:118 +msgid "To" +msgstr "收件人" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:49 +msgid "Light" +msgstr "亮色的" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:58 +msgid "Dark" +msgstr "深色" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:67 +msgid "Auto" +msgstr "自动操作" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:140 +msgid "Loading failed" +msgstr "加载失败" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:156 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:41 +msgid "Bridges" +msgstr "桥接" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:174 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:41 +msgid "Exchanges" +msgstr "交易" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:195 +#: widget/embedded/src/pages/CustomTokensPage.tsx:90 +msgid "Custom Tokens" +msgstr "自定义令牌" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:214 +#: widget/embedded/src/pages/LanguagePage.tsx:43 +msgid "Language" +msgstr "语言" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:235 +msgid "Infinite approval" +msgstr "无限批准" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:246 +msgid "Enabling the 'Infinite approval' mode grants unrestricted access to underlying smart contracts, allowing them to utilize the approved token amount without limitations." +msgstr "启用“无限批准”模式允许无限制访问基本智能合同,允许他们不受限制地使用已批准的代币金额。" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:266 +msgid "Theme" +msgstr "主题" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:39 +msgid "Duplicate Token" +msgstr "Duplicate Token" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:40 +msgid "The address you entered is duplicate, please enter a new address." +msgstr "您输入的地址是重复的,请输入一个新地址。" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:46 +msgid "Token Already Exists" +msgstr "令牌已存在" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:47 +msgid "There's no need to add this token again because it already exists and is supported by us." +msgstr "无需再次添加此令牌,因为它已经存在并得到我们的支持。" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:53 +msgid "Token Not Found" +msgstr "未找到令牌" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:54 +msgid "Sorry, no token was found on {blockchain} chain with the provided address. please make sure you have entered the right token address." +msgstr "抱歉,在 {blockchain} 链上未找到具有所提供地址的代币。请确保您输入了正确的代币地址。" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:78 +msgid "Network Error" +msgstr "网络错误" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:109 +#: widget/embedded/src/pages/CustomTokensPage.tsx:149 +msgid "Add Custom Token" +msgstr "添加自定义令牌" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:127 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:128 +msgid "Select chain" +msgstr "选择链接" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:132 +msgid "Enter Address" +msgstr "输入地址" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:139 +msgid "Enter token address" +msgstr "输入令牌地址" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:176 +msgid "Failed Network, Please retry." +msgstr "网络失败,请重试。" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:192 +msgid "Add another custom token" +msgstr "添加另一个自定义令牌" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:236 +msgid "Confirm Swap" +msgstr "确认切换" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:254 +msgid "Start Swap" +msgstr "启动交换机" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:282 +msgid "You get" +msgstr "你得到了" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:102 +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:90 +msgid "Search Token" +msgstr "搜索令牌" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:134 +msgid "No custom tokens" +msgstr "没有自定义令牌" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:135 +msgid "press the button to add your custom token" +msgstr "点击按钮添加您的自定义令牌" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:158 +msgid "Delete Custom Token" +msgstr "删除自定义令牌" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:160 +msgid "Are you sure you want to Delete this Token?" +msgstr "您确定要删除此令牌吗?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:59 +msgid "Complete" +msgstr "Complete" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:63 +msgid "Running" +msgstr "正在运行" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:65 +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:8 +msgid "Failed" +msgstr "失败" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:149 +msgid "Clear" +msgstr "清空" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:161 +msgid "Search Transaction" +msgstr "搜索交易" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:187 +msgid "No transactions" +msgstr "无交易" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:194 +msgid "Your transaction history is stored locally and will appear here after you start a swap" +msgstr "您的交易历史已存储在本地,并将在您开始交换后显示在这里" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:218 +msgid "Clear Transaction History" +msgstr "清除交易记录" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:222 +msgid "Proceeding will remove all successful and failed transactions from the widget. Do you want to continue?" +msgstr "继续操作将从小部件删除所有成功和失败的交易。您想要继续吗?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:229 +msgid "Note: This does not erase your transaction history on the chain; it only removes them here." +msgstr "注意:这不会擦除您在链上的交易历史记录;它只会将它们移到此处。" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:243 +msgid "Yes, Clear the history" +msgstr "是的,清除历史记录" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LanguagePage.tsx:56 +msgid "language" +msgstr "语言" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:121 +msgid "Deselect all" +msgstr "取消全选" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:121 +msgid "Select all" +msgstr "选择所有" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:133 +msgid "Search {sourceType}" +msgstr "搜索 {sourceType}" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectBlockchainPage.tsx:60 +msgid "Search Chain" +msgstr "搜索链接" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:67 +msgid "Source" +msgstr "来源" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:68 +msgid "Destination" +msgstr "目标" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:74 +msgid "Swap {type}" +msgstr "交换 {type}" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SettingsPage.tsx:45 +msgid "Currently, you're in campaign mode with restrictions on liquidity sources. Would you like to switch out of this mode and make use of all available liquidity sources?" +msgstr "目前,您正处于活动模式,并且限制了流动资金来源。 您想要切换此模式并使用所有可用的流动资金来源吗?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SwapDetailsPage.tsx:27 +msgid "The request ID is necessary to display the swap details." +msgstr "请求ID是显示交换详细信息所必需的。" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/WalletsPage.tsx:67 +#: widget/ui/src/containers/ConnectWalletsModal/ConnectWalletsModal.tsx:15 +msgid "Connect Wallets" +msgstr "连接钱包" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/WalletsPage.tsx:82 +msgid "Choose a wallet to connect." +msgstr "选择要连接的钱包。" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:25 +msgid "This week" +msgstr "本周" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:32 +msgid "This month" +msgstr "本月" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:39 +msgid "This year" +msgstr "今年:" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:129 +msgid "Required: >= {min} {symbol}" +msgstr "必需:>= {min} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:142 +msgid "Required: > {min} {symbol}" +msgstr "必需:> {min} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:157 +msgid "Required: <= {max} {symbol}" +msgstr "必需:<= {max} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:170 +msgid "Required: < {max} {symbol}" +msgstr "必填:< {max} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:601 +msgid " for network fee" +msgstr " 网络费用" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:604 +msgid " for swap" +msgstr " 换行" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:607 +msgid " for input and network fee" +msgstr " 输入和网络费用" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:609 +msgid "Needs ≈ {requiredAmount} {symbol}{reason}, but you have {currentAmount} {symbol} in your {blockchain} wallet." +msgstr "需要 ≈ {requiredAmount} {symbol}{reason},但是你的 {blockchain} 钱包里有 {currentAmount} {symbol}。" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:669 +msgid "Waiting for connecting wallet" +msgstr "正在等待连接钱包" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:673 +msgid "Waiting for other running tasks to be finished" +msgstr "等待其他正在运行的任务完成" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:676 +msgid "Waiting for changing wallet network" +msgstr "正在等待更改钱包网络" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:6 +msgid "Sunday" +msgstr "周日" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:7 +msgid "Monday" +msgstr "周一" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:8 +msgid "Tuesday" +msgstr "星期二" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:9 +msgid "Wednesday" +msgstr "星期三" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:10 +msgid "Thursday" +msgstr "星期四" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:11 +msgid "Friday" +msgstr "星期五" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:12 +msgid "Saturday" +msgstr "周六" + +#. js-lingui-explicit-id +#: widget/ui/src/components/BottomLogo/BottomLogo.tsx:14 +msgid "Powered By" +msgstr "支持者" + +#. js-lingui-explicit-id +#: widget/ui/src/components/FullExpandedQuote/FullExpandedQuote.Tooltip.tsx:37 +msgid "Aggregated Transaction" +msgstr "合计交易" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SelectableCategoryList/SelectableCategoryList.tsx:63 +msgid "{blockchainCategory}" +msgstr "{blockchainCategory}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/StepDetails/StepDetails.tsx:75 +#: widget/ui/src/components/StepDetails/StepDetails.tsx:102 +msgid "Swap on {fromChain} via {swapper}" +msgstr "通过 {swapper}在 {fromChain} 上交换" + +#. js-lingui-explicit-id +#: widget/ui/src/components/StepDetails/StepDetails.tsx:109 +msgid "Bridge to {toChain} via {swapper}" +msgstr "通过 {swapper}桥接到 {toChain}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:10 +msgid "Completed" +msgstr "已完成" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:12 +msgid "In progress" +msgstr "进行中" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapToken.tsx:122 +msgid "Waiting for bridge transaction" +msgstr "等待桥接交易" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:12 +msgid "Connected" +msgstr "已连接" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:13 +msgid "Disconnect" +msgstr "断开连接" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:18 +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:19 +msgid "Install" +msgstr "安装" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:24 +msgid "Connecting ..." +msgstr "正在连接..." + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:25 +msgid "Connecting" +msgstr "正在连接" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:30 +msgid "Disconnected" +msgstr "断开连接" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:34 +msgid "you need to pass a correct state to Wallet." +msgstr "您需要将一个正确的状态传递给钱包。" + +#. js-lingui-explicit-id +#: widget/ui/src/containers/Notifications/NotificationNotFound.tsx:15 +msgid "There are no notifications." +msgstr "没有通知。" + +#. js-lingui-explicit-id +#: widget/ui/src/containers/Notifications/Notifications.tsx:39 +msgid "Clear all" +msgstr "全部清除" + +#. js-lingui-explicit-id +#: widget/ui/src/containers/SwapInput/SwapInput.tsx:65 +msgid "Balance" +msgstr "余额" + +#. js-lingui-explicit-id +#: widget/ui/src/containers/SwapInput/SwapInput.tsx:73 +msgid "Max" +msgstr "最大值" + diff --git a/translations/zh-TW.po b/translations/zh-TW.po new file mode 100644 index 0000000000..4f2800c407 --- /dev/null +++ b/translations/zh-TW.po @@ -0,0 +1,1338 @@ +msgid "" +msgstr "" +"POT-Creation-Date: 2023-11-06 17:24+0330\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: @lingui/cli\n" +"Language: zh\n" +"Project-Id-Version: rango\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2024-11-27 15:57\n" +"Last-Translator: \n" +"Language-Team: Chinese Traditional\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Crowdin-Project: rango\n" +"X-Crowdin-Project-ID: 622238\n" +"X-Crowdin-Language: zh-TW\n" +"X-Crowdin-File: en.po\n" +"X-Crowdin-File-ID: 30\n" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SameTokensWarning/SameTokensWarning.tsx:21 +msgid "No Routes Found" +msgstr "未找到路線" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SameTokensWarning/SameTokensWarning.tsx:25 +msgid "You cannot use the same token for From and To." +msgstr "您不能對「寄件者」和「收件者」使用相同的令牌。" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:41 +#: widget/embedded/src/components/TokenList/TokenList.tsx:286 +#: widget/embedded/src/pages/HistoryPage.tsx:186 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:143 +msgid "No results found" +msgstr "沒有找到結果" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:42 +#: widget/embedded/src/components/TokenList/TokenList.tsx:287 +#: widget/embedded/src/pages/HistoryPage.tsx:193 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:144 +msgid "Try using different keywords" +msgstr "嘗試使用不同的關鍵字" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:72 +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:46 +#: widget/embedded/src/pages/SelectBlockchainPage.tsx:42 +#: widget/ui/src/containers/SwapInput/TokenSection.tsx:61 +msgid "Select Chain" +msgstr "選擇鏈條" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:66 +msgid "All" +msgstr "全部" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:100 +msgid "More +{count}" +msgstr "更多 +{count}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabAlert/ActivateTabAlert.tsx:17 +msgid "Activate this tab" +msgstr "啟動此選項卡" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabAlert/ActivateTabAlert.tsx:22 +msgid "Another tab is open and handles transactions." +msgstr "另一個選項卡已開啟並處理交易。" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:20 +msgid "Activate current tab" +msgstr "啟動目前選項卡" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:22 +msgid "Currently, some transactions are running and being handled by other browser tab. If you activate this tab, all transactions that are already in the transaction sign step will expire." +msgstr "目前,某些事務正在運行並由其他瀏覽器選項卡處理。如果您啟動此選項卡,則已在交易簽署步驟中的所有交易都將過期。" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:33 +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:349 +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:152 +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:33 +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:116 +msgid "Confirm" +msgstr "確認" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:365 +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:447 +msgid "Your {blockchainName} wallets" +msgstr "你的 {blockchainName} 錢包" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:384 +msgid "Insufficient account balance" +msgstr "帳戶餘額不足" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:394 +msgid "Proceed anyway" +msgstr "無論如何都要繼續" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:456 +msgid "You need to connect a {blockchainName} wallet." +msgstr "" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/WalletList.tsx:143 +msgid "Add {chain} chain" +msgstr "加入 {chain} 鏈" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/WalletList.tsx:244 +msgid "Show more wallets" +msgstr "顯示更多錢包" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:113 +msgid "Send to a different address" +msgstr "發送到不同的地址" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:129 +msgid "Enter {blockchainName} address" +msgstr "輸入 {blockchainName} 地址" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:147 +msgid "Address {destination} doesn't match the blockchain address pattern." +msgstr "位址 {destination} 與區塊鏈位址模式不符。" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:59 +msgid "via" +msgstr "透過" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:74 +msgid "This token doesn't appear on the active token list(s). Make sure this is the token that you want to trade." +msgstr "此令牌不會出現在活動令牌清單中。確保這是您要交易的代幣。" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:89 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:164 +msgid "Import" +msgstr "進口" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/FilterSelector/FilterSelectorContent.tsx:26 +msgid "Status" +msgstr "地位" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/FilterSelector/FilterSelectorContent.tsx:33 +#: widget/embedded/src/components/NoResult/NoResult.helpers.ts:37 +#: widget/embedded/src/pages/SettingsPage.tsx:55 +msgid "Reset" +msgstr "重置" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/CancelButton.tsx:18 +msgid "Cancel" +msgstr "取消" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:46 +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:34 +msgid "Refresh" +msgstr "重新整理" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:63 +#: widget/ui/src/containers/Notifications/Notifications.tsx:35 +msgid "Notifications" +msgstr "通知" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:79 +#: widget/embedded/src/pages/SettingsPage.tsx:38 +msgid "Settings" +msgstr "設定" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:93 +#: widget/embedded/src/pages/HistoryPage.tsx:139 +msgid "History" +msgstr "歷史" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/WalletButton.tsx:22 +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:16 +#: widget/embedded/src/constants/messages.ts:5 +msgid "Connect Wallet" +msgstr "連接錢包" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HistoryGroupedList/HistoryGroupedList.tsx:118 +#: widget/embedded/src/utils/date.ts:18 +#: widget/embedded/src/utils/time.ts:22 +msgid "Today" +msgstr "今天" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/LoadingSwapDetails/LoadingSwapDetails.tsx:20 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:424 +msgid "Swaps steps" +msgstr "交換步驟" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/NoResult/NoResult.helpers.ts:25 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:191 +msgid "Retry" +msgstr "重試" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:149 +msgid "Slippage Error" +msgstr "滑點錯誤" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:150 +msgid "Slippage Warning" +msgstr "滑點警告" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:153 +msgid "Bridge Limit Error" +msgstr "橋限位誤差" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:240 +msgid "Yours: {amount} {symbol}" +msgstr "你的: {amount} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:261 +msgid "Minimum required slippage: {minRequiredSlippage}" +msgstr "所需最小滑點: {minRequiredSlippage}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:282 +msgid "Yours: {userSlippage}" +msgstr "你的: {userSlippage}" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:395 +msgid "See All Routes" +msgstr "查看所有路線" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:81 +msgid "View more info" +msgstr "查看更多信息" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:91 +msgid "Gas & Fee Explanation" +msgstr "Gas & 費用說明" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:107 +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:103 +msgid "Details" +msgstr "細節" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:146 +msgid "Total Payable Fee" +msgstr "應付費用總額" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:166 +msgid "Hide non-payable fees" +msgstr "隱藏不可支付的費用" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:167 +msgid "Show non-payable fees" +msgstr "顯示非應付費用" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:177 +msgid "Description" +msgstr "描述" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:181 +msgid "The following fees are considered in the transaction output and\n" +" you won’t need to pay extra gas for them." +msgstr "" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteSummary.tsx:25 +msgid "Swap input" +msgstr "交換輸入" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteSummary.tsx:44 +msgid "Estimated output" +msgstr "預計產量" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteTrigger.tsx:65 +msgid "Via:" +msgstr "通過:" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteTrigger.tsx:150 +msgid "Chains:" +msgstr "鏈條:" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/Quotes.tsx:77 +msgid "Sort by" +msgstr "排序方式" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:17 +msgid "Smart Routing" +msgstr "智慧路由" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:21 +msgid "Lowest Fee" +msgstr "最低費用" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:25 +msgid "Fastest Transfer" +msgstr "最快的傳輸" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:29 +msgid "Maximum Return" +msgstr "最大回報" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:33 +msgid "Maximum Output" +msgstr "最大輸出" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:43 +msgid "Swapping" +msgstr "交換" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:51 +msgid "Gas cost" +msgstr "天然氣成本" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:59 +msgid "Receiving" +msgstr "接收" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:67 +msgid "Price impact" +msgstr "價格影響" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:35 +msgid "You need to increase slippage to at least {minRequiredSlippage} for this route." +msgstr "您需要將該路線的滑點增加到至少 {minRequiredSlippage} 。" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:59 +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:61 +msgid "We recommend you to increase slippage to at least {minRequiredSlippage} for this route." +msgstr "我們建議您將此路線的滑點增加到至少 {minRequiredSlippage} 。" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:68 +msgid "Caution, your slippage is high." +msgstr "小心,你的滑點很高。" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.tsx:78 +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.Warning.tsx:26 +msgid "Change" +msgstr "改變" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:42 +msgid "Change settings" +msgstr "更改設定" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:52 +msgid "High slippage" +msgstr "高滑點" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:53 +msgid "Low slippage" +msgstr "低滑點" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:57 +msgid " Caution, your slippage is high (={userSlippage}). Your trade may be front run." +msgstr " 請注意,您的滑點很高 (={userSlippage})。您的交易可能會搶先交易。" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:78 +msgid "Confirm anyway" +msgstr "無論如何確認" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:22 +msgid "Something went wrong" +msgstr "出了點問題" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:24 +msgid "Something went wrong. Please refresh the app." +msgstr "出了點問題。請刷新應用程式。" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/Slippage.tsx:38 +msgid "Slippage tolerance per swap" +msgstr "每次互換的滑點容差" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/Slippage.tsx:91 +msgid "Custom" +msgstr "風俗" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:11 +msgid "Your transaction will be reverted if the price changes unfavorably by more than this percentage." +msgstr "如果價格不利變化超過此百分比,您的交易將被恢復。" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:16 +#: widget/embedded/src/containers/Settings/Lists.tsx:245 +msgid "Warning" +msgstr "警告" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:17 +msgid "This setting is applied to each step (e.g. 1Inch, Thorchain, etc.), meaning only that specific step will be reverted, not the entire route." +msgstr "此設定應用於每個步驟(例如 1Inch、Thorchain 等),這意味著僅恢復該特定步驟,而不是整個路線。" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:25 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:269 +msgid "Swap Details" +msgstr "互換詳情" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:33 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:312 +msgid "Request ID" +msgstr "請求ID" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:64 +msgid "Not found" +msgstr "未找到" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:65 +msgid "Swap with request ID = {requestId} not found." +msgstr "與請求 ID 進行交換 = {requestId} 未找到。" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:219 +msgid "You have received {amount} {token} in {conciseAddress} wallet on {chain} chain." +msgstr "您已在 {chain} 鏈上的 {conciseAddress} 錢包中收到 {amount} {token} 。" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:242 +msgid "Transaction was not sent." +msgstr "交易未發送。" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:244 +msgid "{amount} {symbol} on {blockchain} remains in your wallet." +msgstr "{blockchain} 上的 {amount} {symbol} 仍保留在您的錢包中。" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:281 +msgid "Delete" +msgstr "刪除" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:304 +msgid "Try again" +msgstr "再試一次" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:322 +msgid "Copied To Clipboard" +msgstr "複製到剪貼簿" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:323 +msgid "Copy Request ID" +msgstr "複製請求 ID" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:346 +msgid "View on Rango Explorer" +msgstr "在 Rango Explorer 上查看" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:355 +msgid "Finished at" +msgstr "完成於" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:355 +msgid "Created at" +msgstr "創建於" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.tsx:50 +msgid "View transaction" +msgstr "查看交易" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.Warning.tsx:49 +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:31 +msgid "Connect" +msgstr "連接" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:43 +msgid "Swap Successful" +msgstr "兌換成功" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:71 +msgid "Transaction Failed" +msgstr "交易失敗" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:87 +msgid "Done" +msgstr "完畢" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:100 +msgid "Diagnosis" +msgstr "診斷" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:112 +msgid "See Details" +msgstr "看詳情" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:13 +msgid "Cancel Swap" +msgstr "取消掉期" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:14 +msgid "Are you sure you want to cancel this swap?" +msgstr "您確定要取消此交換嗎?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:23 +msgid "Yes, Cancel it" +msgstr "是的,取消它" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:32 +#: widget/embedded/src/pages/CustomTokensPage.tsx:181 +msgid "No, Continue" +msgstr "不,繼續" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:13 +msgid "Delete Transaction" +msgstr "刪除交易" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:14 +msgid "Are you sure you want to delete this swap?" +msgstr "您確定要刪除此交換嗎?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:23 +#: widget/embedded/src/pages/CustomTokensPage.tsx:171 +msgid "Yes, Delete it" +msgstr "是的,刪除它" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:33 +#: widget/embedded/src/pages/HistoryPage.tsx:253 +msgid "No, Cancel" +msgstr "不,取消" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:12 +msgid "Change Network" +msgstr "改變網路" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:20 +msgid "Network Changed" +msgstr "網路已更改" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/TokenList/TokenList.tsx:271 +#: widget/ui/src/containers/SwapInput/TokenSection.tsx:54 +msgid "Select Token" +msgstr "選擇代幣" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:27 +msgid "Wallet Connected" +msgstr "錢包已連接" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:28 +msgid "Your wallet is connected, you can use it to swap." +msgstr "您的錢包已連接,您可以用它來兌換。" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:39 +msgid "Failed to Connect" +msgstr "連線失敗" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:41 +msgid "Your wallet is not connected. Please try again." +msgstr "您的錢包未連接。請再試一次。" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:50 +msgid "Connecting to your wallet" +msgstr "連接到您的錢包" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:51 +msgid "Click connect in your wallet popup." +msgstr "點擊錢包彈出視窗中的“連接”。" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:99 +msgid "Select Derivation Path" +msgstr "選擇推導路徑" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:100 +msgid "In order to connect to {type}, you must first select a Derivation Path" +msgstr "為了連接到 {type},您必須先選擇派生路徑" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:118 +msgid "Choose Derivation Path Template" +msgstr "選擇派生路徑模板" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:133 +msgid "Enter Path" +msgstr "輸入路徑" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:134 +msgid "Enter Index" +msgstr "輸入索引" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:15 +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:18 +msgid "Add {blockchainDisplayName} Chain" +msgstr "加入 {blockchainDisplayName} 鏈" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:20 +msgid "Would you like to add the {blockchainDisplayName} experimental chain to your wallet?" +msgstr "您想將 {blockchainDisplayName} 實驗鏈加入您的錢包嗎?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:22 +msgid "Please approve the experimental chain pop-up in your wallet." +msgstr "請批准您錢包中彈出的實驗鏈。" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:30 +msgid "{blockchainDisplayName} Chain Added" +msgstr "{blockchainDisplayName} 已加入鏈" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:34 +msgid "The {blockchainDisplayName} chain has been successfully added to your wallet." +msgstr "{blockchainDisplayName} 鏈已成功添加到您的錢包中。" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:42 +msgid "Request Rejected" +msgstr "請求被拒絕" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:43 +msgid "You've rejected adding {blockchainDisplayName} chain to your wallet." +msgstr "您已拒絕將 {blockchainDisplayName} 鏈添加到您的錢包中。" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:70 +msgid "Select chain types" +msgstr "選擇鏈條類型" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:71 +msgid "This wallet supports multiple chains. Select which chain you'd like to connect to." +msgstr "該錢包支援多鏈。選擇您想要連接的鏈。" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:9 +msgid "Failed Network, Please retry your swap." +msgstr "網路故障,請重試交換。" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:11 +msgid "Please reset your liquidity sources." +msgstr "請重置您的流動性來源。" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:12 +msgid "You have limited the liquidity sources and this might result in Rango finding no routes. Please consider resetting your liquidity sources." +msgstr "您限制了流動性來源,這可能會導致 Rango 找不到路線。請考慮重置您的流動性來源。" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:17 +msgid "No Routes Found." +msgstr "未找到路線。" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:18 +msgid "Reasons why Rango couldn't find a route: low liquidity on token, very low input amount or no routes available for the selected input/output token combination." +msgstr "Rango 找不到路線的原因:代幣流動性低、輸入量極低或所選輸入/輸出代幣組合沒有可用路線。" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:23 +msgid "Bridge Limit Error: Please increase your amount." +msgstr "橋接限制錯誤:請增加您的金額。" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:26 +msgid "Bridge Limit Error: Please decrease your amount." +msgstr "橋限制錯誤:請減少您的金額。" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:31 +msgid "High Price Impact" +msgstr "高價影響" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:32 +msgid "Price impact is too high!" +msgstr "價格影響太大了!" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:33 +msgid "The price impact is significantly higher than the allowed amount." +msgstr "價格影響明顯高於允許的金額。" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:36 +msgid "Confirm high price impact" +msgstr "確認高價影響" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:39 +msgid "Route updated and price impact is too high, try again later!" +msgstr "路線已更新,價格影響太大,請稍後再試!" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:44 +msgid "USD Price Unknown" +msgstr "美元價格未知" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:45 +msgid "USD Price Unknown, Cannot calculate Price Impact." +msgstr "美元價格未知,無法計算價格影響。" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:46 +msgid "USD Price Unknown, Cannot calculate Price Impact. The price impact may be higher than usual. Are you sure to continue the Swap?" +msgstr "美元價格未知,無法計算價格影響。價格影響可能比平常更大。您確定要繼續交換嗎?" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:49 +msgid "Confirm USD Price Unknown" +msgstr "確認美元價格未知" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:6 +#: widget/embedded/src/pages/Home.tsx:163 +msgid "Swap" +msgstr "交換" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:7 +msgid "Swap anyway" +msgstr "無論如何交換" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:8 +msgid "The route goes through Ethereum. Continue?" +msgstr "路線經過以太坊。繼續?" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:10 +msgid "Route has been updated." +msgstr "路線已更新。" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:12 +msgid "Output amount changed to {newOutputAmount} ({percentageChange}% change)." +msgstr "輸出量改為 {newOutputAmount} ({percentageChange}% 變化)。" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:20 +msgid "Route swappers has been updated." +msgstr "路由交換器已更新。" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:22 +msgid "Route internal coins has been updated." +msgstr "路線內部硬幣已更新。" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/ExpandedQuotes/ExpandedQuotes.tsx:53 +#: widget/embedded/src/pages/Routes.tsx:48 +msgid "Routes" +msgstr "路線" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Inputs/Inputs.tsx:76 +msgid "From" +msgstr "從" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Inputs/Inputs.tsx:118 +msgid "To" +msgstr "到" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:49 +msgid "Light" +msgstr "光" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:58 +msgid "Dark" +msgstr "黑暗的" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:67 +msgid "Auto" +msgstr "汽車" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:140 +msgid "Loading failed" +msgstr "載入失敗" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:156 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:41 +msgid "Bridges" +msgstr "橋樑" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:174 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:41 +msgid "Exchanges" +msgstr "交流" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:195 +#: widget/embedded/src/pages/CustomTokensPage.tsx:90 +msgid "Custom Tokens" +msgstr "自訂令牌" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:214 +#: widget/embedded/src/pages/LanguagePage.tsx:43 +msgid "Language" +msgstr "語言" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:235 +msgid "Infinite approval" +msgstr "無限認可" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:246 +msgid "Enabling the 'Infinite approval' mode grants unrestricted access to underlying smart contracts, allowing them to utilize the approved token amount without limitations." +msgstr "啟用「無限批准」模式可以不受限制地存取底層智慧合約,從而允許他們不受限制地使用批准的代幣數量。" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:266 +msgid "Theme" +msgstr "主題" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:39 +msgid "Duplicate Token" +msgstr "重複令牌" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:40 +msgid "The address you entered is duplicate, please enter a new address." +msgstr "您輸入的地址重複,請輸入新地址。" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:46 +msgid "Token Already Exists" +msgstr "令牌已存在" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:47 +msgid "There's no need to add this token again because it already exists and is supported by us." +msgstr "無需再次添加此令牌,因為它已經存在並且受到我們的支持。" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:53 +msgid "Token Not Found" +msgstr "未找到令牌" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:54 +msgid "Sorry, no token was found on {blockchain} chain with the provided address. please make sure you have entered the right token address." +msgstr "抱歉,在 {blockchain} 鏈上找不到具有所提供地址的代幣。請確保您輸入了正確的代幣地址。" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:78 +msgid "Network Error" +msgstr "網路錯誤" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:109 +#: widget/embedded/src/pages/CustomTokensPage.tsx:149 +msgid "Add Custom Token" +msgstr "新增自訂令牌" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:127 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:128 +msgid "Select chain" +msgstr "選擇鏈條" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:132 +msgid "Enter Address" +msgstr "輸入地址" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:139 +msgid "Enter token address" +msgstr "輸入代幣地址" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:176 +msgid "Failed Network, Please retry." +msgstr "網路故障,請重試。" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:192 +msgid "Add another custom token" +msgstr "新增另一個自訂令牌" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:236 +msgid "Confirm Swap" +msgstr "確認兌換" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:254 +msgid "Start Swap" +msgstr "開始交換" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:282 +msgid "You get" +msgstr "你得到" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:102 +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:90 +msgid "Search Token" +msgstr "搜尋令牌" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:134 +msgid "No custom tokens" +msgstr "沒有自訂令牌" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:135 +msgid "press the button to add your custom token" +msgstr "按下按鈕新增您的自訂令牌" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:158 +msgid "Delete Custom Token" +msgstr "刪除自訂令牌" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:160 +msgid "Are you sure you want to Delete this Token?" +msgstr "您確定要刪除此令牌嗎?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:59 +msgid "Complete" +msgstr "完全的" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:63 +msgid "Running" +msgstr "跑步" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:65 +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:8 +msgid "Failed" +msgstr "失敗的" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:149 +msgid "Clear" +msgstr "清除" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:161 +msgid "Search Transaction" +msgstr "搜尋交易" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:187 +msgid "No transactions" +msgstr "沒有交易" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:194 +msgid "Your transaction history is stored locally and will appear here after you start a swap" +msgstr "您的交易歷史記錄儲存在本地,並在您開始兌換後顯示在此處" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:218 +msgid "Clear Transaction History" +msgstr "清除交易歷史記錄" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:222 +msgid "Proceeding will remove all successful and failed transactions from the widget. Do you want to continue?" +msgstr "繼續將從小部件中刪除所有成功和失敗的交易。您想繼續嗎?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:229 +msgid "Note: This does not erase your transaction history on the chain; it only removes them here." +msgstr "注意:這不會刪除您在鏈上的交易歷史記錄;它只在這裡刪除它們。" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:243 +msgid "Yes, Clear the history" +msgstr "是的,清除歷史記錄" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LanguagePage.tsx:56 +msgid "language" +msgstr "語言" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:121 +msgid "Deselect all" +msgstr "取消全選" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:121 +msgid "Select all" +msgstr "選擇全部" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:133 +msgid "Search {sourceType}" +msgstr "搜尋 {sourceType}" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectBlockchainPage.tsx:60 +msgid "Search Chain" +msgstr "搜尋鏈" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:67 +msgid "Source" +msgstr "來源" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:68 +msgid "Destination" +msgstr "目的地" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:74 +msgid "Swap {type}" +msgstr "交換 {type}" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SettingsPage.tsx:45 +msgid "Currently, you're in campaign mode with restrictions on liquidity sources. Would you like to switch out of this mode and make use of all available liquidity sources?" +msgstr "目前,您處於活動模式,流動性來源受到限制。您想退出這種模式並利用所有可用的流動性來源嗎?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SwapDetailsPage.tsx:27 +msgid "The request ID is necessary to display the swap details." +msgstr "請求 ID 是顯示交換詳細資訊所必需的。" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/WalletsPage.tsx:67 +#: widget/ui/src/containers/ConnectWalletsModal/ConnectWalletsModal.tsx:15 +msgid "Connect Wallets" +msgstr "連接錢包" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/WalletsPage.tsx:82 +msgid "Choose a wallet to connect." +msgstr "選擇要連接的錢包。" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:25 +msgid "This week" +msgstr "本星期" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:32 +msgid "This month" +msgstr "本月" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:39 +msgid "This year" +msgstr "今年" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:129 +msgid "Required: >= {min} {symbol}" +msgstr "必填:>= {min} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:142 +msgid "Required: > {min} {symbol}" +msgstr "必填: > {min} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:157 +msgid "Required: <= {max} {symbol}" +msgstr "必填:<= {max} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:170 +msgid "Required: < {max} {symbol}" +msgstr "必填:< {max} {symbol}" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:601 +msgid " for network fee" +msgstr " 收取網路費" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:604 +msgid " for swap" +msgstr " 用於交換" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:607 +msgid " for input and network fee" +msgstr " 輸入費和網路費" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:609 +msgid "Needs ≈ {requiredAmount} {symbol}{reason}, but you have {currentAmount} {symbol} in your {blockchain} wallet." +msgstr "需要 ≈ {requiredAmount} {symbol}{reason},但你的 {blockchain} 錢包裡有 {currentAmount} {symbol}。" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:669 +msgid "Waiting for connecting wallet" +msgstr "等待連接錢包" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:673 +msgid "Waiting for other running tasks to be finished" +msgstr "等待其他正在運行的任務完成" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:676 +msgid "Waiting for changing wallet network" +msgstr "等待更改錢包網絡" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:6 +msgid "Sunday" +msgstr "星期日" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:7 +msgid "Monday" +msgstr "週一" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:8 +msgid "Tuesday" +msgstr "週二" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:9 +msgid "Wednesday" +msgstr "週三" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:10 +msgid "Thursday" +msgstr "週四" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:11 +msgid "Friday" +msgstr "星期五" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:12 +msgid "Saturday" +msgstr "週六" + +#. js-lingui-explicit-id +#: widget/ui/src/components/BottomLogo/BottomLogo.tsx:14 +msgid "Powered By" +msgstr "供電" + +#. js-lingui-explicit-id +#: widget/ui/src/components/FullExpandedQuote/FullExpandedQuote.Tooltip.tsx:37 +msgid "Aggregated Transaction" +msgstr "聚合交易" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SelectableCategoryList/SelectableCategoryList.tsx:63 +msgid "{blockchainCategory}" +msgstr "" + +#. js-lingui-explicit-id +#: widget/ui/src/components/StepDetails/StepDetails.tsx:75 +#: widget/ui/src/components/StepDetails/StepDetails.tsx:102 +msgid "Swap on {fromChain} via {swapper}" +msgstr "透過 {swapper}交換 {fromChain}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/StepDetails/StepDetails.tsx:109 +msgid "Bridge to {toChain} via {swapper}" +msgstr "經 {swapper}橋接在 {toChain}" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:10 +msgid "Completed" +msgstr "完全的" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:12 +msgid "In progress" +msgstr "進行中" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapToken.tsx:122 +msgid "Waiting for bridge transaction" +msgstr "等待橋接交易" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:12 +msgid "Connected" +msgstr "已連接" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:13 +msgid "Disconnect" +msgstr "斷開" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:18 +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:19 +msgid "Install" +msgstr "安裝" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:24 +msgid "Connecting ..." +msgstr "正在連接..." + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:25 +msgid "Connecting" +msgstr "連接中" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:30 +msgid "Disconnected" +msgstr "已斷開連接" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:34 +msgid "you need to pass a correct state to Wallet." +msgstr "您需要將正確的狀態傳遞給錢包。" + +#. js-lingui-explicit-id +#: widget/ui/src/containers/Notifications/NotificationNotFound.tsx:15 +msgid "There are no notifications." +msgstr "沒有任何通知。" + +#. js-lingui-explicit-id +#: widget/ui/src/containers/Notifications/Notifications.tsx:39 +msgid "Clear all" +msgstr "全部清除" + +#. js-lingui-explicit-id +#: widget/ui/src/containers/SwapInput/SwapInput.tsx:65 +msgid "Balance" +msgstr "平衡" + +#. js-lingui-explicit-id +#: widget/ui/src/containers/SwapInput/SwapInput.tsx:73 +msgid "Max" +msgstr "最大限度" + diff --git a/translations/zh.po b/translations/zh.po new file mode 100644 index 0000000000..078cb9d37e --- /dev/null +++ b/translations/zh.po @@ -0,0 +1,1329 @@ +msgid "" +msgstr "" +"POT-Creation-Date: 2023-11-06 17:24+0330\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: @lingui/cli\n" +"Language: zh\n" +"Project-Id-Version: rango\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2024-10-09 12:58\n" +"Last-Translator: \n" +"Language-Team: Chinese Simplified\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Crowdin-Project: rango\n" +"X-Crowdin-Project-ID: 622238\n" +"X-Crowdin-Language: zh-CN\n" +"X-Crowdin-File: en.po\n" +"X-Crowdin-File-ID: 30\n" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:41 +#: widget/embedded/src/components/TokenList/TokenList.tsx:286 +#: widget/embedded/src/pages/HistoryPage.tsx:186 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:143 +msgid "No results found" +msgstr "未找到结果" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:42 +#: widget/embedded/src/components/TokenList/TokenList.tsx:287 +#: widget/embedded/src/pages/HistoryPage.tsx:193 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:144 +msgid "Try using different keywords" +msgstr "尝试使用不同的关键字" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainList/BlockchainList.tsx:72 +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:46 +#: widget/embedded/src/pages/SelectBlockchainPage.tsx:42 +#: widget/ui/src/containers/SwapInput/TokenSection.tsx:61 +msgid "Select Chain" +msgstr "选择链条" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:66 +msgid "All" +msgstr "所有的" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx:100 +msgid "More +{count}" +msgstr "" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabAlert/ActivateTabAlert.tsx:17 +msgid "Activate this tab" +msgstr "激活此标签" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabAlert/ActivateTabAlert.tsx:22 +msgid "Another tab is open and handles transactions." +msgstr "另一个标签是打开和处理交易。" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:20 +msgid "Activate current tab" +msgstr "激活当前标签" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:22 +msgid "Currently, some transactions are running and being handled by other browser tab. If you activate this tab, all transactions that are already in the transaction sign step will expire." +msgstr "目前,有些交易正在运行,正在由其他浏览器选项卡处理。 如果您激活此标签,所有已经在交易签名步骤中的交易都将过期。" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx:33 +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:349 +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:152 +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:33 +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:116 +msgid "Confirm" +msgstr "确认" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:365 +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:447 +msgid "Your {blockchainName} wallets" +msgstr "" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:384 +msgid "Insufficient account balance" +msgstr "账户余额不足" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:394 +msgid "Proceed anyway" +msgstr "仍然继续" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx:456 +msgid "You need to connect a {blockchainName} wallet." +msgstr "" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/WalletList.tsx:143 +msgid "Add {chain} chain" +msgstr "" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/ConfirmWalletsModal/WalletList.tsx:244 +msgid "Show more wallets" +msgstr "显示更多钱包" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:113 +msgid "Send to a different address" +msgstr "发送到另一个地址" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:129 +msgid "Enter {blockchainName} address" +msgstr "" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomDestination/CustomDestination.tsx:147 +msgid "Address {destination} doesn't match the blockchain address pattern." +msgstr "" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:59 +msgid "via" +msgstr "通过" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:74 +msgid "This token doesn't appear on the active token list(s). Make sure this is the token that you want to trade." +msgstr "此令牌不会出现在活动令牌列表中。请确保这是您想要交易的令牌。" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx:89 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:164 +msgid "Import" +msgstr "导入" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/FilterSelector/FilterSelectorContent.tsx:26 +msgid "Status" +msgstr "状态" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/FilterSelector/FilterSelectorContent.tsx:33 +#: widget/embedded/src/components/NoResult/NoResult.helpers.ts:40 +#: widget/embedded/src/pages/SettingsPage.tsx:55 +msgid "Reset" +msgstr "Reset" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/CancelButton.tsx:18 +msgid "Cancel" +msgstr "取消" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:46 +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:34 +msgid "Refresh" +msgstr "刷新" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:63 +#: widget/ui/src/containers/Notifications/Notifications.tsx:35 +msgid "Notifications" +msgstr "通知" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:79 +#: widget/embedded/src/pages/SettingsPage.tsx:38 +msgid "Settings" +msgstr "设置" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx:93 +#: widget/embedded/src/pages/HistoryPage.tsx:139 +msgid "History" +msgstr "历史记录" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HeaderButtons/WalletButton.tsx:22 +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:16 +#: widget/embedded/src/constants/messages.ts:5 +msgid "Connect Wallet" +msgstr "连接钱包" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/HistoryGroupedList/HistoryGroupedList.tsx:118 +#: widget/embedded/src/utils/date.ts:18 +#: widget/embedded/src/utils/time.ts:22 +msgid "Today" +msgstr "今日:" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/LoadingSwapDetails/LoadingSwapDetails.tsx:20 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:424 +msgid "Swaps steps" +msgstr "互换步骤" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/NoResult/NoResult.helpers.ts:28 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:191 +msgid "Retry" +msgstr "重试" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:149 +msgid "Slippage Error" +msgstr "翻转错误" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:150 +msgid "Slippage Warning" +msgstr "翻转警告" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:153 +msgid "Bridge Limit Error" +msgstr "桥接限制错误" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:240 +msgid "Yours: {amount} {symbol}" +msgstr "" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:261 +msgid "Minimum required slippage: {minRequiredSlippage}" +msgstr "" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:282 +msgid "Yours: {userSlippage}" +msgstr "" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/Quote.tsx:395 +msgid "See All Routes" +msgstr "查看所有路由" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:81 +msgid "View more info" +msgstr "查看更多信息" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:91 +msgid "Gas & Fee Explanation" +msgstr "气体和费用解释" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:107 +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:103 +msgid "Details" +msgstr "详细信息" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:146 +msgid "Total Payable Fee" +msgstr "应支付费用总额" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:166 +msgid "Hide non-payable fees" +msgstr "隐藏非支付费用" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:167 +msgid "Show non-payable fees" +msgstr "显示非应支付费用" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:177 +msgid "Description" +msgstr "描述" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteCostDetails.tsx:181 +msgid "The following fees are considered in the transaction output and\n" +" you won’t need to pay extra gas for them." +msgstr "在交易输出中考虑到以下费用和\n" +" 您将不需要支付额外的气体。" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteSummary.tsx:25 +msgid "Swap input" +msgstr "Swap input" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteSummary.tsx:44 +msgid "Estimated output" +msgstr "估计输出" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteTrigger.tsx:65 +msgid "Via:" +msgstr "Via:" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quote/QuoteTrigger.tsx:150 +msgid "Chains:" +msgstr "链:" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/Quotes.tsx:77 +msgid "Sort by" +msgstr "排序方式" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:17 +msgid "Smart Routing" +msgstr "智能路由" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:21 +msgid "Lowest Fee" +msgstr "最低费用" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:25 +msgid "Fastest Transfer" +msgstr "最快的传输" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:29 +msgid "Maximum Return" +msgstr "最大返回" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Quotes/SelectStrategy.tsx:33 +msgid "Maximum Output" +msgstr "最大输出" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:43 +msgid "Swapping" +msgstr "Swapping" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:51 +msgid "Gas cost" +msgstr "煤气成本" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:59 +msgid "Receiving" +msgstr "接收中" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx:67 +msgid "Price impact" +msgstr "价格影响" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:35 +msgid "You need to increase slippage to at least {minRequiredSlippage} for this route." +msgstr "" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:59 +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:61 +msgid "We recommend you to increase slippage to at least {minRequiredSlippage} for this route." +msgstr "" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts:68 +msgid "Caution, your slippage is high." +msgstr "注意力,您的幻灯片很高。" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.tsx:78 +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.Warning.tsx:26 +msgid "Change" +msgstr "更改" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:42 +msgid "Change settings" +msgstr "更改设置" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:52 +msgid "High slippage" +msgstr "高滑块" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:53 +msgid "Low slippage" +msgstr "低滑块" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:57 +msgid " Caution, your slippage is high (={userSlippage}). Your trade may be front run." +msgstr "" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx:78 +msgid "Confirm anyway" +msgstr "仍然确认" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:22 +msgid "Something went wrong" +msgstr "出了错。" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/RefreshModal/RefreshModal.tsx:24 +msgid "Something went wrong. Please refresh the app." +msgstr "出错了。请刷新应用程序。" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/Slippage.tsx:38 +msgid "Slippage tolerance per swap" +msgstr "每次交换时翻页范围" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/Slippage.tsx:91 +msgid "Custom" +msgstr "自定义" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:11 +msgid "Your transaction will be reverted if the price changes unfavorably by more than this percentage." +msgstr "如果价格变化大于此百分比,您的交易将会恢复。" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:16 +#: widget/embedded/src/containers/Settings/Lists.tsx:245 +msgid "Warning" +msgstr "警告" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/Slippage/SlippageTooltipContent.tsx:17 +msgid "This setting is applied to each step (e.g. 1Inch, Thorchain, etc.), meaning only that specific step will be reverted, not the entire route." +msgstr "此设置适用于每一步(例如1Inch、Thorchain等),只表示特定步骤将被还原,而不是整个路径。" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:25 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:269 +msgid "Swap Details" +msgstr "交换详情" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:33 +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:312 +msgid "Request ID" +msgstr "请求ID" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:64 +msgid "Not found" +msgstr "找不到" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.Placeholder.tsx:65 +msgid "Swap with request ID = {requestId} not found." +msgstr "" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:219 +msgid "You have received {amount} {token} in {conciseAddress} wallet on {chain} chain." +msgstr "" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:242 +msgid "Transaction was not sent." +msgstr "交易未发送。" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:244 +msgid "{amount} {symbol} on {blockchain} remains in your wallet." +msgstr "" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:281 +msgid "Delete" +msgstr "删除" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:304 +msgid "Try again" +msgstr "再试一次" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:322 +msgid "Copied To Clipboard" +msgstr "复制到剪贴板" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:323 +msgid "Copy Request ID" +msgstr "复制请求ID" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:346 +msgid "View on Rango Explorer" +msgstr "在Rango浏览器上查看" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:355 +msgid "Finished at" +msgstr "完成于" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetails/SwapDetails.tsx:355 +msgid "Created at" +msgstr "创建于" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.tsx:50 +msgid "View transaction" +msgstr "查看交易" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsAlerts/SwapDetailsAlerts.Warning.tsx:49 +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:31 +msgid "Connect" +msgstr "连接" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:43 +msgid "Swap Successful" +msgstr "交换成功" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:71 +msgid "Transaction Failed" +msgstr "交易失败" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:87 +msgid "Done" +msgstr "完成" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:100 +msgid "Diagnosis" +msgstr "诊断信息" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsCompleteModal.tsx:112 +msgid "See Details" +msgstr "查看详细信息" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:13 +msgid "Cancel Swap" +msgstr "取消切换" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:14 +msgid "Are you sure you want to cancel this swap?" +msgstr "您确定要取消此交换吗?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:23 +msgid "Yes, Cancel it" +msgstr "是,取消它" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Cancel.tsx:32 +#: widget/embedded/src/pages/CustomTokensPage.tsx:181 +msgid "No, Continue" +msgstr "否,继续" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:13 +msgid "Delete Transaction" +msgstr "删除交易" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:14 +msgid "Are you sure you want to delete this swap?" +msgstr "您确定要删除这个交换吗?" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:23 +#: widget/embedded/src/pages/CustomTokensPage.tsx:171 +msgid "Yes, Delete it" +msgstr "是,删除它" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.Delete.tsx:33 +#: widget/embedded/src/pages/HistoryPage.tsx:253 +msgid "No, Cancel" +msgstr "否,取消" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:12 +msgid "Change Network" +msgstr "更改网络" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/SwapDetailsModal/SwapDetailsModal.helpers.tsx:20 +msgid "Network Changed" +msgstr "网络已更改" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/TokenList/TokenList.tsx:271 +#: widget/ui/src/containers/SwapInput/TokenSection.tsx:54 +msgid "Select Token" +msgstr "选择令牌" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:27 +msgid "Wallet Connected" +msgstr "钱包已连接" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:28 +msgid "Your wallet is connected, you can use it to swap." +msgstr "您的钱包已连接,您可以使用它交换。" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:39 +msgid "Failed to Connect" +msgstr "连接失败" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:41 +msgid "Your wallet is not connected. Please try again." +msgstr "您的钱包未连接。请重试。" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:50 +msgid "Connecting to your wallet" +msgstr "正在连接你的钱包" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ConnectStatus.tsx:51 +msgid "Click connect in your wallet popup." +msgstr "点击在你的钱包弹出窗口中连接。" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:99 +msgid "Select Derivation Path" +msgstr "选择派生路径" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:100 +msgid "In order to connect to {type}, you must first select a Derivation Path" +msgstr "" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:118 +msgid "Choose Derivation Path Template" +msgstr "选择派生路径模板" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:133 +msgid "Enter Path" +msgstr "输入路径" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/DerivationPath.tsx:134 +msgid "Enter Index" +msgstr "输入索引" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:15 +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:18 +msgid "Add {blockchainDisplayName} Chain" +msgstr "" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx:20 +msgid "Would you like to add the {blockchainDisplayName} experimental chain to your wallet?" +msgstr "" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:22 +msgid "Please approve the experimental chain pop-up in your wallet." +msgstr "请批准您钱包中的实验性链弹出窗口。" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:30 +msgid "{blockchainDisplayName} Chain Added" +msgstr "" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:34 +msgid "The {blockchainDisplayName} chain has been successfully added to your wallet." +msgstr "" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:42 +msgid "Request Rejected" +msgstr "请求被拒绝" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts:43 +msgid "You've rejected adding {blockchainDisplayName} chain to your wallet." +msgstr "" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:70 +msgid "Select chain types" +msgstr "选择链类型" + +#. js-lingui-explicit-id +#: widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx:71 +msgid "This wallet supports multiple chains. Select which chain you'd like to connect to." +msgstr "这个钱包支持多个链。选择你想要连接的链。" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:9 +msgid "Failed Network, Please retry your swap." +msgstr "网络失败,请重试您的交换。" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:11 +msgid "Please reset your liquidity sources." +msgstr "请重置您的流动资金来源。" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:12 +msgid "You have limited the liquidity sources and this might result in Rango finding no routes. Please consider resetting your liquidity sources." +msgstr "您限制了流动资金来源,这可能导致Rango找不到路径。请考虑重置您的流动资金来源。" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:17 +msgid "No Routes Found." +msgstr "未找到路由。" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:18 +msgid "Reasons why Rango couldn't find a route: low liquidity on token, very low input amount or no routes available for the selected input/output token combination." +msgstr "为什么Rango找不到路由:代币流动性低,输入量很低,或者没有选择的输入/输出代币组合可用的路由。" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:23 +msgid "Bridge Limit Error: Please increase your amount." +msgstr "桥接限制错误:请增加您的金额。" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:26 +msgid "Bridge Limit Error: Please decrease your amount." +msgstr "桥接限制错误:请减少您的金额。" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:31 +msgid "High Price Impact" +msgstr "高价格影响" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:32 +msgid "Price impact is too high!" +msgstr "价格影响过高!" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:33 +msgid "The price impact is significantly higher than the allowed amount." +msgstr "价格影响大大高于允许的数额。" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:36 +msgid "Confirm high price impact" +msgstr "确认高价格影响" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:39 +msgid "Route updated and price impact is too high, try again later!" +msgstr "路由更新且价格影响太大,请稍后再试" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:44 +msgid "USD Price Unknown" +msgstr "美元价格未知" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:45 +msgid "USD Price Unknown, Cannot calculate Price Impact." +msgstr "美元价格未知,不能计算价格影响。" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:46 +msgid "USD Price Unknown, Cannot calculate Price Impact. The price impact may be higher than usual. Are you sure to continue the Swap?" +msgstr "美元价格未知,不能计算价格影响。价格影响可能高于通常。您确定要继续掉期吗?" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/errors.ts:49 +msgid "Confirm USD Price Unknown" +msgstr "确认美元价格未知" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:6 +#: widget/embedded/src/pages/Home.tsx:161 +msgid "Swap" +msgstr "切换" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:7 +msgid "Swap anyway" +msgstr "仍然切换" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/messages.ts:8 +msgid "The route goes through Ethereum. Continue?" +msgstr "航线穿过太太空了。继续吗?" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:10 +msgid "Route has been updated." +msgstr "路由已更新。" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:12 +msgid "Output amount changed to {newOutputAmount} ({percentageChange}% change)." +msgstr "" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:20 +msgid "Route swappers has been updated." +msgstr "路由交换器已更新。" + +#. js-lingui-explicit-id +#: widget/embedded/src/constants/warnings.ts:22 +msgid "Route internal coins has been updated." +msgstr "内部硬币已更新。" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/ExpandedQuotes/ExpandedQuotes.tsx:53 +#: widget/embedded/src/pages/Routes.tsx:48 +msgid "Routes" +msgstr "路由" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Inputs/Inputs.tsx:76 +msgid "From" +msgstr "来自" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Inputs/Inputs.tsx:118 +msgid "To" +msgstr "收件人" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:49 +msgid "Light" +msgstr "亮色的" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:58 +msgid "Dark" +msgstr "深色" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:67 +msgid "Auto" +msgstr "自动操作" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:140 +msgid "Loading failed" +msgstr "加载失败" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:156 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:41 +msgid "Bridges" +msgstr "桥接" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:174 +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:41 +msgid "Exchanges" +msgstr "交易" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:195 +#: widget/embedded/src/pages/CustomTokensPage.tsx:90 +msgid "Custom Tokens" +msgstr "自定义令牌" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:214 +#: widget/embedded/src/pages/LanguagePage.tsx:43 +msgid "Language" +msgstr "语言" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:235 +msgid "Infinite approval" +msgstr "无限批准" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:246 +msgid "Enabling the 'Infinite approval' mode grants unrestricted access to underlying smart contracts, allowing them to utilize the approved token amount without limitations." +msgstr "启用“无限批准”模式允许无限制访问基本智能合同,允许他们不受限制地使用已批准的代币金额。" + +#. js-lingui-explicit-id +#: widget/embedded/src/containers/Settings/Lists.tsx:266 +msgid "Theme" +msgstr "主题" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:39 +msgid "Duplicate Token" +msgstr "Duplicate Token" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:40 +msgid "The address you entered is duplicate, please enter a new address." +msgstr "您输入的地址是重复的,请输入一个新地址。" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:46 +msgid "Token Already Exists" +msgstr "令牌已存在" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:47 +msgid "There's no need to add this token again because it already exists and is supported by us." +msgstr "无需再次添加此令牌,因为它已经存在并得到我们的支持。" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:53 +msgid "Token Not Found" +msgstr "未找到令牌" + +#. js-lingui-explicit-id +#: widget/embedded/src/hooks/useFetchCustomToken.ts:54 +msgid "Sorry, no token was found on {blockchain} chain with the provided address. please make sure you have entered the right token address." +msgstr "" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:78 +msgid "Network Error" +msgstr "网络错误" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:109 +#: widget/embedded/src/pages/CustomTokensPage.tsx:149 +msgid "Add Custom Token" +msgstr "添加自定义令牌" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:127 +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:128 +msgid "Select chain" +msgstr "选择链接" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:132 +msgid "Enter Address" +msgstr "输入地址" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:139 +msgid "Enter token address" +msgstr "输入令牌地址" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:176 +msgid "Failed Network, Please retry." +msgstr "网络失败,请重试。" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/AddCustomTokenPage.tsx:192 +msgid "Add another custom token" +msgstr "添加另一个自定义令牌" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:236 +msgid "Confirm Swap" +msgstr "确认切换" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:254 +msgid "Start Swap" +msgstr "启动交换机" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/ConfirmSwapPage.tsx:282 +msgid "You get" +msgstr "你得到了" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:102 +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:90 +msgid "Search Token" +msgstr "搜索令牌" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:134 +msgid "No custom tokens" +msgstr "没有自定义令牌" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:135 +msgid "press the button to add your custom token" +msgstr "点击按钮添加您的自定义令牌" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:158 +msgid "Delete Custom Token" +msgstr "删除自定义令牌" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/CustomTokensPage.tsx:160 +msgid "Are you sure you want to Delete this Token?" +msgstr "您确定要删除此令牌吗?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:59 +msgid "Complete" +msgstr "Complete" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:63 +msgid "Running" +msgstr "正在运行" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:65 +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:8 +msgid "Failed" +msgstr "失败" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:149 +msgid "Clear" +msgstr "清空" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:161 +msgid "Search Transaction" +msgstr "搜索交易" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:187 +msgid "No transactions" +msgstr "无交易" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:194 +msgid "Your transaction history is stored locally and will appear here after you start a swap" +msgstr "您的交易历史已存储在本地,并将在您开始交换后显示在这里" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:218 +msgid "Clear Transaction History" +msgstr "清除交易记录" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:222 +msgid "Proceeding will remove all successful and failed transactions from the widget. Do you want to continue?" +msgstr "继续操作将从小部件删除所有成功和失败的交易。您想要继续吗?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:229 +msgid "Note: This does not erase your transaction history on the chain; it only removes them here." +msgstr "注意:这不会擦除您在链上的交易历史记录;它只会将它们移到此处。" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/HistoryPage.tsx:243 +msgid "Yes, Clear the history" +msgstr "是的,清除历史记录" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LanguagePage.tsx:56 +msgid "language" +msgstr "语言" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:121 +msgid "Deselect all" +msgstr "取消全选" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:121 +msgid "Select all" +msgstr "选择所有" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/LiquiditySourcePage.tsx:133 +msgid "Search {sourceType}" +msgstr "" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectBlockchainPage.tsx:60 +msgid "Search Chain" +msgstr "搜索链接" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:67 +msgid "Source" +msgstr "来源" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:68 +msgid "Destination" +msgstr "目标" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SelectSwapItemsPage.tsx:74 +msgid "Swap {type}" +msgstr "" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SettingsPage.tsx:45 +msgid "Currently, you're in campaign mode with restrictions on liquidity sources. Would you like to switch out of this mode and make use of all available liquidity sources?" +msgstr "目前,您正处于活动模式,并且限制了流动资金来源。 您想要切换此模式并使用所有可用的流动资金来源吗?" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/SwapDetailsPage.tsx:27 +msgid "The request ID is necessary to display the swap details." +msgstr "请求ID是显示交换详细信息所必需的。" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/WalletsPage.tsx:67 +#: widget/ui/src/containers/ConnectWalletsModal/ConnectWalletsModal.tsx:15 +msgid "Connect Wallets" +msgstr "连接钱包" + +#. js-lingui-explicit-id +#: widget/embedded/src/pages/WalletsPage.tsx:82 +msgid "Choose a wallet to connect." +msgstr "选择要连接的钱包。" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:25 +msgid "This week" +msgstr "本周" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:32 +msgid "This month" +msgstr "本月" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/date.ts:39 +msgid "This year" +msgstr "今年:" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:129 +msgid "Required: >= {min} {symbol}" +msgstr "" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:142 +msgid "Required: > {min} {symbol}" +msgstr "" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:157 +msgid "Required: <= {max} {symbol}" +msgstr "" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:170 +msgid "Required: < {max} {symbol}" +msgstr "" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:604 +msgid " for network fee" +msgstr " 网络费用" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:607 +msgid " for swap" +msgstr " 换行" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:610 +msgid " for input and network fee" +msgstr " 输入和网络费用" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:612 +msgid "Needs ≈ {requiredAmount} {symbol}{reason}, but you have {currentAmount} {symbol} in your {blockchain} wallet." +msgstr "" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:672 +msgid "Waiting for connecting wallet" +msgstr "正在等待连接钱包" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:676 +msgid "Waiting for other running tasks to be finished" +msgstr "等待其他正在运行的任务完成" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/swap.ts:679 +msgid "Waiting for changing wallet network" +msgstr "正在等待更改钱包网络" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:6 +msgid "Sunday" +msgstr "周日" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:7 +msgid "Monday" +msgstr "周一" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:8 +msgid "Tuesday" +msgstr "星期二" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:9 +msgid "Wednesday" +msgstr "星期三" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:10 +msgid "Thursday" +msgstr "星期四" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:11 +msgid "Friday" +msgstr "星期五" + +#. js-lingui-explicit-id +#: widget/embedded/src/utils/time.ts:12 +msgid "Saturday" +msgstr "周六" + +#. js-lingui-explicit-id +#: widget/ui/src/components/BottomLogo/BottomLogo.tsx:14 +msgid "Powered By" +msgstr "支持者" + +#. js-lingui-explicit-id +#: widget/ui/src/components/FullExpandedQuote/FullExpandedQuote.Tooltip.tsx:37 +msgid "Aggregated Transaction" +msgstr "合计交易" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SelectableCategoryList/SelectableCategoryList.tsx:63 +msgid "{blockchainCategory}" +msgstr "" + +#. js-lingui-explicit-id +#: widget/ui/src/components/StepDetails/StepDetails.tsx:75 +#: widget/ui/src/components/StepDetails/StepDetails.tsx:102 +msgid "Swap on {fromChain} via {swapper}" +msgstr "" + +#. js-lingui-explicit-id +#: widget/ui/src/components/StepDetails/StepDetails.tsx:109 +msgid "Bridge to {toChain} via {swapper}" +msgstr "" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:10 +msgid "Completed" +msgstr "已完成" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts:12 +msgid "In progress" +msgstr "进行中" + +#. js-lingui-explicit-id +#: widget/ui/src/components/SwapListItem/SwapToken.tsx:122 +msgid "Waiting for bridge transaction" +msgstr "等待桥接交易" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:12 +msgid "Connected" +msgstr "已连接" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:13 +msgid "Disconnect" +msgstr "断开连接" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:18 +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:19 +msgid "Install" +msgstr "安装" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:24 +msgid "Connecting ..." +msgstr "正在连接..." + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:25 +msgid "Connecting" +msgstr "正在连接" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:30 +msgid "Disconnected" +msgstr "断开连接" + +#. js-lingui-explicit-id +#: widget/ui/src/components/Wallet/Wallet.helpers.ts:34 +msgid "you need to pass a correct state to Wallet." +msgstr "您需要将一个正确的状态传递给钱包。" + +#. js-lingui-explicit-id +#: widget/ui/src/containers/Notifications/NotificationNotFound.tsx:15 +msgid "There are no notifications." +msgstr "没有通知。" + +#. js-lingui-explicit-id +#: widget/ui/src/containers/Notifications/Notifications.tsx:39 +msgid "Clear all" +msgstr "全部清除" + +#. js-lingui-explicit-id +#: widget/ui/src/containers/SwapInput/SwapInput.tsx:65 +msgid "Balance" +msgstr "余额" + +#. js-lingui-explicit-id +#: widget/ui/src/containers/SwapInput/SwapInput.tsx:73 +msgid "Max" +msgstr "最大值" + diff --git a/tsconfig.base.json b/tsconfig.base.json index d047b93b60..5510cb9153 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -1,5 +1,29 @@ { "compilerOptions": { - "declarationMap": true + "module": "esnext", + // use Node's module resolution algorithm, instead of the legacy TS one + "target": "ES2015", + "moduleResolution": "node", + // stricter type-checking for stronger correctness. Recommended by TS + "strict": true, + // significant perf increase by skipping checking .d.ts files, particularly those in node_modules. Recommended by TS + "skipLibCheck": true, + // error out if import and file system have a casing mismatch. Recommended by TS + "forceConsistentCasingInFileNames": true, + "importHelpers": true, + // output .js.map sourcemap files for consumers + "sourceMap": true, + // linter checks for common issues + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + // noUnused* overlap with @typescript-eslint/no-unused-vars, can disable if duplicative + "noUnusedLocals": true, + "noUnusedParameters": true, + + // ESBuild + "isolatedModules": true, + // interop between ESM and CJS modules. Recommended by TS + "esModuleInterop": true, + "allowSyntheticDefaultImports": true } } diff --git a/tsconfig.bundler.json b/tsconfig.bundler.json new file mode 100644 index 0000000000..caef733bcb --- /dev/null +++ b/tsconfig.bundler.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "strict": true, + "target": "es2022", + "module": "esnext", + "moduleResolution": "bundler", + "esModuleInterop": true, + "allowImportingTsExtensions": true, + "allowArbitraryExtensions": true, + "verbatimModuleSyntax": true + } +} diff --git a/tsconfig.lib.json b/tsconfig.lib.json new file mode 100644 index 0000000000..b5ca3a701e --- /dev/null +++ b/tsconfig.lib.json @@ -0,0 +1,9 @@ +{ + "extends": "./tsconfig.base.json", + "compilerOptions": { + "emitDeclarationOnly": true, + // output .d.ts declaration files for consumers + "declaration": true, + "declarationMap": true + } +} diff --git a/tsconfig.libnext.json b/tsconfig.libnext.json new file mode 100644 index 0000000000..412ebda959 --- /dev/null +++ b/tsconfig.libnext.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "module": "node16", + "target": "es2022", + "strict": true, + "verbatimModuleSyntax": true, + "declaration": true, + "sourceMap": true, + "declarationMap": true + } +} diff --git a/vitest.config.ts b/vitest.config.ts new file mode 100644 index 0000000000..19ebacfe1e --- /dev/null +++ b/vitest.config.ts @@ -0,0 +1,8 @@ +import { defineConfig } from 'vitest/config'; + +export default defineConfig({ + test: { + environment: 'happy-dom', + watch: false, + }, +}); diff --git a/wallets/core/CHANGELOG.md b/wallets/core/CHANGELOG.md new file mode 100644 index 0000000000..b8966f5ee9 --- /dev/null +++ b/wallets/core/CHANGELOG.md @@ -0,0 +1,179 @@ +# [0.40.0](https://github.com/rango-exchange/rango-client/compare/wallets-core@0.39.0...wallets-core@0.40.0) (2024-11-12) + + + +# [0.39.0](https://github.com/rango-exchange/rango-client/compare/wallets-core@0.38.0...wallets-core@0.39.0) (2024-10-12) + + +### Bug Fixes + +* bump sdk and fix type issues ([d442208](https://github.com/rango-exchange/rango-client/commit/d4422083bf5dd27d5f509ce1db7f9560d05428c8)) + + +### Features + +* introducing hub, our new wallet management ([92692fe](https://github.com/rango-exchange/rango-client/commit/92692fe7a05be72caea8b99bcc4ac5e2326f2f5a)) + + +### Performance Improvements + +* lazy load signer packages ([7b88f18](https://github.com/rango-exchange/rango-client/commit/7b88f1834f7b29b4b81ab6c81a07bb88e8ccf55c)) + + + +# [0.38.0](https://github.com/rango-exchange/rango-client/compare/wallets-core@0.37.0...wallets-core@0.38.0) (2024-09-10) + + + +# [0.37.0](https://github.com/rango-exchange/rango-client/compare/wallets-core@0.36.1...wallets-core@0.37.0) (2024-08-11) + + + +## [0.36.1](https://github.com/rango-exchange/rango-client/compare/wallets-core@0.36.0...wallets-core@0.36.1) (2024-07-14) + + + +# [0.36.0](https://github.com/rango-exchange/rango-client/compare/wallets-core@0.34.0...wallets-core@0.36.0) (2024-07-09) + + +### Features + +* add a modal for setting custom derivation path for ledger ([5b74ec0](https://github.com/rango-exchange/rango-client/commit/5b74ec049393ed74e3e7547edc72b68bd70b7dce)) + + + +# [0.35.0](https://github.com/rango-exchange/rango-client/compare/wallets-core@0.34.0...wallets-core@0.35.0) (2024-06-01) + + + +# [0.34.0](https://github.com/rango-exchange/rango-client/compare/wallets-core@0.33.0...wallets-core@0.34.0) (2024-05-14) + + +### Features + +* add solana to ledger ([77b6695](https://github.com/rango-exchange/rango-client/commit/77b6695758165f9258a0ba5bd3b2cf39b0b2aab5)) + + + +# [0.33.0](https://github.com/rango-exchange/rango-client/compare/wallets-core@0.32.0...wallets-core@0.33.0) (2024-04-24) + + + +# [0.32.0](https://github.com/rango-exchange/rango-client/compare/wallets-core@0.31.0...wallets-core@0.32.0) (2024-04-23) + + +### Bug Fixes + +* set current state for current network in conencting multi-chain wallets ([dc62af0](https://github.com/rango-exchange/rango-client/commit/dc62af03f0edc10400394ba600c7d83e1250b4e8)) + + + +# [0.31.0](https://github.com/rango-exchange/rango-client/compare/wallets-core@0.30.0...wallets-core@0.31.0) (2024-04-09) + + + +# [0.30.0](https://github.com/rango-exchange/rango-client/compare/wallets-core@0.29.0...wallets-core@0.30.0) (2024-03-12) + + +### Bug Fixes + +* fix wallet connect namespace and switch network ([c8f31b3](https://github.com/rango-exchange/rango-client/commit/c8f31b3ddf4ceeaf745bc089f530b6a4b1eb9637)) + + + +# [0.29.0](https://github.com/rango-exchange/rango-client/compare/wallets-core@0.28.0...wallets-core@0.29.0) (2024-02-20) + + + +# [0.28.0](https://github.com/rango-exchange/rango-client/compare/wallets-core@0.27.0...wallets-core@0.28.0) (2024-02-07) + + + +# [0.27.0](https://github.com/rango-exchange/rango-client/compare/wallets-core@0.26.0...wallets-core@0.27.0) (2024-01-22) + + +### Bug Fixes + +* cleanup wallets' subscriber when setProvider get null ([88d6a42](https://github.com/rango-exchange/rango-client/commit/88d6a423c49b34b3d9ff567e22df36c3b009bb76)) + + + +# [0.26.0](https://github.com/rango-exchange/rango-client/compare/wallets-core@0.24.0...wallets-core@0.26.0) (2023-12-24) + + +### Bug Fixes + +* fix HMR for widget and playground ([8524820](https://github.com/rango-exchange/rango-client/commit/8524820f10cf0b8921f3db0c4f620ff98daa4103)) +* handle safe wallet in widget ([52fcca4](https://github.com/rango-exchange/rango-client/commit/52fcca49315f7e2edb4655ae7b9cd0792c2800d7)) +* handle switch network flow for wallet-connect ([8c4a17b](https://github.com/rango-exchange/rango-client/commit/8c4a17b47b2919820a4e0726f6d1c48b8994abe3)) + + + +# [0.14.0](https://github.com/rango-exchange/rango-client/compare/wallets-core@0.13.0...wallets-core@0.14.0) (2023-08-03) + + + +# [0.13.0](https://github.com/rango-exchange/rango-client/compare/wallets-core@0.12.0...wallets-core@0.13.0) (2023-08-01) + + + +# [0.9.0](https://github.com/rango-exchange/rango-client/compare/wallets-core@0.8.0...wallets-core@0.9.0) (2023-07-31) + + +### Features + +* add project id as a external value ([0c80404](https://github.com/rango-exchange/rango-client/commit/0c80404a8cacb6c5b0338dea1e416b0b11db254b)) +* Support for WalletConnect 2 ([faedef0](https://github.com/rango-exchange/rango-client/commit/faedef0b5e6fc3c5ef881cbbe4ec05334cc1c910)) +* support safe wallet ([d04cbcd](https://github.com/rango-exchange/rango-client/commit/d04cbcd2a612755563512d9dff6f2312088d8b4d)) + + + +# [0.7.0](https://github.com/rango-exchange/rango-client/compare/wallets-core@0.6.0...wallets-core@0.7.0) (2023-07-11) + + + +# [0.6.0](https://github.com/rango-exchange/rango-client/compare/wallets-core@0.5.0...wallets-core@0.6.0) (2023-07-11) + + +### Features + +* implement wallets auto-connect functionality ([f47d32b](https://github.com/rango-exchange/rango-client/commit/f47d32bb8bbb38a72b961e5eb2ee7e2b985f9f7d)) + + +### Reverts + +* Revert "support for rango-types cjs format" ([ed4e050](https://github.com/rango-exchange/rango-client/commit/ed4e050bfc0dcde7aeffa6b0d73b02080a5721eb)) + + + +# [0.5.0](https://github.com/rango-exchange/rango-client/compare/wallets-core@0.4.0...wallets-core@0.5.0) (2023-05-31) + + + +# [0.4.0](https://github.com/rango-exchange/rango-client/compare/wallets-core@0.3.0...wallets-core@0.4.0) (2023-05-31) + + + +# [0.3.0](https://github.com/rango-exchange/rango-client/compare/wallets-core@0.2.0...wallets-core@0.3.0) (2023-05-30) + + + +# [0.2.0](https://github.com/rango-exchange/rango-client/compare/wallets-core@0.1.15...wallets-core@0.2.0) (2023-05-30) + + +### Bug Fixes + +* fix bug of duplicate modals for wallet connect ([efb5482](https://github.com/rango-exchange/rango-client/commit/efb54827fd51e6c6c8f42c6abf33c3d7610755e8)) +* fix can switch network for wallet connect ([e3cdeac](https://github.com/rango-exchange/rango-client/commit/e3cdeacd836e254ea2d5384aab4b624a3e7259eb)) + + + +## [0.1.14](https://github.com/rango-exchange/rango-client/compare/wallets-core@0.1.13...wallets-core@0.1.14) (2023-05-15) + + +### Bug Fixes + +* update rango-types and fix notification bugs ([993f185](https://github.com/rango-exchange/rango-client/commit/993f185e0b8c5e5e15a2c65ba2d85d1f9c8daa90)) + + + diff --git a/wallets/core/legacy/package.json b/wallets/core/legacy/package.json new file mode 100644 index 0000000000..99cafad321 --- /dev/null +++ b/wallets/core/legacy/package.json @@ -0,0 +1,8 @@ +{ + "name": "@rango-dev/wallets-core/legacy", + "type": "module", + "main": "../dist/legacy/mod.js", + "module": "../dist/legacy/mod.js", + "types": "../dist/legacy/mod.d.ts", + "sideEffects": false +} diff --git a/wallets/core/namespaces/common/package.json b/wallets/core/namespaces/common/package.json new file mode 100644 index 0000000000..ffe669f283 --- /dev/null +++ b/wallets/core/namespaces/common/package.json @@ -0,0 +1,8 @@ +{ + "name": "@rango-dev/wallets-core/namespaces/common", + "type": "module", + "main": "../../dist/namespaces/common/mod.js", + "module": "../../dist/namespaces/common/mod.js", + "types": "../../dist/namespaces/common/mod.d.ts", + "sideEffects": false +} diff --git a/wallets/core/namespaces/evm/package.json b/wallets/core/namespaces/evm/package.json new file mode 100644 index 0000000000..c577b311fe --- /dev/null +++ b/wallets/core/namespaces/evm/package.json @@ -0,0 +1,8 @@ +{ + "name": "@rango-dev/wallets-core/namespaces/evm", + "type": "module", + "main": "../../dist/namespaces/evm/mod.js", + "module": "../../dist/namespaces/evm/mod.js", + "types": "../../dist/namespaces/evm/mod.d.ts", + "sideEffects": false +} diff --git a/wallets/core/namespaces/solana/package.json b/wallets/core/namespaces/solana/package.json new file mode 100644 index 0000000000..806e951cbc --- /dev/null +++ b/wallets/core/namespaces/solana/package.json @@ -0,0 +1,8 @@ +{ + "name": "@rango-dev/wallets-core/namespaces/solana", + "type": "module", + "main": "../../dist/namespaces/solana/mod.js", + "module": "../../dist/namespaces/solana/mod.js", + "types": "../../dist/namespaces/solana/mod.d.ts", + "sideEffects": false +} diff --git a/wallets/core/package.json b/wallets/core/package.json index 52e2d28f81..0609d6e72b 100644 --- a/wallets/core/package.json +++ b/wallets/core/package.json @@ -1,52 +1,61 @@ { "name": "@rango-dev/wallets-core", - "version": "0.1.12", + "version": "0.40.1-next.8", "license": "MIT", - "module": "dist/wallets-core.esm.js", - "main": "dist/index.js", - "typings": "dist/index.d.ts", + "type": "module", + "source": "./src/mod.ts", + "main": "./dist/mod.js", + "typings": "./dist/mod.d.ts", + "exports": { + ".": { + "types": "./dist/mod.d.ts", + "default": "./dist/mod.js" + }, + "./legacy": { + "types": "./dist/legacy/mod.d.ts", + "default": "./dist/legacy/mod.js" + }, + "./utils": { + "types": "./dist/utils/mod.d.ts", + "default": "./dist/utils/mod.js" + }, + "./namespaces/common": { + "types": "./dist/namespaces/common/mod.d.ts", + "default": "./dist/namespaces/common/mod.js" + }, + "./namespaces/evm": { + "types": "./dist/namespaces/evm/mod.d.ts", + "default": "./dist/namespaces/evm/mod.js" + }, + "./namespaces/solana": { + "types": "./dist/namespaces/solana/mod.d.ts", + "default": "./dist/namespaces/solana/mod.js" + } + }, "files": [ "dist", - "src" + "src", + "legacy" ], "scripts": { - "start": "tsdx watch", - "build": "tsdx build --tsconfig ./tsconfig.json", - "test": "tsdx test --passWithNoTests", - "lint": "tsdx lint", - "size": "size-limit", - "analyze": "size-limit --why" + "build": "node ../../scripts/build/command.mjs --path wallets/core --inputs src/mod.ts,src/utils/mod.ts,src/legacy/mod.ts,src/namespaces/evm/mod.ts,src/namespaces/solana/mod.ts,src/namespaces/common/mod.ts", + "ts-check": "tsc --declaration --emitDeclarationOnly -p ./tsconfig.json", + "clean": "rimraf dist", + "format": "prettier --write '{.,src}/**/*.{ts,tsx}'", + "lint": "eslint \"**/*.{ts,tsx}\" --ignore-path ../../.eslintignore", + "test": "vitest", + "coverage": "vitest run --coverage" }, "peerDependencies": { "@types/react": "^17.0.0 || ^18.0.0", "react": "^17.0.0 || ^18.0.0", "react-dom": "^17.0.0 || ^18.0.0" }, - "husky": { - "hooks": { - "pre-commit": "tsdx lint" - } - }, - "prettier": { - "printWidth": 80, - "semi": true, - "singleQuote": true, - "trailingComma": "es5" - }, - "size-limit": [ - { - "path": "dist/wallets-core.cjs.production.min.js", - "limit": "10 KB" - }, - { - "path": "dist/wallets-core.esm.js", - "limit": "10 KB" - } - ], "dependencies": { - "@rango-dev/wallets-shared": "^0.1.11", - "@walletconnect/ethereum-provider": "1.8.0", - "rango-types": "^0.1.28" + "caip": "^1.1.1", + "immer": "^10.0.4", + "rango-types": "^0.1.74", + "zustand": "^4.5.2" }, "publishConfig": { "access": "public" diff --git a/wallets/core/readme.md b/wallets/core/readme.md index b95ef394b5..0ed3aff343 100644 --- a/wallets/core/readme.md +++ b/wallets/core/readme.md @@ -1 +1,3 @@ -# @rango-dev/wallets-core \ No newline at end of file +# @rango-dev/wallets-core + +Core package for handling web3 wallets supported by Rango diff --git a/wallets/core/src/builders/action.ts b/wallets/core/src/builders/action.ts new file mode 100644 index 0000000000..fb09246d09 --- /dev/null +++ b/wallets/core/src/builders/action.ts @@ -0,0 +1,86 @@ +import type { Actions, Context, Operators } from '../hub/namespaces/types.js'; +import type { AnyFunction, FunctionWithContext } from '../types/actions.js'; + +export interface ActionByBuilder { + actionName: keyof T; + and: Operators; + or: Operators; + after: Operators; + before: Operators; + action: FunctionWithContext; +} + +/* + * TODO: + * Currently, to use this builder you will write something like this: + * new ActionBuilder('disconnect').after(....) + * + * I couldn't figure it out to be able typescript infer the constructor value as key of actions. + * Ideal usage: + * new ActionBuilder('disconnect').after(....) + * + */ +export class ActionBuilder, K extends keyof T> { + readonly name: K; + #and: Operators = new Map(); + #or: Operators = new Map(); + #after: Operators = new Map(); + #before: Operators = new Map(); + #action: FunctionWithContext> | undefined; + + constructor(name: K) { + this.name = name; + } + + public and(action: FunctionWithContext>) { + if (!this.#and.has(this.name)) { + this.#and.set(this.name, []); + } + this.#and.get(this.name)?.push(action); + return this; + } + + public or(action: FunctionWithContext>) { + if (!this.#or.has(this.name)) { + this.#or.set(this.name, []); + } + this.#or.get(this.name)?.push(action); + return this; + } + + public before(action: FunctionWithContext>) { + if (!this.#before.has(this.name)) { + this.#before.set(this.name, []); + } + this.#before.get(this.name)?.push(action); + return this; + } + + public after(action: FunctionWithContext>) { + if (!this.#after.has(this.name)) { + this.#after.set(this.name, []); + } + this.#after.get(this.name)?.push(action); + return this; + } + + public action(action: FunctionWithContext>) { + this.#action = action; + return this; + } + + public build(): ActionByBuilder> { + if (!this.#action) { + throw new Error('Your action builder should includes an action.'); + } + + return { + actionName: this.name, + action: this.#action, + before: this.#before, + after: this.#after, + and: this.#and, + or: this.#or, + }; + } +} diff --git a/wallets/core/src/builders/mod.ts b/wallets/core/src/builders/mod.ts new file mode 100644 index 0000000000..ce8394e228 --- /dev/null +++ b/wallets/core/src/builders/mod.ts @@ -0,0 +1,5 @@ +export type { ProxiedNamespace, FindProxiedNamespace } from './types.js'; + +export { NamespaceBuilder } from './namespace.js'; +export { ProviderBuilder } from './provider.js'; +export { ActionBuilder } from './action.js'; diff --git a/wallets/core/src/builders/namespace.ts b/wallets/core/src/builders/namespace.ts new file mode 100644 index 0000000000..aeb3e8ae9f --- /dev/null +++ b/wallets/core/src/builders/namespace.ts @@ -0,0 +1,229 @@ +import type { ActionByBuilder } from './action.js'; +import type { ProxiedNamespace } from './types.js'; +import type { Actions, ActionsMap, Context } from '../hub/namespaces/mod.js'; +import type { NamespaceConfig } from '../hub/store/mod.js'; +import type { FunctionWithContext } from '../types/actions.js'; + +import { Namespace } from '../hub/mod.js'; + +/** + * There are Namespace's methods that should be called directly on Proxy object. + * The Proxy object is creating in `.build`. + */ +export const allowedMethods = [ + 'init', + 'state', + 'after', + 'before', + 'and_then', + 'or_else', + 'store', +] as const; + +export class NamespaceBuilder> { + #id: string; + #providerId: string; + #actions: ActionsMap = new Map(); + /* + * We keep a list of `ActionBuilder` outputs here to use them in separate phases. + * Actually, `ActionBuilder` is packing action and its hooks in one place, here we should expand them and them in appropriate places. + * Eventually, action will be added to `#actions` and its hooks will be added to `Namespace`. + */ + #actionBuilders: ActionByBuilder>[] = []; + #configs: NamespaceConfig; + + constructor(id: string, providerId: string) { + this.#id = id; + this.#providerId = providerId; + this.#configs = {}; + } + + /** There are some predefined configs that can be set for each namespace separately */ + public config( + name: K, + value: NamespaceConfig[K] + ) { + this.#configs[name] = value; + return this; + } + + /** + * Getting a list of actions. + * + * e.g.: + * ```ts + * .action([ + * ["connect", () => {}], + * ["disconnect", () => {}] + * ]) + * ``` + * + */ + public action( + action: (readonly [K, FunctionWithContext>])[] + ): NamespaceBuilder; + + /** + * + * Add a single action + * + * e.g.: + * ```ts + * .action( ["connect", () => {}] ) + * ``` + */ + public action( + action: K, + actionFn: FunctionWithContext> + ): NamespaceBuilder; + + public action(action: ActionByBuilder>): NamespaceBuilder; + + /** + * + * Actions are piece of functionality that a namespace can have, for example it can be a `connect` function + * or a sign function or even a function for updating namespace's internal state. Actions are flexible and can be anything. + * + * Generally, each standard namespace (e.g. evm) has an standard interface defined in `src/namespaces/` + * and provider (which includes namespaces) authors will implement those actions. + * + * You can call this function by a list of actions or a single action. + * + */ + public action( + action: (readonly [K, FunctionWithContext>])[] | K, + actionFn?: FunctionWithContext> + ) { + // List mode + if (Array.isArray(action)) { + action.forEach(([name, actionFnForItem]) => { + this.#actions.set(name, actionFnForItem); + }); + return this; + } + + // Action builder mode + + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + if (typeof action === 'object' && !!action?.actionName) { + this.#actionBuilders.push(action); + return this; + } + + // Single action mode + if (!!actionFn) { + this.#actions.set(action, actionFn); + } + + return this; + } + + /** + * By calling build, an instance of Namespace will be built. + * + * Note: it's not exactly a `Namespace`, it returns a Proxy which add more convenient use like `namespace.connect()` instead of `namespace.run("connect")` + */ + public build(): ProxiedNamespace { + if (this.#isConfigsValid(this.#configs)) { + return this.#buildApi(this.#configs); + } + + throw new Error(`You namespace config isn't valid.`); + } + + // Currently, namespace doesn't has any config. + #isConfigsValid(_config: NamespaceConfig): boolean { + return true; + } + + /* + * Extracting hooks and add them to `Namespace` for the action. + * + * Note: this should be called after `addActionsFromActionBuilders` to ensure the action is added first. + */ + #addHooksFromActionBuilders(namespace: Namespace) { + this.#actionBuilders.forEach((actionByBuild) => { + actionByBuild.after.forEach((afterHooks) => { + afterHooks.map((action) => { + namespace.after(actionByBuild.actionName, action); + }); + }); + + actionByBuild.before.forEach((beforeHooks) => { + beforeHooks.map((action) => { + namespace.before(actionByBuild.actionName, action); + }); + }); + + actionByBuild.and.forEach((andHooks) => { + andHooks.map((action) => { + namespace.and_then(actionByBuild.actionName, action); + }); + }); + + actionByBuild.or.forEach((orHooks) => { + orHooks.map((action) => { + namespace.or_else(actionByBuild.actionName, action); + }); + }); + }); + } + + /** + * Iterate over `actionBuilders` and add them to exists `actions`. + * Note: Hooks will be added in a separate phase. + */ + #addActionsFromActionBuilders() { + this.#actionBuilders.forEach((actionByBuild) => { + this.#actions.set(actionByBuild.actionName, actionByBuild.action); + }); + } + + /** + * Build a Proxy object to call actions in a more convenient way. e.g `.connect()` instead of `.run(connect)` + */ + #buildApi(configs: NamespaceConfig): ProxiedNamespace { + this.#addActionsFromActionBuilders(); + const namespace = new Namespace(this.#id, this.#providerId, { + configs, + actions: this.#actions, + }); + this.#addHooksFromActionBuilders(namespace); + + const api = new Proxy(namespace, { + get: (_, property) => { + if (typeof property !== 'string') { + throw new Error( + 'You can use string as your property on Namespace instance.' + ); + } + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore-next-line + const targetValue = namespace[property]; + + if ( + allowedMethods.includes(property as (typeof allowedMethods)[number]) + ) { + return targetValue.bind(namespace); + } + + /* + * This is useful accessing values like `version`, If we don't do this, we should whitelist + * All the values as well, So it can be confusing for someone that only wants to add a public value to `Namespace` + */ + const allowedPublicValues = ['string', 'number']; + if (allowedPublicValues.includes(typeof targetValue)) { + return targetValue; + } + + return namespace.run.bind(namespace, property as keyof T); + }, + set: () => { + throw new Error('You can not set anything on this object.'); + }, + }); + + return api as unknown as ProxiedNamespace; + } +} diff --git a/wallets/core/src/builders/provider.ts b/wallets/core/src/builders/provider.ts new file mode 100644 index 0000000000..0e6646c05a --- /dev/null +++ b/wallets/core/src/builders/provider.ts @@ -0,0 +1,61 @@ +import type { FindProxiedNamespace } from './types.js'; +import type { + CommonNamespaces, + ExtendableInternalActions, + ProviderBuilderOptions, +} from '../hub/provider/mod.js'; +import type { ProviderConfig } from '../hub/store/mod.js'; + +import { Provider } from '../hub/provider/mod.js'; + +export class ProviderBuilder { + #id: string; + #namespaces = new Map(); + #methods: ExtendableInternalActions = {}; + #configs: Partial = {}; + #options: Partial; + + constructor(id: string, options?: ProviderBuilderOptions) { + this.#id = id; + this.#options = options || {}; + } + + public add( + id: K, + namespace: FindProxiedNamespace + ) { + if (this.#options.store) { + namespace.store(this.#options.store); + } + this.#namespaces.set(id, namespace); + return this; + } + + public config( + name: K, + value: ProviderConfig[K] + ) { + this.#configs[name] = value; + return this; + } + + public init(cb: Exclude) { + this.#methods.init = cb; + return this; + } + + public build(): Provider { + if (this.#isConfigsValid(this.#configs)) { + return new Provider(this.#id, this.#namespaces, this.#configs, { + extendInternalActions: this.#methods, + store: this.#options.store, + }); + } + + throw new Error('You need to set all required configs.'); + } + + #isConfigsValid(config: Partial): config is ProviderConfig { + return !!config.info; + } +} diff --git a/wallets/core/src/builders/types.ts b/wallets/core/src/builders/types.ts new file mode 100644 index 0000000000..a70cf9fc04 --- /dev/null +++ b/wallets/core/src/builders/types.ts @@ -0,0 +1,29 @@ +import type { allowedMethods } from './namespace.js'; +import type { Actions, Namespace } from '../hub/namespaces/mod.js'; + +// These should be matched with `/hub/namespace.ts` public values. +type NamespacePublicValues = { + namespaceId: string; + providerId: string; +}; + +/** + * NamespaceBuilder is creating a proxy instead of return Namespace instance. + * The reason is improving access to actions. e.g `.connect()` instead of `.run('connect')` + */ +export type ProxiedNamespace> = T & + Pick, (typeof allowedMethods)[number]> & + NamespacePublicValues; + +/** + * This is useful when you gave a list of namespaces and want to map a key to corresponding namespace. + * + * e.g: + * Type List = { evm: EvmActions, solana: SolanaActions}; + * FindProxiedNamespace<"solana", List> + */ +export type FindProxiedNamespace = T[K] extends Actions< + T[K] +> + ? ProxiedNamespace + : never; diff --git a/wallets/core/src/helpers.ts b/wallets/core/src/helpers.ts deleted file mode 100644 index e568a3f048..0000000000 --- a/wallets/core/src/helpers.ts +++ /dev/null @@ -1,150 +0,0 @@ -import WalletConnectProvider from '@walletconnect/ethereum-provider'; -import { - convertEvmBlockchainMetaToEvmChainInfo, - evmChainsToRpcMap, - Network, - WalletType, -} from '@rango-dev/wallets-shared'; -import { State, WalletProvider, WalletProviders } from './types'; -import { Options, State as WalletState } from './wallet'; -import { BlockchainMeta, isEvmBlockchain } from 'rango-types'; - -export function choose(wallets: any[], type: WalletType): any | null { - return wallets.find((wallet) => wallet.type === type) || null; -} - -export const defaultWalletState: WalletState = { - connected: false, - connecting: false, - reachable: false, - installed: false, - accounts: null, - network: null, -}; - -export function state_reducer(state: State, action: any) { - if (action.type === 'new_state') { - // TODO fix problem and remove ts-ignore - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore - const target_wallet = state[action.wallet]; - if (!target_wallet) { - return { - ...state, - [action.wallet]: { - ...defaultWalletState, - [action.name]: action.value, - }, - }; - } - - return { - ...state, - [action.wallet]: { - ...target_wallet, - [action.name]: action.value, - }, - }; - } - - return state; -} - -export function formatAddressWithNetwork( - address: string, - network?: Network | null -) { - return `${network || ''}:${address}`; -} - -export function accountAddressesWithNetwork( - addresses: string[] | null, - network?: Network | null -) { - if (!addresses) return []; - - return addresses.map((address) => { - return formatAddressWithNetwork(address, network); - }); -} - -export function readAccountAddress(addressWithNetwork: string): { - address: string; - network: Network; -} { - const [network, address] = addressWithNetwork.split(':'); - - return { - network: network as Network, - address, - }; -} - -export function connectedWallets(providersState: State): WalletType[] { - return Object.entries(providersState) - .filter(([, wallet_state]) => { - return wallet_state?.connected; - }) - .map(([type]) => { - return type as WalletType; - }); -} - -export function availableWallets(providersState: State): WalletType[] { - return Object.entries(providersState).map(([type]) => { - return type as WalletType; - }); -} - -export function checkWalletProviders(list: WalletProvider[]): WalletProviders { - const wallets: WalletProviders = new Map(); - - list.forEach((provider) => { - const { config, ...actions } = provider; - wallets.set(config.type, { - actions, - config, - }); - }); - - return wallets; -} - -/* eslint-disable @typescript-eslint/ban-types */ -export function isAsync(fn: Function) { - return fn?.constructor?.name === 'AsyncFunction'; -} - -export function needsCheckInstallation(options: Options) { - const { checkInstallation = true } = options.config; - return checkInstallation; -} - -/* - WalletConnect instance is not compatible with ethers.providers.Web3Provider, - Here we are returning a comptable instance, instead of the original one. -*/ - -export function isWalletDerivedFromWalletConnect(wallet_type: WalletType) { - return wallet_type === WalletType.WALLET_CONNECT; -} - -export function getComptaibleProvider( - supportedChains: BlockchainMeta[], - provider: any, - type: WalletType -) { - if (isWalletDerivedFromWalletConnect(type)) { - const evmBlockchains = supportedChains.filter(isEvmBlockchain); - const rpcUrls = evmChainsToRpcMap( - convertEvmBlockchainMetaToEvmChainInfo(evmBlockchains) - ); - return new WalletConnectProvider({ - qrcode: false, - rpc: rpcUrls, - connector: provider, - chainId: provider.chainId, - }); - } - return provider; -} diff --git a/wallets/core/src/hub/helpers.ts b/wallets/core/src/hub/helpers.ts new file mode 100644 index 0000000000..f0c0dfc9a8 --- /dev/null +++ b/wallets/core/src/hub/helpers.ts @@ -0,0 +1,11 @@ +/** + * Note: This only works native async, if we are going to support for old transpilers like Babel. + */ +// eslint-disable-next-line @typescript-eslint/ban-types +export function isAsync(fn: Function) { + return fn.constructor.name === 'AsyncFunction'; +} + +export function generateStoreId(providerId: string, namespace: string) { + return `${providerId}$$${namespace}`; +} diff --git a/wallets/core/src/hub/hub.ts b/wallets/core/src/hub/hub.ts new file mode 100644 index 0000000000..4fac1e4e9f --- /dev/null +++ b/wallets/core/src/hub/hub.ts @@ -0,0 +1,115 @@ +import type { Namespace, State as NamespaceState } from './namespaces/mod.js'; +import type { Provider, State as ProviderState } from './provider/mod.js'; +import type { Store } from './store/mod.js'; + +type HubState = { + [key in string]: ProviderState & { + namespaces: NamespaceState[]; + }; +}; + +type RunAllResult = { + id: string; + provider: unknown; + namespaces: unknown[]; +}; + +interface HubOptions { + store?: Store; +} +export class Hub { + #providers = new Map(); + #options: HubOptions; + + constructor(options?: HubOptions) { + this.#options = options ?? {}; + } + + init() { + this.runAll('init'); + } + + /* + * Running a specific action (e.g. init) on all namespaces and providers one by one. + * + * TODO: Some of methods may accepts args, with this implementation we only limit to those one without any argument. + */ + runAll(action: string): RunAllResult[] { + const output: RunAllResult[] = []; + + // run action on all providers eagerConnect, disconnect + const providers = this.#providers.values(); + + for (const provider of providers) { + // Calling `action` on `Provider` if exists. + const providerOutput: RunAllResult = { + id: provider.id, + provider: undefined, + namespaces: [], + }; + + const providerMethod = provider[action as keyof Provider]; + if (typeof providerMethod === 'function') { + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore-next-line + providerOutput.provider = providerMethod.call(provider); + } + + // Namespace instances can have their own `action` as well. we will call them as well. + const namespaces = provider.getAll().values(); + for (const namespace of namespaces) { + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore-next-line + const namespaceMethod = namespace[action]; + if (typeof namespaceMethod === 'function') { + const result = namespaceMethod(); + providerOutput.namespaces.push(result); + } + } + + output.push(providerOutput); + } + + return output; + } + + add(id: string, provider: Provider) { + if (this.#options.store) { + provider.store(this.#options.store); + } + this.#providers.set(id, provider); + return this; + } + + get(providerId: string): Provider | undefined { + return this.#providers.get(providerId); + } + + getAll() { + return this.#providers; + } + + state(): HubState { + const output = this.runAll('state'); + const res: HubState = {}; + + output.forEach((result) => { + const namespaces: NamespaceState[] = []; + result.namespaces.forEach((b) => { + const [getNamespaceState] = b as ReturnType['state']>; + + namespaces.push(getNamespaceState()); + }); + + const [getProviderState] = result.provider as ReturnType< + Provider['state'] + >; + + res[result.id] = { + ...(getProviderState() || {}), + namespaces: namespaces, + }; + }); + return res; + } +} diff --git a/wallets/core/src/hub/mod.ts b/wallets/core/src/hub/mod.ts new file mode 100644 index 0000000000..4b014aef7d --- /dev/null +++ b/wallets/core/src/hub/mod.ts @@ -0,0 +1,13 @@ +export { Namespace } from './namespaces/mod.js'; + +export { Provider } from './provider/mod.js'; +export type { CommonNamespaces, CommonNamespaceKeys } from './provider/mod.js'; + +export { Hub } from './hub.js'; +export type { Store, State, ProviderInfo } from './store/mod.js'; +export { + createStore, + guessProviderStateSelector, + namespaceStateSelector, +} from './store/mod.js'; +export { generateStoreId } from './helpers.js'; diff --git a/wallets/core/src/hub/namespaces/errors.ts b/wallets/core/src/hub/namespaces/errors.ts new file mode 100644 index 0000000000..dba48628ea --- /dev/null +++ b/wallets/core/src/hub/namespaces/errors.ts @@ -0,0 +1,8 @@ +export const ACTION_NOT_FOUND_ERROR = (name: string) => + `Couldn't find "${name}" action. Are you sure you've added the action?`; + +export const OR_ELSE_ACTION_FAILED_ERROR = (name: string) => + `An error occurred during running ${name}`; + +export const NO_STORE_FOUND_ERROR = + 'For setup store, you should set `store` first.'; diff --git a/wallets/core/src/hub/namespaces/mod.ts b/wallets/core/src/hub/namespaces/mod.ts new file mode 100644 index 0000000000..0e7f4d1a39 --- /dev/null +++ b/wallets/core/src/hub/namespaces/mod.ts @@ -0,0 +1,9 @@ +export type { + Subscriber, + State, + RegisteredActions as ActionsMap, + Context, + Actions, +} from './types.js'; + +export { Namespace } from './namespace.js'; diff --git a/wallets/core/src/hub/namespaces/namespace.test.ts b/wallets/core/src/hub/namespaces/namespace.test.ts new file mode 100644 index 0000000000..e779faca82 --- /dev/null +++ b/wallets/core/src/hub/namespaces/namespace.test.ts @@ -0,0 +1,333 @@ +import { describe, expect, test, vi } from 'vitest'; + +import { createStore } from '../mod.js'; + +import { OR_ELSE_ACTION_FAILED_ERROR } from './errors.js'; +import { Namespace } from './namespace.js'; + +interface TestNamespaceActions { + connect: () => void; + disconnect: () => void; +} + +describe('check initializing Namespace', () => { + const NAMESPACE = 'evm'; + const PROVIDER_ID = 'garbage provider'; + + test('initialize a namespace and run an action', () => { + const connect = vi.fn(); + const disconnect = vi.fn(); + const actions = new Map(); + actions.set('connect', connect); + actions.set('disconnect', disconnect); + + const ns = new Namespace(NAMESPACE, PROVIDER_ID, { + actions: actions, + }); + + ns.run('connect'); + + expect(disconnect).toBeCalledTimes(0); + expect(connect).toBeCalledTimes(1); + }); + + test('init action should be called once', () => { + const connect = vi.fn(); + const disconnect = vi.fn(); + const init = vi.fn(); + const actions = new Map(); + actions.set('connect', connect); + actions.set('disconnect', disconnect); + actions.set('init', init); + + const ns = new Namespace(NAMESPACE, PROVIDER_ID, { + actions: actions, + }); + + expect(init).toBeCalledTimes(0); + + ns.run('connect'); + ns.init(); + ns.init(); + + expect(disconnect).toBeCalledTimes(0); + expect(connect).toBeCalledTimes(1); + expect(init).toBeCalledTimes(1); + }); + + test('state should be updated and actions have access to them', () => { + const connect = vi.fn((context) => { + const [, setState] = context.state(); + setState('connected', true); + }); + const init = vi.fn((context) => { + const [, setState] = context.state(); + setState('connecting', true); + }); + const actions = new Map(); + actions.set('connect', connect); + actions.set('init', init); + + const store = createStore(); + const ns = new Namespace(NAMESPACE, PROVIDER_ID, { + actions: actions, + store, + }); + + ns.run('connect'); + ns.init(); + ns.init(); + + const [currentState] = ns.state(); + expect(currentState().connected).toBe(true); + expect(currentState('connecting')).toBe(true); + }); + + test("throw an error if store doesn't set", () => { + const ns = new Namespace(NAMESPACE, PROVIDER_ID, { + actions: new Map(), + }); + + expect(() => ns.state()).toThrowError(); + }); +}); + +describe('check actions with hooks and operators', () => { + const NAMESPACE = 'bip122'; + const PROVIDER_ID = 'garbage provider'; + + test('add actions and run them.', () => { + const actions = new Map(); + actions.set('hello', () => 'hello world'); + actions.set('bye', () => 'bye bye'); + actions.set('chainable', () => "it's also chainable"); + actions.set('chain2', () => "it's also chainable"); + + const ns = new Namespace<{ + hello: () => string; + bye: () => string; + chainable: () => void; + chain2: () => void; + }>(NAMESPACE, PROVIDER_ID, { actions }); + + expect(ns.run('hello')).toBe('hello world'); + expect(ns.run('bye')).toBe('bye bye'); + + expect(() => { + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore-next-line + return ns.run('some_action_name_that_has_not_added'); + }).toThrowError(); + }); + + test('should be called before/after target action correctly even with multiple hook assigned to an action name', () => { + const beforeAction = vi.fn(); + const anotherBeforeAction = vi.fn(); + const afterAction = vi.fn(); + const anotherAfterAction = vi.fn(); + const connectAction = vi.fn(); + const disconnectAction = vi.fn(); + + const actions = new Map(); + actions.set('connect', connectAction); + actions.set('disconnect', disconnectAction); + + const ns = new Namespace(NAMESPACE, PROVIDER_ID, { + actions, + }); + + ns.run('connect'); + expect(connectAction).toBeCalledTimes(1); + expect(beforeAction).toBeCalledTimes(0); + expect(anotherBeforeAction).toBeCalledTimes(0); + expect(afterAction).toBeCalledTimes(0); + expect(anotherAfterAction).toBeCalledTimes(0); + + ns.before('connect', beforeAction); + ns.before('connect', anotherBeforeAction); + ns.run('connect'); + expect(connectAction).toBeCalledTimes(2); + expect(beforeAction).toBeCalledTimes(1); + expect(anotherBeforeAction).toBeCalledTimes(1); + expect(afterAction).toBeCalledTimes(0); + expect(anotherAfterAction).toBeCalledTimes(0); + + ns.after('connect', afterAction); + ns.after('connect', anotherAfterAction); + ns.run('connect'); + expect(beforeAction).toBeCalledTimes(2); + expect(anotherBeforeAction).toBeCalledTimes(2); + expect(afterAction).toBeCalledTimes(1); + expect(anotherAfterAction).toBeCalledTimes(1); + }); + + test('should call `and_then` sequentially.', () => { + const andActionFirst = vi.fn((_ctx, result) => result + 1); + const andActionSecond = vi.fn((_ctx, result) => result + 1); + + const connectAction = vi.fn(() => 0); + const disconnectAction = vi.fn(); + + const actions = new Map(); + actions.set('connect', connectAction); + actions.set('disconnect', disconnectAction); + + const ns = new Namespace(NAMESPACE, PROVIDER_ID, { + actions: actions, + }); + ns.and_then('connect', andActionFirst); + ns.and_then('connect', andActionSecond); + + const result = ns.run('connect'); + + expect(connectAction).toBeCalledTimes(1); + expect(andActionFirst).toBeCalledTimes(1); + expect(andActionSecond).toBeCalledTimes(1); + + expect(result).toBe(2); + + ns.run('connect'); + expect(connectAction).toBeCalledTimes(2); + expect(andActionFirst).toBeCalledTimes(2); + expect(andActionSecond).toBeCalledTimes(2); + }); + + test("shouldn't run other `and_then` hooks if one of them fails then fallback to `or_else`.", () => { + const andActionFirst = vi.fn((_ctx, _result) => { + throw new Error('Oops!'); + }); + const andActionSecond = vi.fn((_ctx, result) => result + 1); + + const orAction = vi.fn((_ctx, e) => e instanceof Error); + + const connectAction = vi.fn(() => 0); + const actions = new Map(); + actions.set('connect', connectAction); + + const ns = new Namespace<{ + connect: () => void; + }>(NAMESPACE, PROVIDER_ID, { + actions: actions, + configs: {}, + }); + ns.and_then('connect', andActionFirst); + ns.and_then('connect', andActionSecond); + + ns.or_else('connect', orAction); + + const result = ns.run('connect'); + + expect(connectAction).toBeCalledTimes(1); + expect(andActionFirst).toBeCalledTimes(1); + expect(andActionSecond).toBeCalledTimes(0); + expect(orAction).toBeCalledTimes(1); + expect(result).toBe(true); + }); + + test('should throw error if there are no `or` to handle error', () => { + const andActionFirst = vi.fn((_ctx, _result) => { + throw new Error('Oops!'); + }); + const andActionSecond = vi.fn((_ctx, result) => result + 1); + + const connectAction = vi.fn(() => 0); + const actions = new Map(); + actions.set('connect', connectAction); + + const ns = new Namespace<{ + connect: () => void; + }>(NAMESPACE, PROVIDER_ID, { + actions: actions, + configs: {}, + }); + + ns.and_then('connect', andActionFirst); + ns.and_then('connect', andActionSecond); + + expect(() => ns.run('connect')).toThrowError(); + }); + + test('ensure `or_else` has access to error', () => { + const actions = new Map(); + actions.set('connect', () => { + throw new Error('Oops!'); + }); + + const ns = new Namespace<{ + connect: () => void; + }>(NAMESPACE, PROVIDER_ID, { + actions: actions, + configs: {}, + }); + + ns.or_else('connect', (_ctx: any, err: any) => { + return err instanceof Error; + }); + + const result = ns.run('connect'); + expect(result).toBe(true); + }); + + test('should call `or_else` sequentially.', () => { + const orActionFirst = vi.fn((_ctx, _err) => 1); + const orActionSecond = vi.fn((_ctx, _err) => _err + 1); + + const connectAction = vi.fn(() => { + throw new Error('Oops!'); + }); + + const actions = new Map(); + actions.set('connect', connectAction); + + const ns = new Namespace<{ + connect: () => void; + }>(NAMESPACE, PROVIDER_ID, { + actions: actions, + }); + + ns.or_else('connect', orActionFirst); + ns.or_else('connect', orActionSecond); + + const result = ns.run('connect'); + + expect(connectAction).toBeCalledTimes(1); + expect(orActionFirst).toBeCalledTimes(1); + expect(orActionSecond).toBeCalledTimes(1); + + expect(result).toBe(2); + + ns.run('connect'); + expect(connectAction).toBeCalledTimes(2); + expect(orActionFirst).toBeCalledTimes(2); + expect(orActionSecond).toBeCalledTimes(2); + }); + test('throw error if `or_else` itself failed to run.', () => { + const orActionFirst = vi.fn((_ctx, _err) => 1); + const orActionSecond = vi.fn((_ctx, _err) => { + throw new Error('This is actually a bad situation'); + }); + + const connectAction = vi.fn(() => { + throw new Error('Oops!'); + }); + + const actions = new Map(); + actions.set('connect', connectAction); + + const ns = new Namespace<{ + connect: () => void; + }>(NAMESPACE, PROVIDER_ID, { + actions: actions, + }); + + ns.or_else('connect', orActionFirst); + ns.or_else('connect', orActionSecond); + + expect(() => { + ns.run('connect'); + }).toThrowError(OR_ELSE_ACTION_FAILED_ERROR('connect')); + expect(orActionFirst).toBeCalledTimes(1); + expect(connectAction).toBeCalledTimes(1); + expect(orActionSecond).toBeCalledTimes(1); + }); +}); diff --git a/wallets/core/src/hub/namespaces/namespace.ts b/wallets/core/src/hub/namespaces/namespace.ts new file mode 100644 index 0000000000..76487ca474 --- /dev/null +++ b/wallets/core/src/hub/namespaces/namespace.ts @@ -0,0 +1,446 @@ +import type { + Actions, + Context, + GetState, + HooksWithOptions, + Operators, + RegisteredActions, + SetState, + State, +} from './types.js'; +import type { + AndFunction, + AnyFunction, + FunctionWithContext, +} from '../../types/actions.js'; +import type { NamespaceConfig, Store } from '../store/mod.js'; + +import { generateStoreId, isAsync } from '../helpers.js'; + +import { + ACTION_NOT_FOUND_ERROR, + NO_STORE_FOUND_ERROR, + OR_ELSE_ACTION_FAILED_ERROR, +} from './errors.js'; + +/** + * + * A Namespace is a unit of wallets where usually handles connecting, signing, accounts, ... + * It will be injected by wallet in its object, for example, `window.phantom.ethereum` or `window.phantom.solana` + * Each namespace (like solana) has its own functionality which is not shared between all the blockchains. + * For example in EVM namespaces, you can have different networks (e.g. Ethereum,Polygon, ...) and there are specific flows to handle connecting to them or add a network and etc. + * But Solana doesn't have this concept and you will directly always connect to solana itself. + * This is true for signing a transaction, getting information about blockchain and more. + * So by creating a namespace for each of these, we can define a custom namespace based on blockchain's properties. + * + */ +class Namespace> { + /** it will be used for `store` and accessing to store by its id mainly. */ + public readonly namespaceId: string; + /** it will be used for `store` and accessing to store by its id mainly. */ + public readonly providerId: string; + + #actions: RegisteredActions; + #andOperators: Operators = new Map(); + #orOperators: Operators = new Map(); + // `context` for these two can be Namespace context or Provider context + #beforeHooks: HooksWithOptions = new Map(); + #afterHooks: HooksWithOptions = new Map(); + + #initiated = false; + #store: Store | undefined; + // Namespace doesn't has any configs now, but we will need the feature in future + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore noUnusedParameters + #configs: NamespaceConfig; + + constructor( + id: string, + providerId: string, + options: { + store?: Store; + configs?: NamespaceConfig; + actions: RegisteredActions; + } + ) { + const { configs, actions } = options; + + this.namespaceId = id; + this.providerId = providerId; + + this.#configs = configs || new Map(); + this.#actions = actions; + + if (options.store) { + this.store(options.store); + } + } + + /** + * This is an special action that will be called **only once**. + * We don't call this in `constructor` and developer should call this manually. we only ensure it will be called once. + * + * ```ts + * const myInit = () => { whatever; } + * const actions = new Map(); + * actions.set("init", myInit) + * const ns = new Namespace(..., {actions}); + * + * // Will run `myInit` + * ns.init() + * + * // Will not run `myInit` anymore. + * ns.init() + * ns.init() + * ``` + */ + public init(): void { + if (this.#initiated) { + return; + } + + const definedInitByUser = this.#actions.get('init'); + + if (definedInitByUser) { + definedInitByUser(this.#context()); + } + // else, this namespace doesn't have any `init` implemented. + + this.#initiated = true; + } + + /** + * Reading states from store and also update them. + * + * @example + * ```ts + * const ns = new Namespace(...); + * const [getState, setState] = ns.state(); + * ``` + */ + public state(): [GetState, SetState] { + const store = this.#store; + if (!store) { + throw new Error( + 'You need to set your store using `.store` method first.' + ); + } + + const id = this.#storeId(); + const setState: SetState = (name, value) => { + store.getState().namespaces.updateStatus(id, name, value); + }; + + const getState: GetState = (name?: K) => { + const state: State = store.getState().namespaces.getNamespaceData(id); + + if (!name) { + return state; + } + + return state[name]; + }; + + return [getState, setState]; + } + + /** + * For keeping state, we need a store. all the states will be write to/read from store. + * + * Note: Store can be setup on constructor as well. + * + * @example + * ```ts + * const myStore = createStore(); + * const ns = new Namespace(...); + * ns.store(myStore); + * ``` + */ + public store(store: Store): this { + if (this.#store) { + console.warn( + "You've already set an store for your Namespace. Old store will be replaced by the new one." + ); + } + this.#store = store; + this.#setupStore(); + + return this; + } + + /** + * It's a boolean operator to run a sync function if action ran successfully. + * For example, if we have a `connect` action, we can add function to be run after `connect` if it ran successfully. + * + * @example + * ```ts + * const ns = new Namespace(..); + * + * ns.and_then('connect', (context) => { + * ... + * }); + * ``` + * + */ + public and_then( + actionName: K, + operatorFn: FunctionWithContext, Context> + ): this { + const currentAndOperators = this.#andOperators.get(actionName) || []; + this.#andOperators.set(actionName, currentAndOperators.concat(operatorFn)); + + return this; + } + + /** + * It's a boolean operator to run a function to handle when an action fails. + * For example, if we have a `connect` action, we can add function to be run when `connect` fails (throw an error). + * + * @example + * ```ts + * const ns = new Namespace(..); + * + * ns.or_else('connect', (context, error) => { + * ... + * }); + * ``` + */ + public or_else( + actionName: K, + operatorFn: FunctionWithContext + ): this { + const currentOrOperators = this.#orOperators.get(actionName) || []; + this.#orOperators.set(actionName, currentOrOperators.concat(operatorFn)); + + return this; + } + + /** + * Running a function after a specific action + * + * Note: the context can be set from outside as well. this is useful for Provider to set its context instead of namespace context. + * + * @example + * ```ts + * const ns = new Namespace(...); + * + * ns.after("connect", (context) => {}); + * ``` + */ + public after( + actionName: K, + hook: FunctionWithContext, + options?: { context?: C } + ): this { + const currentAfterHooks = this.#afterHooks.get(actionName) || []; + const hookWithOptions = { + hook, + options: { + context: options?.context, + }, + }; + + this.#afterHooks.set(actionName, currentAfterHooks.concat(hookWithOptions)); + return this; + } + + /** + * Running a function before a specific action + * + * Note: the context can be set from outside as well. this is useful for Provider to set its context instead of using namespace context. + * + * @example + * ```ts + * const ns = new Namespace(...); + * + * ns.before("connect", (context) => {}); + * ``` + */ + public before( + actionName: K, + hook: FunctionWithContext, + options?: { context?: C } + ): this { + const currentBeforeHooks = this.#beforeHooks.get(actionName) || []; + const hookWithOptions = { + hook, + options: { + context: options?.context, + }, + }; + this.#beforeHooks.set( + actionName, + currentBeforeHooks.concat(hookWithOptions) + ); + + return this; + } + + /** + * + * Registered actions will be called using `run`. it will run an action and all the operators or hooks that assigned. + * + * @example + * ```ts + * const actions = new Map(); + * actions.set('connect', connectAction); + * + * const ns = new Namespace(NAMESPACE, PROVIDER_ID, { + * actions: actions, + * }); + * + * ns.run("action"); + * ``` + */ + public run( + actionName: K, + ...args: any[] + ): unknown | Promise { + const action = this.#actions.get(actionName); + if (!action) { + throw new Error(ACTION_NOT_FOUND_ERROR(actionName.toString())); + } + + /* + * Action can be both, sync or async. To simplify the process we can not make `sync` mode to async + * Since every user's sync action will be an async function and affect what user expect, + * it makes all the actions async and it doesn't match with Namespace interface (e.g. EvmActions) + * + * To avoid this issue and also not duplicating code, I broke the process into smaller methods + * and two main methods to run actions: tryRunAsyncAction & tryRunAction. + */ + const result = isAsync(action) + ? this.#tryRunAsyncAction(actionName, args) + : this.#tryRunAction(actionName, args); + + return result; + } + + #tryRunAction(actionName: K, params: any[]): unknown { + this.#tryRunBeforeHooks(actionName); + + const action = this.#actions.get(actionName); + if (!action) { + throw new Error(ACTION_NOT_FOUND_ERROR(actionName.toString())); + } + + const context = this.#context(); + + let result; + try { + result = action(context, ...params); + result = this.#tryRunAndOperators(actionName, result); + } catch (e) { + result = this.#tryRunOrOperators(actionName, e); + } finally { + this.#tryRunAfterHooks(actionName); + } + + return result; + } + + async #tryRunAsyncAction( + actionName: K, + params: any[] + ): Promise { + this.#tryRunBeforeHooks(actionName); + + const action = this.#actions.get(actionName); + if (!action) { + throw new Error(ACTION_NOT_FOUND_ERROR(actionName.toString())); + } + + const context = this.#context(); + return await action(context, ...params) + .then((result: unknown) => this.#tryRunAndOperators(actionName, result)) + .catch((e: unknown) => this.#tryRunOrOperators(actionName, e)) + .finally(() => this.#tryRunAfterHooks(actionName)); + } + + #tryRunAfterHooks(actionName: K) { + const afterActions = this.#afterHooks.get(actionName); + + if (afterActions) { + afterActions.forEach((afterAction) => { + const context = afterAction.options?.context || this.#context(); + afterAction.hook(context); + }); + } + } + + #tryRunBeforeHooks(actionName: K): void { + const beforeActions = this.#beforeHooks.get(actionName); + if (beforeActions) { + beforeActions.forEach((beforeAction) => { + const context = beforeAction.options?.context || this.#context(); + beforeAction.hook(context); + }); + } + } + + #tryRunAndOperators( + actionName: K, + result: unknown + ): unknown { + const andActions = this.#andOperators.get(actionName); + + if (andActions) { + const context = this.#context(); + result = andActions.reduce((prev, andAction) => { + return andAction(context, prev); + }, result); + } + return result; + } + + #tryRunOrOperators( + actionName: K, + actionError: unknown + ): unknown { + const orActions = this.#orOperators.get(actionName); + + if (orActions) { + try { + const context = this.#context(); + return orActions.reduce((prev, orAction) => { + return orAction(context, prev); + }, actionError); + } catch (orError) { + const errorMessage = OR_ELSE_ACTION_FAILED_ERROR( + `${actionName.toString()} for ${this.namespaceId} namespace.` + ); + throw new Error(errorMessage, { + cause: actionError, + }); + } + } else { + throw actionError; + } + } + + #setupStore(): void { + const store = this.#store; + if (!store) { + throw new Error(NO_STORE_FOUND_ERROR); + } + + const id = this.#storeId(); + store.getState().namespaces.addNamespace(id, { + namespaceId: this.namespaceId, + providerId: this.providerId, + }); + } + + #storeId() { + return generateStoreId(this.providerId, this.namespaceId); + } + + #context(): Context { + return { + state: this.state.bind(this), + action: this.run.bind(this), + }; + } +} + +export { Namespace }; diff --git a/wallets/core/src/hub/namespaces/types.ts b/wallets/core/src/hub/namespaces/types.ts new file mode 100644 index 0000000000..7d4df3f1df --- /dev/null +++ b/wallets/core/src/hub/namespaces/types.ts @@ -0,0 +1,50 @@ +import type { AnyFunction, FunctionWithContext } from '../../types/actions.js'; +import type { NamespaceData } from '../store/mod.js'; + +type ActionName = K | Omit; + +export type Subscriber> = ( + context: Context, + ...args: any[] +) => void; +export type SubscriberCleanUp> = ( + context: Context, + ...args: any[] +) => void; +export type State = NamespaceData; +export type SetState = ( + name: K, + value: State[K] +) => void; +export type GetState = { + (): State; + (name: K): State[K]; +}; +export type RegisteredActions> = Map< + ActionName, + FunctionWithContext> +>; + +export type AndUseActions = Map; +export type Operators = Map; +export type HooksWithOptions = Map< + keyof T, + { + hook: AnyFunction; + options?: { + context?: unknown; + }; + }[] +>; +export type Context = object> = { + state: () => [GetState, SetState]; + action: (name: keyof T, ...args: any[]) => any; +}; + +/** + * This actually define what kind of action will be implemented in namespaces. + * For example evm namespace will have .connect(chain: string) and .switchNetwork + * But solana namespace only have: `.connect()`. + * This actions will be passed to this generic. + */ +export type Actions = Record; diff --git a/wallets/core/src/hub/provider/mod.ts b/wallets/core/src/hub/provider/mod.ts new file mode 100644 index 0000000000..720b58f7ee --- /dev/null +++ b/wallets/core/src/hub/provider/mod.ts @@ -0,0 +1,10 @@ +export type { + ExtendableInternalActions, + CommonNamespaces, + CommonNamespaceKeys, + State, + Context, + ProviderBuilderOptions, +} from './types.js'; + +export { Provider } from './provider.js'; diff --git a/wallets/core/src/hub/provider/provider.test.ts b/wallets/core/src/hub/provider/provider.test.ts new file mode 100644 index 0000000000..013e21389a --- /dev/null +++ b/wallets/core/src/hub/provider/provider.test.ts @@ -0,0 +1,231 @@ +import type { EvmActions } from '../../namespaces/evm/types.js'; +import type { SolanaActions } from '../../namespaces/solana/types.js'; +import type { Store } from '../store/mod.js'; + +import { beforeEach, describe, expect, test, vi } from 'vitest'; + +import { NamespaceBuilder } from '../../builders/namespace.js'; +import { ProviderBuilder } from '../../builders/provider.js'; +import { garbageWalletInfo } from '../../test-utils/fixtures.js'; +import { createStore } from '../store/mod.js'; + +import { Provider } from './provider.js'; + +describe('check providers', () => { + let namespaces: { + evm: NamespaceBuilder; + solana: NamespaceBuilder; + }; + let namespacesMap: Map; + let store: Store; + + beforeEach(() => { + store = createStore(); + const evmNamespace = new NamespaceBuilder('eip155', 'garbage'); + const solanaNamespace = new NamespaceBuilder( + 'solana', + 'garbage' + ); + + namespaces = { + evm: evmNamespace, + solana: solanaNamespace, + }; + + namespacesMap = new Map(); + namespacesMap.set('evm', evmNamespace.build()); + namespacesMap.set('solana', solanaNamespace.build()); + + return () => { + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore-next-line + (store = undefined), (namespaces = undefined); + }; + }); + + test('Initialize providers correctly', () => { + const provider = new Provider('garbage', namespacesMap, { + info: garbageWalletInfo, + }); + + const allNamespaces = provider.getAll(); + + expect(allNamespaces.size).toBe(2); + }); + + test("throw an error if store hasn't set and try to access .state() and .info()", () => { + const provider = new Provider('garbage', namespacesMap, { + info: garbageWalletInfo, + }); + + expect(() => provider.state()).toThrowError(); + expect(() => provider.info()).toThrowError(); + }); + + test('access state correctly', () => { + const provider = new Provider( + 'garbage', + namespacesMap, + { + info: garbageWalletInfo, + }, + { + store: createStore(), + } + ); + + const [getState, setState] = provider.state(); + + expect(getState().connected).toBe(false); + expect(getState('connected')).toBe(false); + expect(() => { + // @ts-expect-error intentionally using an state that doesn't exist. + getState('not_exist_state'); + }).toThrowError(); + expect(() => { + // @ts-expect-error intentionally using an state that doesn't exist and try to update. + setState('another_not_exist_state'); + }).toThrowError(); + }); + test('update state properly', () => { + const store = createStore(); + const provider = new Provider( + 'garbage', + namespacesMap, + { + info: garbageWalletInfo, + }, + { + store, + } + ); + + const [getState, setState] = provider.state(); + + provider.store(store); + setState('installed', true); + const isInstalled = getState('installed'); + expect(isInstalled).toBe(true); + }); + + test('run namespace actions from provider', async () => { + const { evm, solana } = namespaces; + solana.action('connect', async () => [ + 'solana:mainnet:0x000000000000000000000000000000000000dead', + ]); + const testNamespaces = new Map(); + testNamespaces.set('evm', evm.build()); + testNamespaces.set('solana', solana.build()); + + const provider = new Provider('garbage', testNamespaces, { + info: garbageWalletInfo, + }); + + const result = await provider.get('solana')?.connect(); + + expect(result).toStrictEqual([ + 'solana:mainnet:0x000000000000000000000000000000000000dead', + ]); + // Since we didn't add any action regarding connect for `evm` + await expect(async () => + provider.get('evm')?.connect('0x1') + ).rejects.toThrowError(); + }); + + test('sets config properly', () => { + const builder = new ProviderBuilder('garbage'); + builder.config('info', garbageWalletInfo); + const provider = builder.build().store(store); + + expect(provider.info()).toStrictEqual(garbageWalletInfo); + }); + + test('.init should works on Provider', () => { + const builder = new ProviderBuilder('garbage').config( + 'info', + garbageWalletInfo + ); + let count = 0; + builder.init(() => { + count++; + }); + const provider = builder.build().store(store); + expect(count).toBe(0); + provider.init(); + provider.init(); + provider.init(); + expect(count).toBe(1); + }); + + test(".init shouldn't do anything when use hasn't set anything", () => { + const builder = new ProviderBuilder('garbage').config( + 'info', + garbageWalletInfo + ); + const provider = builder.build().store(store); + expect(() => { + provider.init(); + provider.init(); + provider.init(); + }).not.toThrow(); + }); + + test('A provider can be found using its namespace', () => { + const builder = new ProviderBuilder('garbage', { store }).config( + 'info', + garbageWalletInfo + ); + + const { evm, solana } = namespaces; + builder.add('evm', evm.build()).add('solana', solana.build()); + const provider = builder.build(); + + const result = provider.findByNamespace('solana'); + expect(result).toBeDefined(); + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore-next-line + expect(result?.namespaceId).toBe('solana'); + + const result2 = provider.findByNamespace('evm'); + expect(result2).toBeUndefined(); + }); + + test('`before/after` is calling with correct context ', () => { + const connect = vi.fn(); + const before = vi.fn(function (context) { + const [, setState] = context.state(); + setState('installed', true); + }); + const after = vi.fn(function (context) { + const [, setState] = context.state(); + setState('installed', false); + }); + + const { evm } = namespaces; + const evmNamespace = evm.action('connect', connect).build(); + + const builder = new ProviderBuilder('garbage', { store }) + .add('evm', evmNamespace) + .config('info', garbageWalletInfo); + const provider = builder.build(); + + const [getState] = provider.state(); + const result = provider.get('evm'); + + // Adding `after` then make it will run + provider.before('connect', before); + void result?.connect('whatever'); + + expect(connect).toBeCalledTimes(1); + expect(before).toBeCalledTimes(1); + expect(getState('installed')).toBe(true); + + // Adding `after` then make it will run + provider.after('connect', after); + void result?.connect('whatever'); + expect(connect).toBeCalledTimes(2); + expect(after).toBeCalledTimes(1); + + expect(getState('installed')).toBe(false); + }); +}); diff --git a/wallets/core/src/hub/provider/provider.ts b/wallets/core/src/hub/provider/provider.ts new file mode 100644 index 0000000000..7e5f4b873c --- /dev/null +++ b/wallets/core/src/hub/provider/provider.ts @@ -0,0 +1,330 @@ +import type { + CommonNamespaces, + Context, + ExtendableInternalActions, + GetState, + RegisteredNamespaces, + SetState, + State, +} from './types.js'; +import type { FindProxiedNamespace } from '../../builders/mod.js'; +import type { AnyFunction, FunctionWithContext } from '../../types/actions.js'; +import type { ProviderConfig, Store } from '../store/mod.js'; + +const VERSION = '1.0'; + +export class Provider { + public readonly id: string; + public readonly version = VERSION; + + #namespaces: RegisteredNamespaces; + #initiated = false; + #extendInternalActions: ExtendableInternalActions = {}; + #store: Store | undefined; + #configs: ProviderConfig; + + constructor( + id: string, + namespaces: RegisteredNamespaces, + configs: ProviderConfig, + options?: { + /** + * There are some cases we need to have a behavior like initializing a provider which will be run when we are creating an instance. + * These internal steps and behaviors will be useful for library user to extend the behavior by running a specific code. + */ + extendInternalActions?: ExtendableInternalActions; + store?: Store; + } + ) { + this.id = id; + this.#configs = configs; + // it should be only created here, to make sure `after/before` will work properly. + this.#extendInternalActions = options?.extendInternalActions || {}; + this.#namespaces = namespaces; + + if (options?.store) { + this.#store = options.store; + this.#setupStore(); + } + } + + /** + * This is an special callback that will be called **only once**. + * We don't call this in `constructor` and developer should call this manually. we only ensure it will be called once. + * + * ```ts + * const myInit = () => { whatever; } * + * const provider = new Provider(..., {extendInternalActions: {init: myInit} }); + * + * // Will run `myInit` + * provider.init() + * + * // Will not run `myInit` anymore. + * provider.init() + * provider.init() + * ``` + */ + public init(): void { + if (this.#initiated) { + return; + } + + const definedInitByUser = this.#extendInternalActions.init; + if (definedInitByUser) { + definedInitByUser(this.#context()); + } + + this.#initiated = true; + } + + /** + * Getting state of a provider + * + * **Note:** + * Each namespace has it's own state as well, in Legacy we didn't have this separation and all of them was accessible through Provider itself + * To be compatible with legacy, `getState` has a logic to guess the final state to produce same state as legacy. + * + * @example + * ```ts + * const provider = new Provider(...); + * const [getState, setState] = provider.state(); + * + * getState('installed'); + * // or + * getState().installed; + * ``` + * + */ + public state(): [GetState, SetState] { + const store = this.#store; + if (!store) { + throw new Error( + `Any store detected for ${this.id}. You need to set your store using '.store' method first.` + ); + } + + /** + * State updater + */ + const setState: SetState = (name, value) => { + switch (name) { + case 'installed': + return store.getState().providers.updateStatus(this.id, name, value); + default: + throw new Error( + `Unhandled state update for provider. (provider id: ${this.id}, state name: ${name})` + ); + } + }; + + /** + * State getter + */ + const getState: GetState = (name?: K) => { + const state: State = store + .getState() + .providers.guessNamespacesState(this.id); + + if (!name) { + return state; + } + + switch (name) { + case 'installed': + case 'connected': + case 'connecting': + return state[name]; + default: + throw new Error('Unhandled state for provider'); + } + }; + + return [getState, setState]; + } + + /** + * For keeping state, we need a store. all the states will be write to/read from store. + * + * **Note: When you are setting an store for provider, it will be set for its namespaces automatically as well** + * + * @example + * ```ts + * const myStore = createStore(); + * const provider = new Provider(...); + * provider.store(myStore); // or it can be passed to Provider constructor; + * ``` + */ + public store(store: Store): this { + if (this.#store) { + console.warn( + "You've already set an store for your Provider. Old store will be replaced by the new one." + ); + } + this.#store = store; + this.#setupStore(); + return this; + } + + /** + * Getting information about a provider which has been set on constructing Provider. + * + * @example + * ```ts + * const walletInfo = {name: "Garbage wallet", ...} + * const provider = new Provider(..., {info: walletInfo}); + * + * provider.info(); + * ``` + */ + public info(): ProviderConfig['info'] | undefined { + const store = this.#store; + if (!store) { + throw new Error( + 'You need to set your store using `.store` method first.' + ); + } + + return store.getState().providers.list[this.id].config.info; + } + + /** + * A list of registered _proxied_ namespaces. + * + * @example + * ```ts + * const provider = new Provider(...); + * const allNamespaces = provider.getAll(); + * ``` + */ + public getAll(): RegisteredNamespaces< + keyof CommonNamespaces, + CommonNamespaces + > { + return this.#namespaces; + } + + /** + * Get a registered namespace in provider by its **namespace key**. + * + * Note: difference between namespace key and namespace id is the first one is setting from a predefined list the second one can be anything and will be chosen by library's user. + * + * @param {string} id - evm, solana, cosmos, ... (CommonActions) + */ + public get( + id: K + ): FindProxiedNamespace | undefined { + return this.#namespaces.get(id) as unknown as + | FindProxiedNamespace + | undefined; + } + + /** + * + * Get a registered namespace by its **namespaceId**. + * + * Note: difference between namespace key and namespace id is the first one is setting from a predefined list the second one can be anything and will be chosen by library's user. + * + * @example + * ```ts + * const provider = new Provider(...); + * provider.findByNamespace("whatever-id-i-set-for-namespace") + * ``` + */ + public findByNamespace( + namespaceLookingFor: K | string + ): FindProxiedNamespace | undefined { + // If we didn't found any match, we will return `undefined`. + let result: object | undefined = undefined; + + this.#namespaces.forEach((namespace) => { + if (namespace.namespaceId === namespaceLookingFor) { + result = namespace; + } + }); + + return result; + } + + /** + * Running a hook function _after_ a specific action for **all registered namespaces**. + * + * **Note:** the context can be set from outside as well. this is useful for Provider to set its context instead of namespace context. + * + * @example + * ```ts + * const provider = new Provider(...); + * + * provider.after("connect", (context) => {}); + * ``` + */ + public before( + actionName: string, + hookFn: FunctionWithContext + ): this { + this.#addHook('before', actionName, hookFn); + return this; + } + + /** + * Running a hook function _before_ a specific action for **all registered namespaces**. + * + * **Note:** the context can be set from outside as well. this is useful for Provider to set its context instead of namespace context. + * + * @example + * ```ts + * const provider = new Provider(...); + * + * provider.after("connect", (context) => {}); + * ``` + */ + public after( + actionName: string, + hookFn: FunctionWithContext + ): this { + this.#addHook('after', actionName, hookFn); + return this; + } + + #addHook( + hookName: 'after' | 'before', + actionName: string, + cb: FunctionWithContext + ): this { + const context = { + state: this.state.bind(this), + }; + + this.#namespaces.forEach((namespace) => { + if (hookName === 'after') { + namespace.after(actionName as any, cb, { + context, + }); + } else if (hookName === 'before') { + namespace.before(actionName as any, cb, { + context, + }); + } else { + throw new Error(`You hook name is invalid: ${hookName}`); + } + }); + + return this; + } + + #setupStore(): void { + const store = this.#store; + if (!store) { + throw new Error('For setup store, you should set `store` first.'); + } + store.getState().providers.addProvider(this.id, this.#configs); + this.#namespaces.forEach((provider) => { + provider.store(store); + }); + } + + #context(): Context { + return { + state: this.state.bind(this), + }; + } +} diff --git a/wallets/core/src/hub/provider/types.ts b/wallets/core/src/hub/provider/types.ts new file mode 100644 index 0000000000..cfc3e0e3c6 --- /dev/null +++ b/wallets/core/src/hub/provider/types.ts @@ -0,0 +1,41 @@ +import type { FindProxiedNamespace } from '../../builders/mod.js'; +import type { Store } from '../../hub/mod.js'; +import type { LegacyState } from '../../legacy/mod.js'; +import type { CosmosActions } from '../../namespaces/cosmos/mod.js'; +import type { EvmActions } from '../../namespaces/evm/mod.js'; +import type { SolanaActions } from '../../namespaces/solana/mod.js'; +import type { AnyFunction, FunctionWithContext } from '../../types/actions.js'; +import type { Prettify } from '../../types/utils.js'; + +export type Context = { + state: () => [GetState, SetState]; +}; + +export type State = Omit; +export type SetState = >( + name: K, + value: State[K] +) => void; +export type GetState = { + (): State; + (name: K): State[K]; +}; + +export interface CommonNamespaces { + evm: EvmActions; + solana: SolanaActions; + cosmos: CosmosActions; +} + +export type CommonNamespaceKeys = Prettify; + +export interface ExtendableInternalActions { + init?: FunctionWithContext; +} + +export type RegisteredNamespaces = Map< + K, + FindProxiedNamespace +>; + +export type ProviderBuilderOptions = { store?: Store }; diff --git a/wallets/core/src/hub/store/hub.ts b/wallets/core/src/hub/store/hub.ts new file mode 100644 index 0000000000..569f5eeef4 --- /dev/null +++ b/wallets/core/src/hub/store/hub.ts @@ -0,0 +1,18 @@ +/************ Hub ************/ + +import type { State } from './mod.js'; +import type { StateCreator } from 'zustand'; + +type HubConfig = object; + +export interface HubStore { + config: HubConfig; +} + +type HubStateCreator = StateCreator; + +const hubStore: HubStateCreator = () => ({ + config: {}, +}); + +export { hubStore }; diff --git a/wallets/core/src/hub/store/mod.ts b/wallets/core/src/hub/store/mod.ts new file mode 100644 index 0000000000..08193d4e4a --- /dev/null +++ b/wallets/core/src/hub/store/mod.ts @@ -0,0 +1,8 @@ +export { + guessProviderStateSelector, + namespaceStateSelector, +} from './selectors.js'; +export type { Store, State } from './store.js'; +export type { ProviderInfo, ProviderConfig } from './providers.js'; +export type { NamespaceConfig, NamespaceData } from './namespaces.js'; +export { createStore } from './store.js'; diff --git a/wallets/core/src/hub/store/namespaces.ts b/wallets/core/src/hub/store/namespaces.ts new file mode 100644 index 0000000000..f2bbcc7b36 --- /dev/null +++ b/wallets/core/src/hub/store/namespaces.ts @@ -0,0 +1,90 @@ +/************ Namespace ************/ + +import type { StateCreator } from 'zustand'; + +import { produce } from 'immer'; + +import { namespaceStateSelector, type State } from './mod.js'; + +// eslint-disable-next-line @typescript-eslint/no-empty-interface +export interface NamespaceConfig { + // Currently, namespace doesn't has any config. +} + +export interface NamespaceData { + accounts: null | string[]; + network: null | string; + connected: boolean; + connecting: boolean; +} + +interface NamespaceInfo { + providerId: string; + namespaceId: string; +} + +type NamespaceState = { + list: Record< + string, + { + info: NamespaceInfo; + data: NamespaceData; + error: unknown; + } + >; +}; + +interface NamespaceActions { + addNamespace: (id: string, config: NamespaceInfo) => void; + updateStatus: ( + id: string, + key: K, + value: NamespaceData[K] + ) => void; +} +interface NamespaceSelectors { + getNamespaceData(storeId: string): NamespaceData; +} + +export type NamespaceStore = NamespaceState & + NamespaceActions & + NamespaceSelectors; +type NamespaceStateCreator = StateCreator; + +const namespacesStore: NamespaceStateCreator = (set, get) => ({ + list: {}, + addNamespace: (id, info) => { + const item = { + data: { + accounts: null, + network: null, + connected: false, + connecting: false, + }, + error: '', + info, + }; + + set( + produce((state: State) => { + state.namespaces.list[id] = item; + }) + ); + }, + updateStatus: (id, key, value) => { + if (!get().namespaces.list[id]) { + throw new Error(`No namespace with '${id}' found.`); + } + + set( + produce((state: State) => { + state.namespaces.list[id].data[key] = value; + }) + ); + }, + getNamespaceData(storeId) { + return namespaceStateSelector(get(), storeId); + }, +}); + +export { namespacesStore }; diff --git a/wallets/core/src/hub/store/providers.ts b/wallets/core/src/hub/store/providers.ts new file mode 100644 index 0000000000..a08f12db73 --- /dev/null +++ b/wallets/core/src/hub/store/providers.ts @@ -0,0 +1,91 @@ +import type { Namespace } from '../../namespaces/common/types.js'; +import type { State as InternalProviderState } from '../provider/mod.js'; +import type { StateCreator } from 'zustand'; + +import { produce } from 'immer'; + +import { guessProviderStateSelector, type State } from './mod.js'; + +type Browsers = 'firefox' | 'chrome' | 'edge' | 'brave' | 'homepage'; +type Property = { name: N; value: V }; +type DetachedInstances = Property<'detached', Namespace[]>; + +export type ProviderInfo = { + name: string; + icon: string; + extensions: Partial>; + properties?: DetachedInstances[]; +}; + +export interface ProviderConfig { + info: ProviderInfo; +} + +interface ProviderData { + installed: boolean; +} + +type ProviderState = { + list: Record< + string, + { + config: ProviderConfig; + data: ProviderData; + error: unknown; + } + >; +}; +interface ProviderActions { + addProvider: (id: string, config: ProviderConfig) => void; + updateStatus: ( + id: string, + key: K, + value: ProviderData[K] + ) => void; +} + +interface ProviderSelectors { + /** + * Provider has a limited state to itself, to be compatible with legacy, we try to produce same object as legacy + * which includes namespace state as well. + */ + guessNamespacesState: (id: string) => InternalProviderState; +} + +export type ProviderStore = ProviderState & ProviderActions & ProviderSelectors; +type ProvidersStateCreator = StateCreator; + +const providersStore: ProvidersStateCreator = (set, get) => ({ + list: {}, + addProvider: (id, config) => { + const item = { + data: { + installed: false, + }, + error: '', + config, + }; + + set( + produce((state: State) => { + state.providers.list[id] = item; + }) + ); + }, + updateStatus: (id, key, value) => { + if (!get().providers.list[id]) { + throw new Error(`No namespace namespace with '${id}' found.`); + } + + set( + produce((state: State) => { + state.providers.list[id].data[key] = value; + }) + ); + }, + guessNamespacesState: (providerId: string): InternalProviderState => { + return guessProviderStateSelector(get(), providerId); + }, +}); + +export { providersStore }; diff --git a/wallets/core/src/hub/store/selectors.ts b/wallets/core/src/hub/store/selectors.ts new file mode 100644 index 0000000000..a124032d1e --- /dev/null +++ b/wallets/core/src/hub/store/selectors.ts @@ -0,0 +1,59 @@ +/** + * Note: Zustand has some difficulty when you are trying to `previous` state on `subscribe`. + * If these selectors define inside store directly and use `get()` for accessing state, it will get the latest state + * instead of previous state which desired. + * So make them a helper will let us to reuse them both in store and outside of store in a `subscribe`. + */ +import type { State } from '../mod.js'; +import type { State as InternalProviderState } from '../provider/mod.js'; + +/** + * Legacy provider state includes `connecting` and `connected` values. It hadn't a separation layer for `namespaces`. + * For compatibility reasons, we should produce these two values somehow. + * + * Currently, We return `true` if any of namespaces return true. We are missing failed namespace here. + * But if we want to solve that, we should migrate our client code to use `namespace` state directly and not from `provider` + */ +export function guessProviderStateSelector( + state: State, + providerId: string +): InternalProviderState { + /* + * We keep namespaces in a separate branch than providers. + * We should look at all of them and find all the namespaces that for our current proivder. + */ + const allNamespaces = state.namespaces.list; + const currentProviderNamespaces = Object.keys(allNamespaces).filter( + (key) => allNamespaces[key].info.providerId === providerId + ); + + // Returning provider state value directly. + const installed = state.providers.list[providerId].data.installed; + + /* + * If any namespaces returns `true`, we consider the whole provider for this field to be `true`. + * it has a downside regarding errors which explained on top of the function. + */ + const connected = + currentProviderNamespaces.length > 0 + ? currentProviderNamespaces.some( + (key) => allNamespaces[key].data.connected + ) + : false; + const connecting = + currentProviderNamespaces.length > 0 + ? currentProviderNamespaces.some( + (key) => allNamespaces[key].data.connecting + ) + : false; + + return { + installed, + connected, + connecting, + }; +} + +export function namespaceStateSelector(state: State, storeId: string) { + return state.namespaces.list[storeId].data; +} diff --git a/wallets/core/src/hub/store/store.test.ts b/wallets/core/src/hub/store/store.test.ts new file mode 100644 index 0000000000..a1a8fc4ceb --- /dev/null +++ b/wallets/core/src/hub/store/store.test.ts @@ -0,0 +1,32 @@ +import type { Store } from './store.js'; + +import { beforeEach, describe, expect, test } from 'vitest'; + +import { createStore } from './store.js'; + +describe('checking store', () => { + let hubStore: Store; + + beforeEach(() => { + hubStore = createStore(); + }); + + test('new providers can be added to store', () => { + const id = 'sol-or-something'; + const info = { + info: { + name: 'sol grabage wallet', + icon: 'http://somewhere.world', + extensions: { + homepage: 'http://somewhere.world', + }, + }, + }; + + const { getState } = hubStore; + getState().providers.addProvider(id, info); + + expect(getState().providers.list[id]).toBeDefined(); + expect(Object.keys(getState().providers.list).length).toBe(1); + }); +}); diff --git a/wallets/core/src/hub/store/store.ts b/wallets/core/src/hub/store/store.ts new file mode 100644 index 0000000000..17211cca26 --- /dev/null +++ b/wallets/core/src/hub/store/store.ts @@ -0,0 +1,26 @@ +import type { StoreApi } from 'zustand/vanilla'; + +import { createStore as createZustandStore } from 'zustand/vanilla'; + +import { hubStore, type HubStore } from './hub.js'; +import { namespacesStore, type NamespaceStore } from './namespaces.js'; +import { providersStore, type ProviderStore } from './providers.js'; + +/************ State ************/ + +export interface State { + hub: HubStore; + providers: ProviderStore; + namespaces: NamespaceStore; +} + +export type Store = StoreApi; +export const createStore = (): Store => { + return createZustandStore((...api) => { + return { + hub: hubStore(...api), + providers: providersStore(...api), + namespaces: namespacesStore(...api), + }; + }); +}; diff --git a/wallets/core/src/index.ts b/wallets/core/src/index.ts deleted file mode 100644 index 340c56c781..0000000000 --- a/wallets/core/src/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from './helpers'; -export { default as Provider, useWallets } from './provider'; -export * from './types'; diff --git a/wallets/core/src/legacy/helpers.ts b/wallets/core/src/legacy/helpers.ts new file mode 100644 index 0000000000..b800acab29 --- /dev/null +++ b/wallets/core/src/legacy/helpers.ts @@ -0,0 +1,75 @@ +import type { Network } from './types.js'; +import type { Options } from './wallet.js'; +import type { BlockchainMeta } from 'rango-types'; + +import { Networks } from './types.js'; + +export function formatAddressWithNetwork( + address: string, + network?: Network | null +) { + return `${network || ''}:${address}`; +} + +export function accountAddressesWithNetwork( + addresses: string[] | null, + network?: Network | null +) { + if (!addresses) { + return []; + } + + return addresses.map((address) => { + return formatAddressWithNetwork(address, network); + }); +} + +export function readAccountAddress(addressWithNetwork: string): { + address: string; + network: Network; +} { + const [network, address] = addressWithNetwork.split(':'); + + return { + network, + address, + }; +} + +export function needsCheckInstallation(options: Options) { + const { checkInstallation = true } = options.config; + return checkInstallation; +} + +export const getBlockChainNameFromId = ( + chainId: string | number, + blockchains: BlockchainMeta[] +): Network | null => { + chainId = + typeof chainId === 'string' && chainId.startsWith('0x') + ? parseInt(chainId) + : chainId; + + /* + * Sometimes providers are passing `Network` as chainId. + * If chainId is a `Network`, we return itself. + */ + const allNetworks = Object.values(Networks); + if (allNetworks.includes(String(chainId) as Networks)) { + return chainId as Networks; + } + + if (chainId === 'Binance-Chain-Tigris') { + return Networks.BINANCE; + } + return ( + blockchains + .filter((blockchainMeta) => !!blockchainMeta.chainId) + .find((blockchainMeta) => { + const blockchainChainId = blockchainMeta.chainId?.startsWith('0x') + ? parseInt(blockchainMeta.chainId) + : blockchainMeta.chainId; + return blockchainChainId == chainId; + })?.name || null + ); +}; diff --git a/wallets/core/src/legacy/mod.ts b/wallets/core/src/legacy/mod.ts new file mode 100644 index 0000000000..4c1d63c082 --- /dev/null +++ b/wallets/core/src/legacy/mod.ts @@ -0,0 +1,42 @@ +/* + * All the exported types/values from legacy should be prefixed with `Legacy` + * since they will be removed soon and isn't part of the main interface for this package. + */ +export type { + EventHandler as LegacyEventHandler, + State as LegacyState, + Options as LegacyOptions, +} from './wallet.js'; + +export type { + Connect as LegacyConnect, + Disconnect as LegacyDisconnect, + Subscribe as LegacySubscribe, + CanEagerConnect as LegacyCanEagerConnect, + SwitchNetwork as LegacySwitchNetwork, + Suggest as LegacySuggest, + CanSwitchNetwork as LegacyCanSwitchNetwork, + NamespaceData as LegacyNamespaceData, + ProviderInterface as LegacyProviderInterface, + Network as LegacyNetwork, + WalletType as LegacyWalletType, + InstallObjects as LegacyInstallObjects, + WalletInfo as LegacyWalletInfo, + ConnectResult as LegacyConnectResult, + NamespaceInputForConnect as LegacyNamespaceInputForConnect, +} from './types.js'; + +export { Events as LegacyEvents, Networks as LegacyNetworks } from './types.js'; + +export { Persistor } from './persistor.js'; +export { + readAccountAddress as legacyReadAccountAddress, + getBlockChainNameFromId as legacyGetBlockChainNameFromId, + formatAddressWithNetwork as legacyFormatAddressWithNetwork, +} from './helpers.js'; +export { default as LegacyWallet } from './wallet.js'; + +export { + eagerConnectHandler as legacyEagerConnectHandler, + isEvmNamespace as legacyIsEvmNamespace, +} from './utils.js'; diff --git a/wallets/core/src/legacy/persistor.ts b/wallets/core/src/legacy/persistor.ts new file mode 100644 index 0000000000..8481d1f5aa --- /dev/null +++ b/wallets/core/src/legacy/persistor.ts @@ -0,0 +1,19 @@ +export interface PersistStorage { + getItem: (name: string) => T | null; + setItem: (name: string, value: T) => void; + removeItem: (name: string) => void; +} + +export class Persistor implements PersistStorage { + getItem(name: string) { + const item = localStorage.getItem(name); + const parsedItem = item ? (JSON.parse(item) as T) : null; + return parsedItem; + } + setItem(name: string, value: T) { + localStorage.setItem(name, JSON.stringify(value)); + } + removeItem(name: string) { + localStorage.removeItem(name); + } +} diff --git a/wallets/core/src/legacy/types.ts b/wallets/core/src/legacy/types.ts new file mode 100644 index 0000000000..ec0f1f5899 --- /dev/null +++ b/wallets/core/src/legacy/types.ts @@ -0,0 +1,275 @@ +import type { State as WalletState } from './wallet.js'; +import type { Namespace } from '../namespaces/common/mod.js'; +import type { BlockchainMeta, SignerFactory } from 'rango-types'; + +export enum Networks { + BTC = 'BTC', + BSC = 'BSC', + LTC = 'LTC', + THORCHAIN = 'THOR', + BCH = 'BCH', + BINANCE = 'BNB', + ETHEREUM = 'ETH', + POLYGON = 'POLYGON', + TERRA = 'TERRA', + POLKADOT = '', + TRON = 'TRON', + DOGE = 'DOGE', + HARMONY = 'HARMONY', + AVAX_CCHAIN = 'AVAX_CCHAIN', + FANTOM = 'FANTOM', + MOONBEAM = 'MOONBEAM', + ARBITRUM = 'ARBITRUM', + BOBA = 'BOBA', + OPTIMISM = 'OPTIMISM', + FUSE = 'FUSE', + CRONOS = 'CRONOS', + SOLANA = 'SOLANA', + MOONRIVER = 'MOONRIVER', + GNOSIS = 'GNOSIS', + COSMOS = 'COSMOS', + OSMOSIS = 'OSMOSIS', + AXELAR = 'AXELAR', + MARS = 'MARS', + STRIDE = 'STRIDE', + MAYA = 'MAYA', + AKASH = 'AKASH', + IRIS = 'IRIS', + PERSISTENCE = 'PERSISTENCE', + SENTINEL = 'SENTINEL', + REGEN = 'REGEN', + CRYPTO_ORG = 'CRYPTO_ORG', + SIF = 'SIF', + CHIHUAHUA = 'CHIHUAHUA', + JUNO = 'JUNO', + KUJIRA = 'KUJIRA', + STARNAME = 'STARNAME', + COMDEX = 'COMDEX', + STARGAZE = 'STARGAZE', + DESMOS = 'DESMOS', + BITCANNA = 'BITCANNA', + SECRET = 'SECRET', + INJECTIVE = 'INJECTIVE', + LUMNETWORK = 'LUMNETWORK', + BANDCHAIN = 'BANDCHAIN', + EMONEY = 'EMONEY', + BITSONG = 'BITSONG', + KI = 'KI', + MEDIBLOC = 'MEDIBLOC', + KONSTELLATION = 'KONSTELLATION', + UMEE = 'UMEE', + STARKNET = 'STARKNET', + TON = 'TON', + + // Using instead of null + Unknown = 'Unkown', +} + +export type NamespaceData = { + namespace: Namespace; + derivationPath?: string; +}; + +export type WalletType = string; +export type Network = string; + +export type InstallObjects = { + CHROME?: string; + FIREFOX?: string; + EDGE?: string; + BRAVE?: string; + DEFAULT: string; +}; + +interface NeedsNamespace { + selection: 'single' | 'multiple'; + data: { + label: string; + /** + * By using a matched `blockchain.name` (in meta) and `id`, we show logo in Namespace modal + * e.g. ETH + */ + id: string; + value: Namespace; + }[]; +} + +interface NeedsDerivationPath { + data: { + id: string; + label: string; + namespace: Namespace; + generateDerivationPath: (index: string) => string; + }[]; +} + +export type WalletInfo = { + name: string; + img: string; + installLink: InstallObjects | string; + /** + * @deprecated we don't use this value anymore. + */ + color: string; + supportedChains: BlockchainMeta[]; + showOnMobile?: boolean; + isContractWallet?: boolean; + mobileWallet?: boolean; + + needsDerivationPath?: NeedsDerivationPath; + needsNamespace?: NeedsNamespace; +}; + +export type State = { + [key: string]: WalletState | undefined; +}; + +export type ConnectResult = { + accounts: string[] | null; + network: Network | null; + provider: any; +}; + +export type Providers = { [type in WalletType]?: any }; + +export enum Events { + CONNECTED = 'connected', + CONNECTING = 'connecting', + REACHABLE = 'reachable', + INSTALLED = 'installed', + ACCOUNTS = 'accounts', + NETWORK = 'network', +} + +export type ProviderConnectResult = { + accounts: string[]; + chainId: string; +}; + +export type GetInstanceOptions = { + network?: Network; + currentProvider: any; + meta: BlockchainMeta[]; + getState: () => WalletState; + /** + * We always get the instance once and reuse it whenever we needs. By using this option + * We can force the library to get a new instance and replace it with the old one. + * + * Originally, we used this option for wallet connect 1 and its switching network challenge. + */ + force?: boolean; + updateChainId: (chainId: number | string) => void; +}; + +export type GetInstance = + | (() => any) + | ((options: GetInstanceOptions) => Promise); + +export type TryGetInstance = + | (() => any) + | ((options: Pick) => Promise); + +export type Connect = (options: { + instance: any; + network?: Network; + meta: BlockchainMeta[]; + namespaces?: NamespaceData[]; +}) => Promise; + +export type Disconnect = (options: { + instance: any; + destroyInstance: () => void; +}) => Promise; + +type CleanupSubscribe = () => void; + +export type Subscribe = (options: { + instance: any; + state: WalletState; + meta: BlockchainMeta[]; + updateChainId: (chainId: string) => void; + updateAccounts: (accounts: string[], chainId?: string) => void; + connect: (network?: Network) => void; + disconnect: () => void; +}) => CleanupSubscribe | void; + +export type SwitchNetwork = (options: { + instance: any; + network: Network; + meta: BlockchainMeta[]; + newInstance?: TryGetInstance; + getState?: () => WalletState; + updateChainId: (chainId: string) => void; +}) => Promise; + +export type Suggest = (options: { + instance: any; + network: Network; + meta: BlockchainMeta[]; +}) => Promise; + +export type CanSwitchNetwork = (options: { + network: Network; + meta: BlockchainMeta[]; + provider: any; +}) => boolean; + +export type CanEagerConnect = (options: { + instance: any; + meta: BlockchainMeta[]; +}) => Promise; + +export type EagerConnectResult = { + accounts: string[] | null; + network: string | null; + provider: I | null; +}; + +export interface WalletActions { + connect: Connect; + getInstance: any; + disconnect?: Disconnect; + subscribe?: Subscribe; + // unsubscribe, // coupled to subscribe. + + // Optional, but should be provided at the same time. + suggest?: Suggest; + switchNetwork?: SwitchNetwork; + getSigners: (provider: any) => Promise; + canSwitchNetworkTo?: CanSwitchNetwork; + canEagerConnect?: CanEagerConnect; + getWalletInfo(allBlockChains: BlockchainMeta[]): WalletInfo; +} + +export interface WalletConfig { + type: WalletType; + defaultNetwork?: Network; + checkInstallation?: boolean; + isAsyncInstance?: boolean; + isAsyncSwitchNetwork?: boolean; +} + +export type WalletProviders = Map< + WalletType, + { + actions: WalletActions; + config: WalletConfig; + } +>; + +export type ProviderInterface = { config: WalletConfig } & WalletActions; + +// it comes from wallets.ts and `connect` +type NetworkTypeFromLegacyConnect = Network | undefined; + +export type NamespaceInputForConnect = { + /** + * By default, you should specify namespace (e.g. evm). + */ + namespace: T; + /** + * In some cases, we need to connect a specific network on a namespace. e.g. Polygon on EVM. + */ + network: NetworkTypeFromLegacyConnect; + derivationPath?: string; +}; diff --git a/wallets/core/src/legacy/utils.ts b/wallets/core/src/legacy/utils.ts new file mode 100644 index 0000000000..672227e463 --- /dev/null +++ b/wallets/core/src/legacy/utils.ts @@ -0,0 +1,20 @@ +import type { NamespaceInputForConnect } from './types.js'; + +export async function eagerConnectHandler(params: { + canEagerConnect: () => Promise; + connectHandler: () => Promise; + providerName: string; +}) { + // Check if we can eagerly connect to the wallet + if (await params.canEagerConnect()) { + // Connect to wallet as usual + return await params.connectHandler(); + } + throw new Error(`can't restore connection for ${params.providerName}.`); +} + +export function isEvmNamespace( + namespace: NamespaceInputForConnect +): namespace is NamespaceInputForConnect<'EVM'> { + return namespace.namespace === 'EVM'; +} diff --git a/wallets/core/src/legacy/wallet.ts b/wallets/core/src/legacy/wallet.ts new file mode 100644 index 0000000000..a83d6d5fc0 --- /dev/null +++ b/wallets/core/src/legacy/wallet.ts @@ -0,0 +1,536 @@ +import type { + EagerConnectResult, + GetInstanceOptions, + NamespaceData, + Network, + WalletActions, + WalletConfig, + WalletType, +} from './types.js'; +import type { BlockchainMeta } from 'rango-types'; + +import { + accountAddressesWithNetwork, + getBlockChainNameFromId, + needsCheckInstallation, +} from './helpers.js'; +import { Events, Networks } from './types.js'; +import { eagerConnectHandler } from './utils.js'; + +export type EventHandler = ( + type: WalletType, + event: Events, + value: any, + coreState: State, + info: EventInfo +) => void; + +export type EventInfo = { + supportedBlockchains: BlockchainMeta[]; + isContractWallet: boolean; + // This is for Hub and be able to make it compatible with legacy behavior. + isHub: boolean; +}; + +export interface State { + connected: boolean; + connecting: boolean; + /** + * @depreacted it always returns `false`. don't use it. + */ + reachable: boolean; + installed: boolean; + accounts: string[] | null; + network: Network | null; +} + +export interface Options { + config: WalletConfig; + handler: EventHandler; +} + +class Wallet { + public provider: InstanceType | null; + private actions: WalletActions; + private state: State; + private options: Options; + private info: EventInfo; + private cleanupSubscribe?: (() => void) | void; + + constructor(options: Options, actions: WalletActions) { + this.actions = actions; + this.options = options; + this.provider = null; + this.info = { + supportedBlockchains: [], + isContractWallet: false, + isHub: false, + }; + this.state = { + connected: false, + connecting: false, + // TODO: Remove + reachable: false, + installed: false, + accounts: null, + network: null, + }; + + if (!needsCheckInstallation(options)) { + this.setInstalledAs(true); + } + } + + async suggestAndConnect(network: Network) { + if (this.actions.suggest) { + await this.actions.suggest({ + instance: this.provider, + meta: this.info.supportedBlockchains, + network, + }); + } + return await this.connect(network); + } + + async connect(network?: Network, namespaces?: NamespaceData[]) { + // If it's connecting, nothing do. + if (this.state.connecting) { + throw new Error('Connecting...'); + } + + const connectionFromState = await this.getConnectionFromState(); + const currentNetwork = this.state.network; + /* + * If a network hasn't been provided and also we have `lastNetwork` + * We will use lastNetwork to make sure we will not + * Ask the user to switch his network wrongly. + */ + const requestedNetwork = + network || currentNetwork || this.options.config.defaultNetwork; + + if (connectionFromState) { + const networkChanged = + currentNetwork !== requestedNetwork && !!requestedNetwork; + + // Reuse current connection if nothing has changed and we already have the connection in memory. + if (currentNetwork === requestedNetwork) { + return connectionFromState; + } + + let canSwitch = true; + if (this.actions.canSwitchNetworkTo) { + canSwitch = this.actions.canSwitchNetworkTo({ + provider: this.provider, + meta: this.info.supportedBlockchains, + network: requestedNetwork || '', + }); + } + + if (networkChanged && canSwitch && !!this.actions.switchNetwork) { + await this.actions.switchNetwork({ + instance: this.provider, + meta: this.info.supportedBlockchains, + // TODO: Fix type error + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + network: requestedNetwork, + newInstance: this.tryGetInstance.bind(this), + getState: this.getState.bind(this), + updateChainId: this.updateChainId.bind(this), + }); + + /* + * We assume if we reach here (`switchNetwork` not throwing error), Switch successfully has been done. + * But for providers with async switch network like wallet-connect, we need to wait for chain change + * event before changing network. + */ + if ( + requestedNetwork !== this.state.network && + !this.options.config.isAsyncSwitchNetwork + ) { + this.updateState({ + network, + }); + } + + return { + // Only network has been changed, so we reuse accounts from what we have already. + accounts: connectionFromState.accounts, + network: requestedNetwork, + provider: this.provider, + }; + } + + // If none of the above conditions didn't match, continute to connect. + } + + // We are connecting to wallet for the first time + + // Trying to get wallet's instance, if it's not available, raise an error. + const instance = await this.tryGetInstance({ network }); + + // Instance exists, trying to connect + this.updateState({ + connecting: true, + }); + this.setInstalledAs(true); + + try { + // eslint-disable-next-line no-var + var connectResult = await this.actions.connect({ + instance, + network: requestedNetwork || undefined, + meta: this.info.supportedBlockchains || [], + namespaces, + }); + } catch (e) { + this.resetState(); + throw e; + } + + this.updateState({ + connected: true, + reachable: true, + connecting: false, + }); + + // TODO: Handle accounts.length > 0 + + // Inserting accounts into our state. + let nextAccounts: string[] = []; + let nextNetwork: Network | null | undefined = null; + if (Array.isArray(connectResult)) { + let activeEvmNetwork: Network | null = null; + const accounts = connectResult.flatMap((blockchain) => { + const chainId = blockchain.chainId || Networks.Unknown; + // Try to map chainId with a Network, if not found, we use chainId directly. + const network = + getBlockChainNameFromId(chainId, this.info.supportedBlockchains) || + Networks.Unknown; + + /* + * When connecting to an evm instance, it will return address and wallet's active chain. + * On switch network we are comparing state's network and what passed as requestedNetwork. + * This code is for making sure we are setting correct active chain in state if it's evm. + */ + if (!activeEvmNetwork && network !== Networks.Unknown) { + const blockchainMeta = this.info.supportedBlockchains.find( + (blockchain) => blockchain.name === network + ); + if (blockchainMeta?.info?.infoType === 'EvmMetaInfo') { + activeEvmNetwork = network; + } + } + // TODO: second parameter should be `string` when we decided to open source the package. + return accountAddressesWithNetwork(blockchain.accounts, network); + }); + nextAccounts = accounts.filter(Boolean); + nextNetwork = + activeEvmNetwork || + requestedNetwork || + this.options.config.defaultNetwork; + } else { + const chainId = connectResult.chainId || Networks.Unknown; + const network = + getBlockChainNameFromId(chainId, this.info.supportedBlockchains) || + Networks.Unknown; + + // We fallback to current active network if `chainId` not provided. + nextAccounts = accountAddressesWithNetwork( + connectResult.accounts, + network + ); + nextNetwork = network; + } + + if (nextAccounts.length > 0) { + this.updateState({ + accounts: nextAccounts, + network: nextNetwork, + }); + } + + return { + accounts: this.state.accounts, + network: this.state.network, + provider: this.provider, + }; + } + + async disconnect() { + this.resetState(); + + if (this.actions.disconnect) { + void this.actions.disconnect({ + instance: this.provider, + // On wallet connect, we need to destory the instance and get a whole new instance when we are going to connect + destroyInstance: () => { + this.setProvider(null); + }, + }); + } + } + + // This method is only used for auto connection + async eagerConnect(): Promise> { + const instance = await this.tryGetInstance({ network: undefined }); + const { canEagerConnect } = this.actions; + const providerName = this.options.config.type; + + return await eagerConnectHandler({ + canEagerConnect: async () => { + if (!canEagerConnect) { + throw new Error( + `${providerName} provider hasn't implemented canEagerConnect.` + ); + } + + return await canEagerConnect({ + instance: instance, + meta: this.info.supportedBlockchains, + }); + }, + connectHandler: async () => { + const result = await this.connect(); + return result; + }, + providerName, + }); + } + + async getSigners(provider: any) { + return await this.actions.getSigners(provider); + } + getWalletInfo(allBlockChains: BlockchainMeta[]) { + return this.actions.getWalletInfo(allBlockChains); + } + canSwitchNetworkTo(network: Network, provider: any) { + const switchTo = this.actions.canSwitchNetworkTo; + if (!switchTo) { + return false; + } + + return switchTo({ + network, + meta: this.info.supportedBlockchains, + provider, + }); + } + + onInit() { + // some times functions can be overridden by wallets. see rf-2119 + if (!this.actions.getInstance) { + throw new Error( + `Provider hasn't defined how to get wallet's instance. provider: ${this.options.config.type} on: onInit` + ); + } + + if (!this.options.config.isAsyncInstance) { + const instance = this.actions.getInstance(); + if (!!instance && !this.state.installed) { + this.setInstalledAs(true); + } + } else if (needsCheckInstallation(this.options)) { + this.actions.getInstance().then((data: any) => { + if (data) { + this.setInstalledAs(true); + } + }); + } + } + + setProvider(value: any) { + this.provider = value; + if (!!value && !!this.actions.subscribe) { + const cleanup = this.actions.subscribe({ + instance: value, + state: this.state, + meta: this.info.supportedBlockchains, + connect: this.connect.bind(this), + disconnect: this.disconnect.bind(this), + updateAccounts: (accounts, chainId) => { + let network = this.state.network; + if (chainId) { + network = + getBlockChainNameFromId( + chainId, + this.info.supportedBlockchains + ) || Networks.Unknown; + } + + const nextAccounts = accountAddressesWithNetwork(accounts, network); + if (nextAccounts.length > 0) { + this.updateState({ + accounts: nextAccounts, + }); + } + }, + updateChainId: this.updateChainId.bind(this), + }); + this.cleanupSubscribe = cleanup; + } else if (!value && this.cleanupSubscribe) { + this.cleanupSubscribe(); + } + } + + setInfo(info: Partial) { + if (typeof info.supportedBlockchains !== 'undefined') { + this.info.supportedBlockchains = info.supportedBlockchains; + } + if (typeof info.isContractWallet !== 'undefined') { + this.info.isContractWallet = info.isContractWallet; + } + } + + setHandler(handler: EventHandler) { + this.options.handler = handler; + } + + getState(): State { + return this.state; + } + + updateState(states: Partial) { + /* + * We will notify handler after updating all the states. + * Because when we call `handler` it will has latest states. + */ + const updates: [Events, any][] = []; + + if (typeof states.connected !== 'undefined') { + this.state.connected = states.connected; + updates.push([Events.CONNECTED, states.connected]); + } + if (typeof states.connecting !== 'undefined') { + this.state.connecting = states.connecting; + updates.push([Events.CONNECTING, states.connecting]); + } + if (typeof states.reachable !== 'undefined') { + this.state.reachable = states.reachable; + updates.push([Events.REACHABLE, states.reachable]); + } + if (typeof states.installed !== 'undefined') { + this.state.installed = states.installed; + updates.push([Events.INSTALLED, states.installed]); + } + if (typeof states.accounts !== 'undefined') { + this.state.accounts = states.accounts; + updates.push([Events.ACCOUNTS, states.accounts]); + } + if (typeof states.network !== 'undefined') { + this.state.network = states.network; + updates.push([Events.NETWORK, states.network]); + } + + const state = this.getState(); + updates.forEach(([name, value]) => { + const eventInfo: EventInfo = { + supportedBlockchains: this.info.supportedBlockchains, + isContractWallet: this.info.isContractWallet, + isHub: false, + }; + this.options.handler( + this.options.config.type, + name, + value, + state, + eventInfo + ); + }); + } + + resetState() { + this.updateState({ + connected: false, + connecting: false, + reachable: false, + accounts: null, + network: null, + }); + } + + private async getConnectionFromState() { + // Already connected, so we return provider that we have in memory. + + /* + * For switching network on Trust Wallet (WalletConnect), + * We only kill the session (and not restting the whole state) + * So we are relying on this.provider for achieving this functionality. + */ + if (this.state.connected && !!this.provider) { + return { + accounts: this.state.accounts, + network: this.state.network, + provider: this.provider, + }; + } + + return null; + } + + private updateChainId(chainId: string | number) { + const network = chainId + ? getBlockChainNameFromId(chainId, this.info.supportedBlockchains) + : Networks.Unknown; + + this.updateState({ + network, + }); + } + + private setInstalledAs(value: boolean) { + if (!needsCheckInstallation(this.options) && value === false) { + return; + } + + this.updateState({ + installed: value, + }); + } + // eslint-disable-next-line destructuring/in-methods-params + private async tryGetInstance({ + network, + force, + }: { + network?: Network; + force?: boolean; + }) { + let instance = null; + /* + * For switching network on Trust Wallet (WalletConnect), + * We only kill the session (and not restting the whole state) + * So we are relying on this.provider for achieving this functionality. + */ + this.setProvider(null); + if (this.options.config.isAsyncInstance) { + // Trying to connect + const instanceOptions: GetInstanceOptions = { + currentProvider: this.provider, + meta: this.info.supportedBlockchains, + force: force || false, + updateChainId: this.updateChainId.bind(this), + getState: this.getState.bind(this), + }; + + if (network) { + instanceOptions.network = network; + } + instance = await this.actions.getInstance(instanceOptions); + } else { + instance = this.actions.getInstance(); + } + + if (!instance) { + this.setInstalledAs(false); + this.resetState(); + + const error_message = `It seems your selected wallet (${this.options.config.type}) isn't installed.`; + throw new Error(error_message); + } + + this.setProvider(instance); + return instance; + } +} + +export default Wallet; diff --git a/wallets/core/src/mod.ts b/wallets/core/src/mod.ts new file mode 100644 index 0000000000..b6eb03010f --- /dev/null +++ b/wallets/core/src/mod.ts @@ -0,0 +1,39 @@ +export type { + Store, + State, + ProviderInfo, + CommonNamespaces, + CommonNamespaceKeys, +} from './hub/mod.js'; +export { + Hub, + Provider, + Namespace, + createStore, + guessProviderStateSelector, + namespaceStateSelector, +} from './hub/mod.js'; + +export type { ProxiedNamespace, FindProxiedNamespace } from './builders/mod.js'; +export { + NamespaceBuilder, + ProviderBuilder, + ActionBuilder, +} from './builders/mod.js'; + +/* + * Our `embedded` hasn't been migrated to NodeNext yet so it doesn't support `exports` field. + * There are two approach to make `NodeNext` which is used for our libs with old moduleResolution: + * + * 1. Use direct paths, e.g. '@rango-dev/wallets-core/dist/legacy/mod' + * 2. Add types and function that are using in `embedded` to package entry point (this file). + * + * The first one is better since we don't need to deprecate or having a breaking change in future, + * But Parcel has weird behavior on resolving ESM exports. We enabled exports for Parcel using `packageExports: true` option, + * But it will use `exports` fields whenever it finds the field in package.json and ignore `moduleResolution` in tsconfig. + * + * To make it work for Parcel, we should go with second mentioned option. + * + */ +export type { VersionedProviders } from './utils/mod.js'; +export { defineVersions, pickVersion } from './utils/mod.js'; diff --git a/wallets/core/src/namespaces/common/actions.ts b/wallets/core/src/namespaces/common/actions.ts new file mode 100644 index 0000000000..f520932638 --- /dev/null +++ b/wallets/core/src/namespaces/common/actions.ts @@ -0,0 +1,11 @@ +import type { Context } from '../../hub/namespaces/mod.js'; + +export function disconnect(context: Context): void { + const [, setState] = context.state(); + setState('network', null); + setState('accounts', null); + setState('connected', false); + setState('connecting', false); +} + +export const recommended = [['disconnect', disconnect] as const]; diff --git a/wallets/core/src/namespaces/common/after.ts b/wallets/core/src/namespaces/common/after.ts new file mode 100644 index 0000000000..9f66c6ba23 --- /dev/null +++ b/wallets/core/src/namespaces/common/after.ts @@ -0,0 +1,8 @@ +import type { Context } from '../../hub/namespaces/mod.js'; + +export function intoConnectionFinished(context: Context) { + const [, setState] = context.state(); + setState('connecting', false); +} + +export const recommended = [['connect', intoConnectionFinished] as const]; diff --git a/wallets/core/src/namespaces/common/and.ts b/wallets/core/src/namespaces/common/and.ts new file mode 100644 index 0000000000..7b6a219871 --- /dev/null +++ b/wallets/core/src/namespaces/common/and.ts @@ -0,0 +1,42 @@ +import type { + Accounts, + AccountsWithActiveChain, +} from './../../types/accounts.js'; +import type { Context } from '../../hub/namespaces/mod.js'; + +import { isValidCaipAddress } from './helpers.js'; + +export function connectAndUpdateStateForSingleNetwork( + context: Context, + accounts: Accounts +) { + if (!accounts.every(isValidCaipAddress)) { + throw new Error( + `Your provider should format account addresses in CAIP-10 format. Your provided accounts: ${accounts}` + ); + } + + const [, setState] = context.state(); + setState('accounts', accounts); + setState('connected', true); + return accounts; +} + +export function connectAndUpdateStateForMultiNetworks( + context: Context, + accounts: AccountsWithActiveChain +) { + if (!accounts.accounts.every(isValidCaipAddress)) { + throw new Error( + `Your provider should format account addresses in CAIP-10 format. Your provided accounts: ${accounts.accounts}` + ); + } + + const [, setState] = context.state(); + setState('accounts', accounts.accounts); + setState('network', accounts.network); + setState('connected', true); + return accounts; +} + +export const recommended = []; diff --git a/wallets/core/src/namespaces/common/before.ts b/wallets/core/src/namespaces/common/before.ts new file mode 100644 index 0000000000..6945b36dfc --- /dev/null +++ b/wallets/core/src/namespaces/common/before.ts @@ -0,0 +1,9 @@ +import type { Context } from '../../hub/namespaces/mod.js'; + +export function intoConnecting(context: Context) { + const [, setState] = context.state(); + setState('connecting', true); +} + +// Please consider if you are going to add something here, make sure it works on all namespaces. +export const recommended = [['connect', intoConnecting] as const]; diff --git a/wallets/core/src/namespaces/common/builders.ts b/wallets/core/src/namespaces/common/builders.ts new file mode 100644 index 0000000000..0cefece29c --- /dev/null +++ b/wallets/core/src/namespaces/common/builders.ts @@ -0,0 +1,14 @@ +import type { AutoImplementedActionsByRecommended } from './types.js'; +import type { Actions } from '../../hub/namespaces/types.js'; + +import { ActionBuilder } from '../../mod.js'; + +import { disconnect as disconnectAction } from './actions.js'; + +export const disconnect = < + T extends Actions & + Record<'disconnect', AutoImplementedActionsByRecommended['disconnect']> +>() => + new ActionBuilder( + 'disconnect' + ).action(disconnectAction) as unknown as ActionBuilder; diff --git a/wallets/core/src/namespaces/common/helpers.ts b/wallets/core/src/namespaces/common/helpers.ts new file mode 100644 index 0000000000..29f85b68a7 --- /dev/null +++ b/wallets/core/src/namespaces/common/helpers.ts @@ -0,0 +1,10 @@ +import { AccountId } from 'caip'; + +export function isValidCaipAddress(address: string): boolean { + try { + AccountId.parse(address); + return true; + } catch { + return false; + } +} diff --git a/wallets/core/src/namespaces/common/mod.ts b/wallets/core/src/namespaces/common/mod.ts new file mode 100644 index 0000000000..ef4c65d64d --- /dev/null +++ b/wallets/core/src/namespaces/common/mod.ts @@ -0,0 +1,20 @@ +export * as actions from './actions.js'; +export * as builders from './builders.js'; +export { + intoConnectionFinished, + recommended as afterRecommended, +} from './after.js'; +export { + connectAndUpdateStateForMultiNetworks, + connectAndUpdateStateForSingleNetwork, + recommended as andRecommended, +} from './and.js'; +export { intoConnecting, recommended as beforeRecommended } from './before.js'; + +export type { + CaipAccount, + Accounts, + AccountsWithActiveChain, +} from '../../types/accounts.js'; + +export type { Namespace } from './types.js'; diff --git a/wallets/core/src/namespaces/common/types.ts b/wallets/core/src/namespaces/common/types.ts new file mode 100644 index 0000000000..f4a2e7f8f9 --- /dev/null +++ b/wallets/core/src/namespaces/common/types.ts @@ -0,0 +1,23 @@ +/* + * These are supported namespaces in Rango that we want to officially support. + * This should be private and don't make it public since core can support more namespaces and should be extendable. + */ +type RangoNamespace = + | 'EVM' + | 'Solana' + | 'Cosmos' + | 'UTXO' + | 'Starknet' + | 'Tron' + | 'Ton'; + +// eslint-disable-next-line @typescript-eslint/ban-types +export type Namespace = RangoNamespace | (string & {}); + +export interface CommonActions { + init: () => void; +} + +export interface AutoImplementedActionsByRecommended { + disconnect: () => void; +} diff --git a/wallets/core/src/namespaces/cosmos/mod.ts b/wallets/core/src/namespaces/cosmos/mod.ts new file mode 100644 index 0000000000..38b10b297f --- /dev/null +++ b/wallets/core/src/namespaces/cosmos/mod.ts @@ -0,0 +1 @@ +export type { CosmosActions } from './types.js'; diff --git a/wallets/core/src/namespaces/cosmos/types.ts b/wallets/core/src/namespaces/cosmos/types.ts new file mode 100644 index 0000000000..83d17ba007 --- /dev/null +++ b/wallets/core/src/namespaces/cosmos/types.ts @@ -0,0 +1,11 @@ +import type { + AutoImplementedActionsByRecommended, + CommonActions, +} from '../common/types.js'; + +export interface CosmosActions + extends AutoImplementedActionsByRecommended, + CommonActions { + // TODO + connect: () => Promise; +} diff --git a/wallets/core/src/namespaces/evm/actions.ts b/wallets/core/src/namespaces/evm/actions.ts new file mode 100644 index 0000000000..5810dbe0bf --- /dev/null +++ b/wallets/core/src/namespaces/evm/actions.ts @@ -0,0 +1,148 @@ +import type { EIP1193EventMap } from './eip1193.js'; +import type { EvmActions, ProviderAPI } from './types.js'; +import type { Context, Subscriber } from '../../hub/namespaces/mod.js'; +import type { SubscriberCleanUp } from '../../hub/namespaces/types.js'; +import type { CaipAccount } from '../../types/accounts.js'; +import type { FunctionWithContext } from '../../types/actions.js'; + +import { AccountId } from 'caip'; + +import { recommended as commonRecommended } from '../common/actions.js'; + +import { CAIP_NAMESPACE } from './constants.js'; +import { getAccounts, switchOrAddNetwork } from './utils.js'; + +export const recommended = [...commonRecommended]; + +export function connect( + instance: () => ProviderAPI +): FunctionWithContext { + return async (_context, chain) => { + const evmInstance = instance(); + + if (!evmInstance) { + throw new Error( + 'Do your wallet injected correctly and is evm compatible?' + ); + } + + if (chain) { + await switchOrAddNetwork(evmInstance, chain); + } + + const chainId = await evmInstance.request({ method: 'eth_chainId' }); + + const result = await getAccounts(evmInstance); + + const formatAccounts = result.accounts.map( + (account) => + AccountId.format({ + address: account, + chainId: { + namespace: CAIP_NAMESPACE, + reference: chainId, + }, + }) as CaipAccount + ); + + return { + accounts: formatAccounts, + network: result.chainId, + }; + }; +} + +export function changeAccountSubscriber( + instance: () => ProviderAPI +): [Subscriber, SubscriberCleanUp] { + let eventCallback: EIP1193EventMap['accountsChanged']; + + // subscriber can be passed to `or`, it will get the error and should rethrow error to pass the error to next `or` or throw error. + return [ + (context, err) => { + const evmInstance = instance(); + + if (!evmInstance) { + throw new Error( + 'Trying to subscribe to your EVM wallet, but seems its instance is not available.' + ); + } + + const [, setState] = context.state(); + + eventCallback = async (accounts) => { + /* + * In Phantom, when user is switching to an account which is not connected to dApp yet, it returns a null. + * So null means we don't have access to account and we need to disconnect and let the user connect the account. + * + * This assumption may not work for other wallets, if that the case, we need to consider a new approach. + */ + if (!accounts || accounts.length === 0) { + context.action('disconnect'); + return; + } + + const chainId = await evmInstance.request({ method: 'eth_chainId' }); + const formatAccounts = accounts.map((account) => + AccountId.format({ + address: account, + chainId: { + namespace: CAIP_NAMESPACE, + reference: chainId, + }, + }) + ); + + setState('accounts', formatAccounts); + }; + evmInstance.on('accountsChanged', eventCallback); + + if (err instanceof Error) { + throw err; + } + }, + (_, err) => { + const evmInstance = instance(); + + if (eventCallback && evmInstance) { + evmInstance.removeListener('accountsChanged', eventCallback); + } + + if (err instanceof Error) { + throw err; + } + }, + ]; +} + +export function changeChainSubscriber( + instance: () => ProviderAPI +): [Subscriber, SubscriberCleanUp] { + let eventCallback: EIP1193EventMap['chainChanged']; + + return [ + (context) => { + const evmInstance = instance(); + + if (!evmInstance) { + throw new Error( + 'Trying to subscribe to your EVM wallet, but seems its instance is not available.' + ); + } + + const [, setState] = context.state(); + + eventCallback = async (chainId: string) => { + setState('network', chainId); + }; + evmInstance.on('chainChanged', eventCallback); + }, + () => { + const evmInstance = instance(); + + if (eventCallback && evmInstance) { + evmInstance.removeListener('chainChanged', eventCallback); + } + }, + ]; +} diff --git a/wallets/core/src/namespaces/evm/after.ts b/wallets/core/src/namespaces/evm/after.ts new file mode 100644 index 0000000000..229710d3bf --- /dev/null +++ b/wallets/core/src/namespaces/evm/after.ts @@ -0,0 +1,3 @@ +import { recommended as commonRecommended } from '../common/after.js'; + +export const recommended = [...commonRecommended]; diff --git a/wallets/core/src/namespaces/evm/and.ts b/wallets/core/src/namespaces/evm/and.ts new file mode 100644 index 0000000000..b1af366a39 --- /dev/null +++ b/wallets/core/src/namespaces/evm/and.ts @@ -0,0 +1,5 @@ +import { connectAndUpdateStateForMultiNetworks } from '../common/mod.js'; + +export const recommended = [ + ['connect', connectAndUpdateStateForMultiNetworks] as const, +]; diff --git a/wallets/core/src/namespaces/evm/before.ts b/wallets/core/src/namespaces/evm/before.ts new file mode 100644 index 0000000000..34a27af402 --- /dev/null +++ b/wallets/core/src/namespaces/evm/before.ts @@ -0,0 +1,3 @@ +import { beforeRecommended } from '../common/mod.js'; + +export const recommended = [...beforeRecommended]; diff --git a/wallets/core/src/namespaces/evm/builders.ts b/wallets/core/src/namespaces/evm/builders.ts new file mode 100644 index 0000000000..fec7dd8293 --- /dev/null +++ b/wallets/core/src/namespaces/evm/builders.ts @@ -0,0 +1,10 @@ +import type { EvmActions } from './types.js'; + +import { ActionBuilder } from '../../mod.js'; +import { intoConnectionFinished } from '../common/after.js'; +import { connectAndUpdateStateForMultiNetworks } from '../common/and.js'; + +export const connect = () => + new ActionBuilder('connect') + .and(connectAndUpdateStateForMultiNetworks) + .after(intoConnectionFinished); diff --git a/wallets/core/src/namespaces/evm/constants.ts b/wallets/core/src/namespaces/evm/constants.ts new file mode 100644 index 0000000000..13af0a2d0c --- /dev/null +++ b/wallets/core/src/namespaces/evm/constants.ts @@ -0,0 +1,2 @@ +export const CAIP_NAMESPACE = 'eip155'; +export const CAIP_ETHEREUM_CHAIN_ID = '1'; diff --git a/wallets/core/src/namespaces/evm/eip1193.ts b/wallets/core/src/namespaces/evm/eip1193.ts new file mode 100644 index 0000000000..e2634e370f --- /dev/null +++ b/wallets/core/src/namespaces/evm/eip1193.ts @@ -0,0 +1,1414 @@ +/* + * These are copied from `viem` (EIP1193Provider) + * They have an issue with `node16`, we can not directly import from their package. + * When they fixed the issue, it would better to re-export from viem instead of keeping it here and maintaining the changes. + */ + +// These are types that has so much nested types, for now i put any instead. +type Block = any; +type Log = any; +type TransactionRequest = any; +type BlockNumber = any; +type BlockTag = any; +type BlockIdentifier = any; +type RpcStateOverride = any; +type FeeHistory = any; +type Proof = any; +type Transaction = any; +type TransactionReceipt = any; +type LogTopic = any; +type Uncle = any; +type RpcUserOperation<_ = any> = any; +type RpcEstimateUserOperationGasReturnType = any; +type RpcGetUserOperationByHashReturnType = any; +type RpcUserOperationReceipt = any; + +type KeyofUnion = type extends type ? keyof type : never; + +export type OneOf< + union extends object, + fallback extends object | undefined = undefined, + /// + keys extends KeyofUnion = KeyofUnion +> = union extends infer item + ? Prettify< + item & { + [key in Exclude]?: fallback extends object + ? key extends keyof fallback + ? fallback[key] + : undefined + : undefined; + } + > + : never; + +export type AddEthereumChainParameter = { + /** A 0x-prefixed hexadecimal string */ + chainId: string; + /** The chain name. */ + chainName: string; + /** Native currency for the chain. */ + nativeCurrency?: + | { + name: string; + symbol: string; + decimals: number; + } + | undefined; + rpcUrls: readonly string[]; + blockExplorerUrls?: string[] | undefined; + iconUrls?: string[] | undefined; +}; + +export type NetworkSync = { + /** The current block number */ + currentBlock: Quantity; + /** Number of latest block on the network */ + highestBlock: Quantity; + /** Block number at which syncing started */ + startingBlock: Quantity; +}; + +export type WalletCapabilities = { + [capability: string]: any; +}; + +export type WalletCapabilitiesRecord< + capabilities extends WalletCapabilities = WalletCapabilities, + id extends string | number = Hex +> = { + [chainId in id]: capabilities; +}; + +export type WalletCallReceipt = { + logs: { + address: Hex; + data: Hex; + topics: Hex[]; + }[]; + status: status; + blockHash: Hex; + blockNumber: quantity; + gasUsed: quantity; + transactionHash: Hex; +}; + +export type WalletGrantPermissionsParameters = { + signer?: + | { + type: string; + data?: unknown | undefined; + } + | undefined; + permissions: readonly { + data: unknown; + policies: readonly { + data: unknown; + type: string; + }[]; + required?: boolean | undefined; + type: string; + }[]; + expiry: number; +}; + +export type WalletGrantPermissionsReturnType = { + expiry: number; + factory?: `0x${string}` | undefined; + factoryData?: string | undefined; + grantedPermissions: readonly { + data: unknown; + policies: readonly { + data: unknown; + type: string; + }[]; + required?: boolean | undefined; + type: string; + }[]; + permissionsContext: string; + signerData?: + | { + userOpBuilder?: `0x${string}` | undefined; + submitToAddress?: `0x${string}` | undefined; + } + | undefined; +}; + +export type WalletGetCallsStatusReturnType = { + status: 'PENDING' | 'CONFIRMED'; + receipts?: WalletCallReceipt[] | undefined; +}; + +export type WalletPermissionCaveat = { + type: string; + value: any; +}; + +export type WalletPermission = { + caveats: WalletPermissionCaveat[]; + date: number; + id: string; + invoker: `http://${string}` | `https://${string}`; + parentCapability: 'eth_accounts' | string; +}; + +export type WalletSendCallsParameters< + capabilities extends WalletCapabilities = WalletCapabilities, + chainId extends Hex | number = Hex, + quantity extends Quantity | bigint = Quantity +> = [ + { + calls: OneOf< + | { + to: Address; + data?: Hex | undefined; + value?: quantity | undefined; + } + | { + data: Hex; + } + >[]; + capabilities?: capabilities | undefined; + chainId: chainId; + from: Address; + version: string; + } +]; + +export type WatchAssetParams = { + /** Token type. */ + type: 'ERC20'; + options: { + /** The address of the token contract */ + address: string; + /** A ticker symbol or shorthand, up to 11 characters */ + symbol: string; + /** The number of token decimals */ + decimals: number; + /** A string url of the token logo */ + image?: string | undefined; + }; +}; + +export type ExactPartial = { + [key in keyof type]?: type[key] | undefined; +}; + +export type PartialBy = Omit & + ExactPartial>; + +/** TypeScript type to use for `address` values */ +type Address = `0x${string}`; + +export type ProviderConnectInfo = { + chainId: string; +}; + +export type ProviderMessage = { + type: string; + data: unknown; +}; + +class ProviderRpcError extends Error { + code: number; + details: string; + + constructor(code: number, message: string) { + super(message); + this.code = code; + this.details = message; + } +} + +export type EIP1193EventMap = { + accountsChanged(accounts: Address[]): void; + chainChanged(chainId: string): void; + connect(connectInfo: ProviderConnectInfo): void; + disconnect(error: ProviderRpcError): void; + message(message: ProviderMessage): void; +}; + +export type EIP1193Events = { + on( + event: event, + listener: EIP1193EventMap[event] + ): void; + removeListener( + event: event, + listener: EIP1193EventMap[event] + ): void; +}; + +export type Prettify = { + [K in keyof T]: T[K]; + // eslint-disable-next-line @typescript-eslint/ban-types +} & {}; + +export type RpcSchema = readonly { + Method: string; + Parameters?: unknown | undefined; + ReturnType: unknown; +}[]; + +export type RpcSchemaOverride = Omit; + +export type EIP1193Parameters< + rpcSchema extends RpcSchema | undefined = undefined +> = rpcSchema extends RpcSchema + ? { + [K in keyof rpcSchema]: Prettify< + { + method: rpcSchema[K] extends rpcSchema[number] + ? rpcSchema[K]['Method'] + : never; + } & (rpcSchema[K] extends rpcSchema[number] + ? rpcSchema[K]['Parameters'] extends undefined + ? { params?: undefined } + : { params: rpcSchema[K]['Parameters'] } + : never) + >; + }[number] + : { + method: string; + params?: unknown | undefined; + }; + +export type EIP1193RequestOptions = { + // Deduplicate in-flight requests. + dedupe?: boolean | undefined; + // The base delay (in ms) between retries. + retryDelay?: number | undefined; + // The max number of times to retry. + retryCount?: number | undefined; + /** Unique identifier for the request. */ + uid?: string | undefined; +}; + +type DerivedRpcSchema< + rpcSchema extends RpcSchema | undefined, + rpcSchemaOverride extends RpcSchemaOverride | undefined +> = rpcSchemaOverride extends RpcSchemaOverride + ? [rpcSchemaOverride & { Method: string }] + : rpcSchema; + +export type EIP1193RequestFn< + rpcSchema extends RpcSchema | undefined = undefined +> = < + rpcSchemaOverride extends RpcSchemaOverride | undefined = undefined, + _parameters extends EIP1193Parameters< + DerivedRpcSchema + > = EIP1193Parameters>, + _returnType = DerivedRpcSchema extends RpcSchema + ? Extract< + DerivedRpcSchema[number], + { Method: _parameters['method'] } + >['ReturnType'] + : unknown +>( + args: _parameters, + options?: EIP1193RequestOptions | undefined +) => Promise<_returnType>; + +export type Hex = `0x${string}`; +export type Hash = `0x${string}`; +export type Quantity = `0x${string}`; + +export type PublicRpcSchema = [ + /** + * @description Returns the version of the current client + * + * @example + * provider.request({ method: 'web3_clientVersion' }) + * // => 'MetaMask/v1.0.0' + */ + { + Method: 'web3_clientVersion'; + Parameters?: undefined; + ReturnType: string; + }, + /** + * @description Hashes data using the Keccak-256 algorithm + * + * @example + * provider.request({ method: 'web3_sha3', params: ['0x68656c6c6f20776f726c64'] }) + * // => '0xc94770007dda54cF92009BFF0dE90c06F603a09f' + */ + { + Method: 'web3_sha3'; + Parameters: [data: Hash]; + ReturnType: string; + }, + /** + * @description Determines if this client is listening for new network connections + * + * @example + * provider.request({ method: 'net_listening' }) + * // => true + */ + { + Method: 'net_listening'; + Parameters?: undefined; + ReturnType: boolean; + }, + /** + * @description Returns the number of peers currently connected to this client + * + * @example + * provider.request({ method: 'net_peerCount' }) + * // => '0x1' + */ + { + Method: 'net_peerCount'; + Parameters?: undefined; + ReturnType: Quantity; + }, + /** + * @description Returns the chain ID associated with the current network + * + * @example + * provider.request({ method: 'net_version' }) + * // => '1' + */ + { + Method: 'net_version'; + Parameters?: undefined; + ReturnType: Quantity; + }, + /** + * @description Returns the base fee per blob gas in wei. + * + * @example + * provider.request({ method: 'eth_blobBaseFee' }) + * // => '0x09184e72a000' + */ + { + Method: 'eth_blobBaseFee'; + Parameters?: undefined; + ReturnType: Quantity; + }, + /** + * @description Returns the number of the most recent block seen by this client + * + * @example + * provider.request({ method: 'eth_blockNumber' }) + * // => '0x1b4' + */ + { + Method: 'eth_blockNumber'; + Parameters?: undefined; + ReturnType: Quantity; + }, + /** + * @description Executes a new message call immediately without submitting a transaction to the network + * + * @example + * provider.request({ method: 'eth_call', params: [{ to: '0x...', data: '0x...' }] }) + * // => '0x...' + */ + { + Method: 'eth_call'; + Parameters: + | [transaction: ExactPartial] + | [ + transaction: ExactPartial, + block: BlockNumber | BlockTag | BlockIdentifier + ] + | [ + transaction: ExactPartial, + block: BlockNumber | BlockTag | BlockIdentifier, + stateOverrideSet: RpcStateOverride + ]; + ReturnType: Hex; + }, + /** + * @description Returns the chain ID associated with the current network + * @example + * provider.request({ method: 'eth_chainId' }) + * // => '1' + */ + { + Method: 'eth_chainId'; + Parameters?: undefined; + ReturnType: Quantity; + }, + /** + * @description Returns the client coinbase address. + * @example + * provider.request({ method: 'eth_coinbase' }) + * // => '0x...' + */ + { + Method: 'eth_coinbase'; + Parameters?: undefined; + ReturnType: Address; + }, + /** + * @description Estimates the gas necessary to complete a transaction without submitting it to the network + * + * @example + * provider.request({ + * method: 'eth_estimateGas', + * params: [{ from: '0x...', to: '0x...', value: '0x...' }] + * }) + * // => '0x5208' + */ + { + Method: 'eth_estimateGas'; + Parameters: + | [transaction: TransactionRequest] + | [transaction: TransactionRequest, block: BlockNumber | BlockTag] + | [ + transaction: TransactionRequest, + block: BlockNumber | BlockTag, + stateOverride: RpcStateOverride + ]; + ReturnType: Quantity; + }, + /** + * @description Returns a collection of historical gas information + * + * @example + * provider.request({ + * method: 'eth_feeHistory', + * params: ['4', 'latest', ['25', '75']] + * }) + * // => { + * // oldestBlock: '0x1', + * // baseFeePerGas: ['0x1', '0x2', '0x3', '0x4'], + * // gasUsedRatio: ['0x1', '0x2', '0x3', '0x4'], + * // reward: [['0x1', '0x2'], ['0x3', '0x4'], ['0x5', '0x6'], ['0x7', '0x8']] + * // } + * + */ + { + Method: 'eth_feeHistory'; + Parameters: [ + /** Number of blocks in the requested range. Between 1 and 1024 blocks can be requested in a single query. Less than requested may be returned if not all blocks are available. */ + blockCount: Quantity, + /** Highest number block of the requested range. */ + newestBlock: BlockNumber | BlockTag, + /** A monotonically increasing list of percentile values to sample from each block's effective priority fees per gas in ascending order, weighted by gas used. */ + rewardPercentiles: number[] | undefined + ]; + ReturnType: FeeHistory; + }, + /** + * @description Returns the current price of gas expressed in wei + * + * @example + * provider.request({ method: 'eth_gasPrice' }) + * // => '0x09184e72a000' + */ + { + Method: 'eth_gasPrice'; + Parameters?: undefined; + ReturnType: Quantity; + }, + /** + * @description Returns the balance of an address in wei + * + * @example + * provider.request({ method: 'eth_getBalance', params: ['0x...', 'latest'] }) + * // => '0x12a05...' + */ + { + Method: 'eth_getBalance'; + Parameters: [ + address: Address, + block: BlockNumber | BlockTag | BlockIdentifier + ]; + ReturnType: Quantity; + }, + /** + * @description Returns information about a block specified by hash + * @link https://eips.ethereum.org/EIPS/eip-1474 + * @example + * provider.request({ method: 'eth_getBlockByHash', params: ['0x...', true] }) + * // => { + * // number: '0x1b4', + * // hash: '0x...', + * // parentHash: '0x...', + * // ... + * // } + */ + { + Method: 'eth_getBlockByHash'; + Parameters: [ + /** hash of a block */ + hash: Hash, + /** true will pull full transaction objects, false will pull transaction hashes */ + includeTransactionObjects: boolean + ]; + ReturnType: Block | null; + }, + /** + * @description Returns information about a block specified by number + * @link https://eips.ethereum.org/EIPS/eip-1474 + * @example + * provider.request({ method: 'eth_getBlockByNumber', params: ['0x1b4', true] }) + * // => { + * // number: '0x1b4', + * // hash: '0x...', + * // parentHash: '0x...', + * // ... + * // } + */ + { + Method: 'eth_getBlockByNumber'; + Parameters: [ + /** block number, or one of "latest", "safe", "finalized", "earliest" or "pending" */ + block: BlockNumber | BlockTag, + /** true will pull full transaction objects, false will pull transaction hashes */ + includeTransactionObjects: boolean + ]; + ReturnType: Block | null; + }, + /** + * @description Returns the number of transactions in a block specified by block hash + * @link https://eips.ethereum.org/EIPS/eip-1474 + * @example + * provider.request({ method: 'eth_getBlockTransactionCountByHash', params: ['0x...'] }) + * // => '0x1' + */ + { + Method: 'eth_getBlockTransactionCountByHash'; + Parameters: [hash: Hash]; + ReturnType: Quantity; + }, + /** + * @description Returns the number of transactions in a block specified by block number + * @link https://eips.ethereum.org/EIPS/eip-1474 + * @example + * provider.request({ method: 'eth_getBlockTransactionCountByNumber', params: ['0x1b4'] }) + * // => '0x1' + */ + { + Method: 'eth_getBlockTransactionCountByNumber'; + Parameters: [block: BlockNumber | BlockTag]; + ReturnType: Quantity; + }, + /** + * @description Returns the contract code stored at a given address + * @link https://eips.ethereum.org/EIPS/eip-1474 + * @example + * provider.request({ method: 'eth_getCode', params: ['0x...', 'latest'] }) + * // => '0x...' + */ + { + Method: 'eth_getCode'; + Parameters: [ + address: Address, + block: BlockNumber | BlockTag | BlockIdentifier + ]; + ReturnType: Hex; + }, + /** + * @description Returns a list of all logs based on filter ID since the last log retrieval + * @link https://eips.ethereum.org/EIPS/eip-1474 + * @example + * provider.request({ method: 'eth_getFilterChanges', params: ['0x...'] }) + * // => [{ ... }, { ... }] + */ + { + Method: 'eth_getFilterChanges'; + Parameters: [filterId: Quantity]; + ReturnType: Log[] | Hex[]; + }, + /** + * @description Returns a list of all logs based on filter ID + * @link https://eips.ethereum.org/EIPS/eip-1474 + * @example + * provider.request({ method: 'eth_getFilterLogs', params: ['0x...'] }) + * // => [{ ... }, { ... }] + */ + { + Method: 'eth_getFilterLogs'; + Parameters: [filterId: Quantity]; + ReturnType: Log[]; + }, + /** + * @description Returns a list of all logs based on a filter object + * @link https://eips.ethereum.org/EIPS/eip-1474 + * @example + * provider.request({ method: 'eth_getLogs', params: [{ fromBlock: '0x...', toBlock: '0x...', address: '0x...', topics: ['0x...'] }] }) + * // => [{ ... }, { ... }] + */ + { + Method: 'eth_getLogs'; + Parameters: [ + { + address?: Address | Address[] | undefined; + topics?: LogTopic[] | undefined; + } & ( + | { + fromBlock?: BlockNumber | BlockTag | undefined; + toBlock?: BlockNumber | BlockTag | undefined; + blockHash?: undefined; + } + | { + fromBlock?: undefined; + toBlock?: undefined; + blockHash?: Hash | undefined; + } + ) + ]; + ReturnType: Log[]; + }, + /** + * @description Returns the account and storage values of the specified account including the Merkle-proof. + * @link https://eips.ethereum.org/EIPS/eip-1186 + * @example + * provider.request({ method: 'eth_getProof', params: ['0x...', ['0x...'], 'latest'] }) + * // => { + * // ... + * // } + */ + { + Method: 'eth_getProof'; + Parameters: [ + /** Address of the account. */ + address: Address, + /** An array of storage-keys that should be proofed and included. */ + storageKeys: Hash[], + block: BlockNumber | BlockTag + ]; + ReturnType: Proof; + }, + /** + * @description Returns the value from a storage position at an address + * @link https://eips.ethereum.org/EIPS/eip-1474 + * @example + * provider.request({ method: 'eth_getStorageAt', params: ['0x...', '0x...', 'latest'] }) + * // => '0x...' + */ + { + Method: 'eth_getStorageAt'; + Parameters: [ + address: Address, + index: Quantity, + block: BlockNumber | BlockTag | BlockIdentifier + ]; + ReturnType: Hex; + }, + /** + * @description Returns information about a transaction specified by block hash and transaction index + * @link https://eips.ethereum.org/EIPS/eip-1474 + * @example + * provider.request({ method: 'eth_getTransactionByBlockHashAndIndex', params: ['0x...', '0x...'] }) + * // => { ... } + */ + { + Method: 'eth_getTransactionByBlockHashAndIndex'; + Parameters: [hash: Hash, index: Quantity]; + ReturnType: Transaction | null; + }, + /** + * @description Returns information about a transaction specified by block number and transaction index + * @link https://eips.ethereum.org/EIPS/eip-1474 + * @example + * provider.request({ method: 'eth_getTransactionByBlockNumberAndIndex', params: ['0x...', '0x...'] }) + * // => { ... } + */ + { + Method: 'eth_getTransactionByBlockNumberAndIndex'; + Parameters: [block: BlockNumber | BlockTag, index: Quantity]; + ReturnType: Transaction | null; + }, + /** + * @description Returns information about a transaction specified by hash + * @link https://eips.ethereum.org/EIPS/eip-1474 + * @example + * provider.request({ method: 'eth_getTransactionByHash', params: ['0x...'] }) + * // => { ... } + */ + { + Method: 'eth_getTransactionByHash'; + Parameters: [hash: Hash]; + ReturnType: Transaction | null; + }, + /** + * @description Returns the number of transactions sent from an address + * @link https://eips.ethereum.org/EIPS/eip-1474 + * @example + * provider.request({ method: 'eth_getTransactionCount', params: ['0x...', 'latest'] }) + * // => '0x1' + */ + { + Method: 'eth_getTransactionCount'; + Parameters: [ + address: Address, + block: BlockNumber | BlockTag | BlockIdentifier + ]; + ReturnType: Quantity; + }, + /** + * @description Returns the receipt of a transaction specified by hash + * @link https://eips.ethereum.org/EIPS/eip-1474 + * @example + * provider.request({ method: 'eth_getTransactionReceipt', params: ['0x...'] }) + * // => { ... } + */ + { + Method: 'eth_getTransactionReceipt'; + Parameters: [hash: Hash]; + ReturnType: TransactionReceipt | null; + }, + /** + * @description Returns information about an uncle specified by block hash and uncle index position + * @link https://eips.ethereum.org/EIPS/eip-1474 + * @example + * provider.request({ method: 'eth_getUncleByBlockHashAndIndex', params: ['0x...', '0x...'] }) + * // => { ... } + */ + { + Method: 'eth_getUncleByBlockHashAndIndex'; + Parameters: [hash: Hash, index: Quantity]; + ReturnType: Uncle | null; + }, + /** + * @description Returns information about an uncle specified by block number and uncle index position + * @link https://eips.ethereum.org/EIPS/eip-1474 + * @example + * provider.request({ method: 'eth_getUncleByBlockNumberAndIndex', params: ['0x...', '0x...'] }) + * // => { ... } + */ + { + Method: 'eth_getUncleByBlockNumberAndIndex'; + Parameters: [block: BlockNumber | BlockTag, index: Quantity]; + ReturnType: Uncle | null; + }, + /** + * @description Returns the number of uncles in a block specified by block hash + * @link https://eips.ethereum.org/EIPS/eip-1474 + * @example + * provider.request({ method: 'eth_getUncleCountByBlockHash', params: ['0x...'] }) + * // => '0x1' + */ + { + Method: 'eth_getUncleCountByBlockHash'; + Parameters: [hash: Hash]; + ReturnType: Quantity; + }, + /** + * @description Returns the number of uncles in a block specified by block number + * @link https://eips.ethereum.org/EIPS/eip-1474 + * @example + * provider.request({ method: 'eth_getUncleCountByBlockNumber', params: ['0x...'] }) + * // => '0x1' + */ + { + Method: 'eth_getUncleCountByBlockNumber'; + Parameters: [block: BlockNumber | BlockTag]; + ReturnType: Quantity; + }, + /** + * @description Returns the current maxPriorityFeePerGas in wei. + * @link https://ethereum.github.io/execution-apis/api-documentation/ + * @example + * provider.request({ method: 'eth_maxPriorityFeePerGas' }) + * // => '0x5f5e100' + */ + { + Method: 'eth_maxPriorityFeePerGas'; + Parameters?: undefined; + ReturnType: Quantity; + }, + /** + * @description Creates a filter to listen for new blocks that can be used with `eth_getFilterChanges` + * @link https://eips.ethereum.org/EIPS/eip-1474 + * @example + * provider.request({ method: 'eth_newBlockFilter' }) + * // => '0x1' + */ + { + Method: 'eth_newBlockFilter'; + Parameters?: undefined; + ReturnType: Quantity; + }, + /** + * @description Creates a filter to listen for specific state changes that can then be used with `eth_getFilterChanges` + * @link https://eips.ethereum.org/EIPS/eip-1474 + * @example + * provider.request({ method: 'eth_newFilter', params: [{ fromBlock: '0x...', toBlock: '0x...', address: '0x...', topics: ['0x...'] }] }) + * // => '0x1' + */ + { + Method: 'eth_newFilter'; + Parameters: [ + filter: { + fromBlock?: BlockNumber | BlockTag | undefined; + toBlock?: BlockNumber | BlockTag | undefined; + address?: Address | Address[] | undefined; + topics?: LogTopic[] | undefined; + } + ]; + ReturnType: Quantity; + }, + /** + * @description Creates a filter to listen for new pending transactions that can be used with `eth_getFilterChanges` + * @link https://eips.ethereum.org/EIPS/eip-1474 + * @example + * provider.request({ method: 'eth_newPendingTransactionFilter' }) + * // => '0x1' + */ + { + Method: 'eth_newPendingTransactionFilter'; + Parameters?: undefined; + ReturnType: Quantity; + }, + /** + * @description Returns the current Ethereum protocol version + * @link https://eips.ethereum.org/EIPS/eip-1474 + * @example + * provider.request({ method: 'eth_protocolVersion' }) + * // => '54' + */ + { + Method: 'eth_protocolVersion'; + Parameters?: undefined; + ReturnType: string; + }, + /** + * @description Sends a **signed** transaction to the network + * @link https://eips.ethereum.org/EIPS/eip-1474 + * @example + * provider.request({ method: 'eth_sendRawTransaction', params: ['0x...'] }) + * // => '0x...' + */ + { + Method: 'eth_sendRawTransaction'; + Parameters: [signedTransaction: Hex]; + ReturnType: Hash; + }, + /** + * @description Destroys a filter based on filter ID + * @link https://eips.ethereum.org/EIPS/eip-1474 + * @example + * provider.request({ method: 'eth_uninstallFilter', params: ['0x1'] }) + * // => true + */ + { + Method: 'eth_uninstallFilter'; + Parameters: [filterId: Quantity]; + ReturnType: boolean; + } +]; + +export type WalletRpcSchema = [ + /** + * @description Returns a list of addresses owned by this client + * @link https://eips.ethereum.org/EIPS/eip-1474 + * @example + * provider.request({ method: 'eth_accounts' }) + * // => ['0x0fB69...'] + */ + { + Method: 'eth_accounts'; + Parameters?: undefined; + ReturnType: Address[]; + }, + /** + * @description Returns the current chain ID associated with the wallet. + * @example + * provider.request({ method: 'eth_chainId' }) + * // => '1' + */ + { + Method: 'eth_chainId'; + Parameters?: undefined; + ReturnType: Quantity; + }, + /** + * @description Estimates the gas necessary to complete a transaction without submitting it to the network + * + * @example + * provider.request({ + * method: 'eth_estimateGas', + * params: [{ from: '0x...', to: '0x...', value: '0x...' }] + * }) + * // => '0x5208' + */ + { + Method: 'eth_estimateGas'; + Parameters: + | [transaction: TransactionRequest] + | [transaction: TransactionRequest, block: BlockNumber | BlockTag] + | [ + transaction: TransactionRequest, + block: BlockNumber | BlockTag, + stateOverride: RpcStateOverride + ]; + ReturnType: Quantity; + }, + /** + * @description Requests that the user provides an Ethereum address to be identified by. Typically causes a browser extension popup to appear. + * @link https://eips.ethereum.org/EIPS/eip-1102 + * @example + * provider.request({ method: 'eth_requestAccounts' }] }) + * // => ['0x...', '0x...'] + */ + { + Method: 'eth_requestAccounts'; + Parameters?: undefined; + ReturnType: Address[]; + }, + /** + * @description Creates, signs, and sends a new transaction to the network + * @link https://eips.ethereum.org/EIPS/eip-1474 + * @example + * provider.request({ method: 'eth_sendTransaction', params: [{ from: '0x...', to: '0x...', value: '0x...' }] }) + * // => '0x...' + */ + { + Method: 'eth_sendTransaction'; + Parameters: [transaction: TransactionRequest]; + ReturnType: Hash; + }, + /** + * @description Sends and already-signed transaction to the network + * @link https://eips.ethereum.org/EIPS/eip-1474 + * @example + * provider.request({ method: 'eth_sendRawTransaction', params: ['0x...'] }) + * // => '0x...' + */ + { + Method: 'eth_sendRawTransaction'; + Parameters: [signedTransaction: Hex]; + ReturnType: Hash; + }, + /** + * @description Calculates an Ethereum-specific signature in the form of `keccak256("\x19Ethereum Signed Message:\n" + len(message) + message))` + * @link https://eips.ethereum.org/EIPS/eip-1474 + * @example + * provider.request({ method: 'eth_sign', params: ['0x...', '0x...'] }) + * // => '0x...' + */ + { + Method: 'eth_sign'; + Parameters: [ + /** Address to use for signing */ + address: Address, + /** Data to sign */ + data: Hex + ]; + ReturnType: Hex; + }, + /** + * @description Signs a transaction that can be submitted to the network at a later time using with `eth_sendRawTransaction` + * @link https://eips.ethereum.org/EIPS/eip-1474 + * @example + * provider.request({ method: 'eth_signTransaction', params: [{ from: '0x...', to: '0x...', value: '0x...' }] }) + * // => '0x...' + */ + { + Method: 'eth_signTransaction'; + Parameters: [request: TransactionRequest]; + ReturnType: Hex; + }, + /** + * @description Calculates an Ethereum-specific signature in the form of `keccak256("\x19Ethereum Signed Message:\n" + len(message) + message))` + * @link https://eips.ethereum.org/EIPS/eip-1474 + * @example + * provider.request({ method: 'eth_signTypedData_v4', params: [{ from: '0x...', data: [{ type: 'string', name: 'message', value: 'hello world' }] }] }) + * // => '0x...' + */ + { + Method: 'eth_signTypedData_v4'; + Parameters: [ + /** Address to use for signing */ + address: Address, + /** Message to sign containing type information, a domain separator, and data */ + message: string + ]; + ReturnType: Hex; + }, + /** + * @description Returns information about the status of this client’s network synchronization + * @link https://eips.ethereum.org/EIPS/eip-1474 + * @example + * provider.request({ method: 'eth_syncing' }) + * // => { startingBlock: '0x...', currentBlock: '0x...', highestBlock: '0x...' } + */ + { + Method: 'eth_syncing'; + Parameters?: undefined; + ReturnType: NetworkSync | false; + }, + /** + * @description Calculates an Ethereum-specific signature in the form of `keccak256("\x19Ethereum Signed Message:\n" + len(message) + message))` + * @link https://eips.ethereum.org/EIPS/eip-1474 + * @example + * provider.request({ method: 'personal_sign', params: ['0x...', '0x...'] }) + * // => '0x...' + */ + { + Method: 'personal_sign'; + Parameters: [ + /** Data to sign */ + data: Hex, + /** Address to use for signing */ + address: Address + ]; + ReturnType: Hex; + }, + /** + * @description Add an Ethereum chain to the wallet. + * @link https://eips.ethereum.org/EIPS/eip-3085 + * @example + * provider.request({ method: 'wallet_addEthereumChain', params: [{ chainId: 1, rpcUrl: 'https://mainnet.infura.io/v3/...' }] }) + * // => { ... } + */ + { + Method: 'wallet_addEthereumChain'; + Parameters: [chain: AddEthereumChainParameter]; + ReturnType: null; + }, + /** + * @description Returns the status of a call batch that was sent via `wallet_sendCalls`. + * @link https://eips.ethereum.org/EIPS/eip-5792 + * @example + * provider.request({ method: 'wallet_getCallsStatus' }) + * // => { ... } + */ + { + Method: 'wallet_getCallsStatus'; + Parameters?: [string]; + ReturnType: WalletGetCallsStatusReturnType; + }, + /** + * @description Gets the connected wallet's capabilities. + * @link https://eips.ethereum.org/EIPS/eip-5792 + * @example + * provider.request({ method: 'wallet_getCapabilities' }) + * // => { ... } + */ + { + Method: 'wallet_getCapabilities'; + Parameters?: [Address]; + ReturnType: Prettify; + }, + /** + * @description Gets the wallets current permissions. + * @link https://eips.ethereum.org/EIPS/eip-2255 + * @example + * provider.request({ method: 'wallet_getPermissions' }) + * // => { ... } + */ + { + Method: 'wallet_getPermissions'; + Parameters?: undefined; + ReturnType: WalletPermission[]; + }, + /** + * @description Requests permissions from a wallet + * @link https://eips.ethereum.org/EIPS/eip-7715 + * @example + * provider.request({ method: 'wallet_grantPermissions', params: [{ ... }] }) + * // => { ... } + */ + { + Method: 'wallet_grantPermissions'; + Parameters?: [WalletGrantPermissionsParameters]; + ReturnType: Prettify; + }, + /** + * @description Requests the given permissions from the user. + * @link https://eips.ethereum.org/EIPS/eip-2255 + * @example + * provider.request({ method: 'wallet_requestPermissions', params: [{ eth_accounts: {} }] }) + * // => { ... } + */ + { + Method: 'wallet_requestPermissions'; + Parameters: [permissions: { eth_accounts: Record }]; + ReturnType: WalletPermission[]; + }, + /** + * @description Revokes the given permissions from the user. + * @link https://github.com/MetaMask/metamask-improvement-proposals/blob/main/MIPs/mip-2.md + * @example + * provider.request({ method: 'wallet_revokePermissions', params: [{ eth_accounts: {} }] }) + * // => { ... } + */ + { + Method: 'wallet_revokePermissions'; + Parameters: [permissions: { eth_accounts: Record }]; + ReturnType: null; + }, + /** + * @description Requests the connected wallet to send a batch of calls. + * @link https://eips.ethereum.org/EIPS/eip-5792 + * @example + * provider.request({ method: 'wallet_sendCalls' }) + * // => { ... } + */ + { + Method: 'wallet_sendCalls'; + Parameters?: WalletSendCallsParameters; + ReturnType: string; + }, + /** + * @description Requests for the wallet to show information about a call batch + * that was sent via `wallet_sendCalls`. + * @link https://eips.ethereum.org/EIPS/eip-5792 + * @example + * provider.request({ method: 'wallet_showCallsStatus', params: ['...'] }) + */ + { + Method: 'wallet_showCallsStatus'; + Parameters?: [string]; + ReturnType: void; + }, + /** + * @description Switch the wallet to the given Ethereum chain. + * @link https://eips.ethereum.org/EIPS/eip-3326 + * @example + * provider.request({ method: 'wallet_switchEthereumChain', params: [{ chainId: '0xf00' }] }) + * // => { ... } + */ + { + Method: 'wallet_switchEthereumChain'; + Parameters: [chain: { chainId: string }]; + ReturnType: null; + }, + /** + * @description Requests that the user tracks the token in their wallet. Returns a boolean indicating if the token was successfully added. + * @link https://eips.ethereum.org/EIPS/eip-747 + * @example + * provider.request({ method: 'wallet_watchAsset' }] }) + * // => true + */ + { + Method: 'wallet_watchAsset'; + Parameters: WatchAssetParams; + ReturnType: boolean; + } +]; + +export type BundlerRpcSchema = [ + /** + * @description Returns the chain ID associated with the current network + * + * @link https://eips.ethereum.org/EIPS/eip-4337#-eth_chainid + */ + { + Method: 'eth_chainId'; + Parameters?: undefined; + ReturnType: Hex; + }, + /** + * @description Estimate the gas values for a UserOperation. + * + * @link https://eips.ethereum.org/EIPS/eip-4337#-eth_estimateuseroperationgas + * + * @example + * provider.request({ + * method: 'eth_estimateUserOperationGas', + * params: [{ ... }] + * }) + * // => { ... } + */ + { + Method: 'eth_estimateUserOperationGas'; + Parameters: + | [userOperation: RpcUserOperation, entrypoint: Address] + | [ + userOperation: RpcUserOperation, + entrypoint: Address, + stateOverrideSet: RpcStateOverride + ]; + ReturnType: RpcEstimateUserOperationGasReturnType; + }, + /** + * @description Return a UserOperation based on a hash. + * + * @link https://eips.ethereum.org/EIPS/eip-4337#-eth_getuseroperationbyhash + * + * @example + * provider.request({ + * method: 'eth_getUserOperationByHash', + * params: ['0x...'] + * }) + * // => { ... } + */ + { + Method: 'eth_getUserOperationByHash'; + Parameters: [hash: Hash]; + ReturnType: RpcGetUserOperationByHashReturnType | null; + }, + /** + * @description Return a UserOperation receipt based on a hash. + * + * @link https://eips.ethereum.org/EIPS/eip-4337#-eth_getuseroperationreceipt + * + * @example + * provider.request({ + * method: 'eth_getUserOperationReceipt', + * params: ['0x...'] + * }) + * // => { ... } + */ + { + Method: 'eth_getUserOperationReceipt'; + Parameters: [hash: Hash]; + ReturnType: RpcUserOperationReceipt | null; + }, + /** + * @description Submits a User Operation object to the User Operation pool of the client. + * + * @link https://eips.ethereum.org/EIPS/eip-4337#-eth_senduseroperation + * + * @example + * provider.request({ + * method: 'eth_sendUserOperation', + * params: [{ ... }] + * }) + * // => '0x...' + */ + { + Method: 'eth_sendUserOperation'; + Parameters: [userOperation: RpcUserOperation, entrypoint: Address]; + ReturnType: Hash; + }, + /** + * @description Return the list of supported entry points by the client. + * + * @link https://eips.ethereum.org/EIPS/eip-4337#-eth_supportedentrypoints + */ + { + Method: 'eth_supportedEntryPoints'; + Parameters?: undefined; + ReturnType: readonly Address[]; + } +]; + +export type PaymasterRpcSchema = [ + /** + * @description Returns the chain ID associated with the current network + * + * @link https://eips.ethereum.org/EIPS/eip-4337#-eth_chainid + */ + { + Method: 'pm_getPaymasterStubData'; + Parameters?: [ + userOperation: OneOf< + | PartialBy< + Pick< + RpcUserOperation<'0.6'>, + | 'callData' + | 'callGasLimit' + | 'initCode' + | 'maxFeePerGas' + | 'maxPriorityFeePerGas' + | 'nonce' + | 'sender' + | 'preVerificationGas' + | 'verificationGasLimit' + >, + | 'callGasLimit' + | 'initCode' + | 'maxFeePerGas' + | 'maxPriorityFeePerGas' + | 'preVerificationGas' + | 'verificationGasLimit' + > + | PartialBy< + Pick< + RpcUserOperation<'0.7'>, + | 'callData' + | 'callGasLimit' + | 'factory' + | 'factoryData' + | 'maxFeePerGas' + | 'maxPriorityFeePerGas' + | 'nonce' + | 'sender' + | 'preVerificationGas' + | 'verificationGasLimit' + >, + | 'callGasLimit' + | 'factory' + | 'factoryData' + | 'maxFeePerGas' + | 'maxPriorityFeePerGas' + | 'preVerificationGas' + | 'verificationGasLimit' + > + >, + entrypoint: Address, + chainId: Hex, + context: unknown + ]; + ReturnType: OneOf< + | { paymasterAndData: Hex } + | { + paymaster: Address; + paymasterData: Hex; + paymasterVerificationGasLimit: Hex; + paymasterPostOpGasLimit: Hex; + } + > & { + sponsor?: { name: string; icon?: string | undefined } | undefined; + isFinal?: boolean | undefined; + }; + }, + /** + * @description Returns values to be used in paymaster-related fields of a signed user operation. + * + * @link https://github.com/ethereum/ERCs/blob/master/ERCS/erc-7677.md#pm_getpaymasterdata + */ + { + Method: 'pm_getPaymasterData'; + Parameters?: [ + userOperation: + | Pick< + RpcUserOperation<'0.6'>, + | 'callData' + | 'callGasLimit' + | 'initCode' + | 'maxFeePerGas' + | 'maxPriorityFeePerGas' + | 'nonce' + | 'sender' + | 'preVerificationGas' + | 'verificationGasLimit' + > + | Pick< + RpcUserOperation<'0.7'>, + | 'callData' + | 'callGasLimit' + | 'factory' + | 'factoryData' + | 'maxFeePerGas' + | 'maxPriorityFeePerGas' + | 'nonce' + | 'sender' + | 'preVerificationGas' + | 'verificationGasLimit' + >, + entrypoint: Address, + chainId: Hex, + context: unknown + ]; + ReturnType: OneOf< + | { paymasterAndData: Hex } + | { + paymaster: Address; + paymasterData: Hex; + paymasterVerificationGasLimit: Hex; + paymasterPostOpGasLimit: Hex; + } + >; + } +]; + +export type EIP1474Methods = [ + ...PublicRpcSchema, + ...WalletRpcSchema, + ...BundlerRpcSchema, + ...PaymasterRpcSchema +]; + +export type EIP1193Provider = EIP1193Events & { + request: EIP1193RequestFn; +}; diff --git a/wallets/core/src/namespaces/evm/mod.ts b/wallets/core/src/namespaces/evm/mod.ts new file mode 100644 index 0000000000..9b45bbd158 --- /dev/null +++ b/wallets/core/src/namespaces/evm/mod.ts @@ -0,0 +1,9 @@ +export * as actions from './actions.js'; +export * as after from './after.js'; +export * as and from './and.js'; +export * as before from './before.js'; +export * as utils from './utils.js'; +export * as builders from './builders.js'; + +export type { EvmActions, ProviderAPI } from './types.js'; +export { CAIP_NAMESPACE, CAIP_ETHEREUM_CHAIN_ID } from './constants.js'; diff --git a/wallets/core/src/namespaces/evm/types.ts b/wallets/core/src/namespaces/evm/types.ts new file mode 100644 index 0000000000..a1c5bac375 --- /dev/null +++ b/wallets/core/src/namespaces/evm/types.ts @@ -0,0 +1,18 @@ +import type { AddEthereumChainParameter } from './eip1193.js'; +import type { AccountsWithActiveChain } from '../../types/accounts.js'; +import type { + AutoImplementedActionsByRecommended, + CommonActions, +} from '../common/types.js'; + +export interface EvmActions + extends AutoImplementedActionsByRecommended, + CommonActions { + connect: (chain?: Chain | ChainId) => Promise; +} + +export type { EIP1193Provider as ProviderAPI } from './eip1193.js'; + +// A 0x-prefixed hexadecimal string +export type ChainId = string; +export type Chain = AddEthereumChainParameter; diff --git a/wallets/core/src/namespaces/evm/utils.ts b/wallets/core/src/namespaces/evm/utils.ts new file mode 100644 index 0000000000..4399eafed0 --- /dev/null +++ b/wallets/core/src/namespaces/evm/utils.ts @@ -0,0 +1,52 @@ +import type { Chain, ChainId, ProviderAPI } from './types.js'; + +export async function getAccounts(provider: ProviderAPI) { + const [accounts, chainId] = await Promise.all([ + provider.request({ method: 'eth_requestAccounts' }), + provider.request({ method: 'eth_chainId' }), + ]); + + return { + accounts, + chainId, + }; +} + +export async function suggestNetwork(instance: ProviderAPI, chain: Chain) { + return await instance.request({ + method: 'wallet_addEthereumChain', + params: [chain], + }); +} + +export async function switchNetwork(instance: ProviderAPI, chainId: ChainId) { + return await instance.request({ + method: 'wallet_switchEthereumChain', + params: [{ chainId: chainId }], + }); +} + +export async function switchOrAddNetwork( + instance: ProviderAPI, + chain: ChainId | Chain +) { + try { + const chainId = typeof chain === 'string' ? chain : chain.chainId; + await switchNetwork(instance, chainId); + } catch (switchError) { + const error = switchError as { code: number }; + + const NOT_FOUND_CHAIN_ERROR_CODE = 4902; + if ( + typeof chain !== 'string' && + (error.code === NOT_FOUND_CHAIN_ERROR_CODE || !error.code) + ) { + /* + * Note: on WalletConnect `code` is undefined so we have to use !switchError.code as fallback. + * This error code indicates that the chain has not been added to wallet. + */ + await suggestNetwork(instance, chain); + } + throw switchError; + } +} diff --git a/wallets/core/src/namespaces/solana/actions.ts b/wallets/core/src/namespaces/solana/actions.ts new file mode 100644 index 0000000000..48517a49ff --- /dev/null +++ b/wallets/core/src/namespaces/solana/actions.ts @@ -0,0 +1,70 @@ +import type { ProviderAPI, SolanaActions } from './types.js'; +import type { Subscriber } from '../../hub/namespaces/mod.js'; +import type { SubscriberCleanUp } from '../../hub/namespaces/types.js'; +import type { AnyFunction } from '../../types/actions.js'; + +import { AccountId } from 'caip'; + +import { recommended as commonRecommended } from '../common/actions.js'; + +import { CAIP_NAMESPACE, CAIP_SOLANA_CHAIN_ID } from './constants.js'; + +export const recommended = [...commonRecommended]; + +export function changeAccountSubscriber( + instance: () => ProviderAPI | undefined +): [Subscriber, SubscriberCleanUp] { + let eventCallback: AnyFunction; + + // subscriber can be passed to `or`, it will get the error and should rethrow error to pass the error to next `or` or throw error. + return [ + (context, err) => { + const solanaInstance = instance(); + + if (!solanaInstance) { + throw new Error( + 'Trying to subscribe to your Solana wallet, but seems its instance is not available.' + ); + } + + const [, setState] = context.state(); + + eventCallback = (publicKey) => { + /* + * In Phantom, when user is switching to an account which is not connected to dApp yet, it returns a null. + * So null means we don't have access to account and we 0 need to disconnect and let the user connect the account. + */ + if (!publicKey) { + context.action('disconnect'); + return; + } + + setState('accounts', [ + AccountId.format({ + address: publicKey.toString(), + chainId: { + namespace: CAIP_NAMESPACE, + reference: CAIP_SOLANA_CHAIN_ID, + }, + }), + ]); + }; + solanaInstance.on('accountChanged', eventCallback); + + if (err instanceof Error) { + throw err; + } + }, + (_context, err) => { + const solanaInstance = instance(); + + if (eventCallback && solanaInstance) { + solanaInstance.off('accountChanged', eventCallback); + } + + if (err instanceof Error) { + throw err; + } + }, + ]; +} diff --git a/wallets/core/src/namespaces/solana/after.ts b/wallets/core/src/namespaces/solana/after.ts new file mode 100644 index 0000000000..229710d3bf --- /dev/null +++ b/wallets/core/src/namespaces/solana/after.ts @@ -0,0 +1,3 @@ +import { recommended as commonRecommended } from '../common/after.js'; + +export const recommended = [...commonRecommended]; diff --git a/wallets/core/src/namespaces/solana/and.ts b/wallets/core/src/namespaces/solana/and.ts new file mode 100644 index 0000000000..0eb8ef6141 --- /dev/null +++ b/wallets/core/src/namespaces/solana/and.ts @@ -0,0 +1,5 @@ +import { connectAndUpdateStateForSingleNetwork } from '../common/mod.js'; + +export const recommended = [ + ['connect', connectAndUpdateStateForSingleNetwork] as const, +]; diff --git a/wallets/core/src/namespaces/solana/before.ts b/wallets/core/src/namespaces/solana/before.ts new file mode 100644 index 0000000000..ceeb4ffad1 --- /dev/null +++ b/wallets/core/src/namespaces/solana/before.ts @@ -0,0 +1,3 @@ +import { recommended as commonRecommended } from '../common/before.js'; + +export const recommended = [...commonRecommended]; diff --git a/wallets/core/src/namespaces/solana/builders.ts b/wallets/core/src/namespaces/solana/builders.ts new file mode 100644 index 0000000000..73f4dc1d24 --- /dev/null +++ b/wallets/core/src/namespaces/solana/builders.ts @@ -0,0 +1,10 @@ +import type { SolanaActions } from './types.js'; + +import { ActionBuilder } from '../../mod.js'; +import { intoConnectionFinished } from '../common/after.js'; +import { connectAndUpdateStateForSingleNetwork } from '../common/and.js'; + +export const connect = () => + new ActionBuilder('connect') + .and(connectAndUpdateStateForSingleNetwork) + .after(intoConnectionFinished); diff --git a/wallets/core/src/namespaces/solana/constants.ts b/wallets/core/src/namespaces/solana/constants.ts new file mode 100644 index 0000000000..31d6877448 --- /dev/null +++ b/wallets/core/src/namespaces/solana/constants.ts @@ -0,0 +1,2 @@ +export const CAIP_NAMESPACE = 'solana'; +export const CAIP_SOLANA_CHAIN_ID = '5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp'; diff --git a/wallets/core/src/namespaces/solana/mod.ts b/wallets/core/src/namespaces/solana/mod.ts new file mode 100644 index 0000000000..7b797d47dd --- /dev/null +++ b/wallets/core/src/namespaces/solana/mod.ts @@ -0,0 +1,8 @@ +export * as actions from './actions.js'; +export * as after from './after.js'; +export * as and from './and.js'; +export * as before from './before.js'; +export * as builders from './builders.js'; + +export type { ProviderAPI, SolanaActions } from './types.js'; +export { CAIP_NAMESPACE, CAIP_SOLANA_CHAIN_ID } from './constants.js'; diff --git a/wallets/core/src/namespaces/solana/types.ts b/wallets/core/src/namespaces/solana/types.ts new file mode 100644 index 0000000000..1023a92324 --- /dev/null +++ b/wallets/core/src/namespaces/solana/types.ts @@ -0,0 +1,20 @@ +import type { Accounts } from '../../types/accounts.js'; +import type { + AutoImplementedActionsByRecommended, + CommonActions, +} from '../common/types.js'; + +export interface SolanaActions + extends AutoImplementedActionsByRecommended, + CommonActions { + connect: () => Promise; +} + +/* + * + * TODO: That would be better to define a type for Solana injected wallets. + * They have something called [Wallet Standard](https://github.com/wallet-standard/wallet-standard) but not sure all the Solana wallets support that (Phantom do). + * If Phantom's interface is what Solana wallets are supporting, another option would be define that type here. + * + */ +export type ProviderAPI = Record; diff --git a/wallets/core/src/provider.tsx b/wallets/core/src/provider.tsx deleted file mode 100644 index 5e8bcc3261..0000000000 --- a/wallets/core/src/provider.tsx +++ /dev/null @@ -1,255 +0,0 @@ -import React, { - createContext, - useContext, - useEffect, - useReducer, - useRef, -} from 'react'; - -import { - availableWallets, - checkWalletProviders, - connectedWallets, - defaultWalletState, - getComptaibleProvider, - state_reducer, -} from './helpers'; -import { - ProviderProps, - ProviderContext, - WalletActions, - WalletConfig, -} from './types'; -import { WalletType } from '@rango-dev/wallets-shared'; - -import Wallet, { EventHandler as WalletEventHandler } from './wallet'; - -// TODO fix lint problem -// eslint-disable-next-line @typescript-eslint/ban-ts-comment -// @ts-ignore -const WalletContext = createContext({}); - -/* - Our event handler includes an internal state updater, and a notifier - for the outside listener. - On creating first wallet refrence, and on chaning `props.onUpdateState` - we are using this function. -*/ -function makeEventHandler(dispatcher: any, onUpdateState?: WalletEventHandler) { - const handler: WalletEventHandler = ( - type, - name, - value, - coreState, - supportedChains - ) => { - const action = { type: 'new_state', wallet: type, name, value }; - // Update state - dispatcher(action); - - // Giving the event to the outside listener - if (onUpdateState) { - onUpdateState(type, name, value, coreState, supportedChains); - } - }; - - return handler; -} - -function useInitializers(onChangeState: WalletEventHandler) { - const availableWallets = useRef<{ - [key in WalletType]?: Wallet; - }>({}); - - function updater(wallet: { - actions: WalletActions; - config: WalletConfig; - }): Wallet { - const type = wallet.config.type; - // We only update, if there is no instance available. - if (typeof availableWallets.current[type] === 'undefined') { - availableWallets.current[type] = new Wallet( - { - config: wallet.config, - handler: onChangeState, - }, - wallet.actions - ); - } - - return availableWallets.current[type]!; - } - - return updater; -} - -function Provider(props: ProviderProps) { - const [providersState, dispatch] = useReducer(state_reducer, {}); - - const addWalletRef = useInitializers( - makeEventHandler(dispatch, props.onUpdateState) - ); - // const providersRef = useRef<{ [type in WalletType]?: any }>({}); - - const listOfProviders = props.providers; - const wallets = checkWalletProviders(listOfProviders); - const api: ProviderContext = { - // TODO: Fix type error - // @ts-ignore - async connect(type, network) { - const wallet = wallets.get(type); - if (!wallet) { - throw new Error(`You should add ${type} to provider first.`); - } - - const ref = addWalletRef(wallet); - const result = await ref.connect(network); - - return result; - }, - async disconnect(type) { - const wallet = wallets.get(type); - if (!wallet) { - throw new Error(`You should add ${type} to provider first.`); - } - - const ref = addWalletRef(wallet); - await ref.disconnect(); - }, - async disconnectAll() { - const disconnect_promises: Promise[] = []; - - // When a wallet is initializing, a record will be added to `providersState` - // So we use them to know what wallet has been initialized then we need to - // filter connected wallets only. - connectedWallets(providersState).forEach((type) => { - const wallet = wallets.get(type); - - if (!!wallet) { - const ref = addWalletRef(wallet); - disconnect_promises.push(ref.disconnect()); - } - }); - - return await Promise.allSettled(disconnect_promises); - }, - state(type) { - return providersState[type] || defaultWalletState; - }, - canSwitchNetworkTo(type, network) { - const wallet = wallets.get(type); - if (!wallet) { - return false; - } - - const ref = addWalletRef(wallet); - return ref.canSwitchNetworkTo ? ref.canSwitchNetworkTo(network) : false; - }, - providers() { - const providers: { [type in WalletType]?: any } = {}; - availableWallets(providersState).forEach((type) => { - const wallet = wallets.get(type); - if (!!wallet) { - const ref = addWalletRef(wallet); - providers[type] = ref.provider; - } - }); - - return providers; - }, - getWalletInfo(type) { - const wallet = wallets.get(type); - if (!wallet) { - throw new Error(`You should add ${type} to provider first.`); - } - - // Get wallet info could be used in render methods to show wallets data - // So, addWalletRef method shouldn't be called in this method - - return wallet.actions.getWalletInfo(props.allBlockChains || []); - }, - getSigners(type) { - const wallet = wallets.get(type); - - if (!wallet) { - throw new Error(`You should add ${type} to provider first.`); - } - const ref = addWalletRef(wallet); - const supportedChains = ref.getWalletInfo( - props.allBlockChains || [] - ).supportedChains; - const provider = getComptaibleProvider( - supportedChains, - ref.provider, - type - ); - const result = ref.getSigners(provider); - - return result; - }, - }; - - useEffect(() => { - wallets.forEach((wallet) => { - const ref = addWalletRef(wallet); - const runOnInit = () => { - if (!!ref.onInit) { - ref.onInit(); - } - }; - - const initWhenPageIsReady = (event: Event) => { - if ( - event.target && - (event.target as Document).readyState === 'complete' - ) { - runOnInit(); - - document.removeEventListener('readystatechange', initWhenPageIsReady); - } - }; - - // Try to run, maybe it's ready. - runOnInit(); - - // Try again when the page has been completely loaded. - // Some of wallets, take some time to be fully injected and loaded. - document.addEventListener('readystatechange', initWhenPageIsReady); - }); - }, []); - - useEffect(() => { - const allBlockChains = props.allBlockChains; - if (!!allBlockChains) { - wallets.forEach((wallet) => { - const ref = addWalletRef(wallet); - const supportedChains = ref.getWalletInfo( - props.allBlockChains || [] - ).supportedChains; - ref.setMeta(supportedChains); - }); - } - }, [props.allBlockChains]); - - useEffect(() => { - wallets.forEach((wallet) => { - const ref = addWalletRef(wallet); - ref.setHandler(makeEventHandler(dispatch, props.onUpdateState)); - }); - }, [props.onUpdateState]); - - return ( - - {props.children} - - ); -} - -export function useWallets(): ProviderContext { - const context = useContext(WalletContext); - if (!context) - throw Error('useWallet can only be used within the Provider component'); - return context; -} - -export default Provider; diff --git a/wallets/core/src/test-utils/fixtures.ts b/wallets/core/src/test-utils/fixtures.ts new file mode 100644 index 0000000000..f4c15f5cf2 --- /dev/null +++ b/wallets/core/src/test-utils/fixtures.ts @@ -0,0 +1,9 @@ +import type { ProviderConfig } from '../hub/store/mod.js'; + +export const garbageWalletInfo: ProviderConfig['info'] = { + name: 'Garbage Wallet', + icon: 'https://somewhereininternet.com/icon.svg', + extensions: { + homepage: 'https://app.rango.exchange', + }, +}; diff --git a/wallets/core/src/types.ts b/wallets/core/src/types.ts deleted file mode 100644 index 2e940c611a..0000000000 --- a/wallets/core/src/types.ts +++ /dev/null @@ -1,126 +0,0 @@ -import { PropsWithChildren } from 'react'; -import { Network, WalletType, WalletInfo } from '@rango-dev/wallets-shared'; -import { - EventHandler as WalletEventHandler, - State as WalletState, -} from './wallet'; -import { SignerFactory, BlockchainMeta } from 'rango-types'; - -export type State = { - [key in WalletType]?: WalletState; -}; - -export type ConnectResult = { - accounts: string[] | null; - network: Network | null; - provider: any; -}; - -export type Providers = { [type in WalletType]?: any }; - -export type ProviderContext = { - connect(type: WalletType, network?: Network): Promise; - disconnect(type: WalletType): Promise; - disconnectAll(): Promise[]>; - state(type: WalletType): WalletState; - canSwitchNetworkTo(type: WalletType, network: Network): boolean; - providers(): Providers; - getSigners(type: WalletType): SignerFactory; - getWalletInfo(type: WalletType): WalletInfo; -}; - -export type ProviderProps = PropsWithChildren<{ - onUpdateState?: WalletEventHandler; - allBlockChains?: BlockchainMeta[]; - providers: WalletProvider[]; -}>; - -export enum Events { - CONNECTED = 'connected', - CONNECTING = 'connecting', - REACHABLE = 'reachable', - INSTALLED = 'installed', - ACCOUNTS = 'accounts', - NETWORK = 'network', -} - -export type ProviderConnectResult = { - accounts: string[]; - chainId: string; -}; - -export type GetInstanceOptions = { - network?: Network; - currentProvider: any; - meta: BlockchainMeta[]; - force?: boolean; -}; -export type GetInstance = - | (() => any) - | ((options: GetInstanceOptions) => Promise); -export type TryGetInstance = - | (() => any) - | ((options: Pick) => Promise); -export type Connect = (options: { - instance: any; - network?: Network; - meta: BlockchainMeta[]; -}) => Promise; - -export type Disconnect = (options: { - instance: any; - destroyInstance: () => void; -}) => Promise; -export type Subscribe = (options: { - instance: any; - state: WalletState; - meta: BlockchainMeta[]; - updateChainId: (chainId: string) => void; - updateAccounts: (accounts: string[], chainId?: string) => void; - connect: (network?: Network) => void; - disconnect: () => void; -}) => void; - -export type SwitchNetwork = (options: { - instance: any; - network: Network; - meta: BlockchainMeta[]; - newInstance?: TryGetInstance; -}) => Promise; - -export type CanSwitchNetwork = (options: { - network: Network; - meta: BlockchainMeta[]; -}) => boolean; - -export interface WalletActions { - connect: Connect; - getInstance: any; - disconnect?: Disconnect; - subscribe?: Subscribe; - // eagerConnect, // optional? - // unsubscribe, // coupled to subscribe. - - // Optional, but should be provided at the same time. - switchNetwork?: SwitchNetwork; - getSigners: (provider: any) => SignerFactory; - canSwitchNetworkTo?: CanSwitchNetwork; - getWalletInfo(allBlockChains: BlockchainMeta[]): WalletInfo; -} - -export interface WalletConfig { - type: WalletType; - defaultNetwork?: Network; - checkInstallation?: boolean; - isAsyncInstance?: boolean; -} - -export type WalletProviders = Map< - WalletType, - { - actions: WalletActions; - config: WalletConfig; - } ->; - -export type WalletProvider = { config: WalletConfig } & WalletActions; diff --git a/wallets/core/src/types/accounts.ts b/wallets/core/src/types/accounts.ts new file mode 100644 index 0000000000..e0df116e3f --- /dev/null +++ b/wallets/core/src/types/accounts.ts @@ -0,0 +1,12 @@ +type CaipNamespace = string; +type CaipChainId = string; +type CaipAccountAddress = string; + +export type CaipAccount = + `${CaipNamespace}:${CaipChainId}:${CaipAccountAddress}`; + +export type Accounts = CaipAccount[]; +export type AccountsWithActiveChain = { + accounts: Accounts; + network: string; +}; diff --git a/wallets/core/src/types/actions.ts b/wallets/core/src/types/actions.ts new file mode 100644 index 0000000000..1bba954708 --- /dev/null +++ b/wallets/core/src/types/actions.ts @@ -0,0 +1,11 @@ +export type AnyFunction = (...args: any[]) => any; +export type AnyPromiseFunction = (...args: any[]) => Promise; + +export type AndFunction< + T extends Record, + K extends keyof T +> = (result: Awaited>) => Awaited>; + +export type FunctionWithContext = T extends (...args: infer P) => infer R + ? (context: C, ...args: P) => R + : never; diff --git a/wallets/core/src/types/utils.ts b/wallets/core/src/types/utils.ts new file mode 100644 index 0000000000..8883c62fff --- /dev/null +++ b/wallets/core/src/types/utils.ts @@ -0,0 +1,7 @@ +/** + * @see https://x.com/mattpocockuk/status/1622730173446557697 + */ +export type Prettify = { + [K in keyof T]: T[K]; + // eslint-disable-next-line @typescript-eslint/ban-types +} & {}; diff --git a/wallets/core/src/utils/mod.ts b/wallets/core/src/utils/mod.ts new file mode 100644 index 0000000000..0870b202dd --- /dev/null +++ b/wallets/core/src/utils/mod.ts @@ -0,0 +1,8 @@ +/* + * It is not a good idea to re-export all of CAIP because if they have a breaking change, we will break as well. + * It would be better to create an abstraction over them and export our own interface to ensure it is under our control. + */ +export * as CAIP from 'caip'; + +export { generateStoreId } from '../hub/helpers.js'; +export * from './versions.js'; diff --git a/wallets/core/src/utils/versions.test.ts b/wallets/core/src/utils/versions.test.ts new file mode 100644 index 0000000000..c115b4b768 --- /dev/null +++ b/wallets/core/src/utils/versions.test.ts @@ -0,0 +1,22 @@ +import { describe, expect, test } from 'vitest'; + +import { defineVersions, pickVersion } from './versions.js'; + +describe('Picking versions should work correctly', () => { + test("Error on picking a version doesn't exist", () => { + const versions = defineVersions().build(); + // const versions: Versions = [['1.0.0', {}]]; + expect(() => pickVersion(versions, '1.0.0')).toThrowError(); + }); + + test('Pick the correct version if it exist', () => { + const versions = defineVersions() + .version('0.0.0', {} as any) + .version('1.0.0', {} as any) + .build(); + + const target = pickVersion(versions, '1.0.0'); + expect(target).toBeDefined(); + expect(target[0]).toBe('1.0.0'); + }); +}); diff --git a/wallets/core/src/utils/versions.ts b/wallets/core/src/utils/versions.ts new file mode 100644 index 0000000000..e28e1a8997 --- /dev/null +++ b/wallets/core/src/utils/versions.ts @@ -0,0 +1,62 @@ +import type { Provider } from '../hub/mod.js'; +import type { LegacyProviderInterface } from '../legacy/mod.js'; + +type LegacyVersioned = ['0.0.0', LegacyProviderInterface]; +type HubVersioned = ['1.0.0', Provider]; +type AvailableVersionedProviders = LegacyVersioned | HubVersioned; +export type VersionedProviders = AvailableVersionedProviders[]; +export type VersionInterface = T[1]; + +type SemVer = T extends [infer U, any] ? U : never; +type MatchVersion = Extract< + T[number], + [Version, any] +>; + +export function pickVersion< + L extends VersionedProviders, + V extends SemVer +>(list: L, targetVersion: V): MatchVersion { + if (!targetVersion) { + throw new Error(`You should provide a valid semver, e.g 1.0.0.`); + } + + const target = list.find(([version]) => version === targetVersion); + + if (!target) { + throw new Error( + `You target version hasn't been found. Available versions: ${Object.keys( + list + ).join(', ')}` + ); + } + return target as MatchVersion; +} + +interface DefineVersionsApi { + version: >( + semver: T, + value: VersionInterface> + ) => DefineVersionsApi; + build: () => VersionedProviders; +} + +export function defineVersions(): DefineVersionsApi { + const versions: VersionedProviders = []; + const api: DefineVersionsApi = { + version: (semver, value) => { + versions.push([semver, value]); + return api; + }, + build: () => { + return versions; + }, + }; + return api; +} + +export function legacyProviderImportsToVersionsInterface( + provider: LegacyProviderInterface +): VersionedProviders { + return defineVersions().version('0.0.0', provider).build(); +} diff --git a/wallets/core/src/wallet.ts b/wallets/core/src/wallet.ts deleted file mode 100644 index 3d62cf7342..0000000000 --- a/wallets/core/src/wallet.ts +++ /dev/null @@ -1,387 +0,0 @@ -import { - getBlockChainNameFromId, - Network, - WalletType, -} from '@rango-dev/wallets-shared'; -import { accountAddressesWithNetwork, needsCheckInstallation } from './helpers'; -import { - Events, - GetInstanceOptions, - WalletActions, - WalletConfig, -} from './types'; -import { BlockchainMeta } from 'rango-types'; - -export type EventHandler = ( - type: WalletType, - event: Events, - value: any, - coreState: State, - supportedChains: BlockchainMeta[] -) => void; - -export interface State { - connected: boolean; - connecting: boolean; - reachable: boolean; - installed: boolean; - accounts: string[] | null; - network: Network | null; -} - -export interface Options { - config: WalletConfig; - handler: EventHandler; -} - -class Wallet { - private actions: WalletActions; - private state: State; - private options: Options; - private meta: BlockchainMeta[]; - public provider: InstanceType | null; - - constructor(options: Options, actions: WalletActions) { - this.actions = actions; - this.options = options; - this.provider = null; - this.meta = []; - this.state = { - connected: false, - connecting: false, - // TODO: Remove - reachable: false, - installed: false, - accounts: null, - network: null, - }; - - if (!needsCheckInstallation(options)) { - this.setInstalledAs(true); - } - } - - async eagerConnection() { - // Already connected, so we return provider that we have in memory. - - // For switching network on Trust Wallet (WalletConnect), - // We only kill the session (and not restting the whole state) - // So we are relying on this.provider for achieving this functionality. - if (this.state.connected && !!this.provider) { - return { - accounts: this.state.accounts, - network: this.state.network, - provider: this.provider, - }; - } - - // TODO: call actions.eagerConnection - return null; - } - async connect(network?: Network) { - // If it's connecting, nothing do. - if (this.state.connecting) { - throw new Error('Connecting...'); - } - - const eagerConnection = await this.eagerConnection(); - const currentNetwork = this.state.network; - // If a network hasn't been provided and also we have `lastNetwork` - // We will use lastNetwork to make sure we will not - // Ask the user to switch his network wrongly. - const requestedNetwork = - network || currentNetwork || this.options.config.defaultNetwork; - - if (!!eagerConnection) { - const networkChanged = - currentNetwork !== requestedNetwork && !!requestedNetwork; - - // Reuse current connection if nothing has changed and we already have the connection in memory. - if (currentNetwork === requestedNetwork) { - return eagerConnection; - } - if (networkChanged && !!this.actions.switchNetwork) { - await this.actions.switchNetwork({ - instance: this.provider, - meta: this.meta, - // TODO: Fix type error - // @ts-ignore - network: requestedNetwork, - newInstance: this.tryGetInstance.bind(this), - }); - - return { - // Only network has been changed, so we reuse accounts from what we have already. - accounts: eagerConnection.accounts, - network: requestedNetwork, - provider: this.provider, - }; - } - - // If none of the above conditions didn't match, continute to connect. - } - - // We are connecting to wallet for the first time - - // Trying to get wallet's instance, if it's not available, raise an error. - const instance = await this.tryGetInstance({ network }); - - // Instance exists, trying to connect - this.updateState({ - connecting: true, - }); - this.setInstalledAs(true); - - try { - // eslint-disable-next-line no-var - var connectResult = await this.actions.connect({ - instance, - network: requestedNetwork || undefined, - meta: this.meta || [], - }); - } catch (e) { - this.resetState(); - throw e; - } - - this.updateState({ - connected: true, - reachable: true, - connecting: false, - }); - - // TODO: Handle accounts.length > 0 - - // Inserting accounts into our state. - let nextAccounts: string[] = []; - let nextNetwork: Network | null | undefined = null; - if (Array.isArray(connectResult)) { - const accounts = connectResult.flatMap((blockchain) => { - const chainId = blockchain.chainId || Network.Unknown; - // Try to map chainId with a Network, if not found, we use chainId directly. - const network = - getBlockChainNameFromId(chainId, this.meta) || Network.Unknown; - // TODO: second parameter should be `string` when we decided to open source the package. - return accountAddressesWithNetwork( - blockchain.accounts, - network as Network - ); - }); - // Typescript can not detect we are filtering out null values:( - nextAccounts = accounts.filter(Boolean) as string[]; - nextNetwork = requestedNetwork || this.options.config.defaultNetwork; - } else { - const chainId = connectResult.chainId || Network.Unknown; - const network = - getBlockChainNameFromId(chainId, this.meta) || Network.Unknown; - // We fallback to current active network if `chainId` not provided. - nextAccounts = accountAddressesWithNetwork( - connectResult.accounts, - network as Network - ); - nextNetwork = network as Network; - } - - if (nextAccounts.length > 0) { - this.updateState({ - accounts: nextAccounts, - network: nextNetwork, - }); - } - - return { - accounts: this.state.accounts, - network: this.state.network, - provider: this.provider, - }; - } - - async disconnect() { - this.resetState(); - - if (this.actions.disconnect) { - this.actions.disconnect({ - instance: this.provider, - // On wallet connect, we need to destory the instance and get a whole new instance when we are going to connect - destroyInstance: () => { - this.setProvider(null); - }, - }); - } - } - - getSigners(provider: any) { - return this.actions.getSigners(provider); - } - getWalletInfo(allBlockChains: BlockchainMeta[]) { - return this.actions.getWalletInfo(allBlockChains); - } - canSwitchNetworkTo(network: Network) { - const switchTo = this.actions.canSwitchNetworkTo; - if (!switchTo) return false; - - return switchTo({ - network, - meta: this.meta, - }); - } - - onInit() { - if (!this.options.config.isAsyncInstance) { - const instance = this.actions.getInstance(); - if (!!instance && !this.state.installed) { - this.setInstalledAs(true); - } - } - } - - setProvider(value: any) { - this.provider = value; - - if (!!value && !!this.actions.subscribe) { - this.actions.subscribe({ - instance: value, - state: this.state, - meta: this.meta, - connect: this.connect.bind(this), - disconnect: this.disconnect.bind(this), - updateAccounts: (accounts, chainId) => { - let network = this.state.network; - if (chainId) { - network = - getBlockChainNameFromId(chainId, this.meta) || Network.Unknown; - } - - const nextAccounts = accountAddressesWithNetwork(accounts, network); - if (nextAccounts.length > 0) { - this.updateState({ - accounts: nextAccounts, - }); - } - }, - updateChainId: (chainId) => { - const network = !!chainId - ? getBlockChainNameFromId(chainId, this.meta) - : Network.Unknown; - this.updateState({ - network, - }); - }, - }); - } - } - - setMeta(value: BlockchainMeta[]) { - this.meta = value; - } - - setHandler(handler: EventHandler) { - this.options.handler = handler; - } - - getState(): State { - return this.state; - } - updateState(states: Partial) { - // We will notify handler after updating all the states. - // Because when we call `handler` it will has latest states. - const updates: [Events, any][] = []; - - if (typeof states.connected !== 'undefined') { - this.state.connected = states.connected; - updates.push([Events.CONNECTED, states.connected]); - } - if (typeof states.connecting !== 'undefined') { - this.state.connecting = states.connecting; - updates.push([Events.CONNECTING, states.connecting]); - } - if (typeof states.reachable !== 'undefined') { - this.state.reachable = states.reachable; - updates.push([Events.REACHABLE, states.reachable]); - } - if (typeof states.installed !== 'undefined') { - this.state.installed = states.installed; - updates.push([Events.INSTALLED, states.installed]); - } - if (typeof states.accounts !== 'undefined') { - this.state.accounts = states.accounts; - updates.push([Events.ACCOUNTS, states.accounts]); - } - if (typeof states.network !== 'undefined') { - this.state.network = states.network; - updates.push([Events.NETWORK, states.network]); - } - - const state = this.getState(); - updates.forEach(([name, value]) => { - this.options.handler( - this.options.config.type, - name, - value, - state, - this.meta - ); - }); - } - - resetState() { - this.updateState({ - connected: false, - connecting: false, - reachable: false, - accounts: null, - network: null, - }); - } - - private setInstalledAs(value: boolean) { - if (!needsCheckInstallation(this.options) && value === false) return; - - this.updateState({ - installed: value, - }); - } - private async tryGetInstance({ - network, - force, - }: { - network?: Network; - force?: boolean; - }) { - let instance = null; - // For switching network on Trust Wallet (WalletConnect), - // We only kill the session (and not restting the whole state) - // So we are relying on this.provider for achieving this functionality. - this.setProvider(null); - - if (this.options.config.isAsyncInstance) { - // Trying to connect - const instanceOptions: GetInstanceOptions = { - currentProvider: this.provider, - meta: this.meta, - force: force || false, - }; - - if (network) { - instanceOptions.network = network; - } - - instance = await this.actions.getInstance(instanceOptions); - } else { - instance = this.actions.getInstance(); - } - - if (!instance) { - this.setInstalledAs(false); - this.resetState(); - - const error_message = `It seems your selected wallet (${this.options.config.type}) isn't installed.`; - throw new Error(error_message); - } - - this.setProvider(instance); - return instance; - } -} - -export default Wallet; diff --git a/wallets/core/tests/hub.test.ts b/wallets/core/tests/hub.test.ts new file mode 100644 index 0000000000..5bc10d800c --- /dev/null +++ b/wallets/core/tests/hub.test.ts @@ -0,0 +1,63 @@ +import type { Context } from '../src/hub/namespaces/types.js'; +import type { EvmActions } from '../src/namespaces/evm/types.js'; +import type { FunctionWithContext } from '../src/types/actions.js'; + +import { beforeEach, describe, expect, test } from 'vitest'; + +import { NamespaceBuilder, ProviderBuilder } from '../src/builders/mod.js'; +import { Hub } from '../src/hub/hub.js'; +import { createStore, type Store } from '../src/hub/store/mod.js'; +import { garbageWalletInfo } from '../src/test-utils/fixtures.js'; + +describe('check hub', () => { + const walletName = 'garbage-wallet'; + let store: Store; + + beforeEach(() => { + store = createStore(); + + return () => { + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore-next-line + store = undefined; + }; + }); + + test('connect through hub', async () => { + const evmConnect: FunctionWithContext< + EvmActions['connect'], + Context + > = async (_context, _chain) => { + return { + accounts: [ + 'eip155:0x1:0x000000000000000000000000000000000000dead', + 'eip155:0x1:0x0000000000000000000000000000000000000000', + ], + network: 'eth', + }; + }; + + const evmNamespace = new NamespaceBuilder('eip155', walletName) + .action('connect', evmConnect) + .build(); + const garbageWalletBuilder = new ProviderBuilder(walletName).config( + 'info', + garbageWalletInfo + ); + garbageWalletBuilder.add('evm', evmNamespace); + const garbageWallet = garbageWalletBuilder.build(); + + const myHub = new Hub({ + store, + }).add(garbageWallet.id, garbageWallet); + const wallet = myHub.get(garbageWallet.id); + // this is only for checking `.store` to has been set. + wallet?.state(); + const evmResult = await wallet?.get('evm')?.connect('0x0'); + + expect(evmResult?.accounts).toStrictEqual([ + 'eip155:0x1:0x000000000000000000000000000000000000dead', + 'eip155:0x1:0x0000000000000000000000000000000000000000', + ]); + }); +}); diff --git a/wallets/core/tests/providers.test.ts b/wallets/core/tests/providers.test.ts new file mode 100644 index 0000000000..6d7b4996bf --- /dev/null +++ b/wallets/core/tests/providers.test.ts @@ -0,0 +1,210 @@ +import type { Context } from '../src/hub/namespaces/mod.js'; +import type { EvmActions } from '../src/namespaces/evm/types.js'; +import type { SolanaActions } from '../src/namespaces/solana/types.js'; +import type { + AccountsWithActiveChain, + CaipAccount, +} from '../src/types/accounts.js'; +import type { FunctionWithContext } from '../src/types/actions.js'; + +import { describe, expect, test, vi } from 'vitest'; + +import { + ActionBuilder, + NamespaceBuilder, + ProviderBuilder, +} from '../src/builders/mod.js'; +import { garbageWalletInfo } from '../src/test-utils/fixtures.js'; + +describe('check Provider works with Blockchain correctly', () => { + const walletName = 'garbage-wallet'; + + test('connect successfully when two blockchain type has been added to Provider', async () => { + // Wallet Code + const spyOnEvmConnect = vi.fn(); + const evmConnect: FunctionWithContext< + EvmActions['connect'], + Context + > = async (_context, _chain) => { + spyOnEvmConnect(); + return { + accounts: ['eip155:0x1:0x000000000000000000000000000000000000dead'], + network: 'eth', + }; + }; + + const spyOnSolanaConnect = vi.fn(); + const solanaConnect: FunctionWithContext< + SolanaActions['connect'], + Context + > = async () => { + spyOnSolanaConnect(); + return ['solana:mainnet:1nc1nerator11111111111111111111111111111111']; + }; + + const evmNamespace = new NamespaceBuilder('eip155', walletName) + .action('connect', evmConnect) + .build(); + const solanaNamespace = new NamespaceBuilder( + 'solana', + walletName + ) + .action('connect', solanaConnect) + .build(); + + const garbageWalletBuilder = new ProviderBuilder(walletName).config( + 'info', + garbageWalletInfo + ); + garbageWalletBuilder.add('evm', evmNamespace); + garbageWalletBuilder.add('solana', solanaNamespace); + + const garbageWallet = garbageWalletBuilder.build(); + const evmResult = await garbageWallet.get('evm')?.connect('0x1'); + const solanaResult = await garbageWallet.get('solana')?.connect(); + + expect(evmResult?.accounts).toStrictEqual([ + 'eip155:0x1:0x000000000000000000000000000000000000dead', + ]); + expect(solanaResult).toStrictEqual([ + 'solana:mainnet:1nc1nerator11111111111111111111111111111111', + ]); + + expect(spyOnEvmConnect).toBeCalledTimes(1); + expect(spyOnSolanaConnect).toBeCalledTimes(1); + }); + + test('check post actions to work correctly.', async () => { + const spyOnConnect = vi.fn(); + const evmConnect: FunctionWithContext = + async function (_context, _chain) { + spyOnConnect(); + return { + // `as CaipAccount` is ok here because we are going to make to `CaipAccount` in `and` hook. + accounts: [ + '0x000000000000000000000000000000000000dead' as CaipAccount, + '0x0000000000000000000000000000000000000000' as CaipAccount, + ], + network: 'eth', + }; + }; + + const andConnect = vi.fn((_context, result: AccountsWithActiveChain) => { + return { + network: result.network, + accounts: result.accounts.map((account) => `eip155:0x1:${account}`), + }; + }); + + const evmDisconnect = vi.fn(); + const afterDisconnect = vi.fn(); + + const connectAction = new ActionBuilder('connect') + .action(evmConnect) + .and(andConnect) + .build(); + + const disconnectAction = new ActionBuilder( + 'disconnect' + ) + .action(evmDisconnect) + .after(afterDisconnect) + .build(); + + const evmNamespace = new NamespaceBuilder('eip155', walletName) + .action(connectAction) + .action(disconnectAction) + .build(); + + const garbageWalletBuilder = new ProviderBuilder('garbage-wallet').config( + 'info', + garbageWalletInfo + ); + garbageWalletBuilder.add('evm', evmNamespace); + + const garbageWallet = garbageWalletBuilder.build(); + const evmResult = await garbageWallet.get('evm')?.connect('0x1'); + + expect(evmResult?.accounts).toStrictEqual([ + 'eip155:0x1:0x000000000000000000000000000000000000dead', + 'eip155:0x1:0x0000000000000000000000000000000000000000', + ]); + + await garbageWallet.get('evm')?.connect('0x1'); + garbageWallet.get('evm')?.disconnect(); + expect(spyOnConnect).toBeCalledTimes(2); + expect(andConnect).toBeCalledTimes(2); + + expect(evmDisconnect).toBeCalledTimes(1); + expect(afterDisconnect).toBeCalledTimes(1); + }); + + test('check action builder works with namespace correctly.', async () => { + const spyOnSuccessAndAction = vi.fn((_ctx, value) => value); + const spyOnThrowAndAction = vi.fn(); + const spyOnThrowAndActionWithOr = vi.fn(); + + const spyOnSuccessOrAction = vi.fn(); + const spyOnThrowOrAction = vi.fn(); + + interface GarbageActions { + successfulAction: () => string; + throwErrorAction: () => void; + throwErrorActionWithOr: () => void; + } + + const successfulAction = new ActionBuilder< + GarbageActions, + 'successfulAction' + >('successfulAction') + .action(() => { + return 'yay!'; + }) + .and(spyOnSuccessAndAction) + .or(spyOnSuccessOrAction) + .build(); + + const throwErrorAction = new ActionBuilder< + GarbageActions, + 'throwErrorAction' + >('throwErrorAction') + .action(() => { + throw new Error('whatever'); + }) + .and(spyOnThrowAndAction) + .build(); + + const throwErrorActionWithOr = new ActionBuilder< + GarbageActions, + 'throwErrorActionWithOr' + >('throwErrorActionWithOr') + .action(() => { + throw new Error('whatever'); + }) + .and(spyOnThrowAndActionWithOr) + .or(spyOnThrowOrAction) + .build(); + + const garbageNamespace = new NamespaceBuilder<{ + successfulAction: () => string; + throwErrorAction: () => void; + throwErrorActionWithOr: () => void; + }>('eip155', walletName) + .action(successfulAction) + .action(throwErrorAction) + .action(throwErrorActionWithOr) + .build(); + + garbageNamespace.successfulAction(); + expect(spyOnSuccessAndAction).toBeCalledTimes(1); + expect(spyOnSuccessAndAction).toHaveLastReturnedWith('yay!'); + + expect(() => garbageNamespace.throwErrorAction()).toThrowError(); + expect(spyOnThrowAndAction).toBeCalledTimes(0); + + garbageNamespace.throwErrorActionWithOr(); + expect(spyOnThrowAndActionWithOr).toBeCalledTimes(0); + expect(spyOnSuccessOrAction).toBeCalledTimes(0); + expect(spyOnThrowOrAction).toBeCalledTimes(1); + }); +}); diff --git a/wallets/core/tsconfig.build.json b/wallets/core/tsconfig.build.json new file mode 100644 index 0000000000..d77c2c36b7 --- /dev/null +++ b/wallets/core/tsconfig.build.json @@ -0,0 +1,7 @@ +{ + "extends": "../../tsconfig.libnext.json", + "include": ["src"], + "compilerOptions": { + "outDir": "dist" + } +} diff --git a/wallets/core/tsconfig.json b/wallets/core/tsconfig.json index e3d0095fe9..a3a0b0f59d 100644 --- a/wallets/core/tsconfig.json +++ b/wallets/core/tsconfig.json @@ -1,37 +1 @@ -{ - // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs - "extends": "../../tsconfig.base.json", - "include": ["src", "types"], - "exclude": ["node_modules"], - "compilerOptions": { - "module": "esnext", - "lib": ["dom", "esnext"], - "importHelpers": true, - // output .d.ts declaration files for consumers - "declaration": true, - // output .js.map sourcemap files for consumers - "sourceMap": true, - // match output dir to input dir. e.g. dist/index instead of dist/src/index - "rootDir": "./src", - // stricter type-checking for stronger correctness. Recommended by TS - "strict": true, - // linter checks for common issues - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true, - // noUnused* overlap with @typescript-eslint/no-unused-vars, can disable if duplicative - "noUnusedLocals": true, - "noUnusedParameters": true, - // use Node's module resolution algorithm, instead of the legacy TS one - "moduleResolution": "node", - // transpile JSX to React.createElement - "jsx": "react", - // interop between ESM and CJS modules. Recommended by TS - "esModuleInterop": true, - // significant perf increase by skipping checking .d.ts files, particularly those in node_modules. Recommended by TS - "skipLibCheck": true, - // error out if import and file system have a casing mismatch. Recommended by TS - "forceConsistentCasingInFileNames": true, - // `tsdx build` ignores this option, but it is commonly used when type-checking separately with `tsc` - "noEmit": true - } -} +{ "extends": "./tsconfig.build.json", "include": ["src", "tests"] } diff --git a/wallets/demo/package.json b/wallets/demo/package.json deleted file mode 100644 index 9e18b0c73f..0000000000 --- a/wallets/demo/package.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "name": "@rango-dev/wallets-demo", - "version": "0.1.12", - "license": "MIT", - "private": true, - "source": "public/index.html", - "browserslist": "> 0.5%, last 2 versions, not dead", - "scripts": { - "dev": "parcel --cache-dir=.parcel-cache", - "build": "parcel build --cache-dir=.parcel-cache" - }, - "dependencies": { - "@rango-dev/provider-all": "^0.1.12", - "@rango-dev/ui": "^0.1.12", - "@rango-dev/wallets-core": "^0.1.12", - "parcel": "^2.8.0", - "rango-sdk": "^0.1.20", - "rango-types": "^0.1.28", - "react": "^18.2.0", - "react-dom": "^18.2.0" - } -} diff --git a/wallets/demo/src/App.tsx b/wallets/demo/src/App.tsx deleted file mode 100644 index fad4660d63..0000000000 --- a/wallets/demo/src/App.tsx +++ /dev/null @@ -1,50 +0,0 @@ -import React, { useEffect, useState } from 'react'; -import { Provider } from '@rango-dev/wallets-core'; -import List from './components/List'; -import { allProviders } from '@rango-dev/provider-all'; -import { RangoClient } from 'rango-sdk'; -import { InfoCircleIcon, Spinner, Typography } from '@rango-dev/ui'; - -const providers = allProviders(); - -export function App() { - const client = new RangoClient(process.env.REACT_APP_API_KEY as string); - // Because allBlockChains didn't use the BlockchainMeta type from rango-sdk, we have to use any type - const [blockchains, setBlockChains] = useState([]); - const [error, setError] = useState(''); - const [loading, setLoading] = useState(true); - - useEffect(() => { - const getAllBlockchains = async () => { - try { - const res = await client.getAllMetadata(); - setBlockChains(res.blockchains); - } catch (e) { - console.log('failed on connect.', e); - setError(e.message); - } - setLoading(false); - }; - getAllBlockchains(); - }, []); - - return ( - - {!process.env.REACT_APP_API_KEY && ( -

- Please add REACT_APP_API_KEY into .env -

- )} -
-

Providers

- {loading && ( -
- Loading... -
- )} -
- {!!error &&

Failed Get Blockchains From Server: {error}

} - -
- ); -} diff --git a/wallets/demo/src/components/List/Item.tsx b/wallets/demo/src/components/List/Item.tsx deleted file mode 100644 index 7354d5cbf0..0000000000 --- a/wallets/demo/src/components/List/Item.tsx +++ /dev/null @@ -1,212 +0,0 @@ -import React, { useState } from 'react'; -import { readAccountAddress, useWallets } from '@rango-dev/wallets-core'; -import { Network, WalletType, detectInstallLink, WalletInfo } from '@rango-dev/wallets-shared'; -import './styles.css'; -import { - Button, - HorizontalSwapIcon, - InfoCircleIcon, - SignatureIcon, - Spacer, - Spinner, - Tooltip, - Typography, -} from '@rango-dev/ui'; -import { - evmBasedChainsSelector, - prepareAccounts, - walletAndSupportedChainsNames, -} from '../../helper'; -import { TransactionType } from 'rango-sdk'; - -function Item({ type, info }: { type: WalletType; info: WalletInfo }) { - const { connect, state, disconnect, canSwitchNetworkTo, getSigners } = useWallets(); - const walletState = state(type); - const [network, setNetwork] = useState(Network.Unknown); - const [error, setError] = useState(''); - const evmBasedChains = evmBasedChainsSelector(info.supportedChains); - const handleConnectWallet = async () => { - if (walletState.connecting) return; - try { - if (!walletState.connected) { - if (walletState.installed) { - const result = await connect(type); - setError(''); - setNetwork(result.network || Network.Unknown); - } else { - window.open(detectInstallLink(info.installLink), '_blank'); - } - } else { - disconnect(type); - } - } catch (err) { - setError('Error: ' + (err.message || 'Failed to connect wallet')); - } - }; - const canSwitchNetwork = network !== Network.Unknown && canSwitchNetworkTo(type, network); - const handleChangeNetwork = async () => { - if (canSwitchNetwork) { - try { - const result = await connect(type, network); - setError(''); - setNetwork(result.network || Network.Unknown); - } catch (err) { - setError('Error: ' + (err.message || 'Failed to connect wallet')); - } - } - }; - const handleSigner = () => { - if (!walletState.accounts || !walletState.accounts.length) { - alert("You don't currently have an account or you haven't connected to wallet correctly!"); - } else { - const supportedChainsNames = walletAndSupportedChainsNames(info.supportedChains); - const activeAccount = prepareAccounts( - walletState.accounts, - walletState.network, - evmBasedChains, - supportedChainsNames, - ).find((a) => a.accounts.find((b) => b.isConnected)); - const signers = getSigners(type); - const address = - (walletState.accounts?.length > 1 && - readAccountAddress( - walletState.accounts.find((account) => - account?.toLowerCase()?.includes(network?.toLowerCase()), - )!, - ).address) || - activeAccount?.accounts[0].address; - - const currentChain = info.supportedChains.find((chain) => chain.name === network); - const txType = currentChain?.type || TransactionType.EVM; - const chainId = currentChain?.chainId || null; - const result = signers.getSigner(txType).signMessage('Hello World', address!, chainId); - result - .then((signature) => { - alert(signature); - }) - .catch((ex) => { - alert('Error' + `(${info.name}): ` + (ex.message || 'Failed to sign')); - }); - } - }; - return ( -
-
-
- {walletState.connected ? ( -
-
- {info.name} -
-

{info.name}

-
- ) : ( -
- )} -
- {walletState.connected && !canSwitchNetwork && ( - <> - - - - - - )} -
-
-
- - {walletState.connected ? ( - <> -

Accounts:

-
- {walletState?.accounts?.map((account) => ( -
{account}
- ))} -
-
-

Chain:

-
{walletState?.network}
-
- - ) : ( -
- {info.name} -

{info.name}

- - {!walletState.installed - ? 'The wallet is not installed' - : 'The wallet is disconnected'} - -
- )} - - {error && ( -

- - {error} -

- )} -
- -
- -
- - - -
-
- - - -
-
-
- ); -} - -export default Item; diff --git a/wallets/demo/src/components/List/List.tsx b/wallets/demo/src/components/List/List.tsx deleted file mode 100644 index 290d5e6097..0000000000 --- a/wallets/demo/src/components/List/List.tsx +++ /dev/null @@ -1,35 +0,0 @@ -import React from 'react'; -import { useWallets } from '@rango-dev/wallets-core'; -import { sortWalletsBasedOnState, WalletInfo, WalletType } from '@rango-dev/wallets-shared'; -import Item from './Item'; -import './styles.css'; -const excludedWallets = [WalletType.UNKNOWN, WalletType.TERRA_STATION, WalletType.LEAP]; - -function List() { - const { state, getWalletInfo } = useWallets(); - const allWallets = sortWalletsBasedOnState( - Object.keys(WalletType) - .filter((i) => !excludedWallets.includes(WalletType[i])) - .map((type) => { - const walletState = state(WalletType[type]); - const connected = walletState.connected; - const installed = walletState.installed; - const info = getWalletInfo(WalletType[type]); - return { - type: WalletType[type], - connected, - extensionAvailable: installed, - info, - }; - }), - ); - return ( -
- {allWallets.map((wallet) => ( - - ))} -
- ); -} - -export default List; diff --git a/wallets/demo/src/components/List/index.ts b/wallets/demo/src/components/List/index.ts deleted file mode 100644 index 8e34bd3970..0000000000 --- a/wallets/demo/src/components/List/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { default } from "./List"; diff --git a/wallets/demo/src/helper.ts b/wallets/demo/src/helper.ts deleted file mode 100644 index caee96ec0e..0000000000 --- a/wallets/demo/src/helper.ts +++ /dev/null @@ -1,71 +0,0 @@ -import { readAccountAddress } from '@rango-dev/wallets-core'; -import { Network } from '@rango-dev/wallets-shared'; -import { BlockchainMeta, isEvmBlockchain } from 'rango-types'; -export type Blockchain = { name: Network; accounts: { address: string; isConnected: boolean }[] }; - -export function prepareAccounts( - accounts: string[], - connectedNetwork: Network | null, - evmBasedChains: string[], - supportedChainNames: Network[] | null, -): Blockchain[] { - const result = {} as { [type in Network]: Blockchain }; - - function addAccount(network: Network, address: string) { - const isConnected = network === connectedNetwork; - const newAccount = { - address, - isConnected, - }; - - if (!!result[network]) { - result[network].accounts.push(newAccount); - } else { - result[network] = { - name: network, - accounts: [newAccount], - }; - } - } - - const supportedChains = supportedChainNames || []; - - accounts.forEach((account) => { - const { address, network } = readAccountAddress(account); - - const hasLimitation = supportedChains.length > 0; - const isSupported = supportedChains.includes(network); - const isUnknown = network === Network.Unknown; - const notSupportedNetworkByWallet = hasLimitation && !isSupported && !isUnknown; - if (notSupportedNetworkByWallet) return; - - const isEvmBasedChain = evmBasedChains.includes(network); - - if (isEvmBasedChain) { - const evmChainsSupportedByWallet = supportedChains.filter((chain) => - evmBasedChains.includes(chain), - ); - evmChainsSupportedByWallet.forEach((network) => { - addAccount(network, address.toLowerCase()); - }); - } else { - addAccount(network, address); - } - }); - - return Object.values(result); -} - -export function walletAndSupportedChainsNames(supportedChains: BlockchainMeta[]): Network[] | null { - if (!supportedChains) return null; - let walletAndSupportedChainsNames: string[] = []; - walletAndSupportedChainsNames = supportedChains.map((blockchainMeta) => blockchainMeta.name); - - return walletAndSupportedChainsNames as Network[]; -} - -export const evmBasedChainsSelector = (blockchains: BlockchainMeta[]) => - blockchains - .map((blockchainMeta) => blockchainMeta) - .filter(isEvmBlockchain) - .map((blockchainMeta) => blockchainMeta.name); diff --git a/wallets/demo/src/index.tsx b/wallets/demo/src/index.tsx deleted file mode 100644 index 4b375392af..0000000000 --- a/wallets/demo/src/index.tsx +++ /dev/null @@ -1,7 +0,0 @@ -import React from "react"; -import { createRoot } from "react-dom/client"; -import { App } from "./App"; -import './index.css'; -const container = document.getElementById("app")!; -const root = createRoot(container) -root.render(); \ No newline at end of file diff --git a/wallets/provider-all/CHANGELOG.md b/wallets/provider-all/CHANGELOG.md new file mode 100644 index 0000000000..bb29148c5d --- /dev/null +++ b/wallets/provider-all/CHANGELOG.md @@ -0,0 +1,236 @@ +# [0.41.0](https://github.com/rango-exchange/rango-client/compare/provider-all@0.40.0...provider-all@0.41.0) (2024-12-30) + + + +# [0.40.0](https://github.com/rango-exchange/rango-client/compare/provider-all@0.39.0...provider-all@0.40.0) (2024-11-27) + + +### Bug Fixes + +* improve ton signer and mytonwallet provider ([7027755](https://github.com/rango-exchange/rango-client/commit/7027755740426359f42b088b842dfd01590df5c3)) + + +### Features + +* add ton connect provider ([2a2dbb7](https://github.com/rango-exchange/rango-client/commit/2a2dbb79022263f19446ced49d298e04d63f927f)) + + + +# [0.39.0](https://github.com/rango-exchange/rango-client/compare/provider-all@0.38.5...provider-all@0.39.0) (2024-11-12) + + + +## [0.38.5](https://github.com/rango-exchange/rango-client/compare/provider-all@0.38.4...provider-all@0.38.5) (2024-11-06) + + + +## [0.38.4](https://github.com/rango-exchange/rango-client/compare/provider-all@0.38.3...provider-all@0.38.4) (2024-11-06) + + + +## [0.38.3](https://github.com/rango-exchange/rango-client/compare/provider-all@0.38.2...provider-all@0.38.3) (2024-11-06) + + + +## [0.38.2](https://github.com/rango-exchange/rango-client/compare/provider-all@0.38.1...provider-all@0.38.2) (2024-11-06) + + + +## [0.38.1](https://github.com/rango-exchange/rango-client/compare/provider-all@0.38.0...provider-all@0.38.1) (2024-10-30) + + + +# [0.38.0](https://github.com/rango-exchange/rango-client/compare/provider-all@0.37.3...provider-all@0.38.0) (2024-10-12) + + + +## [0.37.3](https://github.com/rango-exchange/rango-client/compare/provider-all@0.37.2...provider-all@0.37.3) (2024-10-05) + + + +## [0.37.2](https://github.com/rango-exchange/rango-client/compare/provider-all@0.37.1...provider-all@0.37.2) (2024-09-25) + + + +## [0.37.1](https://github.com/rango-exchange/rango-client/compare/provider-all@0.37.0...provider-all@0.37.1) (2024-09-16) + + +### Bug Fixes + +* enabling trezor by removing bundling for @trezor/connect-web ([eb0be81](https://github.com/rango-exchange/rango-client/commit/eb0be81dd582a21e4c46b32c68bfd3ddd2a3cfa0)) + + + +# [0.37.0](https://github.com/rango-exchange/rango-client/compare/provider-all@0.36.0...provider-all@0.37.0) (2024-09-10) + + +### Bug Fixes + +* remove trezor temporarily ([8647cb4](https://github.com/rango-exchange/rango-client/commit/8647cb431dfdae99b82bda2d3fb7eaff7cbbf299)) + + + +# [0.36.0](https://github.com/rango-exchange/rango-client/compare/provider-all@0.35.1...provider-all@0.36.0) (2024-08-11) + + +### Features + +* integrate solflare wallet ([fb6aaf1](https://github.com/rango-exchange/rango-client/commit/fb6aaf1c255149df18a75a7bfb16fc83c23b85a8)) + + + +## [0.35.1](https://github.com/rango-exchange/rango-client/compare/provider-all@0.35.0...provider-all@0.35.1) (2024-07-14) + + + +# [0.35.0](https://github.com/rango-exchange/rango-client/compare/provider-all@0.33.2...provider-all@0.35.0) (2024-07-09) + + +### Features + +* add support for Trezor hardware wallet ([6edecbb](https://github.com/rango-exchange/rango-client/commit/6edecbb14fd008fc741c892bfa3e025c10160b9b)) +* integrate rabby wallet extension ([145fb8f](https://github.com/rango-exchange/rango-client/commit/145fb8ffbbf5e46e7e8386aeffcefc8f4ddb22e7)) +* integrate tomo wallet extension ([9f0f065](https://github.com/rango-exchange/rango-client/commit/9f0f0650fcd213a621dcc6ddca3e32424c1a5ada)) + + + +# [0.34.0](https://github.com/rango-exchange/rango-client/compare/provider-all@0.33.2...provider-all@0.34.0) (2024-06-01) + + + +## [0.33.2](https://github.com/rango-exchange/rango-client/compare/provider-all@0.33.1...provider-all@0.33.2) (2024-05-26) + + + +## [0.33.1](https://github.com/rango-exchange/rango-client/compare/provider-all@0.33.0...provider-all@0.33.1) (2024-05-25) + + + +# [0.33.0](https://github.com/rango-exchange/rango-client/compare/provider-all@0.32.1...provider-all@0.33.0) (2024-05-14) + + +### Features + +* detect proper error related to wallet connect params ([a0d8d95](https://github.com/rango-exchange/rango-client/commit/a0d8d95ed977fffbd0244f498c81f7ce3550ee71)) + + + +## [0.32.1](https://github.com/rango-exchange/rango-client/compare/provider-all@0.32.0...provider-all@0.32.1) (2024-04-24) + + + +# [0.32.0](https://github.com/rango-exchange/rango-client/compare/provider-all@0.31.0...provider-all@0.32.0) (2024-04-24) + + +### Features + +* add ethereum for ledger ([084aae2](https://github.com/rango-exchange/rango-client/commit/084aae28adaf0310dffe3a3100dd783252393053)) + + + +# [0.31.0](https://github.com/rango-exchange/rango-client/compare/provider-all@0.30.0...provider-all@0.31.0) (2024-04-23) + + +### Features + +* add solflare snap connect and signer ([42aa2b0](https://github.com/rango-exchange/rango-client/commit/42aa2b039dd910e8e44db473e1acd28689a8b43b)) + + + +# [0.30.0](https://github.com/rango-exchange/rango-client/compare/provider-all@0.29.0...provider-all@0.30.0) (2024-04-09) + + + +# [0.29.0](https://github.com/rango-exchange/rango-client/compare/provider-all@0.28.0...provider-all@0.29.0) (2024-03-12) + + + +# [0.28.0](https://github.com/rango-exchange/rango-client/compare/provider-all@0.27.0...provider-all@0.28.0) (2024-02-20) + + + +# [0.27.0](https://github.com/rango-exchange/rango-client/compare/provider-all@0.26.0...provider-all@0.27.0) (2024-02-07) + + + +# [0.26.0](https://github.com/rango-exchange/rango-client/compare/provider-all@0.25.0...provider-all@0.26.0) (2024-01-22) + + +### Features + +* add default injected wallet ([238977c](https://github.com/rango-exchange/rango-client/commit/238977c0e3cd09feba9f2557f1b099b9af3afb0d)) + + + +# [0.25.0](https://github.com/rango-exchange/rango-client/compare/provider-all@0.24.0...provider-all@0.25.0) (2023-12-24) + + +### Bug Fixes + +* fix HMR for widget and playground ([8524820](https://github.com/rango-exchange/rango-client/commit/8524820f10cf0b8921f3db0c4f620ff98daa4103)) + + + +# [0.14.0](https://github.com/rango-exchange/rango-client/compare/provider-all@0.13.0...provider-all@0.14.0) (2023-08-03) + + +### Bug Fixes + +* disable safe on provider-all since it breaks the CRA ([32092c0](https://github.com/rango-exchange/rango-client/commit/32092c01b320f58495a1d43bd5cee0d05cc1e8d9)) + + + +# [0.13.0](https://github.com/rango-exchange/rango-client/compare/provider-all@0.12.0...provider-all@0.13.0) (2023-08-01) + + + +# [0.9.0](https://github.com/rango-exchange/rango-client/compare/provider-all@0.8.0...provider-all@0.9.0) (2023-07-31) + + +### Features + +* add project id as a external value ([0c80404](https://github.com/rango-exchange/rango-client/commit/0c80404a8cacb6c5b0338dea1e416b0b11db254b)) +* Get Wallet Connect project id from config ([9fb30b4](https://github.com/rango-exchange/rango-client/commit/9fb30b4b1a83e2005bbf42553298f24b1e278e1c)) +* support braavos wallet ([fb38ebe](https://github.com/rango-exchange/rango-client/commit/fb38ebef00a33b92cabf506c88ef83d8c77cce84)) +* Support for WalletConnect 2 ([faedef0](https://github.com/rango-exchange/rango-client/commit/faedef0b5e6fc3c5ef881cbbe4ec05334cc1c910)) +* support safe wallet ([d04cbcd](https://github.com/rango-exchange/rango-client/commit/d04cbcd2a612755563512d9dff6f2312088d8b4d)) + + + +# [0.7.0](https://github.com/rango-exchange/rango-client/compare/provider-all@0.6.0...provider-all@0.7.0) (2023-07-11) + + + +# [0.6.0](https://github.com/rango-exchange/rango-client/compare/provider-all@0.5.0...provider-all@0.6.0) (2023-07-11) + + +### Features + +* add bitkeep wallet ([c02c3df](https://github.com/rango-exchange/rango-client/commit/c02c3dfd236070295eada74aeb97514f8dacd0ed)) + + + +# [0.5.0](https://github.com/rango-exchange/rango-client/compare/provider-all@0.4.0...provider-all@0.5.0) (2023-05-31) + + + +# [0.4.0](https://github.com/rango-exchange/rango-client/compare/provider-all@0.3.0...provider-all@0.4.0) (2023-05-31) + + + +# [0.3.0](https://github.com/rango-exchange/rango-client/compare/provider-all@0.2.0...provider-all@0.3.0) (2023-05-30) + + + +# [0.2.0](https://github.com/rango-exchange/rango-client/compare/provider-all@0.1.21...provider-all@0.2.0) (2023-05-30) + + + +## [0.1.21](https://github.com/rango-exchange/rango-client/compare/provider-all@0.1.20...provider-all@0.1.21) (2023-05-15) + + + +## [0.1.14](https://github.com/rango-exchange/rango-client/compare/provider-all@0.1.13...provider-all@0.1.14) (2023-05-15) + + + diff --git a/wallets/provider-all/package.json b/wallets/provider-all/package.json index 7ecd4ea53d..acf832469b 100644 --- a/wallets/provider-all/package.json +++ b/wallets/provider-all/package.json @@ -1,68 +1,65 @@ { "name": "@rango-dev/provider-all", - "version": "0.1.12", + "version": "0.40.1-next.8", "license": "MIT", - "module": "dist/provider-all.esm.js", - "main": "dist/index.js", + "type": "module", + "source": "./src/index.ts", + "main": "./dist/index.js", + "exports": { + ".": "./dist/index.js" + }, "typings": "dist/index.d.ts", "files": [ "dist", "src" ], "scripts": { - "start": "tsdx watch", - "build": "tsdx build --tsconfig ./tsconfig.json", - "test": "tsdx test --passWithNoTests", - "lint": "tsdx lint", - "size": "size-limit", - "analyze": "size-limit --why" - }, - "husky": { - "hooks": { - "pre-commit": "tsdx lint" - } + "build": "node ../../scripts/build/command.mjs --path wallets/provider-all", + "ts-check": "tsc --declaration --emitDeclarationOnly -p ./tsconfig.json", + "clean": "rimraf dist", + "format": "prettier --write '{.,src}/**/*.{ts,tsx}'", + "lint": "eslint \"**/*.{ts,tsx}\" --ignore-path ../../.eslintignore" }, - "prettier": { - "printWidth": 80, - "semi": true, - "singleQuote": true, - "trailingComma": "es5" - }, - "size-limit": [ - { - "path": "dist/provider-all.cjs.production.min.js", - "limit": "10 KB" - }, - { - "path": "dist/provider-all.esm.js", - "limit": "10 KB" - } - ], "dependencies": { - "@rango-dev/provider-argentx": "^0.1.12", - "@rango-dev/provider-binance-chain-wallet": "^0.1.12", - "@rango-dev/provider-brave": "^0.1.12", - "@rango-dev/provider-clover": "^0.1.12", - "@rango-dev/provider-coin98": "^0.1.11", - "@rango-dev/provider-coinbase": "^0.1.12", - "@rango-dev/provider-cosmostation": "^0.1.11", - "@rango-dev/provider-exodus": "^0.1.12", - "@rango-dev/provider-frontier": "^0.1.12", - "@rango-dev/provider-keplr": "^0.1.12", - "@rango-dev/provider-kucoin-wallet": "^0.1.12", - "@rango-dev/provider-leap-cosmos": "^0.1.12", - "@rango-dev/provider-math-wallet": "^0.1.12", - "@rango-dev/provider-metamask": "^0.1.12", - "@rango-dev/provider-okx": "^0.1.12", - "@rango-dev/provider-phantom": "^0.1.12", - "@rango-dev/provider-safepal": "^0.1.12", - "@rango-dev/provider-tokenpocket": "^0.1.12", - "@rango-dev/provider-tron-link": "^0.1.12", - "@rango-dev/provider-trustwallet": "^0.1.12", - "@rango-dev/provider-walletconnect": "^0.1.12", - "@rango-dev/provider-xdefi": "^0.1.12" + "@rango-dev/provider-argentx": "^0.41.1-next.6", + "@rango-dev/provider-bitget": "^0.37.1-next.6", + "@rango-dev/provider-braavos": "^0.34.1-next.6", + "@rango-dev/provider-brave": "^0.41.1-next.6", + "@rango-dev/provider-clover": "^0.41.1-next.6", + "@rango-dev/provider-coin98": "^0.41.1-next.6", + "@rango-dev/provider-coinbase": "^0.40.1-next.6", + "@rango-dev/provider-cosmostation": "^0.40.1-next.6", + "@rango-dev/provider-default": "^0.37.1-next.6", + "@rango-dev/provider-enkrypt": "^0.40.1-next.6", + "@rango-dev/provider-exodus": "^0.40.1-next.6", + "@rango-dev/provider-frontier": "^0.40.1-next.6", + "@rango-dev/provider-halo": "^0.40.1-next.6", + "@rango-dev/provider-keplr": "^0.40.1-next.6", + "@rango-dev/provider-leap-cosmos": "^0.40.1-next.6", + "@rango-dev/provider-ledger": "^0.10.1-next.6", + "@rango-dev/provider-math-wallet": "^0.40.1-next.6", + "@rango-dev/provider-metamask": "^0.40.1-next.6", + "@rango-dev/provider-mytonwallet": "^0.25.1-next.6", + "@rango-dev/provider-okx": "^0.40.1-next.6", + "@rango-dev/provider-phantom": "^0.40.1-next.7", + "@rango-dev/provider-rabby": "^0.7.1-next.6", + "@rango-dev/provider-safe": "^0.33.1-next.6", + "@rango-dev/provider-safepal": "^0.40.1-next.6", + "@rango-dev/provider-solflare": "^0.6.1-next.6", + "@rango-dev/provider-solflare-snap": "^0.11.1-next.6", + "@rango-dev/provider-taho": "^0.40.1-next.6", + "@rango-dev/provider-tokenpocket": "^0.40.1-next.6", + "@rango-dev/provider-tomo": "^0.7.1-next.6", + "@rango-dev/provider-tonconnect": "^0.2.1-next.6", + "@rango-dev/provider-trezor": "^0.7.1-next.6", + "@rango-dev/provider-tron-link": "^0.40.1-next.6", + "@rango-dev/provider-trustwallet": "^0.40.1-next.6", + "@rango-dev/provider-walletconnect-2": "^0.33.1-next.6", + "@rango-dev/provider-xdefi": "^0.40.1-next.6", + "@rango-dev/wallets-react": "^0.26.1-next.9", + "@rango-dev/wallets-shared": "^0.40.1-next.6" }, "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/wallets/provider-all/src/helpers.ts b/wallets/provider-all/src/helpers.ts new file mode 100644 index 0000000000..5a6a46d8ad --- /dev/null +++ b/wallets/provider-all/src/helpers.ts @@ -0,0 +1,19 @@ +import type { VersionedProviders } from '@rango-dev/wallets-core/utils'; +import type { ProviderInterface } from '@rango-dev/wallets-react'; +import type { WalletType, WalletTypes } from '@rango-dev/wallets-shared'; + +export const isWalletExcluded = ( + providers: (WalletType | ProviderInterface)[], + wallet: { name: string; type: WalletTypes } +) => { + return ( + providers.length && + !providers.find((provider) => + typeof provider === 'string' + ? provider === wallet.type + : provider.getWalletInfo([]).name === wallet.name + ) + ); +}; + +export const lazyProvider = (provider: VersionedProviders) => () => provider; diff --git a/wallets/provider-all/src/index.ts b/wallets/provider-all/src/index.ts index a8a5138dac..00dfb32cba 100644 --- a/wallets/provider-all/src/index.ts +++ b/wallets/provider-all/src/index.ts @@ -1,47 +1,146 @@ -import * as binance from '@rango-dev/provider-binance-chain-wallet'; -import * as xdefi from '@rango-dev/provider-xdefi'; +import type { Environments as TonConnectEnvironments } from '@rango-dev/provider-tonconnect'; +import type { Environments as TrezorEnvironments } from '@rango-dev/provider-trezor'; +import type { Environments as WalletConnectEnvironments } from '@rango-dev/provider-walletconnect-2'; +import type { ProviderInterface } from '@rango-dev/wallets-react'; + +import * as argentx from '@rango-dev/provider-argentx'; +import * as bitget from '@rango-dev/provider-bitget'; +import * as braavos from '@rango-dev/provider-braavos'; import * as brave from '@rango-dev/provider-brave'; import * as clover from '@rango-dev/provider-clover'; -import * as coin98 from '@rango-dev/provider-coin98'; +import { versions as coin98 } from '@rango-dev/provider-coin98'; import * as coinbase from '@rango-dev/provider-coinbase'; import * as cosmostation from '@rango-dev/provider-cosmostation'; +import * as defaultInjected from '@rango-dev/provider-default'; +import * as enkrypt from '@rango-dev/provider-enkrypt'; import * as exodus from '@rango-dev/provider-exodus'; +import * as frontier from '@rango-dev/provider-frontier'; +import * as halo from '@rango-dev/provider-halo'; import * as keplr from '@rango-dev/provider-keplr'; +import * as leapCosmos from '@rango-dev/provider-leap-cosmos'; +import * as ledger from '@rango-dev/provider-ledger'; import * as mathwallet from '@rango-dev/provider-math-wallet'; import * as metamask from '@rango-dev/provider-metamask'; +import * as mytonwallet from '@rango-dev/provider-mytonwallet'; import * as okx from '@rango-dev/provider-okx'; -import * as phantom from '@rango-dev/provider-phantom'; +import { versions as phantom } from '@rango-dev/provider-phantom'; +import * as rabby from '@rango-dev/provider-rabby'; +import * as safe from '@rango-dev/provider-safe'; import * as safepal from '@rango-dev/provider-safepal'; +import * as solflare from '@rango-dev/provider-solflare'; +import * as solflareSnap from '@rango-dev/provider-solflare-snap'; +import * as taho from '@rango-dev/provider-taho'; import * as tokenpocket from '@rango-dev/provider-tokenpocket'; -import * as trustwallet from '@rango-dev/provider-trustwallet'; -import * as walletconnect from '@rango-dev/provider-walletconnect'; -import * as argentx from '@rango-dev/provider-argentx'; +import * as tomo from '@rango-dev/provider-tomo'; +import * as tonconnect from '@rango-dev/provider-tonconnect'; +import * as trezor from '@rango-dev/provider-trezor'; import * as tronLink from '@rango-dev/provider-tron-link'; -import * as kucoin from '@rango-dev/provider-kucoin-wallet'; -import * as leapCosmos from '@rango-dev/provider-leap-cosmos'; -import * as frontier from '@rango-dev/provider-frontier'; +import * as trustwallet from '@rango-dev/provider-trustwallet'; +import * as walletconnect2 from '@rango-dev/provider-walletconnect-2'; +import * as xdefi from '@rango-dev/provider-xdefi'; +import { + legacyProviderImportsToVersionsInterface, + type VersionedProviders, +} from '@rango-dev/wallets-core/utils'; +import { type WalletType, WalletTypes } from '@rango-dev/wallets-shared'; + +import { isWalletExcluded, lazyProvider } from './helpers.js'; + +interface Options { + walletconnect2: WalletConnectEnvironments; + selectedProviders?: (WalletType | ProviderInterface)[]; + trezor?: TrezorEnvironments; + tonConnect?: TonConnectEnvironments; +} + +export const allProviders = ( + options?: Options +): (() => VersionedProviders)[] => { + const providers = options?.selectedProviders || []; + + if ( + !isWalletExcluded(providers, { + type: WalletTypes.WALLET_CONNECT_2, + name: 'WalletConnect', + }) + ) { + if (!!options?.walletconnect2?.WC_PROJECT_ID) { + walletconnect2.init(options.walletconnect2); + } else { + throw new Error( + 'WalletConnect has been included in your providers. Passing a Project ID is required. Make sure you are passing "WC_PROJECT_ID".' + ); + } + } + + if ( + !isWalletExcluded(providers, { + type: WalletTypes.TREZOR, + name: 'Trezor', + }) + ) { + if (!!options?.trezor?.manifest) { + trezor.init(options.trezor); + } + } + + if ( + !isWalletExcluded(providers, { + type: WalletTypes.MY_TON_WALLET, + name: 'mytonwallet', + }) + ) { + if (!!options?.tonConnect?.manifestUrl) { + mytonwallet.init(options.tonConnect); + } + } + + if ( + !isWalletExcluded(providers, { + type: WalletTypes.TON_CONNECT, + name: 'tonconnect', + }) + ) { + if (!!options?.tonConnect?.manifestUrl) { + tonconnect.init(options.tonConnect); + } + } -export const allProviders = () => [ - binance, - xdefi, - brave, - clover, - coin98, - coinbase, - cosmostation, - exodus, - keplr, - mathwallet, - metamask, - okx, - phantom, - safepal, - tokenpocket, - trustwallet, - walletconnect, - argentx, - tronLink, - kucoin, - leapCosmos, - frontier, -]; + return [ + lazyProvider(legacyProviderImportsToVersionsInterface(safe)), + lazyProvider(legacyProviderImportsToVersionsInterface(defaultInjected)), + lazyProvider(legacyProviderImportsToVersionsInterface(metamask)), + lazyProvider(legacyProviderImportsToVersionsInterface(solflareSnap)), + lazyProvider(legacyProviderImportsToVersionsInterface(walletconnect2)), + lazyProvider(legacyProviderImportsToVersionsInterface(tonconnect)), + lazyProvider(legacyProviderImportsToVersionsInterface(keplr)), + phantom, + lazyProvider(legacyProviderImportsToVersionsInterface(argentx)), + lazyProvider(legacyProviderImportsToVersionsInterface(tronLink)), + lazyProvider(legacyProviderImportsToVersionsInterface(trustwallet)), + lazyProvider(legacyProviderImportsToVersionsInterface(bitget)), + lazyProvider(legacyProviderImportsToVersionsInterface(enkrypt)), + lazyProvider(legacyProviderImportsToVersionsInterface(xdefi)), + lazyProvider(legacyProviderImportsToVersionsInterface(clover)), + lazyProvider(legacyProviderImportsToVersionsInterface(safepal)), + lazyProvider(legacyProviderImportsToVersionsInterface(brave)), + coin98, + lazyProvider(legacyProviderImportsToVersionsInterface(coinbase)), + lazyProvider(legacyProviderImportsToVersionsInterface(cosmostation)), + lazyProvider(legacyProviderImportsToVersionsInterface(exodus)), + lazyProvider(legacyProviderImportsToVersionsInterface(mathwallet)), + lazyProvider(legacyProviderImportsToVersionsInterface(okx)), + lazyProvider(legacyProviderImportsToVersionsInterface(tokenpocket)), + lazyProvider(legacyProviderImportsToVersionsInterface(tomo)), + lazyProvider(legacyProviderImportsToVersionsInterface(halo)), + lazyProvider(legacyProviderImportsToVersionsInterface(leapCosmos)), + lazyProvider(legacyProviderImportsToVersionsInterface(frontier)), + lazyProvider(legacyProviderImportsToVersionsInterface(taho)), + lazyProvider(legacyProviderImportsToVersionsInterface(braavos)), + lazyProvider(legacyProviderImportsToVersionsInterface(ledger)), + lazyProvider(legacyProviderImportsToVersionsInterface(rabby)), + lazyProvider(legacyProviderImportsToVersionsInterface(trezor)), + lazyProvider(legacyProviderImportsToVersionsInterface(solflare)), + lazyProvider(legacyProviderImportsToVersionsInterface(mytonwallet)), + ]; +}; diff --git a/wallets/provider-all/tsconfig.build.json b/wallets/provider-all/tsconfig.build.json new file mode 100644 index 0000000000..cf4e16a927 --- /dev/null +++ b/wallets/provider-all/tsconfig.build.json @@ -0,0 +1,13 @@ +{ + // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs + "extends": "../../tsconfig.bundler.json", + "include": ["src", "types"], + "compilerOptions": { + "outDir": "dist", + "rootDir": "./src", + "lib": ["dom", "esnext"], + + // `@trezor/connect-web` can not compile without this option, we should remove this option when they've fixed their issue + "skipLibCheck": true + } +} diff --git a/wallets/provider-all/tsconfig.json b/wallets/provider-all/tsconfig.json index 2c85b2d991..a3a0b0f59d 100644 --- a/wallets/provider-all/tsconfig.json +++ b/wallets/provider-all/tsconfig.json @@ -1,35 +1 @@ -{ - // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs - "include": ["src", "types"], - "compilerOptions": { - "module": "esnext", - "lib": ["dom", "esnext"], - "importHelpers": true, - // output .d.ts declaration files for consumers - "declaration": true, - // output .js.map sourcemap files for consumers - "sourceMap": true, - // match output dir to input dir. e.g. dist/index instead of dist/src/index - "rootDir": "./src", - // stricter type-checking for stronger correctness. Recommended by TS - "strict": true, - // linter checks for common issues - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true, - // noUnused* overlap with @typescript-eslint/no-unused-vars, can disable if duplicative - "noUnusedLocals": true, - "noUnusedParameters": true, - // use Node's module resolution algorithm, instead of the legacy TS one - "moduleResolution": "node", - // transpile JSX to React.createElement - "jsx": "react", - // interop between ESM and CJS modules. Recommended by TS - "esModuleInterop": true, - // significant perf increase by skipping checking .d.ts files, particularly those in node_modules. Recommended by TS - "skipLibCheck": true, - // error out if import and file system have a casing mismatch. Recommended by TS - "forceConsistentCasingInFileNames": true, - // `tsdx build` ignores this option, but it is commonly used when type-checking separately with `tsc` - "noEmit": true, - } -} +{ "extends": "./tsconfig.build.json", "include": ["src", "tests"] } diff --git a/wallets/provider-argentx/CHANGELOG.md b/wallets/provider-argentx/CHANGELOG.md new file mode 100644 index 0000000000..bd342a6402 --- /dev/null +++ b/wallets/provider-argentx/CHANGELOG.md @@ -0,0 +1,152 @@ +# [0.42.0](https://github.com/rango-exchange/rango-client/compare/provider-argentx@0.41.0...provider-argentx@0.42.0) (2024-12-30) + + + +# [0.41.0](https://github.com/rango-exchange/rango-client/compare/provider-argentx@0.40.0...provider-argentx@0.41.0) (2024-11-27) + + + +# [0.40.0](https://github.com/rango-exchange/rango-client/compare/provider-argentx@0.39.0...provider-argentx@0.40.0) (2024-11-12) + + + +# [0.39.0](https://github.com/rango-exchange/rango-client/compare/provider-argentx@0.38.0...provider-argentx@0.39.0) (2024-10-12) + + +### Bug Fixes + +* bump sdk and fix type issues ([d442208](https://github.com/rango-exchange/rango-client/commit/d4422083bf5dd27d5f509ce1db7f9560d05428c8)) + + +### Performance Improvements + +* lazy load signer packages ([7b88f18](https://github.com/rango-exchange/rango-client/commit/7b88f1834f7b29b4b81ab6c81a07bb88e8ccf55c)) + + + +# [0.38.0](https://github.com/rango-exchange/rango-client/compare/provider-argentx@0.37.0...provider-argentx@0.38.0) (2024-09-10) + + + +# [0.37.0](https://github.com/rango-exchange/rango-client/compare/provider-argentx@0.36.1...provider-argentx@0.37.0) (2024-08-11) + + + +## [0.36.1](https://github.com/rango-exchange/rango-client/compare/provider-argentx@0.36.0...provider-argentx@0.36.1) (2024-07-14) + + + +# [0.36.0](https://github.com/rango-exchange/rango-client/compare/provider-argentx@0.34.0...provider-argentx@0.36.0) (2024-07-09) + + + +# [0.35.0](https://github.com/rango-exchange/rango-client/compare/provider-argentx@0.34.0...provider-argentx@0.35.0) (2024-06-01) + + + +# [0.34.0](https://github.com/rango-exchange/rango-client/compare/provider-argentx@0.33.0...provider-argentx@0.34.0) (2024-05-14) + + + +# [0.33.0](https://github.com/rango-exchange/rango-client/compare/provider-argentx@0.32.0...provider-argentx@0.33.0) (2024-04-24) + + + +# [0.32.0](https://github.com/rango-exchange/rango-client/compare/provider-argentx@0.31.0...provider-argentx@0.32.0) (2024-04-23) + + + +# [0.31.0](https://github.com/rango-exchange/rango-client/compare/provider-argentx@0.30.0...provider-argentx@0.31.0) (2024-04-09) + + +### Bug Fixes + +* fix the connection problem that happens when another wallet takes over the requested one ([42df212](https://github.com/rango-exchange/rango-client/commit/42df2120aadd84c95045b0bf76844c19305fb59a)) + + + +# [0.30.0](https://github.com/rango-exchange/rango-client/compare/provider-argentx@0.29.0...provider-argentx@0.30.0) (2024-03-12) + + + +# [0.29.0](https://github.com/rango-exchange/rango-client/compare/provider-argentx@0.28.0...provider-argentx@0.29.0) (2024-02-20) + + + +# [0.28.0](https://github.com/rango-exchange/rango-client/compare/provider-argentx@0.27.0...provider-argentx@0.28.0) (2024-02-07) + + + +# [0.27.0](https://github.com/rango-exchange/rango-client/compare/provider-argentx@0.26.0...provider-argentx@0.27.0) (2024-01-22) + + +### Bug Fixes + +* cleanup wallets' subscriber when setProvider get null ([88d6a42](https://github.com/rango-exchange/rango-client/commit/88d6a423c49b34b3d9ff567e22df36c3b009bb76)) + + + +# [0.26.0](https://github.com/rango-exchange/rango-client/compare/provider-argentx@0.24.0...provider-argentx@0.26.0) (2023-12-24) + + +### Bug Fixes + +* fix HMR for widget and playground ([8524820](https://github.com/rango-exchange/rango-client/commit/8524820f10cf0b8921f3db0c4f620ff98daa4103)) + + + +# [0.14.0](https://github.com/rango-exchange/rango-client/compare/provider-argentx@0.13.0...provider-argentx@0.14.0) (2023-08-03) + + + +# [0.13.0](https://github.com/rango-exchange/rango-client/compare/provider-argentx@0.12.0...provider-argentx@0.13.0) (2023-08-01) + + + +# [0.9.0](https://github.com/rango-exchange/rango-client/compare/provider-argentx@0.8.0...provider-argentx@0.9.0) (2023-07-31) + + +### Features + +* support braavos wallet ([fb38ebe](https://github.com/rango-exchange/rango-client/commit/fb38ebef00a33b92cabf506c88ef83d8c77cce84)) + + + +# [0.7.0](https://github.com/rango-exchange/rango-client/compare/provider-argentx@0.6.0...provider-argentx@0.7.0) (2023-07-11) + + + +# [0.6.0](https://github.com/rango-exchange/rango-client/compare/provider-argentx@0.5.0...provider-argentx@0.6.0) (2023-07-11) + + +### Reverts + +* Revert "support for rango-types cjs format" ([ed4e050](https://github.com/rango-exchange/rango-client/commit/ed4e050bfc0dcde7aeffa6b0d73b02080a5721eb)) + + + +# [0.5.0](https://github.com/rango-exchange/rango-client/compare/provider-argentx@0.4.0...provider-argentx@0.5.0) (2023-05-31) + + + +# [0.4.0](https://github.com/rango-exchange/rango-client/compare/provider-argentx@0.3.0...provider-argentx@0.4.0) (2023-05-31) + + + +# [0.3.0](https://github.com/rango-exchange/rango-client/compare/provider-argentx@0.2.0...provider-argentx@0.3.0) (2023-05-30) + + + +# [0.2.0](https://github.com/rango-exchange/rango-client/compare/provider-argentx@0.1.15...provider-argentx@0.2.0) (2023-05-30) + + + +## [0.1.14](https://github.com/rango-exchange/rango-client/compare/provider-argentx@0.1.13...provider-argentx@0.1.14) (2023-05-15) + + +### Bug Fixes + +* update rango-types and fix notification bugs ([993f185](https://github.com/rango-exchange/rango-client/commit/993f185e0b8c5e5e15a2c65ba2d85d1f9c8daa90)) + + + diff --git a/wallets/provider-argentx/package.json b/wallets/provider-argentx/package.json index 4f0c620b97..a7650cee58 100644 --- a/wallets/provider-argentx/package.json +++ b/wallets/provider-argentx/package.json @@ -1,49 +1,31 @@ { "name": "@rango-dev/provider-argentx", - "version": "0.1.12", + "version": "0.41.1-next.6", "license": "MIT", - "module": "dist/provider-argentx.esm.js", - "main": "dist/index.js", + "type": "module", + "source": "./src/index.ts", + "main": "./dist/index.js", + "exports": { + ".": "./dist/index.js" + }, "typings": "dist/index.d.ts", "files": [ "dist", "src" ], "scripts": { - "start": "tsdx watch", - "build": "tsdx build --tsconfig ./tsconfig.json", - "test": "tsdx test --passWithNoTests", - "lint": "tsdx lint", - "size": "size-limit", - "analyze": "size-limit --why" - }, - "husky": { - "hooks": { - "pre-commit": "tsdx lint" - } + "build": "node ../../scripts/build/command.mjs --path wallets/provider-argentx", + "ts-check": "tsc --declaration --emitDeclarationOnly -p ./tsconfig.json", + "clean": "rimraf dist", + "format": "prettier --write '{.,src}/**/*.{ts,tsx}'", + "lint": "eslint \"**/*.{ts,tsx}\" --ignore-path ../../.eslintignore" }, - "prettier": { - "printWidth": 80, - "semi": true, - "singleQuote": true, - "trailingComma": "es5" - }, - "size-limit": [ - { - "path": "dist/provider-argentx.cjs.production.min.js", - "limit": "10 KB" - }, - { - "path": "dist/provider-argentx.esm.js", - "limit": "10 KB" - } - ], "dependencies": { - "@rango-dev/signer-starknet": "^0.1.11", - "@rango-dev/wallets-shared": "^0.1.11", - "rango-types": "^0.1.28" + "@rango-dev/signer-starknet": "^0.32.0", + "@rango-dev/wallets-shared": "^0.40.1-next.6", + "rango-types": "^0.1.74" }, "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/wallets/provider-argentx/src/helpers.ts b/wallets/provider-argentx/src/helpers.ts index a02ebe5ac4..5937b30e80 100644 --- a/wallets/provider-argentx/src/helpers.ts +++ b/wallets/provider-argentx/src/helpers.ts @@ -1,5 +1,5 @@ export function argentx() { - const { starknet } = window; - if (!!starknet) return starknet; + const { starknet_argentX } = window; + if (!!starknet_argentX) return starknet_argentX; return null; } diff --git a/wallets/provider-argentx/src/index.ts b/wallets/provider-argentx/src/index.ts index 4acbf0a1a6..c03f4dc090 100644 --- a/wallets/provider-argentx/src/index.ts +++ b/wallets/provider-argentx/src/index.ts @@ -1,26 +1,31 @@ -import { - Network, - WalletType, +import type { + CanEagerConnect, CanSwitchNetwork, Connect, Subscribe, WalletInfo, } from '@rango-dev/wallets-shared'; -import { SignerFactory, BlockchainMeta, starknetBlockchain } from 'rango-types'; -import { argentx as argentx_instances } from './helpers'; -import signer from './signer'; +import type { BlockchainMeta, SignerFactory } from 'rango-types'; -// https://www.starknetjs.com/docs/API/signer -// https://github.com/apibara/starknet-react -// https://github.com/0xs34n/starknet.js -// https://github.com/argentlabs/argent-x#-usage-with-your-dapp +import { Networks, WalletTypes } from '@rango-dev/wallets-shared'; +import { starknetBlockchain } from 'rango-types'; -const WALLET = WalletType.ARGENTX; +import { argentx as argentx_instances } from './helpers.js'; +import signer from './signer.js'; + +/* + * https://www.starknetjs.com/docs/API/signer + * https://github.com/apibara/starknet-react + * https://github.com/0xs34n/starknet.js + * https://github.com/argentlabs/argent-x#-usage-with-your-dapp + */ + +const WALLET = WalletTypes.ARGENTX; const MAINNET_CHAIN_ID = 'SN_MAIN'; export const config = { type: WALLET, - defaultNetwork: Network.STARKNET, + defaultNetwork: Networks.STARKNET, }; export const getInstance = argentx_instances; @@ -31,26 +36,35 @@ export const connect: Connect = async ({ instance }) => { if (!r || !instance.isConnected || r?.length === 0) { throw new Error('Error connecting ArgentX'); } - if (instance?.chainId !== MAINNET_CHAIN_ID) + if (instance?.chainId !== MAINNET_CHAIN_ID) { throw new Error( `Please switch to Mainnet, current network is ${instance?.chainId}` ); - return { accounts: !!r ? r : [], chainId: Network.STARKNET }; + } + return { accounts: r ? r : [], chainId: Networks.STARKNET }; }; export const subscribe: Subscribe = ({ instance, state, updateAccounts }) => { - instance?.on('accountsChanged', (accounts: any) => { + const handleAccountsChanged = (accounts: any) => { if (state.connected) { - if (!!instance) { - updateAccounts(accounts, Network.STARKNET); + if (instance) { + updateAccounts(accounts, Networks.STARKNET); } } - }); + }; + instance?.on?.('accountsChanged', handleAccountsChanged); + + return () => { + instance?.off?.('accountsChanged', handleAccountsChanged); + }; }; export const canSwitchNetworkTo: CanSwitchNetwork = () => false; -export const getSigners: (provider: any) => SignerFactory = signer; +export const getSigners: (provider: any) => Promise = signer; + +export const canEagerConnect: CanEagerConnect = ({ instance }) => + instance.isPreauthorized(); export const getWalletInfo: (allBlockChains: BlockchainMeta[]) => WalletInfo = ( allBlockChains @@ -58,7 +72,7 @@ export const getWalletInfo: (allBlockChains: BlockchainMeta[]) => WalletInfo = ( const starknet = starknetBlockchain(allBlockChains); return { name: 'ArgentX', - img: 'https://raw.githubusercontent.com/rango-exchange/rango-types/main/assets/icons/wallets/argentx.svg', + img: 'https://raw.githubusercontent.com/rango-exchange/assets/main/wallets/argentx/icon.svg', installLink: { CHROME: 'https://chrome.google.com/webstore/detail/argent-x/dlcobpjiigpikoobohmabehhmhfoodbb', diff --git a/wallets/provider-argentx/src/signer.ts b/wallets/provider-argentx/src/signer.ts index a0eefa39b8..60e90b2966 100644 --- a/wallets/provider-argentx/src/signer.ts +++ b/wallets/provider-argentx/src/signer.ts @@ -1,8 +1,12 @@ +import type { SignerFactory } from 'rango-types'; + import { DefaultStarknetSigner } from '@rango-dev/signer-starknet'; -import { SignerFactory, TransactionType as TxType } from 'rango-types'; +import { DefaultSignerFactory, TransactionType as TxType } from 'rango-types'; -export default function getSigners(provider: any): SignerFactory { - const signers = new SignerFactory(); +export default async function getSigners( + provider: any +): Promise { + const signers = new DefaultSignerFactory(); signers.registerSigner(TxType.STARKNET, new DefaultStarknetSigner(provider)); return signers; } diff --git a/wallets/provider-argentx/tsconfig.build.json b/wallets/provider-argentx/tsconfig.build.json new file mode 100644 index 0000000000..d9181ce0cd --- /dev/null +++ b/wallets/provider-argentx/tsconfig.build.json @@ -0,0 +1,11 @@ +{ + // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs + "extends": "../../tsconfig.libnext.json", + "include": ["src", "types", "../../global-wallets-env.d.ts"], + "compilerOptions": { + "outDir": "dist", + "rootDir": "./src", + "lib": ["dom", "esnext"] + // match output dir to input dir. e.g. dist/index instead of dist/src/index + } +} diff --git a/wallets/provider-argentx/tsconfig.json b/wallets/provider-argentx/tsconfig.json index 365489616a..a3a0b0f59d 100644 --- a/wallets/provider-argentx/tsconfig.json +++ b/wallets/provider-argentx/tsconfig.json @@ -1,35 +1 @@ -{ - // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs - "include": ["src", "types", "../../global-wallets-env.d.ts"], - "compilerOptions": { - "module": "esnext", - "lib": ["dom", "esnext"], - "importHelpers": true, - // output .d.ts declaration files for consumers - "declaration": true, - // output .js.map sourcemap files for consumers - "sourceMap": true, - // match output dir to input dir. e.g. dist/index instead of dist/src/index - "rootDir": "./src", - // stricter type-checking for stronger correctness. Recommended by TS - "strict": true, - // linter checks for common issues - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true, - // noUnused* overlap with @typescript-eslint/no-unused-vars, can disable if duplicative - "noUnusedLocals": true, - "noUnusedParameters": true, - // use Node's module resolution algorithm, instead of the legacy TS one - "moduleResolution": "node", - // transpile JSX to React.createElement - "jsx": "react", - // interop between ESM and CJS modules. Recommended by TS - "esModuleInterop": true, - // significant perf increase by skipping checking .d.ts files, particularly those in node_modules. Recommended by TS - "skipLibCheck": true, - // error out if import and file system have a casing mismatch. Recommended by TS - "forceConsistentCasingInFileNames": true, - // `tsdx build` ignores this option, but it is commonly used when type-checking separately with `tsc` - "noEmit": true, - } -} +{ "extends": "./tsconfig.build.json", "include": ["src", "tests"] } diff --git a/wallets/provider-binance-chain-wallet/package.json b/wallets/provider-binance-chain-wallet/package.json deleted file mode 100644 index 62693c8e89..0000000000 --- a/wallets/provider-binance-chain-wallet/package.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "name": "@rango-dev/provider-binance-chain-wallet", - "version": "0.1.12", - "license": "MIT", - "module": "dist/provider-binance-chain-wallet.esm.js", - "main": "dist/index.js", - "typings": "dist/index.d.ts", - "files": [ - "dist", - "src" - ], - "scripts": { - "start": "tsdx watch", - "build": "tsdx build --tsconfig ./tsconfig.json", - "test": "tsdx test --passWithNoTests", - "lint": "tsdx lint", - "size": "size-limit", - "analyze": "size-limit --why" - }, - "husky": { - "hooks": { - "pre-commit": "tsdx lint" - } - }, - "prettier": { - "printWidth": 80, - "semi": true, - "singleQuote": true, - "trailingComma": "es5" - }, - "size-limit": [ - { - "path": "dist/provider-binance-chain-wallet.cjs.production.min.js", - "limit": "10 KB" - }, - { - "path": "dist/provider-binance-chain-wallet.esm.js", - "limit": "10 KB" - } - ], - "dependencies": { - "@binance-chain/javascript-sdk": "^4.1.1", - "@rango-dev/signer-evm": "^0.1.11", - "@rango-dev/wallets-shared": "^0.1.11", - "rango-types": "^0.1.28" - }, - "publishConfig": { - "access": "public" - } -} diff --git a/wallets/provider-binance-chain-wallet/readme.md b/wallets/provider-binance-chain-wallet/readme.md deleted file mode 100644 index 5392b579ea..0000000000 --- a/wallets/provider-binance-chain-wallet/readme.md +++ /dev/null @@ -1 +0,0 @@ -# @rango-dev/provider-binance-chain-wallet diff --git a/wallets/provider-binance-chain-wallet/src/cosmos-signer.ts b/wallets/provider-binance-chain-wallet/src/cosmos-signer.ts deleted file mode 100644 index 21a7b29d4c..0000000000 --- a/wallets/provider-binance-chain-wallet/src/cosmos-signer.ts +++ /dev/null @@ -1,79 +0,0 @@ -import { BncClient, Transaction } from '@binance-chain/javascript-sdk'; -import { StdSignMsg } from '@binance-chain/javascript-sdk/lib/types'; -import { getPublicKey } from '@binance-chain/javascript-sdk/lib/crypto'; -import { cosmosMessageToBCSendMsg } from './helpers'; -import { - CosmosTransaction, - GenericSigner, - SignerError, - SignerErrorCode, -} from 'rango-types'; - -export const executeCosmosMessage = async ( - cosmosProvider: any, - tx: CosmosTransaction -): Promise => { - // eslint-disable-next-line no-async-promise-executor - return new Promise(async function (resolve, reject) { - try { - const bncClient = new BncClient('https://dex.binance.org'); - bncClient.chooseNetwork('mainnet'); - await bncClient.initChain(); - bncClient.useDefaultSigningDelegate(); - bncClient.useDefaultBroadcastDelegate(); - - const { chainId, account_number, sequence, memo, source } = tx.data; - if (!chainId) throw Error('ChainId is undefined from server'); - if (!account_number) - throw Error('account_number is undefined from server'); - if (!sequence) throw Error('Sequence is undefined from server'); - if (!memo) throw Error('Memo is undefined from server'); - if (!source) throw Error('Source is undefined from server'); - - const sendmsg = cosmosMessageToBCSendMsg(tx.data.msgs[0]); - const data: StdSignMsg = { - chainId, - accountNumber: account_number, - sequence: parseInt(sequence), - memo, - source, - msg: sendmsg.getMsg(), - }; - - const newTx = new Transaction(data); - const r = await cosmosProvider.bbcSignTx({ - tx: newTx, - signMsg: sendmsg.getSignMsg(), - }); - - const pubkey = getPublicKey(r.pubKey); - newTx.addSignature(pubkey, Buffer.from(r.signature, 'hex')); - - const res = await bncClient.sendRawTransaction(newTx.serialize(), true); - - const txHash = res.result[0].hash; - resolve(txHash); - } catch (error) { - reject(new SignerError(SignerErrorCode.SEND_TX_ERROR, undefined, error)); - } - }); -}; - -// TODO - replace with real type -// tslint:disable-next-line: no-any -type CosmosExternalProvider = any; - -export class CustomCosmosSigner implements GenericSigner { - private provider: CosmosExternalProvider; - constructor(provider: CosmosExternalProvider) { - this.provider = provider; - } - - async signMessage(): Promise { - throw SignerError.UnimplementedError('signMessage'); - } - - async signAndSendTx(tx: CosmosTransaction): Promise { - return await executeCosmosMessage(this.provider, tx); - } -} diff --git a/wallets/provider-binance-chain-wallet/src/helpers.ts b/wallets/provider-binance-chain-wallet/src/helpers.ts deleted file mode 100644 index d3aab039f0..0000000000 --- a/wallets/provider-binance-chain-wallet/src/helpers.ts +++ /dev/null @@ -1,130 +0,0 @@ -import { Network, ProviderConnectResult } from '@rango-dev/wallets-shared'; -import { RequestedAccount } from './types'; -import { - SignInputOutput, - SendMsg, -} from '@binance-chain/javascript-sdk/lib/types'; - -export function binance() { - const { BinanceChain } = window; - if (!!BinanceChain) { - if (BinanceChain.isCoin98) { - return null; - } - return BinanceChain; - } - return null; -} - -export function addressTypeToNetwork(type: string): Network { - switch (type) { - case 'eth': - return Network.ETHEREUM; - case 'bbc-mainnet': - return Network.BINANCE; - case 'bsc-mainnet': - return Network.BSC; - default: - return Network.Unknown; - } -} -export function getAllAccounts( - account: RequestedAccount -): ProviderConnectResult[] { - const output: ProviderConnectResult[] = []; - account.addresses - .filter((address) => !address.type.includes('testnet')) - .forEach((address) => { - output.push({ - accounts: [address.address], - chainId: addressTypeToNetwork(address.type), - }); - }); - - return output; -} - -export function findActiveAccount( - accounts: RequestedAccount[], - currentEthAddress: string -): RequestedAccount | undefined { - return accounts.find((account) => { - const searchForAddress = account.addresses.find((addressData) => { - return addressData.address == currentEthAddress; - }); - const foundAddress = !!searchForAddress; - - return foundAddress; - }); -} - -type Coin = { - denom: string; - amount: string; -}; - -type InputOutput = { address: string; coins: Coin[] }; - -type MsgSend = { - __type: string; - inputs: InputOutput[]; - outputs: InputOutput[]; - aminoPrefix: string; -}; - -function isMsgSend(msg: { __type: string }): msg is MsgSend { - return msg.__type === 'MsgSend'; -} - -export function cosmosMessageToBCSendMsg(msg: { __type: string }): SendMsg { - if (isMsgSend(msg)) { - const msgCopy = msg; - - if (msgCopy.inputs.length !== 1) - throw Error('Multi input coins for binance chain not supported'); - if (msgCopy.outputs.length !== 1) - throw Error('Multi output coins for binance chain not supported'); - if (msgCopy.inputs[0].coins.length !== 1) - throw Error('Multi input coins for binance chain not supported'); - if (msgCopy.outputs[0].coins.length !== 1) - throw Error('Multi output coins for binance chain not supported'); - - const outputs: SignInputOutput[] = [ - { - address: msgCopy.outputs[0].address, - coins: [ - { - denom: msgCopy.outputs[0].coins[0].denom.toUpperCase(), - amount: parseInt(msgCopy.outputs[0].coins[0].amount), - }, - ], - }, - ]; - - return new SendMsg(msgCopy.inputs[0].address, outputs); - } - - throw Error( - `Cosmos message with type ${msg.__type} not supported in Terra Station` - ); -} - -export async function accountsForActiveWallet( - instance: any, - currentEthAddress: string -) { - const allAvailableAccounts = - (await instance.requestAccounts()) as RequestedAccount[]; - const activeAccount = findActiveAccount( - allAvailableAccounts, - currentEthAddress - ); - const accounts = activeAccount ? getAllAccounts(activeAccount) : []; - return accounts; -} - -export const BINANCE_CHAIN_WALLET_SUPPORTED_CHAINS = [ - Network.ETHEREUM, - Network.BSC, - Network.BINANCE, -]; diff --git a/wallets/provider-binance-chain-wallet/src/index.ts b/wallets/provider-binance-chain-wallet/src/index.ts deleted file mode 100644 index 66a998a72a..0000000000 --- a/wallets/provider-binance-chain-wallet/src/index.ts +++ /dev/null @@ -1,87 +0,0 @@ -import { - CanSwitchNetwork, - Connect, - Subscribe, - getEvmAccounts, - Network, - WalletType, - WalletInfo, -} from '@rango-dev/wallets-shared'; -import { - accountsForActiveWallet, - binance as binance_instance, - BINANCE_CHAIN_WALLET_SUPPORTED_CHAINS, -} from './helpers'; -import signer from './signer'; -import { SignerFactory, BlockchainMeta, isEvmBlockchain } from 'rango-types'; - -const WALLET = WalletType.BINANCE_CHAIN; - -export const config = { - type: WALLET, - defaultNetwork: Network.ETHEREUM, -}; - -export const getInstance = binance_instance; -export const connect: Connect = async ({ instance }) => { - // Note: We need to get `chainId` here, because for the first time - // after opening the browser, wallet is locked, and don't give us accounts and chainId - // on `check` phase, so `network` will be null. For this case we need to get chainId - // whenever we are requesting accounts. - const evm = await getEvmAccounts(instance); - const accounts = await accountsForActiveWallet(instance, evm.accounts[0]); - - return accounts; -}; - -export const subscribe: Subscribe = ({ - instance, - state, - meta, - updateChainId, - updateAccounts, -}) => { - instance?.on('accountsChanged', async (addresses: string[]) => { - if (state.connected) { - const accounts = await accountsForActiveWallet(instance, addresses[0]); - - for (const account of accounts) { - const chainId = meta - .filter(isEvmBlockchain) - .find((blockchain) => blockchain.name === account.chainId)?.chainId; - const finalChainId = chainId || account.chainId; // use network instead of chain id when it's null - if (finalChainId && account.accounts) { - updateAccounts(account.accounts, finalChainId); - } - } - } - }); - instance?.on('chainChanged', (chainId: string) => { - updateChainId(chainId); - }); -}; - -export const canSwitchNetworkTo: CanSwitchNetwork = () => false; - -export const getSigners: (provider: any) => SignerFactory = signer; - -export const getWalletInfo: (allBlockChains: BlockchainMeta[]) => WalletInfo = ( - allBlockChains -) => ({ - name: 'Binance', - img: 'https://raw.githubusercontent.com/rango-exchange/rango-types/main/assets/icons/wallets/binance.svg', - installLink: { - CHROME: - 'https://chrome.google.com/webstore/detail/binance-chain-wallet/fhbohimaelbohpjbbldcngcnapndodjp', - BRAVE: - 'https://chrome.google.com/webstore/detail/binance-chain-wallet/fhbohimaelbohpjbbldcngcnapndodjp', - FIREFOX: 'https://addons.mozilla.org/en-US/firefox/addon/binance-chain', - DEFAULT: 'https://www.bnbchain.org/en', - }, - color: '#2b2e35', - supportedChains: allBlockChains.filter((blockchainMeta) => - BINANCE_CHAIN_WALLET_SUPPORTED_CHAINS.includes( - blockchainMeta.name as Network - ) - ), -}); diff --git a/wallets/provider-binance-chain-wallet/src/signer.ts b/wallets/provider-binance-chain-wallet/src/signer.ts deleted file mode 100644 index d1d5417b60..0000000000 --- a/wallets/provider-binance-chain-wallet/src/signer.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { DefaultEvmSigner } from '@rango-dev/signer-evm'; -import { Network, getNetworkInstance } from '@rango-dev/wallets-shared'; -import { SignerFactory, TransactionType as TxType } from 'rango-types'; -import { CustomCosmosSigner } from './cosmos-signer'; - -export default function getSigners(provider: any): SignerFactory { - const ethProvider = getNetworkInstance(provider, Network.ETHEREUM); - const cosmosProvider = getNetworkInstance(provider, Network.COSMOS); - const signers = new SignerFactory(); - signers.registerSigner(TxType.EVM, new DefaultEvmSigner(ethProvider)); - signers.registerSigner(TxType.COSMOS, new CustomCosmosSigner(cosmosProvider)); - return signers; -} diff --git a/wallets/provider-binance-chain-wallet/src/types.ts b/wallets/provider-binance-chain-wallet/src/types.ts deleted file mode 100644 index 702bf27a5f..0000000000 --- a/wallets/provider-binance-chain-wallet/src/types.ts +++ /dev/null @@ -1,10 +0,0 @@ -export interface RequestedAccount { - id: string; - name: string; - icon: string; - type: string; - addresses: { - type: string; - address: string; - }[]; -} diff --git a/wallets/provider-binance-chain-wallet/tsconfig.json b/wallets/provider-binance-chain-wallet/tsconfig.json deleted file mode 100644 index 365489616a..0000000000 --- a/wallets/provider-binance-chain-wallet/tsconfig.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs - "include": ["src", "types", "../../global-wallets-env.d.ts"], - "compilerOptions": { - "module": "esnext", - "lib": ["dom", "esnext"], - "importHelpers": true, - // output .d.ts declaration files for consumers - "declaration": true, - // output .js.map sourcemap files for consumers - "sourceMap": true, - // match output dir to input dir. e.g. dist/index instead of dist/src/index - "rootDir": "./src", - // stricter type-checking for stronger correctness. Recommended by TS - "strict": true, - // linter checks for common issues - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true, - // noUnused* overlap with @typescript-eslint/no-unused-vars, can disable if duplicative - "noUnusedLocals": true, - "noUnusedParameters": true, - // use Node's module resolution algorithm, instead of the legacy TS one - "moduleResolution": "node", - // transpile JSX to React.createElement - "jsx": "react", - // interop between ESM and CJS modules. Recommended by TS - "esModuleInterop": true, - // significant perf increase by skipping checking .d.ts files, particularly those in node_modules. Recommended by TS - "skipLibCheck": true, - // error out if import and file system have a casing mismatch. Recommended by TS - "forceConsistentCasingInFileNames": true, - // `tsdx build` ignores this option, but it is commonly used when type-checking separately with `tsc` - "noEmit": true, - } -} diff --git a/wallets/provider-bitget/CHANGELOG.md b/wallets/provider-bitget/CHANGELOG.md new file mode 100644 index 0000000000..9dda9e0ecd --- /dev/null +++ b/wallets/provider-bitget/CHANGELOG.md @@ -0,0 +1,125 @@ +# [0.38.0](https://github.com/rango-exchange/rango-client/compare/provider-bitget@0.37.0...provider-bitget@0.38.0) (2024-12-30) + + + +# [0.37.0](https://github.com/rango-exchange/rango-client/compare/provider-bitget@0.36.0...provider-bitget@0.37.0) (2024-11-27) + + + +# [0.36.0](https://github.com/rango-exchange/rango-client/compare/provider-bitget@0.35.0...provider-bitget@0.36.0) (2024-11-12) + + + +# [0.35.0](https://github.com/rango-exchange/rango-client/compare/provider-bitget@0.34.0...provider-bitget@0.35.0) (2024-10-12) + + +### Bug Fixes + +* bump sdk and fix type issues ([d442208](https://github.com/rango-exchange/rango-client/commit/d4422083bf5dd27d5f509ce1db7f9560d05428c8)) + + +### Performance Improvements + +* lazy load signer packages ([7b88f18](https://github.com/rango-exchange/rango-client/commit/7b88f1834f7b29b4b81ab6c81a07bb88e8ccf55c)) + + + +# [0.34.0](https://github.com/rango-exchange/rango-client/compare/provider-bitget@0.33.0...provider-bitget@0.34.0) (2024-09-10) + + + +# [0.33.0](https://github.com/rango-exchange/rango-client/compare/provider-bitget@0.32.1...provider-bitget@0.33.0) (2024-08-11) + + + +## [0.32.1](https://github.com/rango-exchange/rango-client/compare/provider-bitget@0.32.0...provider-bitget@0.32.1) (2024-07-14) + + + +# [0.32.0](https://github.com/rango-exchange/rango-client/compare/provider-bitget@0.30.2...provider-bitget@0.32.0) (2024-07-09) + + + +# [0.31.0](https://github.com/rango-exchange/rango-client/compare/provider-bitget@0.30.2...provider-bitget@0.31.0) (2024-06-01) + + + +## [0.30.2](https://github.com/rango-exchange/rango-client/compare/provider-bitget@0.30.1...provider-bitget@0.30.2) (2024-05-26) + + + +## [0.30.1](https://github.com/rango-exchange/rango-client/compare/provider-bitget@0.30.0...provider-bitget@0.30.1) (2024-05-25) + + + +# [0.30.0](https://github.com/rango-exchange/rango-client/compare/provider-bitget@0.29.0...provider-bitget@0.30.0) (2024-05-14) + + + +# [0.29.0](https://github.com/rango-exchange/rango-client/compare/provider-bitget@0.28.0...provider-bitget@0.29.0) (2024-04-24) + + + +# [0.28.0](https://github.com/rango-exchange/rango-client/compare/provider-bitget@0.27.0...provider-bitget@0.28.0) (2024-04-23) + + + +# [0.27.0](https://github.com/rango-exchange/rango-client/compare/provider-bitget@0.26.0...provider-bitget@0.27.0) (2024-04-09) + + + +# [0.26.0](https://github.com/rango-exchange/rango-client/compare/provider-bitget@0.25.0...provider-bitget@0.26.0) (2024-03-12) + + + +# [0.25.0](https://github.com/rango-exchange/rango-client/compare/provider-bitget@0.24.0...provider-bitget@0.25.0) (2024-02-20) + + + +# [0.24.0](https://github.com/rango-exchange/rango-client/compare/provider-bitget@0.23.0...provider-bitget@0.24.0) (2024-02-07) + + + +# [0.23.0](https://github.com/rango-exchange/rango-client/compare/provider-bitget@0.22.0...provider-bitget@0.23.0) (2024-01-22) + + +### Bug Fixes + +* cleanup wallets' subscriber when setProvider get null ([88d6a42](https://github.com/rango-exchange/rango-client/commit/88d6a423c49b34b3d9ff567e22df36c3b009bb76)) + + + +# [0.22.0](https://github.com/rango-exchange/rango-client/compare/provider-bitget@0.20.0...provider-bitget@0.22.0) (2023-12-24) + + +### Bug Fixes + +* fix HMR for widget and playground ([8524820](https://github.com/rango-exchange/rango-client/commit/8524820f10cf0b8921f3db0c4f620ff98daa4103)) + + + +# [0.10.0](https://github.com/rango-exchange/rango-client/compare/provider-bitkeep@0.9.0...provider-bitkeep@0.10.0) (2023-08-03) + + + +# [0.9.0](https://github.com/rango-exchange/rango-client/compare/provider-bitkeep@0.8.0...provider-bitkeep@0.9.0) (2023-08-01) + + + +# [0.5.0](https://github.com/rango-exchange/rango-client/compare/provider-bitkeep@0.4.0...provider-bitkeep@0.5.0) (2023-07-31) + + + +# [0.3.0](https://github.com/rango-exchange/rango-client/compare/provider-bitkeep@0.2.0...provider-bitkeep@0.3.0) (2023-07-11) + + + +# 0.2.0 (2023-07-11) + + +### Features + +* add bitkeep wallet ([c02c3df](https://github.com/rango-exchange/rango-client/commit/c02c3dfd236070295eada74aeb97514f8dacd0ed)) + + + diff --git a/wallets/provider-bitget/package.json b/wallets/provider-bitget/package.json new file mode 100644 index 0000000000..1e5a2ef914 --- /dev/null +++ b/wallets/provider-bitget/package.json @@ -0,0 +1,32 @@ +{ + "name": "@rango-dev/provider-bitget", + "version": "0.37.1-next.6", + "license": "MIT", + "type": "module", + "source": "./src/index.ts", + "main": "./dist/index.js", + "exports": { + ".": "./dist/index.js" + }, + "typings": "dist/index.d.ts", + "files": [ + "dist", + "src" + ], + "scripts": { + "build": "node ../../scripts/build/command.mjs --path wallets/provider-bitget", + "ts-check": "tsc --declaration --emitDeclarationOnly -p ./tsconfig.json", + "clean": "rimraf dist", + "format": "prettier --write '{.,src}/**/*.{ts,tsx}'", + "lint": "eslint \"**/*.{ts,tsx}\" --ignore-path ../../.eslintignore" + }, + "dependencies": { + "@rango-dev/signer-evm": "^0.32.0", + "@rango-dev/signer-tron": "^0.31.0", + "@rango-dev/wallets-shared": "^0.40.1-next.6", + "rango-types": "^0.1.74" + }, + "publishConfig": { + "access": "public" + } +} \ No newline at end of file diff --git a/wallets/provider-bitget/readme.md b/wallets/provider-bitget/readme.md new file mode 100644 index 0000000000..51893daadf --- /dev/null +++ b/wallets/provider-bitget/readme.md @@ -0,0 +1 @@ +# @rango-dev/provider-bitget diff --git a/wallets/provider-bitget/src/helpers.ts b/wallets/provider-bitget/src/helpers.ts new file mode 100644 index 0000000000..596651e011 --- /dev/null +++ b/wallets/provider-bitget/src/helpers.ts @@ -0,0 +1,28 @@ +import type { Network } from '@rango-dev/wallets-shared'; + +import { Networks } from '@rango-dev/wallets-shared'; + +type Provider = Map; + +export function bitgetInstances(): Provider | null { + const instances: Provider = new Map(); + const { bitkeep } = window; + + if (!bitkeep) { + return null; + } + + if (bitkeep.ethereum) { + instances.set(Networks.ETHEREUM, bitkeep.ethereum); + } + + if (bitkeep.tronLink) { + instances.set(Networks.TRON, bitkeep.tronLink); + } + + if (instances.size === 0) { + return null; + } + + return instances; +} diff --git a/wallets/provider-bitget/src/index.ts b/wallets/provider-bitget/src/index.ts new file mode 100644 index 0000000000..1097c81e18 --- /dev/null +++ b/wallets/provider-bitget/src/index.ts @@ -0,0 +1,141 @@ +import type { + CanEagerConnect, + CanSwitchNetwork, + Connect, + ProviderConnectResult, + Subscribe, + SwitchNetwork, + WalletInfo, +} from '@rango-dev/wallets-shared'; +import type { BlockchainMeta, SignerFactory } from 'rango-types'; + +import { + canEagerlyConnectToEvm, + canSwitchNetworkToEvm, + chooseInstance, + getEvmAccounts, + Networks, + subscribeToEvm, + switchNetworkForEvm, + WalletTypes, +} from '@rango-dev/wallets-shared'; +import { evmBlockchains, isEvmBlockchain, tronBlockchain } from 'rango-types'; + +import { bitgetInstances } from './helpers.js'; +import signer from './signer.js'; + +const WALLET = WalletTypes.BITGET; + +export const config = { + type: WALLET, + defaultNetwork: Networks.ETHEREUM, +}; + +export const getInstance = bitgetInstances; + +export const connect: Connect = async ({ instance, meta }) => { + const ethInstance = chooseInstance(instance, meta, Networks.ETHEREUM); + const tronInstance = chooseInstance(instance, meta, Networks.TRON); + + const results: ProviderConnectResult[] = []; + + if (ethInstance) { + const evmResult = await getEvmAccounts(ethInstance); + results.push(evmResult); + } + + if (tronInstance) { + const res = await tronInstance.request({ method: 'tron_requestAccounts' }); + if (!res) { + throw new Error('Please unlock your Bitget extension first.'); + } + // eslint-disable-next-line @typescript-eslint/no-magic-numbers + if (!!res?.code && !!res.message && res.code !== 200) { + throw new Error(res.message); + } + const address = tronInstance.tronWeb.defaultAddress.base58; + results.push({ + accounts: address ? [address] : [], + chainId: Networks.TRON, + }); + } + + return results; +}; + +export const subscribe: Subscribe = ({ + instance, + state, + updateChainId, + updateAccounts, + meta, + connect, + disconnect, +}) => { + const ethInstance = instance.get(Networks.ETHEREUM); + const evmBlockchainMeta = meta.filter(isEvmBlockchain); + + const cleanup = subscribeToEvm({ + instance: ethInstance, + state, + updateChainId, + updateAccounts, + meta: evmBlockchainMeta, + connect, + disconnect, + }); + + window.addEventListener('message', (e) => { + if ( + e.data.isTronLink && + e.data.message && + e.data.message.action == 'accountsChanged' + ) { + const account = e?.data?.message?.data?.address; + if (account) { + updateAccounts([account]); + } else { + disconnect(); + } + } + }); + + return () => { + if (cleanup) { + cleanup(); + } + }; +}; + +export const switchNetwork: SwitchNetwork = switchNetworkForEvm; + +export const canSwitchNetworkTo: CanSwitchNetwork = canSwitchNetworkToEvm; + +export const canEagerConnect: CanEagerConnect = async ({ instance, meta }) => { + const evm_instance = chooseInstance(instance, meta, Networks.ETHEREUM); + if (evm_instance) { + return canEagerlyConnectToEvm({ instance: evm_instance, meta }); + } + return Promise.resolve(false); +}; +export const getSigners: (provider: any) => Promise = signer; + +export const getWalletInfo: (allBlockChains: BlockchainMeta[]) => WalletInfo = ( + allBlockChains +) => { + const evms = evmBlockchains(allBlockChains); + const tron = tronBlockchain(allBlockChains); + return { + name: 'Bitget Wallet', + img: 'https://raw.githubusercontent.com/rango-exchange/assets/main/wallets/bitget/icon.svg', + installLink: { + CHROME: + 'https://chrome.google.com/webstore/detail/bitkeep-crypto-nft-wallet/jiidiaalihmmhddjgbnbgdfflelocpak', + BRAVE: + 'https://chrome.google.com/webstore/detail/bitkeep-crypto-nft-wallet/jiidiaalihmmhddjgbnbgdfflelocpak', + DEFAULT: 'https://web3.bitget.com/en/wallet-download?type=1', + }, + color: '#ffffff', + supportedChains: [...evms, ...tron], + }; +}; diff --git a/wallets/provider-bitget/src/signer.ts b/wallets/provider-bitget/src/signer.ts new file mode 100644 index 0000000000..c79fea9e00 --- /dev/null +++ b/wallets/provider-bitget/src/signer.ts @@ -0,0 +1,17 @@ +import type { SignerFactory } from 'rango-types'; + +import { DefaultTronSigner } from '@rango-dev/signer-tron'; +import { getNetworkInstance, Networks } from '@rango-dev/wallets-shared'; +import { DefaultSignerFactory, TransactionType as TxType } from 'rango-types'; + +export default async function getSigners( + provider: any +): Promise { + const ethProvider = getNetworkInstance(provider, Networks.ETHEREUM); + const tronProvider = getNetworkInstance(provider, Networks.TRON); + const signers = new DefaultSignerFactory(); + const { DefaultEvmSigner } = await import('@rango-dev/signer-evm'); + signers.registerSigner(TxType.EVM, new DefaultEvmSigner(ethProvider)); + signers.registerSigner(TxType.TRON, new DefaultTronSigner(tronProvider)); + return signers; +} diff --git a/wallets/provider-bitget/tsconfig.build.json b/wallets/provider-bitget/tsconfig.build.json new file mode 100644 index 0000000000..5297e74971 --- /dev/null +++ b/wallets/provider-bitget/tsconfig.build.json @@ -0,0 +1,10 @@ +{ + // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs + "extends": "../../tsconfig.libnext.json", + "include": ["src", "types", "../../global-wallets-env.d.ts"], + "compilerOptions": { + "outDir": "dist", + "rootDir": "./src", + "lib": ["dom", "esnext"] + } +} diff --git a/wallets/provider-bitget/tsconfig.json b/wallets/provider-bitget/tsconfig.json new file mode 100644 index 0000000000..a3a0b0f59d --- /dev/null +++ b/wallets/provider-bitget/tsconfig.json @@ -0,0 +1 @@ +{ "extends": "./tsconfig.build.json", "include": ["src", "tests"] } diff --git a/wallets/provider-braavos/CHANGELOG.md b/wallets/provider-braavos/CHANGELOG.md new file mode 100644 index 0000000000..f544aa82f4 --- /dev/null +++ b/wallets/provider-braavos/CHANGELOG.md @@ -0,0 +1,114 @@ +# [0.35.0](https://github.com/rango-exchange/rango-client/compare/provider-braavos@0.34.0...provider-braavos@0.35.0) (2024-12-30) + + + +# [0.34.0](https://github.com/rango-exchange/rango-client/compare/provider-braavos@0.33.0...provider-braavos@0.34.0) (2024-11-27) + + + +# [0.33.0](https://github.com/rango-exchange/rango-client/compare/provider-braavos@0.32.0...provider-braavos@0.33.0) (2024-11-12) + + + +# [0.32.0](https://github.com/rango-exchange/rango-client/compare/provider-braavos@0.31.0...provider-braavos@0.32.0) (2024-10-12) + + +### Bug Fixes + +* bump sdk and fix type issues ([d442208](https://github.com/rango-exchange/rango-client/commit/d4422083bf5dd27d5f509ce1db7f9560d05428c8)) + + +### Performance Improvements + +* lazy load signer packages ([7b88f18](https://github.com/rango-exchange/rango-client/commit/7b88f1834f7b29b4b81ab6c81a07bb88e8ccf55c)) + + + +# [0.31.0](https://github.com/rango-exchange/rango-client/compare/provider-braavos@0.30.0...provider-braavos@0.31.0) (2024-09-10) + + + +# [0.30.0](https://github.com/rango-exchange/rango-client/compare/provider-braavos@0.29.1...provider-braavos@0.30.0) (2024-08-11) + + + +## [0.29.1](https://github.com/rango-exchange/rango-client/compare/provider-braavos@0.29.0...provider-braavos@0.29.1) (2024-07-14) + + + +# [0.29.0](https://github.com/rango-exchange/rango-client/compare/provider-braavos@0.27.0...provider-braavos@0.29.0) (2024-07-09) + + + +# [0.28.0](https://github.com/rango-exchange/rango-client/compare/provider-braavos@0.27.0...provider-braavos@0.28.0) (2024-06-01) + + + +# [0.27.0](https://github.com/rango-exchange/rango-client/compare/provider-braavos@0.26.0...provider-braavos@0.27.0) (2024-05-14) + + + +# [0.26.0](https://github.com/rango-exchange/rango-client/compare/provider-braavos@0.25.0...provider-braavos@0.26.0) (2024-04-24) + + + +# [0.25.0](https://github.com/rango-exchange/rango-client/compare/provider-braavos@0.24.0...provider-braavos@0.25.0) (2024-04-23) + + + +# [0.24.0](https://github.com/rango-exchange/rango-client/compare/provider-braavos@0.23.0...provider-braavos@0.24.0) (2024-04-09) + + +### Bug Fixes + +* fix the connection problem that happens when another wallet takes over the requested one ([42df212](https://github.com/rango-exchange/rango-client/commit/42df2120aadd84c95045b0bf76844c19305fb59a)) + + + +# [0.23.0](https://github.com/rango-exchange/rango-client/compare/provider-braavos@0.22.0...provider-braavos@0.23.0) (2024-03-12) + + + +# [0.22.0](https://github.com/rango-exchange/rango-client/compare/provider-braavos@0.21.0...provider-braavos@0.22.0) (2024-02-20) + + + +# [0.21.0](https://github.com/rango-exchange/rango-client/compare/provider-braavos@0.20.0...provider-braavos@0.21.0) (2024-02-07) + + + +# [0.20.0](https://github.com/rango-exchange/rango-client/compare/provider-braavos@0.19.0...provider-braavos@0.20.0) (2024-01-22) + + +### Bug Fixes + +* cleanup wallets' subscriber when setProvider get null ([88d6a42](https://github.com/rango-exchange/rango-client/commit/88d6a423c49b34b3d9ff567e22df36c3b009bb76)) + + + +# [0.19.0](https://github.com/rango-exchange/rango-client/compare/provider-braavos@0.17.0...provider-braavos@0.19.0) (2023-12-24) + + +### Bug Fixes + +* fix HMR for widget and playground ([8524820](https://github.com/rango-exchange/rango-client/commit/8524820f10cf0b8921f3db0c4f620ff98daa4103)) + + + +# [0.7.0](https://github.com/rango-exchange/rango-client/compare/provider-braavos@0.6.0...provider-braavos@0.7.0) (2023-08-03) + + + +# [0.6.0](https://github.com/rango-exchange/rango-client/compare/provider-braavos@0.5.0...provider-braavos@0.6.0) (2023-08-01) + + + +# 0.2.0 (2023-07-31) + + +### Features + +* support braavos wallet ([fb38ebe](https://github.com/rango-exchange/rango-client/commit/fb38ebef00a33b92cabf506c88ef83d8c77cce84)) + + + diff --git a/wallets/provider-braavos/package.json b/wallets/provider-braavos/package.json new file mode 100644 index 0000000000..e3cb6928ab --- /dev/null +++ b/wallets/provider-braavos/package.json @@ -0,0 +1,31 @@ +{ + "name": "@rango-dev/provider-braavos", + "version": "0.34.1-next.6", + "license": "MIT", + "type": "module", + "source": "./src/index.ts", + "main": "./dist/index.js", + "exports": { + ".": "./dist/index.js" + }, + "typings": "dist/index.d.ts", + "files": [ + "dist", + "src" + ], + "scripts": { + "build": "node ../../scripts/build/command.mjs --path wallets/provider-braavos", + "ts-check": "tsc --declaration --emitDeclarationOnly -p ./tsconfig.json", + "clean": "rimraf dist", + "format": "prettier --write '{.,src}/**/*.{ts,tsx}'", + "lint": "eslint \"**/*.{ts,tsx}\" --ignore-path ../../.eslintignore" + }, + "dependencies": { + "@rango-dev/signer-starknet": "^0.32.0", + "@rango-dev/wallets-shared": "^0.40.1-next.6", + "rango-types": "^0.1.74" + }, + "publishConfig": { + "access": "public" + } +} \ No newline at end of file diff --git a/wallets/provider-braavos/readme.md b/wallets/provider-braavos/readme.md new file mode 100644 index 0000000000..e4ff0a108d --- /dev/null +++ b/wallets/provider-braavos/readme.md @@ -0,0 +1 @@ +# @rango-dev/provider-braavos diff --git a/wallets/provider-braavos/src/helpers.ts b/wallets/provider-braavos/src/helpers.ts new file mode 100644 index 0000000000..180825f6eb --- /dev/null +++ b/wallets/provider-braavos/src/helpers.ts @@ -0,0 +1,5 @@ +export function getBraavosInstance() { + const { starknet_braavos } = window; + if (!!starknet_braavos) return starknet_braavos; + return null; +} diff --git a/wallets/provider-braavos/src/index.ts b/wallets/provider-braavos/src/index.ts new file mode 100644 index 0000000000..a6441fd6bc --- /dev/null +++ b/wallets/provider-braavos/src/index.ts @@ -0,0 +1,75 @@ +import type { + CanEagerConnect, + CanSwitchNetwork, + Connect, + Subscribe, + WalletInfo, +} from '@rango-dev/wallets-shared'; +import type { BlockchainMeta, SignerFactory } from 'rango-types'; + +import { Networks, WalletTypes } from '@rango-dev/wallets-shared'; +import { starknetBlockchain } from 'rango-types'; + +import { getBraavosInstance } from './helpers.js'; +import signer from './signer.js'; + +const WALLET = WalletTypes.BRAAVOS; + +export const config = { + type: WALLET, + defaultNetwork: Networks.STARKNET, +}; + +export const getInstance = getBraavosInstance; + +export const connect: Connect = async ({ instance }) => { + const accounts = await instance?.enable(); + if (!accounts?.length || !instance.isConnected) { + throw new Error('Connection Error'); + } + + return { accounts: accounts || [], chainId: Networks.STARKNET }; +}; + +export const subscribe: Subscribe = ({ instance, state, updateAccounts }) => { + const handleAccountsChanged = (accounts: any) => { + if (state.connected) { + if (instance) { + updateAccounts([accounts], Networks.STARKNET); + } + } + }; + instance?.on?.('accountsChanged', handleAccountsChanged); + return () => { + instance?.off?.('accountsChanged', handleAccountsChanged); + }; +}; + +export const canSwitchNetworkTo: CanSwitchNetwork = () => false; + +export const getSigners: (provider: any) => Promise = signer; + +export const canEagerConnect: CanEagerConnect = ({ instance }) => + instance.isPreauthorized(); + +export const getWalletInfo: (allBlockChains: BlockchainMeta[]) => WalletInfo = ( + allBlockChains +) => { + const starknet = starknetBlockchain(allBlockChains); + return { + name: 'Braavos', + img: 'https://raw.githubusercontent.com/rango-exchange/assets/main/wallets/braavos/icon.svg', + installLink: { + CHROME: + 'https://chrome.google.com/webstore/detail/braavos-smart-wallet/jnlgamecbpmbajjfhmmmlhejkemejdma', + BRAVE: + 'https://chrome.google.com/webstore/detail/braavos-smart-wallet/jnlgamecbpmbajjfhmmmlhejkemejdma', + FIREFOX: 'https://addons.mozilla.org/en-US/firefox/addon/braavos-wallet/', + EDGE: 'https://microsoftedge.microsoft.com/addons/detail/braavos-wallet/hkkpjehhcnhgefhbdcgfkeegglpjchdc', + DEFAULT: 'https://braavos.app/', + }, + + color: '#96e7ed', + supportedChains: starknet, + }; +}; diff --git a/wallets/provider-braavos/src/signer.ts b/wallets/provider-braavos/src/signer.ts new file mode 100644 index 0000000000..60e90b2966 --- /dev/null +++ b/wallets/provider-braavos/src/signer.ts @@ -0,0 +1,12 @@ +import type { SignerFactory } from 'rango-types'; + +import { DefaultStarknetSigner } from '@rango-dev/signer-starknet'; +import { DefaultSignerFactory, TransactionType as TxType } from 'rango-types'; + +export default async function getSigners( + provider: any +): Promise { + const signers = new DefaultSignerFactory(); + signers.registerSigner(TxType.STARKNET, new DefaultStarknetSigner(provider)); + return signers; +} diff --git a/wallets/provider-braavos/tsconfig.build.json b/wallets/provider-braavos/tsconfig.build.json new file mode 100644 index 0000000000..5297e74971 --- /dev/null +++ b/wallets/provider-braavos/tsconfig.build.json @@ -0,0 +1,10 @@ +{ + // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs + "extends": "../../tsconfig.libnext.json", + "include": ["src", "types", "../../global-wallets-env.d.ts"], + "compilerOptions": { + "outDir": "dist", + "rootDir": "./src", + "lib": ["dom", "esnext"] + } +} diff --git a/wallets/provider-braavos/tsconfig.json b/wallets/provider-braavos/tsconfig.json new file mode 100644 index 0000000000..a3a0b0f59d --- /dev/null +++ b/wallets/provider-braavos/tsconfig.json @@ -0,0 +1 @@ +{ "extends": "./tsconfig.build.json", "include": ["src", "tests"] } diff --git a/wallets/provider-brave/CHANGELOG.md b/wallets/provider-brave/CHANGELOG.md new file mode 100644 index 0000000000..cd07ca9edf --- /dev/null +++ b/wallets/provider-brave/CHANGELOG.md @@ -0,0 +1,161 @@ +# [0.42.0](https://github.com/rango-exchange/rango-client/compare/provider-brave@0.41.0...provider-brave@0.42.0) (2024-12-30) + + + +# [0.41.0](https://github.com/rango-exchange/rango-client/compare/provider-brave@0.40.0...provider-brave@0.41.0) (2024-11-27) + + +### Features + +* add ton connect provider ([2a2dbb7](https://github.com/rango-exchange/rango-client/commit/2a2dbb79022263f19446ced49d298e04d63f927f)) + + + +# [0.40.0](https://github.com/rango-exchange/rango-client/compare/provider-brave@0.39.0...provider-brave@0.40.0) (2024-11-12) + + + +# [0.39.0](https://github.com/rango-exchange/rango-client/compare/provider-brave@0.38.0...provider-brave@0.39.0) (2024-10-12) + + +### Bug Fixes + +* bump sdk and fix type issues ([d442208](https://github.com/rango-exchange/rango-client/commit/d4422083bf5dd27d5f509ce1db7f9560d05428c8)) +* resolve issues with the sign message method for certain solana providers ([cbe83a3](https://github.com/rango-exchange/rango-client/commit/cbe83a3da8b48560b206fc2a7fa7cf062cdeaa23)) + + +### Performance Improvements + +* lazy load signer packages ([7b88f18](https://github.com/rango-exchange/rango-client/commit/7b88f1834f7b29b4b81ab6c81a07bb88e8ccf55c)) + + + +# [0.38.0](https://github.com/rango-exchange/rango-client/compare/provider-brave@0.37.0...provider-brave@0.38.0) (2024-09-10) + + + +# [0.37.0](https://github.com/rango-exchange/rango-client/compare/provider-brave@0.36.1...provider-brave@0.37.0) (2024-08-11) + + + +## [0.36.1](https://github.com/rango-exchange/rango-client/compare/provider-brave@0.36.0...provider-brave@0.36.1) (2024-07-14) + + + +# [0.36.0](https://github.com/rango-exchange/rango-client/compare/provider-brave@0.34.2...provider-brave@0.36.0) (2024-07-09) + + + +# [0.35.0](https://github.com/rango-exchange/rango-client/compare/provider-brave@0.34.2...provider-brave@0.35.0) (2024-06-01) + + + +## [0.34.2](https://github.com/rango-exchange/rango-client/compare/provider-brave@0.34.1...provider-brave@0.34.2) (2024-05-26) + + + +## [0.34.1](https://github.com/rango-exchange/rango-client/compare/provider-brave@0.34.0...provider-brave@0.34.1) (2024-05-25) + + + +# [0.34.0](https://github.com/rango-exchange/rango-client/compare/provider-brave@0.33.0...provider-brave@0.34.0) (2024-05-14) + + + +# [0.33.0](https://github.com/rango-exchange/rango-client/compare/provider-brave@0.32.0...provider-brave@0.33.0) (2024-04-24) + + + +# [0.32.0](https://github.com/rango-exchange/rango-client/compare/provider-brave@0.31.0...provider-brave@0.32.0) (2024-04-23) + + + +# [0.31.0](https://github.com/rango-exchange/rango-client/compare/provider-brave@0.30.0...provider-brave@0.31.0) (2024-04-09) + + +### Bug Fixes + +* fix the connection problem that happens when another wallet takes over the requested one ([42df212](https://github.com/rango-exchange/rango-client/commit/42df2120aadd84c95045b0bf76844c19305fb59a)) + + + +# [0.30.0](https://github.com/rango-exchange/rango-client/compare/provider-brave@0.29.0...provider-brave@0.30.0) (2024-03-12) + + + +# [0.29.0](https://github.com/rango-exchange/rango-client/compare/provider-brave@0.28.0...provider-brave@0.29.0) (2024-02-20) + + + +# [0.28.0](https://github.com/rango-exchange/rango-client/compare/provider-brave@0.27.0...provider-brave@0.28.0) (2024-02-07) + + + +# [0.27.0](https://github.com/rango-exchange/rango-client/compare/provider-brave@0.26.0...provider-brave@0.27.0) (2024-01-22) + + +### Bug Fixes + +* cleanup wallets' subscriber when setProvider get null ([88d6a42](https://github.com/rango-exchange/rango-client/commit/88d6a423c49b34b3d9ff567e22df36c3b009bb76)) + + + +# [0.26.0](https://github.com/rango-exchange/rango-client/compare/provider-brave@0.24.0...provider-brave@0.26.0) (2023-12-24) + + +### Bug Fixes + +* fix HMR for widget and playground ([8524820](https://github.com/rango-exchange/rango-client/commit/8524820f10cf0b8921f3db0c4f620ff98daa4103)) + + + +# [0.14.0](https://github.com/rango-exchange/rango-client/compare/provider-brave@0.13.0...provider-brave@0.14.0) (2023-08-03) + + + +# [0.13.0](https://github.com/rango-exchange/rango-client/compare/provider-brave@0.12.0...provider-brave@0.13.0) (2023-08-01) + + + +# [0.9.0](https://github.com/rango-exchange/rango-client/compare/provider-brave@0.8.0...provider-brave@0.9.0) (2023-07-31) + + + +# [0.7.0](https://github.com/rango-exchange/rango-client/compare/provider-brave@0.6.0...provider-brave@0.7.0) (2023-07-11) + + + +# [0.6.0](https://github.com/rango-exchange/rango-client/compare/provider-brave@0.5.0...provider-brave@0.6.0) (2023-07-11) + + +### Reverts + +* Revert "support for rango-types cjs format" ([ed4e050](https://github.com/rango-exchange/rango-client/commit/ed4e050bfc0dcde7aeffa6b0d73b02080a5721eb)) + + + +# [0.5.0](https://github.com/rango-exchange/rango-client/compare/provider-brave@0.4.0...provider-brave@0.5.0) (2023-05-31) + + + +# [0.4.0](https://github.com/rango-exchange/rango-client/compare/provider-brave@0.3.0...provider-brave@0.4.0) (2023-05-31) + + + +# [0.3.0](https://github.com/rango-exchange/rango-client/compare/provider-brave@0.2.0...provider-brave@0.3.0) (2023-05-30) + + + +# [0.2.0](https://github.com/rango-exchange/rango-client/compare/provider-brave@0.1.15...provider-brave@0.2.0) (2023-05-30) + + + +## [0.1.14](https://github.com/rango-exchange/rango-client/compare/provider-brave@0.1.13...provider-brave@0.1.14) (2023-05-15) + + +### Bug Fixes + +* update rango-types and fix notification bugs ([993f185](https://github.com/rango-exchange/rango-client/commit/993f185e0b8c5e5e15a2c65ba2d85d1f9c8daa90)) + + + diff --git a/wallets/provider-brave/package.json b/wallets/provider-brave/package.json index 27e5c0e7ab..ee204ac942 100644 --- a/wallets/provider-brave/package.json +++ b/wallets/provider-brave/package.json @@ -1,50 +1,32 @@ { "name": "@rango-dev/provider-brave", - "version": "0.1.12", + "version": "0.41.1-next.6", "license": "MIT", - "module": "dist/provider-brave.esm.js", - "main": "dist/index.js", + "type": "module", + "source": "./src/index.ts", + "main": "./dist/index.js", + "exports": { + ".": "./dist/index.js" + }, "typings": "dist/index.d.ts", "files": [ "dist", "src" ], "scripts": { - "start": "tsdx watch", - "build": "tsdx build --tsconfig ./tsconfig.json", - "test": "tsdx test --passWithNoTests", - "lint": "tsdx lint", - "size": "size-limit", - "analyze": "size-limit --why" - }, - "husky": { - "hooks": { - "pre-commit": "tsdx lint" - } + "build": "node ../../scripts/build/command.mjs --path wallets/provider-brave", + "ts-check": "tsc --declaration --emitDeclarationOnly -p ./tsconfig.json", + "clean": "rimraf dist", + "format": "prettier --write '{.,src}/**/*.{ts,tsx}'", + "lint": "eslint \"**/*.{ts,tsx}\" --ignore-path ../../.eslintignore" }, - "prettier": { - "printWidth": 80, - "semi": true, - "singleQuote": true, - "trailingComma": "es5" - }, - "size-limit": [ - { - "path": "dist/provider-brave.cjs.production.min.js", - "limit": "10 KB" - }, - { - "path": "dist/provider-brave.esm.js", - "limit": "10 KB" - } - ], "dependencies": { - "@rango-dev/signer-evm": "^0.1.11", - "@rango-dev/signer-solana": "^0.1.11", - "@rango-dev/wallets-shared": "^0.1.11", - "rango-types": "^0.1.28" + "@rango-dev/signer-evm": "^0.32.0", + "@rango-dev/signer-solana": "^0.35.1-next.0", + "@rango-dev/wallets-shared": "^0.40.1-next.6", + "rango-types": "^0.1.74" }, "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/wallets/provider-brave/src/helpers.ts b/wallets/provider-brave/src/helpers.ts index 87bf702195..827bbc1918 100644 --- a/wallets/provider-brave/src/helpers.ts +++ b/wallets/provider-brave/src/helpers.ts @@ -1,12 +1,12 @@ -import { Network } from '@rango-dev/wallets-shared'; +import { Networks } from '@rango-dev/wallets-shared'; export function brave() { const { ethereum, braveSolana } = window; const instances = new Map(); - if (ethereum?.isBraveWallet) instances.set(Network.ETHEREUM, ethereum); - if (!!braveSolana) instances.set(Network.SOLANA, braveSolana); + if (ethereum?.isBraveWallet) instances.set(Networks.ETHEREUM, ethereum); + if (braveSolana) instances.set(Networks.SOLANA, braveSolana); if (instances.size === 0) return null; diff --git a/wallets/provider-brave/src/index.ts b/wallets/provider-brave/src/index.ts index eec288e822..3bfaa7ab30 100644 --- a/wallets/provider-brave/src/index.ts +++ b/wallets/provider-brave/src/index.ts @@ -1,41 +1,46 @@ -import { - Network, - WalletType, - canSwitchNetworkToEvm, - chooseInstance, - getEvmAccounts, - switchNetworkForEvm, +import type { + CanEagerConnect, CanSwitchNetwork, Connect, ProviderConnectResult, Subscribe, SwitchNetwork, WalletInfo, +} from '@rango-dev/wallets-shared'; +import type { BlockchainMeta, SignerFactory } from 'rango-types'; + +import { + canEagerlyConnectToEvm, + canSwitchNetworkToEvm, + chooseInstance, + getEvmAccounts, getSolanaAccounts, + Networks, + switchNetworkForEvm, + WalletTypes, } from '@rango-dev/wallets-shared'; -import { brave as brave_instances } from './helpers'; -import signer from './signer'; import { - SignerFactory, + evmBlockchains, isEvmBlockchain, isSolanaBlockchain, - BlockchainMeta, - evmBlockchains, solanaBlockchain, } from 'rango-types'; -const WALLET = WalletType.BRAVE; +import { brave as brave_instances } from './helpers.js'; +import signer from './signer.js'; + +const WALLET = WalletTypes.BRAVE; export const config = { type: WALLET, - defaultNetwork: Network.ETHEREUM, + defaultNetwork: Networks.ETHEREUM, }; export const getInstance = brave_instances; export const connect: Connect = async ({ instance, meta }) => { - const evm_instance = chooseInstance(instance, meta, Network.ETHEREUM); - const sol_instance = chooseInstance(instance, meta, Network.SOLANA); + const evm_instance = chooseInstance(instance, meta, Networks.ETHEREUM); + const sol_instance = chooseInstance(instance, meta, Networks.SOLANA); const results: ProviderConnectResult[] = []; const emptyWalletErrorCode = -32603; const emptyWalletCustomErrorMessage = 'Please create or import a wallet'; @@ -50,7 +55,9 @@ export const connect: Connect = async ({ instance, meta }) => { const err = error as { code: number }; if (err.code === emptyWalletErrorCode) { numberOfEmptyWallets += 1; - } else throw error; + } else { + throw error; + } } } @@ -66,12 +73,15 @@ export const connect: Connect = async ({ instance, meta }) => { const err = error as { code: number }; if (err.code === emptyWalletErrorCode) { numberOfEmptyWallets += 1; - } else throw error; + } else { + throw error; + } } } - if (numberOfEmptyWallets === instance.size) + if (numberOfEmptyWallets === instance.size) { throw new Error(emptyWalletCustomErrorMessage); + } return results; }; @@ -83,38 +93,62 @@ export const subscribe: Subscribe = ({ state, updateChainId, }) => { - const evm_instance = chooseInstance(instance, meta, Network.ETHEREUM); - const sol_instance = chooseInstance(instance, meta, Network.SOLANA); + const evm_instance = chooseInstance(instance, meta, Networks.ETHEREUM); + const sol_instance = chooseInstance(instance, meta, Networks.SOLANA); - evm_instance?.on('accountsChanged', (addresses: string[]) => { + const handleEvmAccountsChanged = (addresses: string[]) => { const eth_chainId = meta .filter(isEvmBlockchain) - .find((blockchain) => blockchain.name === Network.ETHEREUM)?.chainId; + .find((blockchain) => blockchain.name === Networks.ETHEREUM)?.chainId; if (state.connected) { - if (state.network != Network.ETHEREUM && eth_chainId) + if (state.network != Networks.ETHEREUM && eth_chainId) { updateChainId(eth_chainId); + } updateAccounts(addresses); } - }); + }; - evm_instance?.on('chainChanged', (chainId: string) => { + const handleEvmChainChanged = (chainId: string) => { updateChainId(chainId); - }); + }; - sol_instance?.on('accountChanged', async () => { - if (state.network != Network.SOLANA) + const handleSolanaAccountsChanged = async () => { + if (state.network != Networks.SOLANA) { updateChainId(meta.filter(isSolanaBlockchain)[0].chainId); + } const response = await sol_instance.connect(); const account: string = response.publicKey.toString(); updateAccounts([account]); - }); + }; + + evm_instance?.on?.('accountsChanged', handleEvmAccountsChanged); + + evm_instance?.on?.('chainChanged', handleEvmChainChanged); + + sol_instance?.on?.('accountChanged', handleSolanaAccountsChanged); + + return () => { + evm_instance?.off?.('accountsChanged', handleEvmAccountsChanged); + + evm_instance?.off?.('chainChanged', handleEvmChainChanged); + + sol_instance?.off?.('accountChanged', handleSolanaAccountsChanged); + }; }; export const switchNetwork: SwitchNetwork = switchNetworkForEvm; export const canSwitchNetworkTo: CanSwitchNetwork = canSwitchNetworkToEvm; -export const getSigners: (provider: any) => SignerFactory = signer; +export const getSigners: (provider: any) => Promise = signer; + +export const canEagerConnect: CanEagerConnect = async ({ instance, meta }) => { + const evm_instance = chooseInstance(instance, meta, Networks.ETHEREUM); + if (evm_instance) { + return canEagerlyConnectToEvm({ instance: evm_instance, meta }); + } + return Promise.resolve(false); +}; export const getWalletInfo: (allBlockChains: BlockchainMeta[]) => WalletInfo = ( allBlockChains @@ -123,7 +157,7 @@ export const getWalletInfo: (allBlockChains: BlockchainMeta[]) => WalletInfo = ( const solana = solanaBlockchain(allBlockChains); return { name: 'Brave', - img: 'https://raw.githubusercontent.com/rango-exchange/rango-types/main/assets/icons/wallets/brave.png', + img: 'https://raw.githubusercontent.com/rango-exchange/assets/main/wallets/brave/icon.svg', installLink: { DEFAULT: 'https://brave.com/wallet/', }, diff --git a/wallets/provider-brave/src/signer.ts b/wallets/provider-brave/src/signer.ts index 0585e651d9..6cd7760393 100644 --- a/wallets/provider-brave/src/signer.ts +++ b/wallets/provider-brave/src/signer.ts @@ -1,13 +1,18 @@ -import { DefaultEvmSigner } from '@rango-dev/signer-evm'; -import { DefaultSolanaSigner } from '@rango-dev/signer-solana'; -import { Network, getNetworkInstance } from '@rango-dev/wallets-shared'; -import { SignerFactory, TransactionType as TxType } from 'rango-types'; +import type { SignerFactory } from 'rango-types'; -export default function getSigners(provider: any): SignerFactory { - const ethProvider = getNetworkInstance(provider, Network.ETHEREUM); - const solProvider = getNetworkInstance(provider, Network.SOLANA); - const signers = new SignerFactory(); +import { getNetworkInstance, Networks } from '@rango-dev/wallets-shared'; +import { DefaultSignerFactory, TransactionType as TxType } from 'rango-types'; + +import { CustomSolanaSigner } from './solana-signer.js'; + +export default async function getSigners( + provider: any +): Promise { + const ethProvider = getNetworkInstance(provider, Networks.ETHEREUM); + const solProvider = getNetworkInstance(provider, Networks.SOLANA); + const signers = new DefaultSignerFactory(); + const { DefaultEvmSigner } = await import('@rango-dev/signer-evm'); signers.registerSigner(TxType.EVM, new DefaultEvmSigner(ethProvider)); - signers.registerSigner(TxType.SOLANA, new DefaultSolanaSigner(solProvider)); + signers.registerSigner(TxType.SOLANA, new CustomSolanaSigner(solProvider)); return signers; } diff --git a/wallets/provider-brave/src/solana-signer.ts b/wallets/provider-brave/src/solana-signer.ts new file mode 100644 index 0000000000..6eb1c9ee0e --- /dev/null +++ b/wallets/provider-brave/src/solana-signer.ts @@ -0,0 +1,26 @@ +import { DefaultSolanaSigner } from '@rango-dev/signer-solana'; +import { SignerError, SignerErrorCode } from 'rango-types'; + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +type SolanaExternalProvider = any; + +export class CustomSolanaSigner extends DefaultSolanaSigner { + constructor(provider: SolanaExternalProvider) { + super(provider); + } + + async signMessage(msg: string): Promise { + try { + const encodedMessage = new TextEncoder().encode(msg); + const { signature } = await this.provider.request({ + method: 'signMessage', + params: { + message: encodedMessage, + }, + }); + return signature; + } catch (error) { + throw new SignerError(SignerErrorCode.SIGN_TX_ERROR, undefined, error); + } + } +} diff --git a/wallets/provider-brave/tsconfig.build.json b/wallets/provider-brave/tsconfig.build.json new file mode 100644 index 0000000000..d9181ce0cd --- /dev/null +++ b/wallets/provider-brave/tsconfig.build.json @@ -0,0 +1,11 @@ +{ + // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs + "extends": "../../tsconfig.libnext.json", + "include": ["src", "types", "../../global-wallets-env.d.ts"], + "compilerOptions": { + "outDir": "dist", + "rootDir": "./src", + "lib": ["dom", "esnext"] + // match output dir to input dir. e.g. dist/index instead of dist/src/index + } +} diff --git a/wallets/provider-brave/tsconfig.json b/wallets/provider-brave/tsconfig.json index e72b58bc0e..a3a0b0f59d 100644 --- a/wallets/provider-brave/tsconfig.json +++ b/wallets/provider-brave/tsconfig.json @@ -1,36 +1 @@ -{ - // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs - "include": ["src", "types", "../../global-wallets-env.d.ts"], - "compilerOptions": { - "module": "esnext", - "lib": ["dom", "esnext"], - "importHelpers": true, - // output .d.ts declaration files for consumers - "declaration": true, - // output .js.map sourcemap files for consumers - "sourceMap": true, - // match output dir to input dir. e.g. dist/index instead of dist/src/index - "rootDir": "./src", - // stricter type-checking for stronger correctness. Recommended by TS - "strict": true, - // linter checks for common issues - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true, - // noUnused* overlap with @typescript-eslint/no-unused-vars, can disable if duplicative - "noUnusedLocals": true, - "noUnusedParameters": true, - // use Node's module resolution algorithm, instead of the legacy TS one - "moduleResolution": "node", - // transpile JSX to React.createElement - "jsx": "react", - // interop between ESM and CJS modules. Recommended by TS - "esModuleInterop": true, - // significant perf increase by skipping checking .d.ts files, particularly those in node_modules. Recommended by TS - "skipLibCheck": true, - // error out if import and file system have a casing mismatch. Recommended by TS - "forceConsistentCasingInFileNames": true, - // `tsdx build` ignores this option, but it is commonly used when type-checking separately with `tsc` - "noEmit": true, - - } -} +{ "extends": "./tsconfig.build.json", "include": ["src", "tests"] } diff --git a/wallets/provider-clover/CHANGELOG.md b/wallets/provider-clover/CHANGELOG.md new file mode 100644 index 0000000000..4200d1592b --- /dev/null +++ b/wallets/provider-clover/CHANGELOG.md @@ -0,0 +1,156 @@ +# [0.42.0](https://github.com/rango-exchange/rango-client/compare/provider-clover@0.41.0...provider-clover@0.42.0) (2024-12-30) + + + +# [0.41.0](https://github.com/rango-exchange/rango-client/compare/provider-clover@0.40.0...provider-clover@0.41.0) (2024-11-27) + + +### Features + +* add ton connect provider ([2a2dbb7](https://github.com/rango-exchange/rango-client/commit/2a2dbb79022263f19446ced49d298e04d63f927f)) + + + +# [0.40.0](https://github.com/rango-exchange/rango-client/compare/provider-clover@0.39.0...provider-clover@0.40.0) (2024-11-12) + + + +# [0.39.0](https://github.com/rango-exchange/rango-client/compare/provider-clover@0.38.0...provider-clover@0.39.0) (2024-10-12) + + +### Bug Fixes + +* bump sdk and fix type issues ([d442208](https://github.com/rango-exchange/rango-client/commit/d4422083bf5dd27d5f509ce1db7f9560d05428c8)) +* resolve issues with the sign message method for certain solana providers ([cbe83a3](https://github.com/rango-exchange/rango-client/commit/cbe83a3da8b48560b206fc2a7fa7cf062cdeaa23)) + + +### Performance Improvements + +* lazy load signer packages ([7b88f18](https://github.com/rango-exchange/rango-client/commit/7b88f1834f7b29b4b81ab6c81a07bb88e8ccf55c)) + + + +# [0.38.0](https://github.com/rango-exchange/rango-client/compare/provider-clover@0.37.0...provider-clover@0.38.0) (2024-09-10) + + + +# [0.37.0](https://github.com/rango-exchange/rango-client/compare/provider-clover@0.36.1...provider-clover@0.37.0) (2024-08-11) + + + +## [0.36.1](https://github.com/rango-exchange/rango-client/compare/provider-clover@0.36.0...provider-clover@0.36.1) (2024-07-14) + + + +# [0.36.0](https://github.com/rango-exchange/rango-client/compare/provider-clover@0.34.2...provider-clover@0.36.0) (2024-07-09) + + + +# [0.35.0](https://github.com/rango-exchange/rango-client/compare/provider-clover@0.34.2...provider-clover@0.35.0) (2024-06-01) + + + +## [0.34.2](https://github.com/rango-exchange/rango-client/compare/provider-clover@0.34.1...provider-clover@0.34.2) (2024-05-26) + + + +## [0.34.1](https://github.com/rango-exchange/rango-client/compare/provider-clover@0.34.0...provider-clover@0.34.1) (2024-05-25) + + + +# [0.34.0](https://github.com/rango-exchange/rango-client/compare/provider-clover@0.33.0...provider-clover@0.34.0) (2024-05-14) + + + +# [0.33.0](https://github.com/rango-exchange/rango-client/compare/provider-clover@0.32.0...provider-clover@0.33.0) (2024-04-24) + + + +# [0.32.0](https://github.com/rango-exchange/rango-client/compare/provider-clover@0.31.0...provider-clover@0.32.0) (2024-04-23) + + + +# [0.31.0](https://github.com/rango-exchange/rango-client/compare/provider-clover@0.30.0...provider-clover@0.31.0) (2024-04-09) + + +### Bug Fixes + +* fix the connection problem that happens when another wallet takes over the requested one ([42df212](https://github.com/rango-exchange/rango-client/commit/42df2120aadd84c95045b0bf76844c19305fb59a)) + + + +# [0.30.0](https://github.com/rango-exchange/rango-client/compare/provider-clover@0.29.0...provider-clover@0.30.0) (2024-03-12) + + + +# [0.29.0](https://github.com/rango-exchange/rango-client/compare/provider-clover@0.28.0...provider-clover@0.29.0) (2024-02-20) + + + +# [0.28.0](https://github.com/rango-exchange/rango-client/compare/provider-clover@0.27.0...provider-clover@0.28.0) (2024-02-07) + + + +# [0.27.0](https://github.com/rango-exchange/rango-client/compare/provider-clover@0.26.0...provider-clover@0.27.0) (2024-01-22) + + + +# [0.26.0](https://github.com/rango-exchange/rango-client/compare/provider-clover@0.24.0...provider-clover@0.26.0) (2023-12-24) + + +### Bug Fixes + +* fix HMR for widget and playground ([8524820](https://github.com/rango-exchange/rango-client/commit/8524820f10cf0b8921f3db0c4f620ff98daa4103)) + + + +# [0.14.0](https://github.com/rango-exchange/rango-client/compare/provider-clover@0.13.0...provider-clover@0.14.0) (2023-08-03) + + + +# [0.13.0](https://github.com/rango-exchange/rango-client/compare/provider-clover@0.12.0...provider-clover@0.13.0) (2023-08-01) + + + +# [0.9.0](https://github.com/rango-exchange/rango-client/compare/provider-clover@0.8.0...provider-clover@0.9.0) (2023-07-31) + + + +# [0.7.0](https://github.com/rango-exchange/rango-client/compare/provider-clover@0.6.0...provider-clover@0.7.0) (2023-07-11) + + + +# [0.6.0](https://github.com/rango-exchange/rango-client/compare/provider-clover@0.5.0...provider-clover@0.6.0) (2023-07-11) + + +### Reverts + +* Revert "support for rango-types cjs format" ([ed4e050](https://github.com/rango-exchange/rango-client/commit/ed4e050bfc0dcde7aeffa6b0d73b02080a5721eb)) + + + +# [0.5.0](https://github.com/rango-exchange/rango-client/compare/provider-clover@0.4.0...provider-clover@0.5.0) (2023-05-31) + + + +# [0.4.0](https://github.com/rango-exchange/rango-client/compare/provider-clover@0.3.0...provider-clover@0.4.0) (2023-05-31) + + + +# [0.3.0](https://github.com/rango-exchange/rango-client/compare/provider-clover@0.2.0...provider-clover@0.3.0) (2023-05-30) + + + +# [0.2.0](https://github.com/rango-exchange/rango-client/compare/provider-clover@0.1.15...provider-clover@0.2.0) (2023-05-30) + + + +## [0.1.14](https://github.com/rango-exchange/rango-client/compare/provider-clover@0.1.13...provider-clover@0.1.14) (2023-05-15) + + +### Bug Fixes + +* update rango-types and fix notification bugs ([993f185](https://github.com/rango-exchange/rango-client/commit/993f185e0b8c5e5e15a2c65ba2d85d1f9c8daa90)) + + + diff --git a/wallets/provider-clover/package.json b/wallets/provider-clover/package.json index 9fbeb477ce..bc280b628b 100644 --- a/wallets/provider-clover/package.json +++ b/wallets/provider-clover/package.json @@ -1,50 +1,33 @@ { "name": "@rango-dev/provider-clover", - "version": "0.1.12", + "version": "0.41.1-next.6", "license": "MIT", - "module": "dist/provider-clover.esm.js", - "main": "dist/index.js", + "type": "module", + "source": "./src/index.ts", + "main": "./dist/index.js", + "exports": { + ".": "./dist/index.js" + }, "typings": "dist/index.d.ts", "files": [ "dist", "src" ], "scripts": { - "start": "tsdx watch", - "build": "tsdx build --tsconfig ./tsconfig.json", - "test": "tsdx test --passWithNoTests", - "lint": "tsdx lint", - "size": "size-limit", - "analyze": "size-limit --why" - }, - "husky": { - "hooks": { - "pre-commit": "tsdx lint" - } + "build": "node ../../scripts/build/command.mjs --path wallets/provider-clover", + "ts-check": "tsc --declaration --emitDeclarationOnly -p ./tsconfig.json", + "clean": "rimraf dist", + "format": "prettier --write '{.,src}/**/*.{ts,tsx}'", + "lint": "eslint \"**/*.{ts,tsx}\" --ignore-path ../../.eslintignore" }, - "prettier": { - "printWidth": 80, - "semi": true, - "singleQuote": true, - "trailingComma": "es5" - }, - "size-limit": [ - { - "path": "dist/provider-clover.cjs.production.min.js", - "limit": "10 KB" - }, - { - "path": "dist/provider-clover.esm.js", - "limit": "10 KB" - } - ], "dependencies": { - "@rango-dev/signer-evm": "^0.1.11", - "@rango-dev/signer-solana": "^0.1.11", - "@rango-dev/wallets-shared": "^0.1.11", - "rango-types": "^0.1.28" + "@rango-dev/signer-evm": "^0.32.0", + "@rango-dev/signer-solana": "^0.35.1-next.0", + "@rango-dev/wallets-shared": "^0.40.1-next.6", + "bs58": "^5.0.0", + "rango-types": "^0.1.74" }, "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/wallets/provider-clover/src/helpers.ts b/wallets/provider-clover/src/helpers.ts index 2802fdb254..3213bb52e6 100644 --- a/wallets/provider-clover/src/helpers.ts +++ b/wallets/provider-clover/src/helpers.ts @@ -1,13 +1,21 @@ -import { Network, ProviderConnectResult } from '@rango-dev/wallets-shared'; +import type { Network, ProviderConnectResult } from '@rango-dev/wallets-shared'; + +import { Networks } from '@rango-dev/wallets-shared'; export function clover() { const { clover, clover_solana } = window; - if (!clover) return null; + if (!clover) { + return null; + } const instances = new Map(); - if (clover) instances.set(Network.ETHEREUM, clover); - if (clover_solana) instances.set(Network.SOLANA, clover_solana); + if (clover) { + instances.set(Networks.ETHEREUM, clover); + } + if (clover_solana) { + instances.set(Networks.SOLANA, clover_solana); + } return instances; } @@ -17,15 +25,15 @@ type Provider = Map; export async function getNonEvmAccounts( instances: Provider ): Promise { - const solanaInstance = instances.get(Network.SOLANA); + const solanaInstance = instances.get(Networks.SOLANA); const results: ProviderConnectResult[] = []; - if (!!solanaInstance) { + if (solanaInstance) { const solanaAccounts = await solanaInstance.getAccount(); results.push({ accounts: [solanaAccounts], - chainId: Network.SOLANA, + chainId: Networks.SOLANA, }); } diff --git a/wallets/provider-clover/src/index.ts b/wallets/provider-clover/src/index.ts index 43eb76492a..0a559b8acd 100644 --- a/wallets/provider-clover/src/index.ts +++ b/wallets/provider-clover/src/index.ts @@ -1,37 +1,38 @@ -import { - Network, - WalletType, +import type { + CanEagerConnect, CanSwitchNetwork, Connect, ProviderConnectResult, Subscribe, SwitchNetwork, + WalletInfo, +} from '@rango-dev/wallets-shared'; +import type { BlockchainMeta, SignerFactory } from 'rango-types'; + +import { + canEagerlyConnectToEvm, canSwitchNetworkToEvm, chooseInstance, getEvmAccounts, + Networks, switchNetworkForEvm, - WalletInfo, + WalletTypes, } from '@rango-dev/wallets-shared'; -import { getNonEvmAccounts, clover as clover_instance } from './helpers'; -import signer from './signer'; -import { - SignerFactory, - isEvmBlockchain, - evmBlockchains, - BlockchainMeta, - solanaBlockchain, -} from 'rango-types'; +import { evmBlockchains, isEvmBlockchain, solanaBlockchain } from 'rango-types'; + +import { clover as clover_instance, getNonEvmAccounts } from './helpers.js'; +import signer from './signer.js'; -const WALLET = WalletType.CLOVER; +const WALLET = WalletTypes.CLOVER; export const config = { type: WALLET, - defaultNetwork: Network.ETHEREUM, + defaultNetwork: Networks.ETHEREUM, }; export const getInstance = clover_instance; export const connect: Connect = async ({ instance, meta }) => { - const ethInstance = chooseInstance(instance, meta, Network.ETHEREUM); + const ethInstance = chooseInstance(instance, meta, Networks.ETHEREUM); let results: ProviderConnectResult[] = []; @@ -55,19 +56,19 @@ export const subscribe: Subscribe = ({ state, meta, }) => { - const ethInstance = chooseInstance(instance, meta, Network.ETHEREUM); - const solanaInstance = chooseInstance(instance, meta, Network.SOLANA); - ethInstance?.on('accountsChanged', async (addresses: string[]) => { + const ethInstance = chooseInstance(instance, meta, Networks.ETHEREUM); + const solanaInstance = chooseInstance(instance, meta, Networks.SOLANA); + ethInstance?.on?.('accountsChanged', async (addresses: string[]) => { if (state.connected) { - if (!!ethInstance) { + if (ethInstance) { const eth_chainId = meta .filter(isEvmBlockchain) - .find((blockchain) => blockchain.name === Network.ETHEREUM)?.chainId; + .find((blockchain) => blockchain.name === Networks.ETHEREUM)?.chainId; updateAccounts(addresses, eth_chainId); } - if (!!solanaInstance) { + if (solanaInstance) { const solanaAccount = await solanaInstance.getAccount(); - updateAccounts([solanaAccount], Network.SOLANA); + updateAccounts([solanaAccount], Networks.SOLANA); } } }); @@ -87,7 +88,15 @@ export const switchNetwork: SwitchNetwork = async (options) => { export const canSwitchNetworkTo: CanSwitchNetwork = canSwitchNetworkToEvm; -export const getSigners: (provider: any) => SignerFactory = signer; +export const getSigners: (provider: any) => Promise = signer; + +export const canEagerConnect: CanEagerConnect = async ({ instance, meta }) => { + const evm_instance = chooseInstance(instance, meta, Networks.ETHEREUM); + if (evm_instance) { + return canEagerlyConnectToEvm({ instance: evm_instance, meta }); + } + return Promise.resolve(false); +}; export const getWalletInfo: (allBlockChains: BlockchainMeta[]) => WalletInfo = ( allBlockChains @@ -96,7 +105,7 @@ export const getWalletInfo: (allBlockChains: BlockchainMeta[]) => WalletInfo = ( const solana = solanaBlockchain(allBlockChains); return { name: 'Clover', - img: 'https://raw.githubusercontent.com/rango-exchange/rango-types/main/assets/icons/wallets/clover.jpeg', + img: 'https://raw.githubusercontent.com/rango-exchange/assets/main/wallets/clover/icon.svg', installLink: { CHROME: 'https://chrome.google.com/webstore/detail/clover-wallet/nhnkbkgjikgcigadomkphalanndcapjk', diff --git a/wallets/provider-clover/src/signer.ts b/wallets/provider-clover/src/signer.ts index 0585e651d9..6cd7760393 100644 --- a/wallets/provider-clover/src/signer.ts +++ b/wallets/provider-clover/src/signer.ts @@ -1,13 +1,18 @@ -import { DefaultEvmSigner } from '@rango-dev/signer-evm'; -import { DefaultSolanaSigner } from '@rango-dev/signer-solana'; -import { Network, getNetworkInstance } from '@rango-dev/wallets-shared'; -import { SignerFactory, TransactionType as TxType } from 'rango-types'; +import type { SignerFactory } from 'rango-types'; -export default function getSigners(provider: any): SignerFactory { - const ethProvider = getNetworkInstance(provider, Network.ETHEREUM); - const solProvider = getNetworkInstance(provider, Network.SOLANA); - const signers = new SignerFactory(); +import { getNetworkInstance, Networks } from '@rango-dev/wallets-shared'; +import { DefaultSignerFactory, TransactionType as TxType } from 'rango-types'; + +import { CustomSolanaSigner } from './solana-signer.js'; + +export default async function getSigners( + provider: any +): Promise { + const ethProvider = getNetworkInstance(provider, Networks.ETHEREUM); + const solProvider = getNetworkInstance(provider, Networks.SOLANA); + const signers = new DefaultSignerFactory(); + const { DefaultEvmSigner } = await import('@rango-dev/signer-evm'); signers.registerSigner(TxType.EVM, new DefaultEvmSigner(ethProvider)); - signers.registerSigner(TxType.SOLANA, new DefaultSolanaSigner(solProvider)); + signers.registerSigner(TxType.SOLANA, new CustomSolanaSigner(solProvider)); return signers; } diff --git a/wallets/provider-clover/src/solana-signer.ts b/wallets/provider-clover/src/solana-signer.ts new file mode 100644 index 0000000000..2713bc04ec --- /dev/null +++ b/wallets/provider-clover/src/solana-signer.ts @@ -0,0 +1,17 @@ +import { DefaultSolanaSigner } from '@rango-dev/signer-solana'; +import base58 from 'bs58'; + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +type SolanaExternalProvider = any; + +export class CustomSolanaSigner extends DefaultSolanaSigner { + constructor(provider: SolanaExternalProvider) { + super(provider); + } + + async signMessage(msg: string): Promise { + const encodedMessage = new TextEncoder().encode(msg); + const { signature } = await this.provider.signMessage(encodedMessage); + return base58.encode(signature); + } +} diff --git a/wallets/provider-clover/tsconfig.build.json b/wallets/provider-clover/tsconfig.build.json new file mode 100644 index 0000000000..d9181ce0cd --- /dev/null +++ b/wallets/provider-clover/tsconfig.build.json @@ -0,0 +1,11 @@ +{ + // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs + "extends": "../../tsconfig.libnext.json", + "include": ["src", "types", "../../global-wallets-env.d.ts"], + "compilerOptions": { + "outDir": "dist", + "rootDir": "./src", + "lib": ["dom", "esnext"] + // match output dir to input dir. e.g. dist/index instead of dist/src/index + } +} diff --git a/wallets/provider-clover/tsconfig.json b/wallets/provider-clover/tsconfig.json index 365489616a..a3a0b0f59d 100644 --- a/wallets/provider-clover/tsconfig.json +++ b/wallets/provider-clover/tsconfig.json @@ -1,35 +1 @@ -{ - // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs - "include": ["src", "types", "../../global-wallets-env.d.ts"], - "compilerOptions": { - "module": "esnext", - "lib": ["dom", "esnext"], - "importHelpers": true, - // output .d.ts declaration files for consumers - "declaration": true, - // output .js.map sourcemap files for consumers - "sourceMap": true, - // match output dir to input dir. e.g. dist/index instead of dist/src/index - "rootDir": "./src", - // stricter type-checking for stronger correctness. Recommended by TS - "strict": true, - // linter checks for common issues - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true, - // noUnused* overlap with @typescript-eslint/no-unused-vars, can disable if duplicative - "noUnusedLocals": true, - "noUnusedParameters": true, - // use Node's module resolution algorithm, instead of the legacy TS one - "moduleResolution": "node", - // transpile JSX to React.createElement - "jsx": "react", - // interop between ESM and CJS modules. Recommended by TS - "esModuleInterop": true, - // significant perf increase by skipping checking .d.ts files, particularly those in node_modules. Recommended by TS - "skipLibCheck": true, - // error out if import and file system have a casing mismatch. Recommended by TS - "forceConsistentCasingInFileNames": true, - // `tsdx build` ignores this option, but it is commonly used when type-checking separately with `tsc` - "noEmit": true, - } -} +{ "extends": "./tsconfig.build.json", "include": ["src", "tests"] } diff --git a/wallets/provider-coin98/CHANGELOG.md b/wallets/provider-coin98/CHANGELOG.md new file mode 100644 index 0000000000..dd8bb7e67d --- /dev/null +++ b/wallets/provider-coin98/CHANGELOG.md @@ -0,0 +1,166 @@ +# [0.42.0](https://github.com/rango-exchange/rango-client/compare/provider-coin98@0.41.0...provider-coin98@0.42.0) (2024-12-30) + + + +# [0.41.0](https://github.com/rango-exchange/rango-client/compare/provider-coin98@0.40.0...provider-coin98@0.41.0) (2024-11-27) + + +### Features + +* add ton connect provider ([2a2dbb7](https://github.com/rango-exchange/rango-client/commit/2a2dbb79022263f19446ced49d298e04d63f927f)) + + + +# [0.40.0](https://github.com/rango-exchange/rango-client/compare/provider-coin98@0.39.0...provider-coin98@0.40.0) (2024-11-12) + + + +# [0.39.0](https://github.com/rango-exchange/rango-client/compare/provider-coin98@0.38.0...provider-coin98@0.39.0) (2024-10-12) + + +### Bug Fixes + +* bump sdk and fix type issues ([d442208](https://github.com/rango-exchange/rango-client/commit/d4422083bf5dd27d5f509ce1db7f9560d05428c8)) + + +### Performance Improvements + +* enable code splitting in build process ([fe5a41e](https://github.com/rango-exchange/rango-client/commit/fe5a41e0e297298de11cd74ca5825544742aa03a)) +* lazy load signer packages ([7b88f18](https://github.com/rango-exchange/rango-client/commit/7b88f1834f7b29b4b81ab6c81a07bb88e8ccf55c)) + + + +# [0.38.0](https://github.com/rango-exchange/rango-client/compare/provider-coin98@0.37.0...provider-coin98@0.38.0) (2024-09-10) + + + +# [0.37.0](https://github.com/rango-exchange/rango-client/compare/provider-coin98@0.36.1...provider-coin98@0.37.0) (2024-08-11) + + +### Features + +* implement sign message method for providers with a custom signer ([cf9515f](https://github.com/rango-exchange/rango-client/commit/cf9515feb5d3754aac9c228fe83315daf1350c85)) + + + +## [0.36.1](https://github.com/rango-exchange/rango-client/compare/provider-coin98@0.36.0...provider-coin98@0.36.1) (2024-07-14) + + + +# [0.36.0](https://github.com/rango-exchange/rango-client/compare/provider-coin98@0.34.2...provider-coin98@0.36.0) (2024-07-09) + + + +# [0.35.0](https://github.com/rango-exchange/rango-client/compare/provider-coin98@0.34.2...provider-coin98@0.35.0) (2024-06-01) + + + +## [0.34.2](https://github.com/rango-exchange/rango-client/compare/provider-coin98@0.34.1...provider-coin98@0.34.2) (2024-05-26) + + + +## [0.34.1](https://github.com/rango-exchange/rango-client/compare/provider-coin98@0.34.0...provider-coin98@0.34.1) (2024-05-25) + + + +# [0.34.0](https://github.com/rango-exchange/rango-client/compare/provider-coin98@0.33.0...provider-coin98@0.34.0) (2024-05-14) + + + +# [0.33.0](https://github.com/rango-exchange/rango-client/compare/provider-coin98@0.32.0...provider-coin98@0.33.0) (2024-04-24) + + + +# [0.32.0](https://github.com/rango-exchange/rango-client/compare/provider-coin98@0.31.0...provider-coin98@0.32.0) (2024-04-23) + + + +# [0.31.0](https://github.com/rango-exchange/rango-client/compare/provider-coin98@0.30.0...provider-coin98@0.31.0) (2024-04-09) + + +### Bug Fixes + +* fix the connection problem that happens when another wallet takes over the requested one ([42df212](https://github.com/rango-exchange/rango-client/commit/42df2120aadd84c95045b0bf76844c19305fb59a)) + + + +# [0.30.0](https://github.com/rango-exchange/rango-client/compare/provider-coin98@0.29.0...provider-coin98@0.30.0) (2024-03-12) + + + +# [0.29.0](https://github.com/rango-exchange/rango-client/compare/provider-coin98@0.28.0...provider-coin98@0.29.0) (2024-02-20) + + + +# [0.28.0](https://github.com/rango-exchange/rango-client/compare/provider-coin98@0.27.0...provider-coin98@0.28.0) (2024-02-07) + + + +# [0.27.0](https://github.com/rango-exchange/rango-client/compare/provider-coin98@0.26.0...provider-coin98@0.27.0) (2024-01-22) + + +### Bug Fixes + +* cleanup wallets' subscriber when setProvider get null ([88d6a42](https://github.com/rango-exchange/rango-client/commit/88d6a423c49b34b3d9ff567e22df36c3b009bb76)) + + + +# [0.26.0](https://github.com/rango-exchange/rango-client/compare/provider-coin98@0.24.0...provider-coin98@0.26.0) (2023-12-24) + + +### Bug Fixes + +* fix HMR for widget and playground ([8524820](https://github.com/rango-exchange/rango-client/commit/8524820f10cf0b8921f3db0c4f620ff98daa4103)) + + + +# [0.14.0](https://github.com/rango-exchange/rango-client/compare/provider-coin98@0.13.0...provider-coin98@0.14.0) (2023-08-03) + + + +# [0.13.0](https://github.com/rango-exchange/rango-client/compare/provider-coin98@0.12.0...provider-coin98@0.13.0) (2023-08-01) + + + +# [0.9.0](https://github.com/rango-exchange/rango-client/compare/provider-coin98@0.8.0...provider-coin98@0.9.0) (2023-07-31) + + + +# [0.7.0](https://github.com/rango-exchange/rango-client/compare/provider-coin98@0.6.0...provider-coin98@0.7.0) (2023-07-11) + + + +# [0.6.0](https://github.com/rango-exchange/rango-client/compare/provider-coin98@0.5.0...provider-coin98@0.6.0) (2023-07-11) + + +### Reverts + +* Revert "support for rango-types cjs format" ([ed4e050](https://github.com/rango-exchange/rango-client/commit/ed4e050bfc0dcde7aeffa6b0d73b02080a5721eb)) + + + +# [0.5.0](https://github.com/rango-exchange/rango-client/compare/provider-coin98@0.4.0...provider-coin98@0.5.0) (2023-05-31) + + + +# [0.4.0](https://github.com/rango-exchange/rango-client/compare/provider-coin98@0.3.0...provider-coin98@0.4.0) (2023-05-31) + + + +# [0.3.0](https://github.com/rango-exchange/rango-client/compare/provider-coin98@0.2.0...provider-coin98@0.3.0) (2023-05-30) + + + +# [0.2.0](https://github.com/rango-exchange/rango-client/compare/provider-coin98@0.1.15...provider-coin98@0.2.0) (2023-05-30) + + + +## [0.1.14](https://github.com/rango-exchange/rango-client/compare/provider-coin98@0.1.13...provider-coin98@0.1.14) (2023-05-15) + + +### Bug Fixes + +* update rango-types and fix notification bugs ([993f185](https://github.com/rango-exchange/rango-client/commit/993f185e0b8c5e5e15a2c65ba2d85d1f9c8daa90)) + + + diff --git a/wallets/provider-coin98/package.json b/wallets/provider-coin98/package.json index 01eb0c375e..d628c9efec 100644 --- a/wallets/provider-coin98/package.json +++ b/wallets/provider-coin98/package.json @@ -1,50 +1,32 @@ { "name": "@rango-dev/provider-coin98", - "version": "0.1.12", + "version": "0.41.1-next.6", "license": "MIT", - "module": "dist/provider-coin98.esm.js", - "main": "dist/index.js", - "typings": "dist/index.d.ts", + "type": "module", + "source": "./src/mod.ts", + "main": "./dist/mod.js", + "exports": { + ".": "./dist/mod.js" + }, + "typings": "dist/mod.d.ts", "files": [ "dist", "src" ], "scripts": { - "start": "tsdx watch", - "build": "tsdx build --tsconfig ./tsconfig.json", - "test": "tsdx test --passWithNoTests", - "lint": "tsdx lint", - "size": "size-limit", - "analyze": "size-limit --why" - }, - "husky": { - "hooks": { - "pre-commit": "tsdx lint" - } + "build": "node ../../scripts/build/command.mjs --path wallets/provider-coin98 --inputs src/mod.ts", + "ts-check": "tsc --declaration --emitDeclarationOnly -p ./tsconfig.json", + "clean": "rimraf dist", + "format": "prettier --write '{.,src}/**/*.{ts,tsx}'", + "lint": "eslint \"**/*.{ts,tsx}\" --ignore-path ../../.eslintignore" }, - "prettier": { - "printWidth": 80, - "semi": true, - "singleQuote": true, - "trailingComma": "es5" - }, - "size-limit": [ - { - "path": "dist/provider-coin98.cjs.production.min.js", - "limit": "10 KB" - }, - { - "path": "dist/provider-coin98.esm.js", - "limit": "10 KB" - } - ], "dependencies": { - "@rango-dev/signer-evm": "^0.1.11", - "@rango-dev/signer-solana": "^0.1.11", - "@rango-dev/wallets-shared": "^0.1.11", - "@solana/web3.js": "^1.67.2", + "@rango-dev/signer-evm": "^0.32.0", + "@rango-dev/signer-solana": "^0.35.1-next.0", + "@rango-dev/wallets-shared": "^0.40.1-next.6", + "@solana/web3.js": "^1.91.4", "bs58": "^5.0.0", - "rango-types": "^0.1.28" + "rango-types": "^0.1.74" }, "publishConfig": { "access": "public" diff --git a/wallets/provider-coin98/src/constants.ts b/wallets/provider-coin98/src/constants.ts new file mode 100644 index 0000000000..66d2bbf852 --- /dev/null +++ b/wallets/provider-coin98/src/constants.ts @@ -0,0 +1,22 @@ +import { type ProviderInfo } from '@rango-dev/wallets-core'; + +export const WALLET_ID = 'coin98'; + +export const info: ProviderInfo = { + name: 'Coin98', + icon: 'https://raw.githubusercontent.com/rango-exchange/assets/main/wallets/coin98/icon.svg', + extensions: { + chrome: + 'https://chrome.google.com/webstore/detail/coin98-wallet/aeachknmefphepccionboohckonoeemg', + brave: + 'https://chrome.google.com/webstore/detail/coin98-wallet/aeachknmefphepccionboohckonoeemg', + homepage: 'https://coin98.com/wallet', + }, + properties: [ + { + name: 'detached', + // if you are adding a new namespace, don't forget to also update `getWalletInfo` + value: ['evm', 'solana'], + }, + ], +}; diff --git a/wallets/provider-coin98/src/helpers.ts b/wallets/provider-coin98/src/helpers.ts deleted file mode 100644 index eeab85c416..0000000000 --- a/wallets/provider-coin98/src/helpers.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { Network } from '@rango-dev/wallets-shared'; - -export function coin98() { - const { coin98, ethereum } = window; - - if (!coin98) return null; - - const instances = new Map(); - - // When disabled overring metamask - if (coin98.provider) instances.set(Network.ETHEREUM, coin98.provider); - if (ethereum && ethereum.isCoin98) instances.set(Network.ETHEREUM, ethereum); - if (coin98.sol) instances.set(Network.SOLANA, coin98.sol); - - return instances; -} - -/* - This is how coin98 is getting solana accounts. - That's the reason we haven't moved it to `shared` -*/ -export async function getSolanaAccounts(instance: any) { - await instance.enable(); - const accounts = await instance.request({ method: 'sol_accounts' }); - return { - accounts, - }; -} diff --git a/wallets/provider-coin98/src/index.ts b/wallets/provider-coin98/src/index.ts deleted file mode 100644 index 0890d9c7d6..0000000000 --- a/wallets/provider-coin98/src/index.ts +++ /dev/null @@ -1,115 +0,0 @@ -import { - getBlockChainNameFromId, - Network, - WalletType, - canSwitchNetworkToEvm, - chooseInstance, - getEvmAccounts, - switchNetworkForEvm, - CanSwitchNetwork, - Connect, - Subscribe, - SwitchNetwork, - WalletInfo, -} from '@rango-dev/wallets-shared'; -import { coin98 as coin98_instances } from './helpers'; -import { getSolanaAccounts } from './helpers'; -import signer from './signer'; -import { - SignerFactory, - evmBlockchains, - solanaBlockchain, - BlockchainMeta, -} from 'rango-types'; - -const WALLET = WalletType.COIN98; - -export const config = { - type: WALLET, - // TODO: Get from evm networks - defaultNetwork: Network.ETHEREUM, -}; -export const getInstance = coin98_instances; - -export const connect: Connect = async ({ instance, meta }) => { - const evm_instance = chooseInstance(instance, meta, Network.ETHEREUM); - const sol_instance = chooseInstance(instance, meta, Network.SOLANA); - const evm = await getEvmAccounts(evm_instance); - const { accounts: solanaAccounts } = await getSolanaAccounts(sol_instance); - - return [ - evm, - { - accounts: solanaAccounts, - chainId: Network.SOLANA, - }, - ]; -}; - -export const subscribe: Subscribe = ({ - instance, - meta, - updateChainId, - connect, -}) => { - const eth = chooseInstance(instance, meta, Network.ETHEREUM); - eth?.on('chainChanged', (chainId: string) => { - const network = getBlockChainNameFromId(chainId, meta) || Network.Unknown; - const targetInstance = chooseInstance(instance, meta, network); - targetInstance - .request({ method: 'eth_requestAccounts' }) - .then(() => undefined) - .catch((err: unknown) => { - console.log({ err }); - }); - /* - TODO: - We are calling `connect` here because signer can't detect - currect network, I guess the bug is in our signer and it - gets the wrong network by calling a wrong method or something. - Anyways, this works for now, maybe we can reconsider it in future - Whenever we refactored the signer code as well. - */ - - // we need to update `network` first, if not, it will goes through - // the switching network and will open unneccessary pop ups. - updateChainId(chainId); - connect(network); - }); -}; - -export const switchNetwork: SwitchNetwork = async (options) => { - const instance = chooseInstance( - options.instance, - options.meta, - options.network - ); - return switchNetworkForEvm({ - ...options, - instance, - }); -}; - -export const canSwitchNetworkTo: CanSwitchNetwork = canSwitchNetworkToEvm; - -export const getSigners: (provider: any) => SignerFactory = signer; - -export const getWalletInfo: (allBlockChains: BlockchainMeta[]) => WalletInfo = ( - allBlockChains -) => { - const evms = evmBlockchains(allBlockChains); - const solana = solanaBlockchain(allBlockChains); - return { - name: 'Coin98', - img: 'https://raw.githubusercontent.com/rango-exchange/rango-types/main/assets/icons/wallets/coin98.svg', - installLink: { - CHROME: - 'https://chrome.google.com/webstore/detail/coin98-wallet/aeachknmefphepccionboohckonoeemg', - BRAVE: - 'https://chrome.google.com/webstore/detail/coin98-wallet/aeachknmefphepccionboohckonoeemg', - DEFAULT: 'https://coin98.com/wallet', - }, - color: '#1d1c25', - supportedChains: [...evms, ...solana], - }; -}; diff --git a/wallets/provider-coin98/src/legacy/index.ts b/wallets/provider-coin98/src/legacy/index.ts new file mode 100644 index 0000000000..bab9ad8f8c --- /dev/null +++ b/wallets/provider-coin98/src/legacy/index.ts @@ -0,0 +1,151 @@ +import type { LegacyProviderInterface } from '@rango-dev/wallets-core/legacy'; +import type { + CanSwitchNetwork, + Connect, + Subscribe, + SwitchNetwork, + WalletInfo, +} from '@rango-dev/wallets-shared'; +import type { BlockchainMeta, SignerFactory } from 'rango-types'; + +import { + canSwitchNetworkToEvm, + chooseInstance, + getBlockChainNameFromId, + getEvmAccounts, + Networks, + switchNetworkForEvm, + WalletTypes, +} from '@rango-dev/wallets-shared'; +import { evmBlockchains, solanaBlockchain } from 'rango-types'; + +import { coin98 as coin98_instances, getSolanaAccounts } from '../utils.js'; + +import signer from './signer.js'; + +const WALLET = WalletTypes.COIN98; + +export const config = { + type: WALLET, + // TODO: Get from evm networks + defaultNetwork: Networks.ETHEREUM, +}; +export const getInstance = coin98_instances; + +export const connect: Connect = async ({ instance, meta }) => { + const evm_instance = chooseInstance(instance, meta, Networks.ETHEREUM); + const sol_instance = chooseInstance(instance, meta, Networks.SOLANA); + const evm = await getEvmAccounts(evm_instance); + const { accounts: solanaAccounts } = await getSolanaAccounts(sol_instance); + + return [ + evm, + { + accounts: solanaAccounts, + chainId: Networks.SOLANA, + }, + ]; +}; + +export const subscribe: Subscribe = ({ + instance, + meta, + updateChainId, + connect, +}) => { + const eth = chooseInstance(instance, meta, Networks.ETHEREUM); + const handleChainChanged = (chainId: string) => { + const network = getBlockChainNameFromId(chainId, meta) || Networks.Unknown; + const targetInstance = chooseInstance(instance, meta, network); + targetInstance + .request({ method: 'eth_requestAccounts' }) + .then(() => undefined) + .catch((err: unknown) => { + console.log({ err }); + }); + /* + *TODO: + *We are calling `connect` here because signer can't detect + *currect network, I guess the bug is in our signer and it + *gets the wrong network by calling a wrong method or something. + *Anyways, this works for now, maybe we can reconsider it in future + *Whenever we refactored the signer code as well. + */ + + /* + * we need to update `network` first, if not, it will goes through + * the switching network and will open unneccessary pop ups. + */ + updateChainId(chainId); + connect(network); + }; + eth?.on?.('chainChanged', handleChainChanged); + + return () => { + eth?.off?.('chainChanged', handleChainChanged); + }; +}; + +export const switchNetwork: SwitchNetwork = async (options) => { + const instance = chooseInstance( + options.instance, + options.meta, + options.network + ); + return switchNetworkForEvm({ + ...options, + instance, + }); +}; + +export const canSwitchNetworkTo: CanSwitchNetwork = canSwitchNetworkToEvm; + +export const getSigners: (provider: any) => Promise = signer; + +export const getWalletInfo: (allBlockChains: BlockchainMeta[]) => WalletInfo = ( + allBlockChains +) => { + const evms = evmBlockchains(allBlockChains); + const solana = solanaBlockchain(allBlockChains); + return { + name: 'Coin98', + img: 'https://raw.githubusercontent.com/rango-exchange/assets/main/wallets/coin98/icon.svg', + installLink: { + CHROME: + 'https://chrome.google.com/webstore/detail/coin98-wallet/aeachknmefphepccionboohckonoeemg', + BRAVE: + 'https://chrome.google.com/webstore/detail/coin98-wallet/aeachknmefphepccionboohckonoeemg', + DEFAULT: 'https://coin98.com/wallet', + }, + color: '#1d1c25', + supportedChains: [...evms, ...solana], + needsNamespace: { + selection: 'multiple', + data: [ + { + label: 'EVM', + value: 'EVM', + id: 'ETH', + }, + { + label: 'Solana', + value: 'Solana', + id: 'SOLANA', + }, + ], + }, + }; +}; + +const buildLegacyProvider: () => LegacyProviderInterface = () => ({ + config, + getInstance, + connect, + subscribe, + switchNetwork, + canSwitchNetworkTo, + getSigners, + getWalletInfo, +}); + +export { buildLegacyProvider }; diff --git a/wallets/provider-coin98/src/legacy/signer.ts b/wallets/provider-coin98/src/legacy/signer.ts new file mode 100644 index 0000000000..6cd7760393 --- /dev/null +++ b/wallets/provider-coin98/src/legacy/signer.ts @@ -0,0 +1,18 @@ +import type { SignerFactory } from 'rango-types'; + +import { getNetworkInstance, Networks } from '@rango-dev/wallets-shared'; +import { DefaultSignerFactory, TransactionType as TxType } from 'rango-types'; + +import { CustomSolanaSigner } from './solana-signer.js'; + +export default async function getSigners( + provider: any +): Promise { + const ethProvider = getNetworkInstance(provider, Networks.ETHEREUM); + const solProvider = getNetworkInstance(provider, Networks.SOLANA); + const signers = new DefaultSignerFactory(); + const { DefaultEvmSigner } = await import('@rango-dev/signer-evm'); + signers.registerSigner(TxType.EVM, new DefaultEvmSigner(ethProvider)); + signers.registerSigner(TxType.SOLANA, new CustomSolanaSigner(solProvider)); + return signers; +} diff --git a/wallets/provider-coin98/src/legacy/solana-signer.ts b/wallets/provider-coin98/src/legacy/solana-signer.ts new file mode 100644 index 0000000000..50b5069047 --- /dev/null +++ b/wallets/provider-coin98/src/legacy/solana-signer.ts @@ -0,0 +1,53 @@ +import type { SolanaWeb3Signer } from '@rango-dev/signer-solana'; +import type { Transaction, VersionedTransaction } from '@solana/web3.js'; +import type { GenericSigner, SolanaTransaction } from 'rango-types'; + +import { generalSolanaTransactionExecutor } from '@rango-dev/signer-solana'; +import { PublicKey } from '@solana/web3.js'; +import bs58 from 'bs58'; +import { SignerError, SignerErrorCode } from 'rango-types'; + +/* + * TODO - replace with real type + * tslint:disable-next-line: no-any + */ +type SolanaExternalProvider = any; + +export class CustomSolanaSigner implements GenericSigner { + private provider: SolanaExternalProvider; + constructor(provider: SolanaExternalProvider) { + this.provider = provider; + } + + async signMessage(msg: string): Promise { + try { + const result = await this.provider.signMessage(msg); + return result.signature; + } catch (error) { + throw new SignerError(SignerErrorCode.SIGN_TX_ERROR, undefined, error); + } + } + + async signAndSendTx(tx: SolanaTransaction): Promise<{ hash: string }> { + const DefaultSolanaSigner: SolanaWeb3Signer = async ( + solanaWeb3Transaction: Transaction | VersionedTransaction + ) => { + const response: { publicKey: string; signature: string } = + await this.provider.request({ + method: 'sol_sign', + params: [solanaWeb3Transaction], + }); + const publicKey = new PublicKey(response.publicKey); + const sign = bs58.decode(response.signature); + + solanaWeb3Transaction.addSignature(publicKey, Buffer.from(sign)); + const raw = solanaWeb3Transaction.serialize(); + return raw; + }; + const hash = await generalSolanaTransactionExecutor( + tx, + DefaultSolanaSigner + ); + return { hash }; + } +} diff --git a/wallets/provider-coin98/src/mod.ts b/wallets/provider-coin98/src/mod.ts new file mode 100644 index 0000000000..d7cbd1745a --- /dev/null +++ b/wallets/provider-coin98/src/mod.ts @@ -0,0 +1,12 @@ +import { defineVersions } from '@rango-dev/wallets-core/utils'; + +import { buildLegacyProvider } from './legacy/index.js'; +import { buildProvider } from './provider.js'; + +const versions = () => + defineVersions() + .version('0.0.0', buildLegacyProvider()) + .version('1.0.0', buildProvider()) + .build(); + +export { versions }; diff --git a/wallets/provider-coin98/src/namespaces/evm.ts b/wallets/provider-coin98/src/namespaces/evm.ts new file mode 100644 index 0000000000..5afcc3c597 --- /dev/null +++ b/wallets/provider-coin98/src/namespaces/evm.ts @@ -0,0 +1,36 @@ +import type { EvmActions } from '@rango-dev/wallets-core/namespaces/evm'; + +import { NamespaceBuilder } from '@rango-dev/wallets-core'; +import { builders as commonBuilders } from '@rango-dev/wallets-core/namespaces/common'; +import { actions, builders } from '@rango-dev/wallets-core/namespaces/evm'; + +import { WALLET_ID } from '../constants.js'; +import { evmCoin98 } from '../utils.js'; + +const [changeAccountSubscriber, changeAccountCleanup] = + actions.changeAccountSubscriber(evmCoin98); + +/* + * TODO: If user imported a private key for EVM, it hasn't solana. + * when trying to connect to solana for this user we go through `-32603` which is an internal error. + * If phantom added an specific error code for this situation, we can consider handling the error here. + * @see https://docs.phantom.app/solana/errors + */ +const connect = builders + .connect() + .action(actions.connect(evmCoin98)) + .before(changeAccountSubscriber) + .or(changeAccountCleanup) + .build(); + +const disconnect = commonBuilders + .disconnect() + .after(changeAccountCleanup) + .build(); + +const evm = new NamespaceBuilder('EVM', WALLET_ID) + .action(connect) + .action(disconnect) + .build(); + +export { evm }; diff --git a/wallets/provider-coin98/src/namespaces/solana.ts b/wallets/provider-coin98/src/namespaces/solana.ts new file mode 100644 index 0000000000..bac963a858 --- /dev/null +++ b/wallets/provider-coin98/src/namespaces/solana.ts @@ -0,0 +1,64 @@ +import type { CaipAccount } from '@rango-dev/wallets-core/namespaces/common'; +import type { SolanaActions } from '@rango-dev/wallets-core/namespaces/solana'; + +import { NamespaceBuilder } from '@rango-dev/wallets-core'; +import { builders as commonBuilders } from '@rango-dev/wallets-core/namespaces/common'; +import { + actions, + builders, + CAIP_NAMESPACE, + CAIP_SOLANA_CHAIN_ID, +} from '@rango-dev/wallets-core/namespaces/solana'; +import { CAIP } from '@rango-dev/wallets-core/utils'; + +import { WALLET_ID } from '../constants.js'; +import { getSolanaAccounts, solanaCoin98 } from '../utils.js'; + +const [changeAccountSubscriber, changeAccountCleanup] = + actions.changeAccountSubscriber(solanaCoin98); + +/* + * TODO: If user imported a private key for EVM, it hasn't solana. + * when trying to connect to solana for this user we go through `-32603` which is an internal error. + * If phantom added an specific error code for this situation, we can consider handling the error here. + * @see https://docs.phantom.app/solana/errors + */ +const connect = builders + .connect() + .action(async function () { + const solanaInstance = solanaCoin98(); + const result = await getSolanaAccounts(solanaInstance); + if (Array.isArray(result)) { + throw new Error( + 'Expecting solana response to be a single value, not an array.' + ); + } + + const formatAccounts = result.accounts.map( + (account) => + CAIP.AccountId.format({ + address: account, + chainId: { + namespace: CAIP_NAMESPACE, + reference: CAIP_SOLANA_CHAIN_ID, + }, + }) as CaipAccount + ); + + return formatAccounts; + }) + .before(changeAccountSubscriber) + .or(changeAccountCleanup) + .build(); + +const disconnect = commonBuilders + .disconnect() + .after(changeAccountCleanup) + .build(); + +const solana = new NamespaceBuilder('Solana', WALLET_ID) + .action(connect) + .action(disconnect) + .build(); + +export { solana }; diff --git a/wallets/provider-coin98/src/provider.ts b/wallets/provider-coin98/src/provider.ts new file mode 100644 index 0000000000..727e33966f --- /dev/null +++ b/wallets/provider-coin98/src/provider.ts @@ -0,0 +1,23 @@ +import { ProviderBuilder } from '@rango-dev/wallets-core'; + +import { info, WALLET_ID } from './constants.js'; +import { evm } from './namespaces/evm.js'; +import { solana } from './namespaces/solana.js'; +import { coin98 as coin98Instances } from './utils.js'; + +const buildProvider = () => + new ProviderBuilder(WALLET_ID) + .init(function (context) { + const [, setState] = context.state(); + + if (coin98Instances()) { + setState('installed', true); + console.debug('[phantom] instance detected.', context); + } + }) + .config('info', info) + .add('solana', solana) + .add('evm', evm) + .build(); + +export { buildProvider }; diff --git a/wallets/provider-coin98/src/signer.ts b/wallets/provider-coin98/src/signer.ts deleted file mode 100644 index 78471c9464..0000000000 --- a/wallets/provider-coin98/src/signer.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { DefaultEvmSigner } from '@rango-dev/signer-evm'; -import { Network, getNetworkInstance } from '@rango-dev/wallets-shared'; -import { SignerFactory, TransactionType as TxType } from 'rango-types'; -import { CustomSolanaSigner } from './solana-signer'; - -export default function getSigners(provider: any): SignerFactory { - const ethProvider = getNetworkInstance(provider, Network.ETHEREUM); - const solProvider = getNetworkInstance(provider, Network.SOLANA); - const signers = new SignerFactory(); - signers.registerSigner(TxType.EVM, new DefaultEvmSigner(ethProvider)); - signers.registerSigner(TxType.SOLANA, new CustomSolanaSigner(solProvider)); - return signers; -} diff --git a/wallets/provider-coin98/src/solana-signer.ts b/wallets/provider-coin98/src/solana-signer.ts deleted file mode 100644 index 18d903ff3f..0000000000 --- a/wallets/provider-coin98/src/solana-signer.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { GenericSigner, SignerError, SolanaTransaction } from 'rango-types'; -import { PublicKey, Transaction, VersionedTransaction } from '@solana/web3.js'; -import bs58 from 'bs58'; -import { - SolanaWeb3Signer, - generalSolanaTransactionExecutor, -} from '@rango-dev/signer-solana'; - -// TODO - replace with real type -// tslint:disable-next-line: no-any -type SolanaExternalProvider = any; - -export class CustomSolanaSigner implements GenericSigner { - private provider: SolanaExternalProvider; - constructor(provider: SolanaExternalProvider) { - this.provider = provider; - } - - async signMessage(): Promise { - throw SignerError.UnimplementedError('signMessage'); - } - - async signAndSendTx(tx: SolanaTransaction): Promise { - const DefaultSolanaSigner: SolanaWeb3Signer = async ( - solanaWeb3Transaction: Transaction | VersionedTransaction - ) => { - const response: { publicKey: string; signature: string } = - await this.provider.request({ - method: 'sol_sign', - params: [solanaWeb3Transaction], - }); - const publicKey = new PublicKey(response.publicKey); - const sign = bs58.decode(response.signature); - - solanaWeb3Transaction.addSignature(publicKey, Buffer.from(sign)); - const raw = solanaWeb3Transaction.serialize(); - return raw; - }; - const hash = await generalSolanaTransactionExecutor( - tx, - DefaultSolanaSigner - ); - return hash; - } -} diff --git a/wallets/provider-coin98/src/utils.ts b/wallets/provider-coin98/src/utils.ts new file mode 100644 index 0000000000..b468f17e1a --- /dev/null +++ b/wallets/provider-coin98/src/utils.ts @@ -0,0 +1,73 @@ +import type { ProviderAPI as EvmProviderApi } from '@rango-dev/wallets-core/namespaces/evm'; +import type { ProviderAPI as SolanaProviderApi } from '@rango-dev/wallets-core/namespaces/solana'; + +import { LegacyNetworks } from '@rango-dev/wallets-core/legacy'; +import { + Networks, + type ProviderConnectResult, +} from '@rango-dev/wallets-shared'; + +export function coin98() { + const { coin98, ethereum } = window; + + if (!coin98) { + return null; + } + + const instances = new Map(); + + // When disabled overring metamask + if (coin98.provider) { + instances.set(Networks.ETHEREUM, coin98.provider); + } + if (ethereum && ethereum.isCoin98) { + instances.set(Networks.ETHEREUM, ethereum); + } + if (coin98.sol) { + instances.set(Networks.SOLANA, coin98.sol); + } + + return instances; +} + +/* + *This is how coin98 is getting solana accounts. + *That's the reason we haven't moved it to `shared` + */ +export async function getSolanaAccounts( + instance: any +): Promise { + await instance.enable(); + const accounts = await instance.request({ method: 'sol_accounts' }); + return { + accounts, + chainId: LegacyNetworks.SOLANA, + }; +} + +export function solanaCoin98(): SolanaProviderApi { + const instance = coin98(); + const solanaInstance = instance?.get(LegacyNetworks.SOLANA); + + if (!solanaInstance) { + throw new Error( + 'Coin98 not injected or Solana not enabled. Please check your wallet.' + ); + } + + return solanaInstance; +} + +export function evmCoin98(): EvmProviderApi { + const instances = coin98(); + + const evmInstance = instances?.get(LegacyNetworks.ETHEREUM); + + if (!evmInstance) { + throw new Error( + 'Coin98 not injected or EVM not enabled. Please check your wallet.' + ); + } + + return evmInstance as EvmProviderApi; +} diff --git a/wallets/provider-coin98/tsconfig.build.json b/wallets/provider-coin98/tsconfig.build.json new file mode 100644 index 0000000000..d9181ce0cd --- /dev/null +++ b/wallets/provider-coin98/tsconfig.build.json @@ -0,0 +1,11 @@ +{ + // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs + "extends": "../../tsconfig.libnext.json", + "include": ["src", "types", "../../global-wallets-env.d.ts"], + "compilerOptions": { + "outDir": "dist", + "rootDir": "./src", + "lib": ["dom", "esnext"] + // match output dir to input dir. e.g. dist/index instead of dist/src/index + } +} diff --git a/wallets/provider-coin98/tsconfig.json b/wallets/provider-coin98/tsconfig.json index 365489616a..a3a0b0f59d 100644 --- a/wallets/provider-coin98/tsconfig.json +++ b/wallets/provider-coin98/tsconfig.json @@ -1,35 +1 @@ -{ - // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs - "include": ["src", "types", "../../global-wallets-env.d.ts"], - "compilerOptions": { - "module": "esnext", - "lib": ["dom", "esnext"], - "importHelpers": true, - // output .d.ts declaration files for consumers - "declaration": true, - // output .js.map sourcemap files for consumers - "sourceMap": true, - // match output dir to input dir. e.g. dist/index instead of dist/src/index - "rootDir": "./src", - // stricter type-checking for stronger correctness. Recommended by TS - "strict": true, - // linter checks for common issues - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true, - // noUnused* overlap with @typescript-eslint/no-unused-vars, can disable if duplicative - "noUnusedLocals": true, - "noUnusedParameters": true, - // use Node's module resolution algorithm, instead of the legacy TS one - "moduleResolution": "node", - // transpile JSX to React.createElement - "jsx": "react", - // interop between ESM and CJS modules. Recommended by TS - "esModuleInterop": true, - // significant perf increase by skipping checking .d.ts files, particularly those in node_modules. Recommended by TS - "skipLibCheck": true, - // error out if import and file system have a casing mismatch. Recommended by TS - "forceConsistentCasingInFileNames": true, - // `tsdx build` ignores this option, but it is commonly used when type-checking separately with `tsc` - "noEmit": true, - } -} +{ "extends": "./tsconfig.build.json", "include": ["src", "tests"] } diff --git a/wallets/provider-coinbase/CHANGELOG.md b/wallets/provider-coinbase/CHANGELOG.md new file mode 100644 index 0000000000..a79ef458c0 --- /dev/null +++ b/wallets/provider-coinbase/CHANGELOG.md @@ -0,0 +1,166 @@ +# [0.41.0](https://github.com/rango-exchange/rango-client/compare/provider-coinbase@0.40.0...provider-coinbase@0.41.0) (2024-12-30) + + + +# [0.40.0](https://github.com/rango-exchange/rango-client/compare/provider-coinbase@0.39.0...provider-coinbase@0.40.0) (2024-11-27) + + +### Features + +* add ton connect provider ([2a2dbb7](https://github.com/rango-exchange/rango-client/commit/2a2dbb79022263f19446ced49d298e04d63f927f)) + + + +# [0.39.0](https://github.com/rango-exchange/rango-client/compare/provider-coinbase@0.38.0...provider-coinbase@0.39.0) (2024-11-12) + + + +# [0.38.0](https://github.com/rango-exchange/rango-client/compare/provider-coinbase@0.37.0...provider-coinbase@0.38.0) (2024-10-12) + + +### Bug Fixes + +* bump sdk and fix type issues ([d442208](https://github.com/rango-exchange/rango-client/commit/d4422083bf5dd27d5f509ce1db7f9560d05428c8)) +* resolve issues with the sign message method for certain solana providers ([cbe83a3](https://github.com/rango-exchange/rango-client/commit/cbe83a3da8b48560b206fc2a7fa7cf062cdeaa23)) + + +### Performance Improvements + +* lazy load signer packages ([7b88f18](https://github.com/rango-exchange/rango-client/commit/7b88f1834f7b29b4b81ab6c81a07bb88e8ccf55c)) + + + +# [0.37.0](https://github.com/rango-exchange/rango-client/compare/provider-coinbase@0.36.0...provider-coinbase@0.37.0) (2024-09-10) + + + +# [0.36.0](https://github.com/rango-exchange/rango-client/compare/provider-coinbase@0.35.1...provider-coinbase@0.36.0) (2024-08-11) + + + +## [0.35.1](https://github.com/rango-exchange/rango-client/compare/provider-coinbase@0.35.0...provider-coinbase@0.35.1) (2024-07-14) + + + +# [0.35.0](https://github.com/rango-exchange/rango-client/compare/provider-coinbase@0.33.2...provider-coinbase@0.35.0) (2024-07-09) + + + +# [0.34.0](https://github.com/rango-exchange/rango-client/compare/provider-coinbase@0.33.2...provider-coinbase@0.34.0) (2024-06-01) + + + +## [0.33.2](https://github.com/rango-exchange/rango-client/compare/provider-coinbase@0.33.1...provider-coinbase@0.33.2) (2024-05-26) + + + +## [0.33.1](https://github.com/rango-exchange/rango-client/compare/provider-coinbase@0.33.0...provider-coinbase@0.33.1) (2024-05-25) + + + +# [0.33.0](https://github.com/rango-exchange/rango-client/compare/provider-coinbase@0.32.0...provider-coinbase@0.33.0) (2024-05-14) + + + +# [0.32.0](https://github.com/rango-exchange/rango-client/compare/provider-coinbase@0.31.0...provider-coinbase@0.32.0) (2024-04-24) + + + +# [0.31.0](https://github.com/rango-exchange/rango-client/compare/provider-coinbase@0.30.0...provider-coinbase@0.31.0) (2024-04-23) + + +### Bug Fixes + +* resolve conflicts between evm providers ([9a6734c](https://github.com/rango-exchange/rango-client/commit/9a6734cf1537bf0504cf9058d4d775313a9e8e80)) + + + +# [0.30.0](https://github.com/rango-exchange/rango-client/compare/provider-coinbase@0.29.0...provider-coinbase@0.30.0) (2024-04-09) + + +### Bug Fixes + +* fix the connection problem that happens when another wallet takes over the requested one ([42df212](https://github.com/rango-exchange/rango-client/commit/42df2120aadd84c95045b0bf76844c19305fb59a)) + + + +# [0.29.0](https://github.com/rango-exchange/rango-client/compare/provider-coinbase@0.28.0...provider-coinbase@0.29.0) (2024-03-12) + + + +# [0.28.0](https://github.com/rango-exchange/rango-client/compare/provider-coinbase@0.27.0...provider-coinbase@0.28.0) (2024-02-20) + + + +# [0.27.0](https://github.com/rango-exchange/rango-client/compare/provider-coinbase@0.26.0...provider-coinbase@0.27.0) (2024-02-07) + + + +# [0.26.0](https://github.com/rango-exchange/rango-client/compare/provider-coinbase@0.25.0...provider-coinbase@0.26.0) (2024-01-22) + + +### Bug Fixes + +* cleanup wallets' subscriber when setProvider get null ([88d6a42](https://github.com/rango-exchange/rango-client/commit/88d6a423c49b34b3d9ff567e22df36c3b009bb76)) + + + +# [0.25.0](https://github.com/rango-exchange/rango-client/compare/provider-coinbase@0.23.0...provider-coinbase@0.25.0) (2023-12-24) + + +### Bug Fixes + +* fix HMR for widget and playground ([8524820](https://github.com/rango-exchange/rango-client/commit/8524820f10cf0b8921f3db0c4f620ff98daa4103)) + + + +# [0.14.0](https://github.com/rango-exchange/rango-client/compare/provider-coinbase@0.13.0...provider-coinbase@0.14.0) (2023-08-03) + + + +# [0.13.0](https://github.com/rango-exchange/rango-client/compare/provider-coinbase@0.12.0...provider-coinbase@0.13.0) (2023-08-01) + + + +# [0.9.0](https://github.com/rango-exchange/rango-client/compare/provider-coinbase@0.8.0...provider-coinbase@0.9.0) (2023-07-31) + + + +# [0.7.0](https://github.com/rango-exchange/rango-client/compare/provider-coinbase@0.6.0...provider-coinbase@0.7.0) (2023-07-11) + + + +# [0.6.0](https://github.com/rango-exchange/rango-client/compare/provider-coinbase@0.5.0...provider-coinbase@0.6.0) (2023-07-11) + + +### Reverts + +* Revert "support for rango-types cjs format" ([ed4e050](https://github.com/rango-exchange/rango-client/commit/ed4e050bfc0dcde7aeffa6b0d73b02080a5721eb)) + + + +# [0.5.0](https://github.com/rango-exchange/rango-client/compare/provider-coinbase@0.4.0...provider-coinbase@0.5.0) (2023-05-31) + + + +# [0.4.0](https://github.com/rango-exchange/rango-client/compare/provider-coinbase@0.3.0...provider-coinbase@0.4.0) (2023-05-31) + + + +# [0.3.0](https://github.com/rango-exchange/rango-client/compare/provider-coinbase@0.2.0...provider-coinbase@0.3.0) (2023-05-30) + + + +# [0.2.0](https://github.com/rango-exchange/rango-client/compare/provider-coinbase@0.1.15...provider-coinbase@0.2.0) (2023-05-30) + + + +## [0.1.14](https://github.com/rango-exchange/rango-client/compare/provider-coinbase@0.1.13...provider-coinbase@0.1.14) (2023-05-15) + + +### Bug Fixes + +* update rango-types and fix notification bugs ([993f185](https://github.com/rango-exchange/rango-client/commit/993f185e0b8c5e5e15a2c65ba2d85d1f9c8daa90)) + + + diff --git a/wallets/provider-coinbase/package.json b/wallets/provider-coinbase/package.json index 4b8ca1cb97..1abc6336dd 100644 --- a/wallets/provider-coinbase/package.json +++ b/wallets/provider-coinbase/package.json @@ -1,50 +1,33 @@ { "name": "@rango-dev/provider-coinbase", - "version": "0.1.12", + "version": "0.40.1-next.6", "license": "MIT", - "module": "dist/provider-coinbase.esm.js", - "main": "dist/index.js", + "type": "module", + "source": "./src/index.ts", + "main": "./dist/index.js", + "exports": { + ".": "./dist/index.js" + }, "typings": "dist/index.d.ts", "files": [ "dist", "src" ], "scripts": { - "start": "tsdx watch", - "build": "tsdx build --tsconfig ./tsconfig.json", - "test": "tsdx test --passWithNoTests", - "lint": "tsdx lint", - "size": "size-limit", - "analyze": "size-limit --why" - }, - "husky": { - "hooks": { - "pre-commit": "tsdx lint" - } + "build": "node ../../scripts/build/command.mjs --path wallets/provider-coinbase", + "ts-check": "tsc --declaration --emitDeclarationOnly -p ./tsconfig.json", + "clean": "rimraf dist", + "format": "prettier --write '{.,src}/**/*.{ts,tsx}'", + "lint": "eslint \"**/*.{ts,tsx}\" --ignore-path ../../.eslintignore" }, - "prettier": { - "printWidth": 80, - "semi": true, - "singleQuote": true, - "trailingComma": "es5" - }, - "size-limit": [ - { - "path": "dist/provider-coinbase.cjs.production.min.js", - "limit": "10 KB" - }, - { - "path": "dist/provider-coinbase.esm.js", - "limit": "10 KB" - } - ], "dependencies": { - "@rango-dev/signer-evm": "^0.1.11", - "@rango-dev/signer-solana": "^0.1.11", - "@rango-dev/wallets-shared": "^0.1.11", - "rango-types": "^0.1.28" + "@rango-dev/signer-evm": "^0.32.0", + "@rango-dev/signer-solana": "^0.35.1-next.0", + "@rango-dev/wallets-shared": "^0.40.1-next.6", + "bs58": "^5.0.0", + "rango-types": "^0.1.74" }, "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/wallets/provider-coinbase/src/helpers.ts b/wallets/provider-coinbase/src/helpers.ts index 28307650d3..3c7d4429cf 100644 --- a/wallets/provider-coinbase/src/helpers.ts +++ b/wallets/provider-coinbase/src/helpers.ts @@ -1,18 +1,39 @@ -import { Network, ProviderConnectResult } from '@rango-dev/wallets-shared'; +import type { ProviderConnectResult } from '@rango-dev/wallets-shared'; + +import { Networks } from '@rango-dev/wallets-shared'; + +export function coinbase() { + const { coinbaseWalletExtension, coinbaseSolana } = window; + + const instances = new Map(); + if (coinbaseWalletExtension) { + instances.set(Networks.ETHEREUM, coinbaseWalletExtension); + } + + if (!!coinbaseSolana) { + instances.set(Networks.SOLANA, coinbaseSolana); + } + + if (instances.size === 0) { + return null; + } + + return instances; +} export async function getSolanaAccounts( instance: any ): Promise { - const solanaInstance = await instance.get(Network.SOLANA); + const solanaInstance = await instance.get(Networks.SOLANA); const results: ProviderConnectResult[] = []; - if (!!solanaInstance) { + if (solanaInstance) { await solanaInstance.connect(); const account = solanaInstance.publicKey.toString(); results.push({ accounts: account ? [account] : [], - chainId: Network.SOLANA, + chainId: Networks.SOLANA, }); } diff --git a/wallets/provider-coinbase/src/index.ts b/wallets/provider-coinbase/src/index.ts index e8bc39f360..d3a006d859 100644 --- a/wallets/provider-coinbase/src/index.ts +++ b/wallets/provider-coinbase/src/index.ts @@ -1,43 +1,49 @@ -import { - Network, - WalletType, +import type { + CanEagerConnect, CanSwitchNetwork, Connect, ProviderConnectResult, Subscribe, SwitchNetwork, + WalletInfo, +} from '@rango-dev/wallets-shared'; +import type { BlockchainMeta, SignerFactory } from 'rango-types'; + +import { + canEagerlyConnectToEvm, canSwitchNetworkToEvm, chooseInstance, getEvmAccounts, + Networks, switchNetworkForEvm, - getCoinbaseInstance as coinbase_instance, - WalletInfo, + WalletTypes, } from '@rango-dev/wallets-shared'; -import { getSolanaAccounts } from './helpers'; import { - SignerFactory, - isEvmBlockchain, - BlockchainMeta, evmBlockchains, - solanaBlockchain, + isEvmBlockchain, isSolanaBlockchain, + solanaBlockchain, } from 'rango-types'; -import signer from './signer'; -const WALLET = WalletType.COINBASE; +import { coinbase as coinbase_instance, getSolanaAccounts } from './helpers.js'; +import signer from './signer.js'; + +const WALLET = WalletTypes.COINBASE; export const config = { type: WALLET, - defaultNetwork: Network.ETHEREUM, + defaultNetwork: Networks.ETHEREUM, }; export const getInstance = coinbase_instance; export const connect: Connect = async ({ instance, meta }) => { - // Note: We need to get `chainId` here, because for the first time - // after opening the browser, wallet is locked, and don't give us accounts and chainId - // on `check` phase, so `network` will be null. For this case we need to get chainId - // whenever we are requesting accounts. - const evm_instance = chooseInstance(instance, meta, Network.ETHEREUM); + /* + * Note: We need to get `chainId` here, because for the first time + * after opening the browser, wallet is locked, and don't give us accounts and chainId + * on `check` phase, so `network` will be null. For this case we need to get chainId + * whenever we are requesting accounts. + */ + const evm_instance = chooseInstance(instance, meta, Networks.ETHEREUM); let results: ProviderConnectResult[] = []; if (evm_instance) { @@ -54,42 +60,61 @@ export const subscribe: Subscribe = (options) => { const ethInstance = chooseInstance( options.instance, options.meta, - Network.ETHEREUM + Networks.ETHEREUM ); const solanaInstance = chooseInstance( options.instance, options.meta, - Network.SOLANA + Networks.SOLANA ); const { connect, updateAccounts, state, updateChainId, meta } = options; - ethInstance?.on('accountsChanged', (addresses: string[]) => { + const handleEvmAccountsChanged = (addresses: string[]) => { const eth_chainId = meta .filter(isEvmBlockchain) - .find((blockchain) => blockchain.name === Network.ETHEREUM)?.chainId; + .find((blockchain) => blockchain.name === Networks.ETHEREUM)?.chainId; if (state.connected) { - if (state.network != Network.ETHEREUM && eth_chainId) + if (state.network != Networks.ETHEREUM && eth_chainId) { updateChainId(eth_chainId); + } updateAccounts(addresses); } - }); + }; - solanaInstance?.on('accountChanged', async (publicKey: string) => { - if (state.network != Network.SOLANA) + const handleSolanaAccountChanged = async (publicKey: string) => { + if (state.network != Networks.SOLANA) { updateChainId(meta.filter(isSolanaBlockchain)[0].chainId); - const network = Network.SOLANA; + } + const network = Networks.SOLANA; if (publicKey) { const account = publicKey.toString(); updateAccounts([account]); } else { connect(network); } - }); + }; + ethInstance?.on?.('accountsChanged', handleEvmAccountsChanged); + + solanaInstance?.on?.('accountChanged', handleSolanaAccountChanged); + + return () => { + ethInstance?.off?.('accountsChanged', handleEvmAccountsChanged); + + solanaInstance?.off?.('accountChanged', handleSolanaAccountChanged); + }; }; export const switchNetwork: SwitchNetwork = switchNetworkForEvm; export const canSwitchNetworkTo: CanSwitchNetwork = canSwitchNetworkToEvm; -export const getSigners: (provider: any) => SignerFactory = signer; +export const getSigners: (provider: any) => Promise = signer; + +export const canEagerConnect: CanEagerConnect = async ({ instance, meta }) => { + const evm_instance = chooseInstance(instance, meta, Networks.ETHEREUM); + if (evm_instance) { + return canEagerlyConnectToEvm({ instance: evm_instance, meta }); + } + return Promise.resolve(false); +}; export const getWalletInfo: (allBlockChains: BlockchainMeta[]) => WalletInfo = ( allBlockChains @@ -98,7 +123,7 @@ export const getWalletInfo: (allBlockChains: BlockchainMeta[]) => WalletInfo = ( const solana = solanaBlockchain(allBlockChains); return { name: 'Coinbase', - img: 'https://raw.githubusercontent.com/rango-exchange/rango-types/main/assets/icons/wallets/coinbase.svg', + img: 'https://raw.githubusercontent.com/rango-exchange/assets/main/wallets/coinbase/icon.svg', installLink: { CHROME: 'https://chrome.google.com/webstore/detail/coinbase-wallet-extension/hnfanknocfeofbddgcijnmhnfnkdnaad', diff --git a/wallets/provider-coinbase/src/signer.ts b/wallets/provider-coinbase/src/signer.ts index 0585e651d9..6cd7760393 100644 --- a/wallets/provider-coinbase/src/signer.ts +++ b/wallets/provider-coinbase/src/signer.ts @@ -1,13 +1,18 @@ -import { DefaultEvmSigner } from '@rango-dev/signer-evm'; -import { DefaultSolanaSigner } from '@rango-dev/signer-solana'; -import { Network, getNetworkInstance } from '@rango-dev/wallets-shared'; -import { SignerFactory, TransactionType as TxType } from 'rango-types'; +import type { SignerFactory } from 'rango-types'; -export default function getSigners(provider: any): SignerFactory { - const ethProvider = getNetworkInstance(provider, Network.ETHEREUM); - const solProvider = getNetworkInstance(provider, Network.SOLANA); - const signers = new SignerFactory(); +import { getNetworkInstance, Networks } from '@rango-dev/wallets-shared'; +import { DefaultSignerFactory, TransactionType as TxType } from 'rango-types'; + +import { CustomSolanaSigner } from './solana-signer.js'; + +export default async function getSigners( + provider: any +): Promise { + const ethProvider = getNetworkInstance(provider, Networks.ETHEREUM); + const solProvider = getNetworkInstance(provider, Networks.SOLANA); + const signers = new DefaultSignerFactory(); + const { DefaultEvmSigner } = await import('@rango-dev/signer-evm'); signers.registerSigner(TxType.EVM, new DefaultEvmSigner(ethProvider)); - signers.registerSigner(TxType.SOLANA, new DefaultSolanaSigner(solProvider)); + signers.registerSigner(TxType.SOLANA, new CustomSolanaSigner(solProvider)); return signers; } diff --git a/wallets/provider-coinbase/src/solana-signer.ts b/wallets/provider-coinbase/src/solana-signer.ts new file mode 100644 index 0000000000..46847565d4 --- /dev/null +++ b/wallets/provider-coinbase/src/solana-signer.ts @@ -0,0 +1,16 @@ +import { DefaultSolanaSigner } from '@rango-dev/signer-solana'; +import base58 from 'bs58'; + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +type SolanaExternalProvider = any; + +export class CustomSolanaSigner extends DefaultSolanaSigner { + constructor(provider: SolanaExternalProvider) { + super(provider); + } + + async signMessage(msg: string): Promise { + const { signature } = await this.provider.signMessage(msg); + return base58.encode(signature); + } +} diff --git a/wallets/provider-coinbase/tsconfig.build.json b/wallets/provider-coinbase/tsconfig.build.json new file mode 100644 index 0000000000..d9181ce0cd --- /dev/null +++ b/wallets/provider-coinbase/tsconfig.build.json @@ -0,0 +1,11 @@ +{ + // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs + "extends": "../../tsconfig.libnext.json", + "include": ["src", "types", "../../global-wallets-env.d.ts"], + "compilerOptions": { + "outDir": "dist", + "rootDir": "./src", + "lib": ["dom", "esnext"] + // match output dir to input dir. e.g. dist/index instead of dist/src/index + } +} diff --git a/wallets/provider-coinbase/tsconfig.json b/wallets/provider-coinbase/tsconfig.json index 365489616a..a3a0b0f59d 100644 --- a/wallets/provider-coinbase/tsconfig.json +++ b/wallets/provider-coinbase/tsconfig.json @@ -1,35 +1 @@ -{ - // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs - "include": ["src", "types", "../../global-wallets-env.d.ts"], - "compilerOptions": { - "module": "esnext", - "lib": ["dom", "esnext"], - "importHelpers": true, - // output .d.ts declaration files for consumers - "declaration": true, - // output .js.map sourcemap files for consumers - "sourceMap": true, - // match output dir to input dir. e.g. dist/index instead of dist/src/index - "rootDir": "./src", - // stricter type-checking for stronger correctness. Recommended by TS - "strict": true, - // linter checks for common issues - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true, - // noUnused* overlap with @typescript-eslint/no-unused-vars, can disable if duplicative - "noUnusedLocals": true, - "noUnusedParameters": true, - // use Node's module resolution algorithm, instead of the legacy TS one - "moduleResolution": "node", - // transpile JSX to React.createElement - "jsx": "react", - // interop between ESM and CJS modules. Recommended by TS - "esModuleInterop": true, - // significant perf increase by skipping checking .d.ts files, particularly those in node_modules. Recommended by TS - "skipLibCheck": true, - // error out if import and file system have a casing mismatch. Recommended by TS - "forceConsistentCasingInFileNames": true, - // `tsdx build` ignores this option, but it is commonly used when type-checking separately with `tsc` - "noEmit": true, - } -} +{ "extends": "./tsconfig.build.json", "include": ["src", "tests"] } diff --git a/wallets/provider-cosmostation/CHANGELOG.md b/wallets/provider-cosmostation/CHANGELOG.md new file mode 100644 index 0000000000..792e473829 --- /dev/null +++ b/wallets/provider-cosmostation/CHANGELOG.md @@ -0,0 +1,159 @@ +# [0.41.0](https://github.com/rango-exchange/rango-client/compare/provider-cosmostation@0.40.0...provider-cosmostation@0.41.0) (2024-12-30) + + + +# [0.40.0](https://github.com/rango-exchange/rango-client/compare/provider-cosmostation@0.39.0...provider-cosmostation@0.40.0) (2024-11-27) + + + +# [0.39.0](https://github.com/rango-exchange/rango-client/compare/provider-cosmostation@0.38.1...provider-cosmostation@0.39.0) (2024-11-12) + + + +## [0.38.1](https://github.com/rango-exchange/rango-client/compare/provider-cosmostation@0.38.0...provider-cosmostation@0.38.1) (2024-11-06) + + + +# [0.38.0](https://github.com/rango-exchange/rango-client/compare/provider-cosmostation@0.37.0...provider-cosmostation@0.38.0) (2024-10-12) + + +### Bug Fixes + +* bump sdk and fix type issues ([d442208](https://github.com/rango-exchange/rango-client/commit/d4422083bf5dd27d5f509ce1db7f9560d05428c8)) + + +### Performance Improvements + +* lazy load signer packages ([7b88f18](https://github.com/rango-exchange/rango-client/commit/7b88f1834f7b29b4b81ab6c81a07bb88e8ccf55c)) + + + +# [0.37.0](https://github.com/rango-exchange/rango-client/compare/provider-cosmostation@0.36.0...provider-cosmostation@0.37.0) (2024-09-10) + + + +# [0.36.0](https://github.com/rango-exchange/rango-client/compare/provider-cosmostation@0.35.1...provider-cosmostation@0.36.0) (2024-08-11) + + + +## [0.35.1](https://github.com/rango-exchange/rango-client/compare/provider-cosmostation@0.35.0...provider-cosmostation@0.35.1) (2024-07-14) + + + +# [0.35.0](https://github.com/rango-exchange/rango-client/compare/provider-cosmostation@0.33.2...provider-cosmostation@0.35.0) (2024-07-09) + + + +# [0.34.0](https://github.com/rango-exchange/rango-client/compare/provider-cosmostation@0.33.2...provider-cosmostation@0.34.0) (2024-06-01) + + + +## [0.33.2](https://github.com/rango-exchange/rango-client/compare/provider-cosmostation@0.33.1...provider-cosmostation@0.33.2) (2024-05-26) + + + +## [0.33.1](https://github.com/rango-exchange/rango-client/compare/provider-cosmostation@0.33.0...provider-cosmostation@0.33.1) (2024-05-25) + + + +# [0.33.0](https://github.com/rango-exchange/rango-client/compare/provider-cosmostation@0.32.0...provider-cosmostation@0.33.0) (2024-05-14) + + + +# [0.32.0](https://github.com/rango-exchange/rango-client/compare/provider-cosmostation@0.31.0...provider-cosmostation@0.32.0) (2024-04-24) + + + +# [0.31.0](https://github.com/rango-exchange/rango-client/compare/provider-cosmostation@0.30.0...provider-cosmostation@0.31.0) (2024-04-23) + + + +# [0.30.0](https://github.com/rango-exchange/rango-client/compare/provider-cosmostation@0.29.0...provider-cosmostation@0.30.0) (2024-04-09) + + +### Bug Fixes + +* fix the connection problem that happens when another wallet takes over the requested one ([42df212](https://github.com/rango-exchange/rango-client/commit/42df2120aadd84c95045b0bf76844c19305fb59a)) + + + +# [0.29.0](https://github.com/rango-exchange/rango-client/compare/provider-cosmostation@0.28.0...provider-cosmostation@0.29.0) (2024-03-12) + + + +# [0.28.0](https://github.com/rango-exchange/rango-client/compare/provider-cosmostation@0.27.0...provider-cosmostation@0.28.0) (2024-02-20) + + + +# [0.27.0](https://github.com/rango-exchange/rango-client/compare/provider-cosmostation@0.26.0...provider-cosmostation@0.27.0) (2024-02-07) + + + +# [0.26.0](https://github.com/rango-exchange/rango-client/compare/provider-cosmostation@0.25.0...provider-cosmostation@0.26.0) (2024-01-22) + + +### Bug Fixes + +* cleanup wallets' subscriber when setProvider get null ([88d6a42](https://github.com/rango-exchange/rango-client/commit/88d6a423c49b34b3d9ff567e22df36c3b009bb76)) + + + +# [0.25.0](https://github.com/rango-exchange/rango-client/compare/provider-cosmostation@0.23.0...provider-cosmostation@0.25.0) (2023-12-24) + + +### Bug Fixes + +* fix HMR for widget and playground ([8524820](https://github.com/rango-exchange/rango-client/commit/8524820f10cf0b8921f3db0c4f620ff98daa4103)) + + + +# [0.14.0](https://github.com/rango-exchange/rango-client/compare/provider-cosmostation@0.13.0...provider-cosmostation@0.14.0) (2023-08-03) + + + +# [0.13.0](https://github.com/rango-exchange/rango-client/compare/provider-cosmostation@0.12.0...provider-cosmostation@0.13.0) (2023-08-01) + + + +# [0.9.0](https://github.com/rango-exchange/rango-client/compare/provider-cosmostation@0.8.0...provider-cosmostation@0.9.0) (2023-07-31) + + + +# [0.7.0](https://github.com/rango-exchange/rango-client/compare/provider-cosmostation@0.6.0...provider-cosmostation@0.7.0) (2023-07-11) + + + +# [0.6.0](https://github.com/rango-exchange/rango-client/compare/provider-cosmostation@0.5.0...provider-cosmostation@0.6.0) (2023-07-11) + + +### Reverts + +* Revert "support for rango-types cjs format" ([ed4e050](https://github.com/rango-exchange/rango-client/commit/ed4e050bfc0dcde7aeffa6b0d73b02080a5721eb)) + + + +# [0.5.0](https://github.com/rango-exchange/rango-client/compare/provider-cosmostation@0.4.0...provider-cosmostation@0.5.0) (2023-05-31) + + + +# [0.4.0](https://github.com/rango-exchange/rango-client/compare/provider-cosmostation@0.3.0...provider-cosmostation@0.4.0) (2023-05-31) + + + +# [0.3.0](https://github.com/rango-exchange/rango-client/compare/provider-cosmostation@0.2.0...provider-cosmostation@0.3.0) (2023-05-30) + + + +# [0.2.0](https://github.com/rango-exchange/rango-client/compare/provider-cosmostation@0.1.15...provider-cosmostation@0.2.0) (2023-05-30) + + + +## [0.1.14](https://github.com/rango-exchange/rango-client/compare/provider-cosmostation@0.1.13...provider-cosmostation@0.1.14) (2023-05-15) + + +### Bug Fixes + +* update rango-types and fix notification bugs ([993f185](https://github.com/rango-exchange/rango-client/commit/993f185e0b8c5e5e15a2c65ba2d85d1f9c8daa90)) + + + diff --git a/wallets/provider-cosmostation/package.json b/wallets/provider-cosmostation/package.json index 9f4ea37ea7..5b0671074a 100644 --- a/wallets/provider-cosmostation/package.json +++ b/wallets/provider-cosmostation/package.json @@ -1,50 +1,32 @@ { "name": "@rango-dev/provider-cosmostation", - "version": "0.1.12", + "version": "0.40.1-next.6", "license": "MIT", - "module": "dist/provider-cosmostation.esm.js", - "main": "dist/index.js", + "type": "module", + "source": "./src/index.ts", + "main": "./dist/index.js", + "exports": { + ".": "./dist/index.js" + }, "typings": "dist/index.d.ts", "files": [ "dist", "src" ], "scripts": { - "start": "tsdx watch", - "build": "tsdx build --tsconfig ./tsconfig.json", - "test": "tsdx test --passWithNoTests", - "lint": "tsdx lint", - "size": "size-limit", - "analyze": "size-limit --why" - }, - "husky": { - "hooks": { - "pre-commit": "tsdx lint" - } + "build": "node ../../scripts/build/command.mjs --path wallets/provider-cosmostation", + "ts-check": "tsc --declaration --emitDeclarationOnly -p ./tsconfig.json", + "clean": "rimraf dist", + "format": "prettier --write '{.,src}/**/*.{ts,tsx}'", + "lint": "eslint \"**/*.{ts,tsx}\" --ignore-path ../../.eslintignore" }, - "prettier": { - "printWidth": 80, - "semi": true, - "singleQuote": true, - "trailingComma": "es5" - }, - "size-limit": [ - { - "path": "dist/provider-cosmostation.cjs.production.min.js", - "limit": "10 KB" - }, - { - "path": "dist/provider-cosmostation.esm.js", - "limit": "10 KB" - } - ], "dependencies": { - "@rango-dev/signer-cosmos": "^0.1.11", - "@rango-dev/signer-evm": "^0.1.11", - "@rango-dev/wallets-shared": "^0.1.11", - "rango-types": "^0.1.28" + "@rango-dev/signer-cosmos": "^0.30.1", + "@rango-dev/signer-evm": "^0.32.0", + "@rango-dev/wallets-shared": "^0.40.1-next.6", + "rango-types": "^0.1.74" }, "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/wallets/provider-cosmostation/src/helpers.ts b/wallets/provider-cosmostation/src/helpers.ts index 9bedc7ae1e..1a6452bb08 100644 --- a/wallets/provider-cosmostation/src/helpers.ts +++ b/wallets/provider-cosmostation/src/helpers.ts @@ -1,18 +1,26 @@ -import { Network } from '@rango-dev/wallets-shared'; +import { Networks } from '@rango-dev/wallets-shared'; export function cosmostation() { const { cosmostation } = window; const instances = new Map(); - if (!cosmostation || !cosmostation.providers) return null; + if (!cosmostation || !cosmostation.providers) { + return null; + } const evmInstance = cosmostation.providers.metamask; - if (!!evmInstance) instances.set(Network.ETHEREUM, evmInstance); + if (evmInstance) { + instances.set(Networks.ETHEREUM, evmInstance); + } const cosmosInstance = cosmostation.providers.keplr; - if (!!cosmosInstance) instances.set(Network.COSMOS, cosmosInstance); + if (cosmosInstance) { + instances.set(Networks.COSMOS, cosmosInstance); + } - if (instances.size === 0) return null; + if (instances.size === 0) { + return null; + } return instances; } diff --git a/wallets/provider-cosmostation/src/index.ts b/wallets/provider-cosmostation/src/index.ts index 3f9ef5d915..137b004c19 100644 --- a/wallets/provider-cosmostation/src/index.ts +++ b/wallets/provider-cosmostation/src/index.ts @@ -1,41 +1,48 @@ -import { - Network, - WalletType, +import type { + CanEagerConnect, CanSwitchNetwork, Connect, ProviderConnectResult, Subscribe, + Suggest, SwitchNetwork, + WalletInfo, +} from '@rango-dev/wallets-shared'; +import type { BlockchainMeta, SignerFactory } from 'rango-types'; + +import { + canEagerlyConnectToEvm, canSwitchNetworkToEvm, chooseInstance, + getCosmosAccounts, getEvmAccounts, + Networks, subscribeToEvm, + suggestCosmosChain, switchNetworkForEvm, - getCosmosAccounts, - WalletInfo, + WalletTypes, } from '@rango-dev/wallets-shared'; -import { cosmostation as cosmostation_instance } from './helpers'; -import signer from './signer'; import { - SignerFactory, - BlockchainMeta, + cosmosBlockchains, evmBlockchains, - isEvmBlockchain, isCosmosBlockchain, - cosmosBlockchains, + isEvmBlockchain, } from 'rango-types'; -const WALLET = WalletType.COSMOSTATION; +import { cosmostation as cosmostation_instance } from './helpers.js'; +import signer from './signer.js'; + +const WALLET = WalletTypes.COSMOSTATION; export const config = { type: WALLET, - defaultNetwork: Network.ETHEREUM, + defaultNetwork: Networks.COSMOS, }; export const getInstance = cosmostation_instance; -export const connect: Connect = async ({ instance, meta }) => { - const ethInstance = chooseInstance(instance, meta, Network.ETHEREUM); - const cosmosInstance = chooseInstance(instance, meta, Network.COSMOS); +export const connect: Connect = async ({ instance, meta, network }) => { + const ethInstance = chooseInstance(instance, meta, Networks.ETHEREUM); + const cosmosInstance = chooseInstance(instance, meta, Networks.COSMOS); const results: ProviderConnectResult[] = []; @@ -46,13 +53,18 @@ export const connect: Connect = async ({ instance, meta }) => { if (cosmosInstance) { const cosmosBlockchainMeta = meta.filter(isCosmosBlockchain); + const requestedNetwork = network || Networks.COSMOS; + const comsmosResult = await getCosmosAccounts({ instance: cosmosInstance, meta: cosmosBlockchainMeta, - network: Network.COSMOS, + network: requestedNetwork, }); - if (Array.isArray(comsmosResult)) results.push(...comsmosResult); - else results.push(comsmosResult); + if (Array.isArray(comsmosResult)) { + results.push(...comsmosResult); + } else { + results.push(comsmosResult); + } } return results; @@ -71,10 +83,10 @@ export const subscribe: Subscribe = ({ connect, disconnect, }) => { - const ethInstance = instance.get(Network.ETHEREUM); + const ethInstance = instance.get(Networks.ETHEREUM); const EvmBlockchainMeta = meta.filter(isEvmBlockchain); - subscribeToEvm({ + const cleanupEvm = subscribeToEvm({ instance: ethInstance, state, updateChainId, @@ -84,13 +96,48 @@ export const subscribe: Subscribe = ({ disconnect, }); - window.cosmostation.cosmos.on('accountChanged', () => { + const handleCosmosAccountChanged = () => { disconnect(); connect(); - }); + }; + + window.cosmostation.cosmos.on?.('accountChanged', handleCosmosAccountChanged); + + return () => { + if (cleanupEvm) { + cleanupEvm(); + } + window.cosmostation.cosmos.off( + 'accountChanged', + handleCosmosAccountChanged + ); + }; +}; + +export const suggest: Suggest = async (options) => { + const { instance, meta, network } = options; + const cosmosInstance = chooseInstance(instance, meta, Networks.COSMOS); + + if (cosmosInstance) { + const cosmosBlockchainMeta = meta.filter(isCosmosBlockchain); + + await suggestCosmosChain({ + instance: cosmosInstance, + meta: cosmosBlockchainMeta, + network, + }); + } }; -export const getSigners: (provider: any) => SignerFactory = signer; +export const getSigners: (provider: any) => Promise = signer; + +export const canEagerConnect: CanEagerConnect = async ({ instance, meta }) => { + const evm_instance = chooseInstance(instance, meta, Networks.ETHEREUM); + if (evm_instance) { + return canEagerlyConnectToEvm({ instance: evm_instance, meta }); + } + return Promise.resolve(false); +}; export const getWalletInfo: (allBlockChains: BlockchainMeta[]) => WalletInfo = ( allBlockChains @@ -99,7 +146,7 @@ export const getWalletInfo: (allBlockChains: BlockchainMeta[]) => WalletInfo = ( const cosmos = cosmosBlockchains(allBlockChains); return { name: 'Cosmostation', - img: 'https://raw.githubusercontent.com/rango-exchange/rango-types/main/assets/icons/wallets/cosmostation.png', + img: 'https://raw.githubusercontent.com/rango-exchange/assets/main/wallets/cosmostation/icon.svg', installLink: { CHROME: 'https://chrome.google.com/webstore/detail/cosmostation/fpkhgmpbidmiogeglndfbkegfdlnajnf', diff --git a/wallets/provider-cosmostation/src/signer.ts b/wallets/provider-cosmostation/src/signer.ts index 98fb3e6f65..00f5313da3 100644 --- a/wallets/provider-cosmostation/src/signer.ts +++ b/wallets/provider-cosmostation/src/signer.ts @@ -1,12 +1,16 @@ -import { DefaultEvmSigner } from '@rango-dev/signer-evm'; -import { DefaultCosmosSigner } from '@rango-dev/signer-cosmos'; -import { Network, getNetworkInstance } from '@rango-dev/wallets-shared'; -import { SignerFactory, TransactionType as TxType } from 'rango-types'; +import type { SignerFactory } from 'rango-types'; -export default function getSigners(provider: any): SignerFactory { - const ethProvider = getNetworkInstance(provider, Network.ETHEREUM); - const cosmosProvider = getNetworkInstance(provider, Network.COSMOS); - const signers = new SignerFactory(); +import { getNetworkInstance, Networks } from '@rango-dev/wallets-shared'; +import { DefaultSignerFactory, TransactionType as TxType } from 'rango-types'; + +export default async function getSigners( + provider: any +): Promise { + const ethProvider = getNetworkInstance(provider, Networks.ETHEREUM); + const cosmosProvider = getNetworkInstance(provider, Networks.COSMOS); + const signers = new DefaultSignerFactory(); + const { DefaultEvmSigner } = await import('@rango-dev/signer-evm'); + const { DefaultCosmosSigner } = await import('@rango-dev/signer-cosmos'); signers.registerSigner(TxType.EVM, new DefaultEvmSigner(ethProvider)); signers.registerSigner( TxType.COSMOS, diff --git a/wallets/provider-cosmostation/tsconfig.build.json b/wallets/provider-cosmostation/tsconfig.build.json new file mode 100644 index 0000000000..d9181ce0cd --- /dev/null +++ b/wallets/provider-cosmostation/tsconfig.build.json @@ -0,0 +1,11 @@ +{ + // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs + "extends": "../../tsconfig.libnext.json", + "include": ["src", "types", "../../global-wallets-env.d.ts"], + "compilerOptions": { + "outDir": "dist", + "rootDir": "./src", + "lib": ["dom", "esnext"] + // match output dir to input dir. e.g. dist/index instead of dist/src/index + } +} diff --git a/wallets/provider-cosmostation/tsconfig.json b/wallets/provider-cosmostation/tsconfig.json index 365489616a..a3a0b0f59d 100644 --- a/wallets/provider-cosmostation/tsconfig.json +++ b/wallets/provider-cosmostation/tsconfig.json @@ -1,35 +1 @@ -{ - // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs - "include": ["src", "types", "../../global-wallets-env.d.ts"], - "compilerOptions": { - "module": "esnext", - "lib": ["dom", "esnext"], - "importHelpers": true, - // output .d.ts declaration files for consumers - "declaration": true, - // output .js.map sourcemap files for consumers - "sourceMap": true, - // match output dir to input dir. e.g. dist/index instead of dist/src/index - "rootDir": "./src", - // stricter type-checking for stronger correctness. Recommended by TS - "strict": true, - // linter checks for common issues - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true, - // noUnused* overlap with @typescript-eslint/no-unused-vars, can disable if duplicative - "noUnusedLocals": true, - "noUnusedParameters": true, - // use Node's module resolution algorithm, instead of the legacy TS one - "moduleResolution": "node", - // transpile JSX to React.createElement - "jsx": "react", - // interop between ESM and CJS modules. Recommended by TS - "esModuleInterop": true, - // significant perf increase by skipping checking .d.ts files, particularly those in node_modules. Recommended by TS - "skipLibCheck": true, - // error out if import and file system have a casing mismatch. Recommended by TS - "forceConsistentCasingInFileNames": true, - // `tsdx build` ignores this option, but it is commonly used when type-checking separately with `tsc` - "noEmit": true, - } -} +{ "extends": "./tsconfig.build.json", "include": ["src", "tests"] } diff --git a/wallets/provider-default/CHANGELOG.md b/wallets/provider-default/CHANGELOG.md new file mode 100644 index 0000000000..8d942e1b32 --- /dev/null +++ b/wallets/provider-default/CHANGELOG.md @@ -0,0 +1,91 @@ +# [0.38.0](https://github.com/rango-exchange/rango-client/compare/provider-default@0.37.0...provider-default@0.38.0) (2024-12-30) + + + +# [0.37.0](https://github.com/rango-exchange/rango-client/compare/provider-default@0.36.0...provider-default@0.37.0) (2024-11-27) + + + +# [0.36.0](https://github.com/rango-exchange/rango-client/compare/provider-default@0.35.0...provider-default@0.36.0) (2024-11-12) + + + +# [0.35.0](https://github.com/rango-exchange/rango-client/compare/provider-default@0.34.0...provider-default@0.35.0) (2024-10-12) + + +### Bug Fixes + +* bump sdk and fix type issues ([d442208](https://github.com/rango-exchange/rango-client/commit/d4422083bf5dd27d5f509ce1db7f9560d05428c8)) + + +### Performance Improvements + +* lazy load signer packages ([7b88f18](https://github.com/rango-exchange/rango-client/commit/7b88f1834f7b29b4b81ab6c81a07bb88e8ccf55c)) + + + +# [0.34.0](https://github.com/rango-exchange/rango-client/compare/provider-default@0.33.0...provider-default@0.34.0) (2024-09-10) + + + +# [0.33.0](https://github.com/rango-exchange/rango-client/compare/provider-default@0.32.1...provider-default@0.33.0) (2024-08-11) + + + +## [0.32.1](https://github.com/rango-exchange/rango-client/compare/provider-default@0.32.0...provider-default@0.32.1) (2024-07-14) + + + +# [0.32.0](https://github.com/rango-exchange/rango-client/compare/provider-default@0.30.2...provider-default@0.32.0) (2024-07-09) + + + +# [0.31.0](https://github.com/rango-exchange/rango-client/compare/provider-default@0.30.2...provider-default@0.31.0) (2024-06-01) + + + +## [0.30.2](https://github.com/rango-exchange/rango-client/compare/provider-default@0.30.1...provider-default@0.30.2) (2024-05-26) + + + +## [0.30.1](https://github.com/rango-exchange/rango-client/compare/provider-default@0.30.0...provider-default@0.30.1) (2024-05-25) + + + +# [0.30.0](https://github.com/rango-exchange/rango-client/compare/provider-default@0.29.0...provider-default@0.30.0) (2024-05-14) + + + +# [0.29.0](https://github.com/rango-exchange/rango-client/compare/provider-default@0.28.0...provider-default@0.29.0) (2024-04-24) + + + +# [0.28.0](https://github.com/rango-exchange/rango-client/compare/provider-default@0.27.0...provider-default@0.28.0) (2024-04-23) + + + +# [0.27.0](https://github.com/rango-exchange/rango-client/compare/provider-default@0.26.0...provider-default@0.27.0) (2024-04-09) + + + +# [0.26.0](https://github.com/rango-exchange/rango-client/compare/provider-default@0.25.0...provider-default@0.26.0) (2024-03-12) + + + +# [0.25.0](https://github.com/rango-exchange/rango-client/compare/provider-default@0.24.0...provider-default@0.25.0) (2024-02-20) + + + +# [0.24.0](https://github.com/rango-exchange/rango-client/compare/provider-default@0.23.0...provider-default@0.24.0) (2024-02-07) + + + +# 0.23.0 (2024-01-22) + + +### Features + +* add default injected wallet ([238977c](https://github.com/rango-exchange/rango-client/commit/238977c0e3cd09feba9f2557f1b099b9af3afb0d)) + + + diff --git a/wallets/provider-default/package.json b/wallets/provider-default/package.json new file mode 100644 index 0000000000..5992ecdea5 --- /dev/null +++ b/wallets/provider-default/package.json @@ -0,0 +1,31 @@ +{ + "name": "@rango-dev/provider-default", + "version": "0.37.1-next.6", + "license": "MIT", + "type": "module", + "source": "./src/index.ts", + "main": "./dist/index.js", + "exports": { + ".": "./dist/index.js" + }, + "typings": "dist/index.d.ts", + "files": [ + "dist", + "src" + ], + "scripts": { + "build": "node ../../scripts/build/command.mjs --path wallets/provider-default", + "ts-check": "tsc --declaration --emitDeclarationOnly -p ./tsconfig.json", + "clean": "rimraf dist", + "format": "prettier --write '{.,src}/**/*.{ts,tsx}'", + "lint": "eslint \"**/*.{ts,tsx}\" --ignore-path ../../.eslintignore" + }, + "dependencies": { + "@rango-dev/signer-evm": "^0.32.0", + "@rango-dev/wallets-shared": "^0.40.1-next.6", + "rango-types": "^0.1.74" + }, + "publishConfig": { + "access": "public" + } +} \ No newline at end of file diff --git a/wallets/provider-default/readme.md b/wallets/provider-default/readme.md new file mode 100644 index 0000000000..9bfcba6a39 --- /dev/null +++ b/wallets/provider-default/readme.md @@ -0,0 +1 @@ +# @rango-dev/provider-default diff --git a/wallets/provider-default/src/helpers.ts b/wallets/provider-default/src/helpers.ts new file mode 100644 index 0000000000..593fa5a51b --- /dev/null +++ b/wallets/provider-default/src/helpers.ts @@ -0,0 +1,4 @@ +export function defaultInjected() { + const { ethereum } = window; + return ethereum ?? null; +} diff --git a/wallets/provider-default/src/index.ts b/wallets/provider-default/src/index.ts new file mode 100644 index 0000000000..a933b0098f --- /dev/null +++ b/wallets/provider-default/src/index.ts @@ -0,0 +1,69 @@ +import type { + CanEagerConnect, + CanSwitchNetwork, + Connect, + Subscribe, + SwitchNetwork, + WalletInfo, +} from '@rango-dev/wallets-shared'; +import type { BlockchainMeta, SignerFactory } from 'rango-types'; + +import { + canEagerlyConnectToEvm, + canSwitchNetworkToEvm, + getEvmAccounts, + subscribeToEvm, + switchNetworkForEvm, + WalletTypes, +} from '@rango-dev/wallets-shared'; +import { evmBlockchains } from 'rango-types'; + +import { defaultInjected } from './helpers.js'; +import signer from './signer.js'; + +const WALLET = WalletTypes.DEFAULT; + +export const config = { + type: WALLET, +}; + +export const getInstance = defaultInjected; +export const connect: Connect = async ({ instance }) => { + /* + * Note: We need to get `chainId` here, because for the first time + * after opening the browser, wallet is locked, and don't give us accounts and chainId + * on `check` phase, so `network` will be null. For this case we need to get chainId + * whenever we are requesting accounts. + */ + const { accounts, chainId } = await getEvmAccounts(instance); + + return { + accounts, + chainId, + }; +}; + +export const subscribe: Subscribe = subscribeToEvm; + +export const switchNetwork: SwitchNetwork = switchNetworkForEvm; + +export const canSwitchNetworkTo: CanSwitchNetwork = canSwitchNetworkToEvm; + +export const getSigners: (provider: any) => Promise = signer; + +export const canEagerConnect: CanEagerConnect = canEagerlyConnectToEvm; + +export const getWalletInfo: (allBlockChains: BlockchainMeta[]) => WalletInfo = ( + allBlockChains +) => { + const evms = evmBlockchains(allBlockChains); + return { + name: 'Default', + img: 'https://raw.githubusercontent.com/rango-exchange/assets/main/wallets/default/icon.svg', + installLink: { + DEFAULT: 'https://metamask.io/download/', + }, + color: '#dac7ae', + supportedChains: evms, + }; +}; diff --git a/wallets/provider-default/src/signer.ts b/wallets/provider-default/src/signer.ts new file mode 100644 index 0000000000..f7dbf93750 --- /dev/null +++ b/wallets/provider-default/src/signer.ts @@ -0,0 +1,12 @@ +import type { SignerFactory } from 'rango-types'; + +import { DefaultSignerFactory, TransactionType as TxType } from 'rango-types'; + +export default async function getSigners( + provider: any +): Promise { + const signers = new DefaultSignerFactory(); + const { DefaultEvmSigner } = await import('@rango-dev/signer-evm'); + signers.registerSigner(TxType.EVM, new DefaultEvmSigner(provider)); + return signers; +} diff --git a/wallets/provider-default/tsconfig.build.json b/wallets/provider-default/tsconfig.build.json new file mode 100644 index 0000000000..d9181ce0cd --- /dev/null +++ b/wallets/provider-default/tsconfig.build.json @@ -0,0 +1,11 @@ +{ + // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs + "extends": "../../tsconfig.libnext.json", + "include": ["src", "types", "../../global-wallets-env.d.ts"], + "compilerOptions": { + "outDir": "dist", + "rootDir": "./src", + "lib": ["dom", "esnext"] + // match output dir to input dir. e.g. dist/index instead of dist/src/index + } +} diff --git a/wallets/provider-default/tsconfig.json b/wallets/provider-default/tsconfig.json new file mode 100644 index 0000000000..a3a0b0f59d --- /dev/null +++ b/wallets/provider-default/tsconfig.json @@ -0,0 +1 @@ +{ "extends": "./tsconfig.build.json", "include": ["src", "tests"] } diff --git a/wallets/provider-enkrypt/CHANGELOG.md b/wallets/provider-enkrypt/CHANGELOG.md new file mode 100644 index 0000000000..92640bc39e --- /dev/null +++ b/wallets/provider-enkrypt/CHANGELOG.md @@ -0,0 +1,140 @@ +# [0.41.0](https://github.com/rango-exchange/rango-client/compare/provider-enkrypt@0.40.0...provider-enkrypt@0.41.0) (2024-12-30) + + + +# [0.40.0](https://github.com/rango-exchange/rango-client/compare/provider-enkrypt@0.39.0...provider-enkrypt@0.40.0) (2024-11-27) + + + +# [0.39.0](https://github.com/rango-exchange/rango-client/compare/provider-enkrypt@0.38.0...provider-enkrypt@0.39.0) (2024-11-12) + + + +# [0.38.0](https://github.com/rango-exchange/rango-client/compare/provider-enkrypt@0.37.0...provider-enkrypt@0.38.0) (2024-10-12) + + +### Bug Fixes + +* bump sdk and fix type issues ([d442208](https://github.com/rango-exchange/rango-client/commit/d4422083bf5dd27d5f509ce1db7f9560d05428c8)) + + +### Performance Improvements + +* lazy load signer packages ([7b88f18](https://github.com/rango-exchange/rango-client/commit/7b88f1834f7b29b4b81ab6c81a07bb88e8ccf55c)) + + + +# [0.37.0](https://github.com/rango-exchange/rango-client/compare/provider-enkrypt@0.36.0...provider-enkrypt@0.37.0) (2024-09-10) + + + +# [0.36.0](https://github.com/rango-exchange/rango-client/compare/provider-enkrypt@0.35.1...provider-enkrypt@0.36.0) (2024-08-11) + + + +## [0.35.1](https://github.com/rango-exchange/rango-client/compare/provider-enkrypt@0.35.0...provider-enkrypt@0.35.1) (2024-07-14) + + + +# [0.35.0](https://github.com/rango-exchange/rango-client/compare/provider-enkrypt@0.33.2...provider-enkrypt@0.35.0) (2024-07-09) + + + +# [0.34.0](https://github.com/rango-exchange/rango-client/compare/provider-enkrypt@0.33.2...provider-enkrypt@0.34.0) (2024-06-01) + + + +## [0.33.2](https://github.com/rango-exchange/rango-client/compare/provider-enkrypt@0.33.1...provider-enkrypt@0.33.2) (2024-05-26) + + + +## [0.33.1](https://github.com/rango-exchange/rango-client/compare/provider-enkrypt@0.33.0...provider-enkrypt@0.33.1) (2024-05-25) + + + +# [0.33.0](https://github.com/rango-exchange/rango-client/compare/provider-enkrypt@0.32.0...provider-enkrypt@0.33.0) (2024-05-14) + + + +# [0.32.0](https://github.com/rango-exchange/rango-client/compare/provider-enkrypt@0.31.0...provider-enkrypt@0.32.0) (2024-04-24) + + + +# [0.31.0](https://github.com/rango-exchange/rango-client/compare/provider-enkrypt@0.30.0...provider-enkrypt@0.31.0) (2024-04-23) + + + +# [0.30.0](https://github.com/rango-exchange/rango-client/compare/provider-enkrypt@0.29.0...provider-enkrypt@0.30.0) (2024-04-09) + + + +# [0.29.0](https://github.com/rango-exchange/rango-client/compare/provider-enkrypt@0.28.0...provider-enkrypt@0.29.0) (2024-03-12) + + + +# [0.28.0](https://github.com/rango-exchange/rango-client/compare/provider-enkrypt@0.27.0...provider-enkrypt@0.28.0) (2024-02-20) + + + +# [0.27.0](https://github.com/rango-exchange/rango-client/compare/provider-enkrypt@0.26.0...provider-enkrypt@0.27.0) (2024-02-07) + + + +# [0.26.0](https://github.com/rango-exchange/rango-client/compare/provider-enkrypt@0.25.0...provider-enkrypt@0.26.0) (2024-01-22) + + + +# [0.25.0](https://github.com/rango-exchange/rango-client/compare/provider-enkrypt@0.23.0...provider-enkrypt@0.25.0) (2023-12-24) + + +### Bug Fixes + +* fix HMR for widget and playground ([8524820](https://github.com/rango-exchange/rango-client/commit/8524820f10cf0b8921f3db0c4f620ff98daa4103)) + + + +# [0.14.0](https://github.com/rango-exchange/rango-client/compare/provider-enkrypt@0.13.0...provider-enkrypt@0.14.0) (2023-08-03) + + + +# [0.13.0](https://github.com/rango-exchange/rango-client/compare/provider-enkrypt@0.12.0...provider-enkrypt@0.13.0) (2023-08-01) + + + +# [0.9.0](https://github.com/rango-exchange/rango-client/compare/provider-enkrypt@0.8.0...provider-enkrypt@0.9.0) (2023-07-31) + + + +# [0.7.0](https://github.com/rango-exchange/rango-client/compare/provider-enkrypt@0.6.0...provider-enkrypt@0.7.0) (2023-07-11) + + + +# [0.6.0](https://github.com/rango-exchange/rango-client/compare/provider-enkrypt@0.5.0...provider-enkrypt@0.6.0) (2023-07-11) + + +### Reverts + +* Revert "support for rango-types cjs format" ([ed4e050](https://github.com/rango-exchange/rango-client/commit/ed4e050bfc0dcde7aeffa6b0d73b02080a5721eb)) + + + +# [0.5.0](https://github.com/rango-exchange/rango-client/compare/provider-enkrypt@0.4.0...provider-enkrypt@0.5.0) (2023-05-31) + + + +# [0.4.0](https://github.com/rango-exchange/rango-client/compare/provider-enkrypt@0.3.0...provider-enkrypt@0.4.0) (2023-05-31) + + + +# [0.3.0](https://github.com/rango-exchange/rango-client/compare/provider-enkrypt@0.2.0...provider-enkrypt@0.3.0) (2023-05-30) + + + +# [0.2.0](https://github.com/rango-exchange/rango-client/compare/provider-enkrypt@0.1.2...provider-enkrypt@0.2.0) (2023-05-30) + + + +## 0.1.1 (2023-05-15) + + + diff --git a/wallets/provider-enkrypt/package.json b/wallets/provider-enkrypt/package.json new file mode 100644 index 0000000000..5093785384 --- /dev/null +++ b/wallets/provider-enkrypt/package.json @@ -0,0 +1,31 @@ +{ + "name": "@rango-dev/provider-enkrypt", + "version": "0.40.1-next.6", + "license": "MIT", + "type": "module", + "source": "./src/index.ts", + "main": "./dist/index.js", + "exports": { + ".": "./dist/index.js" + }, + "typings": "dist/index.d.ts", + "files": [ + "dist", + "src" + ], + "scripts": { + "build": "node ../../scripts/build/command.mjs --path wallets/provider-enkrypt", + "ts-check": "tsc --declaration --emitDeclarationOnly -p ./tsconfig.json", + "clean": "rimraf dist", + "format": "prettier --write '{.,src}/**/*.{ts,tsx}'", + "lint": "eslint \"**/*.{ts,tsx}\" --ignore-path ../../.eslintignore" + }, + "dependencies": { + "@rango-dev/signer-evm": "^0.32.0", + "@rango-dev/wallets-shared": "^0.40.1-next.6", + "rango-types": "^0.1.74" + }, + "publishConfig": { + "access": "public" + } +} \ No newline at end of file diff --git a/wallets/provider-enkrypt/src/helpers.ts b/wallets/provider-enkrypt/src/helpers.ts new file mode 100644 index 0000000000..d49a1f12ce --- /dev/null +++ b/wallets/provider-enkrypt/src/helpers.ts @@ -0,0 +1,6 @@ +export function enkrypt() { + const { enkrypt } = window; + const ethereum = enkrypt?.providers?.ethereum; + if (!ethereum) return null; + return ethereum; +} diff --git a/wallets/provider-enkrypt/src/index.ts b/wallets/provider-enkrypt/src/index.ts new file mode 100644 index 0000000000..e62950a8c2 --- /dev/null +++ b/wallets/provider-enkrypt/src/index.ts @@ -0,0 +1,76 @@ +import type { + CanEagerConnect, + CanSwitchNetwork, + Connect, + Subscribe, + SwitchNetwork, + WalletInfo, +} from '@rango-dev/wallets-shared'; +import type { BlockchainMeta, SignerFactory } from 'rango-types'; + +import { + canEagerlyConnectToEvm, + canSwitchNetworkToEvm, + getEvmAccounts, + subscribeToEvm, + switchNetworkForEvm, + WalletTypes, +} from '@rango-dev/wallets-shared'; +import { evmBlockchains } from 'rango-types'; + +import { enkrypt as enkrypt_instance } from './helpers.js'; +import signer from './signer.js'; + +export const getInstance = enkrypt_instance; + +const WALLET = WalletTypes.ENKRYPT; + +export const config = { + type: WALLET, +}; + +export const connect: Connect = async ({ instance }) => { + const result = await getEvmAccounts(instance); + const { chainId } = result; + let { accounts } = result; + if (accounts.length > 1) { + accounts = [instance.selectedAddress]; + } + + return { + accounts, + chainId, + }; +}; + +export const subscribe: Subscribe = subscribeToEvm; + +export const switchNetwork: SwitchNetwork = switchNetworkForEvm; + +export const canSwitchNetworkTo: CanSwitchNetwork = canSwitchNetworkToEvm; + +export const getSigners: (provider: any) => Promise = signer; + +export const canEagerConnect: CanEagerConnect = canEagerlyConnectToEvm; + +export const getWalletInfo: (allBlockChains: BlockchainMeta[]) => WalletInfo = ( + allBlockChains +) => { + const evms = evmBlockchains(allBlockChains); + return { + name: 'Enkrypt', + img: 'https://raw.githubusercontent.com/rango-exchange/assets/main/wallets/enkrypt/icon.svg', + installLink: { + CHROME: + 'https://chrome.google.com/webstore/detail/enkrypt/kkpllkodjeloidieedojogacfhpaihoh', + FIREFOX: 'https://addons.mozilla.org/en-US/firefox/addon/enkrypt/', + BRAVE: + 'https://chrome.google.com/webstore/detail/enkrypt/kkpllkodjeloidieedojogacfhpaihoh', + EDGE: 'https://microsoftedge.microsoft.com/addons/detail/enkrypt-ethereum-polkad/gfenajajnjjmmdojhdjmnngomkhlnfjl', + + DEFAULT: 'https://www.enkrypt.com/', + }, + color: '#fff', + supportedChains: evms, + }; +}; diff --git a/wallets/provider-enkrypt/src/signer.ts b/wallets/provider-enkrypt/src/signer.ts new file mode 100644 index 0000000000..f7dbf93750 --- /dev/null +++ b/wallets/provider-enkrypt/src/signer.ts @@ -0,0 +1,12 @@ +import type { SignerFactory } from 'rango-types'; + +import { DefaultSignerFactory, TransactionType as TxType } from 'rango-types'; + +export default async function getSigners( + provider: any +): Promise { + const signers = new DefaultSignerFactory(); + const { DefaultEvmSigner } = await import('@rango-dev/signer-evm'); + signers.registerSigner(TxType.EVM, new DefaultEvmSigner(provider)); + return signers; +} diff --git a/wallets/provider-enkrypt/tsconfig.build.json b/wallets/provider-enkrypt/tsconfig.build.json new file mode 100644 index 0000000000..d9181ce0cd --- /dev/null +++ b/wallets/provider-enkrypt/tsconfig.build.json @@ -0,0 +1,11 @@ +{ + // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs + "extends": "../../tsconfig.libnext.json", + "include": ["src", "types", "../../global-wallets-env.d.ts"], + "compilerOptions": { + "outDir": "dist", + "rootDir": "./src", + "lib": ["dom", "esnext"] + // match output dir to input dir. e.g. dist/index instead of dist/src/index + } +} diff --git a/wallets/provider-enkrypt/tsconfig.json b/wallets/provider-enkrypt/tsconfig.json new file mode 100644 index 0000000000..a3a0b0f59d --- /dev/null +++ b/wallets/provider-enkrypt/tsconfig.json @@ -0,0 +1 @@ +{ "extends": "./tsconfig.build.json", "include": ["src", "tests"] } diff --git a/wallets/provider-exodus/CHANGELOG.md b/wallets/provider-exodus/CHANGELOG.md new file mode 100644 index 0000000000..49f8d560f9 --- /dev/null +++ b/wallets/provider-exodus/CHANGELOG.md @@ -0,0 +1,157 @@ +# [0.41.0](https://github.com/rango-exchange/rango-client/compare/provider-exodus@0.40.0...provider-exodus@0.41.0) (2024-12-30) + + + +# [0.40.0](https://github.com/rango-exchange/rango-client/compare/provider-exodus@0.39.0...provider-exodus@0.40.0) (2024-11-27) + + +### Features + +* add ton connect provider ([2a2dbb7](https://github.com/rango-exchange/rango-client/commit/2a2dbb79022263f19446ced49d298e04d63f927f)) + + + +# [0.39.0](https://github.com/rango-exchange/rango-client/compare/provider-exodus@0.38.0...provider-exodus@0.39.0) (2024-11-12) + + + +# [0.38.0](https://github.com/rango-exchange/rango-client/compare/provider-exodus@0.37.0...provider-exodus@0.38.0) (2024-10-12) + + +### Bug Fixes + +* bump sdk and fix type issues ([d442208](https://github.com/rango-exchange/rango-client/commit/d4422083bf5dd27d5f509ce1db7f9560d05428c8)) +* resolve issues with the sign message method for certain solana providers ([cbe83a3](https://github.com/rango-exchange/rango-client/commit/cbe83a3da8b48560b206fc2a7fa7cf062cdeaa23)) + + +### Performance Improvements + +* lazy load signer packages ([7b88f18](https://github.com/rango-exchange/rango-client/commit/7b88f1834f7b29b4b81ab6c81a07bb88e8ccf55c)) + + + +# [0.37.0](https://github.com/rango-exchange/rango-client/compare/provider-exodus@0.36.0...provider-exodus@0.37.0) (2024-09-10) + + + +# [0.36.0](https://github.com/rango-exchange/rango-client/compare/provider-exodus@0.35.1...provider-exodus@0.36.0) (2024-08-11) + + + +## [0.35.1](https://github.com/rango-exchange/rango-client/compare/provider-exodus@0.35.0...provider-exodus@0.35.1) (2024-07-14) + + + +# [0.35.0](https://github.com/rango-exchange/rango-client/compare/provider-exodus@0.33.2...provider-exodus@0.35.0) (2024-07-09) + + + +# [0.34.0](https://github.com/rango-exchange/rango-client/compare/provider-exodus@0.33.2...provider-exodus@0.34.0) (2024-06-01) + + + +## [0.33.2](https://github.com/rango-exchange/rango-client/compare/provider-exodus@0.33.1...provider-exodus@0.33.2) (2024-05-26) + + + +## [0.33.1](https://github.com/rango-exchange/rango-client/compare/provider-exodus@0.33.0...provider-exodus@0.33.1) (2024-05-25) + + + +# [0.33.0](https://github.com/rango-exchange/rango-client/compare/provider-exodus@0.32.0...provider-exodus@0.33.0) (2024-05-14) + + + +# [0.32.0](https://github.com/rango-exchange/rango-client/compare/provider-exodus@0.31.0...provider-exodus@0.32.0) (2024-04-24) + + + +# [0.31.0](https://github.com/rango-exchange/rango-client/compare/provider-exodus@0.30.0...provider-exodus@0.31.0) (2024-04-23) + + + +# [0.30.0](https://github.com/rango-exchange/rango-client/compare/provider-exodus@0.29.0...provider-exodus@0.30.0) (2024-04-09) + + +### Bug Fixes + +* fix the connection problem that happens when another wallet takes over the requested one ([42df212](https://github.com/rango-exchange/rango-client/commit/42df2120aadd84c95045b0bf76844c19305fb59a)) + + + +# [0.29.0](https://github.com/rango-exchange/rango-client/compare/provider-exodus@0.28.0...provider-exodus@0.29.0) (2024-03-12) + + + +# [0.28.0](https://github.com/rango-exchange/rango-client/compare/provider-exodus@0.27.0...provider-exodus@0.28.0) (2024-02-20) + + + +# [0.27.0](https://github.com/rango-exchange/rango-client/compare/provider-exodus@0.26.0...provider-exodus@0.27.0) (2024-02-07) + + + +# [0.26.0](https://github.com/rango-exchange/rango-client/compare/provider-exodus@0.25.0...provider-exodus@0.26.0) (2024-01-22) + + + +# [0.25.0](https://github.com/rango-exchange/rango-client/compare/provider-exodus@0.23.0...provider-exodus@0.25.0) (2023-12-24) + + +### Bug Fixes + +* fix HMR for widget and playground ([8524820](https://github.com/rango-exchange/rango-client/commit/8524820f10cf0b8921f3db0c4f620ff98daa4103)) + + + +# [0.14.0](https://github.com/rango-exchange/rango-client/compare/provider-exodus@0.13.0...provider-exodus@0.14.0) (2023-08-03) + + + +# [0.13.0](https://github.com/rango-exchange/rango-client/compare/provider-exodus@0.12.0...provider-exodus@0.13.0) (2023-08-01) + + + +# [0.9.0](https://github.com/rango-exchange/rango-client/compare/provider-exodus@0.8.0...provider-exodus@0.9.0) (2023-07-31) + + + +# [0.7.0](https://github.com/rango-exchange/rango-client/compare/provider-exodus@0.6.0...provider-exodus@0.7.0) (2023-07-11) + + + +# [0.6.0](https://github.com/rango-exchange/rango-client/compare/provider-exodus@0.5.0...provider-exodus@0.6.0) (2023-07-11) + + +### Reverts + +* Revert "support for rango-types cjs format" ([ed4e050](https://github.com/rango-exchange/rango-client/commit/ed4e050bfc0dcde7aeffa6b0d73b02080a5721eb)) +* Revert "support for rango-types cjs format" ([4f5f55f](https://github.com/rango-exchange/rango-client/commit/4f5f55f96e8daa329588b932b19c291c30f339c4)) + + + +# [0.5.0](https://github.com/rango-exchange/rango-client/compare/provider-exodus@0.4.0...provider-exodus@0.5.0) (2023-05-31) + + + +# [0.4.0](https://github.com/rango-exchange/rango-client/compare/provider-exodus@0.3.0...provider-exodus@0.4.0) (2023-05-31) + + + +# [0.3.0](https://github.com/rango-exchange/rango-client/compare/provider-exodus@0.2.0...provider-exodus@0.3.0) (2023-05-30) + + + +# [0.2.0](https://github.com/rango-exchange/rango-client/compare/provider-exodus@0.1.15...provider-exodus@0.2.0) (2023-05-30) + + + +## [0.1.14](https://github.com/rango-exchange/rango-client/compare/provider-exodus@0.1.13...provider-exodus@0.1.14) (2023-05-15) + + +### Bug Fixes + +* update rango-types and fix notification bugs ([993f185](https://github.com/rango-exchange/rango-client/commit/993f185e0b8c5e5e15a2c65ba2d85d1f9c8daa90)) + + + diff --git a/wallets/provider-exodus/package.json b/wallets/provider-exodus/package.json index 74cbe0d064..f540810bd1 100644 --- a/wallets/provider-exodus/package.json +++ b/wallets/provider-exodus/package.json @@ -1,50 +1,33 @@ { "name": "@rango-dev/provider-exodus", - "version": "0.1.12", + "version": "0.40.1-next.6", "license": "MIT", - "module": "dist/provider-exodus.esm.js", - "main": "dist/index.js", + "type": "module", + "source": "./src/index.ts", + "main": "./dist/index.js", + "exports": { + ".": "./dist/index.js" + }, "typings": "dist/index.d.ts", "files": [ "dist", "src" ], "scripts": { - "start": "tsdx watch", - "build": "tsdx build --tsconfig ./tsconfig.json", - "test": "tsdx test --passWithNoTests", - "lint": "tsdx lint", - "size": "size-limit", - "analyze": "size-limit --why" - }, - "husky": { - "hooks": { - "pre-commit": "tsdx lint" - } + "build": "node ../../scripts/build/command.mjs --path wallets/provider-exodus", + "ts-check": "tsc --declaration --emitDeclarationOnly -p ./tsconfig.json", + "clean": "rimraf dist", + "format": "prettier --write '{.,src}/**/*.{ts,tsx}'", + "lint": "eslint \"**/*.{ts,tsx}\" --ignore-path ../../.eslintignore" }, - "prettier": { - "printWidth": 80, - "semi": true, - "singleQuote": true, - "trailingComma": "es5" - }, - "size-limit": [ - { - "path": "dist/provider-exodus.cjs.production.min.js", - "limit": "10 KB" - }, - { - "path": "dist/provider-exodus.esm.js", - "limit": "10 KB" - } - ], "dependencies": { - "@rango-dev/signer-evm": "^0.1.11", - "@rango-dev/signer-solana": "^0.1.11", - "@rango-dev/wallets-shared": "^0.1.11", - "rango-types": "^0.1.28" + "@rango-dev/signer-evm": "^0.32.0", + "@rango-dev/signer-solana": "^0.35.1-next.0", + "@rango-dev/wallets-shared": "^0.40.1-next.6", + "bs58": "^5.0.0", + "rango-types": "^0.1.74" }, "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/wallets/provider-exodus/src/helpers.ts b/wallets/provider-exodus/src/helpers.ts index 46c617c711..01c3faaf03 100644 --- a/wallets/provider-exodus/src/helpers.ts +++ b/wallets/provider-exodus/src/helpers.ts @@ -1,29 +1,37 @@ -import { Network, ProviderConnectResult } from '@rango-dev/wallets-shared'; +import type { ProviderConnectResult } from '@rango-dev/wallets-shared'; + +import { Networks } from '@rango-dev/wallets-shared'; export function exodus_instances() { const { exodus } = window; - if (!exodus) return null; + if (!exodus) { + return null; + } const instances = new Map(); - if (exodus.ethereum) instances.set(Network.ETHEREUM, exodus.ethereum); - if (exodus.solana) instances.set(Network.SOLANA, exodus.solana); + if (exodus.ethereum) { + instances.set(Networks.ETHEREUM, exodus.ethereum); + } + if (exodus.solana) { + instances.set(Networks.SOLANA, exodus.solana); + } return instances; } export async function getSolanaAccounts( instance: any ): Promise { - const solanaInstance = await instance.get(Network.SOLANA); + const solanaInstance = await instance.get(Networks.SOLANA); const results: ProviderConnectResult[] = []; - if (!!solanaInstance) { + if (solanaInstance) { const solanaResponse = await solanaInstance.connect(); const account = solanaResponse.publicKey.toString(); results.push({ accounts: account ? [account] : [], - chainId: Network.SOLANA, + chainId: Networks.SOLANA, }); } @@ -31,10 +39,9 @@ export async function getSolanaAccounts( } export const EXODUS_WALLET_SUPPORTED_CHAINS = [ - Network.SOLANA, - Network.ETHEREUM, - Network.BSC, - Network.POLYGON, - Network.AVAX_CCHAIN, - Network.BINANCE, + Networks.SOLANA, + Networks.ETHEREUM, + Networks.BSC, + Networks.POLYGON, + Networks.AVAX_CCHAIN, ]; diff --git a/wallets/provider-exodus/src/index.ts b/wallets/provider-exodus/src/index.ts index 842ef9abb1..d00676a2c4 100644 --- a/wallets/provider-exodus/src/index.ts +++ b/wallets/provider-exodus/src/index.ts @@ -1,10 +1,5 @@ -import { - Network, - WalletType, - canSwitchNetworkToEvm, - chooseInstance, - getEvmAccounts, - switchNetworkForEvm, +import type { + CanEagerConnect, CanSwitchNetwork, Connect, ProviderConnectResult, @@ -12,30 +7,37 @@ import { SwitchNetwork, WalletInfo, } from '@rango-dev/wallets-shared'; +import type { BlockchainMeta, SignerFactory } from 'rango-types'; + +import { + canEagerlyConnectToEvm, + canSwitchNetworkToEvm, + chooseInstance, + getEvmAccounts, + Networks, + switchNetworkForEvm, + WalletTypes, +} from '@rango-dev/wallets-shared'; +import { isEvmBlockchain, isSolanaBlockchain } from 'rango-types'; + import { exodus_instances, EXODUS_WALLET_SUPPORTED_CHAINS, getSolanaAccounts, -} from './helpers'; -import signer from './signer'; -import { - SignerFactory, - isEvmBlockchain, - isSolanaBlockchain, - BlockchainMeta, -} from 'rango-types'; +} from './helpers.js'; +import signer from './signer.js'; -const WALLET = WalletType.EXODUS; +const WALLET = WalletTypes.EXODUS; export const config = { type: WALLET, // TODO: Get from evm networks - defaultNetwork: Network.ETHEREUM, + defaultNetwork: Networks.ETHEREUM, }; export const getInstance = exodus_instances; export const connect: Connect = async ({ instance, meta }) => { - const evm_instance = chooseInstance(instance, meta, Network.ETHEREUM); + const evm_instance = chooseInstance(instance, meta, Networks.ETHEREUM); let results: ProviderConnectResult[] = []; if (evm_instance) { @@ -52,29 +54,31 @@ export const subscribe: Subscribe = (options) => { const ethInstance = chooseInstance( options.instance, options.meta, - Network.ETHEREUM + Networks.ETHEREUM ); const solanaInstance = chooseInstance( options.instance, options.meta, - Network.SOLANA + Networks.SOLANA ); const { connect, updateAccounts, state, updateChainId, meta } = options; - ethInstance?.on('accountsChanged', (addresses: string[]) => { + ethInstance?.on?.('accountsChanged', (addresses: string[]) => { const eth_chainId = meta .filter(isEvmBlockchain) - .find((blockchain) => blockchain.name === Network.ETHEREUM)?.chainId; + .find((blockchain) => blockchain.name === Networks.ETHEREUM)?.chainId; if (state.connected) { - if (state.network != Network.ETHEREUM && eth_chainId) + if (state.network != Networks.ETHEREUM && eth_chainId) { updateChainId(eth_chainId); + } updateAccounts(addresses); } }); - solanaInstance?.on('accountChanged', async (publicKey: string) => { - if (state.network != Network.SOLANA) + solanaInstance?.on?.('accountChanged', async (publicKey: string) => { + if (state.network != Networks.SOLANA) { updateChainId(meta.filter(isSolanaBlockchain)[0].chainId); - const network = Network.SOLANA; + } + const network = Networks.SOLANA; if (publicKey) { const account = publicKey.toString(); updateAccounts([account]); @@ -98,13 +102,21 @@ export const switchNetwork: SwitchNetwork = async (options) => { export const canSwitchNetworkTo: CanSwitchNetwork = canSwitchNetworkToEvm; -export const getSigners: (provider: any) => SignerFactory = signer; +export const getSigners: (provider: any) => Promise = signer; + +export const canEagerConnect: CanEagerConnect = async ({ instance, meta }) => { + const evm_instance = chooseInstance(instance, meta, Networks.ETHEREUM); + if (evm_instance) { + return canEagerlyConnectToEvm({ instance: evm_instance, meta }); + } + return Promise.resolve(false); +}; export const getWalletInfo: (allBlockChains: BlockchainMeta[]) => WalletInfo = ( allBlockChains ) => ({ name: 'Exodus', - img: 'https://raw.githubusercontent.com/rango-exchange/rango-types/main/assets/icons/wallets/exodus.png', + img: 'https://raw.githubusercontent.com/rango-exchange/assets/main/wallets/exodus/icon.svg', installLink: { CHROME: 'https://chrome.google.com/webstore/detail/exodus-web3-wallet/aholpfdialjgjfhomihkjbmgjidlcdno', @@ -114,6 +126,6 @@ export const getWalletInfo: (allBlockChains: BlockchainMeta[]) => WalletInfo = ( }, color: '#8f70fa', supportedChains: allBlockChains.filter((blockchainMeta) => - EXODUS_WALLET_SUPPORTED_CHAINS.includes(blockchainMeta.name as Network) + EXODUS_WALLET_SUPPORTED_CHAINS.includes(blockchainMeta.name as Networks) ), }); diff --git a/wallets/provider-exodus/src/signer.ts b/wallets/provider-exodus/src/signer.ts index a0dbaa6225..6cd7760393 100644 --- a/wallets/provider-exodus/src/signer.ts +++ b/wallets/provider-exodus/src/signer.ts @@ -1,13 +1,18 @@ -import { DefaultEvmSigner } from '@rango-dev/signer-evm'; -import { DefaultSolanaSigner } from '@rango-dev/signer-solana'; -import { Network, getNetworkInstance } from '@rango-dev/wallets-shared'; -import { SignerFactory, TransactionType as TxType } from 'rango-types'; +import type { SignerFactory } from 'rango-types'; -export default function getSigners(provider: any): SignerFactory { - const ethProvider = getNetworkInstance(provider, Network.ETHEREUM); - const solProvider = getNetworkInstance(provider, Network.SOLANA); - const signers = new SignerFactory(); +import { getNetworkInstance, Networks } from '@rango-dev/wallets-shared'; +import { DefaultSignerFactory, TransactionType as TxType } from 'rango-types'; + +import { CustomSolanaSigner } from './solana-signer.js'; + +export default async function getSigners( + provider: any +): Promise { + const ethProvider = getNetworkInstance(provider, Networks.ETHEREUM); + const solProvider = getNetworkInstance(provider, Networks.SOLANA); + const signers = new DefaultSignerFactory(); + const { DefaultEvmSigner } = await import('@rango-dev/signer-evm'); signers.registerSigner(TxType.EVM, new DefaultEvmSigner(ethProvider)); - signers.registerSigner(TxType.COSMOS, new DefaultSolanaSigner(solProvider)); + signers.registerSigner(TxType.SOLANA, new CustomSolanaSigner(solProvider)); return signers; } diff --git a/wallets/provider-exodus/src/solana-signer.ts b/wallets/provider-exodus/src/solana-signer.ts new file mode 100644 index 0000000000..46847565d4 --- /dev/null +++ b/wallets/provider-exodus/src/solana-signer.ts @@ -0,0 +1,16 @@ +import { DefaultSolanaSigner } from '@rango-dev/signer-solana'; +import base58 from 'bs58'; + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +type SolanaExternalProvider = any; + +export class CustomSolanaSigner extends DefaultSolanaSigner { + constructor(provider: SolanaExternalProvider) { + super(provider); + } + + async signMessage(msg: string): Promise { + const { signature } = await this.provider.signMessage(msg); + return base58.encode(signature); + } +} diff --git a/wallets/provider-exodus/tsconfig.build.json b/wallets/provider-exodus/tsconfig.build.json new file mode 100644 index 0000000000..d9181ce0cd --- /dev/null +++ b/wallets/provider-exodus/tsconfig.build.json @@ -0,0 +1,11 @@ +{ + // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs + "extends": "../../tsconfig.libnext.json", + "include": ["src", "types", "../../global-wallets-env.d.ts"], + "compilerOptions": { + "outDir": "dist", + "rootDir": "./src", + "lib": ["dom", "esnext"] + // match output dir to input dir. e.g. dist/index instead of dist/src/index + } +} diff --git a/wallets/provider-exodus/tsconfig.json b/wallets/provider-exodus/tsconfig.json index 365489616a..a3a0b0f59d 100644 --- a/wallets/provider-exodus/tsconfig.json +++ b/wallets/provider-exodus/tsconfig.json @@ -1,35 +1 @@ -{ - // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs - "include": ["src", "types", "../../global-wallets-env.d.ts"], - "compilerOptions": { - "module": "esnext", - "lib": ["dom", "esnext"], - "importHelpers": true, - // output .d.ts declaration files for consumers - "declaration": true, - // output .js.map sourcemap files for consumers - "sourceMap": true, - // match output dir to input dir. e.g. dist/index instead of dist/src/index - "rootDir": "./src", - // stricter type-checking for stronger correctness. Recommended by TS - "strict": true, - // linter checks for common issues - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true, - // noUnused* overlap with @typescript-eslint/no-unused-vars, can disable if duplicative - "noUnusedLocals": true, - "noUnusedParameters": true, - // use Node's module resolution algorithm, instead of the legacy TS one - "moduleResolution": "node", - // transpile JSX to React.createElement - "jsx": "react", - // interop between ESM and CJS modules. Recommended by TS - "esModuleInterop": true, - // significant perf increase by skipping checking .d.ts files, particularly those in node_modules. Recommended by TS - "skipLibCheck": true, - // error out if import and file system have a casing mismatch. Recommended by TS - "forceConsistentCasingInFileNames": true, - // `tsdx build` ignores this option, but it is commonly used when type-checking separately with `tsc` - "noEmit": true, - } -} +{ "extends": "./tsconfig.build.json", "include": ["src", "tests"] } diff --git a/wallets/provider-frontier/CHANGELOG.md b/wallets/provider-frontier/CHANGELOG.md new file mode 100644 index 0000000000..74ea441e2e --- /dev/null +++ b/wallets/provider-frontier/CHANGELOG.md @@ -0,0 +1,160 @@ +# [0.41.0](https://github.com/rango-exchange/rango-client/compare/provider-frontier@0.40.0...provider-frontier@0.41.0) (2024-12-30) + + + +# [0.40.0](https://github.com/rango-exchange/rango-client/compare/provider-frontier@0.39.0...provider-frontier@0.40.0) (2024-11-27) + + +### Features + +* add ton connect provider ([2a2dbb7](https://github.com/rango-exchange/rango-client/commit/2a2dbb79022263f19446ced49d298e04d63f927f)) + + + +# [0.39.0](https://github.com/rango-exchange/rango-client/compare/provider-frontier@0.38.0...provider-frontier@0.39.0) (2024-11-12) + + + +# [0.38.0](https://github.com/rango-exchange/rango-client/compare/provider-frontier@0.37.0...provider-frontier@0.38.0) (2024-10-12) + + +### Bug Fixes + +* bump sdk and fix type issues ([d442208](https://github.com/rango-exchange/rango-client/commit/d4422083bf5dd27d5f509ce1db7f9560d05428c8)) + + +### Performance Improvements + +* lazy load signer packages ([7b88f18](https://github.com/rango-exchange/rango-client/commit/7b88f1834f7b29b4b81ab6c81a07bb88e8ccf55c)) + + + +# [0.37.0](https://github.com/rango-exchange/rango-client/compare/provider-frontier@0.36.0...provider-frontier@0.37.0) (2024-09-10) + + + +# [0.36.0](https://github.com/rango-exchange/rango-client/compare/provider-frontier@0.35.1...provider-frontier@0.36.0) (2024-08-11) + + + +## [0.35.1](https://github.com/rango-exchange/rango-client/compare/provider-frontier@0.35.0...provider-frontier@0.35.1) (2024-07-14) + + + +# [0.35.0](https://github.com/rango-exchange/rango-client/compare/provider-frontier@0.33.2...provider-frontier@0.35.0) (2024-07-09) + + + +# [0.34.0](https://github.com/rango-exchange/rango-client/compare/provider-frontier@0.33.2...provider-frontier@0.34.0) (2024-06-01) + + + +## [0.33.2](https://github.com/rango-exchange/rango-client/compare/provider-frontier@0.33.1...provider-frontier@0.33.2) (2024-05-26) + + + +## [0.33.1](https://github.com/rango-exchange/rango-client/compare/provider-frontier@0.33.0...provider-frontier@0.33.1) (2024-05-25) + + + +# [0.33.0](https://github.com/rango-exchange/rango-client/compare/provider-frontier@0.32.0...provider-frontier@0.33.0) (2024-05-14) + + + +# [0.32.0](https://github.com/rango-exchange/rango-client/compare/provider-frontier@0.31.0...provider-frontier@0.32.0) (2024-04-24) + + + +# [0.31.0](https://github.com/rango-exchange/rango-client/compare/provider-frontier@0.30.0...provider-frontier@0.31.0) (2024-04-23) + + + +# [0.30.0](https://github.com/rango-exchange/rango-client/compare/provider-frontier@0.29.0...provider-frontier@0.30.0) (2024-04-09) + + +### Bug Fixes + +* fix the connection problem that happens when another wallet takes over the requested one ([42df212](https://github.com/rango-exchange/rango-client/commit/42df2120aadd84c95045b0bf76844c19305fb59a)) + + + +# [0.29.0](https://github.com/rango-exchange/rango-client/compare/provider-frontier@0.28.0...provider-frontier@0.29.0) (2024-03-12) + + + +# [0.28.0](https://github.com/rango-exchange/rango-client/compare/provider-frontier@0.27.0...provider-frontier@0.28.0) (2024-02-20) + + + +# [0.27.0](https://github.com/rango-exchange/rango-client/compare/provider-frontier@0.26.0...provider-frontier@0.27.0) (2024-02-07) + + + +# [0.26.0](https://github.com/rango-exchange/rango-client/compare/provider-frontier@0.25.0...provider-frontier@0.26.0) (2024-01-22) + + +### Bug Fixes + +* cleanup wallets' subscriber when setProvider get null ([88d6a42](https://github.com/rango-exchange/rango-client/commit/88d6a423c49b34b3d9ff567e22df36c3b009bb76)) + + + +# [0.25.0](https://github.com/rango-exchange/rango-client/compare/provider-frontier@0.23.0...provider-frontier@0.25.0) (2023-12-24) + + +### Bug Fixes + +* fix HMR for widget and playground ([8524820](https://github.com/rango-exchange/rango-client/commit/8524820f10cf0b8921f3db0c4f620ff98daa4103)) + + + +# [0.14.0](https://github.com/rango-exchange/rango-client/compare/provider-frontier@0.13.0...provider-frontier@0.14.0) (2023-08-03) + + + +# [0.13.0](https://github.com/rango-exchange/rango-client/compare/provider-frontier@0.12.0...provider-frontier@0.13.0) (2023-08-01) + + + +# [0.9.0](https://github.com/rango-exchange/rango-client/compare/provider-frontier@0.8.0...provider-frontier@0.9.0) (2023-07-31) + + + +# [0.7.0](https://github.com/rango-exchange/rango-client/compare/provider-frontier@0.6.0...provider-frontier@0.7.0) (2023-07-11) + + + +# [0.6.0](https://github.com/rango-exchange/rango-client/compare/provider-frontier@0.5.0...provider-frontier@0.6.0) (2023-07-11) + + +### Reverts + +* Revert "support for rango-types cjs format" ([ed4e050](https://github.com/rango-exchange/rango-client/commit/ed4e050bfc0dcde7aeffa6b0d73b02080a5721eb)) + + + +# [0.5.0](https://github.com/rango-exchange/rango-client/compare/provider-frontier@0.4.0...provider-frontier@0.5.0) (2023-05-31) + + + +# [0.4.0](https://github.com/rango-exchange/rango-client/compare/provider-frontier@0.3.0...provider-frontier@0.4.0) (2023-05-31) + + + +# [0.3.0](https://github.com/rango-exchange/rango-client/compare/provider-frontier@0.2.0...provider-frontier@0.3.0) (2023-05-30) + + + +# [0.2.0](https://github.com/rango-exchange/rango-client/compare/provider-frontier@0.1.15...provider-frontier@0.2.0) (2023-05-30) + + + +## [0.1.14](https://github.com/rango-exchange/rango-client/compare/provider-frontier@0.1.13...provider-frontier@0.1.14) (2023-05-15) + + +### Bug Fixes + +* update rango-types and fix notification bugs ([993f185](https://github.com/rango-exchange/rango-client/commit/993f185e0b8c5e5e15a2c65ba2d85d1f9c8daa90)) + + + diff --git a/wallets/provider-frontier/package.json b/wallets/provider-frontier/package.json index 0db3b7a7da..c5ae8216f0 100644 --- a/wallets/provider-frontier/package.json +++ b/wallets/provider-frontier/package.json @@ -1,50 +1,32 @@ { "name": "@rango-dev/provider-frontier", - "version": "0.1.12", + "version": "0.40.1-next.6", "license": "MIT", - "module": "dist/provider-frontier.esm.js", - "main": "dist/index.js", + "type": "module", + "source": "./src/index.ts", + "main": "./dist/index.js", + "exports": { + ".": "./dist/index.js" + }, "typings": "dist/index.d.ts", "files": [ "dist", "src" ], "scripts": { - "start": "tsdx watch", - "build": "tsdx build --tsconfig ./tsconfig.json", - "test": "tsdx test --passWithNoTests", - "lint": "tsdx lint", - "size": "size-limit", - "analyze": "size-limit --why" - }, - "husky": { - "hooks": { - "pre-commit": "tsdx lint" - } + "build": "node ../../scripts/build/command.mjs --path wallets/provider-frontier", + "ts-check": "tsc --declaration --emitDeclarationOnly -p ./tsconfig.json", + "clean": "rimraf dist", + "format": "prettier --write '{.,src}/**/*.{ts,tsx}'", + "lint": "eslint \"**/*.{ts,tsx}\" --ignore-path ../../.eslintignore" }, - "prettier": { - "printWidth": 80, - "semi": true, - "singleQuote": true, - "trailingComma": "es5" - }, - "size-limit": [ - { - "path": "dist/provider-frontier.cjs.production.min.js", - "limit": "10 KB" - }, - { - "path": "dist/provider-frontier.esm.js", - "limit": "10 KB" - } - ], "dependencies": { - "@rango-dev/signer-evm": "^0.1.11", - "@rango-dev/signer-solana": "^0.1.11", - "@rango-dev/wallets-shared": "^0.1.11", - "rango-types": "^0.1.28" + "@rango-dev/signer-evm": "^0.32.0", + "@rango-dev/signer-solana": "^0.35.1-next.0", + "@rango-dev/wallets-shared": "^0.40.1-next.6", + "rango-types": "^0.1.74" }, "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/wallets/provider-frontier/src/helpers.ts b/wallets/provider-frontier/src/helpers.ts index 1e637c6e52..86e73d1623 100644 --- a/wallets/provider-frontier/src/helpers.ts +++ b/wallets/provider-frontier/src/helpers.ts @@ -1,12 +1,20 @@ -import { Network, ProviderConnectResult } from '@rango-dev/wallets-shared'; +import type { ProviderConnectResult } from '@rango-dev/wallets-shared'; + +import { Networks } from '@rango-dev/wallets-shared'; export function frontier() { const { frontier } = window; - if (!frontier) return null; + if (!frontier) { + return null; + } const instances = new Map(); - if (frontier?.ethereum) instances.set(Network.ETHEREUM, frontier?.ethereum); - if (frontier?.solana) instances.set(Network.SOLANA, frontier?.solana); + if (frontier?.ethereum) { + instances.set(Networks.ETHEREUM, frontier?.ethereum); + } + if (frontier?.solana) { + instances.set(Networks.SOLANA, frontier?.solana); + } return instances; } @@ -14,16 +22,16 @@ export function frontier() { export async function getSolanaAccounts( instance: any ): Promise { - const solanaInstance = await instance.get(Network.SOLANA); + const solanaInstance = await instance.get(Networks.SOLANA); const results: ProviderConnectResult[] = []; - if (!!solanaInstance) { + if (solanaInstance) { await solanaInstance.connect(); const account = solanaInstance.publicKey.toString(); results.push({ accounts: account ? [account] : [], - chainId: Network.SOLANA, + chainId: Networks.SOLANA, }); } diff --git a/wallets/provider-frontier/src/index.ts b/wallets/provider-frontier/src/index.ts index 74e573fae8..4bc3f82e69 100644 --- a/wallets/provider-frontier/src/index.ts +++ b/wallets/provider-frontier/src/index.ts @@ -1,38 +1,43 @@ -import { - Network, - WalletType, +import type { + CanEagerConnect, CanSwitchNetwork, Connect, + ProviderConnectResult, Subscribe, - WalletInfo, - getEvmAccounts, SwitchNetwork, - switchNetworkForEvm, + WalletInfo, +} from '@rango-dev/wallets-shared'; +import type { BlockchainMeta, SignerFactory } from 'rango-types'; + +import { + canEagerlyConnectToEvm, canSwitchNetworkToEvm, chooseInstance, + getEvmAccounts, + Networks, + switchNetworkForEvm, + WalletTypes, } from '@rango-dev/wallets-shared'; -import type { ProviderConnectResult } from '@rango-dev/wallets-shared'; -import { frontier as frontier_instance, getSolanaAccounts } from './helpers'; -import signer from './signer'; import { - SignerFactory, - isEvmBlockchain, - BlockchainMeta, evmBlockchains, + isEvmBlockchain, isSolanaBlockchain, solanaBlockchain, } from 'rango-types'; -const WALLET = WalletType.FRONTIER; +import { frontier as frontier_instance, getSolanaAccounts } from './helpers.js'; +import signer from './signer.js'; + +const WALLET = WalletTypes.FRONTIER; export const config = { type: WALLET, - defaultNetwork: Network.ETHEREUM, + defaultNetwork: Networks.ETHEREUM, }; export const getInstance = frontier_instance; export const connect: Connect = async ({ instance, meta }) => { - const ethInstance = chooseInstance(instance, meta, Network.ETHEREUM); + const ethInstance = chooseInstance(instance, meta, Networks.ETHEREUM); let results: ProviderConnectResult[] = []; if (ethInstance) { @@ -51,36 +56,47 @@ export const subscribe: Subscribe = (options) => { const ethInstance = chooseInstance( options.instance, options.meta, - Network.ETHEREUM + Networks.ETHEREUM ); const solanaInstance = chooseInstance( options.instance, options.meta, - Network.SOLANA + Networks.SOLANA ); const { connect, updateAccounts, state, updateChainId, meta } = options; - ethInstance?.on('accountsChanged', (addresses: string[]) => { + const handleEvmAccountsChanged = (addresses: string[]) => { const eth_chainId = meta .filter(isEvmBlockchain) - .find((blockchain) => blockchain.name === Network.ETHEREUM)?.chainId; + .find((blockchain) => blockchain.name === Networks.ETHEREUM)?.chainId; if (state.connected) { - if (state.network != Network.ETHEREUM && eth_chainId) + if (state.network != Networks.ETHEREUM && eth_chainId) { updateChainId(eth_chainId); + } updateAccounts(addresses); } - }); + }; - solanaInstance?.on('accountChanged', async (publicKey: string) => { - if (state.network != Network.SOLANA) + const handleSolanaAccountsChanged = async (publicKey: string) => { + if (state.network != Networks.SOLANA) { updateChainId(meta.filter(isSolanaBlockchain)[0].chainId); - const network = Network.SOLANA; + } + const network = Networks.SOLANA; if (publicKey) { const account = publicKey.toString(); updateAccounts([account]); } else { connect(network); } - }); + }; + ethInstance?.on?.('accountsChanged', handleEvmAccountsChanged); + + solanaInstance?.on?.('accountChanged', handleSolanaAccountsChanged); + + return () => { + ethInstance?.off?.('accountsChanged', handleEvmAccountsChanged); + + solanaInstance?.off?.('accountChanged', handleSolanaAccountsChanged); + }; }; export const switchNetwork: SwitchNetwork = async (options) => { const instance = chooseInstance( @@ -96,7 +112,15 @@ export const switchNetwork: SwitchNetwork = async (options) => { export const canSwitchNetworkTo: CanSwitchNetwork = canSwitchNetworkToEvm; -export const getSigners: (provider: any) => SignerFactory = signer; +export const getSigners: (provider: any) => Promise = signer; + +export const canEagerConnect: CanEagerConnect = async ({ instance, meta }) => { + const evm_instance = chooseInstance(instance, meta, Networks.ETHEREUM); + if (evm_instance) { + return canEagerlyConnectToEvm({ instance: evm_instance, meta }); + } + return Promise.resolve(false); +}; export const getWalletInfo: (allBlockChains: BlockchainMeta[]) => WalletInfo = ( allBlockChains @@ -106,7 +130,7 @@ export const getWalletInfo: (allBlockChains: BlockchainMeta[]) => WalletInfo = ( return { name: 'Frontier', - img: 'https://raw.githubusercontent.com/rango-exchange/rango-types/main/assets/icons/wallets/frontier.png', + img: 'https://raw.githubusercontent.com/rango-exchange/assets/main/wallets/frontier/icon.svg', installLink: { CHROME: 'https://chrome.google.com/webstore/detail/frontier-wallet/kppfdiipphfccemcignhifpjkapfbihd', diff --git a/wallets/provider-frontier/src/signer.ts b/wallets/provider-frontier/src/signer.ts index a0dbaa6225..99e6ce0dcd 100644 --- a/wallets/provider-frontier/src/signer.ts +++ b/wallets/provider-frontier/src/signer.ts @@ -1,13 +1,17 @@ -import { DefaultEvmSigner } from '@rango-dev/signer-evm'; +import type { SignerFactory } from 'rango-types'; + import { DefaultSolanaSigner } from '@rango-dev/signer-solana'; -import { Network, getNetworkInstance } from '@rango-dev/wallets-shared'; -import { SignerFactory, TransactionType as TxType } from 'rango-types'; +import { getNetworkInstance, Networks } from '@rango-dev/wallets-shared'; +import { DefaultSignerFactory, TransactionType as TxType } from 'rango-types'; -export default function getSigners(provider: any): SignerFactory { - const ethProvider = getNetworkInstance(provider, Network.ETHEREUM); - const solProvider = getNetworkInstance(provider, Network.SOLANA); - const signers = new SignerFactory(); +export default async function getSigners( + provider: any +): Promise { + const ethProvider = getNetworkInstance(provider, Networks.ETHEREUM); + const solProvider = getNetworkInstance(provider, Networks.SOLANA); + const signers = new DefaultSignerFactory(); + const { DefaultEvmSigner } = await import('@rango-dev/signer-evm'); signers.registerSigner(TxType.EVM, new DefaultEvmSigner(ethProvider)); - signers.registerSigner(TxType.COSMOS, new DefaultSolanaSigner(solProvider)); + signers.registerSigner(TxType.SOLANA, new DefaultSolanaSigner(solProvider)); return signers; } diff --git a/wallets/provider-frontier/tsconfig.build.json b/wallets/provider-frontier/tsconfig.build.json new file mode 100644 index 0000000000..d9181ce0cd --- /dev/null +++ b/wallets/provider-frontier/tsconfig.build.json @@ -0,0 +1,11 @@ +{ + // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs + "extends": "../../tsconfig.libnext.json", + "include": ["src", "types", "../../global-wallets-env.d.ts"], + "compilerOptions": { + "outDir": "dist", + "rootDir": "./src", + "lib": ["dom", "esnext"] + // match output dir to input dir. e.g. dist/index instead of dist/src/index + } +} diff --git a/wallets/provider-frontier/tsconfig.json b/wallets/provider-frontier/tsconfig.json index 365489616a..a3a0b0f59d 100644 --- a/wallets/provider-frontier/tsconfig.json +++ b/wallets/provider-frontier/tsconfig.json @@ -1,35 +1 @@ -{ - // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs - "include": ["src", "types", "../../global-wallets-env.d.ts"], - "compilerOptions": { - "module": "esnext", - "lib": ["dom", "esnext"], - "importHelpers": true, - // output .d.ts declaration files for consumers - "declaration": true, - // output .js.map sourcemap files for consumers - "sourceMap": true, - // match output dir to input dir. e.g. dist/index instead of dist/src/index - "rootDir": "./src", - // stricter type-checking for stronger correctness. Recommended by TS - "strict": true, - // linter checks for common issues - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true, - // noUnused* overlap with @typescript-eslint/no-unused-vars, can disable if duplicative - "noUnusedLocals": true, - "noUnusedParameters": true, - // use Node's module resolution algorithm, instead of the legacy TS one - "moduleResolution": "node", - // transpile JSX to React.createElement - "jsx": "react", - // interop between ESM and CJS modules. Recommended by TS - "esModuleInterop": true, - // significant perf increase by skipping checking .d.ts files, particularly those in node_modules. Recommended by TS - "skipLibCheck": true, - // error out if import and file system have a casing mismatch. Recommended by TS - "forceConsistentCasingInFileNames": true, - // `tsdx build` ignores this option, but it is commonly used when type-checking separately with `tsc` - "noEmit": true, - } -} +{ "extends": "./tsconfig.build.json", "include": ["src", "tests"] } diff --git a/wallets/provider-halo/CHANGELOG.md b/wallets/provider-halo/CHANGELOG.md new file mode 100644 index 0000000000..31658c165c --- /dev/null +++ b/wallets/provider-halo/CHANGELOG.md @@ -0,0 +1,145 @@ +# [0.41.0](https://github.com/rango-exchange/rango-client/compare/provider-halo@0.40.0...provider-halo@0.41.0) (2024-12-30) + + + +# [0.40.0](https://github.com/rango-exchange/rango-client/compare/provider-halo@0.39.0...provider-halo@0.40.0) (2024-11-27) + + + +# [0.39.0](https://github.com/rango-exchange/rango-client/compare/provider-halo@0.38.0...provider-halo@0.39.0) (2024-11-12) + + + +# [0.38.0](https://github.com/rango-exchange/rango-client/compare/provider-halo@0.37.0...provider-halo@0.38.0) (2024-10-12) + + +### Bug Fixes + +* bump sdk and fix type issues ([d442208](https://github.com/rango-exchange/rango-client/commit/d4422083bf5dd27d5f509ce1db7f9560d05428c8)) + + +### Performance Improvements + +* lazy load signer packages ([7b88f18](https://github.com/rango-exchange/rango-client/commit/7b88f1834f7b29b4b81ab6c81a07bb88e8ccf55c)) + + + +# [0.37.0](https://github.com/rango-exchange/rango-client/compare/provider-halo@0.36.0...provider-halo@0.37.0) (2024-09-10) + + + +# [0.36.0](https://github.com/rango-exchange/rango-client/compare/provider-halo@0.35.1...provider-halo@0.36.0) (2024-08-11) + + + +## [0.35.1](https://github.com/rango-exchange/rango-client/compare/provider-halo@0.35.0...provider-halo@0.35.1) (2024-07-14) + + + +# [0.35.0](https://github.com/rango-exchange/rango-client/compare/provider-halo@0.33.2...provider-halo@0.35.0) (2024-07-09) + + + +# [0.34.0](https://github.com/rango-exchange/rango-client/compare/provider-halo@0.33.2...provider-halo@0.34.0) (2024-06-01) + + + +## [0.33.2](https://github.com/rango-exchange/rango-client/compare/provider-halo@0.33.1...provider-halo@0.33.2) (2024-05-26) + + + +## [0.33.1](https://github.com/rango-exchange/rango-client/compare/provider-halo@0.33.0...provider-halo@0.33.1) (2024-05-25) + + + +# [0.33.0](https://github.com/rango-exchange/rango-client/compare/provider-halo@0.32.0...provider-halo@0.33.0) (2024-05-14) + + + +# [0.32.0](https://github.com/rango-exchange/rango-client/compare/provider-halo@0.31.0...provider-halo@0.32.0) (2024-04-24) + + + +# [0.31.0](https://github.com/rango-exchange/rango-client/compare/provider-halo@0.30.0...provider-halo@0.31.0) (2024-04-23) + + + +# [0.30.0](https://github.com/rango-exchange/rango-client/compare/provider-halo@0.29.0...provider-halo@0.30.0) (2024-04-09) + + + +# [0.29.0](https://github.com/rango-exchange/rango-client/compare/provider-halo@0.28.0...provider-halo@0.29.0) (2024-03-12) + + + +# [0.28.0](https://github.com/rango-exchange/rango-client/compare/provider-halo@0.27.0...provider-halo@0.28.0) (2024-02-20) + + + +# [0.27.0](https://github.com/rango-exchange/rango-client/compare/provider-halo@0.26.0...provider-halo@0.27.0) (2024-02-07) + + + +# [0.26.0](https://github.com/rango-exchange/rango-client/compare/provider-halo@0.25.0...provider-halo@0.26.0) (2024-01-22) + + + +# [0.25.0](https://github.com/rango-exchange/rango-client/compare/provider-halo@0.23.0...provider-halo@0.25.0) (2023-12-24) + + +### Bug Fixes + +* fix HMR for widget and playground ([8524820](https://github.com/rango-exchange/rango-client/commit/8524820f10cf0b8921f3db0c4f620ff98daa4103)) + + + +# [0.14.0](https://github.com/rango-exchange/rango-client/compare/provider-kucoin-wallet@0.13.0...provider-kucoin-wallet@0.14.0) (2023-08-03) + + + +# [0.13.0](https://github.com/rango-exchange/rango-client/compare/provider-kucoin-wallet@0.12.0...provider-kucoin-wallet@0.13.0) (2023-08-01) + + + +# [0.9.0](https://github.com/rango-exchange/rango-client/compare/provider-kucoin-wallet@0.8.0...provider-kucoin-wallet@0.9.0) (2023-07-31) + + + +# [0.7.0](https://github.com/rango-exchange/rango-client/compare/provider-kucoin-wallet@0.6.0...provider-kucoin-wallet@0.7.0) (2023-07-11) + + + +# [0.6.0](https://github.com/rango-exchange/rango-client/compare/provider-kucoin-wallet@0.5.0...provider-kucoin-wallet@0.6.0) (2023-07-11) + + +### Reverts + +* Revert "support for rango-types cjs format" ([ed4e050](https://github.com/rango-exchange/rango-client/commit/ed4e050bfc0dcde7aeffa6b0d73b02080a5721eb)) + + + +# [0.5.0](https://github.com/rango-exchange/rango-client/compare/provider-kucoin-wallet@0.4.0...provider-kucoin-wallet@0.5.0) (2023-05-31) + + + +# [0.4.0](https://github.com/rango-exchange/rango-client/compare/provider-kucoin-wallet@0.3.0...provider-kucoin-wallet@0.4.0) (2023-05-31) + + + +# [0.3.0](https://github.com/rango-exchange/rango-client/compare/provider-kucoin-wallet@0.2.0...provider-kucoin-wallet@0.3.0) (2023-05-30) + + + +# [0.2.0](https://github.com/rango-exchange/rango-client/compare/provider-kucoin-wallet@0.1.15...provider-kucoin-wallet@0.2.0) (2023-05-30) + + + +## [0.1.14](https://github.com/rango-exchange/rango-client/compare/provider-kucoin-wallet@0.1.13...provider-kucoin-wallet@0.1.14) (2023-05-15) + + +### Bug Fixes + +* update rango-types and fix notification bugs ([993f185](https://github.com/rango-exchange/rango-client/commit/993f185e0b8c5e5e15a2c65ba2d85d1f9c8daa90)) + + + diff --git a/wallets/provider-halo/package.json b/wallets/provider-halo/package.json new file mode 100644 index 0000000000..3e8ab5ac59 --- /dev/null +++ b/wallets/provider-halo/package.json @@ -0,0 +1,31 @@ +{ + "name": "@rango-dev/provider-halo", + "version": "0.40.1-next.6", + "license": "MIT", + "type": "module", + "source": "./src/index.ts", + "main": "./dist/index.js", + "exports": { + ".": "./dist/index.js" + }, + "typings": "dist/index.d.ts", + "files": [ + "dist", + "src" + ], + "scripts": { + "build": "node ../../scripts/build/command.mjs --path wallets/provider-halo", + "ts-check": "tsc --declaration --emitDeclarationOnly -p ./tsconfig.json", + "clean": "rimraf dist", + "format": "prettier --write '{.,src}/**/*.{ts,tsx}'", + "lint": "eslint \"**/*.{ts,tsx}\" --ignore-path ../../.eslintignore" + }, + "dependencies": { + "@rango-dev/signer-evm": "^0.32.0", + "@rango-dev/wallets-shared": "^0.40.1-next.6", + "rango-types": "^0.1.74" + }, + "publishConfig": { + "access": "public" + } +} \ No newline at end of file diff --git a/wallets/provider-halo/readme.md b/wallets/provider-halo/readme.md new file mode 100644 index 0000000000..ea8298f390 --- /dev/null +++ b/wallets/provider-halo/readme.md @@ -0,0 +1 @@ +# @rango-dev/provider-halo diff --git a/wallets/provider-halo/src/helpers.ts b/wallets/provider-halo/src/helpers.ts new file mode 100644 index 0000000000..e6593215d4 --- /dev/null +++ b/wallets/provider-halo/src/helpers.ts @@ -0,0 +1,16 @@ +import { Networks } from '@rango-dev/wallets-shared'; + +export function getHaloInstance() { + const { kucoin } = window; + if (kucoin && kucoin.isKuCoinWallet) { + return kucoin; + } + + return null; +} + +export const HALO_WALLET_SUPPORTED_CHAINS = [ + Networks.ETHEREUM, + Networks.POLYGON, + Networks.BSC, +]; diff --git a/wallets/provider-halo/src/index.ts b/wallets/provider-halo/src/index.ts new file mode 100644 index 0000000000..c37abdada1 --- /dev/null +++ b/wallets/provider-halo/src/index.ts @@ -0,0 +1,73 @@ +import type { + CanSwitchNetwork, + Connect, + Networks, + Subscribe, + SwitchNetwork, + WalletInfo, +} from '@rango-dev/wallets-shared'; +import type { BlockchainMeta, SignerFactory } from 'rango-types'; + +import { + canSwitchNetworkToEvm, + getEvmAccounts, + subscribeToEvm, + switchNetworkForEvm, + WalletTypes, +} from '@rango-dev/wallets-shared'; + +import { + getHaloInstance as halo_instance, + HALO_WALLET_SUPPORTED_CHAINS, +} from './helpers.js'; +import signer from './signer.js'; + +const WALLET = WalletTypes.HALO; + +export const config = { + type: WALLET, +}; + +export const getInstance = halo_instance; +export const connect: Connect = async ({ instance }) => { + /* + * Note: We need to get `chainId` here, because for the first time + * after opening the browser, wallet is locked, and don't give us accounts and chainId + * on `check` phase, so `network` will be null. For this case we need to get chainId + * whenever we are requesting accounts. + */ + const { accounts, chainId } = await getEvmAccounts(instance); + + return { + accounts, + chainId, + }; +}; + +export const subscribe: Subscribe = subscribeToEvm; + +export const switchNetwork: SwitchNetwork = switchNetworkForEvm; + +export const canSwitchNetworkTo: CanSwitchNetwork = canSwitchNetworkToEvm; + +export const getSigners: (provider: any) => Promise = signer; + +export const getWalletInfo: (allBlockChains: BlockchainMeta[]) => WalletInfo = ( + allBlockChains +) => { + return { + name: 'Halo', + img: 'https://raw.githubusercontent.com/rango-exchange/assets/main/wallets/halo/icon.svg', + color: '#b2dbff', + installLink: { + CHROME: + 'https://chrome.google.com/webstore/detail/halo-wallet/nbdpmlhambbdkhkmbfpljckjcmgibalo', + BRAVE: + 'https://chrome.google.com/webstore/detail/halo-wallet/nbdpmlhambbdkhkmbfpljckjcmgibalo', + DEFAULT: 'https://halo.social/', + }, + supportedChains: allBlockChains.filter((blockchainMeta) => + HALO_WALLET_SUPPORTED_CHAINS.includes(blockchainMeta.name as Networks) + ), + }; +}; diff --git a/wallets/provider-halo/src/signer.ts b/wallets/provider-halo/src/signer.ts new file mode 100644 index 0000000000..ef3f4e5d09 --- /dev/null +++ b/wallets/provider-halo/src/signer.ts @@ -0,0 +1,14 @@ +import type { SignerFactory } from 'rango-types'; + +import { getNetworkInstance, Networks } from '@rango-dev/wallets-shared'; +import { DefaultSignerFactory, TransactionType as TxType } from 'rango-types'; + +export default async function getSigners( + provider: any +): Promise { + const ethProvider = getNetworkInstance(provider, Networks.ETHEREUM); + const signers = new DefaultSignerFactory(); + const { DefaultEvmSigner } = await import('@rango-dev/signer-evm'); + signers.registerSigner(TxType.EVM, new DefaultEvmSigner(ethProvider)); + return signers; +} diff --git a/wallets/provider-halo/tsconfig.build.json b/wallets/provider-halo/tsconfig.build.json new file mode 100644 index 0000000000..d9181ce0cd --- /dev/null +++ b/wallets/provider-halo/tsconfig.build.json @@ -0,0 +1,11 @@ +{ + // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs + "extends": "../../tsconfig.libnext.json", + "include": ["src", "types", "../../global-wallets-env.d.ts"], + "compilerOptions": { + "outDir": "dist", + "rootDir": "./src", + "lib": ["dom", "esnext"] + // match output dir to input dir. e.g. dist/index instead of dist/src/index + } +} diff --git a/wallets/provider-halo/tsconfig.json b/wallets/provider-halo/tsconfig.json new file mode 100644 index 0000000000..a3a0b0f59d --- /dev/null +++ b/wallets/provider-halo/tsconfig.json @@ -0,0 +1 @@ +{ "extends": "./tsconfig.build.json", "include": ["src", "tests"] } diff --git a/wallets/provider-keplr/CHANGELOG.md b/wallets/provider-keplr/CHANGELOG.md new file mode 100644 index 0000000000..69a6c2195c --- /dev/null +++ b/wallets/provider-keplr/CHANGELOG.md @@ -0,0 +1,150 @@ +# [0.41.0](https://github.com/rango-exchange/rango-client/compare/provider-keplr@0.40.0...provider-keplr@0.41.0) (2024-12-30) + + + +# [0.40.0](https://github.com/rango-exchange/rango-client/compare/provider-keplr@0.39.0...provider-keplr@0.40.0) (2024-11-27) + + + +# [0.39.0](https://github.com/rango-exchange/rango-client/compare/provider-keplr@0.38.2...provider-keplr@0.39.0) (2024-11-12) + + + +## [0.38.2](https://github.com/rango-exchange/rango-client/compare/provider-keplr@0.38.1...provider-keplr@0.38.2) (2024-11-06) + + + +## [0.38.1](https://github.com/rango-exchange/rango-client/compare/provider-keplr@0.38.0...provider-keplr@0.38.1) (2024-11-06) + + + +# [0.38.0](https://github.com/rango-exchange/rango-client/compare/provider-keplr@0.37.0...provider-keplr@0.38.0) (2024-10-12) + + +### Bug Fixes + +* bump sdk and fix type issues ([d442208](https://github.com/rango-exchange/rango-client/commit/d4422083bf5dd27d5f509ce1db7f9560d05428c8)) + + +### Performance Improvements + +* lazy load signer packages ([7b88f18](https://github.com/rango-exchange/rango-client/commit/7b88f1834f7b29b4b81ab6c81a07bb88e8ccf55c)) + + + +# [0.37.0](https://github.com/rango-exchange/rango-client/compare/provider-keplr@0.36.0...provider-keplr@0.37.0) (2024-09-10) + + + +# [0.36.0](https://github.com/rango-exchange/rango-client/compare/provider-keplr@0.35.1...provider-keplr@0.36.0) (2024-08-11) + + + +## [0.35.1](https://github.com/rango-exchange/rango-client/compare/provider-keplr@0.35.0...provider-keplr@0.35.1) (2024-07-14) + + + +# [0.35.0](https://github.com/rango-exchange/rango-client/compare/provider-keplr@0.33.0...provider-keplr@0.35.0) (2024-07-09) + + + +# [0.34.0](https://github.com/rango-exchange/rango-client/compare/provider-keplr@0.33.0...provider-keplr@0.34.0) (2024-06-01) + + + +# [0.33.0](https://github.com/rango-exchange/rango-client/compare/provider-keplr@0.32.0...provider-keplr@0.33.0) (2024-05-14) + + + +# [0.32.0](https://github.com/rango-exchange/rango-client/compare/provider-keplr@0.31.0...provider-keplr@0.32.0) (2024-04-24) + + + +# [0.31.0](https://github.com/rango-exchange/rango-client/compare/provider-keplr@0.30.0...provider-keplr@0.31.0) (2024-04-23) + + + +# [0.30.0](https://github.com/rango-exchange/rango-client/compare/provider-keplr@0.29.0...provider-keplr@0.30.0) (2024-04-09) + + + +# [0.29.0](https://github.com/rango-exchange/rango-client/compare/provider-keplr@0.28.0...provider-keplr@0.29.0) (2024-03-12) + + + +# [0.28.0](https://github.com/rango-exchange/rango-client/compare/provider-keplr@0.27.0...provider-keplr@0.28.0) (2024-02-20) + + + +# [0.27.0](https://github.com/rango-exchange/rango-client/compare/provider-keplr@0.26.0...provider-keplr@0.27.0) (2024-02-07) + + + +# [0.26.0](https://github.com/rango-exchange/rango-client/compare/provider-keplr@0.25.0...provider-keplr@0.26.0) (2024-01-22) + + +### Bug Fixes + +* cleanup wallets' subscriber when setProvider get null ([88d6a42](https://github.com/rango-exchange/rango-client/commit/88d6a423c49b34b3d9ff567e22df36c3b009bb76)) + + + +# [0.25.0](https://github.com/rango-exchange/rango-client/compare/provider-keplr@0.23.0...provider-keplr@0.25.0) (2023-12-24) + + +### Bug Fixes + +* fix HMR for widget and playground ([8524820](https://github.com/rango-exchange/rango-client/commit/8524820f10cf0b8921f3db0c4f620ff98daa4103)) + + + +# [0.14.0](https://github.com/rango-exchange/rango-client/compare/provider-keplr@0.13.0...provider-keplr@0.14.0) (2023-08-03) + + + +# [0.13.0](https://github.com/rango-exchange/rango-client/compare/provider-keplr@0.12.0...provider-keplr@0.13.0) (2023-08-01) + + + +# [0.9.0](https://github.com/rango-exchange/rango-client/compare/provider-keplr@0.8.0...provider-keplr@0.9.0) (2023-07-31) + + + +# [0.7.0](https://github.com/rango-exchange/rango-client/compare/provider-keplr@0.6.0...provider-keplr@0.7.0) (2023-07-11) + + + +# [0.6.0](https://github.com/rango-exchange/rango-client/compare/provider-keplr@0.5.0...provider-keplr@0.6.0) (2023-07-11) + + +### Reverts + +* Revert "support for rango-types cjs format" ([ed4e050](https://github.com/rango-exchange/rango-client/commit/ed4e050bfc0dcde7aeffa6b0d73b02080a5721eb)) + + + +# [0.5.0](https://github.com/rango-exchange/rango-client/compare/provider-keplr@0.4.0...provider-keplr@0.5.0) (2023-05-31) + + + +# [0.4.0](https://github.com/rango-exchange/rango-client/compare/provider-keplr@0.3.0...provider-keplr@0.4.0) (2023-05-31) + + + +# [0.3.0](https://github.com/rango-exchange/rango-client/compare/provider-keplr@0.2.0...provider-keplr@0.3.0) (2023-05-30) + + + +# [0.2.0](https://github.com/rango-exchange/rango-client/compare/provider-keplr@0.1.15...provider-keplr@0.2.0) (2023-05-30) + + + +## [0.1.14](https://github.com/rango-exchange/rango-client/compare/provider-keplr@0.1.13...provider-keplr@0.1.14) (2023-05-15) + + +### Bug Fixes + +* update rango-types and fix notification bugs ([993f185](https://github.com/rango-exchange/rango-client/commit/993f185e0b8c5e5e15a2c65ba2d85d1f9c8daa90)) + + + diff --git a/wallets/provider-keplr/package.json b/wallets/provider-keplr/package.json index dce019c561..e4186a0cd8 100644 --- a/wallets/provider-keplr/package.json +++ b/wallets/provider-keplr/package.json @@ -1,52 +1,37 @@ { "name": "@rango-dev/provider-keplr", - "version": "0.1.12", + "version": "0.40.1-next.6", "license": "MIT", - "module": "dist/provider-keplr.esm.js", - "main": "dist/index.js", + "type": "module", + "source": "./src/index.ts", + "main": "./dist/index.js", + "exports": { + ".": "./dist/index.js" + }, "typings": "dist/index.d.ts", "files": [ "dist", "src" ], "scripts": { - "start": "tsdx watch", - "build": "tsdx build --tsconfig ./tsconfig.json", - "test": "tsdx test --passWithNoTests", - "lint": "tsdx lint", - "size": "size-limit", - "analyze": "size-limit --why" - }, - "husky": { - "hooks": { - "pre-commit": "tsdx lint" - } - }, - "prettier": { - "printWidth": 80, - "semi": true, - "singleQuote": true, - "trailingComma": "es5" + "build": "node ../../scripts/build/command.mjs --path wallets/provider-keplr", + "ts-check": "tsc --declaration --emitDeclarationOnly -p ./tsconfig.json", + "clean": "rimraf dist", + "format": "prettier --write '{.,src}/**/*.{ts,tsx}'", + "lint": "eslint \"**/*.{ts,tsx}\" --ignore-path ../../.eslintignore" }, - "size-limit": [ - { - "path": "dist/provider-keplr.cjs.production.min.js", - "limit": "10 KB" - }, - { - "path": "dist/provider-keplr.esm.js", - "limit": "10 KB" - } - ], "dependencies": { - "@rango-dev/signer-cosmos": "^0.1.11", - "@rango-dev/wallets-shared": "^0.1.11", - "rango-types": "^0.1.28" + "@rango-dev/signer-cosmos": "^0.30.1", + "@rango-dev/wallets-shared": "^0.40.1-next.6", + "rango-types": "^0.1.74" }, "devDependencies": { "@keplr-wallet/types": "^0.11.21" }, + "resolutions": { + "@keplr-wallet/types/secretjs/protobufjs": "^6.11.4" + }, "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/wallets/provider-keplr/src/helpers.ts b/wallets/provider-keplr/src/helpers.ts index 2ab5955f27..b71dd61a16 100644 --- a/wallets/provider-keplr/src/helpers.ts +++ b/wallets/provider-keplr/src/helpers.ts @@ -1,6 +1,4 @@ - -export function keplr() { +// Note: for unknown reason CTRL wallet extension is overiding any function named `keplr`. so make sure you will not use this name for any function! +export function getKeplrInstance() { return window.keplr || null; } - - diff --git a/wallets/provider-keplr/src/index.ts b/wallets/provider-keplr/src/index.ts index 4c9325779e..81695a3653 100644 --- a/wallets/provider-keplr/src/index.ts +++ b/wallets/provider-keplr/src/index.ts @@ -1,23 +1,30 @@ -import { - Network, - WalletType, +import type { Connect, Subscribe, - getCosmosAccounts, + Suggest, WalletInfo, } from '@rango-dev/wallets-shared'; -import { keplr as keplrInstance } from './helpers'; -import signer from './signer'; -import { SignerFactory, cosmosBlockchains, BlockchainMeta } from 'rango-types'; +import type { BlockchainMeta, SignerFactory } from 'rango-types'; + +import { + getCosmosAccounts, + Networks, + suggestCosmosChain, + WalletTypes, +} from '@rango-dev/wallets-shared'; +import { cosmosBlockchains } from 'rango-types'; -const WALLET = WalletType.KEPLR; +import { getKeplrInstance } from './helpers.js'; +import signer from './signer.js'; + +const WALLET = WalletTypes.KEPLR; export const config = { type: WALLET, - defaultNetwork: Network.COSMOS, + defaultNetwork: Networks.COSMOS, }; -export const getInstance = keplrInstance; +export const getInstance = getKeplrInstance; export const connect: Connect = async ({ instance, network, meta }) => { return await getCosmosAccounts({ @@ -28,13 +35,19 @@ export const connect: Connect = async ({ instance, network, meta }) => { }; export const subscribe: Subscribe = ({ connect, disconnect }) => { - window.addEventListener('keplr_keystorechange', () => { + const handleAccountsChanged = () => { disconnect(); connect(); - }); + }; + window.addEventListener('keplr_keystorechange', handleAccountsChanged); + return () => { + window.removeEventListener('keplr_keystorechange', handleAccountsChanged); + }; }; -export const getSigners: (provider: any) => SignerFactory = signer; +export const suggest: Suggest = suggestCosmosChain; + +export const getSigners: (provider: any) => Promise = signer; export const getWalletInfo: (allBlockChains: BlockchainMeta[]) => WalletInfo = ( allBlockChains @@ -42,7 +55,7 @@ export const getWalletInfo: (allBlockChains: BlockchainMeta[]) => WalletInfo = ( const cosmos = cosmosBlockchains(allBlockChains); return { name: 'Keplr', - img: 'https://raw.githubusercontent.com/rango-exchange/rango-types/main/assets/icons/wallets/keplr.png', + img: 'https://raw.githubusercontent.com/rango-exchange/assets/main/wallets/keplr/icon.svg', installLink: { CHROME: 'https://chrome.google.com/webstore/detail/keplr/dmkamcknogkgcdfhhbddcghachkejeap', diff --git a/wallets/provider-keplr/src/signer.ts b/wallets/provider-keplr/src/signer.ts index e1210db76d..6bc073e6e9 100644 --- a/wallets/provider-keplr/src/signer.ts +++ b/wallets/provider-keplr/src/signer.ts @@ -1,10 +1,14 @@ -import { DefaultCosmosSigner } from '@rango-dev/signer-cosmos'; -import { Network, getNetworkInstance } from '@rango-dev/wallets-shared'; -import { SignerFactory, TransactionType as TxType } from 'rango-types'; +import type { SignerFactory } from 'rango-types'; -export default function getSigners(provider: any): SignerFactory { - const cosmosProvider = getNetworkInstance(provider, Network.COSMOS); - const signers = new SignerFactory(); +import { getNetworkInstance, Networks } from '@rango-dev/wallets-shared'; +import { DefaultSignerFactory, TransactionType as TxType } from 'rango-types'; + +export default async function getSigners( + provider: any +): Promise { + const cosmosProvider = getNetworkInstance(provider, Networks.COSMOS); + const signers = new DefaultSignerFactory(); + const { DefaultCosmosSigner } = await import('@rango-dev/signer-cosmos'); signers.registerSigner( TxType.COSMOS, new DefaultCosmosSigner(cosmosProvider) diff --git a/wallets/provider-keplr/tsconfig.build.json b/wallets/provider-keplr/tsconfig.build.json new file mode 100644 index 0000000000..d9181ce0cd --- /dev/null +++ b/wallets/provider-keplr/tsconfig.build.json @@ -0,0 +1,11 @@ +{ + // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs + "extends": "../../tsconfig.libnext.json", + "include": ["src", "types", "../../global-wallets-env.d.ts"], + "compilerOptions": { + "outDir": "dist", + "rootDir": "./src", + "lib": ["dom", "esnext"] + // match output dir to input dir. e.g. dist/index instead of dist/src/index + } +} diff --git a/wallets/provider-keplr/tsconfig.json b/wallets/provider-keplr/tsconfig.json index 365489616a..a3a0b0f59d 100644 --- a/wallets/provider-keplr/tsconfig.json +++ b/wallets/provider-keplr/tsconfig.json @@ -1,35 +1 @@ -{ - // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs - "include": ["src", "types", "../../global-wallets-env.d.ts"], - "compilerOptions": { - "module": "esnext", - "lib": ["dom", "esnext"], - "importHelpers": true, - // output .d.ts declaration files for consumers - "declaration": true, - // output .js.map sourcemap files for consumers - "sourceMap": true, - // match output dir to input dir. e.g. dist/index instead of dist/src/index - "rootDir": "./src", - // stricter type-checking for stronger correctness. Recommended by TS - "strict": true, - // linter checks for common issues - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true, - // noUnused* overlap with @typescript-eslint/no-unused-vars, can disable if duplicative - "noUnusedLocals": true, - "noUnusedParameters": true, - // use Node's module resolution algorithm, instead of the legacy TS one - "moduleResolution": "node", - // transpile JSX to React.createElement - "jsx": "react", - // interop between ESM and CJS modules. Recommended by TS - "esModuleInterop": true, - // significant perf increase by skipping checking .d.ts files, particularly those in node_modules. Recommended by TS - "skipLibCheck": true, - // error out if import and file system have a casing mismatch. Recommended by TS - "forceConsistentCasingInFileNames": true, - // `tsdx build` ignores this option, but it is commonly used when type-checking separately with `tsc` - "noEmit": true, - } -} +{ "extends": "./tsconfig.build.json", "include": ["src", "tests"] } diff --git a/wallets/provider-kucoin-wallet/package.json b/wallets/provider-kucoin-wallet/package.json deleted file mode 100644 index 40674148f7..0000000000 --- a/wallets/provider-kucoin-wallet/package.json +++ /dev/null @@ -1,49 +0,0 @@ -{ - "name": "@rango-dev/provider-kucoin-wallet", - "version": "0.1.12", - "license": "MIT", - "module": "dist/provider-kucoin-wallet.esm.js", - "main": "dist/index.js", - "typings": "dist/index.d.ts", - "files": [ - "dist", - "src" - ], - "scripts": { - "start": "tsdx watch", - "build": "tsdx build --tsconfig ./tsconfig.json", - "test": "tsdx test --passWithNoTests", - "lint": "tsdx lint", - "size": "size-limit", - "analyze": "size-limit --why" - }, - "husky": { - "hooks": { - "pre-commit": "tsdx lint" - } - }, - "prettier": { - "printWidth": 80, - "semi": true, - "singleQuote": true, - "trailingComma": "es5" - }, - "size-limit": [ - { - "path": "dist/provider-kucoin-wallet.cjs.production.min.js", - "limit": "10 KB" - }, - { - "path": "dist/provider-kucoin-wallet.esm.js", - "limit": "10 KB" - } - ], - "dependencies": { - "@rango-dev/signer-evm": "^0.1.11", - "@rango-dev/wallets-shared": "^0.1.11", - "rango-types": "^0.1.28" - }, - "publishConfig": { - "access": "public" - } -} diff --git a/wallets/provider-kucoin-wallet/readme.md b/wallets/provider-kucoin-wallet/readme.md deleted file mode 100644 index 5c4d730552..0000000000 --- a/wallets/provider-kucoin-wallet/readme.md +++ /dev/null @@ -1 +0,0 @@ -# @rango-dev/provider-kucoin-wallet diff --git a/wallets/provider-kucoin-wallet/src/helpers.ts b/wallets/provider-kucoin-wallet/src/helpers.ts deleted file mode 100644 index 79f9537e72..0000000000 --- a/wallets/provider-kucoin-wallet/src/helpers.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { Network } from '@rango-dev/wallets-shared'; - -export function getKucoinInstance() { - const { kucoin } = window; - if (kucoin && kucoin.isKuCoinWallet) return kucoin; - - return null; -} - -export const KUCOIN_WALLET_SUPPORTED_CHAINS = [ - Network.ETHEREUM, - Network.POLYGON, - Network.BSC, -]; diff --git a/wallets/provider-kucoin-wallet/src/index.ts b/wallets/provider-kucoin-wallet/src/index.ts deleted file mode 100644 index 512abe91e4..0000000000 --- a/wallets/provider-kucoin-wallet/src/index.ts +++ /dev/null @@ -1,67 +0,0 @@ -import { - WalletType, - CanSwitchNetwork, - Connect, - Subscribe, - SwitchNetwork, - canSwitchNetworkToEvm, - getEvmAccounts, - subscribeToEvm, - switchNetworkForEvm, - WalletInfo, - Network, -} from '@rango-dev/wallets-shared'; -import { - getKucoinInstance as kucoin_instance, - KUCOIN_WALLET_SUPPORTED_CHAINS, -} from './helpers'; -import signer from './signer'; -import { SignerFactory, BlockchainMeta } from 'rango-types'; - -const WALLET = WalletType.KUCOIN; - -export const config = { - type: WALLET, -}; - -export const getInstance = kucoin_instance; -export const connect: Connect = async ({ instance }) => { - // Note: We need to get `chainId` here, because for the first time - // after opening the browser, wallet is locked, and don't give us accounts and chainId - // on `check` phase, so `network` will be null. For this case we need to get chainId - // whenever we are requesting accounts. - const { accounts, chainId } = await getEvmAccounts(instance); - - return { - accounts, - chainId, - }; -}; - -export const subscribe: Subscribe = subscribeToEvm; - -export const switchNetwork: SwitchNetwork = switchNetworkForEvm; - -export const canSwitchNetworkTo: CanSwitchNetwork = canSwitchNetworkToEvm; - -export const getSigners: (provider: any) => SignerFactory = signer; - -export const getWalletInfo: (allBlockChains: BlockchainMeta[]) => WalletInfo = ( - allBlockChains -) => { - return { - name: 'KuCoin', - img: 'https://raw.githubusercontent.com/rango-exchange/rango-types/main/assets/icons/wallets/kucoin.png', - color: '#b2dbff', - installLink: { - CHROME: - 'https://chrome.google.com/webstore/detail/kucoin-wallet/nbdpmlhambbdkhkmbfpljckjcmgibalo', - BRAVE: - 'https://chrome.google.com/webstore/detail/kucoin-wallet/nbdpmlhambbdkhkmbfpljckjcmgibalo', - DEFAULT: 'https://kuwallet.com/', - }, - supportedChains: allBlockChains.filter((blockchainMeta) => - KUCOIN_WALLET_SUPPORTED_CHAINS.includes(blockchainMeta.name as Network) - ), - }; -}; diff --git a/wallets/provider-kucoin-wallet/src/signer.ts b/wallets/provider-kucoin-wallet/src/signer.ts deleted file mode 100644 index 7ae6c242f8..0000000000 --- a/wallets/provider-kucoin-wallet/src/signer.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { DefaultEvmSigner } from '@rango-dev/signer-evm'; -import { Network, getNetworkInstance } from '@rango-dev/wallets-shared'; -import { SignerFactory, TransactionType as TxType } from 'rango-types'; - -export default function getSigners(provider: any): SignerFactory { - const ethProvider = getNetworkInstance(provider, Network.ETHEREUM); - const signers = new SignerFactory(); - signers.registerSigner(TxType.EVM, new DefaultEvmSigner(ethProvider)); - return signers; -} diff --git a/wallets/provider-kucoin-wallet/tsconfig.json b/wallets/provider-kucoin-wallet/tsconfig.json deleted file mode 100644 index 365489616a..0000000000 --- a/wallets/provider-kucoin-wallet/tsconfig.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs - "include": ["src", "types", "../../global-wallets-env.d.ts"], - "compilerOptions": { - "module": "esnext", - "lib": ["dom", "esnext"], - "importHelpers": true, - // output .d.ts declaration files for consumers - "declaration": true, - // output .js.map sourcemap files for consumers - "sourceMap": true, - // match output dir to input dir. e.g. dist/index instead of dist/src/index - "rootDir": "./src", - // stricter type-checking for stronger correctness. Recommended by TS - "strict": true, - // linter checks for common issues - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true, - // noUnused* overlap with @typescript-eslint/no-unused-vars, can disable if duplicative - "noUnusedLocals": true, - "noUnusedParameters": true, - // use Node's module resolution algorithm, instead of the legacy TS one - "moduleResolution": "node", - // transpile JSX to React.createElement - "jsx": "react", - // interop between ESM and CJS modules. Recommended by TS - "esModuleInterop": true, - // significant perf increase by skipping checking .d.ts files, particularly those in node_modules. Recommended by TS - "skipLibCheck": true, - // error out if import and file system have a casing mismatch. Recommended by TS - "forceConsistentCasingInFileNames": true, - // `tsdx build` ignores this option, but it is commonly used when type-checking separately with `tsc` - "noEmit": true, - } -} diff --git a/wallets/provider-leap-cosmos/CHANGELOG.md b/wallets/provider-leap-cosmos/CHANGELOG.md new file mode 100644 index 0000000000..f8dda056c9 --- /dev/null +++ b/wallets/provider-leap-cosmos/CHANGELOG.md @@ -0,0 +1,146 @@ +# [0.41.0](https://github.com/rango-exchange/rango-client/compare/provider-leap-cosmos@0.40.0...provider-leap-cosmos@0.41.0) (2024-12-30) + + + +# [0.40.0](https://github.com/rango-exchange/rango-client/compare/provider-leap-cosmos@0.39.0...provider-leap-cosmos@0.40.0) (2024-11-27) + + + +# [0.39.0](https://github.com/rango-exchange/rango-client/compare/provider-leap-cosmos@0.38.1...provider-leap-cosmos@0.39.0) (2024-11-12) + + + +## [0.38.1](https://github.com/rango-exchange/rango-client/compare/provider-leap-cosmos@0.38.0...provider-leap-cosmos@0.38.1) (2024-11-06) + + + +# [0.38.0](https://github.com/rango-exchange/rango-client/compare/provider-leap-cosmos@0.37.0...provider-leap-cosmos@0.38.0) (2024-10-12) + + +### Bug Fixes + +* bump sdk and fix type issues ([d442208](https://github.com/rango-exchange/rango-client/commit/d4422083bf5dd27d5f509ce1db7f9560d05428c8)) + + +### Performance Improvements + +* lazy load signer packages ([7b88f18](https://github.com/rango-exchange/rango-client/commit/7b88f1834f7b29b4b81ab6c81a07bb88e8ccf55c)) + + + +# [0.37.0](https://github.com/rango-exchange/rango-client/compare/provider-leap-cosmos@0.36.0...provider-leap-cosmos@0.37.0) (2024-09-10) + + + +# [0.36.0](https://github.com/rango-exchange/rango-client/compare/provider-leap-cosmos@0.35.1...provider-leap-cosmos@0.36.0) (2024-08-11) + + + +## [0.35.1](https://github.com/rango-exchange/rango-client/compare/provider-leap-cosmos@0.35.0...provider-leap-cosmos@0.35.1) (2024-07-14) + + + +# [0.35.0](https://github.com/rango-exchange/rango-client/compare/provider-leap-cosmos@0.33.0...provider-leap-cosmos@0.35.0) (2024-07-09) + + + +# [0.34.0](https://github.com/rango-exchange/rango-client/compare/provider-leap-cosmos@0.33.0...provider-leap-cosmos@0.34.0) (2024-06-01) + + + +# [0.33.0](https://github.com/rango-exchange/rango-client/compare/provider-leap-cosmos@0.32.0...provider-leap-cosmos@0.33.0) (2024-05-14) + + + +# [0.32.0](https://github.com/rango-exchange/rango-client/compare/provider-leap-cosmos@0.31.0...provider-leap-cosmos@0.32.0) (2024-04-24) + + + +# [0.31.0](https://github.com/rango-exchange/rango-client/compare/provider-leap-cosmos@0.30.0...provider-leap-cosmos@0.31.0) (2024-04-23) + + + +# [0.30.0](https://github.com/rango-exchange/rango-client/compare/provider-leap-cosmos@0.29.0...provider-leap-cosmos@0.30.0) (2024-04-09) + + + +# [0.29.0](https://github.com/rango-exchange/rango-client/compare/provider-leap-cosmos@0.28.0...provider-leap-cosmos@0.29.0) (2024-03-12) + + + +# [0.28.0](https://github.com/rango-exchange/rango-client/compare/provider-leap-cosmos@0.27.0...provider-leap-cosmos@0.28.0) (2024-02-20) + + + +# [0.27.0](https://github.com/rango-exchange/rango-client/compare/provider-leap-cosmos@0.26.0...provider-leap-cosmos@0.27.0) (2024-02-07) + + + +# [0.26.0](https://github.com/rango-exchange/rango-client/compare/provider-leap-cosmos@0.25.0...provider-leap-cosmos@0.26.0) (2024-01-22) + + +### Bug Fixes + +* cleanup wallets' subscriber when setProvider get null ([88d6a42](https://github.com/rango-exchange/rango-client/commit/88d6a423c49b34b3d9ff567e22df36c3b009bb76)) + + + +# [0.25.0](https://github.com/rango-exchange/rango-client/compare/provider-leap-cosmos@0.23.0...provider-leap-cosmos@0.25.0) (2023-12-24) + + +### Bug Fixes + +* fix HMR for widget and playground ([8524820](https://github.com/rango-exchange/rango-client/commit/8524820f10cf0b8921f3db0c4f620ff98daa4103)) + + + +# [0.14.0](https://github.com/rango-exchange/rango-client/compare/provider-leap-cosmos@0.13.0...provider-leap-cosmos@0.14.0) (2023-08-03) + + + +# [0.13.0](https://github.com/rango-exchange/rango-client/compare/provider-leap-cosmos@0.12.0...provider-leap-cosmos@0.13.0) (2023-08-01) + + + +# [0.9.0](https://github.com/rango-exchange/rango-client/compare/provider-leap-cosmos@0.8.0...provider-leap-cosmos@0.9.0) (2023-07-31) + + + +# [0.7.0](https://github.com/rango-exchange/rango-client/compare/provider-leap-cosmos@0.6.0...provider-leap-cosmos@0.7.0) (2023-07-11) + + + +# [0.6.0](https://github.com/rango-exchange/rango-client/compare/provider-leap-cosmos@0.5.0...provider-leap-cosmos@0.6.0) (2023-07-11) + + +### Reverts + +* Revert "support for rango-types cjs format" ([ed4e050](https://github.com/rango-exchange/rango-client/commit/ed4e050bfc0dcde7aeffa6b0d73b02080a5721eb)) + + + +# [0.5.0](https://github.com/rango-exchange/rango-client/compare/provider-leap-cosmos@0.4.0...provider-leap-cosmos@0.5.0) (2023-05-31) + + + +# [0.4.0](https://github.com/rango-exchange/rango-client/compare/provider-leap-cosmos@0.3.0...provider-leap-cosmos@0.4.0) (2023-05-31) + + + +# [0.3.0](https://github.com/rango-exchange/rango-client/compare/provider-leap-cosmos@0.2.0...provider-leap-cosmos@0.3.0) (2023-05-30) + + + +# [0.2.0](https://github.com/rango-exchange/rango-client/compare/provider-leap-cosmos@0.1.15...provider-leap-cosmos@0.2.0) (2023-05-30) + + + +## [0.1.14](https://github.com/rango-exchange/rango-client/compare/provider-leap-cosmos@0.1.13...provider-leap-cosmos@0.1.14) (2023-05-15) + + +### Bug Fixes + +* update rango-types and fix notification bugs ([993f185](https://github.com/rango-exchange/rango-client/commit/993f185e0b8c5e5e15a2c65ba2d85d1f9c8daa90)) + + + diff --git a/wallets/provider-leap-cosmos/package.json b/wallets/provider-leap-cosmos/package.json index 7d77c812b1..e8862fefc1 100644 --- a/wallets/provider-leap-cosmos/package.json +++ b/wallets/provider-leap-cosmos/package.json @@ -1,49 +1,31 @@ { "name": "@rango-dev/provider-leap-cosmos", - "version": "0.1.12", + "version": "0.40.1-next.6", "license": "MIT", - "module": "dist/provider-leap-cosmos.esm.js", - "main": "dist/index.js", + "type": "module", + "source": "./src/index.ts", + "main": "./dist/index.js", + "exports": { + ".": "./dist/index.js" + }, "typings": "dist/index.d.ts", "files": [ "dist", "src" ], "scripts": { - "start": "tsdx watch", - "build": "tsdx build --tsconfig ./tsconfig.json", - "test": "tsdx test --passWithNoTests", - "lint": "tsdx lint", - "size": "size-limit", - "analyze": "size-limit --why" - }, - "husky": { - "hooks": { - "pre-commit": "tsdx lint" - } + "build": "node ../../scripts/build/command.mjs --path wallets/provider-leap-cosmos", + "ts-check": "tsc --declaration --emitDeclarationOnly -p ./tsconfig.json", + "clean": "rimraf dist", + "format": "prettier --write '{.,src}/**/*.{ts,tsx}'", + "lint": "eslint \"**/*.{ts,tsx}\" --ignore-path ../../.eslintignore" }, - "prettier": { - "printWidth": 80, - "semi": true, - "singleQuote": true, - "trailingComma": "es5" - }, - "size-limit": [ - { - "path": "dist/provider-leap-cosmos.cjs.production.min.js", - "limit": "10 KB" - }, - { - "path": "dist/provider-leap-cosmos.esm.js", - "limit": "10 KB" - } - ], "dependencies": { - "@rango-dev/signer-cosmos": "^0.1.11", - "@rango-dev/wallets-shared": "^0.1.11", - "rango-types": "^0.1.28" + "@rango-dev/signer-cosmos": "^0.30.1", + "@rango-dev/wallets-shared": "^0.40.1-next.6", + "rango-types": "^0.1.74" }, "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/wallets/provider-leap-cosmos/src/index.ts b/wallets/provider-leap-cosmos/src/index.ts index e2a02a91ee..5c920bec9b 100644 --- a/wallets/provider-leap-cosmos/src/index.ts +++ b/wallets/provider-leap-cosmos/src/index.ts @@ -1,46 +1,97 @@ -import { - Network, - WalletType, +import type { Connect, Subscribe, - getCosmosAccounts, + Suggest, WalletInfo, } from '@rango-dev/wallets-shared'; -import { leap_cosmos_instance, getSupportedChains } from './helpers'; -import signer from './signer'; -import { SignerFactory, cosmosBlockchains, BlockchainMeta } from 'rango-types'; +import type { BlockchainMeta, SignerFactory } from 'rango-types'; + +import { + getCosmosAccounts, + Networks, + suggestCosmosChain, + WalletTypes, +} from '@rango-dev/wallets-shared'; +import { cosmosBlockchains } from 'rango-types'; -const WALLET = WalletType.LEAP_COSMOS; +import { getSupportedChains, leap_cosmos_instance } from './helpers.js'; +import signer from './signer.js'; + +const WALLET = WalletTypes.LEAP_COSMOS; export const config = { type: WALLET, - defaultNetwork: Network.COSMOS, + defaultNetwork: Networks.COSMOS, }; +// TODO: check supported valid chain name : Some chain have different names +const supportedChainWithDifferentName: string[] = [ + Networks.COSMOS.toLowerCase(), + Networks.KI.toLowerCase(), + Networks.SECRET.toLowerCase(), + Networks.TERRA.toLowerCase(), +]; + export const getInstance = leap_cosmos_instance; export const connect: Connect = async ({ instance, network, meta }) => { const supportedChains = await getSupportedChains(instance); - const leapBlockchainMeta = meta.filter( - (chain) => + + const leapBlockchainMeta = meta.filter((chain) => { + const isChainSupported = supportedChains.includes(chain.name.toLowerCase()); + const isNetworkMatch = chain.name === network; + const isDifferentNameSupported = supportedChainWithDifferentName.includes( + chain.name.toLocaleLowerCase() + ); + + return ( chain.enabled && - (supportedChains.includes(chain.name.toLowerCase()) || - chain.name === network) - ); + (isChainSupported || isNetworkMatch || isDifferentNameSupported) + ); + }); + const results = await getCosmosAccounts({ instance, meta: leapBlockchainMeta, + network: network || Networks.COSMOS, }); return results; }; export const subscribe: Subscribe = ({ connect, disconnect }) => { - window.addEventListener('leap_keystorechange', () => { + const handleAccountsChanged = () => { disconnect(); connect(); + }; + window.addEventListener('leap_keystorechange', handleAccountsChanged); + return () => { + window.removeEventListener('leap_keystorechange', handleAccountsChanged); + }; +}; + +export const suggest: Suggest = async (options) => { + const { instance, meta, network } = options; + + const supportedChains = await getSupportedChains(instance); + const leapBlockchainMeta = meta.filter((chain) => { + const isChainSupported = supportedChains.includes(chain.name.toLowerCase()); + const isNetworkMatch = chain.name === network; + const isDifferentNameSupported = supportedChainWithDifferentName.includes( + chain.name.toLocaleLowerCase() + ); + + return ( + chain.enabled && + (isChainSupported || isNetworkMatch || isDifferentNameSupported) + ); + }); + await suggestCosmosChain({ + instance, + meta: leapBlockchainMeta, + network, }); }; -export const getSigners: (provider: any) => SignerFactory = signer; +export const getSigners: (provider: any) => Promise = signer; export const getWalletInfo: (allBlockChains: BlockchainMeta[]) => WalletInfo = ( allBlockChains @@ -48,7 +99,7 @@ export const getWalletInfo: (allBlockChains: BlockchainMeta[]) => WalletInfo = ( const cosmos = cosmosBlockchains(allBlockChains); return { name: 'Leap Cosmos', - img: 'https://raw.githubusercontent.com/rango-exchange/rango-types/main/assets/icons/wallets/leap-cosmos.png', + img: 'https://raw.githubusercontent.com/rango-exchange/assets/main/wallets/leap-cosmos/icon.svg', installLink: { CHROME: 'https://chrome.google.com/webstore/detail/leap-cosmos-wallet/fcfcfllfndlomdhbehjjcoimbgofdncg', diff --git a/wallets/provider-leap-cosmos/src/signer.ts b/wallets/provider-leap-cosmos/src/signer.ts index e1210db76d..6bc073e6e9 100644 --- a/wallets/provider-leap-cosmos/src/signer.ts +++ b/wallets/provider-leap-cosmos/src/signer.ts @@ -1,10 +1,14 @@ -import { DefaultCosmosSigner } from '@rango-dev/signer-cosmos'; -import { Network, getNetworkInstance } from '@rango-dev/wallets-shared'; -import { SignerFactory, TransactionType as TxType } from 'rango-types'; +import type { SignerFactory } from 'rango-types'; -export default function getSigners(provider: any): SignerFactory { - const cosmosProvider = getNetworkInstance(provider, Network.COSMOS); - const signers = new SignerFactory(); +import { getNetworkInstance, Networks } from '@rango-dev/wallets-shared'; +import { DefaultSignerFactory, TransactionType as TxType } from 'rango-types'; + +export default async function getSigners( + provider: any +): Promise { + const cosmosProvider = getNetworkInstance(provider, Networks.COSMOS); + const signers = new DefaultSignerFactory(); + const { DefaultCosmosSigner } = await import('@rango-dev/signer-cosmos'); signers.registerSigner( TxType.COSMOS, new DefaultCosmosSigner(cosmosProvider) diff --git a/wallets/provider-leap-cosmos/tsconfig.build.json b/wallets/provider-leap-cosmos/tsconfig.build.json new file mode 100644 index 0000000000..d9181ce0cd --- /dev/null +++ b/wallets/provider-leap-cosmos/tsconfig.build.json @@ -0,0 +1,11 @@ +{ + // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs + "extends": "../../tsconfig.libnext.json", + "include": ["src", "types", "../../global-wallets-env.d.ts"], + "compilerOptions": { + "outDir": "dist", + "rootDir": "./src", + "lib": ["dom", "esnext"] + // match output dir to input dir. e.g. dist/index instead of dist/src/index + } +} diff --git a/wallets/provider-leap-cosmos/tsconfig.json b/wallets/provider-leap-cosmos/tsconfig.json index 365489616a..a3a0b0f59d 100644 --- a/wallets/provider-leap-cosmos/tsconfig.json +++ b/wallets/provider-leap-cosmos/tsconfig.json @@ -1,35 +1 @@ -{ - // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs - "include": ["src", "types", "../../global-wallets-env.d.ts"], - "compilerOptions": { - "module": "esnext", - "lib": ["dom", "esnext"], - "importHelpers": true, - // output .d.ts declaration files for consumers - "declaration": true, - // output .js.map sourcemap files for consumers - "sourceMap": true, - // match output dir to input dir. e.g. dist/index instead of dist/src/index - "rootDir": "./src", - // stricter type-checking for stronger correctness. Recommended by TS - "strict": true, - // linter checks for common issues - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true, - // noUnused* overlap with @typescript-eslint/no-unused-vars, can disable if duplicative - "noUnusedLocals": true, - "noUnusedParameters": true, - // use Node's module resolution algorithm, instead of the legacy TS one - "moduleResolution": "node", - // transpile JSX to React.createElement - "jsx": "react", - // interop between ESM and CJS modules. Recommended by TS - "esModuleInterop": true, - // significant perf increase by skipping checking .d.ts files, particularly those in node_modules. Recommended by TS - "skipLibCheck": true, - // error out if import and file system have a casing mismatch. Recommended by TS - "forceConsistentCasingInFileNames": true, - // `tsdx build` ignores this option, but it is commonly used when type-checking separately with `tsc` - "noEmit": true, - } -} +{ "extends": "./tsconfig.build.json", "include": ["src", "tests"] } diff --git a/wallets/provider-ledger/CHANGELOG.md b/wallets/provider-ledger/CHANGELOG.md new file mode 100644 index 0000000000..f7de41b145 --- /dev/null +++ b/wallets/provider-ledger/CHANGELOG.md @@ -0,0 +1,96 @@ +# [0.11.0](https://github.com/rango-exchange/rango-client/compare/provider-ledger@0.10.0...provider-ledger@0.11.0) (2024-12-30) + + + +# [0.10.0](https://github.com/rango-exchange/rango-client/compare/provider-ledger@0.9.0...provider-ledger@0.10.0) (2024-11-27) + + +### Features + +* add ton connect provider ([2a2dbb7](https://github.com/rango-exchange/rango-client/commit/2a2dbb79022263f19446ced49d298e04d63f927f)) + + + +# [0.9.0](https://github.com/rango-exchange/rango-client/compare/provider-ledger@0.8.0...provider-ledger@0.9.0) (2024-11-12) + + + +# [0.8.0](https://github.com/rango-exchange/rango-client/compare/provider-ledger@0.7.1...provider-ledger@0.8.0) (2024-10-12) + + +### Bug Fixes + +* bump sdk and fix type issues ([d442208](https://github.com/rango-exchange/rango-client/commit/d4422083bf5dd27d5f509ce1db7f9560d05428c8)) + + +### Performance Improvements + +* enable code splitting in build process ([fe5a41e](https://github.com/rango-exchange/rango-client/commit/fe5a41e0e297298de11cd74ca5825544742aa03a)) +* lazy load signer packages ([7b88f18](https://github.com/rango-exchange/rango-client/commit/7b88f1834f7b29b4b81ab6c81a07bb88e8ccf55c)) + + + +## [0.7.1](https://github.com/rango-exchange/rango-client/compare/provider-ledger@0.7.0...provider-ledger@0.7.1) (2024-09-25) + + + +# [0.7.0](https://github.com/rango-exchange/rango-client/compare/provider-ledger@0.6.0...provider-ledger@0.7.0) (2024-09-10) + + + +# [0.6.0](https://github.com/rango-exchange/rango-client/compare/provider-ledger@0.5.1...provider-ledger@0.6.0) (2024-08-11) + + +### Features + +* add derivation path modal for trezor wallet ([364422f](https://github.com/rango-exchange/rango-client/commit/364422f099b202a27a529591c5e3628bbb35508d)) +* implement sign message method for providers with a custom signer ([cf9515f](https://github.com/rango-exchange/rango-client/commit/cf9515feb5d3754aac9c228fe83315daf1350c85)) + + + +## [0.5.1](https://github.com/rango-exchange/rango-client/compare/provider-ledger@0.5.0...provider-ledger@0.5.1) (2024-07-14) + + + +# [0.5.0](https://github.com/rango-exchange/rango-client/compare/provider-ledger@0.3.0...provider-ledger@0.5.0) (2024-07-09) + + +### Bug Fixes + +* exclud ledger on mobile and fix injected wallet bug ([a6d90aa](https://github.com/rango-exchange/rango-client/commit/a6d90aa01b7b1fcea01ab46d1a74583ff6f98ff8)) + + +### Features + +* add a modal for setting custom derivation path for ledger ([5b74ec0](https://github.com/rango-exchange/rango-client/commit/5b74ec049393ed74e3e7547edc72b68bd70b7dce)) +* add support for Trezor hardware wallet ([6edecbb](https://github.com/rango-exchange/rango-client/commit/6edecbb14fd008fc741c892bfa3e025c10160b9b)) + + + +# [0.4.0](https://github.com/rango-exchange/rango-client/compare/provider-ledger@0.3.0...provider-ledger@0.4.0) (2024-06-01) + + +### Bug Fixes + +* exclud ledger on mobile and fix injected wallet bug ([a6d90aa](https://github.com/rango-exchange/rango-client/commit/a6d90aa01b7b1fcea01ab46d1a74583ff6f98ff8)) + + + +# [0.3.0](https://github.com/rango-exchange/rango-client/compare/provider-ledger@0.2.0...provider-ledger@0.3.0) (2024-05-14) + + +### Features + +* add solana to ledger ([77b6695](https://github.com/rango-exchange/rango-client/commit/77b6695758165f9258a0ba5bd3b2cf39b0b2aab5)) + + + +# 0.2.0 (2024-04-24) + + +### Features + +* add ethereum for ledger ([084aae2](https://github.com/rango-exchange/rango-client/commit/084aae28adaf0310dffe3a3100dd783252393053)) + + + diff --git a/wallets/provider-ledger/package.json b/wallets/provider-ledger/package.json new file mode 100644 index 0000000000..979077ed9c --- /dev/null +++ b/wallets/provider-ledger/package.json @@ -0,0 +1,41 @@ +{ + "name": "@rango-dev/provider-ledger", + "version": "0.10.1-next.6", + "license": "MIT", + "type": "module", + "source": "./src/index.ts", + "main": "./dist/index.js", + "exports": { + ".": "./dist/index.js" + }, + "typings": "dist/index.d.ts", + "files": [ + "dist", + "src" + ], + "scripts": { + "build": "node ../../scripts/build/command.mjs --path wallets/provider-ledger --splitting --external-all-except @ledgerhq/errors,@ledgerhq/hw-app-eth,@ledgerhq/hw-app-solana,@ledgerhq/hw-transport-webhid,@ledgerhq/types-cryptoassets,@ledgerhq/types-devices,", + "ts-check": "tsc --declaration --emitDeclarationOnly -p ./tsconfig.json", + "clean": "rimraf dist", + "format": "prettier --write '{.,src}/**/*.{ts,tsx}'", + "lint": "eslint \"**/*.{ts,tsx}\" --ignore-path ../../.eslintignore" + }, + "dependencies": { + "@ledgerhq/errors": "^6.16.4", + "@ledgerhq/hw-app-eth": "^6.36.0", + "@ledgerhq/hw-app-solana": "^7.1.6", + "@ledgerhq/hw-transport-webhid": "^6.28.6", + "@ledgerhq/types-cryptoassets": "^7.11.0", + "@ledgerhq/types-devices": "^6.24.0", + "@rango-dev/signer-solana": "^0.35.1-next.0", + "@rango-dev/wallets-shared": "^0.40.1-next.6", + "@solana/web3.js": "^1.91.4", + "@types/w3c-web-hid": "^1.0.2", + "bs58": "^5.0.0", + "ethers": "^6.13.2", + "rango-types": "^0.1.74" + }, + "publishConfig": { + "access": "public" + } +} \ No newline at end of file diff --git a/wallets/provider-ledger/readme.md b/wallets/provider-ledger/readme.md new file mode 100644 index 0000000000..0dc03edd5e --- /dev/null +++ b/wallets/provider-ledger/readme.md @@ -0,0 +1 @@ +# @rango-dev/provider-ledger diff --git a/wallets/provider-ledger/src/helpers.ts b/wallets/provider-ledger/src/helpers.ts new file mode 100644 index 0000000000..ec97939e6b --- /dev/null +++ b/wallets/provider-ledger/src/helpers.ts @@ -0,0 +1,120 @@ +import type Transport from '@ledgerhq/hw-transport'; + +import { getAltStatusMessage } from '@ledgerhq/errors'; +import { ETHEREUM_CHAIN_ID, Networks } from '@rango-dev/wallets-shared'; +import bs58 from 'bs58'; + +import { getDerivationPath } from './state.js'; + +export const HEXADECIMAL_BASE = 16; + +const ledgerFrequentErrorMessages: { [statusCode: number]: string } = { + 0x5515: 'The device is locked', + 0x650f: 'Related application is not ready on your device', + 0x6985: 'Action denied by user', +}; + +function getLedgerErrorMessage(statusCode: number): string { + if (ledgerFrequentErrorMessages[statusCode]) { + return ledgerFrequentErrorMessages[statusCode]; + } else if (getAltStatusMessage(statusCode)) { + return getAltStatusMessage(statusCode) as string; + } + + return `Ledger device unknown error 0x${statusCode.toString( + HEXADECIMAL_BASE + )}`; // Hexadecimal numbers are more commonly recognized and utilized for representing ledger error codes +} + +export function getLedgerError(error: any) { + if (error?.statusCode) { + return new Error(getLedgerErrorMessage(error.statusCode)); + } + + if (error?.code === 'INSUFFICIENT_FUNDS') { + return new Error('Insufficient funds for transaction'); + } + return error; +} + +export function getLedgerInstance() { + /* + * Instances have a required property which is `chainId` and is using in swap execution. + * Here we are setting it as Ethereum always since we are supporting only eth for now. + */ + const instances = new Map(); + + instances.set(Networks.ETHEREUM, { chainId: ETHEREUM_CHAIN_ID }); + instances.set(Networks.SOLANA, { chainId: Networks.SOLANA }); + + return instances; +} + +export async function getEthereumAccounts(): Promise<{ + accounts: string[]; + chainId: string; +}> { + try { + const transport = await transportConnect(); + + const eth = new (await import('@ledgerhq/hw-app-eth')).default(transport); + + const accounts: string[] = []; + + const result = await eth.getAddress(getDerivationPath(), false, true); + accounts.push(result.address); + + return { + accounts: accounts, + chainId: ETHEREUM_CHAIN_ID, + }; + } catch (error: any) { + throw getLedgerError(error); + } finally { + await transportDisconnect(); + } +} + +export async function getSolanaAccounts(): Promise<{ + accounts: string[]; + chainId: string; +}> { + try { + const transport = await transportConnect(); + + const solana = new (await import('@ledgerhq/hw-app-solana')).default( + transport + ); + + const accounts: string[] = []; + + const result = await solana.getAddress(getDerivationPath()); + accounts.push(bs58.encode(result.address)); + + return { + accounts: accounts, + chainId: Networks.SOLANA, + }; + } catch (error: any) { + throw getLedgerError(error); + } finally { + await transportDisconnect(); + } +} + +let transportConnection: Transport | null = null; + +export async function transportConnect() { + transportConnection = await ( + await import('@ledgerhq/hw-transport-webhid') + ).default.create(); + + return transportConnection; +} + +export async function transportDisconnect() { + if (transportConnection) { + await transportConnection.close(); + transportConnection = null; + } +} diff --git a/wallets/provider-ledger/src/index.ts b/wallets/provider-ledger/src/index.ts new file mode 100644 index 0000000000..6f099e4b15 --- /dev/null +++ b/wallets/provider-ledger/src/index.ts @@ -0,0 +1,148 @@ +import type { + Connect, + Disconnect, + ProviderConnectResult, + WalletInfo, +} from '@rango-dev/wallets-shared'; + +import { Networks, WalletTypes } from '@rango-dev/wallets-shared'; +import { type BlockchainMeta, type SignerFactory } from 'rango-types'; + +import { + getEthereumAccounts, + getLedgerInstance, + getSolanaAccounts, + transportDisconnect, +} from './helpers.js'; +import signer from './signer.js'; +import { setDerivationPath } from './state.js'; + +export const config = { + type: WalletTypes.LEDGER, +}; + +export const getInstance = getLedgerInstance; +export const connect: Connect = async ({ namespaces }) => { + const results: ProviderConnectResult[] = []; + + const solanaNamespace = namespaces?.find( + (namespaceItem) => namespaceItem.namespace === 'Solana' + ); + const evmNamespace = namespaces?.find( + (namespaceItem) => namespaceItem.namespace === 'EVM' + ); + + if (solanaNamespace) { + if (solanaNamespace.derivationPath) { + setDerivationPath(solanaNamespace.derivationPath); + const accounts = await getSolanaAccounts(); + results.push(accounts); + } else { + throw new Error('Derivation Path can not be empty.'); + } + } else if (evmNamespace) { + if (evmNamespace.derivationPath) { + setDerivationPath(evmNamespace.derivationPath); + const accounts = await getEthereumAccounts(); + results.push(accounts); + } else { + throw new Error('Derivation Path can not be empty.'); + } + } else { + throw new Error( + `It appears that you have selected a namespace that is not yet supported by our system. Your namespaces: ${namespaces?.map( + (namespaceItem) => namespaceItem.namespace + )}` + ); + } + + return results; +}; + +export const disconnect: Disconnect = async () => { + void transportDisconnect(); +}; + +export const getSigners: (provider: any) => Promise = signer; + +export const getWalletInfo: (allBlockChains: BlockchainMeta[]) => WalletInfo = ( + allBlockChains +) => { + const supportedChains: BlockchainMeta[] = []; + + const ethereumBlockchain = allBlockChains.find( + (chain) => chain.name === Networks.ETHEREUM + ); + if (ethereumBlockchain) { + supportedChains.push(ethereumBlockchain); + } + + const solanaBlockchain = allBlockChains.find( + (chain) => chain.name === Networks.SOLANA + ); + if (solanaBlockchain) { + supportedChains.push(solanaBlockchain); + } + + return { + name: 'Ledger', + img: 'https://raw.githubusercontent.com/rango-exchange/assets/main/wallets/ledger/icon.svg', + installLink: { + DEFAULT: + 'https://support.ledger.com/hc/en-us/articles/4404389606417-Download-and-install-Ledger-Live?docs=true', + }, + color: 'black', + supportedChains, + showOnMobile: false, + needsDerivationPath: { + data: [ + { + id: 'metamask', + label: `Metamask (m/44'/60'/0'/0/index)`, + namespace: 'EVM', + generateDerivationPath: (index: string) => `44'/60'/0'/0/${index}`, + }, + { + id: 'ledgerLive', + label: `LedgerLive (m/44'/60'/index'/0/0)`, + namespace: 'EVM', + generateDerivationPath: (index: string) => `44'/60'/${index}'/0/0`, + }, + { + id: 'legacy', + label: `Legacy (m/44'/60'/0'/index)`, + namespace: 'EVM', + generateDerivationPath: (index: string) => `44'/60'/0'/${index}`, + }, + { + id: `(m/44'/501'/index')`, + label: `(m/44'/501'/index')`, + namespace: 'Solana', + generateDerivationPath: (index: string) => `44'/501'/${index}'`, + }, + { + id: `(m/44'/501'/0'/index)`, + label: `(m/44'/501'/0'/index)`, + namespace: 'Solana', + generateDerivationPath: (index: string) => `44'/501'/0'/${index}`, + }, + ], + }, + + needsNamespace: { + selection: 'single', + data: [ + { + label: 'EVM', + value: 'EVM', + id: 'ETH', + }, + { + label: 'Solana', + value: 'Solana', + id: 'SOLANA', + }, + ], + }, + }; +}; diff --git a/wallets/provider-ledger/src/signer.ts b/wallets/provider-ledger/src/signer.ts new file mode 100644 index 0000000000..1b65536d1d --- /dev/null +++ b/wallets/provider-ledger/src/signer.ts @@ -0,0 +1,12 @@ +import type { SignerFactory } from 'rango-types'; + +import { DefaultSignerFactory, TransactionType as TxType } from 'rango-types'; + +export default async function getSigners(): Promise { + const signers = new DefaultSignerFactory(); + const { EthereumSigner } = await import('./signers/ethereum.js'); + const { SolanaSigner } = await import('./signers/solana.js'); + signers.registerSigner(TxType.EVM, new EthereumSigner()); + signers.registerSigner(TxType.SOLANA, new SolanaSigner()); + return signers; +} diff --git a/wallets/provider-ledger/src/signers/ethereum.ts b/wallets/provider-ledger/src/signers/ethereum.ts new file mode 100644 index 0000000000..b49536f818 --- /dev/null +++ b/wallets/provider-ledger/src/signers/ethereum.ts @@ -0,0 +1,97 @@ +import type { TransactionLike } from 'ethers'; +import type { GenericSigner } from 'rango-types'; +import type { EvmTransaction } from 'rango-types/mainApi'; + +import Eth, { ledgerService } from '@ledgerhq/hw-app-eth'; +import { DEFAULT_ETHEREUM_RPC_URL } from '@rango-dev/wallets-shared'; +import { JsonRpcProvider, Transaction } from 'ethers'; +import { SignerError, SignerErrorCode } from 'rango-types'; + +import { + getLedgerError, + transportConnect, + transportDisconnect, +} from '../helpers.js'; +import { getDerivationPath } from '../state.js'; + +export class EthereumSigner implements GenericSigner { + async signMessage(msg: string): Promise { + try { + const transport = await transportConnect(); + + const eth = new Eth(transport); + const result = await eth.signPersonalMessage( + getDerivationPath(), + Buffer.from(msg).toString('hex') + ); + // eslint-disable-next-line @typescript-eslint/no-magic-numbers + let v = (result['v'] - 27).toString(16); + if (v.length < 2) { + v = '0' + v; + } + return '0x' + result['r'] + result['s'] + v; + } catch (error) { + throw new SignerError(SignerErrorCode.SIGN_TX_ERROR, undefined, error); + } + } + + async signAndSendTx( + tx: EvmTransaction, + fromAddress: string, + chainId: string | null + ): Promise<{ hash: string }> { + try { + const provider = new JsonRpcProvider(DEFAULT_ETHEREUM_RPC_URL); // Provider to broadcast transaction + + const transactionCount = await provider.getTransactionCount(fromAddress); // Get nonce + + const transaction: TransactionLike = { + to: tx.to, + gasPrice: tx.gasPrice, + gasLimit: tx.gasLimit, + nonce: transactionCount, + chainId: chainId, + data: tx.data, + value: tx.value, + maxPriorityFeePerGas: tx.maxPriorityFeePerGas, + maxFeePerGas: tx.maxFeePerGas, + }; + + const unsignedTx = + Transaction.from(transaction).unsignedSerialized.substring(2); // Create unsigned transaction + + const resolution = await ledgerService.resolveTransaction( + unsignedTx, + {}, + {} + ); // metadata necessary to allow the device to clear sign information + + const transport = await transportConnect(); + + const eth = new Eth(transport); + + const signature = await eth.signTransaction( + getDerivationPath(), + unsignedTx, + resolution + ); + + const signedTx = Transaction.from({ + ...transaction, + signature: { + r: '0x' + signature.r, + s: '0x' + signature.s, + v: parseInt(signature.v), + }, + }).serialized; + + const broadcastResult = await provider.broadcastTransaction(signedTx); + + return { hash: broadcastResult.hash }; + } catch (error) { + throw getLedgerError(error); + } finally { + await transportDisconnect(); + } + } +} diff --git a/wallets/provider-ledger/src/signers/solana.ts b/wallets/provider-ledger/src/signers/solana.ts new file mode 100644 index 0000000000..e8fdd8b97c --- /dev/null +++ b/wallets/provider-ledger/src/signers/solana.ts @@ -0,0 +1,85 @@ +import type { SolanaWeb3Signer } from '@rango-dev/signer-solana'; +import type { Transaction, VersionedTransaction } from '@solana/web3.js'; +import type { GenericSigner, SolanaTransaction } from 'rango-types'; + +import Solana from '@ledgerhq/hw-app-solana'; +import { generalSolanaTransactionExecutor } from '@rango-dev/signer-solana'; +import { PublicKey } from '@solana/web3.js'; +import { SignerError, SignerErrorCode } from 'rango-types'; + +import { + getLedgerError, + transportConnect, + transportDisconnect, +} from '../helpers.js'; +import { getDerivationPath } from '../state.js'; + +export function isVersionedTransaction( + transaction: Transaction | VersionedTransaction +): transaction is VersionedTransaction { + return 'version' in transaction; +} + +export class SolanaSigner implements GenericSigner { + async signMessage(msg: string): Promise { + try { + const transport = await transportConnect(); + + const solana = new Solana(transport); + + const result = await solana.signOffchainMessage( + getDerivationPath(), + Buffer.from(msg) + ); + return result.signature.toString(); + } catch (error) { + throw new SignerError(SignerErrorCode.SIGN_TX_ERROR, undefined, error); + } + } + + async signAndSendTx(tx: SolanaTransaction): Promise<{ hash: string }> { + try { + const DefaultSolanaSigner: SolanaWeb3Signer = async ( + solanaWeb3Transaction: Transaction | VersionedTransaction + ) => { + const transport = await transportConnect(); + const solana = new Solana(transport); + + let signResult; + if (isVersionedTransaction(solanaWeb3Transaction)) { + signResult = await solana.signTransaction( + getDerivationPath(), + solanaWeb3Transaction.message.serialize() as Buffer + ); + } else { + signResult = await solana.signTransaction( + getDerivationPath(), + solanaWeb3Transaction.serialize() + ); + } + + const addressResult = await solana.getAddress(getDerivationPath()); + + const publicKey = new PublicKey(addressResult.address); + + solanaWeb3Transaction.addSignature( + publicKey, + Buffer.from(signResult.signature) + ); + + const serializedTx = solanaWeb3Transaction.serialize(); + + return serializedTx; + }; + const hash = await generalSolanaTransactionExecutor( + tx, + DefaultSolanaSigner + ); + return { hash }; + } catch (error) { + throw getLedgerError(error); + } finally { + await transportDisconnect(); + } + } +} diff --git a/wallets/provider-ledger/src/state.ts b/wallets/provider-ledger/src/state.ts new file mode 100644 index 0000000000..e8cb68fd61 --- /dev/null +++ b/wallets/provider-ledger/src/state.ts @@ -0,0 +1,10 @@ +// We keep derivationPath here because we need to maintain it for signing transactions after it is set in connect method +let derivationPath = ''; + +export function setDerivationPath(path: string) { + derivationPath = path; +} + +export function getDerivationPath() { + return derivationPath; +} diff --git a/wallets/provider-ledger/tsconfig.build.json b/wallets/provider-ledger/tsconfig.build.json new file mode 100644 index 0000000000..9bb3c269bf --- /dev/null +++ b/wallets/provider-ledger/tsconfig.build.json @@ -0,0 +1,11 @@ +{ + // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs + "extends": "../../tsconfig.bundler.json", + "include": ["src", "types", "../../global-wallets-env.d.ts"], + "compilerOptions": { + "outDir": "dist", + "rootDir": "./src", + "lib": ["dom", "esnext"] + // match output dir to input dir. e.g. dist/index instead of dist/src/index + } +} diff --git a/wallets/provider-ledger/tsconfig.json b/wallets/provider-ledger/tsconfig.json new file mode 100644 index 0000000000..a3a0b0f59d --- /dev/null +++ b/wallets/provider-ledger/tsconfig.json @@ -0,0 +1 @@ +{ "extends": "./tsconfig.build.json", "include": ["src", "tests"] } diff --git a/wallets/provider-math-wallet/CHANGELOG.md b/wallets/provider-math-wallet/CHANGELOG.md new file mode 100644 index 0000000000..d637807033 --- /dev/null +++ b/wallets/provider-math-wallet/CHANGELOG.md @@ -0,0 +1,166 @@ +# [0.41.0](https://github.com/rango-exchange/rango-client/compare/provider-math-wallet@0.40.0...provider-math-wallet@0.41.0) (2024-12-30) + + + +# [0.40.0](https://github.com/rango-exchange/rango-client/compare/provider-math-wallet@0.39.0...provider-math-wallet@0.40.0) (2024-11-27) + + +### Features + +* add ton connect provider ([2a2dbb7](https://github.com/rango-exchange/rango-client/commit/2a2dbb79022263f19446ced49d298e04d63f927f)) + + + +# [0.39.0](https://github.com/rango-exchange/rango-client/compare/provider-math-wallet@0.38.0...provider-math-wallet@0.39.0) (2024-11-12) + + + +# [0.38.0](https://github.com/rango-exchange/rango-client/compare/provider-math-wallet@0.37.0...provider-math-wallet@0.38.0) (2024-10-12) + + +### Bug Fixes + +* bump sdk and fix type issues ([d442208](https://github.com/rango-exchange/rango-client/commit/d4422083bf5dd27d5f509ce1db7f9560d05428c8)) + + +### Performance Improvements + +* enable code splitting in build process ([fe5a41e](https://github.com/rango-exchange/rango-client/commit/fe5a41e0e297298de11cd74ca5825544742aa03a)) +* lazy load signer packages ([7b88f18](https://github.com/rango-exchange/rango-client/commit/7b88f1834f7b29b4b81ab6c81a07bb88e8ccf55c)) + + + +# [0.37.0](https://github.com/rango-exchange/rango-client/compare/provider-math-wallet@0.36.0...provider-math-wallet@0.37.0) (2024-09-10) + + + +# [0.36.0](https://github.com/rango-exchange/rango-client/compare/provider-math-wallet@0.35.1...provider-math-wallet@0.36.0) (2024-08-11) + + + +## [0.35.1](https://github.com/rango-exchange/rango-client/compare/provider-math-wallet@0.35.0...provider-math-wallet@0.35.1) (2024-07-14) + + + +# [0.35.0](https://github.com/rango-exchange/rango-client/compare/provider-math-wallet@0.33.2...provider-math-wallet@0.35.0) (2024-07-09) + + + +# [0.34.0](https://github.com/rango-exchange/rango-client/compare/provider-math-wallet@0.33.2...provider-math-wallet@0.34.0) (2024-06-01) + + + +## [0.33.2](https://github.com/rango-exchange/rango-client/compare/provider-math-wallet@0.33.1...provider-math-wallet@0.33.2) (2024-05-26) + + + +## [0.33.1](https://github.com/rango-exchange/rango-client/compare/provider-math-wallet@0.33.0...provider-math-wallet@0.33.1) (2024-05-25) + + + +# [0.33.0](https://github.com/rango-exchange/rango-client/compare/provider-math-wallet@0.32.0...provider-math-wallet@0.33.0) (2024-05-14) + + + +# [0.32.0](https://github.com/rango-exchange/rango-client/compare/provider-math-wallet@0.31.0...provider-math-wallet@0.32.0) (2024-04-24) + + + +# [0.31.0](https://github.com/rango-exchange/rango-client/compare/provider-math-wallet@0.30.0...provider-math-wallet@0.31.0) (2024-04-23) + + + +# [0.30.0](https://github.com/rango-exchange/rango-client/compare/provider-math-wallet@0.29.0...provider-math-wallet@0.30.0) (2024-04-09) + + + +# [0.29.0](https://github.com/rango-exchange/rango-client/compare/provider-math-wallet@0.28.0...provider-math-wallet@0.29.0) (2024-03-12) + + + +# [0.28.0](https://github.com/rango-exchange/rango-client/compare/provider-math-wallet@0.27.0...provider-math-wallet@0.28.0) (2024-02-20) + + +### Bug Fixes + +* fix cosmjs incompatible dependency version problem ([bf76c4c](https://github.com/rango-exchange/rango-client/commit/bf76c4ca19db0f28ceaa83d89982f0972ec730ac)) + + +### Features + +* add cosmos account and signer for math wallet ([e43a489](https://github.com/rango-exchange/rango-client/commit/e43a48936a63804d688f3ad1408244d7f2ff32f2)) + + + +# [0.27.0](https://github.com/rango-exchange/rango-client/compare/provider-math-wallet@0.26.0...provider-math-wallet@0.27.0) (2024-02-07) + + + +# [0.26.0](https://github.com/rango-exchange/rango-client/compare/provider-math-wallet@0.25.0...provider-math-wallet@0.26.0) (2024-01-22) + + +### Bug Fixes + +* cleanup wallets' subscriber when setProvider get null ([88d6a42](https://github.com/rango-exchange/rango-client/commit/88d6a423c49b34b3d9ff567e22df36c3b009bb76)) + + + +# [0.25.0](https://github.com/rango-exchange/rango-client/compare/provider-math-wallet@0.23.0...provider-math-wallet@0.25.0) (2023-12-24) + + +### Bug Fixes + +* fix HMR for widget and playground ([8524820](https://github.com/rango-exchange/rango-client/commit/8524820f10cf0b8921f3db0c4f620ff98daa4103)) + + + +# [0.14.0](https://github.com/rango-exchange/rango-client/compare/provider-math-wallet@0.13.0...provider-math-wallet@0.14.0) (2023-08-03) + + + +# [0.13.0](https://github.com/rango-exchange/rango-client/compare/provider-math-wallet@0.12.0...provider-math-wallet@0.13.0) (2023-08-01) + + + +# [0.9.0](https://github.com/rango-exchange/rango-client/compare/provider-math-wallet@0.8.0...provider-math-wallet@0.9.0) (2023-07-31) + + + +# [0.7.0](https://github.com/rango-exchange/rango-client/compare/provider-math-wallet@0.6.0...provider-math-wallet@0.7.0) (2023-07-11) + + + +# [0.6.0](https://github.com/rango-exchange/rango-client/compare/provider-math-wallet@0.5.0...provider-math-wallet@0.6.0) (2023-07-11) + + +### Reverts + +* Revert "support for rango-types cjs format" ([ed4e050](https://github.com/rango-exchange/rango-client/commit/ed4e050bfc0dcde7aeffa6b0d73b02080a5721eb)) + + + +# [0.5.0](https://github.com/rango-exchange/rango-client/compare/provider-math-wallet@0.4.0...provider-math-wallet@0.5.0) (2023-05-31) + + + +# [0.4.0](https://github.com/rango-exchange/rango-client/compare/provider-math-wallet@0.3.0...provider-math-wallet@0.4.0) (2023-05-31) + + + +# [0.3.0](https://github.com/rango-exchange/rango-client/compare/provider-math-wallet@0.2.0...provider-math-wallet@0.3.0) (2023-05-30) + + + +# [0.2.0](https://github.com/rango-exchange/rango-client/compare/provider-math-wallet@0.1.15...provider-math-wallet@0.2.0) (2023-05-30) + + + +## [0.1.14](https://github.com/rango-exchange/rango-client/compare/provider-math-wallet@0.1.13...provider-math-wallet@0.1.14) (2023-05-15) + + +### Bug Fixes + +* update rango-types and fix notification bugs ([993f185](https://github.com/rango-exchange/rango-client/commit/993f185e0b8c5e5e15a2c65ba2d85d1f9c8daa90)) + + + diff --git a/wallets/provider-math-wallet/package.json b/wallets/provider-math-wallet/package.json index bb588e8863..6de129991b 100644 --- a/wallets/provider-math-wallet/package.json +++ b/wallets/provider-math-wallet/package.json @@ -1,50 +1,33 @@ { "name": "@rango-dev/provider-math-wallet", - "version": "0.1.12", + "version": "0.40.1-next.6", "license": "MIT", - "module": "dist/provider-math-wallet.esm.js", - "main": "dist/index.js", + "type": "module", + "source": "./src/index.ts", + "main": "./dist/index.js", + "exports": { + ".": "./dist/index.js" + }, "typings": "dist/index.d.ts", "files": [ "dist", "src" ], "scripts": { - "start": "tsdx watch", - "build": "tsdx build --tsconfig ./tsconfig.json", - "test": "tsdx test --passWithNoTests", - "lint": "tsdx lint", - "size": "size-limit", - "analyze": "size-limit --why" - }, - "husky": { - "hooks": { - "pre-commit": "tsdx lint" - } + "build": "node ../../scripts/build/command.mjs --path wallets/provider-math-wallet --splitting", + "ts-check": "tsc --declaration --emitDeclarationOnly -p ./tsconfig.json", + "clean": "rimraf dist", + "format": "prettier --write '{.,src}/**/*.{ts,tsx}'", + "lint": "eslint \"**/*.{ts,tsx}\" --ignore-path ../../.eslintignore" }, - "prettier": { - "printWidth": 80, - "semi": true, - "singleQuote": true, - "trailingComma": "es5" - }, - "size-limit": [ - { - "path": "dist/provider-math-wallet.cjs.production.min.js", - "limit": "10 KB" - }, - { - "path": "dist/provider-math-wallet.esm.js", - "limit": "10 KB" - } - ], "dependencies": { - "@rango-dev/signer-evm": "^0.1.11", - "@rango-dev/signer-solana": "^0.1.11", - "@rango-dev/wallets-shared": "^0.1.11", - "rango-types": "^0.1.28" + "@cosmjs/stargate": "^0.31.0", + "@rango-dev/signer-evm": "^0.32.0", + "@rango-dev/signer-solana": "^0.35.1-next.0", + "@rango-dev/wallets-shared": "^0.40.1-next.6", + "rango-types": "^0.1.74" }, "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/wallets/provider-math-wallet/src/helpers.ts b/wallets/provider-math-wallet/src/helpers.ts index bc400d24e1..7201f6d020 100644 --- a/wallets/provider-math-wallet/src/helpers.ts +++ b/wallets/provider-math-wallet/src/helpers.ts @@ -1,17 +1,28 @@ -import { Network, ProviderConnectResult } from '@rango-dev/wallets-shared'; +import type { Network, ProviderConnectResult } from '@rango-dev/wallets-shared'; + +import { Networks } from '@rango-dev/wallets-shared'; type Provider = Map; export function mathWallet() { const instances = new Map(); - const { solana, ethereum } = window; + const { solana, ethereum, offlineSigner } = window; + + if (!!solana && solana.isMathWallet) { + instances.set(Networks.SOLANA, solana); + } - if (!!solana && solana.isMathWallet) instances.set(Network.SOLANA, solana); + if (ethereum && ethereum.isMathWallet) { + instances.set(Networks.ETHEREUM, ethereum); + } - if (ethereum && ethereum.isMathWallet) - instances.set(Network.ETHEREUM, ethereum); + if (offlineSigner && offlineSigner.getAccounts) { + instances.set(Networks.COSMOS, offlineSigner); + } - if (instances.size === 0) return null; + if (instances.size === 0) { + return null; + } return instances; } @@ -20,10 +31,10 @@ export async function getNonEvmAccounts( instances: Provider ): Promise { // Getting Solana accounts - const solanaInstance = instances.get(Network.SOLANA); + const solanaInstance = instances.get(Networks.SOLANA); const results: ProviderConnectResult[] = []; - if (!!solanaInstance) { + if (solanaInstance) { // Asking for account from wallet. const solanaResponse = await solanaInstance.connect(); @@ -31,9 +42,22 @@ export async function getNonEvmAccounts( results.push({ accounts: [solanaAccounts], - chainId: Network.SOLANA, + chainId: Networks.SOLANA, }); } + // Getting Cosmos accounts + const cosmosInstance = instances.get(Networks.COSMOS); + if (cosmosInstance) { + const [firstAccount] = await cosmosInstance.getAccounts(); + + if (firstAccount) { + results.push({ + accounts: [firstAccount.address], + chainId: Networks.COSMOS, + }); + } + } + return results; } diff --git a/wallets/provider-math-wallet/src/index.ts b/wallets/provider-math-wallet/src/index.ts index adf0421469..43a90d6a77 100644 --- a/wallets/provider-math-wallet/src/index.ts +++ b/wallets/provider-math-wallet/src/index.ts @@ -1,37 +1,39 @@ -import { - Network, - WalletType, +import type { + CanEagerConnect, CanSwitchNetwork, Connect, ProviderConnectResult, Subscribe, + WalletInfo, +} from '@rango-dev/wallets-shared'; +import type { BlockchainMeta, SignerFactory } from 'rango-types'; + +import { + canEagerlyConnectToEvm, chooseInstance, getEvmAccounts, + Networks, subscribeToEvm, - WalletInfo, + WalletTypes, } from '@rango-dev/wallets-shared'; +import { evmBlockchains, solanaBlockchain } from 'rango-types'; + import { getNonEvmAccounts, mathWallet as mathWallet_instance, -} from './helpers'; -import signer from './signer'; -import { - SignerFactory, - evmBlockchains, - solanaBlockchain, - BlockchainMeta, -} from 'rango-types'; +} from './helpers.js'; +import signer from './signer.js'; -const WALLET = WalletType.MATH; +const WALLET = WalletTypes.MATH; export const config = { type: WALLET, - defaultNetwork: Network.ETHEREUM, + defaultNetwork: Networks.ETHEREUM, }; export const getInstance = mathWallet_instance; export const connect: Connect = async ({ instance, meta }) => { - const ethInstance = chooseInstance(instance, meta, Network.ETHEREUM); + const ethInstance = chooseInstance(instance, meta, Networks.ETHEREUM); let results: ProviderConnectResult[] = []; @@ -47,29 +49,46 @@ export const connect: Connect = async ({ instance, meta }) => { }; export const subscribe: Subscribe = (options) => { + let cleanup: ReturnType; const ethInstance = chooseInstance( options.instance, options.meta, - Network.ETHEREUM + Networks.ETHEREUM ); if (ethInstance) { - subscribeToEvm({ ...options, instance: ethInstance }); + cleanup = subscribeToEvm({ ...options, instance: ethInstance }); } + + return () => { + if (cleanup) { + cleanup(); + } + }; }; export const canSwitchNetworkTo: CanSwitchNetwork = () => false; -export const getSigners: (provider: any) => SignerFactory = signer; +export const getSigners: (provider: any) => Promise = signer; +export const canEagerConnect: CanEagerConnect = async ({ instance, meta }) => { + const evm_instance = chooseInstance(instance, meta, Networks.ETHEREUM); + if (evm_instance) { + return canEagerlyConnectToEvm({ instance: evm_instance, meta }); + } + return Promise.resolve(false); +}; export const getWalletInfo: (allBlockChains: BlockchainMeta[]) => WalletInfo = ( allBlockChains ) => { const evms = evmBlockchains(allBlockChains); const solana = solanaBlockchain(allBlockChains); + const cosmos = allBlockChains.filter( + (blockchainMeta) => blockchainMeta.name === Networks.COSMOS + ); return { name: 'Math Wallet', - img: 'https://raw.githubusercontent.com/rango-exchange/rango-types/main/assets/icons/wallets/math.png', + img: 'https://raw.githubusercontent.com/rango-exchange/assets/main/wallets/math/icon.svg', installLink: { CHROME: 'https://chrome.google.com/webstore/detail/math-wallet/afbcbjpbpfadlkmhmclhkeeodmamcflc', @@ -78,6 +97,6 @@ export const getWalletInfo: (allBlockChains: BlockchainMeta[]) => WalletInfo = ( DEFAULT: 'https://mathwallet.org/en-us/', }, color: '#2b2f25', - supportedChains: [...evms, ...solana], + supportedChains: [...evms, ...solana, ...cosmos], }; }; diff --git a/wallets/provider-math-wallet/src/signer.ts b/wallets/provider-math-wallet/src/signer.ts index 0585e651d9..2df36a2432 100644 --- a/wallets/provider-math-wallet/src/signer.ts +++ b/wallets/provider-math-wallet/src/signer.ts @@ -1,13 +1,32 @@ -import { DefaultEvmSigner } from '@rango-dev/signer-evm'; +import type { SignerFactory } from 'rango-types'; + import { DefaultSolanaSigner } from '@rango-dev/signer-solana'; -import { Network, getNetworkInstance } from '@rango-dev/wallets-shared'; -import { SignerFactory, TransactionType as TxType } from 'rango-types'; - -export default function getSigners(provider: any): SignerFactory { - const ethProvider = getNetworkInstance(provider, Network.ETHEREUM); - const solProvider = getNetworkInstance(provider, Network.SOLANA); - const signers = new SignerFactory(); - signers.registerSigner(TxType.EVM, new DefaultEvmSigner(ethProvider)); - signers.registerSigner(TxType.SOLANA, new DefaultSolanaSigner(solProvider)); +import { getNetworkInstance, Networks } from '@rango-dev/wallets-shared'; +import { DefaultSignerFactory, TransactionType as TxType } from 'rango-types'; + +export default async function getSigners( + provider: any +): Promise { + const ethProvider = getNetworkInstance(provider, Networks.ETHEREUM); + const solProvider = getNetworkInstance(provider, Networks.SOLANA); + const cosmosProvider = getNetworkInstance(provider, Networks.COSMOS); + + const signers = new DefaultSignerFactory(); + const { DefaultEvmSigner } = await import('@rango-dev/signer-evm'); + const { MathWalletCosmosSigner } = await import('./signers/cosmosSigner.js'); + + if (!!ethProvider) { + signers.registerSigner(TxType.EVM, new DefaultEvmSigner(ethProvider)); + } + if (!!solProvider) { + signers.registerSigner(TxType.SOLANA, new DefaultSolanaSigner(solProvider)); + } + if (!!cosmosProvider) { + signers.registerSigner( + TxType.COSMOS, + new MathWalletCosmosSigner(cosmosProvider) + ); + } + return signers; } diff --git a/wallets/provider-math-wallet/src/signers/cosmosSigner.ts b/wallets/provider-math-wallet/src/signers/cosmosSigner.ts new file mode 100644 index 0000000000..dab8993bc6 --- /dev/null +++ b/wallets/provider-math-wallet/src/signers/cosmosSigner.ts @@ -0,0 +1,97 @@ +import type { StdFee } from '@cosmjs/stargate'; +import type { CosmosTransaction, GenericSigner } from 'rango-types'; + +import { SigningStargateClient } from '@cosmjs/stargate'; +import { DEFAULT_COSMOS_RPC_URL } from '@rango-dev/wallets-shared'; +import { SignerError, SignerErrorCode } from 'rango-types'; + +const COSMOS_MESSAGE_TRANSFER_TYPE_URL = + '/ibc.applications.transfer.v1.MsgTransfer'; + +export class MathWalletCosmosSigner + implements GenericSigner +{ + private provider: any; + + constructor(provider: any) { + this.provider = provider; + } + + async signMessage(): Promise { + throw SignerError.UnimplementedError('signMessage'); + } + + async signAndSendTx(tx: CosmosTransaction): Promise<{ hash: string }> { + if (!this.provider) { + throw SignerError.AssertionFailed('wallet is null!'); + } + try { + const { + memo, + sequence, + account_number, + chainId, + msgs, + fee, + signType, + rpcUrl, + } = tx.data; + + if (!chainId) { + throw SignerError.AssertionFailed('chainId is undefined from server'); + } + if (!account_number) { + throw SignerError.AssertionFailed( + 'account_number is undefined from server' + ); + } + if (!sequence) { + throw SignerError.AssertionFailed('sequence is undefined from server'); + } + + if (signType === 'AMINO') { + const signingStargateClient = + await SigningStargateClient.connectWithSigner( + rpcUrl || DEFAULT_COSMOS_RPC_URL, + this.provider + ); + + const processedMsgs = msgs.map((msg: any) => ({ + typeUrl: COSMOS_MESSAGE_TRANSFER_TYPE_URL, + value: { + sourcePort: msg.value?.source_port, + sourceChannel: msg.value?.source_channel, + sender: msg.value?.sender, + receiver: msg.value?.receiver, + token: msg.value?.token, + timeoutHeight: msg.value?.timeout_height, + timeoutTimestamp: msg.value?.timeout_timestamp, + memo: msg.value?.memo, + }, + })); + + const signAndBroadcastResult = + await signingStargateClient.signAndBroadcastSync( + tx.fromWalletAddress, + processedMsgs, + fee as StdFee, + memo as string + ); + + return { hash: signAndBroadcastResult }; + } else if (signType === 'DIRECT') { + throw SignerError.UnimplementedError('signMessage'); + } + throw new SignerError( + SignerErrorCode.OPERATION_UNSUPPORTED, + `Sign type for cosmos not supported, type: ${signType}` + ); + } catch (err) { + if (SignerError.isSignerError(err)) { + throw err; + } else { + throw new SignerError(SignerErrorCode.SEND_TX_ERROR, undefined, err); + } + } + } +} diff --git a/wallets/provider-math-wallet/tsconfig.build.json b/wallets/provider-math-wallet/tsconfig.build.json new file mode 100644 index 0000000000..d9181ce0cd --- /dev/null +++ b/wallets/provider-math-wallet/tsconfig.build.json @@ -0,0 +1,11 @@ +{ + // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs + "extends": "../../tsconfig.libnext.json", + "include": ["src", "types", "../../global-wallets-env.d.ts"], + "compilerOptions": { + "outDir": "dist", + "rootDir": "./src", + "lib": ["dom", "esnext"] + // match output dir to input dir. e.g. dist/index instead of dist/src/index + } +} diff --git a/wallets/provider-math-wallet/tsconfig.json b/wallets/provider-math-wallet/tsconfig.json index 365489616a..a3a0b0f59d 100644 --- a/wallets/provider-math-wallet/tsconfig.json +++ b/wallets/provider-math-wallet/tsconfig.json @@ -1,35 +1 @@ -{ - // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs - "include": ["src", "types", "../../global-wallets-env.d.ts"], - "compilerOptions": { - "module": "esnext", - "lib": ["dom", "esnext"], - "importHelpers": true, - // output .d.ts declaration files for consumers - "declaration": true, - // output .js.map sourcemap files for consumers - "sourceMap": true, - // match output dir to input dir. e.g. dist/index instead of dist/src/index - "rootDir": "./src", - // stricter type-checking for stronger correctness. Recommended by TS - "strict": true, - // linter checks for common issues - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true, - // noUnused* overlap with @typescript-eslint/no-unused-vars, can disable if duplicative - "noUnusedLocals": true, - "noUnusedParameters": true, - // use Node's module resolution algorithm, instead of the legacy TS one - "moduleResolution": "node", - // transpile JSX to React.createElement - "jsx": "react", - // interop between ESM and CJS modules. Recommended by TS - "esModuleInterop": true, - // significant perf increase by skipping checking .d.ts files, particularly those in node_modules. Recommended by TS - "skipLibCheck": true, - // error out if import and file system have a casing mismatch. Recommended by TS - "forceConsistentCasingInFileNames": true, - // `tsdx build` ignores this option, but it is commonly used when type-checking separately with `tsc` - "noEmit": true, - } -} +{ "extends": "./tsconfig.build.json", "include": ["src", "tests"] } diff --git a/wallets/provider-metamask/CHANGELOG.md b/wallets/provider-metamask/CHANGELOG.md new file mode 100644 index 0000000000..f4d760726d --- /dev/null +++ b/wallets/provider-metamask/CHANGELOG.md @@ -0,0 +1,151 @@ +# [0.41.0](https://github.com/rango-exchange/rango-client/compare/provider-metamask@0.40.0...provider-metamask@0.41.0) (2024-12-30) + + + +# [0.40.0](https://github.com/rango-exchange/rango-client/compare/provider-metamask@0.39.0...provider-metamask@0.40.0) (2024-11-27) + + + +# [0.39.0](https://github.com/rango-exchange/rango-client/compare/provider-metamask@0.38.0...provider-metamask@0.39.0) (2024-11-12) + + + +# [0.38.0](https://github.com/rango-exchange/rango-client/compare/provider-metamask@0.37.0...provider-metamask@0.38.0) (2024-10-12) + + +### Bug Fixes + +* bump sdk and fix type issues ([d442208](https://github.com/rango-exchange/rango-client/commit/d4422083bf5dd27d5f509ce1db7f9560d05428c8)) + + +### Performance Improvements + +* lazy load signer packages ([7b88f18](https://github.com/rango-exchange/rango-client/commit/7b88f1834f7b29b4b81ab6c81a07bb88e8ccf55c)) + + + +# [0.37.0](https://github.com/rango-exchange/rango-client/compare/provider-metamask@0.36.0...provider-metamask@0.37.0) (2024-09-10) + + + +# [0.36.0](https://github.com/rango-exchange/rango-client/compare/provider-metamask@0.35.1...provider-metamask@0.36.0) (2024-08-11) + + + +## [0.35.1](https://github.com/rango-exchange/rango-client/compare/provider-metamask@0.35.0...provider-metamask@0.35.1) (2024-07-14) + + + +# [0.35.0](https://github.com/rango-exchange/rango-client/compare/provider-metamask@0.33.2...provider-metamask@0.35.0) (2024-07-09) + + + +# [0.34.0](https://github.com/rango-exchange/rango-client/compare/provider-metamask@0.33.2...provider-metamask@0.34.0) (2024-06-01) + + + +## [0.33.2](https://github.com/rango-exchange/rango-client/compare/provider-metamask@0.33.1...provider-metamask@0.33.2) (2024-05-26) + + + +## [0.33.1](https://github.com/rango-exchange/rango-client/compare/provider-metamask@0.33.0...provider-metamask@0.33.1) (2024-05-25) + + + +# [0.33.0](https://github.com/rango-exchange/rango-client/compare/provider-metamask@0.32.0...provider-metamask@0.33.0) (2024-05-14) + + + +# [0.32.0](https://github.com/rango-exchange/rango-client/compare/provider-metamask@0.31.0...provider-metamask@0.32.0) (2024-04-24) + + + +# [0.31.0](https://github.com/rango-exchange/rango-client/compare/provider-metamask@0.30.0...provider-metamask@0.31.0) (2024-04-23) + + +### Bug Fixes + +* resolve conflicts between evm providers ([9a6734c](https://github.com/rango-exchange/rango-client/commit/9a6734cf1537bf0504cf9058d4d775313a9e8e80)) + + + +# [0.30.0](https://github.com/rango-exchange/rango-client/compare/provider-metamask@0.29.0...provider-metamask@0.30.0) (2024-04-09) + + + +# [0.29.0](https://github.com/rango-exchange/rango-client/compare/provider-metamask@0.28.0...provider-metamask@0.29.0) (2024-03-12) + + + +# [0.28.0](https://github.com/rango-exchange/rango-client/compare/provider-metamask@0.27.0...provider-metamask@0.28.0) (2024-02-20) + + + +# [0.27.0](https://github.com/rango-exchange/rango-client/compare/provider-metamask@0.26.0...provider-metamask@0.27.0) (2024-02-07) + + + +# [0.26.0](https://github.com/rango-exchange/rango-client/compare/provider-metamask@0.25.0...provider-metamask@0.26.0) (2024-01-22) + + + +# [0.25.0](https://github.com/rango-exchange/rango-client/compare/provider-metamask@0.23.0...provider-metamask@0.25.0) (2023-12-24) + + +### Bug Fixes + +* fix HMR for widget and playground ([8524820](https://github.com/rango-exchange/rango-client/commit/8524820f10cf0b8921f3db0c4f620ff98daa4103)) + + + +# [0.14.0](https://github.com/rango-exchange/rango-client/compare/provider-metamask@0.13.0...provider-metamask@0.14.0) (2023-08-03) + + + +# [0.13.0](https://github.com/rango-exchange/rango-client/compare/provider-metamask@0.12.0...provider-metamask@0.13.0) (2023-08-01) + + + +# [0.9.0](https://github.com/rango-exchange/rango-client/compare/provider-metamask@0.8.0...provider-metamask@0.9.0) (2023-07-31) + + + +# [0.7.0](https://github.com/rango-exchange/rango-client/compare/provider-metamask@0.6.0...provider-metamask@0.7.0) (2023-07-11) + + + +# [0.6.0](https://github.com/rango-exchange/rango-client/compare/provider-metamask@0.5.0...provider-metamask@0.6.0) (2023-07-11) + + +### Reverts + +* Revert "support for rango-types cjs format" ([ed4e050](https://github.com/rango-exchange/rango-client/commit/ed4e050bfc0dcde7aeffa6b0d73b02080a5721eb)) +* Revert "support for rango-types cjs format" ([4f5f55f](https://github.com/rango-exchange/rango-client/commit/4f5f55f96e8daa329588b932b19c291c30f339c4)) + + + +# [0.5.0](https://github.com/rango-exchange/rango-client/compare/provider-metamask@0.4.0...provider-metamask@0.5.0) (2023-05-31) + + + +# [0.4.0](https://github.com/rango-exchange/rango-client/compare/provider-metamask@0.3.0...provider-metamask@0.4.0) (2023-05-31) + + + +# [0.3.0](https://github.com/rango-exchange/rango-client/compare/provider-metamask@0.2.0...provider-metamask@0.3.0) (2023-05-30) + + + +# [0.2.0](https://github.com/rango-exchange/rango-client/compare/provider-metamask@0.1.15...provider-metamask@0.2.0) (2023-05-30) + + + +## [0.1.14](https://github.com/rango-exchange/rango-client/compare/provider-metamask@0.1.13...provider-metamask@0.1.14) (2023-05-15) + + +### Bug Fixes + +* update rango-types and fix notification bugs ([993f185](https://github.com/rango-exchange/rango-client/commit/993f185e0b8c5e5e15a2c65ba2d85d1f9c8daa90)) + + + diff --git a/wallets/provider-metamask/package.json b/wallets/provider-metamask/package.json index cf854ea24e..a69d588e2c 100644 --- a/wallets/provider-metamask/package.json +++ b/wallets/provider-metamask/package.json @@ -1,49 +1,31 @@ { "name": "@rango-dev/provider-metamask", - "version": "0.1.12", + "version": "0.40.1-next.6", "license": "MIT", - "module": "dist/provider-metamask.esm.js", - "main": "dist/index.js", + "type": "module", + "source": "./src/index.ts", + "main": "./dist/index.js", + "exports": { + ".": "./dist/index.js" + }, "typings": "dist/index.d.ts", "files": [ "dist", "src" ], "scripts": { - "start": "tsdx watch", - "build": "tsdx build --tsconfig ./tsconfig.json", - "test": "tsdx test --passWithNoTests", - "lint": "tsdx lint", - "size": "size-limit", - "analyze": "size-limit --why" - }, - "husky": { - "hooks": { - "pre-commit": "tsdx lint" - } + "build": "node ../../scripts/build/command.mjs --path wallets/provider-metamask", + "ts-check": "tsc --declaration --emitDeclarationOnly -p ./tsconfig.json", + "clean": "rimraf dist", + "format": "prettier --write '{.,src}/**/*.{ts,tsx}'", + "lint": "eslint \"**/*.{ts,tsx}\" --ignore-path ../../.eslintignore" }, - "prettier": { - "printWidth": 80, - "semi": true, - "singleQuote": true, - "trailingComma": "es5" - }, - "size-limit": [ - { - "path": "dist/provider-metamask.cjs.production.min.js", - "limit": "10 KB" - }, - { - "path": "dist/provider-metamask.esm.js", - "limit": "10 KB" - } - ], "dependencies": { - "@rango-dev/signer-evm": "^0.1.11", - "@rango-dev/wallets-shared": "^0.1.11", - "rango-types": "^0.1.28" + "@rango-dev/signer-evm": "^0.32.0", + "@rango-dev/wallets-shared": "^0.40.1-next.6", + "rango-types": "^0.1.74" }, "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/wallets/provider-metamask/src/helpers.ts b/wallets/provider-metamask/src/helpers.ts index b8253a1c90..4734a62719 100644 --- a/wallets/provider-metamask/src/helpers.ts +++ b/wallets/provider-metamask/src/helpers.ts @@ -1,17 +1,95 @@ -import { getCoinbaseInstance } from '@rango-dev/wallets-shared'; +function isMetamaskProvider(ethereum: any): boolean { + const isMetamask = !!ethereum?.isMetaMask; + if (!isMetamask) { + return false; + } + /* + * Brave tries to make itself look like MetaMask + * Could also try RPC `web3_clientVersion` if following is unreliable + */ + if (ethereum.isBraveWallet && !ethereum._events && !ethereum._state) { + return false; + } + if (ethereum.isApexWallet) { + return false; + } + if (ethereum.isAvalanche) { + return false; + } + if (ethereum.isBitKeep) { + return false; + } + if (ethereum.isBlockWallet) { + return false; + } + if (ethereum.isCoin98) { + return false; + } + if (ethereum.isFordefi) { + return false; + } + if (ethereum.__XDEFI) { + return false; + } + if (ethereum.isMathWallet) { + return false; + } + if (ethereum.isOkxWallet || ethereum.isOKExWallet) { + return false; + } + if (ethereum.isOneInchIOSWallet || ethereum.isOneInchAndroidWallet) { + return false; + } + if (ethereum.isOpera) { + return false; + } + if (ethereum.isPortal) { + return false; + } + if (ethereum.isRabby) { + return false; + } + if (ethereum.isDefiant) { + return false; + } + if (ethereum.isTokenPocket) { + return false; + } + if (ethereum.isTokenary) { + return false; + } + if (ethereum.isZeal) { + return false; + } + if (ethereum.isZerion) { + return false; + } + return true; +} export function metamask() { - const isCoinbaseWalletAvailable = !!getCoinbaseInstance(); const { ethereum } = window; - // Some wallets overriding the metamask. So we need to get it properly. - if (isCoinbaseWalletAvailable) { - // Getting intance from overrided structure from coinbase. - return getCoinbaseInstance('metamask'); - } else { - if (!!ethereum && ethereum.isMetaMask) { - return ethereum; + if (Array.isArray(ethereum?.providers)) { + /* + * When alternative EVM wallets are enabled and take precedence over MetaMask, + * they append MetaMask or other EVM wallets to the ethereum.providers array. + * example: 'Core' wallet + */ + let providers = ethereum.providers; + //Exceptions exist, such as when only 'MetaMask' and 'Coinbase' are enabled. + if ( + providers.length > 0 && + Array.isArray(ethereum.providers[0]?.providers) && + providers[0]?.providers.length > 0 + ) { + providers = providers[0]?.providers; + } + + const metamaskProvider = providers.find(isMetamaskProvider); + if (metamaskProvider) { + return metamaskProvider; } } - return null; + return ethereum?.isMetaMask ? ethereum : null; } diff --git a/wallets/provider-metamask/src/index.ts b/wallets/provider-metamask/src/index.ts index 6ea9a8b33a..083508a935 100644 --- a/wallets/provider-metamask/src/index.ts +++ b/wallets/provider-metamask/src/index.ts @@ -1,20 +1,27 @@ -import { - WalletType, - WalletInfo, +import type { + CanEagerConnect, CanSwitchNetwork, Connect, Subscribe, SwitchNetwork, + WalletInfo, +} from '@rango-dev/wallets-shared'; +import type { BlockchainMeta, SignerFactory } from 'rango-types'; + +import { + canEagerlyConnectToEvm, canSwitchNetworkToEvm, getEvmAccounts, subscribeToEvm, switchNetworkForEvm, + WalletTypes, } from '@rango-dev/wallets-shared'; -import { metamask as metamask_instance } from './helpers'; -import signer from './signer'; -import { SignerFactory, evmBlockchains, BlockchainMeta } from 'rango-types'; +import { evmBlockchains } from 'rango-types'; -const WALLET = WalletType.META_MASK; +import { metamask as metamask_instance } from './helpers.js'; +import signer from './signer.js'; + +const WALLET = WalletTypes.META_MASK; export const config = { type: WALLET, @@ -22,10 +29,12 @@ export const config = { export const getInstance = metamask_instance; export const connect: Connect = async ({ instance }) => { - // Note: We need to get `chainId` here, because for the first time - // after opening the browser, wallet is locked, and don't give us accounts and chainId - // on `check` phase, so `network` will be null. For this case we need to get chainId - // whenever we are requesting accounts. + /* + * Note: We need to get `chainId` here, because for the first time + * after opening the browser, wallet is locked, and don't give us accounts and chainId + * on `check` phase, so `network` will be null. For this case we need to get chainId + * whenever we are requesting accounts. + */ const { accounts, chainId } = await getEvmAccounts(instance); return { @@ -40,7 +49,9 @@ export const switchNetwork: SwitchNetwork = switchNetworkForEvm; export const canSwitchNetworkTo: CanSwitchNetwork = canSwitchNetworkToEvm; -export const getSigners: (provider: any) => SignerFactory = signer; +export const getSigners: (provider: any) => Promise = signer; + +export const canEagerConnect: CanEagerConnect = canEagerlyConnectToEvm; export const getWalletInfo: (allBlockChains: BlockchainMeta[]) => WalletInfo = ( allBlockChains @@ -48,7 +59,7 @@ export const getWalletInfo: (allBlockChains: BlockchainMeta[]) => WalletInfo = ( const evms = evmBlockchains(allBlockChains); return { name: 'MetaMask', - img: 'https://raw.githubusercontent.com/rango-exchange/rango-types/main/assets/icons/wallets/metamask.svg', + img: 'https://raw.githubusercontent.com/rango-exchange/assets/main/wallets/metamask/icon.svg', installLink: { CHROME: 'https://chrome.google.com/webstore/detail/metamask/nkbihfbeogaeaoehlefnkodbefgpgknn?hl=en', diff --git a/wallets/provider-metamask/src/signer.ts b/wallets/provider-metamask/src/signer.ts index 5dc8b3a754..f7dbf93750 100644 --- a/wallets/provider-metamask/src/signer.ts +++ b/wallets/provider-metamask/src/signer.ts @@ -1,8 +1,12 @@ -import { DefaultEvmSigner } from '@rango-dev/signer-evm'; -import { SignerFactory, TransactionType as TxType } from 'rango-types'; +import type { SignerFactory } from 'rango-types'; -export default function getSigners(provider: any): SignerFactory { - const signers = new SignerFactory(); +import { DefaultSignerFactory, TransactionType as TxType } from 'rango-types'; + +export default async function getSigners( + provider: any +): Promise { + const signers = new DefaultSignerFactory(); + const { DefaultEvmSigner } = await import('@rango-dev/signer-evm'); signers.registerSigner(TxType.EVM, new DefaultEvmSigner(provider)); return signers; } diff --git a/wallets/provider-metamask/tsconfig.build.json b/wallets/provider-metamask/tsconfig.build.json new file mode 100644 index 0000000000..d9181ce0cd --- /dev/null +++ b/wallets/provider-metamask/tsconfig.build.json @@ -0,0 +1,11 @@ +{ + // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs + "extends": "../../tsconfig.libnext.json", + "include": ["src", "types", "../../global-wallets-env.d.ts"], + "compilerOptions": { + "outDir": "dist", + "rootDir": "./src", + "lib": ["dom", "esnext"] + // match output dir to input dir. e.g. dist/index instead of dist/src/index + } +} diff --git a/wallets/provider-metamask/tsconfig.json b/wallets/provider-metamask/tsconfig.json index 365489616a..a3a0b0f59d 100644 --- a/wallets/provider-metamask/tsconfig.json +++ b/wallets/provider-metamask/tsconfig.json @@ -1,35 +1 @@ -{ - // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs - "include": ["src", "types", "../../global-wallets-env.d.ts"], - "compilerOptions": { - "module": "esnext", - "lib": ["dom", "esnext"], - "importHelpers": true, - // output .d.ts declaration files for consumers - "declaration": true, - // output .js.map sourcemap files for consumers - "sourceMap": true, - // match output dir to input dir. e.g. dist/index instead of dist/src/index - "rootDir": "./src", - // stricter type-checking for stronger correctness. Recommended by TS - "strict": true, - // linter checks for common issues - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true, - // noUnused* overlap with @typescript-eslint/no-unused-vars, can disable if duplicative - "noUnusedLocals": true, - "noUnusedParameters": true, - // use Node's module resolution algorithm, instead of the legacy TS one - "moduleResolution": "node", - // transpile JSX to React.createElement - "jsx": "react", - // interop between ESM and CJS modules. Recommended by TS - "esModuleInterop": true, - // significant perf increase by skipping checking .d.ts files, particularly those in node_modules. Recommended by TS - "skipLibCheck": true, - // error out if import and file system have a casing mismatch. Recommended by TS - "forceConsistentCasingInFileNames": true, - // `tsdx build` ignores this option, but it is commonly used when type-checking separately with `tsc` - "noEmit": true, - } -} +{ "extends": "./tsconfig.build.json", "include": ["src", "tests"] } diff --git a/wallets/provider-mytonwallet/CHANGELOG.md b/wallets/provider-mytonwallet/CHANGELOG.md new file mode 100644 index 0000000000..eee4320ea4 --- /dev/null +++ b/wallets/provider-mytonwallet/CHANGELOG.md @@ -0,0 +1,92 @@ +# [0.26.0](https://github.com/rango-exchange/rango-client/compare/provider-mytonwallet@0.25.0...provider-mytonwallet@0.26.0) (2024-12-30) + + + +# [0.25.0](https://github.com/rango-exchange/rango-client/compare/provider-mytonwallet@0.24.0...provider-mytonwallet@0.25.0) (2024-11-27) + + +### Bug Fixes + +* improve ton signer and mytonwallet provider ([7027755](https://github.com/rango-exchange/rango-client/commit/7027755740426359f42b088b842dfd01590df5c3)) + + + +# [0.24.0](https://github.com/rango-exchange/rango-client/compare/provider-mytonwallet@0.23.0...provider-mytonwallet@0.24.0) (2024-11-12) + + + +# [0.23.0](https://github.com/rango-exchange/rango-client/compare/provider-mytonwallet@0.22.0...provider-mytonwallet@0.23.0) (2024-10-12) + + +### Bug Fixes + +* bump sdk and fix type issues ([d442208](https://github.com/rango-exchange/rango-client/commit/d4422083bf5dd27d5f509ce1db7f9560d05428c8)) + + +### Performance Improvements + +* lazy load signer packages ([7b88f18](https://github.com/rango-exchange/rango-client/commit/7b88f1834f7b29b4b81ab6c81a07bb88e8ccf55c)) + + + +# [0.22.0](https://github.com/rango-exchange/rango-client/compare/provider-mytonwallet@0.21.0...provider-mytonwallet@0.22.0) (2024-09-10) + + + +# [0.21.0](https://github.com/rango-exchange/rango-client/compare/provider-mytonwallet@0.20.1...provider-mytonwallet@0.21.0) (2024-08-11) + + + +## [0.20.1](https://github.com/rango-exchange/rango-client/compare/provider-mytonwallet@0.20.0...provider-mytonwallet@0.20.1) (2024-07-14) + + + +# [0.20.0](https://github.com/rango-exchange/rango-client/compare/provider-mytonwallet@0.18.0...provider-mytonwallet@0.20.0) (2024-07-09) + + + +# [0.19.0](https://github.com/rango-exchange/rango-client/compare/provider-mytonwallet@0.18.0...provider-mytonwallet@0.19.0) (2024-06-01) + + + +# [0.18.0](https://github.com/rango-exchange/rango-client/compare/provider-mytonwallet@0.17.0...provider-mytonwallet@0.18.0) (2024-05-14) + + + +# [0.17.0](https://github.com/rango-exchange/rango-client/compare/provider-mytonwallet@0.16.0...provider-mytonwallet@0.17.0) (2024-04-24) + + + +# [0.16.0](https://github.com/rango-exchange/rango-client/compare/provider-mytonwallet@0.15.0...provider-mytonwallet@0.16.0) (2024-04-23) + + + +# [0.15.0](https://github.com/rango-exchange/rango-client/compare/provider-mytonwallet@0.14.0...provider-mytonwallet@0.15.0) (2024-04-09) + + + +# [0.14.0](https://github.com/rango-exchange/rango-client/compare/provider-mytonwallet@0.13.0...provider-mytonwallet@0.14.0) (2024-03-12) + + + +# [0.13.0](https://github.com/rango-exchange/rango-client/compare/provider-mytonwallet@0.12.0...provider-mytonwallet@0.13.0) (2024-02-20) + + + +# [0.12.0](https://github.com/rango-exchange/rango-client/compare/provider-mytonwallet@0.11.0...provider-mytonwallet@0.12.0) (2024-02-07) + + + +# [0.11.0](https://github.com/rango-exchange/rango-client/compare/provider-mytonwallet@0.10.0...provider-mytonwallet@0.11.0) (2024-01-22) + + + +# [0.10.0](https://github.com/rango-exchange/rango-client/compare/provider-mytonwallet@0.9.0...provider-mytonwallet@0.10.0) (2023-12-24) + + +### Bug Fixes + +* fix HMR for widget and playground ([8524820](https://github.com/rango-exchange/rango-client/commit/8524820f10cf0b8921f3db0c4f620ff98daa4103)) + + + diff --git a/wallets/provider-mytonwallet/package.json b/wallets/provider-mytonwallet/package.json new file mode 100644 index 0000000000..cc9a338614 --- /dev/null +++ b/wallets/provider-mytonwallet/package.json @@ -0,0 +1,36 @@ +{ + "name": "@rango-dev/provider-mytonwallet", + "version": "0.25.1-next.6", + "license": "MIT", + "type": "module", + "source": "./src/index.ts", + "main": "./dist/index.js", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "default": "./dist/index.js" + } + }, + "typings": "dist/index.d.ts", + "files": [ + "dist", + "src" + ], + "scripts": { + "build": "node ../../scripts/build/command.mjs --path wallets/provider-mytonwallet", + "ts-check": "tsc --declaration --emitDeclarationOnly -p ./tsconfig.json", + "clean": "rimraf dist", + "format": "prettier --write '{.,src}/**/*.{ts,tsx}'", + "lint": "eslint \"**/*.{ts,tsx}\" --ignore-path ../../.eslintignore" + }, + "dependencies": { + "@rango-dev/signer-ton": "^0.18.1-next.0", + "@rango-dev/wallets-shared": "^0.40.1-next.6", + "@ton/core": "^0.59.0", + "@ton/crypto": "^3.3.0", + "rango-types": "^0.1.74" + }, + "publishConfig": { + "access": "public" + } +} \ No newline at end of file diff --git a/wallets/provider-mytonwallet/readme.md b/wallets/provider-mytonwallet/readme.md new file mode 100644 index 0000000000..2a93965f70 --- /dev/null +++ b/wallets/provider-mytonwallet/readme.md @@ -0,0 +1,3 @@ +# @rango-dev/provider-mytonwallet + +Mytonwallet \ No newline at end of file diff --git a/wallets/provider-mytonwallet/src/helpers.ts b/wallets/provider-mytonwallet/src/helpers.ts new file mode 100644 index 0000000000..e934189209 --- /dev/null +++ b/wallets/provider-mytonwallet/src/helpers.ts @@ -0,0 +1,27 @@ +import { type ConnectEvent, isTonAddressItemReply } from './types.js'; + +export function myTonWallet() { + return window.mytonwallet?.tonconnect ?? null; +} + +export async function getTonCoreModule() { + const tonCore = await import('@ton/core'); + return tonCore; +} + +export async function parseAddress(rawAddress: string): Promise { + const tonCore = await getTonCoreModule(); + return tonCore.Address.parse(rawAddress).toString({ bounceable: false }); +} + +export async function getAccounts( + event: ConnectEvent +): Promise { + if ('items' in event.payload) { + const accountPromises = event.payload.items + ?.filter(isTonAddressItemReply) + .map(async (item) => parseAddress(item.address)); + return Promise.all(accountPromises); + } + return null; +} diff --git a/wallets/provider-mytonwallet/src/index.ts b/wallets/provider-mytonwallet/src/index.ts new file mode 100644 index 0000000000..f2082423d0 --- /dev/null +++ b/wallets/provider-mytonwallet/src/index.ts @@ -0,0 +1,95 @@ +import type { Environments, TonProvider } from './types.js'; +import type { + CanEagerConnect, + CanSwitchNetwork, + Connect, + WalletInfo, +} from '@rango-dev/wallets-shared'; +import type { BlockchainMeta, SignerFactory } from 'rango-types'; + +import { Networks, WalletTypes } from '@rango-dev/wallets-shared'; +import { tonBlockchain } from 'rango-types'; + +import { getAccounts, myTonWallet as myTonWallet_instance } from './helpers.js'; +import signer from './signer.js'; + +let envs: Environments = { + manifestUrl: '', +}; + +const WALLET = WalletTypes.MY_TON_WALLET; + +export const config = { + type: WALLET, +}; + +export type { Environments }; + +export const init = (environments: Environments) => { + envs = environments; +}; + +export const getInstance = myTonWallet_instance; +export const connect: Connect = async ({ instance }) => { + const tonInstance = instance as TonProvider; + const result = await tonInstance.restoreConnection(); + + const accounts = await getAccounts(result); + + if (accounts) { + return { accounts, chainId: Networks.TON }; + // eslint-disable-next-line no-else-return + } else { + const result = await tonInstance.connect(2, { + manifestUrl: envs.manifestUrl, + items: [{ name: 'ton_addr' }], + }); + + const accounts = await getAccounts(result); + + if (accounts) { + return { accounts, chainId: Networks.TON }; + } + + throw new Error( + 'message' in result.payload + ? result.payload.message + : 'error connecting to MyTonWallet' + ); + } +}; + +export const canEagerConnect: CanEagerConnect = async ({ instance }) => { + try { + const tonInstance = instance as TonProvider; + const result = await tonInstance.restoreConnection(); + if ('items' in result.payload) { + const accounts = result.payload?.items; + return !!(accounts && accounts.length); + } + return false; + } catch (error) { + return false; + } +}; +export const canSwitchNetworkTo: CanSwitchNetwork = () => false; + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export const getSigners: (provider: any) => Promise = signer; + +export const getWalletInfo: (allBlockChains: BlockchainMeta[]) => WalletInfo = ( + allBlockChains +) => { + const ton = tonBlockchain(allBlockChains); + return { + name: 'MyTonWallet', + img: 'https://raw.githubusercontent.com/rango-exchange/assets/main/wallets/mytonwallet/icon.svg', + installLink: { + CHROME: + 'https://chrome.google.com/webstore/detail/mytonwallet-%C2%B7-my-ton-wall/fldfpgipfncgndfolcbkdeeknbbbnhcc', + DEFAULT: 'https://mytonwallet.io/', + }, + color: '#fff', + supportedChains: ton, + }; +}; diff --git a/wallets/provider-mytonwallet/src/signer.ts b/wallets/provider-mytonwallet/src/signer.ts new file mode 100644 index 0000000000..b9d9aa1e4b --- /dev/null +++ b/wallets/provider-mytonwallet/src/signer.ts @@ -0,0 +1,13 @@ +import type { TonProvider } from './types.js'; +import type { SignerFactory } from 'rango-types'; + +import { DefaultTonSigner } from '@rango-dev/signer-ton'; +import { DefaultSignerFactory, TransactionType as TxType } from 'rango-types'; + +export default async function getSigners( + provider: TonProvider +): Promise { + const signers = new DefaultSignerFactory(); + signers.registerSigner(TxType.TON, new DefaultTonSigner(provider)); + return signers; +} diff --git a/wallets/provider-mytonwallet/src/types.ts b/wallets/provider-mytonwallet/src/types.ts new file mode 100644 index 0000000000..62a0edf384 --- /dev/null +++ b/wallets/provider-mytonwallet/src/types.ts @@ -0,0 +1,296 @@ +//TODO : move instance types to wallets-shared + +type SendTransactionFeatureDeprecated = 'SendTransaction'; +type SendTransactionFeature = { + name: 'SendTransaction'; + maxMessages: number; +}; +type SignDataFeature = { name: 'SignData' }; + +type Feature = + | SendTransactionFeatureDeprecated + | SendTransactionFeature + | SignDataFeature; + +type WalletInfo = { + name: string; + image: string; + tondns?: string; + about_url: string; +}; + +interface DeviceInfo { + platform: + | 'iphone' + | 'ipad' + | 'android' + | 'windows' + | 'mac' + | 'linux' + | 'browser'; + appName: string; // e.g. "Tonkeeper" + appVersion: string; // e.g. "2.3.367" + maxProtocolVersion: number; + features: Feature[]; +} + +type ConnectItem = TonAddressItem | TonProofItem; + +interface TonAddressItem { + name: 'ton_addr'; +} + +interface TonProofItem { + name: 'ton_proof'; + payload: string; +} + +interface ConnectRequest { + manifestUrl: string; + items: ConnectItem[]; +} + +type ConnectItemReply = TonAddressItemReply | TonProofItemReply; + +enum CHAIN { + MAINNET = '-239', + TESTNET = '-3', +} + +interface TonAddressItemReply { + name: 'ton_addr'; + address: string; + network: CHAIN; + walletStateInit: string; + publicKey: string; +} + +type TonProofItemReply = TonProofItemReplySuccess | TonProofItemReplyError; + +interface TonProofItemReplySuccess { + name: 'ton_proof'; + proof: { + timestamp: number; + domain: { + lengthBytes: number; + value: string; + }; + payload: string; + signature: string; + }; +} + +/* eslint-disable @typescript-eslint/no-magic-numbers */ +enum CONNECT_ITEM_ERROR_CODES { + UNKNOWN_ERROR = 0, + METHOD_NOT_SUPPORTED = 400, +} +/* eslint-disable @typescript-eslint/no-magic-numbers */ + +type ConnectItemReplyError = { + name: T; + error: { + code: CONNECT_ITEM_ERROR_CODES; + message?: string; + }; +}; + +type TonProofItemReplyError = ConnectItemReplyError< + TonProofItemReplySuccess['name'] +>; + +interface ConnectEventSuccess { + event: 'connect'; + id: number; + payload: { + items: ConnectItemReply[]; + device: DeviceInfo; + }; +} + +interface ConnectEventError { + event: 'connect_error'; + id: number; + payload: { + code: CONNECT_EVENT_ERROR_CODES; + message: string; + }; +} + +/* eslint-disable @typescript-eslint/no-magic-numbers */ +enum CONNECT_EVENT_ERROR_CODES { + UNKNOWN_ERROR = 0, + BAD_REQUEST_ERROR = 1, + MANIFEST_NOT_FOUND_ERROR = 2, + MANIFEST_CONTENT_ERROR = 3, + UNKNOWN_APP_ERROR = 100, + USER_REJECTS_ERROR = 300, + METHOD_NOT_SUPPORTED = 400, +} +/* eslint-disable @typescript-eslint/no-magic-numbers */ + +export type ConnectEvent = ConnectEventSuccess | ConnectEventError; + +type RpcMethod = 'disconnect' | 'sendTransaction' | 'signData'; + +interface SendTransactionRpcRequest { + method: 'sendTransaction'; + params: [string]; + id: string; +} + +interface SignDataRpcRequest { + method: 'signData'; + params: [ + { + schema_crc: number; + cell: string; + } + ]; + id: string; +} + +interface DisconnectRpcRequest { + method: 'disconnect'; + params: []; + id: string; +} + +type RpcRequests = { + sendTransaction: SendTransactionRpcRequest; + signData: SignDataRpcRequest; + disconnect: DisconnectRpcRequest; +}; + +type AppRequest = RpcRequests[T]; + +interface DisconnectEvent { + event: 'disconnect'; + id: number; + payload: object; +} + +type WalletEvent = ConnectEvent | DisconnectEvent; + +enum SEND_TRANSACTION_ERROR_CODES { + UNKNOWN_ERROR = 0, + BAD_REQUEST_ERROR = 1, + UNKNOWN_APP_ERROR = 100, + USER_REJECTS_ERROR = 300, + METHOD_NOT_SUPPORTED = 400, +} + +interface WalletResponseTemplateError { + error: { code: number; message: string; data?: unknown }; + id: string; +} + +interface SendTransactionRpcResponseError extends WalletResponseTemplateError { + error: { + code: SEND_TRANSACTION_ERROR_CODES; + message: string; + data?: unknown; + }; + id: string; +} + +interface WalletResponseTemplateSuccess { + result: string; + id: string; +} + +type SendTransactionRpcResponseSuccess = WalletResponseTemplateSuccess; + +/* eslint-disable @typescript-eslint/no-magic-numbers */ +enum SIGN_DATA_ERROR_CODES { + UNKNOWN_ERROR = 0, + BAD_REQUEST_ERROR = 1, + UNKNOWN_APP_ERROR = 100, + USER_REJECTS_ERROR = 300, + METHOD_NOT_SUPPORTED = 400, +} +/* eslint-disable @typescript-eslint/no-magic-numbers */ + +interface SignDataRpcResponseError extends WalletResponseTemplateError { + error: { code: SIGN_DATA_ERROR_CODES; message: string; data?: unknown }; + id: string; +} + +interface SignDataRpcResponseSuccess { + id: string; + result: { + signature: string; + timestamp: string; + }; +} + +/* eslint-disable @typescript-eslint/no-magic-numbers */ +enum DISCONNECT_ERROR_CODES { + UNKNOWN_ERROR = 0, + BAD_REQUEST_ERROR = 1, + UNKNOWN_APP_ERROR = 100, + METHOD_NOT_SUPPORTED = 400, +} +/* eslint-disable @typescript-eslint/no-magic-numbers */ + +interface DisconnectRpcResponseError extends WalletResponseTemplateError { + error: { code: DISCONNECT_ERROR_CODES; message: string; data?: unknown }; + id: string; +} + +interface DisconnectRpcResponseSuccess { + id: string; + result: object; +} + +type RpcResponses = { + sendTransaction: { + error: SendTransactionRpcResponseError; + success: SendTransactionRpcResponseSuccess; + }; + + signData: { + error: SignDataRpcResponseError; + success: SignDataRpcResponseSuccess; + }; + + disconnect: { + error: DisconnectRpcResponseError; + success: DisconnectRpcResponseSuccess; + }; +}; + +type WalletResponseSuccess = RpcResponses[T]['success']; + +type WalletResponseError = RpcResponses[T]['error']; + +type WalletResponse = + | WalletResponseSuccess + | WalletResponseError; + +export interface TonProvider { + deviceInfo: DeviceInfo; + walletInfo: WalletInfo; + protocolVersion: number; + isWalletBrowser: boolean; + connect( + protocolVersion: number, + message: ConnectRequest + ): Promise; + restoreConnection(): Promise; + send(message: AppRequest): Promise>; + listen(callback: (event: WalletEvent) => void): () => void; + + /** + * @deprecated + */ + disconnect(): void; +} + +export const isTonAddressItemReply = ( + item: ConnectItemReply +): item is TonAddressItemReply => item.name === 'ton_addr'; + +export interface Environments extends Record { + manifestUrl: string; +} diff --git a/wallets/provider-mytonwallet/tsconfig.build.json b/wallets/provider-mytonwallet/tsconfig.build.json new file mode 100644 index 0000000000..d2ac5e673f --- /dev/null +++ b/wallets/provider-mytonwallet/tsconfig.build.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig.libnext.json", + "include": ["src", "types", "../../global-wallets-env.d.ts"], + "compilerOptions": { + "outDir": "dist", + "rootDir": "./src", + "lib": ["dom", "esnext"] + } +} diff --git a/wallets/provider-mytonwallet/tsconfig.json b/wallets/provider-mytonwallet/tsconfig.json new file mode 100644 index 0000000000..a3a0b0f59d --- /dev/null +++ b/wallets/provider-mytonwallet/tsconfig.json @@ -0,0 +1 @@ +{ "extends": "./tsconfig.build.json", "include": ["src", "tests"] } diff --git a/wallets/provider-okx/CHANGELOG.md b/wallets/provider-okx/CHANGELOG.md new file mode 100644 index 0000000000..0ba64a2c9c --- /dev/null +++ b/wallets/provider-okx/CHANGELOG.md @@ -0,0 +1,166 @@ +# [0.41.0](https://github.com/rango-exchange/rango-client/compare/provider-okx@0.40.0...provider-okx@0.41.0) (2024-12-30) + + + +# [0.40.0](https://github.com/rango-exchange/rango-client/compare/provider-okx@0.39.0...provider-okx@0.40.0) (2024-11-27) + + +### Features + +* add ton connect provider ([2a2dbb7](https://github.com/rango-exchange/rango-client/commit/2a2dbb79022263f19446ced49d298e04d63f927f)) + + + +# [0.39.0](https://github.com/rango-exchange/rango-client/compare/provider-okx@0.38.0...provider-okx@0.39.0) (2024-11-12) + + + +# [0.38.0](https://github.com/rango-exchange/rango-client/compare/provider-okx@0.37.0...provider-okx@0.38.0) (2024-10-12) + + +### Bug Fixes + +* bump sdk and fix type issues ([d442208](https://github.com/rango-exchange/rango-client/commit/d4422083bf5dd27d5f509ce1db7f9560d05428c8)) +* resolve issues with the sign message method for certain solana providers ([cbe83a3](https://github.com/rango-exchange/rango-client/commit/cbe83a3da8b48560b206fc2a7fa7cf062cdeaa23)) + + +### Performance Improvements + +* lazy load signer packages ([7b88f18](https://github.com/rango-exchange/rango-client/commit/7b88f1834f7b29b4b81ab6c81a07bb88e8ccf55c)) + + + +# [0.37.0](https://github.com/rango-exchange/rango-client/compare/provider-okx@0.36.0...provider-okx@0.37.0) (2024-09-10) + + + +# [0.36.0](https://github.com/rango-exchange/rango-client/compare/provider-okx@0.35.1...provider-okx@0.36.0) (2024-08-11) + + + +## [0.35.1](https://github.com/rango-exchange/rango-client/compare/provider-okx@0.35.0...provider-okx@0.35.1) (2024-07-14) + + + +# [0.35.0](https://github.com/rango-exchange/rango-client/compare/provider-okx@0.33.2...provider-okx@0.35.0) (2024-07-09) + + + +# [0.34.0](https://github.com/rango-exchange/rango-client/compare/provider-okx@0.33.2...provider-okx@0.34.0) (2024-06-01) + + + +## [0.33.2](https://github.com/rango-exchange/rango-client/compare/provider-okx@0.33.1...provider-okx@0.33.2) (2024-05-26) + + + +## [0.33.1](https://github.com/rango-exchange/rango-client/compare/provider-okx@0.33.0...provider-okx@0.33.1) (2024-05-25) + + + +# [0.33.0](https://github.com/rango-exchange/rango-client/compare/provider-okx@0.32.0...provider-okx@0.33.0) (2024-05-14) + + + +# [0.32.0](https://github.com/rango-exchange/rango-client/compare/provider-okx@0.31.0...provider-okx@0.32.0) (2024-04-24) + + + +# [0.31.0](https://github.com/rango-exchange/rango-client/compare/provider-okx@0.30.0...provider-okx@0.31.0) (2024-04-23) + + +### Bug Fixes + +* update okx wallet supported chains ([5d24823](https://github.com/rango-exchange/rango-client/commit/5d248235067138bfd82288bf3bef2f2b54b8ce09)) + + + +# [0.30.0](https://github.com/rango-exchange/rango-client/compare/provider-okx@0.29.0...provider-okx@0.30.0) (2024-04-09) + + +### Bug Fixes + +* fix the connection problem that happens when another wallet takes over the requested one ([42df212](https://github.com/rango-exchange/rango-client/commit/42df2120aadd84c95045b0bf76844c19305fb59a)) + + + +# [0.29.0](https://github.com/rango-exchange/rango-client/compare/provider-okx@0.28.0...provider-okx@0.29.0) (2024-03-12) + + + +# [0.28.0](https://github.com/rango-exchange/rango-client/compare/provider-okx@0.27.0...provider-okx@0.28.0) (2024-02-20) + + + +# [0.27.0](https://github.com/rango-exchange/rango-client/compare/provider-okx@0.26.0...provider-okx@0.27.0) (2024-02-07) + + + +# [0.26.0](https://github.com/rango-exchange/rango-client/compare/provider-okx@0.25.0...provider-okx@0.26.0) (2024-01-22) + + +### Bug Fixes + +* cleanup wallets' subscriber when setProvider get null ([88d6a42](https://github.com/rango-exchange/rango-client/commit/88d6a423c49b34b3d9ff567e22df36c3b009bb76)) + + + +# [0.25.0](https://github.com/rango-exchange/rango-client/compare/provider-okx@0.23.0...provider-okx@0.25.0) (2023-12-24) + + +### Bug Fixes + +* fix HMR for widget and playground ([8524820](https://github.com/rango-exchange/rango-client/commit/8524820f10cf0b8921f3db0c4f620ff98daa4103)) + + + +# [0.14.0](https://github.com/rango-exchange/rango-client/compare/provider-okx@0.13.0...provider-okx@0.14.0) (2023-08-03) + + + +# [0.13.0](https://github.com/rango-exchange/rango-client/compare/provider-okx@0.12.0...provider-okx@0.13.0) (2023-08-01) + + + +# [0.9.0](https://github.com/rango-exchange/rango-client/compare/provider-okx@0.8.0...provider-okx@0.9.0) (2023-07-31) + + + +# [0.7.0](https://github.com/rango-exchange/rango-client/compare/provider-okx@0.6.0...provider-okx@0.7.0) (2023-07-11) + + + +# [0.6.0](https://github.com/rango-exchange/rango-client/compare/provider-okx@0.5.0...provider-okx@0.6.0) (2023-07-11) + + +### Reverts + +* Revert "support for rango-types cjs format" ([ed4e050](https://github.com/rango-exchange/rango-client/commit/ed4e050bfc0dcde7aeffa6b0d73b02080a5721eb)) + + + +# [0.5.0](https://github.com/rango-exchange/rango-client/compare/provider-okx@0.4.0...provider-okx@0.5.0) (2023-05-31) + + + +# [0.4.0](https://github.com/rango-exchange/rango-client/compare/provider-okx@0.3.0...provider-okx@0.4.0) (2023-05-31) + + + +# [0.3.0](https://github.com/rango-exchange/rango-client/compare/provider-okx@0.2.0...provider-okx@0.3.0) (2023-05-30) + + + +# [0.2.0](https://github.com/rango-exchange/rango-client/compare/provider-okx@0.1.15...provider-okx@0.2.0) (2023-05-30) + + + +## [0.1.14](https://github.com/rango-exchange/rango-client/compare/provider-okx@0.1.13...provider-okx@0.1.14) (2023-05-15) + + +### Bug Fixes + +* update rango-types and fix notification bugs ([993f185](https://github.com/rango-exchange/rango-client/commit/993f185e0b8c5e5e15a2c65ba2d85d1f9c8daa90)) + + + diff --git a/wallets/provider-okx/package.json b/wallets/provider-okx/package.json index e780dc6ef1..d079408d70 100644 --- a/wallets/provider-okx/package.json +++ b/wallets/provider-okx/package.json @@ -1,50 +1,32 @@ { "name": "@rango-dev/provider-okx", - "version": "0.1.12", + "version": "0.40.1-next.6", "license": "MIT", - "module": "dist/provider-okx.esm.js", - "main": "dist/index.js", + "type": "module", + "source": "./src/index.ts", + "main": "./dist/index.js", + "exports": { + ".": "./dist/index.js" + }, "typings": "dist/index.d.ts", "files": [ "dist", "src" ], "scripts": { - "start": "tsdx watch", - "build": "tsdx build --tsconfig ./tsconfig.json", - "test": "tsdx test --passWithNoTests", - "lint": "tsdx lint", - "size": "size-limit", - "analyze": "size-limit --why" - }, - "husky": { - "hooks": { - "pre-commit": "tsdx lint" - } + "build": "node ../../scripts/build/command.mjs --path wallets/provider-okx", + "ts-check": "tsc --declaration --emitDeclarationOnly -p ./tsconfig.json", + "clean": "rimraf dist", + "format": "prettier --write '{.,src}/**/*.{ts,tsx}'", + "lint": "eslint \"**/*.{ts,tsx}\" --ignore-path ../../.eslintignore" }, - "prettier": { - "printWidth": 80, - "semi": true, - "singleQuote": true, - "trailingComma": "es5" - }, - "size-limit": [ - { - "path": "dist/provider-okx.cjs.production.min.js", - "limit": "10 KB" - }, - { - "path": "dist/provider-okx.esm.js", - "limit": "10 KB" - } - ], "dependencies": { - "@rango-dev/signer-evm": "^0.1.11", - "@rango-dev/signer-solana": "^0.1.11", - "@rango-dev/wallets-shared": "^0.1.11", - "rango-types": "^0.1.28" + "@rango-dev/signer-evm": "^0.32.0", + "@rango-dev/signer-solana": "^0.35.1-next.0", + "@rango-dev/wallets-shared": "^0.40.1-next.6", + "rango-types": "^0.1.74" }, "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/wallets/provider-okx/src/helpers.ts b/wallets/provider-okx/src/helpers.ts index 7919696b9e..02b1583ae1 100644 --- a/wallets/provider-okx/src/helpers.ts +++ b/wallets/provider-okx/src/helpers.ts @@ -1,11 +1,19 @@ -import { Network, ProviderConnectResult } from '@rango-dev/wallets-shared'; +import type { ProviderConnectResult } from '@rango-dev/wallets-shared'; + +import { Networks } from '@rango-dev/wallets-shared'; export function okx_instance() { const { okxwallet } = window; - if (!okxwallet) return null; + if (!okxwallet) { + return null; + } const instances = new Map(); - if (okxwallet) instances.set(Network.ETHEREUM, okxwallet); - if (okxwallet.solana) instances.set(Network.SOLANA, okxwallet.solana); + if (okxwallet) { + instances.set(Networks.ETHEREUM, okxwallet); + } + if (okxwallet.solana) { + instances.set(Networks.SOLANA, okxwallet.solana); + } return instances; } @@ -13,16 +21,16 @@ export function okx_instance() { export async function getSolanaAccounts( instance: any ): Promise { - const solanaInstance = await instance.get(Network.SOLANA); + const solanaInstance = await instance.get(Networks.SOLANA); const results: ProviderConnectResult[] = []; - if (!!solanaInstance) { + if (solanaInstance) { const solanaResponse = await solanaInstance.connect(); const account = solanaResponse.publicKey.toString(); results.push({ accounts: account ? [account] : [], - chainId: Network.SOLANA, + chainId: Networks.SOLANA, }); } @@ -30,21 +38,18 @@ export async function getSolanaAccounts( } export const OKX_WALLET_SUPPORTED_CHAINS = [ - Network.ETHEREUM, - Network.BTC, - Network.BSC, - Network.TRON, - Network.SOLANA, - Network.POLYGON, - Network.FANTOM, - Network.ARBITRUM, - Network.OPTIMISM, - Network.CRONOS, - Network.BOBA, - Network.GNOSIS, - Network.MOONBEAM, - Network.MOONRIVER, - Network.HARMONY, - Network.LTC, - Network.AVAX_CCHAIN, + Networks.ETHEREUM, + Networks.BSC, + Networks.SOLANA, + Networks.POLYGON, + Networks.FANTOM, + Networks.ARBITRUM, + Networks.OPTIMISM, + Networks.CRONOS, + Networks.BOBA, + Networks.GNOSIS, + Networks.MOONBEAM, + Networks.MOONRIVER, + Networks.HARMONY, + Networks.AVAX_CCHAIN, ]; diff --git a/wallets/provider-okx/src/index.ts b/wallets/provider-okx/src/index.ts index 574040517c..1d76309381 100644 --- a/wallets/provider-okx/src/index.ts +++ b/wallets/provider-okx/src/index.ts @@ -1,38 +1,44 @@ -import { - Network, - WalletType, +import type { + CanEagerConnect, CanSwitchNetwork, Connect, ProviderConnectResult, Subscribe, SwitchNetwork, + WalletInfo, +} from '@rango-dev/wallets-shared'; +import type { BlockchainMeta, SignerFactory } from 'rango-types'; + +import { + canEagerlyConnectToEvm, canSwitchNetworkToEvm, chooseInstance, getEvmAccounts, + Networks, switchNetworkForEvm, - WalletInfo, + WalletTypes, } from '@rango-dev/wallets-shared'; +import { isEvmBlockchain } from 'rango-types'; import { getSolanaAccounts, okx_instance, OKX_WALLET_SUPPORTED_CHAINS, -} from './helpers'; -import signer from './signer'; -import { SignerFactory, isEvmBlockchain, BlockchainMeta } from 'rango-types'; +} from './helpers.js'; +import signer from './signer.js'; -const WALLET = WalletType.OKX; +const WALLET = WalletTypes.OKX; export const config = { type: WALLET, - defaultNetwork: Network.ETHEREUM, + defaultNetwork: Networks.ETHEREUM, }; export const getInstance = okx_instance; export const connect: Connect = async ({ instance, meta }) => { let results: ProviderConnectResult[] = []; - const evm_instance = chooseInstance(instance, meta, Network.ETHEREUM); + const evm_instance = chooseInstance(instance, meta, Networks.ETHEREUM); if (evm_instance) { const evm = await getEvmAccounts(evm_instance); @@ -47,17 +53,21 @@ export const connect: Connect = async ({ instance, meta }) => { }; export const subscribe: Subscribe = ({ instance, updateAccounts, meta }) => { - const ethInstance = chooseInstance(instance, meta, Network.ETHEREUM); - - ethInstance?.on('accountsChanged', async (addresses: string[]) => { + const ethInstance = chooseInstance(instance, meta, Networks.ETHEREUM); + const handleEvmAccountsChanged = async (addresses: string[]) => { const eth_chainId = meta .filter(isEvmBlockchain) - .find((blockchain) => blockchain.name === Network.ETHEREUM)?.chainId; + .find((blockchain) => blockchain.name === Networks.ETHEREUM)?.chainId; updateAccounts(addresses, eth_chainId); const [{ accounts, chainId }] = await getSolanaAccounts(instance); updateAccounts(accounts, chainId); - }); + }; + ethInstance?.on?.('accountsChanged', handleEvmAccountsChanged); + + return () => { + ethInstance?.off?.('accountsChanged', handleEvmAccountsChanged); + }; }; export const switchNetwork: SwitchNetwork = async (options) => { @@ -74,13 +84,21 @@ export const switchNetwork: SwitchNetwork = async (options) => { export const canSwitchNetworkTo: CanSwitchNetwork = canSwitchNetworkToEvm; -export const getSigners: (provider: any) => SignerFactory = signer; +export const getSigners: (provider: any) => Promise = signer; + +export const canEagerConnect: CanEagerConnect = async ({ instance, meta }) => { + const evm_instance = chooseInstance(instance, meta, Networks.ETHEREUM); + if (evm_instance) { + return canEagerlyConnectToEvm({ instance: evm_instance, meta }); + } + return Promise.resolve(false); +}; export const getWalletInfo: (allBlockChains: BlockchainMeta[]) => WalletInfo = ( allBlockChains ) => ({ name: 'OKX', - img: 'https://raw.githubusercontent.com/rango-exchange/rango-types/main/assets/icons/wallets/okx.png', + img: 'https://raw.githubusercontent.com/rango-exchange/assets/main/wallets/okx/icon.svg', installLink: { CHROME: 'https://chrome.google.com/webstore/detail/okx-wallet/mcohilncbfahbmgdjkbpemcciiolgcge', @@ -91,6 +109,6 @@ export const getWalletInfo: (allBlockChains: BlockchainMeta[]) => WalletInfo = ( }, color: 'white', supportedChains: allBlockChains.filter((blockchainMeta) => - OKX_WALLET_SUPPORTED_CHAINS.includes(blockchainMeta.name as Network) + OKX_WALLET_SUPPORTED_CHAINS.includes(blockchainMeta.name as Networks) ), }); diff --git a/wallets/provider-okx/src/signer.ts b/wallets/provider-okx/src/signer.ts index 0585e651d9..6cd7760393 100644 --- a/wallets/provider-okx/src/signer.ts +++ b/wallets/provider-okx/src/signer.ts @@ -1,13 +1,18 @@ -import { DefaultEvmSigner } from '@rango-dev/signer-evm'; -import { DefaultSolanaSigner } from '@rango-dev/signer-solana'; -import { Network, getNetworkInstance } from '@rango-dev/wallets-shared'; -import { SignerFactory, TransactionType as TxType } from 'rango-types'; +import type { SignerFactory } from 'rango-types'; -export default function getSigners(provider: any): SignerFactory { - const ethProvider = getNetworkInstance(provider, Network.ETHEREUM); - const solProvider = getNetworkInstance(provider, Network.SOLANA); - const signers = new SignerFactory(); +import { getNetworkInstance, Networks } from '@rango-dev/wallets-shared'; +import { DefaultSignerFactory, TransactionType as TxType } from 'rango-types'; + +import { CustomSolanaSigner } from './solana-signer.js'; + +export default async function getSigners( + provider: any +): Promise { + const ethProvider = getNetworkInstance(provider, Networks.ETHEREUM); + const solProvider = getNetworkInstance(provider, Networks.SOLANA); + const signers = new DefaultSignerFactory(); + const { DefaultEvmSigner } = await import('@rango-dev/signer-evm'); signers.registerSigner(TxType.EVM, new DefaultEvmSigner(ethProvider)); - signers.registerSigner(TxType.SOLANA, new DefaultSolanaSigner(solProvider)); + signers.registerSigner(TxType.SOLANA, new CustomSolanaSigner(solProvider)); return signers; } diff --git a/wallets/provider-okx/src/solana-signer.ts b/wallets/provider-okx/src/solana-signer.ts new file mode 100644 index 0000000000..53d18f589b --- /dev/null +++ b/wallets/provider-okx/src/solana-signer.ts @@ -0,0 +1,25 @@ +import { DefaultSolanaSigner } from '@rango-dev/signer-solana'; +import { SignerError, SignerErrorCode } from 'rango-types'; + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +type SolanaExternalProvider = any; + +export class CustomSolanaSigner extends DefaultSolanaSigner { + constructor(provider: SolanaExternalProvider) { + super(provider); + } + + async signMessage(msg: string): Promise { + try { + const { signature } = await this.provider.request({ + method: 'signMessage', + params: { + message: msg, + }, + }); + return signature; + } catch (error) { + throw new SignerError(SignerErrorCode.SIGN_TX_ERROR, undefined, error); + } + } +} diff --git a/wallets/provider-okx/tsconfig.build.json b/wallets/provider-okx/tsconfig.build.json new file mode 100644 index 0000000000..d9181ce0cd --- /dev/null +++ b/wallets/provider-okx/tsconfig.build.json @@ -0,0 +1,11 @@ +{ + // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs + "extends": "../../tsconfig.libnext.json", + "include": ["src", "types", "../../global-wallets-env.d.ts"], + "compilerOptions": { + "outDir": "dist", + "rootDir": "./src", + "lib": ["dom", "esnext"] + // match output dir to input dir. e.g. dist/index instead of dist/src/index + } +} diff --git a/wallets/provider-okx/tsconfig.json b/wallets/provider-okx/tsconfig.json index 365489616a..a3a0b0f59d 100644 --- a/wallets/provider-okx/tsconfig.json +++ b/wallets/provider-okx/tsconfig.json @@ -1,35 +1 @@ -{ - // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs - "include": ["src", "types", "../../global-wallets-env.d.ts"], - "compilerOptions": { - "module": "esnext", - "lib": ["dom", "esnext"], - "importHelpers": true, - // output .d.ts declaration files for consumers - "declaration": true, - // output .js.map sourcemap files for consumers - "sourceMap": true, - // match output dir to input dir. e.g. dist/index instead of dist/src/index - "rootDir": "./src", - // stricter type-checking for stronger correctness. Recommended by TS - "strict": true, - // linter checks for common issues - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true, - // noUnused* overlap with @typescript-eslint/no-unused-vars, can disable if duplicative - "noUnusedLocals": true, - "noUnusedParameters": true, - // use Node's module resolution algorithm, instead of the legacy TS one - "moduleResolution": "node", - // transpile JSX to React.createElement - "jsx": "react", - // interop between ESM and CJS modules. Recommended by TS - "esModuleInterop": true, - // significant perf increase by skipping checking .d.ts files, particularly those in node_modules. Recommended by TS - "skipLibCheck": true, - // error out if import and file system have a casing mismatch. Recommended by TS - "forceConsistentCasingInFileNames": true, - // `tsdx build` ignores this option, but it is commonly used when type-checking separately with `tsc` - "noEmit": true, - } -} +{ "extends": "./tsconfig.build.json", "include": ["src", "tests"] } diff --git a/wallets/provider-phantom/CHANGELOG.md b/wallets/provider-phantom/CHANGELOG.md new file mode 100644 index 0000000000..0ff5952cea --- /dev/null +++ b/wallets/provider-phantom/CHANGELOG.md @@ -0,0 +1,152 @@ +# [0.41.0](https://github.com/rango-exchange/rango-client/compare/provider-phantom@0.40.0...provider-phantom@0.41.0) (2024-12-30) + + + +# [0.40.0](https://github.com/rango-exchange/rango-client/compare/provider-phantom@0.39.0...provider-phantom@0.40.0) (2024-11-27) + + +### Features + +* add ton connect provider ([2a2dbb7](https://github.com/rango-exchange/rango-client/commit/2a2dbb79022263f19446ced49d298e04d63f927f)) + + + +# [0.39.0](https://github.com/rango-exchange/rango-client/compare/provider-phantom@0.38.0...provider-phantom@0.39.0) (2024-11-12) + + + +# [0.38.0](https://github.com/rango-exchange/rango-client/compare/provider-phantom@0.37.0...provider-phantom@0.38.0) (2024-10-12) + + +### Bug Fixes + +* bump sdk and fix type issues ([d442208](https://github.com/rango-exchange/rango-client/commit/d4422083bf5dd27d5f509ce1db7f9560d05428c8)) + + +### Performance Improvements + +* lazy load signer packages ([7b88f18](https://github.com/rango-exchange/rango-client/commit/7b88f1834f7b29b4b81ab6c81a07bb88e8ccf55c)) + + + +# [0.37.0](https://github.com/rango-exchange/rango-client/compare/provider-phantom@0.36.0...provider-phantom@0.37.0) (2024-09-10) + + + +# [0.36.0](https://github.com/rango-exchange/rango-client/compare/provider-phantom@0.35.1...provider-phantom@0.36.0) (2024-08-11) + + + +## [0.35.1](https://github.com/rango-exchange/rango-client/compare/provider-phantom@0.35.0...provider-phantom@0.35.1) (2024-07-14) + + + +# [0.35.0](https://github.com/rango-exchange/rango-client/compare/provider-phantom@0.33.0...provider-phantom@0.35.0) (2024-07-09) + + + +# [0.34.0](https://github.com/rango-exchange/rango-client/compare/provider-phantom@0.33.0...provider-phantom@0.34.0) (2024-06-01) + + + +# [0.33.0](https://github.com/rango-exchange/rango-client/compare/provider-phantom@0.32.0...provider-phantom@0.33.0) (2024-05-14) + + + +# [0.32.0](https://github.com/rango-exchange/rango-client/compare/provider-phantom@0.31.0...provider-phantom@0.32.0) (2024-04-24) + + + +# [0.31.0](https://github.com/rango-exchange/rango-client/compare/provider-phantom@0.30.0...provider-phantom@0.31.0) (2024-04-23) + + + +# [0.30.0](https://github.com/rango-exchange/rango-client/compare/provider-phantom@0.29.0...provider-phantom@0.30.0) (2024-04-09) + + +### Bug Fixes + +* fix the connection problem that happens when another wallet takes over the requested one ([42df212](https://github.com/rango-exchange/rango-client/commit/42df2120aadd84c95045b0bf76844c19305fb59a)) + + + +# [0.29.0](https://github.com/rango-exchange/rango-client/compare/provider-phantom@0.28.0...provider-phantom@0.29.0) (2024-03-12) + + + +# [0.28.0](https://github.com/rango-exchange/rango-client/compare/provider-phantom@0.27.0...provider-phantom@0.28.0) (2024-02-20) + + + +# [0.27.0](https://github.com/rango-exchange/rango-client/compare/provider-phantom@0.26.0...provider-phantom@0.27.0) (2024-02-07) + + + +# [0.26.0](https://github.com/rango-exchange/rango-client/compare/provider-phantom@0.25.0...provider-phantom@0.26.0) (2024-01-22) + + +### Bug Fixes + +* cleanup wallets' subscriber when setProvider get null ([88d6a42](https://github.com/rango-exchange/rango-client/commit/88d6a423c49b34b3d9ff567e22df36c3b009bb76)) + + + +# [0.25.0](https://github.com/rango-exchange/rango-client/compare/provider-phantom@0.23.0...provider-phantom@0.25.0) (2023-12-24) + + +### Bug Fixes + +* fix HMR for widget and playground ([8524820](https://github.com/rango-exchange/rango-client/commit/8524820f10cf0b8921f3db0c4f620ff98daa4103)) + + + +# [0.14.0](https://github.com/rango-exchange/rango-client/compare/provider-phantom@0.13.0...provider-phantom@0.14.0) (2023-08-03) + + + +# [0.13.0](https://github.com/rango-exchange/rango-client/compare/provider-phantom@0.12.0...provider-phantom@0.13.0) (2023-08-01) + + + +# [0.9.0](https://github.com/rango-exchange/rango-client/compare/provider-phantom@0.8.0...provider-phantom@0.9.0) (2023-07-31) + + + +# [0.7.0](https://github.com/rango-exchange/rango-client/compare/provider-phantom@0.6.0...provider-phantom@0.7.0) (2023-07-11) + + + +# [0.6.0](https://github.com/rango-exchange/rango-client/compare/provider-phantom@0.5.0...provider-phantom@0.6.0) (2023-07-11) + + +### Reverts + +* Revert "support for rango-types cjs format" ([ed4e050](https://github.com/rango-exchange/rango-client/commit/ed4e050bfc0dcde7aeffa6b0d73b02080a5721eb)) + + + +# [0.5.0](https://github.com/rango-exchange/rango-client/compare/provider-phantom@0.4.0...provider-phantom@0.5.0) (2023-05-31) + + + +# [0.4.0](https://github.com/rango-exchange/rango-client/compare/provider-phantom@0.3.0...provider-phantom@0.4.0) (2023-05-31) + + + +# [0.3.0](https://github.com/rango-exchange/rango-client/compare/provider-phantom@0.2.0...provider-phantom@0.3.0) (2023-05-30) + + + +# [0.2.0](https://github.com/rango-exchange/rango-client/compare/provider-phantom@0.1.15...provider-phantom@0.2.0) (2023-05-30) + + + +## [0.1.14](https://github.com/rango-exchange/rango-client/compare/provider-phantom@0.1.13...provider-phantom@0.1.14) (2023-05-15) + + +### Bug Fixes + +* update rango-types and fix notification bugs ([993f185](https://github.com/rango-exchange/rango-client/commit/993f185e0b8c5e5e15a2c65ba2d85d1f9c8daa90)) + + + diff --git a/wallets/provider-phantom/package.json b/wallets/provider-phantom/package.json index 7a0fc102d0..49fe84ed34 100644 --- a/wallets/provider-phantom/package.json +++ b/wallets/provider-phantom/package.json @@ -1,47 +1,29 @@ { "name": "@rango-dev/provider-phantom", - "version": "0.1.12", + "version": "0.40.1-next.7", "license": "MIT", - "module": "dist/provider-phantom.esm.js", - "main": "dist/index.js", - "typings": "dist/index.d.ts", + "type": "module", + "source": "./src/mod.ts", + "main": "./dist/mod.js", + "exports": { + ".": "./dist/mod.js" + }, + "typings": "dist/mod.d.ts", "files": [ "dist", "src" ], "scripts": { - "start": "tsdx watch", - "build": "tsdx build --tsconfig ./tsconfig.json", - "test": "tsdx test --passWithNoTests", - "lint": "tsdx lint", - "size": "size-limit", - "analyze": "size-limit --why" - }, - "husky": { - "hooks": { - "pre-commit": "tsdx lint" - } + "build": "node ../../scripts/build/command.mjs --path wallets/provider-phantom --inputs src/mod.ts", + "ts-check": "tsc --declaration --emitDeclarationOnly -p ./tsconfig.json", + "clean": "rimraf dist", + "format": "prettier --write '{.,src}/**/*.{ts,tsx}'", + "lint": "eslint \"**/*.{ts,tsx}\" --ignore-path ../../.eslintignore" }, - "prettier": { - "printWidth": 80, - "semi": true, - "singleQuote": true, - "trailingComma": "es5" - }, - "size-limit": [ - { - "path": "dist/provider-phantom.cjs.production.min.js", - "limit": "10 KB" - }, - { - "path": "dist/provider-phantom.esm.js", - "limit": "10 KB" - } - ], "dependencies": { - "@rango-dev/signer-solana": "^0.1.11", - "@rango-dev/wallets-shared": "^0.1.11", - "rango-types": "^0.1.28" + "@rango-dev/signer-solana": "^0.35.1-next.0", + "@rango-dev/wallets-shared": "^0.40.1-next.6", + "rango-types": "^0.1.74" }, "publishConfig": { "access": "public" diff --git a/wallets/provider-phantom/src/constants.ts b/wallets/provider-phantom/src/constants.ts new file mode 100644 index 0000000000..68a03fd1a1 --- /dev/null +++ b/wallets/provider-phantom/src/constants.ts @@ -0,0 +1,26 @@ +import { type ProviderInfo } from '@rango-dev/wallets-core'; +import { LegacyNetworks } from '@rango-dev/wallets-core/legacy'; + +export const EVM_SUPPORTED_CHAINS = [ + LegacyNetworks.ETHEREUM, + LegacyNetworks.POLYGON, +]; + +export const WALLET_ID = 'phantom'; + +export const info: ProviderInfo = { + name: 'Phantom', + icon: 'https://raw.githubusercontent.com/rango-exchange/assets/main/wallets/phantom/icon.svg', + extensions: { + chrome: + 'https://chrome.google.com/webstore/detail/phantom/bfnaelmomeimhlpmgjnjophhpkkoljpa', + homepage: 'https://phantom.app/', + }, + properties: [ + { + name: 'detached', + // if you are adding a new namespace, don't forget to also update `getWalletInfo` + value: ['Solana', 'EVM'], + }, + ], +}; diff --git a/wallets/provider-phantom/src/helpers.ts b/wallets/provider-phantom/src/helpers.ts deleted file mode 100644 index 007b5ed099..0000000000 --- a/wallets/provider-phantom/src/helpers.ts +++ /dev/null @@ -1,11 +0,0 @@ -export function phantom() { - if ('phantom' in window) { - const instance = window.phantom?.solana; - - if (instance?.isPhantom) { - return instance; - } - } - - return null; -} diff --git a/wallets/provider-phantom/src/index.ts b/wallets/provider-phantom/src/index.ts deleted file mode 100644 index f170297cf3..0000000000 --- a/wallets/provider-phantom/src/index.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { - Network, - WalletType, - CanSwitchNetwork, - Connect, - Subscribe, - getSolanaAccounts, - WalletInfo, -} from '@rango-dev/wallets-shared'; -import { phantom as phantom_instance } from './helpers'; -import signer from './signer'; -import { SignerFactory, BlockchainMeta, solanaBlockchain } from 'rango-types'; - -const WALLET = WalletType.PHANTOM; - -export const config = { - type: WALLET, -}; - -export const getInstance = phantom_instance; -export const connect: Connect = getSolanaAccounts; - -export const subscribe: Subscribe = ({ instance, updateAccounts, connect }) => { - instance?.on('accountChanged', async (publicKey: string) => { - const network = Network.SOLANA; - if (publicKey) { - const account = publicKey.toString(); - updateAccounts([account]); - } else { - connect(network); - } - }); -}; - -export const canSwitchNetworkTo: CanSwitchNetwork = () => false; - -export const getSigners: (provider: any) => SignerFactory = signer; - -export const getWalletInfo: (allBlockChains: BlockchainMeta[]) => WalletInfo = ( - allBlockChains -) => { - const solana = solanaBlockchain(allBlockChains); - return { - name: 'Phantom', - img: 'https://raw.githubusercontent.com/rango-exchange/rango-types/main/assets/icons/wallets/phantom.svg', - installLink: { - CHROME: - 'https://chrome.google.com/webstore/detail/phantom/bfnaelmomeimhlpmgjnjophhpkkoljpa', - - DEFAULT: 'https://phantom.app/', - }, - color: '#4d40c6', - supportedChains: solana, - }; -}; diff --git a/wallets/provider-phantom/src/legacy/index.ts b/wallets/provider-phantom/src/legacy/index.ts new file mode 100644 index 0000000000..bbe2a0fef7 --- /dev/null +++ b/wallets/provider-phantom/src/legacy/index.ts @@ -0,0 +1,140 @@ +import type { LegacyProviderInterface } from '@rango-dev/wallets-core/legacy'; +import type { + CanEagerConnect, + CanSwitchNetwork, + Connect, + Subscribe, + WalletInfo, +} from '@rango-dev/wallets-shared'; +import type { + BlockchainMeta, + EvmBlockchainMeta, + SignerFactory, +} from 'rango-types'; + +import { LegacyNetworks as Networks } from '@rango-dev/wallets-core/legacy'; +import { + chooseInstance, + getSolanaAccounts, + WalletTypes, +} from '@rango-dev/wallets-shared'; +import { isEvmBlockchain, solanaBlockchain } from 'rango-types'; + +import { EVM_SUPPORTED_CHAINS } from '../constants.js'; +import { phantom as phantom_instance } from '../utils.js'; + +import signer from './signer.js'; + +const WALLET = WalletTypes.PHANTOM; + +export const config = { + type: WALLET, +}; + +export const getInstance = phantom_instance; + +/* + * NOTE: Phantom's Hub version has support for EVM as well since we are deprecating the legacy, + * we just want to keep the implementation for some time and then legacy provider will be removed soon. + * So we don't add new namespaces (like EVM) to legacy. + */ +const connect: Connect = async ({ instance, meta }) => { + const solanaInstance = instance.get(Networks.SOLANA); + const result = await getSolanaAccounts({ + instance: solanaInstance, + meta, + }); + + return result; +}; + +export const subscribe: Subscribe = ({ instance, updateAccounts, connect }) => { + const handleAccountsChanged = async (publicKey: string) => { + const network = Networks.SOLANA; + if (publicKey) { + const account = publicKey.toString(); + updateAccounts([account]); + } else { + connect(network); + } + }; + instance?.on?.('accountChanged', handleAccountsChanged); + + return () => { + instance?.off?.('accountChanged', handleAccountsChanged); + }; +}; + +const canSwitchNetworkTo: CanSwitchNetwork = ({ network }) => { + return EVM_SUPPORTED_CHAINS.includes(network as Networks); +}; + +export const getSigners: (provider: any) => Promise = signer; + +const canEagerConnect: CanEagerConnect = async ({ instance, meta }) => { + const solanaInstance = chooseInstance(instance, meta, Networks.SOLANA); + try { + const result = await solanaInstance.connect({ onlyIfTrusted: true }); + return !!result; + } catch (error) { + return false; + } +}; +export const getWalletInfo: (allBlockChains: BlockchainMeta[]) => WalletInfo = ( + allBlockChains +) => { + const solana = solanaBlockchain(allBlockChains); + const evms = allBlockChains.filter( + (chain): chain is EvmBlockchainMeta => + isEvmBlockchain(chain) && + EVM_SUPPORTED_CHAINS.includes(chain.name as Networks) + ); + + return { + name: 'Phantom', + img: 'https://raw.githubusercontent.com/rango-exchange/assets/main/wallets/phantom/icon.svg', + installLink: { + CHROME: + 'https://chrome.google.com/webstore/detail/phantom/bfnaelmomeimhlpmgjnjophhpkkoljpa', + + DEFAULT: 'https://phantom.app/', + }, + color: '#4d40c6', + // if you are adding a new namespace, don't forget to also update `properties` + supportedChains: [ + ...solana, + ...evms.filter((chain) => + EVM_SUPPORTED_CHAINS.includes(chain.name as Networks) + ), + ], + + needsNamespace: { + selection: 'multiple', + data: [ + { + label: 'EVM', + value: 'EVM', + id: 'ETH', + }, + { + label: 'Solana', + value: 'Solana', + id: 'SOLANA', + }, + ], + }, + }; +}; + +const buildLegacyProvider: () => LegacyProviderInterface = () => ({ + config, + getInstance, + connect, + subscribe, + canSwitchNetworkTo, + getSigners, + getWalletInfo, + canEagerConnect, +}); + +export { buildLegacyProvider }; diff --git a/wallets/provider-phantom/src/legacy/signer.ts b/wallets/provider-phantom/src/legacy/signer.ts new file mode 100644 index 0000000000..c0af13aaae --- /dev/null +++ b/wallets/provider-phantom/src/legacy/signer.ts @@ -0,0 +1,19 @@ +import type { SignerFactory } from 'rango-types'; + +import { LegacyNetworks as Networks } from '@rango-dev/wallets-core/legacy'; +import { getNetworkInstance } from '@rango-dev/wallets-shared'; +import { DefaultSignerFactory, TransactionType as TxType } from 'rango-types'; + +export default async function getSigners( + provider: any +): Promise { + const solProvider = getNetworkInstance(provider, Networks.SOLANA); + const evmProvider = getNetworkInstance(provider, Networks.ETHEREUM); + + const { DefaultEvmSigner } = await import('@rango-dev/signer-evm'); + const { DefaultSolanaSigner } = await import('@rango-dev/signer-solana'); + const signers = new DefaultSignerFactory(); + signers.registerSigner(TxType.SOLANA, new DefaultSolanaSigner(solProvider)); + signers.registerSigner(TxType.EVM, new DefaultEvmSigner(evmProvider)); + return signers; +} diff --git a/wallets/provider-phantom/src/mod.ts b/wallets/provider-phantom/src/mod.ts new file mode 100644 index 0000000000..d7cbd1745a --- /dev/null +++ b/wallets/provider-phantom/src/mod.ts @@ -0,0 +1,12 @@ +import { defineVersions } from '@rango-dev/wallets-core/utils'; + +import { buildLegacyProvider } from './legacy/index.js'; +import { buildProvider } from './provider.js'; + +const versions = () => + defineVersions() + .version('0.0.0', buildLegacyProvider()) + .version('1.0.0', buildProvider()) + .build(); + +export { versions }; diff --git a/wallets/provider-phantom/src/namespaces/evm.ts b/wallets/provider-phantom/src/namespaces/evm.ts new file mode 100644 index 0000000000..4343aec514 --- /dev/null +++ b/wallets/provider-phantom/src/namespaces/evm.ts @@ -0,0 +1,36 @@ +import type { EvmActions } from '@rango-dev/wallets-core/namespaces/evm'; + +import { NamespaceBuilder } from '@rango-dev/wallets-core'; +import { builders as commonBuilders } from '@rango-dev/wallets-core/namespaces/common'; +import { actions, builders } from '@rango-dev/wallets-core/namespaces/evm'; + +import { WALLET_ID } from '../constants.js'; +import { evmPhantom } from '../utils.js'; + +const [changeAccountSubscriber, changeAccountCleanup] = + actions.changeAccountSubscriber(evmPhantom); + +/* + * TODO: If user imported a private key for EVM, it hasn't solana. + * when trying to connect to solana for this user we go through `-32603` which is an internal error. + * If phantom added an specific error code for this situation, we can consider handling the error here. + * @see https://docs.phantom.app/solana/errors + */ +const connect = builders + .connect() + .action(actions.connect(evmPhantom)) + .before(changeAccountSubscriber) + .or(changeAccountCleanup) + .build(); + +const disconnect = commonBuilders + .disconnect() + .after(changeAccountCleanup) + .build(); + +const evm = new NamespaceBuilder('EVM', WALLET_ID) + .action(connect) + .action(disconnect) + .build(); + +export { evm }; diff --git a/wallets/provider-phantom/src/namespaces/solana.ts b/wallets/provider-phantom/src/namespaces/solana.ts new file mode 100644 index 0000000000..0a5506e4fd --- /dev/null +++ b/wallets/provider-phantom/src/namespaces/solana.ts @@ -0,0 +1,68 @@ +import type { CaipAccount } from '@rango-dev/wallets-core/namespaces/common'; +import type { SolanaActions } from '@rango-dev/wallets-core/namespaces/solana'; + +import { NamespaceBuilder } from '@rango-dev/wallets-core'; +import { builders as commonBuilders } from '@rango-dev/wallets-core/namespaces/common'; +import { + actions, + builders, + CAIP_NAMESPACE, + CAIP_SOLANA_CHAIN_ID, +} from '@rango-dev/wallets-core/namespaces/solana'; +import { CAIP } from '@rango-dev/wallets-core/utils'; +import { getSolanaAccounts } from '@rango-dev/wallets-shared'; + +import { WALLET_ID } from '../constants.js'; +import { solanaPhantom } from '../utils.js'; + +const [changeAccountSubscriber, changeAccountCleanup] = + actions.changeAccountSubscriber(solanaPhantom); + +/* + * TODO: If user imported a private key for EVM, it hasn't solana. + * when trying to connect to solana for this user we go through `-32603` which is an internal error. + * If phantom added an specific error code for this situation, we can consider handling the error here. + * @see https://docs.phantom.app/solana/errors + */ +const connect = builders + .connect() + .action(async function () { + const solanaInstance = solanaPhantom(); + const result = await getSolanaAccounts({ + instance: solanaInstance, + meta: [], + }); + if (Array.isArray(result)) { + throw new Error( + 'Expecting solana response to be a single value, not an array.' + ); + } + + const formatAccounts = result.accounts.map( + (account) => + CAIP.AccountId.format({ + address: account, + chainId: { + namespace: CAIP_NAMESPACE, + reference: CAIP_SOLANA_CHAIN_ID, + }, + }) as CaipAccount + ); + + return formatAccounts; + }) + .before(changeAccountSubscriber) + .or(changeAccountCleanup) + .build(); + +const disconnect = commonBuilders + .disconnect() + .after(changeAccountCleanup) + .build(); + +const solana = new NamespaceBuilder('Solana', WALLET_ID) + .action(connect) + .action(disconnect) + .build(); + +export { solana }; diff --git a/wallets/provider-phantom/src/provider.ts b/wallets/provider-phantom/src/provider.ts new file mode 100644 index 0000000000..69fdf40113 --- /dev/null +++ b/wallets/provider-phantom/src/provider.ts @@ -0,0 +1,23 @@ +import { ProviderBuilder } from '@rango-dev/wallets-core'; + +import { info, WALLET_ID } from './constants.js'; +import { evm } from './namespaces/evm.js'; +import { solana } from './namespaces/solana.js'; +import { phantom as phantomInstance } from './utils.js'; + +const buildProvider = () => + new ProviderBuilder(WALLET_ID) + .init(function (context) { + const [, setState] = context.state(); + + if (phantomInstance()) { + setState('installed', true); + console.debug('[phantom] instance detected.', context); + } + }) + .config('info', info) + .add('solana', solana) + .add('evm', evm) + .build(); + +export { buildProvider }; diff --git a/wallets/provider-phantom/src/signer.ts b/wallets/provider-phantom/src/signer.ts deleted file mode 100644 index edc5072244..0000000000 --- a/wallets/provider-phantom/src/signer.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { DefaultSolanaSigner } from '@rango-dev/signer-solana'; -import { Network, getNetworkInstance } from '@rango-dev/wallets-shared'; -import { SignerFactory, TransactionType as TxType } from 'rango-types'; - -export default function getSigners(provider: any): SignerFactory { - const solProvider = getNetworkInstance(provider, Network.SOLANA); - const signers = new SignerFactory(); - signers.registerSigner(TxType.SOLANA, new DefaultSolanaSigner(solProvider)); - return signers; -} diff --git a/wallets/provider-phantom/src/utils.ts b/wallets/provider-phantom/src/utils.ts new file mode 100644 index 0000000000..be8309b6df --- /dev/null +++ b/wallets/provider-phantom/src/utils.ts @@ -0,0 +1,55 @@ +import type { ProviderAPI as EvmProviderApi } from '@rango-dev/wallets-core/namespaces/evm'; +import type { ProviderAPI as SolanaProviderApi } from '@rango-dev/wallets-core/namespaces/solana'; + +import { LegacyNetworks } from '@rango-dev/wallets-core/legacy'; + +type Provider = Map; + +export function phantom(): Provider | null { + const { phantom } = window; + + if (!phantom) { + return null; + } + + const { solana, ethereum } = phantom; + + const instances: Provider = new Map(); + + if (ethereum && ethereum.isPhantom) { + instances.set(LegacyNetworks.ETHEREUM, ethereum); + } + + if (solana && solana.isPhantom) { + instances.set(LegacyNetworks.SOLANA, solana); + } + + return instances; +} + +export function evmPhantom(): EvmProviderApi { + const instances = phantom(); + + const evmInstance = instances?.get(LegacyNetworks.ETHEREUM); + + if (!evmInstance) { + throw new Error( + 'Phantom not injected or EVM not enabled. Please check your wallet.' + ); + } + + return evmInstance as EvmProviderApi; +} + +export function solanaPhantom(): SolanaProviderApi { + const instance = phantom(); + const solanaInstance = instance?.get(LegacyNetworks.SOLANA); + + if (!solanaInstance) { + throw new Error( + 'Phantom not injected or Solana not enabled. Please check your wallet.' + ); + } + + return solanaInstance; +} diff --git a/wallets/provider-phantom/tsconfig.build.json b/wallets/provider-phantom/tsconfig.build.json new file mode 100644 index 0000000000..fc43a1c995 --- /dev/null +++ b/wallets/provider-phantom/tsconfig.build.json @@ -0,0 +1,12 @@ +{ + // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs + "extends": "../../tsconfig.libnext.json", + "include": ["src", "types"], + "files": ["../../global-wallets-env.d.ts"], + "compilerOptions": { + "outDir": "dist", + "rootDir": "./src", + "lib": ["dom", "esnext"] + // match output dir to input dir. e.g. dist/index instead of dist/src/index + } +} diff --git a/wallets/provider-phantom/tsconfig.json b/wallets/provider-phantom/tsconfig.json index 365489616a..a3a0b0f59d 100644 --- a/wallets/provider-phantom/tsconfig.json +++ b/wallets/provider-phantom/tsconfig.json @@ -1,35 +1 @@ -{ - // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs - "include": ["src", "types", "../../global-wallets-env.d.ts"], - "compilerOptions": { - "module": "esnext", - "lib": ["dom", "esnext"], - "importHelpers": true, - // output .d.ts declaration files for consumers - "declaration": true, - // output .js.map sourcemap files for consumers - "sourceMap": true, - // match output dir to input dir. e.g. dist/index instead of dist/src/index - "rootDir": "./src", - // stricter type-checking for stronger correctness. Recommended by TS - "strict": true, - // linter checks for common issues - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true, - // noUnused* overlap with @typescript-eslint/no-unused-vars, can disable if duplicative - "noUnusedLocals": true, - "noUnusedParameters": true, - // use Node's module resolution algorithm, instead of the legacy TS one - "moduleResolution": "node", - // transpile JSX to React.createElement - "jsx": "react", - // interop between ESM and CJS modules. Recommended by TS - "esModuleInterop": true, - // significant perf increase by skipping checking .d.ts files, particularly those in node_modules. Recommended by TS - "skipLibCheck": true, - // error out if import and file system have a casing mismatch. Recommended by TS - "forceConsistentCasingInFileNames": true, - // `tsdx build` ignores this option, but it is commonly used when type-checking separately with `tsc` - "noEmit": true, - } -} +{ "extends": "./tsconfig.build.json", "include": ["src", "tests"] } diff --git a/wallets/provider-rabby/CHANGELOG.md b/wallets/provider-rabby/CHANGELOG.md new file mode 100644 index 0000000000..334ce9e998 --- /dev/null +++ b/wallets/provider-rabby/CHANGELOG.md @@ -0,0 +1,47 @@ +# [0.8.0](https://github.com/rango-exchange/rango-client/compare/provider-rabby@0.7.0...provider-rabby@0.8.0) (2024-12-30) + + + +# [0.7.0](https://github.com/rango-exchange/rango-client/compare/provider-rabby@0.6.0...provider-rabby@0.7.0) (2024-11-27) + + + +# [0.6.0](https://github.com/rango-exchange/rango-client/compare/provider-rabby@0.5.0...provider-rabby@0.6.0) (2024-11-12) + + + +# [0.5.0](https://github.com/rango-exchange/rango-client/compare/provider-rabby@0.4.0...provider-rabby@0.5.0) (2024-10-12) + + +### Bug Fixes + +* bump sdk and fix type issues ([d442208](https://github.com/rango-exchange/rango-client/commit/d4422083bf5dd27d5f509ce1db7f9560d05428c8)) + + +### Performance Improvements + +* lazy load signer packages ([7b88f18](https://github.com/rango-exchange/rango-client/commit/7b88f1834f7b29b4b81ab6c81a07bb88e8ccf55c)) + + + +# [0.4.0](https://github.com/rango-exchange/rango-client/compare/provider-rabby@0.3.0...provider-rabby@0.4.0) (2024-09-10) + + + +# [0.3.0](https://github.com/rango-exchange/rango-client/compare/provider-rabby@0.2.1...provider-rabby@0.3.0) (2024-08-11) + + + +## [0.2.1](https://github.com/rango-exchange/rango-client/compare/provider-rabby@0.2.0...provider-rabby@0.2.1) (2024-07-14) + + + +# 0.2.0 (2024-07-09) + + +### Features + +* integrate rabby wallet extension ([145fb8f](https://github.com/rango-exchange/rango-client/commit/145fb8ffbbf5e46e7e8386aeffcefc8f4ddb22e7)) + + + diff --git a/wallets/provider-rabby/package.json b/wallets/provider-rabby/package.json new file mode 100644 index 0000000000..f42f29dc0f --- /dev/null +++ b/wallets/provider-rabby/package.json @@ -0,0 +1,31 @@ +{ + "name": "@rango-dev/provider-rabby", + "version": "0.7.1-next.6", + "license": "MIT", + "type": "module", + "source": "./src/index.ts", + "main": "./dist/index.js", + "exports": { + ".": "./dist/index.js" + }, + "typings": "dist/index.d.ts", + "files": [ + "dist", + "src" + ], + "scripts": { + "build": "node ../../scripts/build/command.mjs --path wallets/provider-rabby", + "ts-check": "tsc --declaration --emitDeclarationOnly -p ./tsconfig.json", + "clean": "rimraf dist", + "format": "prettier --write '{.,src}/**/*.{ts,tsx}'", + "lint": "eslint \"**/*.{ts,tsx}\" --ignore-path ../../.eslintignore" + }, + "dependencies": { + "@rango-dev/signer-evm": "^0.32.0", + "@rango-dev/wallets-shared": "^0.40.1-next.6", + "rango-types": "^0.1.74" + }, + "publishConfig": { + "access": "public" + } +} \ No newline at end of file diff --git a/wallets/provider-rabby/readme.md b/wallets/provider-rabby/readme.md new file mode 100644 index 0000000000..269d403af2 --- /dev/null +++ b/wallets/provider-rabby/readme.md @@ -0,0 +1 @@ +# @rango-dev/provider-rabby diff --git a/wallets/provider-rabby/src/helpers.ts b/wallets/provider-rabby/src/helpers.ts new file mode 100644 index 0000000000..08f1a1daf0 --- /dev/null +++ b/wallets/provider-rabby/src/helpers.ts @@ -0,0 +1,5 @@ +export function rabby() { + const { ethereum } = window; + + return ethereum?.isRabby ? ethereum : null; +} diff --git a/wallets/provider-rabby/src/index.ts b/wallets/provider-rabby/src/index.ts new file mode 100644 index 0000000000..9a1a93b1e9 --- /dev/null +++ b/wallets/provider-rabby/src/index.ts @@ -0,0 +1,69 @@ +import type { + CanEagerConnect, + CanSwitchNetwork, + Connect, + Subscribe, + SwitchNetwork, + WalletInfo, +} from '@rango-dev/wallets-shared'; +import type { BlockchainMeta, SignerFactory } from 'rango-types'; + +import { + canEagerlyConnectToEvm, + canSwitchNetworkToEvm, + getEvmAccounts, + subscribeToEvm, + switchNetworkForEvm, + WalletTypes, +} from '@rango-dev/wallets-shared'; +import { evmBlockchains } from 'rango-types'; + +import { rabby as rabby_instance } from './helpers.js'; +import signer from './signer.js'; + +export const config = { + type: WalletTypes.Rabby, +}; + +export const getInstance = rabby_instance; +export const connect: Connect = async ({ instance }) => { + /* + * Note: We need to get `chainId` here, because for the first time + * after opening the browser, wallet is locked, and don't give us accounts and chainId + * on `check` phase, so `network` will be null. For this case we need to get chainId + * whenever we are requesting accounts. + */ + const { accounts, chainId } = await getEvmAccounts(instance); + + return { + accounts, + chainId, + }; +}; + +export const subscribe: Subscribe = subscribeToEvm; + +export const switchNetwork: SwitchNetwork = switchNetworkForEvm; + +export const canSwitchNetworkTo: CanSwitchNetwork = canSwitchNetworkToEvm; + +export const getSigners: (provider: any) => Promise = signer; + +export const canEagerConnect: CanEagerConnect = canEagerlyConnectToEvm; + +export const getWalletInfo: (allBlockChains: BlockchainMeta[]) => WalletInfo = ( + allBlockChains +) => { + const evms = evmBlockchains(allBlockChains); + return { + name: 'Rabby', + img: 'https://raw.githubusercontent.com/rango-exchange/assets/main/wallets/rabby/icon.svg', + installLink: { + CHROME: + 'https://chromewebstore.google.com/detail/rabby-wallet/acmacodkjbdgmoleebolmdjonilkdbch', + DEFAULT: 'https://rabby.io/', + }, + color: '#fff', + supportedChains: evms, + }; +}; diff --git a/wallets/provider-rabby/src/signer.ts b/wallets/provider-rabby/src/signer.ts new file mode 100644 index 0000000000..f7dbf93750 --- /dev/null +++ b/wallets/provider-rabby/src/signer.ts @@ -0,0 +1,12 @@ +import type { SignerFactory } from 'rango-types'; + +import { DefaultSignerFactory, TransactionType as TxType } from 'rango-types'; + +export default async function getSigners( + provider: any +): Promise { + const signers = new DefaultSignerFactory(); + const { DefaultEvmSigner } = await import('@rango-dev/signer-evm'); + signers.registerSigner(TxType.EVM, new DefaultEvmSigner(provider)); + return signers; +} diff --git a/wallets/provider-rabby/tsconfig.build.json b/wallets/provider-rabby/tsconfig.build.json new file mode 100644 index 0000000000..d9181ce0cd --- /dev/null +++ b/wallets/provider-rabby/tsconfig.build.json @@ -0,0 +1,11 @@ +{ + // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs + "extends": "../../tsconfig.libnext.json", + "include": ["src", "types", "../../global-wallets-env.d.ts"], + "compilerOptions": { + "outDir": "dist", + "rootDir": "./src", + "lib": ["dom", "esnext"] + // match output dir to input dir. e.g. dist/index instead of dist/src/index + } +} diff --git a/wallets/provider-rabby/tsconfig.json b/wallets/provider-rabby/tsconfig.json new file mode 100644 index 0000000000..a3a0b0f59d --- /dev/null +++ b/wallets/provider-rabby/tsconfig.json @@ -0,0 +1 @@ +{ "extends": "./tsconfig.build.json", "include": ["src", "tests"] } diff --git a/wallets/provider-safe/CHANGELOG.md b/wallets/provider-safe/CHANGELOG.md new file mode 100644 index 0000000000..22119ed2fe --- /dev/null +++ b/wallets/provider-safe/CHANGELOG.md @@ -0,0 +1,120 @@ +# [0.34.0](https://github.com/rango-exchange/rango-client/compare/provider-safe@0.33.0...provider-safe@0.34.0) (2024-12-30) + + + +# [0.33.0](https://github.com/rango-exchange/rango-client/compare/provider-safe@0.32.0...provider-safe@0.33.0) (2024-11-27) + + + +# [0.32.0](https://github.com/rango-exchange/rango-client/compare/provider-safe@0.31.0...provider-safe@0.32.0) (2024-11-12) + + + +# [0.31.0](https://github.com/rango-exchange/rango-client/compare/provider-safe@0.30.0...provider-safe@0.31.0) (2024-10-12) + + +### Bug Fixes + +* bump sdk and fix type issues ([d442208](https://github.com/rango-exchange/rango-client/commit/d4422083bf5dd27d5f509ce1db7f9560d05428c8)) + + +### Performance Improvements + +* enable code splitting in build process ([fe5a41e](https://github.com/rango-exchange/rango-client/commit/fe5a41e0e297298de11cd74ca5825544742aa03a)) +* lazy load signer packages ([7b88f18](https://github.com/rango-exchange/rango-client/commit/7b88f1834f7b29b4b81ab6c81a07bb88e8ccf55c)) + + + +# [0.30.0](https://github.com/rango-exchange/rango-client/compare/provider-safe@0.29.0...provider-safe@0.30.0) (2024-09-10) + + + +# [0.29.0](https://github.com/rango-exchange/rango-client/compare/provider-safe@0.28.1...provider-safe@0.29.0) (2024-08-11) + + + +## [0.28.1](https://github.com/rango-exchange/rango-client/compare/provider-safe@0.28.0...provider-safe@0.28.1) (2024-07-14) + + + +# [0.28.0](https://github.com/rango-exchange/rango-client/compare/provider-safe@0.26.2...provider-safe@0.28.0) (2024-07-09) + + + +# [0.27.0](https://github.com/rango-exchange/rango-client/compare/provider-safe@0.26.2...provider-safe@0.27.0) (2024-06-01) + + + +## [0.26.2](https://github.com/rango-exchange/rango-client/compare/provider-safe@0.26.1...provider-safe@0.26.2) (2024-05-26) + + + +## [0.26.1](https://github.com/rango-exchange/rango-client/compare/provider-safe@0.26.0...provider-safe@0.26.1) (2024-05-25) + + + +# [0.26.0](https://github.com/rango-exchange/rango-client/compare/provider-safe@0.25.0...provider-safe@0.26.0) (2024-05-14) + + + +# [0.25.0](https://github.com/rango-exchange/rango-client/compare/provider-safe@0.24.0...provider-safe@0.25.0) (2024-04-24) + + + +# [0.24.0](https://github.com/rango-exchange/rango-client/compare/provider-safe@0.23.0...provider-safe@0.24.0) (2024-04-23) + + + +# [0.23.0](https://github.com/rango-exchange/rango-client/compare/provider-safe@0.22.0...provider-safe@0.23.0) (2024-04-09) + + + +# [0.22.0](https://github.com/rango-exchange/rango-client/compare/provider-safe@0.21.0...provider-safe@0.22.0) (2024-03-12) + + + +# [0.21.0](https://github.com/rango-exchange/rango-client/compare/provider-safe@0.20.0...provider-safe@0.21.0) (2024-02-20) + + + +# [0.20.0](https://github.com/rango-exchange/rango-client/compare/provider-safe@0.19.0...provider-safe@0.20.0) (2024-02-07) + + + +# [0.19.0](https://github.com/rango-exchange/rango-client/compare/provider-safe@0.18.0...provider-safe@0.19.0) (2024-01-22) + + +### Bug Fixes + +* cleanup wallets' subscriber when setProvider get null ([88d6a42](https://github.com/rango-exchange/rango-client/commit/88d6a423c49b34b3d9ff567e22df36c3b009bb76)) + + + +# [0.18.0](https://github.com/rango-exchange/rango-client/compare/provider-safe@0.16.0...provider-safe@0.18.0) (2023-12-24) + + +### Bug Fixes + +* display transaction url after refreshing ([c976bff](https://github.com/rango-exchange/rango-client/commit/c976bffd3827ee20de5dd0f21be6d430432fff28)) +* fix HMR for widget and playground ([8524820](https://github.com/rango-exchange/rango-client/commit/8524820f10cf0b8921f3db0c4f620ff98daa4103)) +* handle safe wallet in widget ([52fcca4](https://github.com/rango-exchange/rango-client/commit/52fcca49315f7e2edb4655ae7b9cd0792c2800d7)) + + + +# [0.7.0](https://github.com/rango-exchange/rango-client/compare/provider-safe@0.6.0...provider-safe@0.7.0) (2023-08-03) + + + +# [0.6.0](https://github.com/rango-exchange/rango-client/compare/provider-safe@0.5.0...provider-safe@0.6.0) (2023-08-01) + + + +# 0.2.0 (2023-07-31) + + +### Features + +* support safe wallet ([d04cbcd](https://github.com/rango-exchange/rango-client/commit/d04cbcd2a612755563512d9dff6f2312088d8b4d)) + + + diff --git a/wallets/provider-safe/package.json b/wallets/provider-safe/package.json new file mode 100644 index 0000000000..88c290c84d --- /dev/null +++ b/wallets/provider-safe/package.json @@ -0,0 +1,34 @@ +{ + "name": "@rango-dev/provider-safe", + "version": "0.33.1-next.6", + "license": "MIT", + "type": "module", + "source": "./src/index.ts", + "main": "./dist/index.js", + "exports": { + ".": "./dist/index.js" + }, + "typings": "dist/index.d.ts", + "files": [ + "dist", + "src" + ], + "scripts": { + "build": "node ../../scripts/build/command.mjs --path wallets/provider-safe --splitting", + "ts-check": "tsc --declaration --emitDeclarationOnly -p ./tsconfig.json", + "clean": "rimraf dist", + "format": "prettier --write '{.,src}/**/*.{ts,tsx}'", + "lint": "eslint \"**/*.{ts,tsx}\" --ignore-path ../../.eslintignore" + }, + "dependencies": { + "@rango-dev/signer-evm": "^0.32.0", + "@rango-dev/wallets-shared": "^0.40.1-next.6", + "@safe-global/safe-apps-provider": "^0.17.0", + "@safe-global/safe-apps-sdk": "^9.1.0", + "ethers": "^6.13.2", + "rango-types": "^0.1.74" + }, + "publishConfig": { + "access": "public" + } +} \ No newline at end of file diff --git a/wallets/provider-safe/readme.md b/wallets/provider-safe/readme.md new file mode 100644 index 0000000000..7060019623 --- /dev/null +++ b/wallets/provider-safe/readme.md @@ -0,0 +1 @@ +# @rango-dev/provider-safe diff --git a/wallets/provider-safe/src/helpers.ts b/wallets/provider-safe/src/helpers.ts new file mode 100644 index 0000000000..87f703f8dc --- /dev/null +++ b/wallets/provider-safe/src/helpers.ts @@ -0,0 +1,29 @@ +import { SafeAppProvider } from '@safe-global/safe-apps-provider'; +import SafeAppsSDK from '@safe-global/safe-apps-sdk'; + +const options = { + debug: false, +}; + +/* + * similar to: + * https://github.com/wagmi-dev/references/pull/114 + */ +let SDK = SafeAppsSDK; +if ( + typeof SafeAppsSDK !== 'function' && + // @ts-expect-error This import error is not visible to TypeScript + typeof SafeAppsSDK.default === 'function' +) { + SDK = (SafeAppsSDK as unknown as { default: typeof SafeAppsSDK }).default; +} +export const sdk = new SDK(options); + +export async function getSafeInstance(): Promise { + const timeout = 200; + const accountInfo = await Promise.race([ + sdk.safe.getInfo(), + new Promise((resolve) => setTimeout(resolve, timeout)), + ]); + return accountInfo ? new SafeAppProvider(accountInfo, sdk as any) : null; +} diff --git a/wallets/provider-safe/src/index.ts b/wallets/provider-safe/src/index.ts new file mode 100644 index 0000000000..5140b7e734 --- /dev/null +++ b/wallets/provider-safe/src/index.ts @@ -0,0 +1,94 @@ +import type { + CanEagerConnect, + CanSwitchNetwork, + Connect, + GetInstance, + Subscribe, + SwitchNetwork, + WalletInfo, +} from '@rango-dev/wallets-shared'; +import type { BlockchainMeta, SignerFactory } from 'rango-types'; + +import { + canEagerlyConnectToEvm, + canSwitchNetworkToEvm, + subscribeToEvm, + switchNetworkForEvm, + WalletTypes, +} from '@rango-dev/wallets-shared'; +import { evmBlockchains, isEvmBlockchain } from 'rango-types'; + +import { getSafeInstance } from './helpers.js'; +import signer from './signer.js'; + +const WALLET = WalletTypes.SAFE; + +export const config = { + type: WALLET, + isAsyncInstance: true, +}; + +export const getInstance: GetInstance = async () => { + return await getSafeInstance(); +}; + +export const connect: Connect = async ({ instance }) => { + const accounts = await instance.request({ + method: 'eth_accounts', + }); + + const { chainId } = instance; + + return { accounts, chainId }; +}; + +export const subscribe: Subscribe = ({ + instance, + state, + updateChainId, + updateAccounts, + meta, + connect, + disconnect, +}) => { + const evmBlockchainMeta = meta.filter(isEvmBlockchain); + + const cleanup = subscribeToEvm({ + instance, + state, + updateChainId, + updateAccounts, + meta: evmBlockchainMeta, + connect, + disconnect, + }); + return () => { + if (cleanup) { + cleanup(); + } + }; +}; + +export const switchNetwork: SwitchNetwork = switchNetworkForEvm; + +export const canSwitchNetworkTo: CanSwitchNetwork = canSwitchNetworkToEvm; + +export const getSigners: (provider: any) => Promise = signer; + +export const canEagerConnect: CanEagerConnect = canEagerlyConnectToEvm; + +export const getWalletInfo: (allBlockChains: BlockchainMeta[]) => WalletInfo = ( + allBlockChains +) => { + const evms = evmBlockchains(allBlockChains); + return { + name: 'Safe', + img: 'https://raw.githubusercontent.com/rango-exchange/assets/main/wallets/safe/icon.svg', + installLink: { + DEFAULT: 'https://app.safe.global/', + }, + color: '#ffffff', + supportedChains: evms, + isContractWallet: true, + }; +}; diff --git a/wallets/provider-safe/src/signer.ts b/wallets/provider-safe/src/signer.ts new file mode 100644 index 0000000000..7372f23f8c --- /dev/null +++ b/wallets/provider-safe/src/signer.ts @@ -0,0 +1,13 @@ +import type { SignerFactory } from 'rango-types'; + +import { DefaultSignerFactory, TransactionType as TxType } from 'rango-types'; + +export default async function getSigners( + provider: any +): Promise { + const signers = new DefaultSignerFactory(); + const { CustomEvmSigner } = await import('./signers/evm.ts'); + signers.registerSigner(TxType.EVM, new CustomEvmSigner(provider)); + + return signers; +} diff --git a/wallets/provider-safe/src/signers/evm.ts b/wallets/provider-safe/src/signers/evm.ts new file mode 100644 index 0000000000..a60a8e026b --- /dev/null +++ b/wallets/provider-safe/src/signers/evm.ts @@ -0,0 +1,86 @@ +import type { OffChainSignMessageResponse } from '@safe-global/safe-apps-sdk'; +import type { TransactionResponse } from 'ethers'; +import type { GenericSigner } from 'rango-types'; +import type { EvmTransaction } from 'rango-types/mainApi'; + +import { DefaultEvmSigner, waitMs } from '@rango-dev/signer-evm'; +import { TransactionStatus } from '@safe-global/safe-apps-sdk'; + +import { sdk } from '../helpers.js'; + +export async function getTxHash(safeHash: string): Promise<{ txHash: string }> { + let txHash; + const timeout = 5_000; + + while (!txHash) { + try { + /** The SDK will be pinged until a txHash is available and the txStatus is in an end-state */ + const queued = await sdk.txs.getBySafeTxHash(safeHash); + if ( + queued.txStatus === TransactionStatus.AWAITING_CONFIRMATIONS || + queued.txStatus === TransactionStatus.AWAITING_EXECUTION + ) { + /** Mimic a status watcher by checking once every 5 seconds */ + await waitMs(timeout); + } else if (queued.txHash) { + /** The txStatus is in an end-state (e.g. success) so we probably have a valid, on chain txHash*/ + txHash = queued.txHash; + } + } catch { + txHash = safeHash; + } + } + return { txHash }; +} + +export class CustomEvmSigner implements GenericSigner { + private signer; + + constructor(provider: any) { + this.signer = new DefaultEvmSigner(provider); + } + + async signMessage(msg: string): Promise { + const { signature } = (await sdk.txs.signMessage( + msg + )) as OffChainSignMessageResponse & { signature: string }; + + return signature; + } + + async signAndSendTx( + tx: EvmTransaction, + address: string, + chainId: string | null + ): Promise<{ + hash: string; + response: Partial & { hashRequiringUpdate: boolean }; + }> { + const { hash, response } = await this.signer.signAndSendTx( + tx, + address, + chainId + ); + return { + hash, + response: { ...response, hashRequiringUpdate: true }, + }; + } + + async wait( + safeHash: string, + chainId: string, + response: TransactionResponse + ): Promise<{ + hash: string; + response: TransactionResponse; + chainId: string; + }> { + const { txHash: hash } = await getTxHash(safeHash); + return { + hash, + response, + chainId, + }; + } +} diff --git a/wallets/provider-safe/tsconfig.build.json b/wallets/provider-safe/tsconfig.build.json new file mode 100644 index 0000000000..b578536384 --- /dev/null +++ b/wallets/provider-safe/tsconfig.build.json @@ -0,0 +1,10 @@ +{ + // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs + "extends": "../../tsconfig.bundler.json", + "include": ["src", "types", "../../global-wallets-env.d.ts"], + "compilerOptions": { + "outDir": "dist", + "rootDir": "./src", + "lib": ["dom", "esnext"] + } +} diff --git a/wallets/provider-safe/tsconfig.json b/wallets/provider-safe/tsconfig.json new file mode 100644 index 0000000000..a3a0b0f59d --- /dev/null +++ b/wallets/provider-safe/tsconfig.json @@ -0,0 +1 @@ +{ "extends": "./tsconfig.build.json", "include": ["src", "tests"] } diff --git a/wallets/provider-safepal/CHANGELOG.md b/wallets/provider-safepal/CHANGELOG.md new file mode 100644 index 0000000000..de0c93cbd6 --- /dev/null +++ b/wallets/provider-safepal/CHANGELOG.md @@ -0,0 +1,155 @@ +# [0.41.0](https://github.com/rango-exchange/rango-client/compare/provider-safepal@0.40.0...provider-safepal@0.41.0) (2024-12-30) + + + +# [0.40.0](https://github.com/rango-exchange/rango-client/compare/provider-safepal@0.39.0...provider-safepal@0.40.0) (2024-11-27) + + +### Features + +* add ton connect provider ([2a2dbb7](https://github.com/rango-exchange/rango-client/commit/2a2dbb79022263f19446ced49d298e04d63f927f)) + + + +# [0.39.0](https://github.com/rango-exchange/rango-client/compare/provider-safepal@0.38.0...provider-safepal@0.39.0) (2024-11-12) + + + +# [0.38.0](https://github.com/rango-exchange/rango-client/compare/provider-safepal@0.37.0...provider-safepal@0.38.0) (2024-10-12) + + +### Bug Fixes + +* bump sdk and fix type issues ([d442208](https://github.com/rango-exchange/rango-client/commit/d4422083bf5dd27d5f509ce1db7f9560d05428c8)) + + +### Performance Improvements + +* lazy load signer packages ([7b88f18](https://github.com/rango-exchange/rango-client/commit/7b88f1834f7b29b4b81ab6c81a07bb88e8ccf55c)) + + + +# [0.37.0](https://github.com/rango-exchange/rango-client/compare/provider-safepal@0.36.0...provider-safepal@0.37.0) (2024-09-10) + + + +# [0.36.0](https://github.com/rango-exchange/rango-client/compare/provider-safepal@0.35.1...provider-safepal@0.36.0) (2024-08-11) + + + +## [0.35.1](https://github.com/rango-exchange/rango-client/compare/provider-safepal@0.35.0...provider-safepal@0.35.1) (2024-07-14) + + + +# [0.35.0](https://github.com/rango-exchange/rango-client/compare/provider-safepal@0.33.2...provider-safepal@0.35.0) (2024-07-09) + + + +# [0.34.0](https://github.com/rango-exchange/rango-client/compare/provider-safepal@0.33.2...provider-safepal@0.34.0) (2024-06-01) + + + +## [0.33.2](https://github.com/rango-exchange/rango-client/compare/provider-safepal@0.33.1...provider-safepal@0.33.2) (2024-05-26) + + + +## [0.33.1](https://github.com/rango-exchange/rango-client/compare/provider-safepal@0.33.0...provider-safepal@0.33.1) (2024-05-25) + + + +# [0.33.0](https://github.com/rango-exchange/rango-client/compare/provider-safepal@0.32.0...provider-safepal@0.33.0) (2024-05-14) + + + +# [0.32.0](https://github.com/rango-exchange/rango-client/compare/provider-safepal@0.31.0...provider-safepal@0.32.0) (2024-04-24) + + + +# [0.31.0](https://github.com/rango-exchange/rango-client/compare/provider-safepal@0.30.0...provider-safepal@0.31.0) (2024-04-23) + + + +# [0.30.0](https://github.com/rango-exchange/rango-client/compare/provider-safepal@0.29.0...provider-safepal@0.30.0) (2024-04-09) + + + +# [0.29.0](https://github.com/rango-exchange/rango-client/compare/provider-safepal@0.28.0...provider-safepal@0.29.0) (2024-03-12) + + + +# [0.28.0](https://github.com/rango-exchange/rango-client/compare/provider-safepal@0.27.0...provider-safepal@0.28.0) (2024-02-20) + + + +# [0.27.0](https://github.com/rango-exchange/rango-client/compare/provider-safepal@0.26.0...provider-safepal@0.27.0) (2024-02-07) + + + +# [0.26.0](https://github.com/rango-exchange/rango-client/compare/provider-safepal@0.25.0...provider-safepal@0.26.0) (2024-01-22) + + +### Bug Fixes + +* cleanup wallets' subscriber when setProvider get null ([88d6a42](https://github.com/rango-exchange/rango-client/commit/88d6a423c49b34b3d9ff567e22df36c3b009bb76)) + + + +# [0.25.0](https://github.com/rango-exchange/rango-client/compare/provider-safepal@0.23.0...provider-safepal@0.25.0) (2023-12-24) + + +### Bug Fixes + +* fix HMR for widget and playground ([8524820](https://github.com/rango-exchange/rango-client/commit/8524820f10cf0b8921f3db0c4f620ff98daa4103)) + + + +# [0.14.0](https://github.com/rango-exchange/rango-client/compare/provider-safepal@0.13.0...provider-safepal@0.14.0) (2023-08-03) + + + +# [0.13.0](https://github.com/rango-exchange/rango-client/compare/provider-safepal@0.12.0...provider-safepal@0.13.0) (2023-08-01) + + + +# [0.9.0](https://github.com/rango-exchange/rango-client/compare/provider-safepal@0.8.0...provider-safepal@0.9.0) (2023-07-31) + + + +# [0.7.0](https://github.com/rango-exchange/rango-client/compare/provider-safepal@0.6.0...provider-safepal@0.7.0) (2023-07-11) + + + +# [0.6.0](https://github.com/rango-exchange/rango-client/compare/provider-safepal@0.5.0...provider-safepal@0.6.0) (2023-07-11) + + +### Reverts + +* Revert "support for rango-types cjs format" ([ed4e050](https://github.com/rango-exchange/rango-client/commit/ed4e050bfc0dcde7aeffa6b0d73b02080a5721eb)) + + + +# [0.5.0](https://github.com/rango-exchange/rango-client/compare/provider-safepal@0.4.0...provider-safepal@0.5.0) (2023-05-31) + + + +# [0.4.0](https://github.com/rango-exchange/rango-client/compare/provider-safepal@0.3.0...provider-safepal@0.4.0) (2023-05-31) + + + +# [0.3.0](https://github.com/rango-exchange/rango-client/compare/provider-safepal@0.2.0...provider-safepal@0.3.0) (2023-05-30) + + + +# [0.2.0](https://github.com/rango-exchange/rango-client/compare/provider-safepal@0.1.15...provider-safepal@0.2.0) (2023-05-30) + + + +## [0.1.14](https://github.com/rango-exchange/rango-client/compare/provider-safepal@0.1.13...provider-safepal@0.1.14) (2023-05-15) + + +### Bug Fixes + +* update rango-types and fix notification bugs ([993f185](https://github.com/rango-exchange/rango-client/commit/993f185e0b8c5e5e15a2c65ba2d85d1f9c8daa90)) + + + diff --git a/wallets/provider-safepal/package.json b/wallets/provider-safepal/package.json index 7c02be9554..926e330098 100644 --- a/wallets/provider-safepal/package.json +++ b/wallets/provider-safepal/package.json @@ -1,50 +1,32 @@ { "name": "@rango-dev/provider-safepal", - "version": "0.1.12", + "version": "0.40.1-next.6", "license": "MIT", - "module": "dist/provider-safepal.esm.js", - "main": "dist/index.js", + "type": "module", + "source": "./src/index.ts", + "main": "./dist/index.js", + "exports": { + ".": "./dist/index.js" + }, "typings": "dist/index.d.ts", "files": [ "dist", "src" ], "scripts": { - "start": "tsdx watch", - "build": "tsdx build --tsconfig ./tsconfig.json", - "test": "tsdx test --passWithNoTests", - "lint": "tsdx lint", - "size": "size-limit", - "analyze": "size-limit --why" - }, - "husky": { - "hooks": { - "pre-commit": "tsdx lint" - } + "build": "node ../../scripts/build/command.mjs --path wallets/provider-safepal", + "ts-check": "tsc --declaration --emitDeclarationOnly -p ./tsconfig.json", + "clean": "rimraf dist", + "format": "prettier --write '{.,src}/**/*.{ts,tsx}'", + "lint": "eslint \"**/*.{ts,tsx}\" --ignore-path ../../.eslintignore" }, - "prettier": { - "printWidth": 80, - "semi": true, - "singleQuote": true, - "trailingComma": "es5" - }, - "size-limit": [ - { - "path": "dist/provider-safepal.cjs.production.min.js", - "limit": "10 KB" - }, - { - "path": "dist/provider-safepal.esm.js", - "limit": "10 KB" - } - ], "dependencies": { - "@rango-dev/signer-evm": "^0.1.11", - "@rango-dev/signer-solana": "^0.1.11", - "@rango-dev/wallets-shared": "^0.1.11", - "rango-types": "^0.1.28" + "@rango-dev/signer-evm": "^0.32.0", + "@rango-dev/signer-solana": "^0.35.1-next.0", + "@rango-dev/wallets-shared": "^0.40.1-next.6", + "rango-types": "^0.1.74" }, "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/wallets/provider-safepal/src/constants.ts b/wallets/provider-safepal/src/constants.ts deleted file mode 100644 index 2727d9be21..0000000000 --- a/wallets/provider-safepal/src/constants.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { Network } from '@rango-dev/wallets-shared'; - -// export const SUPPORTED_NATIVE_CHAINS = [Network.BTC, Network.BCH, Network.LTC]; diff --git a/wallets/provider-safepal/src/helpers.ts b/wallets/provider-safepal/src/helpers.ts index 4c3e78e6a0..0c6875ed64 100644 --- a/wallets/provider-safepal/src/helpers.ts +++ b/wallets/provider-safepal/src/helpers.ts @@ -1,4 +1,6 @@ -import { Network, ProviderConnectResult } from '@rango-dev/wallets-shared'; +import type { Network, ProviderConnectResult } from '@rango-dev/wallets-shared'; + +import { Networks } from '@rango-dev/wallets-shared'; type Provider = Map; @@ -6,15 +8,21 @@ export function safepal() { const instances = new Map(); const { isSafePal, safepal, safepalProvider } = window; - if (!isSafePal) return null; + if (!isSafePal) { + return null; + } - if (!!safepal && safepal.isSafePalWallet) - instances.set(Network.SOLANA, safepal); + if (!!safepal && safepal.isSafePalWallet) { + instances.set(Networks.SOLANA, safepal); + } - if (safepalProvider && safepalProvider) - instances.set(Network.ETHEREUM, safepalProvider); + if (safepalProvider && safepalProvider) { + instances.set(Networks.ETHEREUM, safepalProvider); + } - if (instances.size === 0) return null; + if (instances.size === 0) { + return null; + } return instances; } @@ -22,17 +30,17 @@ export function safepal() { export async function getNonEvmAccounts( instances: Provider ): Promise { - const solanaInstance = instances.get(Network.SOLANA); + const solanaInstance = instances.get(Networks.SOLANA); const results: ProviderConnectResult[] = []; - if (!!solanaInstance) { + if (solanaInstance) { const solanaResponse = await solanaInstance.connect(); const solanaAccounts: string = solanaResponse.publicKey.toString(); results.push({ accounts: [solanaAccounts], - chainId: Network.SOLANA, + chainId: Networks.SOLANA, }); } diff --git a/wallets/provider-safepal/src/index.ts b/wallets/provider-safepal/src/index.ts index 9f4a4c3b7b..be7ea142fb 100644 --- a/wallets/provider-safepal/src/index.ts +++ b/wallets/provider-safepal/src/index.ts @@ -1,37 +1,37 @@ -import { - Network, - WalletType, +import type { CanSwitchNetwork, Connect, ProviderConnectResult, Subscribe, SwitchNetwork, + WalletInfo, +} from '@rango-dev/wallets-shared'; +import type { BlockchainMeta, SignerFactory } from 'rango-types'; + +import { canSwitchNetworkToEvm, chooseInstance, getEvmAccounts, + Networks, subscribeToEvm, switchNetworkForEvm, - WalletInfo, + WalletTypes, } from '@rango-dev/wallets-shared'; -import { getNonEvmAccounts, safepal as safepal_instance } from './helpers'; -import signer from './signer'; -import { - SignerFactory, - BlockchainMeta, - evmBlockchains, - solanaBlockchain, -} from 'rango-types'; +import { evmBlockchains, solanaBlockchain } from 'rango-types'; + +import { getNonEvmAccounts, safepal as safepal_instance } from './helpers.js'; +import signer from './signer.js'; -const WALLET = WalletType.SAFEPAL; +const WALLET = WalletTypes.SAFEPAL; export const config = { type: WALLET, - defaultNetwork: Network.ETHEREUM, + defaultNetwork: Networks.ETHEREUM, }; export const getInstance = safepal_instance; export const connect: Connect = async ({ instance, meta }) => { - const ethInstance = chooseInstance(instance, meta, Network.ETHEREUM); + const ethInstance = chooseInstance(instance, meta, Networks.ETHEREUM); let results: ProviderConnectResult[] = []; @@ -47,22 +47,29 @@ export const connect: Connect = async ({ instance, meta }) => { }; export const subscribe: Subscribe = (options) => { + let cleanup: ReturnType; const ethInstance = chooseInstance( options.instance, options.meta, - Network.ETHEREUM + Networks.ETHEREUM ); if (ethInstance) { - subscribeToEvm({ ...options, instance: ethInstance }); + cleanup = subscribeToEvm({ ...options, instance: ethInstance }); } + + return () => { + if (cleanup) { + cleanup(); + } + }; }; export const switchNetwork: SwitchNetwork = switchNetworkForEvm; export const canSwitchNetworkTo: CanSwitchNetwork = canSwitchNetworkToEvm; -export const getSigners: (provider: any) => SignerFactory = signer; +export const getSigners: (provider: any) => Promise = signer; export const getWalletInfo: (allBlockChains: BlockchainMeta[]) => WalletInfo = ( allBlockChains @@ -71,7 +78,7 @@ export const getWalletInfo: (allBlockChains: BlockchainMeta[]) => WalletInfo = ( const solana = solanaBlockchain(allBlockChains); return { name: 'SafePal', - img: 'https://raw.githubusercontent.com/rango-exchange/rango-types/main/assets/icons/wallets/safepal.png', + img: 'https://raw.githubusercontent.com/rango-exchange/assets/main/wallets/safepal/icon.svg', installLink: { CHROME: 'https://chrome.google.com/webstore/detail/safepal-extension-wallet/lgmpcpglpngdoalbgeoldeajfclnhafa', diff --git a/wallets/provider-safepal/src/signer.ts b/wallets/provider-safepal/src/signer.ts index 0585e651d9..99e6ce0dcd 100644 --- a/wallets/provider-safepal/src/signer.ts +++ b/wallets/provider-safepal/src/signer.ts @@ -1,12 +1,16 @@ -import { DefaultEvmSigner } from '@rango-dev/signer-evm'; +import type { SignerFactory } from 'rango-types'; + import { DefaultSolanaSigner } from '@rango-dev/signer-solana'; -import { Network, getNetworkInstance } from '@rango-dev/wallets-shared'; -import { SignerFactory, TransactionType as TxType } from 'rango-types'; +import { getNetworkInstance, Networks } from '@rango-dev/wallets-shared'; +import { DefaultSignerFactory, TransactionType as TxType } from 'rango-types'; -export default function getSigners(provider: any): SignerFactory { - const ethProvider = getNetworkInstance(provider, Network.ETHEREUM); - const solProvider = getNetworkInstance(provider, Network.SOLANA); - const signers = new SignerFactory(); +export default async function getSigners( + provider: any +): Promise { + const ethProvider = getNetworkInstance(provider, Networks.ETHEREUM); + const solProvider = getNetworkInstance(provider, Networks.SOLANA); + const signers = new DefaultSignerFactory(); + const { DefaultEvmSigner } = await import('@rango-dev/signer-evm'); signers.registerSigner(TxType.EVM, new DefaultEvmSigner(ethProvider)); signers.registerSigner(TxType.SOLANA, new DefaultSolanaSigner(solProvider)); return signers; diff --git a/wallets/provider-safepal/tsconfig.build.json b/wallets/provider-safepal/tsconfig.build.json new file mode 100644 index 0000000000..d9181ce0cd --- /dev/null +++ b/wallets/provider-safepal/tsconfig.build.json @@ -0,0 +1,11 @@ +{ + // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs + "extends": "../../tsconfig.libnext.json", + "include": ["src", "types", "../../global-wallets-env.d.ts"], + "compilerOptions": { + "outDir": "dist", + "rootDir": "./src", + "lib": ["dom", "esnext"] + // match output dir to input dir. e.g. dist/index instead of dist/src/index + } +} diff --git a/wallets/provider-safepal/tsconfig.json b/wallets/provider-safepal/tsconfig.json index 365489616a..a3a0b0f59d 100644 --- a/wallets/provider-safepal/tsconfig.json +++ b/wallets/provider-safepal/tsconfig.json @@ -1,35 +1 @@ -{ - // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs - "include": ["src", "types", "../../global-wallets-env.d.ts"], - "compilerOptions": { - "module": "esnext", - "lib": ["dom", "esnext"], - "importHelpers": true, - // output .d.ts declaration files for consumers - "declaration": true, - // output .js.map sourcemap files for consumers - "sourceMap": true, - // match output dir to input dir. e.g. dist/index instead of dist/src/index - "rootDir": "./src", - // stricter type-checking for stronger correctness. Recommended by TS - "strict": true, - // linter checks for common issues - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true, - // noUnused* overlap with @typescript-eslint/no-unused-vars, can disable if duplicative - "noUnusedLocals": true, - "noUnusedParameters": true, - // use Node's module resolution algorithm, instead of the legacy TS one - "moduleResolution": "node", - // transpile JSX to React.createElement - "jsx": "react", - // interop between ESM and CJS modules. Recommended by TS - "esModuleInterop": true, - // significant perf increase by skipping checking .d.ts files, particularly those in node_modules. Recommended by TS - "skipLibCheck": true, - // error out if import and file system have a casing mismatch. Recommended by TS - "forceConsistentCasingInFileNames": true, - // `tsdx build` ignores this option, but it is commonly used when type-checking separately with `tsc` - "noEmit": true, - } -} +{ "extends": "./tsconfig.build.json", "include": ["src", "tests"] } diff --git a/wallets/provider-solflare-snap/CHANGELOG.md b/wallets/provider-solflare-snap/CHANGELOG.md new file mode 100644 index 0000000000..966f1bc5a1 --- /dev/null +++ b/wallets/provider-solflare-snap/CHANGELOG.md @@ -0,0 +1,87 @@ +# [0.12.0](https://github.com/rango-exchange/rango-client/compare/provider-solflare-snap@0.11.0...provider-solflare-snap@0.12.0) (2024-12-30) + + + +# [0.11.0](https://github.com/rango-exchange/rango-client/compare/provider-solflare-snap@0.10.0...provider-solflare-snap@0.11.0) (2024-11-27) + + +### Features + +* add ton connect provider ([2a2dbb7](https://github.com/rango-exchange/rango-client/commit/2a2dbb79022263f19446ced49d298e04d63f927f)) + + + +# [0.10.0](https://github.com/rango-exchange/rango-client/compare/provider-solflare-snap@0.9.0...provider-solflare-snap@0.10.0) (2024-11-12) + + + +# [0.9.0](https://github.com/rango-exchange/rango-client/compare/provider-solflare-snap@0.8.0...provider-solflare-snap@0.9.0) (2024-10-12) + + +### Bug Fixes + +* bump sdk and fix type issues ([d442208](https://github.com/rango-exchange/rango-client/commit/d4422083bf5dd27d5f509ce1db7f9560d05428c8)) + + +### Performance Improvements + +* enable code splitting in build process ([fe5a41e](https://github.com/rango-exchange/rango-client/commit/fe5a41e0e297298de11cd74ca5825544742aa03a)) +* lazy load signer packages ([7b88f18](https://github.com/rango-exchange/rango-client/commit/7b88f1834f7b29b4b81ab6c81a07bb88e8ccf55c)) + + + +# [0.8.0](https://github.com/rango-exchange/rango-client/compare/provider-solflare-snap@0.7.0...provider-solflare-snap@0.8.0) (2024-09-10) + + +### Bug Fixes + +* fix solfare and solfare-snap signers ([896c70b](https://github.com/rango-exchange/rango-client/commit/896c70b8cc8b5e29ec6dfcd98378ef0b3f05698f)) + + + +# [0.7.0](https://github.com/rango-exchange/rango-client/compare/provider-solflare-snap@0.6.1...provider-solflare-snap@0.7.0) (2024-08-11) + + +### Features + +* implement sign message method for providers with a custom signer ([cf9515f](https://github.com/rango-exchange/rango-client/commit/cf9515feb5d3754aac9c228fe83315daf1350c85)) + + + +## [0.6.1](https://github.com/rango-exchange/rango-client/compare/provider-solflare-snap@0.6.0...provider-solflare-snap@0.6.1) (2024-07-14) + + + +# [0.6.0](https://github.com/rango-exchange/rango-client/compare/provider-solflare-snap@0.4.2...provider-solflare-snap@0.6.0) (2024-07-09) + + + +# [0.5.0](https://github.com/rango-exchange/rango-client/compare/provider-solflare-snap@0.4.2...provider-solflare-snap@0.5.0) (2024-06-01) + + + +## [0.4.2](https://github.com/rango-exchange/rango-client/compare/provider-solflare-snap@0.4.1...provider-solflare-snap@0.4.2) (2024-05-26) + + + +## [0.4.1](https://github.com/rango-exchange/rango-client/compare/provider-solflare-snap@0.4.0...provider-solflare-snap@0.4.1) (2024-05-25) + + + +# [0.4.0](https://github.com/rango-exchange/rango-client/compare/provider-solflare-snap@0.3.0...provider-solflare-snap@0.4.0) (2024-05-14) + + + +# [0.3.0](https://github.com/rango-exchange/rango-client/compare/provider-solflare-snap@0.2.0...provider-solflare-snap@0.3.0) (2024-04-24) + + + +# 0.2.0 (2024-04-23) + + +### Features + +* add solflare snap connect and signer ([42aa2b0](https://github.com/rango-exchange/rango-client/commit/42aa2b039dd910e8e44db473e1acd28689a8b43b)) + + + diff --git a/wallets/provider-solflare-snap/package.json b/wallets/provider-solflare-snap/package.json new file mode 100644 index 0000000000..a55e2d0a50 --- /dev/null +++ b/wallets/provider-solflare-snap/package.json @@ -0,0 +1,34 @@ +{ + "name": "@rango-dev/provider-solflare-snap", + "version": "0.11.1-next.6", + "license": "MIT", + "type": "module", + "source": "./src/index.ts", + "main": "./dist/index.js", + "exports": { + ".": "./dist/index.js" + }, + "typings": "dist/index.d.ts", + "files": [ + "dist", + "src" + ], + "scripts": { + "build": "node ../../scripts/build/command.mjs --path wallets/provider-solflare-snap", + "ts-check": "tsc --declaration --emitDeclarationOnly -p ./tsconfig.json", + "clean": "rimraf dist", + "format": "prettier --write '{.,src}/**/*.{ts,tsx}'", + "lint": "eslint \"**/*.{ts,tsx}\" --ignore-path ../../.eslintignore" + }, + "dependencies": { + "@rango-dev/provider-metamask": "^0.40.1-next.6", + "@rango-dev/signer-solana": "^0.35.1-next.0", + "@rango-dev/wallets-shared": "^0.40.1-next.6", + "@solflare-wallet/metamask-sdk": "^1.0.3", + "bs58": "^5.0.0", + "rango-types": "^0.1.74" + }, + "publishConfig": { + "access": "public" + } +} \ No newline at end of file diff --git a/wallets/provider-solflare-snap/readme.md b/wallets/provider-solflare-snap/readme.md new file mode 100644 index 0000000000..584c584263 --- /dev/null +++ b/wallets/provider-solflare-snap/readme.md @@ -0,0 +1 @@ +# @rango-dev/provider-solflare-snap diff --git a/wallets/provider-solflare-snap/src/helpers.ts b/wallets/provider-solflare-snap/src/helpers.ts new file mode 100644 index 0000000000..339ff2c752 --- /dev/null +++ b/wallets/provider-solflare-snap/src/helpers.ts @@ -0,0 +1,13 @@ +import { getInstance as getMetaMaskInstance } from '@rango-dev/provider-metamask'; +import SolflareMetaMask from '@solflare-wallet/metamask-sdk'; + +export function getSolflareSnapInstance() { + const metamaskInstance = getMetaMaskInstance(); + if (metamaskInstance) { + const solflareMetaMask = new SolflareMetaMask(); + + return solflareMetaMask; + } + + return null; +} diff --git a/wallets/provider-solflare-snap/src/index.ts b/wallets/provider-solflare-snap/src/index.ts new file mode 100644 index 0000000000..f24548c7d9 --- /dev/null +++ b/wallets/provider-solflare-snap/src/index.ts @@ -0,0 +1,64 @@ +import type { + Connect, + Disconnect, + Subscribe, + WalletInfo, +} from '@rango-dev/wallets-shared'; +import type { BlockchainMeta, SignerFactory } from 'rango-types'; + +import { Networks, WalletTypes } from '@rango-dev/wallets-shared'; +import { solanaBlockchain } from 'rango-types'; + +import { getSolflareSnapInstance } from './helpers.js'; +import signer from './signer.js'; + +export const config = { + type: WalletTypes.SOLFLARE_SNAP, +}; + +export const getInstance = getSolflareSnapInstance; +export const connect: Connect = async ({ instance }) => { + try { + await instance.connect(); + + if (!!instance.standardAccounts?.length) { + return { + accounts: [ + instance.standardAccounts?.map((account: any) => account.address), + ], + chainId: Networks.SOLANA, + }; + } + + return []; + } catch (error) { + throw new Error('Could not connect to Snap'); + } +}; + +export const disconnect: Disconnect = async ({ instance }) => { + if (instance?.isConnected) { + instance?.disconnect(); + } +}; + +export const subscribe: Subscribe = ({ instance, disconnect }) => { + instance?.on('disconnect', async () => disconnect()); +}; + +export const getSigners: (provider: any) => Promise = signer; + +export const getWalletInfo: (allBlockChains: BlockchainMeta[]) => WalletInfo = ( + allBlockChains +) => { + const solana = solanaBlockchain(allBlockChains); + return { + name: 'Solana Snap', + img: 'https://raw.githubusercontent.com/rango-exchange/assets/main/wallets/solflare-snap/icon.svg', + installLink: { + DEFAULT: 'https://solflare.com/metamask', + }, + color: '#dac7ae', + supportedChains: solana, + }; +}; diff --git a/wallets/provider-solflare-snap/src/signer.ts b/wallets/provider-solflare-snap/src/signer.ts new file mode 100644 index 0000000000..9094bc7c52 --- /dev/null +++ b/wallets/provider-solflare-snap/src/signer.ts @@ -0,0 +1,13 @@ +import type { SignerFactory } from 'rango-types'; + +import { DefaultSignerFactory, TransactionType as TxType } from 'rango-types'; + +import { SolflareSnapSolanaSigner } from './signers/solanaSigner.js'; + +export default async function getSigners( + provider: any +): Promise { + const signers = new DefaultSignerFactory(); + signers.registerSigner(TxType.SOLANA, new SolflareSnapSolanaSigner(provider)); + return signers; +} diff --git a/wallets/provider-solflare-snap/src/signers/solanaSigner.ts b/wallets/provider-solflare-snap/src/signers/solanaSigner.ts new file mode 100644 index 0000000000..dbeac155c5 --- /dev/null +++ b/wallets/provider-solflare-snap/src/signers/solanaSigner.ts @@ -0,0 +1,63 @@ +import type SolflareMetaMask from '@solflare-wallet/metamask-sdk'; +import type { GenericSigner, SolanaTransaction } from 'rango-types'; + +import { + getSolanaConnection, + prepareTransaction, + simulateTransaction, +} from '@rango-dev/signer-solana'; +import base58 from 'bs58'; +import { SignerError, SignerErrorCode } from 'rango-types'; + +const REJECTION_CODE = 4001; + +export class SolflareSnapSolanaSigner + implements GenericSigner +{ + private provider: SolflareMetaMask; + + constructor(provider: SolflareMetaMask) { + this.provider = provider; + } + + async signMessage(msg: string): Promise { + try { + const encodedMessage = new TextEncoder().encode(msg); + const signature = await this.provider.signMessage(encodedMessage); + return base58.encode(signature); + } catch (error) { + throw new SignerError(SignerErrorCode.SIGN_TX_ERROR, undefined, error); + } + } + + async signAndSendTx(tx: SolanaTransaction): Promise<{ hash: string }> { + try { + const connection = getSolanaConnection(); + const latestBlock = await connection.getLatestBlockhash('confirmed'); + + const finalTx = prepareTransaction(tx, latestBlock.blockhash); + + await simulateTransaction(finalTx, tx.txType); + + const hash = await this.provider.signAndSendTransaction(finalTx); + + return { hash }; + } catch (error: any) { + if (error instanceof SignerError) { + throw error; + } + if ( + error && + Object.hasOwn(error, 'code') && + error.code === REJECTION_CODE + ) { + throw new SignerError( + SignerErrorCode.REJECTED_BY_USER, + undefined, + error + ); + } + throw new SignerError(SignerErrorCode.SEND_TX_ERROR, undefined, error); + } + } +} diff --git a/wallets/provider-solflare-snap/tsconfig.build.json b/wallets/provider-solflare-snap/tsconfig.build.json new file mode 100644 index 0000000000..9bb3c269bf --- /dev/null +++ b/wallets/provider-solflare-snap/tsconfig.build.json @@ -0,0 +1,11 @@ +{ + // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs + "extends": "../../tsconfig.bundler.json", + "include": ["src", "types", "../../global-wallets-env.d.ts"], + "compilerOptions": { + "outDir": "dist", + "rootDir": "./src", + "lib": ["dom", "esnext"] + // match output dir to input dir. e.g. dist/index instead of dist/src/index + } +} diff --git a/wallets/provider-solflare-snap/tsconfig.json b/wallets/provider-solflare-snap/tsconfig.json new file mode 100644 index 0000000000..a3a0b0f59d --- /dev/null +++ b/wallets/provider-solflare-snap/tsconfig.json @@ -0,0 +1 @@ +{ "extends": "./tsconfig.build.json", "include": ["src", "tests"] } diff --git a/wallets/provider-solflare/CHANGELOG.md b/wallets/provider-solflare/CHANGELOG.md new file mode 100644 index 0000000000..0d2e4e97bf --- /dev/null +++ b/wallets/provider-solflare/CHANGELOG.md @@ -0,0 +1,59 @@ +# [0.7.0](https://github.com/rango-exchange/rango-client/compare/provider-solflare@0.6.0...provider-solflare@0.7.0) (2024-12-30) + + + +# [0.6.0](https://github.com/rango-exchange/rango-client/compare/provider-solflare@0.5.0...provider-solflare@0.6.0) (2024-11-27) + + +### Features + +* add ton connect provider ([2a2dbb7](https://github.com/rango-exchange/rango-client/commit/2a2dbb79022263f19446ced49d298e04d63f927f)) + + + +# [0.5.0](https://github.com/rango-exchange/rango-client/compare/provider-solflare@0.4.1...provider-solflare@0.5.0) (2024-11-12) + + + +## [0.4.1](https://github.com/rango-exchange/rango-client/compare/provider-solflare@0.4.0...provider-solflare@0.4.1) (2024-10-30) + + +### Bug Fixes + +* when host is using cjs, fallback to .default() for solfare sdk ([0aa702a](https://github.com/rango-exchange/rango-client/commit/0aa702ab1bed865a049541e87c4fa3b1a5006c1d)) + + + +# [0.4.0](https://github.com/rango-exchange/rango-client/compare/provider-solflare@0.3.0...provider-solflare@0.4.0) (2024-10-12) + + +### Bug Fixes + +* bump sdk and fix type issues ([d442208](https://github.com/rango-exchange/rango-client/commit/d4422083bf5dd27d5f509ce1db7f9560d05428c8)) + + +### Performance Improvements + +* enable code splitting in build process ([fe5a41e](https://github.com/rango-exchange/rango-client/commit/fe5a41e0e297298de11cd74ca5825544742aa03a)) +* lazy load signer packages ([7b88f18](https://github.com/rango-exchange/rango-client/commit/7b88f1834f7b29b4b81ab6c81a07bb88e8ccf55c)) + + + +# [0.3.0](https://github.com/rango-exchange/rango-client/compare/provider-solflare@0.2.0...provider-solflare@0.3.0) (2024-09-10) + + +### Bug Fixes + +* fix solfare and solfare-snap signers ([896c70b](https://github.com/rango-exchange/rango-client/commit/896c70b8cc8b5e29ec6dfcd98378ef0b3f05698f)) + + + +# 0.2.0 (2024-08-11) + + +### Features + +* integrate solflare wallet ([fb6aaf1](https://github.com/rango-exchange/rango-client/commit/fb6aaf1c255149df18a75a7bfb16fc83c23b85a8)) + + + diff --git a/wallets/provider-solflare/package.json b/wallets/provider-solflare/package.json new file mode 100644 index 0000000000..8fcf39e816 --- /dev/null +++ b/wallets/provider-solflare/package.json @@ -0,0 +1,33 @@ +{ + "name": "@rango-dev/provider-solflare", + "version": "0.6.1-next.6", + "license": "MIT", + "type": "module", + "source": "./src/index.ts", + "main": "./dist/index.js", + "exports": { + ".": "./dist/index.js" + }, + "typings": "dist/index.d.ts", + "files": [ + "dist", + "src" + ], + "scripts": { + "build": "node ../../scripts/build/command.mjs --path wallets/provider-solflare", + "ts-check": "tsc --declaration --emitDeclarationOnly -p ./tsconfig.json", + "clean": "rimraf dist", + "format": "prettier --write '{.,src}/**/*.{ts,tsx}'", + "lint": "eslint \"**/*.{ts,tsx}\" --ignore-path ../../.eslintignore" + }, + "dependencies": { + "@rango-dev/signer-solana": "^0.35.1-next.0", + "@rango-dev/wallets-shared": "^0.40.1-next.6", + "@solflare-wallet/sdk": "^1.4.2", + "bs58": "^5.0.0", + "rango-types": "^0.1.74" + }, + "publishConfig": { + "access": "public" + } +} \ No newline at end of file diff --git a/wallets/provider-solflare/readme.md b/wallets/provider-solflare/readme.md new file mode 100644 index 0000000000..f79779aa32 --- /dev/null +++ b/wallets/provider-solflare/readme.md @@ -0,0 +1 @@ +# @rango-dev/provider-solflare diff --git a/wallets/provider-solflare/src/index.ts b/wallets/provider-solflare/src/index.ts new file mode 100644 index 0000000000..208af66e5a --- /dev/null +++ b/wallets/provider-solflare/src/index.ts @@ -0,0 +1,100 @@ +import type { + CanSwitchNetwork, + Connect, + Subscribe, + WalletInfo, +} from '@rango-dev/wallets-shared'; +import type { BlockchainMeta, SignerFactory } from 'rango-types'; + +import { Networks, WalletTypes } from '@rango-dev/wallets-shared'; +import Solflare from '@solflare-wallet/sdk'; +import { solanaBlockchain } from 'rango-types'; + +import signer from './signer.js'; + +const WALLET = WalletTypes.SOLFLARE; + +export const config = { + type: WALLET, +}; +/* + * Solflare is a transpiling ESM to CJS as well. It causes interop issues which is normally will be fixed using following code + */ +let SDK = Solflare; +if ( + typeof Solflare !== 'function' && + // @ts-expect-error This import error is not visible to TypeScript + typeof Solflare.default === 'function' +) { + SDK = (Solflare as unknown as { default: typeof Solflare }).default; +} +const walletInstance = new SDK(); + +export const getInstance = () => (window.solflare ? walletInstance : null); +export const connect: Connect = async ({ + instance, +}: { + instance: Solflare; +}) => { + try { + await instance.connect(); + + if (instance.publicKey) { + const account = instance.publicKey?.toString(); + + return { + accounts: [account], + chainId: Networks.SOLANA, + }; + } + throw new Error(); + } catch (error) { + throw new Error('An error occurred while connecting to Solflare.'); + } +}; + +export const subscribe: Subscribe = ({ + instance, + updateAccounts, + disconnect, +}) => { + const handleAccountsChanged = async (publicKey: string) => { + if (publicKey) { + const account = publicKey.toString(); + updateAccounts([account]); + } else { + disconnect(); + } + }; + instance?.on?.('accountChanged', handleAccountsChanged); + + return () => { + instance?.off?.('accountChanged', handleAccountsChanged); + }; +}; + +export const canSwitchNetworkTo: CanSwitchNetwork = () => false; + +export const getSigners: (provider: any) => Promise = signer; + +export const getWalletInfo: (allBlockChains: BlockchainMeta[]) => WalletInfo = ( + allBlockChains +) => { + const solana = solanaBlockchain(allBlockChains); + return { + name: 'Solflare', + img: 'https://raw.githubusercontent.com/rango-exchange/assets/main/wallets/solflare/icon.svg', + installLink: { + CHROME: + 'https://chromewebstore.google.com/detail/solflare-wallet/bhhhlbepdkbapadjdnnojkbgioiodbic', + BRAVE: + 'https://chromewebstore.google.com/detail/solflare-wallet/bhhhlbepdkbapadjdnnojkbgioiodbic', + FIREFOX: + 'https://addons.mozilla.org/en-US/firefox/addon/solflare-wallet/', + EDGE: 'https://chromewebstore.google.com/detail/solflare-wallet/bhhhlbepdkbapadjdnnojkbgioiodbic', + DEFAULT: 'https://solflare.com', + }, + color: '#4d40c6', + supportedChains: solana, + }; +}; diff --git a/wallets/provider-solflare/src/signer.ts b/wallets/provider-solflare/src/signer.ts new file mode 100644 index 0000000000..b898b4f1f4 --- /dev/null +++ b/wallets/provider-solflare/src/signer.ts @@ -0,0 +1,14 @@ +import type Solflare from '@solflare-wallet/sdk'; +import type { SignerFactory } from 'rango-types'; + +import { DefaultSignerFactory, TransactionType as TxType } from 'rango-types'; + +import { CustomSolanaSigner } from './signers/solanaSigner.js'; + +export default async function getSigners( + provider: Solflare +): Promise { + const signers = new DefaultSignerFactory(); + signers.registerSigner(TxType.SOLANA, new CustomSolanaSigner(provider)); + return signers; +} diff --git a/wallets/provider-solflare/src/signers/solanaSigner.ts b/wallets/provider-solflare/src/signers/solanaSigner.ts new file mode 100644 index 0000000000..046303213c --- /dev/null +++ b/wallets/provider-solflare/src/signers/solanaSigner.ts @@ -0,0 +1,28 @@ +import type Solflare from '@solflare-wallet/sdk'; +import type { GenericSigner, SolanaTransaction } from 'rango-types'; + +import { executeSolanaTransaction } from '@rango-dev/signer-solana'; +import base58 from 'bs58'; + +export class CustomSolanaSigner implements GenericSigner { + private provider: any; // Used any instead of Solflare because there is an issue in type of `signTransaction` method of Solflare + + constructor(provider: Solflare) { + this.provider = provider; + } + + async signMessage(msg: string): Promise { + const encoder = new TextEncoder(); + const messageBytes = encoder.encode(msg); + const messageSignature = await this.provider.signMessage( + messageBytes, + 'utf8' + ); + return base58.encode(messageSignature); + } + + async signAndSendTx(tx: SolanaTransaction): Promise<{ hash: string }> { + const hash = await executeSolanaTransaction(tx, this.provider); + return { hash }; + } +} diff --git a/wallets/provider-solflare/tsconfig.build.json b/wallets/provider-solflare/tsconfig.build.json new file mode 100644 index 0000000000..42470c5192 --- /dev/null +++ b/wallets/provider-solflare/tsconfig.build.json @@ -0,0 +1,11 @@ +{ + // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs + "extends": "../../tsconfig.bundler.json", + "include": ["src"], + "files": ["../../global-wallets-env.d.ts"], + "compilerOptions": { + "outDir": "dist", + "rootDir": "./src", + "lib": ["dom", "esnext"] + } +} diff --git a/wallets/provider-solflare/tsconfig.json b/wallets/provider-solflare/tsconfig.json new file mode 100644 index 0000000000..a3a0b0f59d --- /dev/null +++ b/wallets/provider-solflare/tsconfig.json @@ -0,0 +1 @@ +{ "extends": "./tsconfig.build.json", "include": ["src", "tests"] } diff --git a/wallets/provider-station/CHANGELOG.md b/wallets/provider-station/CHANGELOG.md new file mode 100644 index 0000000000..98506e1a50 --- /dev/null +++ b/wallets/provider-station/CHANGELOG.md @@ -0,0 +1,146 @@ +# [0.40.0](https://github.com/rango-exchange/rango-client/compare/provider-station@0.39.0...provider-station@0.40.0) (2024-12-30) + + + +# [0.39.0](https://github.com/rango-exchange/rango-client/compare/provider-station@0.38.0...provider-station@0.39.0) (2024-11-27) + + + +# [0.38.0](https://github.com/rango-exchange/rango-client/compare/provider-station@0.37.0...provider-station@0.38.0) (2024-11-12) + + + +# [0.37.0](https://github.com/rango-exchange/rango-client/compare/provider-station@0.36.0...provider-station@0.37.0) (2024-10-12) + + +### Bug Fixes + +* bump sdk and fix type issues ([d442208](https://github.com/rango-exchange/rango-client/commit/d4422083bf5dd27d5f509ce1db7f9560d05428c8)) + + +### Performance Improvements + +* lazy load signer packages ([7b88f18](https://github.com/rango-exchange/rango-client/commit/7b88f1834f7b29b4b81ab6c81a07bb88e8ccf55c)) + + + +# [0.36.0](https://github.com/rango-exchange/rango-client/compare/provider-station@0.35.0...provider-station@0.36.0) (2024-09-10) + + + +# [0.35.0](https://github.com/rango-exchange/rango-client/compare/provider-station@0.34.1...provider-station@0.35.0) (2024-08-11) + + + +## [0.34.1](https://github.com/rango-exchange/rango-client/compare/provider-station@0.34.0...provider-station@0.34.1) (2024-07-14) + + + +# [0.34.0](https://github.com/rango-exchange/rango-client/compare/provider-station@0.32.0...provider-station@0.34.0) (2024-07-09) + + + +# [0.33.0](https://github.com/rango-exchange/rango-client/compare/provider-station@0.32.0...provider-station@0.33.0) (2024-06-01) + + + +# [0.32.0](https://github.com/rango-exchange/rango-client/compare/provider-station@0.31.0...provider-station@0.32.0) (2024-05-14) + + + +# [0.31.0](https://github.com/rango-exchange/rango-client/compare/provider-station@0.30.0...provider-station@0.31.0) (2024-04-24) + + + +# [0.30.0](https://github.com/rango-exchange/rango-client/compare/provider-station@0.29.0...provider-station@0.30.0) (2024-04-23) + + + +# [0.29.0](https://github.com/rango-exchange/rango-client/compare/provider-station@0.28.0...provider-station@0.29.0) (2024-04-09) + + + +# [0.28.0](https://github.com/rango-exchange/rango-client/compare/provider-station@0.27.0...provider-station@0.28.0) (2024-03-12) + + + +# [0.27.0](https://github.com/rango-exchange/rango-client/compare/provider-station@0.26.0...provider-station@0.27.0) (2024-02-20) + + + +# [0.26.0](https://github.com/rango-exchange/rango-client/compare/provider-station@0.25.0...provider-station@0.26.0) (2024-02-07) + + + +# [0.25.0](https://github.com/rango-exchange/rango-client/compare/provider-station@0.24.0...provider-station@0.25.0) (2024-01-22) + + +### Bug Fixes + +* cleanup wallets' subscriber when setProvider get null ([88d6a42](https://github.com/rango-exchange/rango-client/commit/88d6a423c49b34b3d9ff567e22df36c3b009bb76)) + + + +# [0.24.0](https://github.com/rango-exchange/rango-client/compare/provider-station@0.23.0...provider-station@0.24.0) (2023-12-24) + + +### Bug Fixes + +* fix HMR for widget and playground ([8524820](https://github.com/rango-exchange/rango-client/commit/8524820f10cf0b8921f3db0c4f620ff98daa4103)) + + + +# [0.14.0](https://github.com/rango-exchange/rango-client/compare/provider-station@0.13.0...provider-station@0.14.0) (2023-08-03) + + + +# [0.13.0](https://github.com/rango-exchange/rango-client/compare/provider-station@0.12.0...provider-station@0.13.0) (2023-08-01) + + + +# [0.9.0](https://github.com/rango-exchange/rango-client/compare/provider-station@0.8.0...provider-station@0.9.0) (2023-07-31) + + + +# [0.7.0](https://github.com/rango-exchange/rango-client/compare/provider-station@0.6.0...provider-station@0.7.0) (2023-07-11) + + + +# [0.6.0](https://github.com/rango-exchange/rango-client/compare/provider-station@0.5.0...provider-station@0.6.0) (2023-07-11) + + +### Reverts + +* Revert "support for rango-types cjs format" ([ed4e050](https://github.com/rango-exchange/rango-client/commit/ed4e050bfc0dcde7aeffa6b0d73b02080a5721eb)) + + + +# [0.5.0](https://github.com/rango-exchange/rango-client/compare/provider-station@0.4.0...provider-station@0.5.0) (2023-05-31) + + + +# [0.4.0](https://github.com/rango-exchange/rango-client/compare/provider-station@0.3.0...provider-station@0.4.0) (2023-05-31) + + + +# [0.3.0](https://github.com/rango-exchange/rango-client/compare/provider-station@0.2.0...provider-station@0.3.0) (2023-05-30) + + + +# [0.2.0](https://github.com/rango-exchange/rango-client/compare/provider-station@0.1.18...provider-station@0.2.0) (2023-05-30) + + + +## [0.1.18](https://github.com/rango-exchange/rango-client/compare/provider-station@0.1.17...provider-station@0.1.18) (2023-05-15) + + + +## 0.1.11 (2023-05-15) + + +### Bug Fixes + +* refactor station wallet ([580a2af](https://github.com/rango-exchange/rango-client/commit/580a2af692f63a85921d69152464143551b3f748)) + + + diff --git a/wallets/provider-station/package.json b/wallets/provider-station/package.json new file mode 100644 index 0000000000..9734533970 --- /dev/null +++ b/wallets/provider-station/package.json @@ -0,0 +1,35 @@ +{ + "name": "@rango-dev/provider-station", + "version": "0.39.1-next.6", + "license": "MIT", + "type": "module", + "source": "./src/index.ts", + "main": "./dist/index.js", + "exports": { + ".": "./dist/index.js" + }, + "typings": "dist/index.d.ts", + "files": [ + "dist", + "src" + ], + "scripts": { + "build": "node ../../scripts/build/command.mjs --path wallets/provider-station", + "ts-check": "tsc --declaration --emitDeclarationOnly -p ./tsconfig.json", + "clean": "rimraf dist", + "format": "prettier --write '{.,src}/**/*.{ts,tsx}'", + "lint": "eslint \"**/*.{ts,tsx}\" --ignore-path ../../.eslintignore" + }, + "peerDependencies": { + "react": ">=16" + }, + "dependencies": { + "@rango-dev/signer-terra": "^0.31.0", + "@rango-dev/wallets-shared": "^0.40.1-next.6", + "@terra-money/wallet-controller": "^3.11.2", + "rango-types": "^0.1.74" + }, + "publishConfig": { + "access": "public" + } +} \ No newline at end of file diff --git a/wallets/provider-station/src/helpers.ts b/wallets/provider-station/src/helpers.ts new file mode 100644 index 0000000000..dc738e8f62 --- /dev/null +++ b/wallets/provider-station/src/helpers.ts @@ -0,0 +1,43 @@ +import type { NetworkInfo } from '@terra-money/wallet-controller'; + +import { WalletController } from '@terra-money/wallet-controller'; + +export const TERRA_STATION_WALLET_ID = 'station'; + +const classic: NetworkInfo = { + name: 'classic', + chainID: 'columbus-5', + lcd: 'https://lcd.terra.dev', + walletconnectID: 1, +}; +const mainnet: NetworkInfo = { + name: 'mainnet', + chainID: 'phoenix-1', + lcd: 'https://phoenix-lcd.terra.dev', + walletconnectID: 2, +}; + +const walletConnectChainIds: Record = { + 0: classic, + 1: mainnet, +}; + +let controller: any; + +export function station() { + const terra = window.terraWallets; + if (!controller) { + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + controller = new WalletController({ + defaultNetwork: mainnet, + walletConnectChainIds, + }); + } + + if (terra) { + return controller; + } + + return null; +} diff --git a/wallets/provider-station/src/index.ts b/wallets/provider-station/src/index.ts new file mode 100644 index 0000000000..196d170625 --- /dev/null +++ b/wallets/provider-station/src/index.ts @@ -0,0 +1,107 @@ +import type { + CanSwitchNetwork, + Connect, + Subscribe, + WalletInfo, +} from '@rango-dev/wallets-shared'; +import type { BlockchainMeta, SignerFactory } from 'rango-types'; + +import { WalletTypes } from '@rango-dev/wallets-shared'; +import { ConnectType } from '@terra-money/wallet-controller'; + +import { station as station_instance } from './helpers.js'; +import signer from './signer.js'; + +const WALLET = WalletTypes.STATION; +const STATION_WALLET_ID = 'station'; +const INTERVAL_TIMEOUT = 3_000; +const MAX_TRY_COUNT = 3; + +export const config = { + type: WALLET, +}; + +async function waitInterval(instance: any) { + return new Promise((resolve) => { + let count = 1; + const interval = setInterval(async () => { + const state = instance.extension.getLastStates(); + if (state.type === 'WALLET_CONNECTED') { + resolve(state); + clearInterval(interval); + } else { + count++; + } + if (count > MAX_TRY_COUNT) { + resolve(state); + clearInterval(interval); + } + }, INTERVAL_TIMEOUT); + }); +} + +export const getInstance = station_instance; +export const connect: Connect = async ({ instance, meta }) => { + let accounts: string[] = []; + let chainId = ''; + await instance.connect(ConnectType.EXTENSION, STATION_WALLET_ID); + await instance.refetchStates(); + const { network, wallet, type } = await waitInterval(instance); + if (type === 'INITIALIZING') { + throw new Error('Please unlock your Station wallet first.'); + } + chainId = network.chainID; + const foundChain = meta.find((m) => m.chainId === chainId); + if (!foundChain) { + throw new Error( + "We don't support this chain. Please try with another chain" + ); + } + accounts = [wallet.terraAddress]; + return { accounts, chainId }; +}; + +export const subscribe: Subscribe = ({ + instance, + updateAccounts, + updateChainId, +}) => { + instance.states().subscribe({ + next: (value: any) => { + if (value.status === 'WALLET_CONNECTED') { + const accounts = value.wallets.map( + ({ terraAddress }: any) => terraAddress + ); + updateAccounts(accounts); + updateChainId(value.network.chainID); + } + }, + }); +}; + +export const canSwitchNetworkTo: CanSwitchNetwork = () => false; + +export const getSigners: (provider: any) => Promise = signer; + +export const getWalletInfo: (allBlockChains: BlockchainMeta[]) => WalletInfo = ( + allBlockChains +) => { + return { + name: 'Station', + img: 'https://raw.githubusercontent.com/rango-exchange/assets/main/wallets/station/icon.svg', + installLink: { + CHROME: + 'https://chrome.google.com/webstore/detail/terra-station/aiifbnbfobpmeekipheeijimdpnlpgpp', + BRAVE: + 'https://chrome.google.com/webstore/detail/station-wallet/aiifbnbfobpmeekipheeijimdpnlpgpp', + FIREFOX: + 'https://addons.mozilla.org/en-US/firefox/addon/terra-station-wallet/?utm_source=addons.mozilla.org', + DEFAULT: + 'https://classic-docs.terra.money/docs/learn/terra-station/download/terra-station-desktop.html', + }, + color: '#ffffff', + supportedChains: allBlockChains.filter((blockchainMeta) => + ['TERRA_CLASSIC', 'TERRA'].includes(blockchainMeta.name) + ), + }; +}; diff --git a/wallets/provider-station/src/signer.ts b/wallets/provider-station/src/signer.ts new file mode 100644 index 0000000000..ba980bf637 --- /dev/null +++ b/wallets/provider-station/src/signer.ts @@ -0,0 +1,12 @@ +import type { SignerFactory } from 'rango-types'; + +import { DefaultSignerFactory, TransactionType as TxType } from 'rango-types'; + +export default async function getSigners( + provider: any +): Promise { + const signers = new DefaultSignerFactory(); + const { DefaultTerraSigner } = await import('@rango-dev/signer-terra'); + signers.registerSigner(TxType.COSMOS, new DefaultTerraSigner(provider)); + return signers; +} diff --git a/wallets/provider-station/tsconfig.build.json b/wallets/provider-station/tsconfig.build.json new file mode 100644 index 0000000000..d9181ce0cd --- /dev/null +++ b/wallets/provider-station/tsconfig.build.json @@ -0,0 +1,11 @@ +{ + // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs + "extends": "../../tsconfig.libnext.json", + "include": ["src", "types", "../../global-wallets-env.d.ts"], + "compilerOptions": { + "outDir": "dist", + "rootDir": "./src", + "lib": ["dom", "esnext"] + // match output dir to input dir. e.g. dist/index instead of dist/src/index + } +} diff --git a/wallets/provider-station/tsconfig.json b/wallets/provider-station/tsconfig.json new file mode 100644 index 0000000000..a3a0b0f59d --- /dev/null +++ b/wallets/provider-station/tsconfig.json @@ -0,0 +1 @@ +{ "extends": "./tsconfig.build.json", "include": ["src", "tests"] } diff --git a/wallets/provider-taho/CHANGELOG.md b/wallets/provider-taho/CHANGELOG.md new file mode 100644 index 0000000000..4ad42b90fd --- /dev/null +++ b/wallets/provider-taho/CHANGELOG.md @@ -0,0 +1,124 @@ +# [0.41.0](https://github.com/rango-exchange/rango-client/compare/provider-taho@0.40.0...provider-taho@0.41.0) (2024-12-30) + + + +# [0.40.0](https://github.com/rango-exchange/rango-client/compare/provider-taho@0.39.0...provider-taho@0.40.0) (2024-11-27) + + + +# [0.39.0](https://github.com/rango-exchange/rango-client/compare/provider-taho@0.38.0...provider-taho@0.39.0) (2024-11-12) + + + +# [0.38.0](https://github.com/rango-exchange/rango-client/compare/provider-taho@0.37.0...provider-taho@0.38.0) (2024-10-12) + + +### Bug Fixes + +* bump sdk and fix type issues ([d442208](https://github.com/rango-exchange/rango-client/commit/d4422083bf5dd27d5f509ce1db7f9560d05428c8)) + + +### Performance Improvements + +* lazy load signer packages ([7b88f18](https://github.com/rango-exchange/rango-client/commit/7b88f1834f7b29b4b81ab6c81a07bb88e8ccf55c)) + + + +# [0.37.0](https://github.com/rango-exchange/rango-client/compare/provider-taho@0.36.0...provider-taho@0.37.0) (2024-09-10) + + + +# [0.36.0](https://github.com/rango-exchange/rango-client/compare/provider-taho@0.35.1...provider-taho@0.36.0) (2024-08-11) + + + +## [0.35.1](https://github.com/rango-exchange/rango-client/compare/provider-taho@0.35.0...provider-taho@0.35.1) (2024-07-14) + + + +# [0.35.0](https://github.com/rango-exchange/rango-client/compare/provider-taho@0.33.2...provider-taho@0.35.0) (2024-07-09) + + + +# [0.34.0](https://github.com/rango-exchange/rango-client/compare/provider-taho@0.33.2...provider-taho@0.34.0) (2024-06-01) + + + +## [0.33.2](https://github.com/rango-exchange/rango-client/compare/provider-taho@0.33.1...provider-taho@0.33.2) (2024-05-26) + + + +## [0.33.1](https://github.com/rango-exchange/rango-client/compare/provider-taho@0.33.0...provider-taho@0.33.1) (2024-05-25) + + + +# [0.33.0](https://github.com/rango-exchange/rango-client/compare/provider-taho@0.32.0...provider-taho@0.33.0) (2024-05-14) + + + +# [0.32.0](https://github.com/rango-exchange/rango-client/compare/provider-taho@0.31.0...provider-taho@0.32.0) (2024-04-24) + + + +# [0.31.0](https://github.com/rango-exchange/rango-client/compare/provider-taho@0.30.0...provider-taho@0.31.0) (2024-04-23) + + + +# [0.30.0](https://github.com/rango-exchange/rango-client/compare/provider-taho@0.29.0...provider-taho@0.30.0) (2024-04-09) + + + +# [0.29.0](https://github.com/rango-exchange/rango-client/compare/provider-taho@0.28.0...provider-taho@0.29.0) (2024-03-12) + + + +# [0.28.0](https://github.com/rango-exchange/rango-client/compare/provider-taho@0.27.0...provider-taho@0.28.0) (2024-02-20) + + + +# [0.27.0](https://github.com/rango-exchange/rango-client/compare/provider-taho@0.26.0...provider-taho@0.27.0) (2024-02-07) + + + +# [0.26.0](https://github.com/rango-exchange/rango-client/compare/provider-taho@0.25.0...provider-taho@0.26.0) (2024-01-22) + + + +# [0.25.0](https://github.com/rango-exchange/rango-client/compare/provider-taho@0.23.0...provider-taho@0.25.0) (2023-12-24) + + +### Bug Fixes + +* fix HMR for widget and playground ([8524820](https://github.com/rango-exchange/rango-client/commit/8524820f10cf0b8921f3db0c4f620ff98daa4103)) + + + +# [0.14.0](https://github.com/rango-exchange/rango-client/compare/provider-taho@0.13.0...provider-taho@0.14.0) (2023-08-03) + + + +# [0.13.0](https://github.com/rango-exchange/rango-client/compare/provider-taho@0.12.0...provider-taho@0.13.0) (2023-08-01) + + + +# [0.9.0](https://github.com/rango-exchange/rango-client/compare/provider-taho@0.8.0...provider-taho@0.9.0) (2023-07-31) + + + +# [0.7.0](https://github.com/rango-exchange/rango-client/compare/provider-taho@0.6.0...provider-taho@0.7.0) (2023-07-11) + + + +# 0.6.0 (2023-07-11) + + + +## [0.1.14](https://github.com/rango-exchange/rango-client/compare/provider-taho@0.1.13...provider-taho@0.1.14) (2023-05-15) + + +### Bug Fixes + +* update rango-types and fix notification bugs ([993f185](https://github.com/rango-exchange/rango-client/commit/993f185e0b8c5e5e15a2c65ba2d85d1f9c8daa90)) + + + diff --git a/wallets/provider-taho/package.json b/wallets/provider-taho/package.json new file mode 100644 index 0000000000..9aa089ed69 --- /dev/null +++ b/wallets/provider-taho/package.json @@ -0,0 +1,31 @@ +{ + "name": "@rango-dev/provider-taho", + "version": "0.40.1-next.6", + "license": "MIT", + "type": "module", + "source": "./src/index.ts", + "main": "./dist/index.js", + "exports": { + ".": "./dist/index.js" + }, + "typings": "dist/index.d.ts", + "files": [ + "dist", + "src" + ], + "scripts": { + "build": "node ../../scripts/build/command.mjs --path wallets/provider-taho", + "ts-check": "tsc --declaration --emitDeclarationOnly -p ./tsconfig.json", + "clean": "rimraf dist", + "format": "prettier --write '{.,src}/**/*.{ts,tsx}'", + "lint": "eslint \"**/*.{ts,tsx}\" --ignore-path ../../.eslintignore" + }, + "dependencies": { + "@rango-dev/signer-evm": "^0.32.0", + "@rango-dev/wallets-shared": "^0.40.1-next.6", + "rango-types": "^0.1.74" + }, + "publishConfig": { + "access": "public" + } +} \ No newline at end of file diff --git a/wallets/provider-taho/readme.md b/wallets/provider-taho/readme.md new file mode 100644 index 0000000000..79de9502a0 --- /dev/null +++ b/wallets/provider-taho/readme.md @@ -0,0 +1 @@ +# @rango-dev/provider-taho diff --git a/wallets/provider-taho/src/helpers.ts b/wallets/provider-taho/src/helpers.ts new file mode 100644 index 0000000000..6b928e4cb1 --- /dev/null +++ b/wallets/provider-taho/src/helpers.ts @@ -0,0 +1,20 @@ +import { Networks } from '@rango-dev/wallets-shared'; + +export function taho() { + const { tally } = window; + + if (!tally) { + return null; + } + + return tally; +} + +export const TAHO_WALLET_SUPPORTED_CHAINS = [ + Networks.ETHEREUM, + Networks.POLYGON, + Networks.OPTIMISM, + Networks.ARBITRUM, + Networks.AVAX_CCHAIN, + Networks.BSC, +]; diff --git a/wallets/provider-taho/src/index.ts b/wallets/provider-taho/src/index.ts new file mode 100644 index 0000000000..78943c5e9f --- /dev/null +++ b/wallets/provider-taho/src/index.ts @@ -0,0 +1,71 @@ +import type { + CanEagerConnect, + CanSwitchNetwork, + Connect, + Networks, + Subscribe, + SwitchNetwork, + WalletInfo, +} from '@rango-dev/wallets-shared'; +import type { BlockchainMeta, SignerFactory } from 'rango-types'; + +import { + canEagerlyConnectToEvm, + canSwitchNetworkToEvm, + getEvmAccounts, + subscribeToEvm, + switchNetworkForEvm, + WalletTypes, +} from '@rango-dev/wallets-shared'; + +import { + taho as taho_instances, + TAHO_WALLET_SUPPORTED_CHAINS, +} from './helpers.js'; +import signer from './signer.js'; + +const WALLET = WalletTypes.TAHO; + +export const config = { + type: WALLET, +}; + +export const getInstance = taho_instances; + +export const connect: Connect = async ({ instance }) => { + const { accounts, chainId } = await getEvmAccounts(instance); + + return { + accounts, + chainId, + }; +}; +export const subscribe: Subscribe = subscribeToEvm; + +export const switchNetwork: SwitchNetwork = switchNetworkForEvm; + +export const canSwitchNetworkTo: CanSwitchNetwork = canSwitchNetworkToEvm; + +export const getSigners: (provider: any) => Promise = signer; + +export const canEagerConnect: CanEagerConnect = canEagerlyConnectToEvm; + +export const getWalletInfo: (allBlockChains: BlockchainMeta[]) => WalletInfo = ( + allBlockChains +) => { + return { + name: 'Taho', + img: 'https://raw.githubusercontent.com/rango-exchange/assets/main/wallets/taho/icon.svg', + installLink: { + CHROME: + 'https://chrome.google.com/webstore/detail/taho/eajafomhmkipbjmfmhebemolkcicgfmd', + BRAVE: + 'https://chrome.google.com/webstore/detail/taho/eajafomhmkipbjmfmhebemolkcicgfmd', + DEFAULT: 'https://taho.xyz', + }, + color: '#ffffff', + supportedChains: allBlockChains.filter((blockchainMeta) => + TAHO_WALLET_SUPPORTED_CHAINS.includes(blockchainMeta.name as Networks) + ), + }; +}; diff --git a/wallets/provider-taho/src/signer.ts b/wallets/provider-taho/src/signer.ts new file mode 100644 index 0000000000..f7dbf93750 --- /dev/null +++ b/wallets/provider-taho/src/signer.ts @@ -0,0 +1,12 @@ +import type { SignerFactory } from 'rango-types'; + +import { DefaultSignerFactory, TransactionType as TxType } from 'rango-types'; + +export default async function getSigners( + provider: any +): Promise { + const signers = new DefaultSignerFactory(); + const { DefaultEvmSigner } = await import('@rango-dev/signer-evm'); + signers.registerSigner(TxType.EVM, new DefaultEvmSigner(provider)); + return signers; +} diff --git a/wallets/provider-taho/tsconfig.build.json b/wallets/provider-taho/tsconfig.build.json new file mode 100644 index 0000000000..d9181ce0cd --- /dev/null +++ b/wallets/provider-taho/tsconfig.build.json @@ -0,0 +1,11 @@ +{ + // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs + "extends": "../../tsconfig.libnext.json", + "include": ["src", "types", "../../global-wallets-env.d.ts"], + "compilerOptions": { + "outDir": "dist", + "rootDir": "./src", + "lib": ["dom", "esnext"] + // match output dir to input dir. e.g. dist/index instead of dist/src/index + } +} diff --git a/wallets/provider-taho/tsconfig.json b/wallets/provider-taho/tsconfig.json new file mode 100644 index 0000000000..a3a0b0f59d --- /dev/null +++ b/wallets/provider-taho/tsconfig.json @@ -0,0 +1 @@ +{ "extends": "./tsconfig.build.json", "include": ["src", "tests"] } diff --git a/wallets/provider-tokenpocket/CHANGELOG.md b/wallets/provider-tokenpocket/CHANGELOG.md new file mode 100644 index 0000000000..3d832e9f87 --- /dev/null +++ b/wallets/provider-tokenpocket/CHANGELOG.md @@ -0,0 +1,145 @@ +# [0.41.0](https://github.com/rango-exchange/rango-client/compare/provider-tokenpocket@0.40.0...provider-tokenpocket@0.41.0) (2024-12-30) + + + +# [0.40.0](https://github.com/rango-exchange/rango-client/compare/provider-tokenpocket@0.39.0...provider-tokenpocket@0.40.0) (2024-11-27) + + + +# [0.39.0](https://github.com/rango-exchange/rango-client/compare/provider-tokenpocket@0.38.0...provider-tokenpocket@0.39.0) (2024-11-12) + + + +# [0.38.0](https://github.com/rango-exchange/rango-client/compare/provider-tokenpocket@0.37.0...provider-tokenpocket@0.38.0) (2024-10-12) + + +### Bug Fixes + +* bump sdk and fix type issues ([d442208](https://github.com/rango-exchange/rango-client/commit/d4422083bf5dd27d5f509ce1db7f9560d05428c8)) + + +### Performance Improvements + +* lazy load signer packages ([7b88f18](https://github.com/rango-exchange/rango-client/commit/7b88f1834f7b29b4b81ab6c81a07bb88e8ccf55c)) + + + +# [0.37.0](https://github.com/rango-exchange/rango-client/compare/provider-tokenpocket@0.36.0...provider-tokenpocket@0.37.0) (2024-09-10) + + + +# [0.36.0](https://github.com/rango-exchange/rango-client/compare/provider-tokenpocket@0.35.1...provider-tokenpocket@0.36.0) (2024-08-11) + + + +## [0.35.1](https://github.com/rango-exchange/rango-client/compare/provider-tokenpocket@0.35.0...provider-tokenpocket@0.35.1) (2024-07-14) + + + +# [0.35.0](https://github.com/rango-exchange/rango-client/compare/provider-tokenpocket@0.33.2...provider-tokenpocket@0.35.0) (2024-07-09) + + + +# [0.34.0](https://github.com/rango-exchange/rango-client/compare/provider-tokenpocket@0.33.2...provider-tokenpocket@0.34.0) (2024-06-01) + + + +## [0.33.2](https://github.com/rango-exchange/rango-client/compare/provider-tokenpocket@0.33.1...provider-tokenpocket@0.33.2) (2024-05-26) + + + +## [0.33.1](https://github.com/rango-exchange/rango-client/compare/provider-tokenpocket@0.33.0...provider-tokenpocket@0.33.1) (2024-05-25) + + + +# [0.33.0](https://github.com/rango-exchange/rango-client/compare/provider-tokenpocket@0.32.0...provider-tokenpocket@0.33.0) (2024-05-14) + + + +# [0.32.0](https://github.com/rango-exchange/rango-client/compare/provider-tokenpocket@0.31.0...provider-tokenpocket@0.32.0) (2024-04-24) + + + +# [0.31.0](https://github.com/rango-exchange/rango-client/compare/provider-tokenpocket@0.30.0...provider-tokenpocket@0.31.0) (2024-04-23) + + + +# [0.30.0](https://github.com/rango-exchange/rango-client/compare/provider-tokenpocket@0.29.0...provider-tokenpocket@0.30.0) (2024-04-09) + + + +# [0.29.0](https://github.com/rango-exchange/rango-client/compare/provider-tokenpocket@0.28.0...provider-tokenpocket@0.29.0) (2024-03-12) + + + +# [0.28.0](https://github.com/rango-exchange/rango-client/compare/provider-tokenpocket@0.27.0...provider-tokenpocket@0.28.0) (2024-02-20) + + + +# [0.27.0](https://github.com/rango-exchange/rango-client/compare/provider-tokenpocket@0.26.0...provider-tokenpocket@0.27.0) (2024-02-07) + + + +# [0.26.0](https://github.com/rango-exchange/rango-client/compare/provider-tokenpocket@0.25.0...provider-tokenpocket@0.26.0) (2024-01-22) + + + +# [0.25.0](https://github.com/rango-exchange/rango-client/compare/provider-tokenpocket@0.23.0...provider-tokenpocket@0.25.0) (2023-12-24) + + +### Bug Fixes + +* fix HMR for widget and playground ([8524820](https://github.com/rango-exchange/rango-client/commit/8524820f10cf0b8921f3db0c4f620ff98daa4103)) + + + +# [0.14.0](https://github.com/rango-exchange/rango-client/compare/provider-tokenpocket@0.13.0...provider-tokenpocket@0.14.0) (2023-08-03) + + + +# [0.13.0](https://github.com/rango-exchange/rango-client/compare/provider-tokenpocket@0.12.0...provider-tokenpocket@0.13.0) (2023-08-01) + + + +# [0.9.0](https://github.com/rango-exchange/rango-client/compare/provider-tokenpocket@0.8.0...provider-tokenpocket@0.9.0) (2023-07-31) + + + +# [0.7.0](https://github.com/rango-exchange/rango-client/compare/provider-tokenpocket@0.6.0...provider-tokenpocket@0.7.0) (2023-07-11) + + + +# [0.6.0](https://github.com/rango-exchange/rango-client/compare/provider-tokenpocket@0.5.0...provider-tokenpocket@0.6.0) (2023-07-11) + + +### Reverts + +* Revert "support for rango-types cjs format" ([ed4e050](https://github.com/rango-exchange/rango-client/commit/ed4e050bfc0dcde7aeffa6b0d73b02080a5721eb)) + + + +# [0.5.0](https://github.com/rango-exchange/rango-client/compare/provider-tokenpocket@0.4.0...provider-tokenpocket@0.5.0) (2023-05-31) + + + +# [0.4.0](https://github.com/rango-exchange/rango-client/compare/provider-tokenpocket@0.3.0...provider-tokenpocket@0.4.0) (2023-05-31) + + + +# [0.3.0](https://github.com/rango-exchange/rango-client/compare/provider-tokenpocket@0.2.0...provider-tokenpocket@0.3.0) (2023-05-30) + + + +# [0.2.0](https://github.com/rango-exchange/rango-client/compare/provider-tokenpocket@0.1.15...provider-tokenpocket@0.2.0) (2023-05-30) + + + +## [0.1.14](https://github.com/rango-exchange/rango-client/compare/provider-tokenpocket@0.1.13...provider-tokenpocket@0.1.14) (2023-05-15) + + +### Bug Fixes + +* update rango-types and fix notification bugs ([993f185](https://github.com/rango-exchange/rango-client/commit/993f185e0b8c5e5e15a2c65ba2d85d1f9c8daa90)) + + + diff --git a/wallets/provider-tokenpocket/package.json b/wallets/provider-tokenpocket/package.json index facc756fb9..c9f9903916 100644 --- a/wallets/provider-tokenpocket/package.json +++ b/wallets/provider-tokenpocket/package.json @@ -1,49 +1,31 @@ { "name": "@rango-dev/provider-tokenpocket", - "version": "0.1.12", + "version": "0.40.1-next.6", "license": "MIT", - "module": "dist/provider-tokenpocket.esm.js", - "main": "dist/index.js", + "type": "module", + "source": "./src/index.ts", + "main": "./dist/index.js", + "exports": { + ".": "./dist/index.js" + }, "typings": "dist/index.d.ts", "files": [ "dist", "src" ], "scripts": { - "start": "tsdx watch", - "build": "tsdx build --tsconfig ./tsconfig.json", - "test": "tsdx test --passWithNoTests", - "lint": "tsdx lint", - "size": "size-limit", - "analyze": "size-limit --why" - }, - "husky": { - "hooks": { - "pre-commit": "tsdx lint" - } + "build": "node ../../scripts/build/command.mjs --path wallets/provider-tokenpocket", + "ts-check": "tsc --declaration --emitDeclarationOnly -p ./tsconfig.json", + "clean": "rimraf dist", + "format": "prettier --write '{.,src}/**/*.{ts,tsx}'", + "lint": "eslint \"**/*.{ts,tsx}\" --ignore-path ../../.eslintignore" }, - "prettier": { - "printWidth": 80, - "semi": true, - "singleQuote": true, - "trailingComma": "es5" - }, - "size-limit": [ - { - "path": "dist/provider-tokenpocket.cjs.production.min.js", - "limit": "10 KB" - }, - { - "path": "dist/provider-tokenpocket.esm.js", - "limit": "10 KB" - } - ], "dependencies": { - "@rango-dev/signer-evm": "^0.1.11", - "@rango-dev/wallets-shared": "^0.1.11", - "rango-types": "^0.1.28" + "@rango-dev/signer-evm": "^0.32.0", + "@rango-dev/wallets-shared": "^0.40.1-next.6", + "rango-types": "^0.1.74" }, "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/wallets/provider-tokenpocket/src/index.ts b/wallets/provider-tokenpocket/src/index.ts index 254673a1b6..50bd04dbce 100644 --- a/wallets/provider-tokenpocket/src/index.ts +++ b/wallets/provider-tokenpocket/src/index.ts @@ -1,20 +1,27 @@ -import { - WalletType, +import type { + CanEagerConnect, CanSwitchNetwork, Connect, Subscribe, SwitchNetwork, + WalletInfo, +} from '@rango-dev/wallets-shared'; +import type { BlockchainMeta, SignerFactory } from 'rango-types'; + +import { + canEagerlyConnectToEvm, canSwitchNetworkToEvm, getEvmAccounts, subscribeToEvm, switchNetworkForEvm, - WalletInfo, + WalletTypes, } from '@rango-dev/wallets-shared'; -import { tokenpocket as tokenpocket_instance } from './helpers'; -import signer from './signer'; -import { SignerFactory, BlockchainMeta, evmBlockchains } from 'rango-types'; +import { evmBlockchains } from 'rango-types'; -const WALLET = WalletType.TOKEN_POCKET; +import { tokenpocket as tokenpocket_instance } from './helpers.js'; +import signer from './signer.js'; + +const WALLET = WalletTypes.TOKEN_POCKET; export const config = { type: WALLET, @@ -22,10 +29,12 @@ export const config = { export const getInstance = tokenpocket_instance; export const connect: Connect = async ({ instance }) => { - // Note: We need to get `chainId` here, because for the first time - // after opening the browser, wallet is locked, and don't give us accounts and chainId - // on `check` phase, so `network` will be null. For this case we need to get chainId - // whenever we are requesting accounts. + /* + * Note: We need to get `chainId` here, because for the first time + * after opening the browser, wallet is locked, and don't give us accounts and chainId + * on `check` phase, so `network` will be null. For this case we need to get chainId + * whenever we are requesting accounts. + */ const { accounts, chainId } = await getEvmAccounts(instance); return { @@ -40,7 +49,9 @@ export const switchNetwork: SwitchNetwork = switchNetworkForEvm; export const canSwitchNetworkTo: CanSwitchNetwork = canSwitchNetworkToEvm; -export const getSigners: (provider: any) => SignerFactory = signer; +export const getSigners: (provider: any) => Promise = signer; + +export const canEagerConnect: CanEagerConnect = canEagerlyConnectToEvm; export const getWalletInfo: (allBlockChains: BlockchainMeta[]) => WalletInfo = ( allBlockChains @@ -48,7 +59,7 @@ export const getWalletInfo: (allBlockChains: BlockchainMeta[]) => WalletInfo = ( const evms = evmBlockchains(allBlockChains); return { name: 'Token Pocket', - img: 'https://raw.githubusercontent.com/rango-exchange/rango-types/main/assets/icons/wallets/tp.png', + img: 'https://raw.githubusercontent.com/rango-exchange/assets/main/wallets/tokenpocket/icon.svg', color: '#b2dbff', installLink: { CHROME: diff --git a/wallets/provider-tokenpocket/src/signer.ts b/wallets/provider-tokenpocket/src/signer.ts index 7ae6c242f8..ef3f4e5d09 100644 --- a/wallets/provider-tokenpocket/src/signer.ts +++ b/wallets/provider-tokenpocket/src/signer.ts @@ -1,10 +1,14 @@ -import { DefaultEvmSigner } from '@rango-dev/signer-evm'; -import { Network, getNetworkInstance } from '@rango-dev/wallets-shared'; -import { SignerFactory, TransactionType as TxType } from 'rango-types'; +import type { SignerFactory } from 'rango-types'; -export default function getSigners(provider: any): SignerFactory { - const ethProvider = getNetworkInstance(provider, Network.ETHEREUM); - const signers = new SignerFactory(); +import { getNetworkInstance, Networks } from '@rango-dev/wallets-shared'; +import { DefaultSignerFactory, TransactionType as TxType } from 'rango-types'; + +export default async function getSigners( + provider: any +): Promise { + const ethProvider = getNetworkInstance(provider, Networks.ETHEREUM); + const signers = new DefaultSignerFactory(); + const { DefaultEvmSigner } = await import('@rango-dev/signer-evm'); signers.registerSigner(TxType.EVM, new DefaultEvmSigner(ethProvider)); return signers; } diff --git a/wallets/provider-tokenpocket/tsconfig.build.json b/wallets/provider-tokenpocket/tsconfig.build.json new file mode 100644 index 0000000000..d9181ce0cd --- /dev/null +++ b/wallets/provider-tokenpocket/tsconfig.build.json @@ -0,0 +1,11 @@ +{ + // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs + "extends": "../../tsconfig.libnext.json", + "include": ["src", "types", "../../global-wallets-env.d.ts"], + "compilerOptions": { + "outDir": "dist", + "rootDir": "./src", + "lib": ["dom", "esnext"] + // match output dir to input dir. e.g. dist/index instead of dist/src/index + } +} diff --git a/wallets/provider-tokenpocket/tsconfig.json b/wallets/provider-tokenpocket/tsconfig.json index 365489616a..a3a0b0f59d 100644 --- a/wallets/provider-tokenpocket/tsconfig.json +++ b/wallets/provider-tokenpocket/tsconfig.json @@ -1,35 +1 @@ -{ - // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs - "include": ["src", "types", "../../global-wallets-env.d.ts"], - "compilerOptions": { - "module": "esnext", - "lib": ["dom", "esnext"], - "importHelpers": true, - // output .d.ts declaration files for consumers - "declaration": true, - // output .js.map sourcemap files for consumers - "sourceMap": true, - // match output dir to input dir. e.g. dist/index instead of dist/src/index - "rootDir": "./src", - // stricter type-checking for stronger correctness. Recommended by TS - "strict": true, - // linter checks for common issues - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true, - // noUnused* overlap with @typescript-eslint/no-unused-vars, can disable if duplicative - "noUnusedLocals": true, - "noUnusedParameters": true, - // use Node's module resolution algorithm, instead of the legacy TS one - "moduleResolution": "node", - // transpile JSX to React.createElement - "jsx": "react", - // interop between ESM and CJS modules. Recommended by TS - "esModuleInterop": true, - // significant perf increase by skipping checking .d.ts files, particularly those in node_modules. Recommended by TS - "skipLibCheck": true, - // error out if import and file system have a casing mismatch. Recommended by TS - "forceConsistentCasingInFileNames": true, - // `tsdx build` ignores this option, but it is commonly used when type-checking separately with `tsc` - "noEmit": true, - } -} +{ "extends": "./tsconfig.build.json", "include": ["src", "tests"] } diff --git a/wallets/provider-tomo/CHANGELOG.md b/wallets/provider-tomo/CHANGELOG.md new file mode 100644 index 0000000000..4934b744ff --- /dev/null +++ b/wallets/provider-tomo/CHANGELOG.md @@ -0,0 +1,47 @@ +# [0.8.0](https://github.com/rango-exchange/rango-client/compare/provider-tomo@0.7.0...provider-tomo@0.8.0) (2024-12-30) + + + +# [0.7.0](https://github.com/rango-exchange/rango-client/compare/provider-tomo@0.6.0...provider-tomo@0.7.0) (2024-11-27) + + + +# [0.6.0](https://github.com/rango-exchange/rango-client/compare/provider-tomo@0.5.0...provider-tomo@0.6.0) (2024-11-12) + + + +# [0.5.0](https://github.com/rango-exchange/rango-client/compare/provider-tomo@0.4.0...provider-tomo@0.5.0) (2024-10-12) + + +### Bug Fixes + +* bump sdk and fix type issues ([d442208](https://github.com/rango-exchange/rango-client/commit/d4422083bf5dd27d5f509ce1db7f9560d05428c8)) + + +### Performance Improvements + +* lazy load signer packages ([7b88f18](https://github.com/rango-exchange/rango-client/commit/7b88f1834f7b29b4b81ab6c81a07bb88e8ccf55c)) + + + +# [0.4.0](https://github.com/rango-exchange/rango-client/compare/provider-tomo@0.3.0...provider-tomo@0.4.0) (2024-09-10) + + + +# [0.3.0](https://github.com/rango-exchange/rango-client/compare/provider-tomo@0.2.1...provider-tomo@0.3.0) (2024-08-11) + + + +## [0.2.1](https://github.com/rango-exchange/rango-client/compare/provider-tomo@0.2.0...provider-tomo@0.2.1) (2024-07-14) + + + +# 0.2.0 (2024-07-09) + + +### Features + +* integrate tomo wallet extension ([9f0f065](https://github.com/rango-exchange/rango-client/commit/9f0f0650fcd213a621dcc6ddca3e32424c1a5ada)) + + + diff --git a/wallets/provider-tomo/package.json b/wallets/provider-tomo/package.json new file mode 100644 index 0000000000..708666e6d6 --- /dev/null +++ b/wallets/provider-tomo/package.json @@ -0,0 +1,31 @@ +{ + "name": "@rango-dev/provider-tomo", + "version": "0.7.1-next.6", + "license": "MIT", + "type": "module", + "source": "./src/index.ts", + "main": "./dist/index.js", + "exports": { + ".": "./dist/index.js" + }, + "typings": "dist/index.d.ts", + "files": [ + "dist", + "src" + ], + "scripts": { + "build": "node ../../scripts/build/command.mjs --path wallets/provider-tomo", + "ts-check": "tsc --declaration --emitDeclarationOnly -p ./tsconfig.json", + "clean": "rimraf dist", + "format": "prettier --write '{.,src}/**/*.{ts,tsx}'", + "lint": "eslint \"**/*.{ts,tsx}\" --ignore-path ../../.eslintignore" + }, + "dependencies": { + "@rango-dev/signer-evm": "^0.32.0", + "@rango-dev/wallets-shared": "^0.40.1-next.6", + "rango-types": "^0.1.74" + }, + "publishConfig": { + "access": "public" + } +} \ No newline at end of file diff --git a/wallets/provider-tomo/readme.md b/wallets/provider-tomo/readme.md new file mode 100644 index 0000000000..0d9ec9c58a --- /dev/null +++ b/wallets/provider-tomo/readme.md @@ -0,0 +1 @@ +# @rango-dev/provider-tomo diff --git a/wallets/provider-tomo/src/helpers.ts b/wallets/provider-tomo/src/helpers.ts new file mode 100644 index 0000000000..881f355674 --- /dev/null +++ b/wallets/provider-tomo/src/helpers.ts @@ -0,0 +1,8 @@ +export function tomo() { + const { tomo_evm } = window; + if (tomo_evm) { + return tomo_evm; + } + + return null; +} diff --git a/wallets/provider-tomo/src/index.ts b/wallets/provider-tomo/src/index.ts new file mode 100644 index 0000000000..a001a4b5f0 --- /dev/null +++ b/wallets/provider-tomo/src/index.ts @@ -0,0 +1,67 @@ +import type { + CanEagerConnect, + CanSwitchNetwork, + Connect, + Subscribe, + SwitchNetwork, + WalletInfo, +} from '@rango-dev/wallets-shared'; +import type { BlockchainMeta, SignerFactory } from 'rango-types'; + +import { + canEagerlyConnectToEvm, + canSwitchNetworkToEvm, + getEvmAccounts, + subscribeToEvm, + switchNetworkForEvm, + WalletTypes, +} from '@rango-dev/wallets-shared'; +import { evmBlockchains } from 'rango-types'; + +import { tomo as tomo_instance } from './helpers.js'; +import signer from './signer.js'; + +const WALLET = WalletTypes.TOMO; + +export const config = { + type: WALLET, +}; + +export const getInstance = tomo_instance; +export const connect: Connect = async ({ instance }) => { + const { accounts, chainId } = await getEvmAccounts(instance); + + return { + accounts, + chainId, + }; +}; + +export const subscribe: Subscribe = subscribeToEvm; + +export const switchNetwork: SwitchNetwork = switchNetworkForEvm; + +export const canSwitchNetworkTo: CanSwitchNetwork = canSwitchNetworkToEvm; + +export const getSigners: (provider: any) => Promise = signer; + +export const canEagerConnect: CanEagerConnect = canEagerlyConnectToEvm; + +export const getWalletInfo: (allBlockChains: BlockchainMeta[]) => WalletInfo = ( + allBlockChains +) => { + const evms = evmBlockchains(allBlockChains); + return { + name: 'Tomo', + img: 'https://raw.githubusercontent.com/rango-exchange/assets/main/wallets/tomo/icon.svg', + color: '#b2dbff', + installLink: { + CHROME: + 'https://chromewebstore.google.com/detail/tomo-wallet/pfccjkejcgoppjnllalolplgogenfojk?hl=en', + BRAVE: + 'https://chromewebstore.google.com/detail/tomo-wallet/pfccjkejcgoppjnllalolplgogenfojk?hl=en', + DEFAULT: 'https://tomo.inc/', + }, + supportedChains: evms, + }; +}; diff --git a/wallets/provider-tomo/src/signer.ts b/wallets/provider-tomo/src/signer.ts new file mode 100644 index 0000000000..ef3f4e5d09 --- /dev/null +++ b/wallets/provider-tomo/src/signer.ts @@ -0,0 +1,14 @@ +import type { SignerFactory } from 'rango-types'; + +import { getNetworkInstance, Networks } from '@rango-dev/wallets-shared'; +import { DefaultSignerFactory, TransactionType as TxType } from 'rango-types'; + +export default async function getSigners( + provider: any +): Promise { + const ethProvider = getNetworkInstance(provider, Networks.ETHEREUM); + const signers = new DefaultSignerFactory(); + const { DefaultEvmSigner } = await import('@rango-dev/signer-evm'); + signers.registerSigner(TxType.EVM, new DefaultEvmSigner(ethProvider)); + return signers; +} diff --git a/wallets/provider-tomo/tsconfig.build.json b/wallets/provider-tomo/tsconfig.build.json new file mode 100644 index 0000000000..d9181ce0cd --- /dev/null +++ b/wallets/provider-tomo/tsconfig.build.json @@ -0,0 +1,11 @@ +{ + // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs + "extends": "../../tsconfig.libnext.json", + "include": ["src", "types", "../../global-wallets-env.d.ts"], + "compilerOptions": { + "outDir": "dist", + "rootDir": "./src", + "lib": ["dom", "esnext"] + // match output dir to input dir. e.g. dist/index instead of dist/src/index + } +} diff --git a/wallets/provider-tomo/tsconfig.json b/wallets/provider-tomo/tsconfig.json new file mode 100644 index 0000000000..a3a0b0f59d --- /dev/null +++ b/wallets/provider-tomo/tsconfig.json @@ -0,0 +1 @@ +{ "extends": "./tsconfig.build.json", "include": ["src", "tests"] } diff --git a/wallets/provider-tonconnect/CHANGELOG.md b/wallets/provider-tonconnect/CHANGELOG.md new file mode 100644 index 0000000000..56d3ca9f87 --- /dev/null +++ b/wallets/provider-tonconnect/CHANGELOG.md @@ -0,0 +1,13 @@ +# [0.3.0](https://github.com/rango-exchange/rango-client/compare/provider-tonconnect@0.2.0...provider-tonconnect@0.3.0) (2024-12-30) + + + +# 0.2.0 (2024-11-27) + + +### Features + +* add ton connect provider ([2a2dbb7](https://github.com/rango-exchange/rango-client/commit/2a2dbb79022263f19446ced49d298e04d63f927f)) + + + diff --git a/wallets/provider-tonconnect/package.json b/wallets/provider-tonconnect/package.json new file mode 100644 index 0000000000..7096edf104 --- /dev/null +++ b/wallets/provider-tonconnect/package.json @@ -0,0 +1,36 @@ +{ + "name": "@rango-dev/provider-tonconnect", + "version": "0.2.1-next.6", + "license": "MIT", + "type": "module", + "source": "./src/index.ts", + "main": "./dist/index.js", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "default": "./dist/index.js" + } + }, + "typings": "dist/index.d.ts", + "files": [ + "dist", + "src" + ], + "scripts": { + "build": "node ../../scripts/build/command.mjs --path wallets/provider-tonconnect", + "ts-check": "tsc --declaration --emitDeclarationOnly -p ./tsconfig.json", + "clean": "rimraf dist", + "format": "prettier --write '{.,src}/**/*.{ts,tsx}'", + "lint": "eslint \"**/*.{ts,tsx}\" --ignore-path ../../.eslintignore" + }, + "dependencies": { + "@rango-dev/wallets-shared": "^0.40.1-next.6", + "@ton/core": "^0.59.0", + "@ton/crypto": "^3.3.0", + "@tonconnect/ui": "^2.0.9", + "rango-types": "^0.1.75" + }, + "publishConfig": { + "access": "public" + } +} \ No newline at end of file diff --git a/wallets/provider-tonconnect/readme.md b/wallets/provider-tonconnect/readme.md new file mode 100644 index 0000000000..5da1c55d43 --- /dev/null +++ b/wallets/provider-tonconnect/readme.md @@ -0,0 +1,3 @@ +# @rango-dev/provider-tonconnect + +TonConnect \ No newline at end of file diff --git a/wallets/provider-tonconnect/src/helpers.ts b/wallets/provider-tonconnect/src/helpers.ts new file mode 100644 index 0000000000..508d680f0c --- /dev/null +++ b/wallets/provider-tonconnect/src/helpers.ts @@ -0,0 +1,47 @@ +import type { TonConnectUI } from '@tonconnect/ui'; + +export async function getTonConnectUIModule() { + const tonConnectUI = await import('@tonconnect/ui'); + return tonConnectUI; +} + +export async function getTonCoreModule() { + const tonCore = await import('@ton/core'); + return tonCore; +} + +export async function waitForConnection( + tonConnectUI: TonConnectUI +): Promise { + return new Promise((resolve, reject) => { + const unsubscribeStatusChange = tonConnectUI.onStatusChange( + (state) => { + const walletConnected = !!state?.account.address; + + if (walletConnected) { + unsubscribeStatusChange(); + resolve(state.account.address); + } + }, + (error) => { + unsubscribeStatusChange(); + reject(error); + } + ); + + const unsubscribeModalStateChange = tonConnectUI.onModalStateChange( + (modalState) => { + if (modalState.closeReason === 'action-cancelled') { + unsubscribeStatusChange(); + unsubscribeModalStateChange(); + reject(new Error('The action was canceled by the user')); + } + } + ); + }); +} + +export async function parseAddress(rawAddress: string): Promise { + const tonCore = await getTonCoreModule(); + return tonCore.Address.parse(rawAddress).toString({ bounceable: false }); +} diff --git a/wallets/provider-tonconnect/src/index.ts b/wallets/provider-tonconnect/src/index.ts new file mode 100644 index 0000000000..11726377a8 --- /dev/null +++ b/wallets/provider-tonconnect/src/index.ts @@ -0,0 +1,97 @@ +import type { Environments } from './types.js'; +import type { + CanEagerConnect, + CanSwitchNetwork, + Connect, + Disconnect, + GetInstance, + WalletInfo, +} from '@rango-dev/wallets-shared'; +import type { TonConnectUI } from '@tonconnect/ui'; +import type { BlockchainMeta, SignerFactory } from 'rango-types'; + +import { Networks, WalletTypes } from '@rango-dev/wallets-shared'; +import { tonBlockchain } from 'rango-types'; + +import { + getTonConnectUIModule, + parseAddress, + waitForConnection, +} from './helpers.js'; +import signer from './signer.js'; + +let envs: Environments = { + manifestUrl: '', +}; + +const WALLET = WalletTypes.TON_CONNECT; + +export const config = { + type: WALLET, + isAsyncInstance: true, + checkInstallation: false, +}; + +export type { Environments }; + +export const init = (environments: Environments) => { + envs = environments; +}; + +let instance: TonConnectUI | null = null; + +export const getInstance: GetInstance = async () => { + if (!instance) { + const { TonConnectUI } = await getTonConnectUIModule(); + instance = new TonConnectUI(envs); + } + return instance; +}; + +export const connect: Connect = async ({ instance }) => { + const tonConnectUI: TonConnectUI = instance; + const connectionRestored = await tonConnectUI.connectionRestored; + + if (connectionRestored && tonConnectUI.account?.address) { + const parsedAddress = await parseAddress(tonConnectUI.account.address); + return { accounts: [parsedAddress], chainId: Networks.TON }; + } + + await tonConnectUI.openModal(); + const result = await waitForConnection(tonConnectUI); + const parsedAddress = await parseAddress(result); + + return { + accounts: [parsedAddress], + chainId: Networks.TON, + }; +}; + +export const canEagerConnect: CanEagerConnect = async ({ instance }) => { + const tonConnectUI = instance as TonConnectUI; + const connectionRestored = await tonConnectUI.connectionRestored; + return connectionRestored; +}; + +export const canSwitchNetworkTo: CanSwitchNetwork = () => false; + +export const getSigners: (provider: TonConnectUI) => Promise = + signer; + +export const getWalletInfo: (allBlockChains: BlockchainMeta[]) => WalletInfo = ( + allBlockChains +) => { + const ton = tonBlockchain(allBlockChains); + return { + name: 'TON Connect', + img: 'https://raw.githubusercontent.com/rango-exchange/assets/7fb19ed5d5019b4d6a41ce91b39cde64f86af4c6/wallets/tonconnect/icon.svg', + installLink: '', + color: '#fff', + supportedChains: ton, + }; +}; + +export const disconnect: Disconnect = async ({ instance }) => { + const tonConnectUI = instance as TonConnectUI; + await tonConnectUI.disconnect(); +}; diff --git a/wallets/provider-tonconnect/src/signer.ts b/wallets/provider-tonconnect/src/signer.ts new file mode 100644 index 0000000000..1bbe14a9d6 --- /dev/null +++ b/wallets/provider-tonconnect/src/signer.ts @@ -0,0 +1,13 @@ +import type { TonConnectUI } from '@tonconnect/ui'; +import type { SignerFactory } from 'rango-types'; + +import { DefaultSignerFactory, TransactionType as TxType } from 'rango-types'; + +export default async function getSigners( + provider: TonConnectUI +): Promise { + const signers = new DefaultSignerFactory(); + const { CustomTonSigner } = await import('./ton-signer.js'); + signers.registerSigner(TxType.TON, new CustomTonSigner(provider)); + return signers; +} diff --git a/wallets/provider-tonconnect/src/ton-signer.ts b/wallets/provider-tonconnect/src/ton-signer.ts new file mode 100644 index 0000000000..7eacba12bb --- /dev/null +++ b/wallets/provider-tonconnect/src/ton-signer.ts @@ -0,0 +1,29 @@ +import type { TonConnectUI } from '@tonconnect/ui'; +import type { GenericSigner, TonTransaction } from 'rango-types'; + +import { Cell } from '@ton/core'; +import { CHAIN } from '@tonconnect/ui'; +import { SignerError } from 'rango-types'; + +export class CustomTonSigner implements GenericSigner { + private provider: TonConnectUI; + + constructor(provider: TonConnectUI) { + this.provider = provider; + } + + async signMessage(): Promise { + throw SignerError.UnimplementedError('signMessage'); + } + + async signAndSendTx(tx: TonTransaction): Promise<{ hash: string }> { + const { blockChain, type, ...txObjectForSign } = tx; + const result = await this.provider.sendTransaction({ + ...txObjectForSign, + network: CHAIN.MAINNET, + }); + + const hash = Cell.fromBase64(result.boc).hash().toString('hex'); + return { hash }; + } +} diff --git a/wallets/provider-tonconnect/src/types.ts b/wallets/provider-tonconnect/src/types.ts new file mode 100644 index 0000000000..8403e975c1 --- /dev/null +++ b/wallets/provider-tonconnect/src/types.ts @@ -0,0 +1,3 @@ +export interface Environments extends Record { + manifestUrl: string; +} diff --git a/wallets/provider-tonconnect/tsconfig.build.json b/wallets/provider-tonconnect/tsconfig.build.json new file mode 100644 index 0000000000..d2ac5e673f --- /dev/null +++ b/wallets/provider-tonconnect/tsconfig.build.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig.libnext.json", + "include": ["src", "types", "../../global-wallets-env.d.ts"], + "compilerOptions": { + "outDir": "dist", + "rootDir": "./src", + "lib": ["dom", "esnext"] + } +} diff --git a/wallets/provider-tonconnect/tsconfig.json b/wallets/provider-tonconnect/tsconfig.json new file mode 100644 index 0000000000..a3a0b0f59d --- /dev/null +++ b/wallets/provider-tonconnect/tsconfig.json @@ -0,0 +1 @@ +{ "extends": "./tsconfig.build.json", "include": ["src", "tests"] } diff --git a/wallets/provider-trezor/CHANGELOG.md b/wallets/provider-trezor/CHANGELOG.md new file mode 100644 index 0000000000..5623ea0e0c --- /dev/null +++ b/wallets/provider-trezor/CHANGELOG.md @@ -0,0 +1,77 @@ +# [0.8.0](https://github.com/rango-exchange/rango-client/compare/provider-trezor@0.7.0...provider-trezor@0.8.0) (2024-12-30) + + + +# [0.7.0](https://github.com/rango-exchange/rango-client/compare/provider-trezor@0.6.0...provider-trezor@0.7.0) (2024-11-27) + + + +# [0.6.0](https://github.com/rango-exchange/rango-client/compare/provider-trezor@0.5.0...provider-trezor@0.6.0) (2024-11-12) + + +### Bug Fixes + +* resolve issues with trezor provider's sign message method ([017570f](https://github.com/rango-exchange/rango-client/commit/017570f6d757acdf03a81ad6999e6c8c1ba03b6b)) + + + +# [0.5.0](https://github.com/rango-exchange/rango-client/compare/provider-trezor@0.4.1...provider-trezor@0.5.0) (2024-10-12) + + +### Bug Fixes + +* bump sdk and fix type issues ([d442208](https://github.com/rango-exchange/rango-client/commit/d4422083bf5dd27d5f509ce1db7f9560d05428c8)) + + +### Performance Improvements + +* enable code splitting in build process ([fe5a41e](https://github.com/rango-exchange/rango-client/commit/fe5a41e0e297298de11cd74ca5825544742aa03a)) +* lazy load signer packages ([7b88f18](https://github.com/rango-exchange/rango-client/commit/7b88f1834f7b29b4b81ab6c81a07bb88e8ccf55c)) + + + +## [0.4.1](https://github.com/rango-exchange/rango-client/compare/provider-trezor@0.4.0...provider-trezor@0.4.1) (2024-09-16) + + +### Bug Fixes + +* enabling trezor by removing bundling for @trezor/connect-web ([eb0be81](https://github.com/rango-exchange/rango-client/commit/eb0be81dd582a21e4c46b32c68bfd3ddd2a3cfa0)) + + + +# [0.4.0](https://github.com/rango-exchange/rango-client/compare/provider-trezor@0.3.0...provider-trezor@0.4.0) (2024-09-10) + + +### Bug Fixes + +* incorrect error message on Trezor wallet transaction rejection ([3998563](https://github.com/rango-exchange/rango-client/commit/3998563fa06c694b34a61730b4f6c13f3323a407)) + + + +# [0.3.0](https://github.com/rango-exchange/rango-client/compare/provider-trezor@0.2.1...provider-trezor@0.3.0) (2024-08-11) + + +### Features + +* add derivation path modal for trezor wallet ([364422f](https://github.com/rango-exchange/rango-client/commit/364422f099b202a27a529591c5e3628bbb35508d)) + + + +## [0.2.1](https://github.com/rango-exchange/rango-client/compare/provider-trezor@0.2.0...provider-trezor@0.2.1) (2024-07-14) + + + +# 0.2.0 (2024-07-09) + + +### Bug Fixes + +* import Trezor module ([cd71eb5](https://github.com/rango-exchange/rango-client/commit/cd71eb5f390f1b07974ea9e2368f35db383a8c82)) + + +### Features + +* add support for Trezor hardware wallet ([6edecbb](https://github.com/rango-exchange/rango-client/commit/6edecbb14fd008fc741c892bfa3e025c10160b9b)) + + + diff --git a/wallets/provider-trezor/notes.md b/wallets/provider-trezor/notes.md new file mode 100644 index 0000000000..f8a5b4a03a --- /dev/null +++ b/wallets/provider-trezor/notes.md @@ -0,0 +1,11 @@ +## @trezor/connect-web is cjs + +Our packages should be ESM-only. One of our dependencies, `@trezor/connect-web` is CJS, We first tried to bundle a transpiled version of the `@trezor/connect-web` package, but it has some problems with `.default`-thing. you can add `--external-all-except @trezor/connect-web` to `build` and try to link to our dApp. + +There are two workaround for solving this: + +1. Consider user to have a bundler/tool to transpile it on host (e.g. Vite). +2. Remove the provider from `provider-all` and add besides `privder-all` separately in our dApp. This way we ensure all the `provider-all` dependencies include only ESM packages and when some is using `embedded` there is no need to transpile CJS to ESM and our `embedded` can be used directly. + +We are going with the first one from the beginning so we will keep it for now. +In future, we need to investigate and somehow figure out this problem and be ESM-only. diff --git a/wallets/provider-trezor/package.json b/wallets/provider-trezor/package.json new file mode 100644 index 0000000000..127c3d4335 --- /dev/null +++ b/wallets/provider-trezor/package.json @@ -0,0 +1,36 @@ +{ + "name": "@rango-dev/provider-trezor", + "version": "0.7.1-next.6", + "license": "MIT", + "type": "module", + "source": "./src/index.ts", + "main": "./dist/index.js", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "default": "./dist/index.js" + } + }, + "typings": "dist/index.d.ts", + "files": [ + "dist", + "src" + ], + "scripts": { + "build": "node ../../scripts/build/command.mjs --path wallets/provider-trezor --splitting", + "ts-check": "tsc --declaration --emitDeclarationOnly -p ./tsconfig.json", + "clean": "rimraf dist", + "format": "prettier --write '{.,src}/**/*.{ts,tsx}'", + "lint": "eslint \"**/*.{ts,tsx}\" --ignore-path ../../.eslintignore" + }, + "dependencies": { + "@rango-dev/signer-evm": "^0.32.0", + "@rango-dev/wallets-shared": "^0.40.1-next.6", + "@trezor/connect-web": "^9.2.4", + "ethers": "^6.13.2", + "rango-types": "^0.1.74" + }, + "publishConfig": { + "access": "public" + } +} \ No newline at end of file diff --git a/wallets/provider-trezor/readme.md b/wallets/provider-trezor/readme.md new file mode 100644 index 0000000000..517465ee5d --- /dev/null +++ b/wallets/provider-trezor/readme.md @@ -0,0 +1 @@ +# @rango-dev/provider-trezor diff --git a/wallets/provider-trezor/src/helpers.ts b/wallets/provider-trezor/src/helpers.ts new file mode 100644 index 0000000000..880dc07918 --- /dev/null +++ b/wallets/provider-trezor/src/helpers.ts @@ -0,0 +1,70 @@ +import type { TrezorConnect } from '@trezor/connect-web'; + +import { ETHEREUM_CHAIN_ID, Networks } from '@rango-dev/wallets-shared'; + +import { getDerivationPath } from './state.js'; + +export const trezorErrorMessages: { [statusCode: string]: string } = { + Failure_ActionCancelled: 'User rejected the transaction.', +}; + +// `@trezor/connect-web` is commonjs, when we are importing it dynamically, it has some differences in different tooling. for example vite (you can check widget-examples), goes throw error. this is a workaround for solving this interop issue. +export async function getTrezorModule() { + const mod = await import('@trezor/connect-web'); + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + if (mod.default.default) { + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + return mod.default.default as unknown as TrezorConnect; + } + + return mod.default; +} + +export function getTrezorInstance() { + /* + * Instances have a required property which is `chainId` and is using in swap execution. + * Here we are setting it as Ethereum always since we are supporting only eth for now. + */ + const instances = new Map(); + + instances.set(Networks.ETHEREUM, { chainId: ETHEREUM_CHAIN_ID }); + + return instances; +} + +export async function getEthereumAccounts(): Promise<{ + accounts: string[]; + chainId: string; +}> { + const TrezorConnect = await getTrezorModule(); + const result = await TrezorConnect.ethereumGetAddress({ + path: getDerivationPath(), + }); + + if (!result.success) { + throw new Error(result.payload.error); + } + + return { + accounts: [result.payload.address], + chainId: ETHEREUM_CHAIN_ID, + }; +} + +/* + * Using BigInt in the valueToHex function ensures that the function + * can handle very large integer values that exceed the range of standard JavaScript number types. + */ +export const valueToHex = (value: string) => { + const ZERO_BIGINT = BigInt(0); + const HEX_BASE = 16; + return BigInt(value) > ZERO_BIGINT + ? `0x${BigInt(value).toString(HEX_BASE)}` + : '0x0'; +}; + +export const getTrezorNormalizedDerivationPath = ( + path: string // TrezorConnect needs master node to be added to derivation path +) => (path && !path.startsWith('m/') ? 'm/' + path : path); diff --git a/wallets/provider-trezor/src/index.ts b/wallets/provider-trezor/src/index.ts new file mode 100644 index 0000000000..f68ea3465c --- /dev/null +++ b/wallets/provider-trezor/src/index.ts @@ -0,0 +1,146 @@ +import type { Environments } from './types.js'; +import type { + Connect, + ProviderConnectResult, + WalletInfo, +} from '@rango-dev/wallets-shared'; + +import { Networks, WalletTypes } from '@rango-dev/wallets-shared'; +import { type BlockchainMeta, type SignerFactory } from 'rango-types'; + +import { + getEthereumAccounts, + getTrezorInstance, + getTrezorModule, + getTrezorNormalizedDerivationPath, +} from './helpers.js'; +import signer from './signer.js'; +import { setDerivationPath } from './state.js'; + +let trezorManifest: Environments['manifest'] = { + appUrl: '', + email: '', +}; +export const config = { + type: WalletTypes.TREZOR, +}; + +export type { Environments }; + +export const init = (environments: Environments) => { + trezorManifest = environments.manifest; +}; + +export const getInstance = getTrezorInstance; + +let isTrezorInitialized = false; +export const connect: Connect = async ({ namespaces }) => { + const results: ProviderConnectResult[] = []; + + const TrezorConnect = await getTrezorModule(); + + const evmNamespace = namespaces?.find( + (namespaceItem) => namespaceItem.namespace === 'EVM' + ); + + if (evmNamespace) { + if (evmNamespace.derivationPath) { + setDerivationPath( + getTrezorNormalizedDerivationPath(evmNamespace.derivationPath) + ); + + if (!isTrezorInitialized) { + await TrezorConnect.init({ + lazyLoad: true, // this param will prevent iframe injection until TrezorConnect.method will be called + manifest: trezorManifest, + }); + + isTrezorInitialized = true; + } + + const accounts = await getEthereumAccounts(); + results.push(accounts); + } else { + throw new Error('Derivation Path can not be empty.'); + } + } else { + throw new Error( + `It appears that you have selected a namespace that is not yet supported by our system. Your namespaces: ${namespaces?.map( + (namespaceItem) => namespaceItem.namespace + )}` + ); + } + + return results; +}; + +export const getSigners: (provider: any) => Promise = signer; + +export const getWalletInfo: (allBlockChains: BlockchainMeta[]) => WalletInfo = ( + allBlockChains +) => { + const supportedChains: BlockchainMeta[] = []; + + const ethereumBlockchain = allBlockChains.find( + (chain) => chain.name === Networks.ETHEREUM + ); + if (ethereumBlockchain) { + supportedChains.push(ethereumBlockchain); + } + + return { + name: 'Trezor', + img: 'https://raw.githubusercontent.com/rango-exchange/assets/main/wallets/trezor/icon.svg', + installLink: { + DEFAULT: 'https://trezor.io/learn/a/download-verify-trezor-suite', + }, + color: 'black', + supportedChains, + showOnMobile: false, + + needsNamespace: { + selection: 'single', + data: [ + { + id: 'ETH', + value: 'EVM', + label: 'Ethereum', + }, + ], + }, + needsDerivationPath: { + data: [ + { + id: 'metamask', + label: `Metamask (m/44'/60'/0'/0/index)`, + namespace: 'EVM', + generateDerivationPath: (index: string) => `44'/60'/0'/0/${index}`, + }, + { + id: 'ledgerLive', + label: `LedgerLive (m/44'/60'/index'/0/0)`, + namespace: 'EVM', + generateDerivationPath: (index: string) => `44'/60'/${index}'/0/0`, + }, + { + id: 'legacy', + label: `Legacy (m/44'/60'/0'/index)`, + namespace: 'EVM', + generateDerivationPath: (index: string) => `44'/60'/0'/${index}`, + }, + { + id: `(m/44'/501'/index')`, + label: `(m/44'/501'/index')`, + namespace: 'Solana', + generateDerivationPath: (index: string) => `44'/501'/${index}'`, + }, + { + id: `(m/44'/501'/0'/index)`, + label: `(m/44'/501'/0'/index)`, + namespace: 'Solana', + generateDerivationPath: (index: string) => `44'/501'/0'/${index}`, + }, + ], + }, + }; +}; diff --git a/wallets/provider-trezor/src/signer.ts b/wallets/provider-trezor/src/signer.ts new file mode 100644 index 0000000000..f043fc33b2 --- /dev/null +++ b/wallets/provider-trezor/src/signer.ts @@ -0,0 +1,10 @@ +import type { SignerFactory } from 'rango-types'; + +import { DefaultSignerFactory, TransactionType as TxType } from 'rango-types'; + +export default async function getSigners(): Promise { + const signers = new DefaultSignerFactory(); + const { EthereumSigner } = await import('./signers/ethereum.js'); + signers.registerSigner(TxType.EVM, new EthereumSigner()); + return signers; +} diff --git a/wallets/provider-trezor/src/signers/ethereum.ts b/wallets/provider-trezor/src/signers/ethereum.ts new file mode 100644 index 0000000000..3295a7dc40 --- /dev/null +++ b/wallets/provider-trezor/src/signers/ethereum.ts @@ -0,0 +1,110 @@ +import type { EvmTransaction } from 'rango-types/mainApi'; + +import { cleanEvmError } from '@rango-dev/signer-evm'; +import { DEFAULT_ETHEREUM_RPC_URL } from '@rango-dev/wallets-shared'; +import { JsonRpcProvider, Transaction } from 'ethers'; +import { type GenericSigner } from 'rango-types'; + +import { + getTrezorModule, + trezorErrorMessages, + valueToHex, +} from '../helpers.js'; +import { getDerivationPath } from '../state.js'; + +export function getTrezorErrorMessage(error: any) { + if (error?.shortMessage) { + /* + * Some error signs have lengthy, challenging-to-read messages. + * shortMessage is used because it is shorter and easier to understand. + */ + return new Error(error.shortMessage, { cause: error }); + } + return cleanEvmError(error); +} + +export class EthereumSigner implements GenericSigner { + async signMessage(msg: string): Promise { + const TrezorConnect = await getTrezorModule(); + + const { success, payload } = await TrezorConnect.ethereumSignMessage({ + message: msg, + path: getDerivationPath(), + }); + if (!success) { + throw new Error(payload.error); + } + return payload.signature; + } + + async signAndSendTx( + tx: EvmTransaction, + fromAddress: string, + chainId: string + ): Promise<{ hash: string }> { + try { + const TrezorConnect = await getTrezorModule(); + const { gasPrice, maxFeePerGas, maxPriorityFeePerGas } = tx; + const isEIP1559 = maxFeePerGas && maxPriorityFeePerGas; + + if (isEIP1559 && !maxFeePerGas) { + throw new Error('Missing maxFeePerGas'); + } + if (isEIP1559 && !maxPriorityFeePerGas) { + throw new Error('Missing maxPriorityFeePerGas'); + } + if (!isEIP1559 && !gasPrice) { + throw new Error('Missing gasPrice'); + } + const provider = new JsonRpcProvider(DEFAULT_ETHEREUM_RPC_URL); // Provider to broadcast transaction + const transactionCount = await provider.getTransactionCount(fromAddress); // Get nonce + const additionalFields = isEIP1559 + ? { + maxFeePerGas: valueToHex(maxFeePerGas || '0'), + maxPriorityFeePerGas: valueToHex(maxPriorityFeePerGas || '0'), + } + : { + gasPrice: valueToHex(gasPrice || '0'), + }; + + const transaction = { + to: tx.to, + data: tx.data || '0x', + value: valueToHex(tx.value?.toString() || '0'), + gasLimit: valueToHex(tx.gasLimit?.toString() || '0'), + chainId: Number.parseInt(chainId), + nonce: valueToHex(transactionCount.toString()), + ...additionalFields, + }; + + const { success, payload } = await TrezorConnect.ethereumSignTransaction({ + path: getDerivationPath(), + transaction, + }); + + if (!success) { + const errorMessage = + trezorErrorMessages[payload?.code || ''] || payload.error; + throw new Error(errorMessage); + } + const { r, s, v } = payload; + + const serializedTx = Transaction.from({ + ...transaction, + nonce: Number.parseInt(transaction.nonce), + /* + * Type 0: This refers to the legacy transaction type that has been used since Ethereum's inception. + * Type 2: This refers to the new transaction type introduced with the EIP-1559 (Ethereum Improvement Proposal 1559) update, + * which was part of the London hard fork. + */ + type: isEIP1559 ? 2 : 0, + signature: { r, s, v: parseInt(v) }, + }).serialized; + const broadcastResult = await provider.broadcastTransaction(serializedTx); + + return { hash: broadcastResult.hash }; + } catch (error) { + throw getTrezorErrorMessage(error); + } + } +} diff --git a/wallets/provider-trezor/src/state.ts b/wallets/provider-trezor/src/state.ts new file mode 100644 index 0000000000..e8cb68fd61 --- /dev/null +++ b/wallets/provider-trezor/src/state.ts @@ -0,0 +1,10 @@ +// We keep derivationPath here because we need to maintain it for signing transactions after it is set in connect method +let derivationPath = ''; + +export function setDerivationPath(path: string) { + derivationPath = path; +} + +export function getDerivationPath() { + return derivationPath; +} diff --git a/wallets/provider-trezor/src/types.ts b/wallets/provider-trezor/src/types.ts new file mode 100644 index 0000000000..b17d6df18b --- /dev/null +++ b/wallets/provider-trezor/src/types.ts @@ -0,0 +1,3 @@ +export interface Environments { + manifest: { appUrl: string; email: string }; +} diff --git a/wallets/provider-trezor/tsconfig.build.json b/wallets/provider-trezor/tsconfig.build.json new file mode 100644 index 0000000000..8c3b6ae906 --- /dev/null +++ b/wallets/provider-trezor/tsconfig.build.json @@ -0,0 +1,12 @@ +{ + // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs + "extends": "../../tsconfig.bundler.json", + "include": ["src", "types", "../../global-wallets-env.d.ts"], + "compilerOptions": { + "outDir": "dist", + "rootDir": "./src", + + // `@trezor/connect-web` can not compile without this option, we should remove this option when they've fixed their issue + "skipLibCheck": true + } +} diff --git a/wallets/provider-trezor/tsconfig.json b/wallets/provider-trezor/tsconfig.json new file mode 100644 index 0000000000..a3a0b0f59d --- /dev/null +++ b/wallets/provider-trezor/tsconfig.json @@ -0,0 +1 @@ +{ "extends": "./tsconfig.build.json", "include": ["src", "tests"] } diff --git a/wallets/provider-tron-link/CHANGELOG.md b/wallets/provider-tron-link/CHANGELOG.md new file mode 100644 index 0000000000..0e923babc9 --- /dev/null +++ b/wallets/provider-tron-link/CHANGELOG.md @@ -0,0 +1,142 @@ +# [0.41.0](https://github.com/rango-exchange/rango-client/compare/provider-tron-link@0.40.0...provider-tron-link@0.41.0) (2024-12-30) + + + +# [0.40.0](https://github.com/rango-exchange/rango-client/compare/provider-tron-link@0.39.0...provider-tron-link@0.40.0) (2024-11-27) + + + +# [0.39.0](https://github.com/rango-exchange/rango-client/compare/provider-tron-link@0.38.0...provider-tron-link@0.39.0) (2024-11-12) + + + +# [0.38.0](https://github.com/rango-exchange/rango-client/compare/provider-tron-link@0.37.0...provider-tron-link@0.38.0) (2024-10-12) + + +### Bug Fixes + +* bump sdk and fix type issues ([d442208](https://github.com/rango-exchange/rango-client/commit/d4422083bf5dd27d5f509ce1db7f9560d05428c8)) + + +### Performance Improvements + +* lazy load signer packages ([7b88f18](https://github.com/rango-exchange/rango-client/commit/7b88f1834f7b29b4b81ab6c81a07bb88e8ccf55c)) + + + +# [0.37.0](https://github.com/rango-exchange/rango-client/compare/provider-tron-link@0.36.0...provider-tron-link@0.37.0) (2024-09-10) + + + +# [0.36.0](https://github.com/rango-exchange/rango-client/compare/provider-tron-link@0.35.1...provider-tron-link@0.36.0) (2024-08-11) + + + +## [0.35.1](https://github.com/rango-exchange/rango-client/compare/provider-tron-link@0.35.0...provider-tron-link@0.35.1) (2024-07-14) + + + +# [0.35.0](https://github.com/rango-exchange/rango-client/compare/provider-tron-link@0.33.0...provider-tron-link@0.35.0) (2024-07-09) + + + +# [0.34.0](https://github.com/rango-exchange/rango-client/compare/provider-tron-link@0.33.0...provider-tron-link@0.34.0) (2024-06-01) + + + +# [0.33.0](https://github.com/rango-exchange/rango-client/compare/provider-tron-link@0.32.0...provider-tron-link@0.33.0) (2024-05-14) + + + +# [0.32.0](https://github.com/rango-exchange/rango-client/compare/provider-tron-link@0.31.0...provider-tron-link@0.32.0) (2024-04-24) + + + +# [0.31.0](https://github.com/rango-exchange/rango-client/compare/provider-tron-link@0.30.0...provider-tron-link@0.31.0) (2024-04-23) + + + +# [0.30.0](https://github.com/rango-exchange/rango-client/compare/provider-tron-link@0.29.0...provider-tron-link@0.30.0) (2024-04-09) + + +### Bug Fixes + +* fix tron-link wallet connecting error ([ad61471](https://github.com/rango-exchange/rango-client/commit/ad614712d4a22a86164d6decf820fef19ff45f3c)) + + + +# [0.29.0](https://github.com/rango-exchange/rango-client/compare/provider-tron-link@0.28.0...provider-tron-link@0.29.0) (2024-03-12) + + + +# [0.28.0](https://github.com/rango-exchange/rango-client/compare/provider-tron-link@0.27.0...provider-tron-link@0.28.0) (2024-02-20) + + + +# [0.27.0](https://github.com/rango-exchange/rango-client/compare/provider-tron-link@0.26.0...provider-tron-link@0.27.0) (2024-02-07) + + + +# [0.26.0](https://github.com/rango-exchange/rango-client/compare/provider-tron-link@0.25.0...provider-tron-link@0.26.0) (2024-01-22) + + + +# [0.25.0](https://github.com/rango-exchange/rango-client/compare/provider-tron-link@0.23.0...provider-tron-link@0.25.0) (2023-12-24) + + +### Bug Fixes + +* fix HMR for widget and playground ([8524820](https://github.com/rango-exchange/rango-client/commit/8524820f10cf0b8921f3db0c4f620ff98daa4103)) + + + +# [0.14.0](https://github.com/rango-exchange/rango-client/compare/provider-tron-link@0.13.0...provider-tron-link@0.14.0) (2023-08-03) + + + +# [0.13.0](https://github.com/rango-exchange/rango-client/compare/provider-tron-link@0.12.0...provider-tron-link@0.13.0) (2023-08-01) + + + +# [0.9.0](https://github.com/rango-exchange/rango-client/compare/provider-tron-link@0.8.0...provider-tron-link@0.9.0) (2023-07-31) + + + +# [0.7.0](https://github.com/rango-exchange/rango-client/compare/provider-tron-link@0.6.0...provider-tron-link@0.7.0) (2023-07-11) + + + +# [0.6.0](https://github.com/rango-exchange/rango-client/compare/provider-tron-link@0.5.0...provider-tron-link@0.6.0) (2023-07-11) + + +### Reverts + +* Revert "support for rango-types cjs format" ([ed4e050](https://github.com/rango-exchange/rango-client/commit/ed4e050bfc0dcde7aeffa6b0d73b02080a5721eb)) + + + +# [0.5.0](https://github.com/rango-exchange/rango-client/compare/provider-tron-link@0.4.0...provider-tron-link@0.5.0) (2023-05-31) + + + +# [0.4.0](https://github.com/rango-exchange/rango-client/compare/provider-tron-link@0.3.0...provider-tron-link@0.4.0) (2023-05-31) + + + +# [0.3.0](https://github.com/rango-exchange/rango-client/compare/provider-tron-link@0.2.0...provider-tron-link@0.3.0) (2023-05-30) + + + +# [0.2.0](https://github.com/rango-exchange/rango-client/compare/provider-tron-link@0.1.15...provider-tron-link@0.2.0) (2023-05-30) + + + +## [0.1.14](https://github.com/rango-exchange/rango-client/compare/provider-tron-link@0.1.13...provider-tron-link@0.1.14) (2023-05-15) + + +### Bug Fixes + +* update rango-types and fix notification bugs ([993f185](https://github.com/rango-exchange/rango-client/commit/993f185e0b8c5e5e15a2c65ba2d85d1f9c8daa90)) + + + diff --git a/wallets/provider-tron-link/package.json b/wallets/provider-tron-link/package.json index b316ae2e2f..7d970ce8fe 100644 --- a/wallets/provider-tron-link/package.json +++ b/wallets/provider-tron-link/package.json @@ -1,49 +1,31 @@ { "name": "@rango-dev/provider-tron-link", - "version": "0.1.12", + "version": "0.40.1-next.6", "license": "MIT", - "module": "dist/provider-tron-link.esm.js", - "main": "dist/index.js", + "type": "module", + "source": "./src/index.ts", + "main": "./dist/index.js", + "exports": { + ".": "./dist/index.js" + }, "typings": "dist/index.d.ts", "files": [ "dist", "src" ], "scripts": { - "dev": "tsdx watch", - "build": "tsdx build --tsconfig ./tsconfig.json", - "test": "tsdx test --passWithNoTests", - "lint": "tsdx lint", - "size": "size-limit", - "analyze": "size-limit --why" - }, - "husky": { - "hooks": { - "pre-commit": "tsdx lint" - } + "build": "node ../../scripts/build/command.mjs --path wallets/provider-tron-link", + "ts-check": "tsc --declaration --emitDeclarationOnly -p ./tsconfig.json", + "clean": "rimraf dist", + "format": "prettier --write '{.,src}/**/*.{ts,tsx}'", + "lint": "eslint \"**/*.{ts,tsx}\" --ignore-path ../../.eslintignore" }, - "prettier": { - "printWidth": 80, - "semi": true, - "singleQuote": true, - "trailingComma": "es5" - }, - "size-limit": [ - { - "path": "dist/provider-tron-link.cjs.production.min.js", - "limit": "10 KB" - }, - { - "path": "dist/provider-tron-link.esm.js", - "limit": "10 KB" - } - ], "dependencies": { - "@rango-dev/signer-tron": "^0.1.11", - "@rango-dev/wallets-shared": "^0.1.11", - "rango-types": "^0.1.28" + "@rango-dev/signer-tron": "^0.31.0", + "@rango-dev/wallets-shared": "^0.40.1-next.6", + "rango-types": "^0.1.74" }, "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/wallets/provider-tron-link/src/index.ts b/wallets/provider-tron-link/src/index.ts index 38b2b378b7..57d4a47dc4 100644 --- a/wallets/provider-tron-link/src/index.ts +++ b/wallets/provider-tron-link/src/index.ts @@ -1,43 +1,45 @@ -import { Subscribe } from '@rango-dev/wallets-shared'; -import { - Network, - WalletType, +import type { CanSwitchNetwork, Connect, + Subscribe, WalletInfo, } from '@rango-dev/wallets-shared'; -import { tronLink as tronLink_instance } from './helpers'; -import signer from './signer'; -import { SignerFactory, BlockchainMeta, tronBlockchain } from 'rango-types'; +import type { BlockchainMeta, SignerFactory } from 'rango-types'; -// https://docs.tronlink.org/dapp/start-developing -// https://developers.tron.network/docs/tronlink-events -const WALLET = WalletType.TRON_LINK; +import { Networks, WalletTypes } from '@rango-dev/wallets-shared'; +import { tronBlockchain } from 'rango-types'; + +import { tronLink as tronLink_instance } from './helpers.js'; +import signer from './signer.js'; + +/* + * https://docs.tronlink.org/dapp/start-developing + * https://developers.tron.network/docs/tronlink-events + */ +const WALLET = WalletTypes.TRON_LINK; export const config = { type: WALLET, - defaultNetwork: Network.TRON, + defaultNetwork: Networks.TRON, }; export const getInstance = tronLink_instance; export const connect: Connect = async ({ instance }) => { let r = undefined; + const SUCCESS_CODE = 200; if (!!instance && !instance.ready) { r = await instance.request({ method: 'tron_requestAccounts' }); if (!r) { throw new Error('Please unlock your TronLink extension first.'); } - if (r.code === 200) { - } else if (!!r?.code && !!r.message) { + if (r?.code !== SUCCESS_CODE && !!r.message) { throw new Error(r.message); } } - const address = instance.tronWeb.address.fromHex( - (await instance.tronWeb.trx.getAccount()).address.toString() - ); + const address = instance.tronWeb.defaultAddress.base58; // TODO check connected network - return { accounts: !!address ? [address] : [], chainId: Network.TRON }; + return { accounts: address ? [address] : [], chainId: Networks.TRON }; }; export const subscribe: Subscribe = ({ updateAccounts, disconnect }) => { @@ -48,7 +50,7 @@ export const subscribe: Subscribe = ({ updateAccounts, disconnect }) => { e.data.message.action == 'accountsChanged' ) { const account = e?.data?.message?.data?.address; - if (!!account) { + if (account) { updateAccounts([account]); } else { disconnect(); @@ -59,7 +61,7 @@ export const subscribe: Subscribe = ({ updateAccounts, disconnect }) => { export const canSwitchNetworkTo: CanSwitchNetwork = () => false; -export const getSigners: (provider: any) => SignerFactory = signer; +export const getSigners: (provider: any) => Promise = signer; export const getWalletInfo: (allBlockChains: BlockchainMeta[]) => WalletInfo = ( allBlockChains @@ -67,7 +69,7 @@ export const getWalletInfo: (allBlockChains: BlockchainMeta[]) => WalletInfo = ( const tron = tronBlockchain(allBlockChains); return { name: 'TronLink', - img: 'https://raw.githubusercontent.com/rango-exchange/rango-types/main/assets/icons/wallets/tronlink.png', + img: 'https://raw.githubusercontent.com/rango-exchange/assets/main/wallets/tronlink/icon.svg', installLink: { CHROME: 'https://chrome.google.com/webstore/detail/tronlink/ibnejdfjmmkpcnlpebklmnkoeoihofec', diff --git a/wallets/provider-tron-link/src/signer.ts b/wallets/provider-tron-link/src/signer.ts index 4fe630c161..02d4a1adbd 100644 --- a/wallets/provider-tron-link/src/signer.ts +++ b/wallets/provider-tron-link/src/signer.ts @@ -1,8 +1,12 @@ +import type { SignerFactory } from 'rango-types'; + import { DefaultTronSigner } from '@rango-dev/signer-tron'; -import { SignerFactory, TransactionType as TxType } from 'rango-types'; +import { DefaultSignerFactory, TransactionType as TxType } from 'rango-types'; -export default function getSigners(provider: any): SignerFactory { - const signers = new SignerFactory(); +export default async function getSigners( + provider: any +): Promise { + const signers = new DefaultSignerFactory(); signers.registerSigner(TxType.TRON, new DefaultTronSigner(provider)); return signers; } diff --git a/wallets/provider-tron-link/tsconfig.build.json b/wallets/provider-tron-link/tsconfig.build.json new file mode 100644 index 0000000000..5297e74971 --- /dev/null +++ b/wallets/provider-tron-link/tsconfig.build.json @@ -0,0 +1,10 @@ +{ + // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs + "extends": "../../tsconfig.libnext.json", + "include": ["src", "types", "../../global-wallets-env.d.ts"], + "compilerOptions": { + "outDir": "dist", + "rootDir": "./src", + "lib": ["dom", "esnext"] + } +} diff --git a/wallets/provider-tron-link/tsconfig.json b/wallets/provider-tron-link/tsconfig.json index 365489616a..a3a0b0f59d 100644 --- a/wallets/provider-tron-link/tsconfig.json +++ b/wallets/provider-tron-link/tsconfig.json @@ -1,35 +1 @@ -{ - // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs - "include": ["src", "types", "../../global-wallets-env.d.ts"], - "compilerOptions": { - "module": "esnext", - "lib": ["dom", "esnext"], - "importHelpers": true, - // output .d.ts declaration files for consumers - "declaration": true, - // output .js.map sourcemap files for consumers - "sourceMap": true, - // match output dir to input dir. e.g. dist/index instead of dist/src/index - "rootDir": "./src", - // stricter type-checking for stronger correctness. Recommended by TS - "strict": true, - // linter checks for common issues - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true, - // noUnused* overlap with @typescript-eslint/no-unused-vars, can disable if duplicative - "noUnusedLocals": true, - "noUnusedParameters": true, - // use Node's module resolution algorithm, instead of the legacy TS one - "moduleResolution": "node", - // transpile JSX to React.createElement - "jsx": "react", - // interop between ESM and CJS modules. Recommended by TS - "esModuleInterop": true, - // significant perf increase by skipping checking .d.ts files, particularly those in node_modules. Recommended by TS - "skipLibCheck": true, - // error out if import and file system have a casing mismatch. Recommended by TS - "forceConsistentCasingInFileNames": true, - // `tsdx build` ignores this option, but it is commonly used when type-checking separately with `tsc` - "noEmit": true, - } -} +{ "extends": "./tsconfig.build.json", "include": ["src", "tests"] } diff --git a/wallets/provider-trustwallet/CHANGELOG.md b/wallets/provider-trustwallet/CHANGELOG.md new file mode 100644 index 0000000000..ec5659d933 --- /dev/null +++ b/wallets/provider-trustwallet/CHANGELOG.md @@ -0,0 +1,146 @@ +# [0.41.0](https://github.com/rango-exchange/rango-client/compare/provider-trustwallet@0.40.0...provider-trustwallet@0.41.0) (2024-12-30) + + + +# [0.40.0](https://github.com/rango-exchange/rango-client/compare/provider-trustwallet@0.39.0...provider-trustwallet@0.40.0) (2024-11-27) + + + +# [0.39.0](https://github.com/rango-exchange/rango-client/compare/provider-trustwallet@0.38.0...provider-trustwallet@0.39.0) (2024-11-12) + + + +# [0.38.0](https://github.com/rango-exchange/rango-client/compare/provider-trustwallet@0.37.0...provider-trustwallet@0.38.0) (2024-10-12) + + +### Bug Fixes + +* bump sdk and fix type issues ([d442208](https://github.com/rango-exchange/rango-client/commit/d4422083bf5dd27d5f509ce1db7f9560d05428c8)) + + +### Performance Improvements + +* lazy load signer packages ([7b88f18](https://github.com/rango-exchange/rango-client/commit/7b88f1834f7b29b4b81ab6c81a07bb88e8ccf55c)) + + + +# [0.37.0](https://github.com/rango-exchange/rango-client/compare/provider-trustwallet@0.36.0...provider-trustwallet@0.37.0) (2024-09-10) + + + +# [0.36.0](https://github.com/rango-exchange/rango-client/compare/provider-trustwallet@0.35.1...provider-trustwallet@0.36.0) (2024-08-11) + + + +## [0.35.1](https://github.com/rango-exchange/rango-client/compare/provider-trustwallet@0.35.0...provider-trustwallet@0.35.1) (2024-07-14) + + + +# [0.35.0](https://github.com/rango-exchange/rango-client/compare/provider-trustwallet@0.33.2...provider-trustwallet@0.35.0) (2024-07-09) + + + +# [0.34.0](https://github.com/rango-exchange/rango-client/compare/provider-trustwallet@0.33.2...provider-trustwallet@0.34.0) (2024-06-01) + + + +## [0.33.2](https://github.com/rango-exchange/rango-client/compare/provider-trustwallet@0.33.1...provider-trustwallet@0.33.2) (2024-05-26) + + + +## [0.33.1](https://github.com/rango-exchange/rango-client/compare/provider-trustwallet@0.33.0...provider-trustwallet@0.33.1) (2024-05-25) + + + +# [0.33.0](https://github.com/rango-exchange/rango-client/compare/provider-trustwallet@0.32.0...provider-trustwallet@0.33.0) (2024-05-14) + + + +# [0.32.0](https://github.com/rango-exchange/rango-client/compare/provider-trustwallet@0.31.0...provider-trustwallet@0.32.0) (2024-04-24) + + + +# [0.31.0](https://github.com/rango-exchange/rango-client/compare/provider-trustwallet@0.30.0...provider-trustwallet@0.31.0) (2024-04-23) + + + +# [0.30.0](https://github.com/rango-exchange/rango-client/compare/provider-trustwallet@0.29.0...provider-trustwallet@0.30.0) (2024-04-09) + + + +# [0.29.0](https://github.com/rango-exchange/rango-client/compare/provider-trustwallet@0.28.0...provider-trustwallet@0.29.0) (2024-03-12) + + + +# [0.28.0](https://github.com/rango-exchange/rango-client/compare/provider-trustwallet@0.27.0...provider-trustwallet@0.28.0) (2024-02-20) + + + +# [0.27.0](https://github.com/rango-exchange/rango-client/compare/provider-trustwallet@0.26.0...provider-trustwallet@0.27.0) (2024-02-07) + + + +# [0.26.0](https://github.com/rango-exchange/rango-client/compare/provider-trustwallet@0.25.0...provider-trustwallet@0.26.0) (2024-01-22) + + + +# [0.25.0](https://github.com/rango-exchange/rango-client/compare/provider-trustwallet@0.23.0...provider-trustwallet@0.25.0) (2023-12-24) + + +### Bug Fixes + +* fix HMR for widget and playground ([8524820](https://github.com/rango-exchange/rango-client/commit/8524820f10cf0b8921f3db0c4f620ff98daa4103)) + + + +# [0.14.0](https://github.com/rango-exchange/rango-client/compare/provider-trustwallet@0.13.0...provider-trustwallet@0.14.0) (2023-08-03) + + + +# [0.13.0](https://github.com/rango-exchange/rango-client/compare/provider-trustwallet@0.12.0...provider-trustwallet@0.13.0) (2023-08-01) + + + +# [0.9.0](https://github.com/rango-exchange/rango-client/compare/provider-trustwallet@0.8.0...provider-trustwallet@0.9.0) (2023-07-31) + + + +# [0.7.0](https://github.com/rango-exchange/rango-client/compare/provider-trustwallet@0.6.0...provider-trustwallet@0.7.0) (2023-07-11) + + + +# [0.6.0](https://github.com/rango-exchange/rango-client/compare/provider-trustwallet@0.5.0...provider-trustwallet@0.6.0) (2023-07-11) + + +### Reverts + +* Revert "support for rango-types cjs format" ([ed4e050](https://github.com/rango-exchange/rango-client/commit/ed4e050bfc0dcde7aeffa6b0d73b02080a5721eb)) +* Revert "support for rango-types cjs format" ([4f5f55f](https://github.com/rango-exchange/rango-client/commit/4f5f55f96e8daa329588b932b19c291c30f339c4)) + + + +# [0.5.0](https://github.com/rango-exchange/rango-client/compare/provider-trustwallet@0.4.0...provider-trustwallet@0.5.0) (2023-05-31) + + + +# [0.4.0](https://github.com/rango-exchange/rango-client/compare/provider-trustwallet@0.3.0...provider-trustwallet@0.4.0) (2023-05-31) + + + +# [0.3.0](https://github.com/rango-exchange/rango-client/compare/provider-trustwallet@0.2.0...provider-trustwallet@0.3.0) (2023-05-30) + + + +# [0.2.0](https://github.com/rango-exchange/rango-client/compare/provider-trustwallet@0.1.15...provider-trustwallet@0.2.0) (2023-05-30) + + + +## [0.1.14](https://github.com/rango-exchange/rango-client/compare/provider-trustwallet@0.1.13...provider-trustwallet@0.1.14) (2023-05-15) + + +### Bug Fixes + +* update rango-types and fix notification bugs ([993f185](https://github.com/rango-exchange/rango-client/commit/993f185e0b8c5e5e15a2c65ba2d85d1f9c8daa90)) + + + diff --git a/wallets/provider-trustwallet/package.json b/wallets/provider-trustwallet/package.json index ad7e882820..4432eb8b6e 100644 --- a/wallets/provider-trustwallet/package.json +++ b/wallets/provider-trustwallet/package.json @@ -1,49 +1,31 @@ { "name": "@rango-dev/provider-trustwallet", - "version": "0.1.12", + "version": "0.40.1-next.6", "license": "MIT", - "module": "dist/provider-trustwallet.esm.js", - "main": "dist/index.js", + "type": "module", + "source": "./src/index.ts", + "main": "./dist/index.js", + "exports": { + ".": "./dist/index.js" + }, "typings": "dist/index.d.ts", "files": [ "dist", "src" ], "scripts": { - "start": "tsdx watch", - "build": "tsdx build --tsconfig ./tsconfig.json", - "test": "tsdx test --passWithNoTests", - "lint": "tsdx lint", - "size": "size-limit", - "analyze": "size-limit --why" - }, - "husky": { - "hooks": { - "pre-commit": "tsdx lint" - } + "build": "node ../../scripts/build/command.mjs --path wallets/provider-trustwallet", + "ts-check": "tsc --declaration --emitDeclarationOnly -p ./tsconfig.json", + "clean": "rimraf dist", + "format": "prettier --write '{.,src}/**/*.{ts,tsx}'", + "lint": "eslint \"**/*.{ts,tsx}\" --ignore-path ../../.eslintignore" }, - "prettier": { - "printWidth": 80, - "semi": true, - "singleQuote": true, - "trailingComma": "es5" - }, - "size-limit": [ - { - "path": "dist/provider-trustwallet.cjs.production.min.js", - "limit": "10 KB" - }, - { - "path": "dist/provider-trustwallet.esm.js", - "limit": "10 KB" - } - ], "dependencies": { - "@rango-dev/signer-evm": "^0.1.11", - "@rango-dev/wallets-shared": "^0.1.11", - "rango-types": "^0.1.28" + "@rango-dev/signer-evm": "^0.32.0", + "@rango-dev/wallets-shared": "^0.40.1-next.6", + "rango-types": "^0.1.74" }, "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/wallets/provider-trustwallet/src/index.ts b/wallets/provider-trustwallet/src/index.ts index 75c3bb0271..34292b00fb 100644 --- a/wallets/provider-trustwallet/src/index.ts +++ b/wallets/provider-trustwallet/src/index.ts @@ -1,20 +1,27 @@ -import { - WalletType, +import type { + CanEagerConnect, CanSwitchNetwork, Connect, Subscribe, SwitchNetwork, + WalletInfo, +} from '@rango-dev/wallets-shared'; +import type { BlockchainMeta, SignerFactory } from 'rango-types'; + +import { + canEagerlyConnectToEvm, canSwitchNetworkToEvm, getEvmAccounts, subscribeToEvm, switchNetworkForEvm, - WalletInfo, + WalletTypes, } from '@rango-dev/wallets-shared'; -import { trustWallet as trustwallet_instance } from './helpers'; -import signer from './signer'; -import { SignerFactory, evmBlockchains, BlockchainMeta } from 'rango-types'; +import { evmBlockchains } from 'rango-types'; -const WALLET = WalletType.TRUST_WALLET; +import { trustWallet as trustwallet_instance } from './helpers.js'; +import signer from './signer.js'; + +const WALLET = WalletTypes.TRUST_WALLET; export const config = { type: WALLET, @@ -37,7 +44,9 @@ export const switchNetwork: SwitchNetwork = switchNetworkForEvm; export const canSwitchNetworkTo: CanSwitchNetwork = canSwitchNetworkToEvm; -export const getSigners: (provider: any) => SignerFactory = signer; +export const getSigners: (provider: any) => Promise = signer; + +export const canEagerConnect: CanEagerConnect = canEagerlyConnectToEvm; export const getWalletInfo: (allBlockChains: BlockchainMeta[]) => WalletInfo = ( allBlockChains @@ -45,12 +54,12 @@ export const getWalletInfo: (allBlockChains: BlockchainMeta[]) => WalletInfo = ( const evms = evmBlockchains(allBlockChains); return { name: 'Trust Wallet', - img: 'https://raw.githubusercontent.com/rango-exchange/rango-types/main/assets/icons/wallets/trust.png', + img: 'https://raw.githubusercontent.com/rango-exchange/assets/main/wallets/trustwallet/icon.svg', installLink: { CHROME: - 'https://chrome.google.com/webstore/detail/trust-wallet/egjidjbpglichdcondbcbdnbeeppgdph/', + 'https://chrome.google.com/webstore/detail/trust-wallet/egjidjbpglichdcondbcbdnbeeppgdph', BRAVE: - 'https://chrome.google.com/webstore/detail/trust-wallet/egjidjbpglichdcondbcbdnbeeppgdph/', + 'https://chrome.google.com/webstore/detail/trust-wallet/egjidjbpglichdcondbcbdnbeeppgdph', DEFAULT: 'https://trustwallet.com/browser-extension', }, color: '#ffffff', diff --git a/wallets/provider-trustwallet/src/signer.ts b/wallets/provider-trustwallet/src/signer.ts index 7ae6c242f8..ef3f4e5d09 100644 --- a/wallets/provider-trustwallet/src/signer.ts +++ b/wallets/provider-trustwallet/src/signer.ts @@ -1,10 +1,14 @@ -import { DefaultEvmSigner } from '@rango-dev/signer-evm'; -import { Network, getNetworkInstance } from '@rango-dev/wallets-shared'; -import { SignerFactory, TransactionType as TxType } from 'rango-types'; +import type { SignerFactory } from 'rango-types'; -export default function getSigners(provider: any): SignerFactory { - const ethProvider = getNetworkInstance(provider, Network.ETHEREUM); - const signers = new SignerFactory(); +import { getNetworkInstance, Networks } from '@rango-dev/wallets-shared'; +import { DefaultSignerFactory, TransactionType as TxType } from 'rango-types'; + +export default async function getSigners( + provider: any +): Promise { + const ethProvider = getNetworkInstance(provider, Networks.ETHEREUM); + const signers = new DefaultSignerFactory(); + const { DefaultEvmSigner } = await import('@rango-dev/signer-evm'); signers.registerSigner(TxType.EVM, new DefaultEvmSigner(ethProvider)); return signers; } diff --git a/wallets/provider-trustwallet/tsconfig.build.json b/wallets/provider-trustwallet/tsconfig.build.json new file mode 100644 index 0000000000..5297e74971 --- /dev/null +++ b/wallets/provider-trustwallet/tsconfig.build.json @@ -0,0 +1,10 @@ +{ + // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs + "extends": "../../tsconfig.libnext.json", + "include": ["src", "types", "../../global-wallets-env.d.ts"], + "compilerOptions": { + "outDir": "dist", + "rootDir": "./src", + "lib": ["dom", "esnext"] + } +} diff --git a/wallets/provider-trustwallet/tsconfig.json b/wallets/provider-trustwallet/tsconfig.json index 365489616a..a3a0b0f59d 100644 --- a/wallets/provider-trustwallet/tsconfig.json +++ b/wallets/provider-trustwallet/tsconfig.json @@ -1,35 +1 @@ -{ - // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs - "include": ["src", "types", "../../global-wallets-env.d.ts"], - "compilerOptions": { - "module": "esnext", - "lib": ["dom", "esnext"], - "importHelpers": true, - // output .d.ts declaration files for consumers - "declaration": true, - // output .js.map sourcemap files for consumers - "sourceMap": true, - // match output dir to input dir. e.g. dist/index instead of dist/src/index - "rootDir": "./src", - // stricter type-checking for stronger correctness. Recommended by TS - "strict": true, - // linter checks for common issues - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true, - // noUnused* overlap with @typescript-eslint/no-unused-vars, can disable if duplicative - "noUnusedLocals": true, - "noUnusedParameters": true, - // use Node's module resolution algorithm, instead of the legacy TS one - "moduleResolution": "node", - // transpile JSX to React.createElement - "jsx": "react", - // interop between ESM and CJS modules. Recommended by TS - "esModuleInterop": true, - // significant perf increase by skipping checking .d.ts files, particularly those in node_modules. Recommended by TS - "skipLibCheck": true, - // error out if import and file system have a casing mismatch. Recommended by TS - "forceConsistentCasingInFileNames": true, - // `tsdx build` ignores this option, but it is commonly used when type-checking separately with `tsc` - "noEmit": true, - } -} +{ "extends": "./tsconfig.build.json", "include": ["src", "tests"] } diff --git a/wallets/provider-walletconnect-2/CHANGELOG.md b/wallets/provider-walletconnect-2/CHANGELOG.md new file mode 100644 index 0000000000..36c7d097f6 --- /dev/null +++ b/wallets/provider-walletconnect-2/CHANGELOG.md @@ -0,0 +1,159 @@ +# [0.34.0](https://github.com/rango-exchange/rango-client/compare/provider-walletconnect-2@0.33.0...provider-walletconnect-2@0.34.0) (2024-12-30) + + + +# [0.33.0](https://github.com/rango-exchange/rango-client/compare/provider-walletconnect-2@0.32.0...provider-walletconnect-2@0.33.0) (2024-11-27) + + +### Features + +* add ton connect provider ([2a2dbb7](https://github.com/rango-exchange/rango-client/commit/2a2dbb79022263f19446ced49d298e04d63f927f)) + + + +# [0.32.0](https://github.com/rango-exchange/rango-client/compare/provider-walletconnect-2@0.31.3...provider-walletconnect-2@0.32.0) (2024-11-12) + + + +## [0.31.3](https://github.com/rango-exchange/rango-client/compare/provider-walletconnect-2@0.31.2...provider-walletconnect-2@0.31.3) (2024-11-06) + + + +## [0.31.2](https://github.com/rango-exchange/rango-client/compare/provider-walletconnect-2@0.31.1...provider-walletconnect-2@0.31.2) (2024-11-06) + + + +## [0.31.1](https://github.com/rango-exchange/rango-client/compare/provider-walletconnect-2@0.31.0...provider-walletconnect-2@0.31.1) (2024-11-06) + + + +# [0.31.0](https://github.com/rango-exchange/rango-client/compare/provider-walletconnect-2@0.30.0...provider-walletconnect-2@0.31.0) (2024-10-12) + + +### Bug Fixes + +* bump sdk and fix type issues ([d442208](https://github.com/rango-exchange/rango-client/commit/d4422083bf5dd27d5f509ce1db7f9560d05428c8)) + + +### Performance Improvements + +* enable code splitting in build process ([fe5a41e](https://github.com/rango-exchange/rango-client/commit/fe5a41e0e297298de11cd74ca5825544742aa03a)) +* lazy load signer packages ([7b88f18](https://github.com/rango-exchange/rango-client/commit/7b88f1834f7b29b4b81ab6c81a07bb88e8ccf55c)) + + + +# [0.30.0](https://github.com/rango-exchange/rango-client/compare/provider-walletconnect-2@0.29.0...provider-walletconnect-2@0.30.0) (2024-09-10) + + + +# [0.29.0](https://github.com/rango-exchange/rango-client/compare/provider-walletconnect-2@0.28.1...provider-walletconnect-2@0.29.0) (2024-08-11) + + + +## [0.28.1](https://github.com/rango-exchange/rango-client/compare/provider-walletconnect-2@0.28.0...provider-walletconnect-2@0.28.1) (2024-07-14) + + + +# [0.28.0](https://github.com/rango-exchange/rango-client/compare/provider-walletconnect-2@0.26.2...provider-walletconnect-2@0.28.0) (2024-07-09) + + +### Features + +* add an option to wallet connect provider to open a desktop wallet directly ([bee0a1f](https://github.com/rango-exchange/rango-client/commit/bee0a1f57ef5470564f6cdc379d00981e7d34b0a)) + + + +# [0.27.0](https://github.com/rango-exchange/rango-client/compare/provider-walletconnect-2@0.26.2...provider-walletconnect-2@0.27.0) (2024-06-01) + + +### Features + +* add an option to wallet connect provider to open a desktop wallet directly ([bee0a1f](https://github.com/rango-exchange/rango-client/commit/bee0a1f57ef5470564f6cdc379d00981e7d34b0a)) + + + +## [0.26.2](https://github.com/rango-exchange/rango-client/compare/provider-walletconnect-2@0.26.1...provider-walletconnect-2@0.26.2) (2024-05-26) + + + +## [0.26.1](https://github.com/rango-exchange/rango-client/compare/provider-walletconnect-2@0.26.0...provider-walletconnect-2@0.26.1) (2024-05-25) + + + +# [0.26.0](https://github.com/rango-exchange/rango-client/compare/provider-walletconnect-2@0.25.0...provider-walletconnect-2@0.26.0) (2024-05-14) + + +### Features + +* detect proper error related to wallet connect params ([a0d8d95](https://github.com/rango-exchange/rango-client/commit/a0d8d95ed977fffbd0244f498c81f7ce3550ee71)) + + + +# [0.25.0](https://github.com/rango-exchange/rango-client/compare/provider-walletconnect-2@0.24.0...provider-walletconnect-2@0.25.0) (2024-04-24) + + + +# [0.24.0](https://github.com/rango-exchange/rango-client/compare/provider-walletconnect-2@0.23.0...provider-walletconnect-2@0.24.0) (2024-04-23) + + + +# [0.23.0](https://github.com/rango-exchange/rango-client/compare/provider-walletconnect-2@0.22.0...provider-walletconnect-2@0.23.0) (2024-04-09) + + + +# [0.22.0](https://github.com/rango-exchange/rango-client/compare/provider-walletconnect-2@0.21.0...provider-walletconnect-2@0.22.0) (2024-03-12) + + +### Bug Fixes + +* fix wallet connect namespace and switch network ([c8f31b3](https://github.com/rango-exchange/rango-client/commit/c8f31b3ddf4ceeaf745bc089f530b6a4b1eb9637)) + + + +# [0.21.0](https://github.com/rango-exchange/rango-client/compare/provider-walletconnect-2@0.20.0...provider-walletconnect-2@0.21.0) (2024-02-20) + + + +# [0.20.0](https://github.com/rango-exchange/rango-client/compare/provider-walletconnect-2@0.19.0...provider-walletconnect-2@0.20.0) (2024-02-07) + + + +# [0.19.0](https://github.com/rango-exchange/rango-client/compare/provider-walletconnect-2@0.18.0...provider-walletconnect-2@0.19.0) (2024-01-22) + + + +# [0.18.0](https://github.com/rango-exchange/rango-client/compare/provider-walletconnect-2@0.16.0...provider-walletconnect-2@0.18.0) (2023-12-24) + + +### Bug Fixes + +* clean evm transaction in wallet-connect signer ([f10175c](https://github.com/rango-exchange/rango-client/commit/f10175cdf03dfd70cd05570aa09b7d1f5634d109)) +* fix HMR for widget and playground ([8524820](https://github.com/rango-exchange/rango-client/commit/8524820f10cf0b8921f3db0c4f620ff98daa4103)) +* handle switch network flow for wallet-connect ([8c4a17b](https://github.com/rango-exchange/rango-client/commit/8c4a17b47b2919820a4e0726f6d1c48b8994abe3)) + + + +# [0.7.0](https://github.com/rango-exchange/rango-client/compare/provider-walletconnect-2@0.6.0...provider-walletconnect-2@0.7.0) (2023-08-03) + + + +# [0.6.0](https://github.com/rango-exchange/rango-client/compare/provider-walletconnect-2@0.5.0...provider-walletconnect-2@0.6.0) (2023-08-01) + + + +# 0.2.0 (2023-07-31) + + +### Bug Fixes + +* if there is no cosmos chain passed to wc2, it will be removed from optional namespaces ([548c9ee](https://github.com/rango-exchange/rango-client/commit/548c9ee9f072b259fdd56b52f794c3d8d267baf9)) + + +### Features + +* add project id as a external value ([0c80404](https://github.com/rango-exchange/rango-client/commit/0c80404a8cacb6c5b0338dea1e416b0b11db254b)) +* Get Wallet Connect project id from config ([9fb30b4](https://github.com/rango-exchange/rango-client/commit/9fb30b4b1a83e2005bbf42553298f24b1e278e1c)) +* Support for WalletConnect 2 ([faedef0](https://github.com/rango-exchange/rango-client/commit/faedef0b5e6fc3c5ef881cbbe4ec05334cc1c910)) + + + diff --git a/wallets/provider-walletconnect-2/notes.md b/wallets/provider-walletconnect-2/notes.md new file mode 100644 index 0000000000..1cf47822d8 --- /dev/null +++ b/wallets/provider-walletconnect-2/notes.md @@ -0,0 +1,15 @@ +# Notes + +## Workaround for `client.d.ts` bug + +`@walletconnect/modal@2.6.2` has an type issue which breaks our build. see `/patches` for more detail. + +Until they fixed them, we are bundling `@walletconnect/modal` into our `dist`. and also `wc-types` is a copy-paste of the original type but the bug has been fixed there. Since `WalletConnectModal` exists in our type outputs, it's been solved temporarily in this way. + +For sum up, +`@walletconnect/modal` will be bundle alongside our provider, so i moved `@walletconnect/modal` from `dependencies` to `devDependencies` to not be installed on host machine. And for our declaration files i've included the fix in `wc-types.d.ts`. so the host machine won't need to install `@walletconnect/modal` by itself. +At the same time we need `patch-package` here, to be able to develop the provider. so it will be need for development, + +After `@walletconnect/modal` fixed the problem, we can revert these changes. + + diff --git a/wallets/provider-walletconnect-2/package.json b/wallets/provider-walletconnect-2/package.json new file mode 100644 index 0000000000..4ae45b02c9 --- /dev/null +++ b/wallets/provider-walletconnect-2/package.json @@ -0,0 +1,52 @@ +{ + "name": "@rango-dev/provider-walletconnect-2", + "version": "0.33.1-next.6", + "license": "MIT", + "type": "module", + "source": "./src/index.ts", + "main": "./dist/index.js", + "exports": { + ".": "./dist/index.js" + }, + "typings": "dist/index.d.ts", + "files": [ + "dist", + "src" + ], + "scripts": { + "build": "node ../../scripts/build/command.mjs --path wallets/provider-walletconnect-2 --splitting --external-all-except @walletconnect/modal", + "ts-check": "tsc --declaration --emitDeclarationOnly -p ./tsconfig.json", + "clean": "rimraf dist", + "format": "prettier --write '{.,src}/**/*.{ts,tsx}'", + "lint": "eslint \"**/*.{ts,tsx}\" --ignore-path ../../.eslintignore" + }, + "dependencies": { + "@cosmjs/launchpad": "^0.27.1", + "@keplr-wallet/cosmos": "^0.9.12", + "@keplr-wallet/simple-fetch": "^0.12.14", + "@rango-dev/logging-core": "^0.6.0", + "@rango-dev/signer-cosmos": "^0.30.1", + "@rango-dev/signer-evm": "^0.32.0", + "@rango-dev/signer-solana": "^0.35.1-next.0", + "@rango-dev/wallets-shared": "^0.40.1-next.6", + "@solana/web3.js": "^1.91.4", + "@walletconnect/encoding": "^1.0.2", + "@walletconnect/sign-client": "^2.11.2", + "@walletconnect/utils": "^2.11.2", + "bs58": "^5.0.0", + "caip": "^1.1.1", + "cosmos-wallet": "^1.2.0", + "rango-types": "^0.1.74" + }, + "devDependencies": { + "@walletconnect/modal": "^2.6.2", + "@walletconnect/types": "^2.11.2" + }, + "resolutions": { + "protobufjs": "^6.11.4", + "@keplr-wallet/cosmos/@keplr-wallet/types/secretjs/protobufjs": "^6.14.4" + }, + "publishConfig": { + "access": "public" + } +} \ No newline at end of file diff --git a/wallets/provider-walletconnect-2/readme.md b/wallets/provider-walletconnect-2/readme.md new file mode 100644 index 0000000000..704ecb0e3d --- /dev/null +++ b/wallets/provider-walletconnect-2/readme.md @@ -0,0 +1,8 @@ +# @rango-dev/provider-walletconnect2 + + +## Known issues + +- Using Private key to import wallets other than `Ethereum` will be problematic. Because it imports only a single blockchain and we are by default asking for `Ethereum`. +- Signing a transaction on Metamask goes through an internal error. +- We couldn't update exist session during a bug in `@walletconnect/utils`, so we are creating new session for accessing to new chains. diff --git a/wallets/provider-walletconnect-2/src/constants.ts b/wallets/provider-walletconnect-2/src/constants.ts new file mode 100644 index 0000000000..c4b18b3bae --- /dev/null +++ b/wallets/provider-walletconnect-2/src/constants.ts @@ -0,0 +1,91 @@ +import { Networks } from '@rango-dev/wallets-shared'; + +export const DEFAULT_NETWORK = Networks.ETHEREUM; +export const PING_TIMEOUT = 10_000; + +export enum NAMESPACES { + ETHEREUM = 'eip155', + SOLANA = 'solana', + COSMOS = 'cosmos', + POLKADOT = 'polkadot', + CARDANO = 'cip34', + ERLOND = 'elrond', + MULTIVERSX = 'multiversx', +} + +export const CHAIN_ID_STORAGE = 'wc@2:client//namespaces'; + +// Refrence: https://docs.walletconnect.com/2.0/advanced/rpc-reference/solana-rpc +export enum SolanaRPCMethods { + GET_ACCOUNTS = 'solana_getAccounts', + REQUEST_ACCOUNTS = 'solana_requestAccounts', + SIGN_TRANSACTION = 'solana_signTransaction', + SIGN_MESSAGE = 'solana_signMessage', +} + +// Refrence: https://docs.walletconnect.com/2.0/advanced/rpc-reference/cosmos-rpc +export enum CosmosRPCMethods { + GET_ACCOUNTS = 'cosmos_getAccounts', + SIGN_DIRECT = 'cosmos_signDirect', + SIGN_AMINO = 'cosmos_signAmino', +} + +// Refrence: https://docs.walletconnect.com/2.0/advanced/rpc-reference/ethereum-rpc +export enum EthereumRPCMethods { + PERSONAL_SIGN = 'personal_sign', + SIGN = 'eth_sign', + SIGN_TYPED_DATA = 'eth_signTypedData', + SIGN_TRANSACTION = 'eth_signTransaction', + SEND_TRANSACTION = 'eth_sendTransaction', + SEND_RAW_TRANSACTION = 'eth_sendRawTransaction', + SWITCH_CHAIN = 'wallet_switchEthereumChain', + ADD_CHAIN = 'wallet_addEthereumChain', + GET_CHAIN = 'eth_chainId', +} + +export enum StarknetRPCMethods { + REQUEST_ADD_INVOKE_TRANSACTION = 'starknet_requestAddInvokeTransaction', + SIGN_TYPED_DATA = 'starknet_signTypedData', +} + +export enum EthereumEvents { + CHAIN_CHANGED = 'chainChanged', + ACCOUNTS_CHANGED = 'accountsChanged', +} + +export const DEFAULT_ETHEREUM_EVENTS: EthereumEvents[] = [ + EthereumEvents.CHAIN_CHANGED, + EthereumEvents.ACCOUNTS_CHANGED, +]; + +export const DEFAULT_ETHEREUM_METHODS = [ + EthereumRPCMethods.PERSONAL_SIGN, + EthereumRPCMethods.SEND_TRANSACTION, + EthereumRPCMethods.SIGN_TRANSACTION, + EthereumRPCMethods.SWITCH_CHAIN, + EthereumRPCMethods.ADD_CHAIN, + EthereumRPCMethods.GET_CHAIN, +]; + +export const DEFAULT_SOLANA_METHODS = [ + SolanaRPCMethods.SIGN_TRANSACTION, + SolanaRPCMethods.SIGN_MESSAGE, +]; + +export const DEFAULT_COSMOS_METHODS = [ + CosmosRPCMethods.GET_ACCOUNTS, + CosmosRPCMethods.SIGN_AMINO, + CosmosRPCMethods.SIGN_DIRECT, +]; + +// refrence: https://github.com/ChainAgnostic/namespaces/blob/main/solana/caip2.md +export const DEFAULT_SOLANA_CHAIN_ID = '4sGjMW1sUnHzSxGspuhpqLDx6wiyjNtZ'; + +export const DEFAULT_APP_METADATA = { + name: 'Rango Exchange', + description: 'The Ultimate Cross-Chain Solution', + url: 'https://app.rango.exchange/', + icons: ['https://app.rango.exchange/logo-rounded.png'], +}; + +export const RELAY_URL = 'wss://relay.walletconnect.com'; diff --git a/wallets/provider-walletconnect-2/src/helpers.ts b/wallets/provider-walletconnect-2/src/helpers.ts new file mode 100644 index 0000000000..281f05a1fc --- /dev/null +++ b/wallets/provider-walletconnect-2/src/helpers.ts @@ -0,0 +1,242 @@ +import type { WalletConnectModal as WalletConnectModalType } from './wc-types.js'; +import type { WalletState } from '@rango-dev/wallets-shared'; +import type { ProposalTypes } from '@walletconnect/types'; +import type { BlockchainMeta } from 'rango-types'; + +import { + convertEvmBlockchainMetaToEvmChainInfo, + isEvmAddress, + Networks, +} from '@rango-dev/wallets-shared'; +import { WalletConnectModal } from '@walletconnect/modal'; +import { AccountId, ChainId } from 'caip'; +import { evmBlockchains, isEvmBlockchain } from 'rango-types'; + +import { + DEFAULT_ETHEREUM_EVENTS, + DEFAULT_ETHEREUM_METHODS, + DEFAULT_SOLANA_CHAIN_ID, + EthereumRPCMethods, + NAMESPACES, +} from './constants.js'; +import { getLastSession } from './session.js'; + +let web3Modal: WalletConnectModalType; +export function createModalInstance(projectId: string) { + if (!web3Modal) { + web3Modal = new WalletConnectModal({ + projectId, + themeMode: 'light', + themeVariables: { + '--wcm-z-index': '999999999', + }, + }) as unknown as WalletConnectModalType; + } +} + +export function getModal(): WalletConnectModalType { + return web3Modal; +} + +type FinalNamespaces = { + [key in NAMESPACES]?: ProposalTypes.BaseRequiredNamespace; +}; + +/* + * Some wallets like 1inch (android) has problem when we pass cosmos chains in optional namespace + * Also some wallets like keplr mobile doesn't work when we don't pass cosmos chains in required namespace + * It seems to be a bug in their current implementation. + */ +export function generateOptionalNamespace( + meta: BlockchainMeta[] +): FinalNamespaces | undefined { + const evm = evmBlockchains(meta); + const evmChains = evm.map((chain) => { + return new ChainId({ + namespace: NAMESPACES.ETHEREUM, + reference: String(parseInt(chain.chainId)), + }).toString(); + }); + + const namespaces: FinalNamespaces = { + [NAMESPACES.ETHEREUM]: { + methods: DEFAULT_ETHEREUM_METHODS, + events: DEFAULT_ETHEREUM_EVENTS, + chains: evmChains, + }, + }; + return namespaces; +} + +export function solanaChainIdToNetworkName(chainId: string): string { + return chainId === DEFAULT_SOLANA_CHAIN_ID ? Networks.SOLANA : chainId; +} + +/** + * + * In `rango-preset` we are working with `window.ethereum.request()`, + * this is an interceptor for some RPC methods (e.g. eth_chainId). + * + */ +export async function simulateRequest( + params: any, + provider: any, + meta: BlockchainMeta[], + getState: () => WalletState +) { + if (params.method === 'eth_chainId') { + const currentSession = getLastSession(provider); + const standaloneChains = Object.values(currentSession.namespaces) + .map((namespace) => namespace.chains) + .flat() as string[]; + + const network = getState().network; + + if (standaloneChains.length > 0) { + const chainId = network + ? getChainIdByNetworkName(network, meta) + : undefined; + + if (chainId) { + return chainId; + } + + const firstIndex = 0; + const firstChain = standaloneChains[firstIndex]; + const firstChainId = new ChainId(firstChain); + return firstChainId.reference; + } + + throw new Error(`Couldn't find any chain on namespace`); + } + throw new Error('Dissallowed method:', params); +} + +export function getChainIdByNetworkName( + network: string, + meta: BlockchainMeta[] +): string | undefined { + const targetBlockchain = meta.find( + (blockchain) => blockchain.name === network + ); + const chainIdInHex = targetBlockchain?.chainId; + if (!chainIdInHex) { + return undefined; + } + + const chainId = String(parseInt(chainIdInHex)); + + return chainId; +} + +export async function switchOrAddEvmChain( + meta: BlockchainMeta[], + requestedNetwork: string, + currentNetwork: string, + instance: any +) { + const evmBlockchains = meta.filter(isEvmBlockchain); + const evmNetworksChainInfo = + convertEvmBlockchainMetaToEvmChainInfo(evmBlockchains); + const targetChain = evmNetworksChainInfo[requestedNetwork]; + const targetBlockchain = meta.find( + (blockchain: BlockchainMeta) => blockchain.name === requestedNetwork + ); + const chainIdInHex = targetBlockchain?.chainId; + + const currentChainId = getChainIdByNetworkName(currentNetwork, meta); + const currentChainEip = ChainId.format({ + namespace: NAMESPACES.ETHEREUM, + reference: String(currentChainId), + }); + + const session = instance.session; + + try { + await instance.client.request({ + topic: session.topic, + request: { + method: EthereumRPCMethods.SWITCH_CHAIN, + params: [ + { + chainId: chainIdInHex, + }, + ], + }, + // It's required to pass current chain, otherwise it won't work + chainId: currentChainEip, + }); + } catch (err: any) { + const addChainError = 4902; + if ( + err?.code === addChainError || + err?.message?.includes(String(addChainError)) + ) { + await instance.client.request({ + topic: session.topic, + request: { + method: EthereumRPCMethods.ADD_CHAIN, + params: [targetChain], + }, + // It's required to pass current chain, otherwise it won't work + chainId: currentChainEip, + }); + } else { + throw err; + } + } +} + +export function getCurrentEvmAccountAddress(instance: any) { + return instance.session.namespaces.eip155.accounts + ?.map((account: string) => { + return new AccountId(account).address; + }) + ?.filter((address: string) => isEvmAddress(address))?.[0]; +} + +export function getEvmAccount( + network: string, + address: string, + meta: BlockchainMeta[] +) { + const currentChainId = getChainIdByNetworkName(network, meta); + return AccountId.format({ + chainId: { + namespace: NAMESPACES.ETHEREUM, + reference: String(currentChainId), + }, + address, + }); +} + +// It's enough to return only connected network for the EVM networks and ignore others +export function filterEvmAccounts( + accounts: { + address: string; + chainId: string; + }[], + currentChainId?: string +) { + let firstEvmAddress = false; + return accounts + .filter(({ address, chainId }) => { + const isEvm = isEvmAddress(address); + if (isEvm) { + if (currentChainId && chainId !== currentChainId) { + return false; + } + if (!currentChainId) { + if (firstEvmAddress) { + return false; + } + firstEvmAddress = true; + } + } + return true; + }) + .map(({ address, chainId }) => ({ + accounts: [address], + chainId: chainId, + })); +} diff --git a/wallets/provider-walletconnect-2/src/index.ts b/wallets/provider-walletconnect-2/src/index.ts new file mode 100644 index 0000000000..3dc3c37dcc --- /dev/null +++ b/wallets/provider-walletconnect-2/src/index.ts @@ -0,0 +1,233 @@ +import type { Environments, WCInstance } from './types.js'; +import type { + CanSwitchNetwork, + Connect, + Disconnect, + GetInstance, + Subscribe, + SwitchNetwork, + WalletConfig, + WalletInfo, +} from '@rango-dev/wallets-shared'; +import type { ISignClient } from '@walletconnect/types'; +import type { BlockchainMeta, SignerFactory } from 'rango-types'; + +import { debug, error as logError } from '@rango-dev/logging-core'; +import { Networks, WalletTypes } from '@rango-dev/wallets-shared'; +import Client from '@walletconnect/sign-client'; +import { AccountId, ChainId } from 'caip'; +import { evmBlockchains } from 'rango-types'; + +import { + DEFAULT_APP_METADATA, + DEFAULT_NETWORK, + EthereumEvents, + EthereumRPCMethods, + NAMESPACES, + RELAY_URL, +} from './constants.js'; +import { + createModalInstance, + filterEvmAccounts, + simulateRequest, + switchOrAddEvmChain, +} from './helpers.js'; +import { + cleanupSingleSession, + disconnectSessions, + getAccountsFromEvent, + getAccountsFromSession, + getPersistedChainId, + ignoreNamespaceMethods, + persistCurrentChainId, + tryConnect, + updateSessionAccounts, +} from './session.js'; +import signer from './signer.js'; + +const WALLET = WalletTypes.WALLET_CONNECT_2; + +let envs: Environments = { + WC_PROJECT_ID: '', + DISABLE_MODAL_AND_OPEN_LINK: undefined, +}; + +export type { Environments }; + +export const init = (environments: Environments) => { + envs = environments; + + createModalInstance(envs.WC_PROJECT_ID); +}; + +export const config: WalletConfig = { + type: WALLET, + checkInstallation: false, + isAsyncInstance: true, + defaultNetwork: DEFAULT_NETWORK, + isAsyncSwitchNetwork: true, +}; + +export const getInstance: GetInstance = async (options) => { + const { currentProvider, getState, meta } = options; + + /* + * Create a new pair, if exists use the pair, + * Or use the already created one. + */ + let provider: ISignClient; + if (!currentProvider) { + if (!envs.WC_PROJECT_ID) { + throw new Error( + 'You need to set `WC_PROJECT_ID` in Wallet Connect provider.' + ); + } + provider = await Client.init({ + relayUrl: RELAY_URL, + projectId: envs.WC_PROJECT_ID, + metadata: DEFAULT_APP_METADATA, + }); + } else { + provider = currentProvider; + } + + return { + client: provider, + session: null, + request: async (params: any) => + simulateRequest(params, provider, meta, getState), + }; +}; + +export const connect: Connect = async ({ instance, meta }) => { + const { client } = instance as WCInstance; + // Try to restore the session first, if couldn't, create a new session by showing a modal. + const session = await tryConnect(client, { meta, envs }); + // Override the value (session). + instance.session = session; + const currentChainId = await getPersistedChainId(client); + const accounts = getAccountsFromSession(session); + return filterEvmAccounts(accounts, currentChainId); +}; + +export const subscribe: Subscribe = ({ + instance, + updateChainId, + updateAccounts, + disconnect, +}) => { + const { client } = instance as WCInstance; + + /** + * Session events refrence: + * https://docs.walletconnect.com/2.0/specs/clients/sign/session-events + */ + + // Listen to updating the session by adding a new chain, method, or event + client.on('session_update', (args) => { + const allAccounts = getAccountsFromEvent(args); + allAccounts.forEach((accountsWithChain) => { + updateAccounts(accountsWithChain.accounts, accountsWithChain.chainId); + }); + }); + + // Listen to events triggred by wallet. (e.g. accountsChanged and chainChanged) + client.on('session_event', (args) => { + if (args.params.event.name === EthereumEvents.ACCOUNTS_CHANGED) { + const accounts = args.params.event.data.map((account: string) => { + return new AccountId(account).address; + }); + const chainId = ChainId.parse(args.params.chainId).reference; + updateAccounts(accounts); + updateChainId(chainId); + } else if (args.params.event.name === EthereumEvents.CHAIN_CHANGED) { + const chainId = args.params.event.data; + updateChainId(chainId); + void persistCurrentChainId(instance.client, chainId); + } else { + console.log('[WC2] session_event not supported', args.params.event); + } + }); + + client.on('session_delete', async (event) => { + console.log('[WC2] your wallet has requested to delete session.', event); + void cleanupSingleSession(client, event.topic); + disconnect(); + }); +}; + +export const switchNetwork: SwitchNetwork = async ({ + network, + instance, + meta, + getState, + updateChainId, +}) => { + const evm = evmBlockchains(meta); + const chainId = evm.find((chain) => chain.name === network)?.chainId; + if (!chainId) { + const error = new Error(`There is no match for ${chainId}`); + logError(error); + throw error; + } + const chaindIdStr = new ChainId({ + namespace: NAMESPACES.ETHEREUM, + reference: String(parseInt(chainId)), + }).toString(); + + const session = instance.session; + const evmNamespace = session.namespaces[NAMESPACES.ETHEREUM]; + const authorizedChains = evmNamespace?.chains || []; + const authorizedMethods = evmNamespace?.methods || []; + + if ( + authorizedMethods.includes(EthereumRPCMethods.SWITCH_CHAIN) && + !ignoreNamespaceMethods(instance) + ) { + const currentNetwork = getState?.().network || Networks.ETHEREUM; + await updateSessionAccounts(instance, network, currentNetwork, meta); + await switchOrAddEvmChain(meta, network, currentNetwork, instance); + } else if (authorizedChains.includes(chaindIdStr)) { + updateChainId(chainId); + return; + } else { + const error = new Error(`Chain ${chainId} is not configured.`); + logError(error); + throw error; + } +}; + +/** + * + * Note: + * There is no straight-forward way to detect the wallet supports which blockchain, + * So we send request to wallet and expect to be rejected on the wallet if it's not supported. + * + */ +export const canSwitchNetworkTo: CanSwitchNetwork = () => true; + +export const disconnect: Disconnect = async ({ instance }) => { + const { client } = instance as WCInstance; + + if (client) { + void disconnectSessions(client).catch((error) => debug(error)); + } +}; + +export const getSigners: (provider: WCInstance) => Promise = + signer; + +export const getWalletInfo: (allBlockChains: BlockchainMeta[]) => WalletInfo = ( + allBlockChains +) => { + const evms = evmBlockchains(allBlockChains); + return { + name: 'WalletConnect', + img: 'https://raw.githubusercontent.com/rango-exchange/assets/main/wallets/walletconnect/icon.svg', + installLink: '', + color: '#b2dbff', + supportedChains: evms, + showOnMobile: true, + mobileWallet: true, + }; +}; diff --git a/wallets/provider-walletconnect-2/src/session.ts b/wallets/provider-walletconnect-2/src/session.ts new file mode 100644 index 0000000000..0a955daf86 --- /dev/null +++ b/wallets/provider-walletconnect-2/src/session.ts @@ -0,0 +1,374 @@ +import type { + ConnectParams, + CreateSessionParams, + Environments, +} from './types.js'; +import type { SignClient } from '@walletconnect/sign-client/dist/types/client'; +import type { + PairingTypes, + SessionTypes, + SignClientTypes, +} from '@walletconnect/types'; +import type { BlockchainMeta } from 'rango-types'; + +import { Networks, timeout } from '@rango-dev/wallets-shared'; +import { getSdkError } from '@walletconnect/utils'; +import { AccountId } from 'caip'; + +import { CHAIN_ID_STORAGE, PING_TIMEOUT } from './constants.js'; +import { + generateOptionalNamespace, + getCurrentEvmAccountAddress, + getEvmAccount, + getModal, + solanaChainIdToNetworkName, +} from './helpers.js'; + +export function getLastSession(client: SignClient) { + return client.session.values[client.session.values.length - 1]; +} + +/** + * + * Try to ping the wallet, if wallet responded with `pong`, session is a valid and we will use the session. + * If the wallet didn't respond during 10 seconds (PING_TIME), we assume the wallet isn't available and we need to create a new session. + * + */ +export async function restoreSession( + client: SignClient, + pairingTopic: PairingTypes.Struct['topic'] +): Promise { + await timeout( + client.ping({ + topic: pairingTopic, + }), + PING_TIMEOUT + ); + + // We assume last session is the correct session, beacuse we are doing clean up and keeps only one pairing/session. + const session = getLastSession(client); + return session; +} + +/** + * + * Getting a pair of required and optional namespaces then tries to show a modal and connect (pair) + * To the wallet. + * @param client + * @param options + * @returns + */ +export async function createSession( + client: SignClient, + options: CreateSessionParams, + configs: { + envs: Environments; + } +): Promise { + const { requiredNamespaces, optionalNamespaces, pairingTopic } = options; + + try { + const { uri, approval } = await client.connect({ + requiredNamespaces, + optionalNamespaces, + pairingTopic, + }); + + // Open QRCode modal if a URI was returned (i.e. we're not connecting an existing pairing). + let onCloseModal; + if (uri) { + /* + * There are some wallets have been listed in WC itself (https://docs.walletconnect.com/cloud/explorer-submission), + * Using `DISABLE_MODAL_AND_OPEN_LINK` option, we can directly open a specific desktop wallet. + */ + const redirectLink = configs.envs.DISABLE_MODAL_AND_OPEN_LINK; + if (redirectLink) { + const url = `${redirectLink}/wc?uri=${encodeURIComponent(uri)}`; + window.open(url, '_blank', 'noreferrer noopener'); + } else { + // Create a flat array of all requested chains across namespaces. + const allNamespaces = { + ...(requiredNamespaces || {}), + ...(optionalNamespaces || {}), + }; + + const standaloneChains = Object.values(allNamespaces) + .map((namespace) => namespace.chains) + .flat() as string[]; + + const modal = getModal(); + void modal.openModal({ uri, chains: standaloneChains }); + + onCloseModal = new Promise((_, reject) => { + modal.subscribeModal((state) => { + // the modal was closed so reject the promise + if (!state.open) { + reject(new Error('Modal has been closed.')); + } + }); + }); + } + } + + const session = approval(); + + if (onCloseModal) { + const result = await Promise.race([session, onCloseModal]); + // We know onClose only reject a modal and never returns a value. + return result as SessionTypes.Struct; + } + return await session; + } finally { + getModal().closeModal(); + } +} + +/** + * + * A user (client) can have multiple pairings (to different wallets), we are assuming + * the last pairing is the active pairing for now. A better UX can be showing a list of pairings + * and let the user to choose the right pairing manually. Because we don't have that yet, we will pick up the last one. + * + */ +export function tryGetPairing( + client: SignClient +): PairingTypes.Struct | undefined { + const pairings = client.pairing.getAll({ active: true }); + const lastPairing = + pairings.length > 0 ? pairings[pairings.length - 1] : undefined; + + return lastPairing; +} + +/** + * + * Try to restore the session first, if couldn't, create a new session by showing a modal. + * + */ +export async function tryConnect( + client: SignClient, + params: ConnectParams +): Promise { + const { meta } = params; + + // We try to get all of our supported chains as optional. + const optionalNamespaces = generateOptionalNamespace(meta); + + // Check if the user has a session, if yes, restore the session and use it. + let session: SessionTypes.Struct | undefined; + const pairing = tryGetPairing(client); + if (pairing) { + try { + session = await restoreSession(client, pairing.topic); + } catch (e) { + await disconnectSessions(client); + } + } + + // In case of connecting for the first time or session couldn't be restored, we will create a new session. + if (!session) { + session = await createSession( + client, + { + requiredNamespaces: {}, + optionalNamespaces, + }, + { + envs: params.envs, + } + ); + } + + return session; +} + +/** + * + * Try to find sessions with a topic id and expire them. + * + */ +export async function cleanupSingleSession(client: SignClient, topic: string) { + const sessions = client.session.getAll(); + const pairings = client.pairing.getAll(); + + sessions.forEach((session) => { + if (session.topic === topic || session.pairingTopic === topic) { + const requestForDeleteTopic = + session.pairingTopic === topic ? session.pairingTopic : session.topic; + client.core.expirer.set(requestForDeleteTopic, 0); + } + }); + + pairings.forEach((pairing) => { + if (pairing.topic === topic) { + client.core.expirer.set(topic, 0); + } + }); +} + +/** + * + * Disconnect means to delete the session on both parties (dApp & wallet) at the same time. + * + */ +export async function disconnectSessions(client: SignClient) { + const allPromises = []; + + const sessions = client.session.getAll(); + for (const session of sessions) { + allPromises.push( + client.disconnect({ + topic: session.topic, + reason: getSdkError('USER_DISCONNECTED'), + }) + ); + } + + const pairings = client.pairing.getAll(); + for (const pairing of pairings) { + allPromises.push( + client.disconnect({ + topic: pairing.topic, + reason: getSdkError('USER_DISCONNECTED'), + }) + ); + } + + // reset the current chain id + void persistCurrentChainId(client, undefined); + + return await Promise.all(allPromises); +} + +export function getAccountsFromSession(session: SessionTypes.Struct) { + const accounts = Object.values(session.namespaces) + .map((namespace) => namespace.accounts) + .flat() + .map((account) => { + const { address, chainId } = new AccountId(account); + /* + * Note: Solana has a specific ID, we need to convert it back to network name. + * It will return the chain id itslef if it's not that specific ID. + */ + const chain = solanaChainIdToNetworkName(chainId.reference); + return { + address, + chainId: chain, + }; + }); + return accounts; +} + +export function getAccountsFromEvent( + event: SignClientTypes.BaseEventArgs<{ + namespaces: SessionTypes.Namespaces; + }> +) { + const accounts = Object.values(event.params.namespaces) + .map((namespace) => namespace.accounts) + .flat() + .map((account) => { + const { address, chainId } = new AccountId(account); + return { + accounts: [address], + chainId: + chainId.namespace === 'solana' ? Networks.SOLANA : chainId.reference, + }; + }); + + return accounts; +} + +/* + * Before switch network, we need to update session namespace accounts + * to contain both current chain and target chain accoutns. + */ +export async function updateSessionAccounts( + instance: any, + requestedNetwork: string, + currentNetwork: string, + meta: BlockchainMeta[] +) { + const session = instance.session; + + const namespaces = session.namespaces; + let needUpdateNamepspace = false; + const accounts = namespaces.eip155.accounts; + + const currentAccountAddress = getCurrentEvmAccountAddress(instance); + const requestedAccount = getEvmAccount( + requestedNetwork, + currentAccountAddress, + meta + ); + if (!accounts.includes(requestedAccount)) { + accounts.push(requestedAccount); + needUpdateNamepspace = true; + } + + const currentAccount = getEvmAccount( + currentNetwork, + currentAccountAddress, + meta + ); + if (!accounts.includes(currentAccount)) { + accounts.push(currentAccount); + needUpdateNamepspace = true; + } + + if (needUpdateNamepspace) { + const updatedNamespaces = { + ...namespaces, + eip155: { + ...namespaces.eip155, + accounts, + }, + }; + await instance.client.session + .update({ + topic: session.topic, + namespaces: updatedNamespaces, + }) + .catch((err: unknown) => { + console.log(err); + }); + } +} + +/* + * Certain wallets, such as Trust Wallet and 1inch, are providing incorrect methods in + * response to session proposal requests. These wallets do not support certain optional + * RPC methods like "wallet_xyz," but they include them in the response under the session namespace. + * For the time being, we should avoid their session namespace response. + * see also: https://github.com/trustwallet/wallet-core/issues/3588 + */ +export function ignoreNamespaceMethods(instance: any): boolean { + const WALLETS_WITH_WRONG_NAMESPACE_METHODS = ['trust', '1inch']; + const peerName = instance?.session?.peer?.metadata?.name; + return WALLETS_WITH_WRONG_NAMESPACE_METHODS.some((name) => + peerName?.toLowerCase()?.includes(name) + ); +} + +export async function persistCurrentChainId( + client: SignClient, + chainId?: string +) { + return client.core.storage.setItem(CHAIN_ID_STORAGE, { + defaultChainId: chainId ? parseInt(chainId) : '', + }); +} + +/* + * get the latest chain id from the storage, + * used for setting current chain id in session reconnect. + */ +export async function getPersistedChainId(client: SignClient) { + try { + const chainId = (await client.core.storage.getItem(CHAIN_ID_STORAGE)) + ?.defaultChainId; + return !!chainId ? String(chainId) : undefined; + } catch { + return undefined; + } +} diff --git a/wallets/provider-walletconnect-2/src/signer.ts b/wallets/provider-walletconnect-2/src/signer.ts new file mode 100644 index 0000000000..1e8cf77431 --- /dev/null +++ b/wallets/provider-walletconnect-2/src/signer.ts @@ -0,0 +1,32 @@ +import type { WCInstance } from './types.js'; +import type { SignerFactory } from 'rango-types'; + +import { DefaultSignerFactory, TransactionType as TxType } from 'rango-types'; + +export default async function getSigners( + instance: WCInstance +): Promise { + if (!instance.session) { + throw new Error('Session is required for wallet connect signers.'); + } + + const signers = new DefaultSignerFactory(); + const EVMSigner = (await import('./signers/evm.js')).default; + const COSMOSSigner = (await import('./signers/cosmos.js')).default; + const SOLANASigner = (await import('./signers/solana.js')).default; + + signers.registerSigner( + TxType.EVM, + new EVMSigner(instance.client, instance.session) + ); + signers.registerSigner( + TxType.COSMOS, + new COSMOSSigner(instance.client, instance.session) + ); + signers.registerSigner( + TxType.SOLANA, + new SOLANASigner(instance.client, instance.session) + ); + + return signers; +} diff --git a/wallets/provider-walletconnect-2/src/signers/cosmos.ts b/wallets/provider-walletconnect-2/src/signers/cosmos.ts new file mode 100644 index 0000000000..5429a3d436 --- /dev/null +++ b/wallets/provider-walletconnect-2/src/signers/cosmos.ts @@ -0,0 +1,248 @@ +import type { AminoSignResponse } from '@cosmjs/launchpad'; +import type { SignClient } from '@walletconnect/sign-client/dist/types/client'; +import type { SessionTypes } from '@walletconnect/types'; +import type { CosmosTransaction, GenericSigner } from 'rango-types'; + +import { BroadcastMode, makeSignDoc } from '@cosmjs/launchpad'; +import { cosmos } from '@keplr-wallet/cosmos'; +import { getsignedTx } from '@rango-dev/signer-cosmos'; +import { uint8ArrayToHex } from '@rango-dev/wallets-shared'; +import { AccountId, ChainId } from 'caip'; +import { formatDirectSignDoc, stringifySignDocValues } from 'cosmos-wallet'; +import { SignerError, SignerErrorCode } from 'rango-types'; + +import { CosmosRPCMethods, NAMESPACES } from '../constants.js'; + +import { sendTx } from './helper.js'; +import { supportedChains } from './mock.js'; + +const NAMESPACE_NAME = NAMESPACES.COSMOS; +type DirectSignResponse = { + signature: { + pub_key: { + type: string; + value: string; + }; + signature: string; + }; + signed: { + chainId: string; + accountNumber: string; + authInfoBytes: string; + bodyBytes: string; + }; +}; +class COSMOSSigner implements GenericSigner { + private client: SignClient; + private session: SessionTypes.Struct; + + constructor(client: SignClient, session: SessionTypes.Struct) { + this.client = client; + this.session = session; + } + + public async signMessage(): Promise { + throw SignerError.UnimplementedError('signMessage'); + } + + async signAndSendTx( + tx: CosmosTransaction, + address: string, + chainId: string | null + ): Promise<{ hash: string }> { + console.log({ tx, address, chainId }); + + const requestedFor = this.isNetworkAndAccountExistInSession({ + address, + chainId, + }); + try { + const { memo, sequence, account_number, chainId, msgs, fee, signType } = + tx.data; + const msgsWithoutType = msgs.map((m) => ({ + ...m, + __type: undefined, + '@type': undefined, + })); + if (!chainId) { + throw SignerError.AssertionFailed('chainId is undefined from server'); + } + if (!account_number) { + throw SignerError.AssertionFailed( + 'account_number is undefined from server' + ); + } + if (!sequence) { + throw SignerError.AssertionFailed('sequence is undefined from server'); + } + + if (signType === 'AMINO') { + const signDoc = makeSignDoc( + msgsWithoutType, + fee as any, + chainId, + memo || undefined, + account_number, + sequence + ); + let signResponse; + try { + signResponse = await this.client.request({ + topic: this.session.topic, + chainId: requestedFor.caipChainId, + request: { + method: CosmosRPCMethods.SIGN_AMINO, + params: { + signDoc, + signerAddress: tx.fromWalletAddress, + }, + }, + }); + } catch (err) { + throw new SignerError(SignerErrorCode.SIGN_TX_ERROR, undefined, err); + } + + const signedTx = getsignedTx(tx, signResponse); + const result = await sendTx( + chainId, + signedTx, + BroadcastMode.Async, + supportedChains + ); + return { hash: uint8ArrayToHex(result) }; + } else if (signType === 'DIRECT') { + let getAccounts; + try { + getAccounts = await this.client.request< + Array<{ + address: string; + algo: string; + pubkey: string; + }> + >({ + topic: this.session.topic, + chainId: requestedFor.caipChainId, + request: { + method: CosmosRPCMethods.GET_ACCOUNTS, + params: {}, + }, + }); + } catch (err) { + throw new SignerError(SignerErrorCode.SIGN_TX_ERROR, undefined, err); + } + const pubkey = + getAccounts?.find( + (account) => account.address === tx.fromWalletAddress + )?.pubkey || ''; + + const bodyBytes = cosmos.tx.v1beta1.TxBody.encode({ + messages: tx.data.protoMsgs.map((m) => ({ + type_url: m.type_url, + value: new Uint8Array(m.value), + })), + memo, + }).finish(); + console.log({ tx, bodyBytes }); + + const signDoc = formatDirectSignDoc( + fee?.amount || [], + pubkey, + parseInt(fee?.gas as string), + account_number, + parseInt(sequence), + uint8ArrayToHex(bodyBytes), + chainId + ); + let signResponse; + try { + signResponse = await this.client.request({ + topic: this.session.topic, + chainId: requestedFor.caipChainId, + request: { + method: CosmosRPCMethods.SIGN_DIRECT, + params: { + signDoc: stringifySignDocValues(signDoc), + signerAddress: tx.fromWalletAddress, + }, + }, + }); + } catch (err) { + throw new SignerError(SignerErrorCode.SIGN_TX_ERROR, undefined, err); + } + console.log({ signResponse }); + const signedTx = cosmos.tx.v1beta1.TxRaw.encode({ + bodyBytes: new TextEncoder().encode(signResponse.signed.bodyBytes), + authInfoBytes: new TextEncoder().encode( + signResponse.signed.authInfoBytes + ), + signatures: [Buffer.from(signResponse.signature.signature, 'base64')], + }).finish(); + console.log({ signedTx }); + const result = await sendTx( + chainId, + signedTx, + BroadcastMode.Async, + supportedChains + ); + + console.log({ result }); + + return { hash: uint8ArrayToHex(result) }; + } + throw new SignerError( + SignerErrorCode.OPERATION_UNSUPPORTED, + `Sign type for cosmos not supported, type: ${signType}` + ); + } catch (err) { + if (SignerError.isSignerError(err)) { + throw err; + } else { + throw new SignerError(SignerErrorCode.SEND_TX_ERROR, undefined, err); + } + } + } + + private isNetworkAndAccountExistInSession(requestedFor: { + address: string; + chainId: string | null; + }) { + const { address, chainId } = requestedFor; + + if (!chainId) { + throw new Error( + 'You need to set your chain for signing message/transaction.' + ); + } + + const caipAddress = new AccountId({ + chainId: { + namespace: NAMESPACE_NAME, + reference: chainId, + }, + address, + }); + const addresses = this.session.namespaces[NAMESPACE_NAME]?.accounts.map( + (address) => address.toLowerCase() + ); + + if (!addresses || !addresses.includes(caipAddress.toString())) { + console.warn( + 'Available adresses and requested address:', + addresses, + caipAddress.toString() + ); + throw new Error( + `Your requested address doesn't exist on your wallect connect session. Please reconnect your wallet.` + ); + } + + const caipChainId = new ChainId({ + namespace: NAMESPACE_NAME, + reference: chainId, + }); + + return { chainId, address, caipChainId: caipChainId.toString() }; + } +} + +export default COSMOSSigner; diff --git a/wallets/provider-walletconnect-2/src/signers/evm.ts b/wallets/provider-walletconnect-2/src/signers/evm.ts new file mode 100644 index 0000000000..fba1f97c52 --- /dev/null +++ b/wallets/provider-walletconnect-2/src/signers/evm.ts @@ -0,0 +1,163 @@ +import type { SignClient } from '@walletconnect/sign-client/dist/types/client'; +import type { SessionTypes } from '@walletconnect/types'; +import type { EvmTransaction } from 'rango-types/mainApi'; + +import { cleanEvmError, DefaultEvmSigner } from '@rango-dev/signer-evm'; +import * as encoding from '@walletconnect/encoding'; +import { AccountId, ChainId } from 'caip'; +import { type GenericSigner } from 'rango-types'; + +import { EthereumRPCMethods, NAMESPACES } from '../constants.js'; + +const NAMESPACE_NAME = NAMESPACES.ETHEREUM; + +class EVMSigner implements GenericSigner { + private client: SignClient; + private session: SessionTypes.Struct; + + constructor(client: SignClient, session: SessionTypes.Struct) { + this.client = client; + this.session = session; + } + + public async signMessage( + msg: string, + address: string, + chainId: string | null + ): Promise { + const requestedFor = this.isNetworkAndAccountExistInSession({ + address, + chainId, + }); + + const caipChainId = new ChainId({ + namespace: NAMESPACE_NAME, + reference: requestedFor.chainId, + }); + const hexMsg = encoding.utf8ToHex(msg, true); + + const params = [hexMsg, address]; + + let signature: string; + try { + // Send message to wallet (using relayer) + signature = await this.client.request({ + topic: this.session.topic, + chainId: caipChainId.toString(), + request: { + method: EthereumRPCMethods.PERSONAL_SIGN, + params, + }, + }); + } catch (error) { + throw cleanEvmError(error); + } + + /* + * TODO: We can also verify the signature here + * Check web-examples: dapps/react-dapp-v2/src/contexts/JsonRpcContext.tsx + */ + + return signature; + } + + async signAndSendTx( + tx: EvmTransaction, + address: string, + chainId: string | null + ): Promise<{ hash: string }> { + try { + const requestedFor = this.isNetworkAndAccountExistInSession({ + address, + chainId, + }); + const transaction = DefaultEvmSigner.buildTx(tx); + const hash: string = await this.client.request({ + topic: this.session.topic, + chainId: requestedFor.caipChainId, + request: { + method: EthereumRPCMethods.SEND_TRANSACTION, + params: [transaction], + }, + }); + // Some wallets e.g. Rainbow wallet are returning invalid hash (e.g. 'null') in case of the rejection + if (!hash?.startsWith('0x')) { + throw new Error( + `Received an invalid hash on signing the transaction. (hash=${hash})` + ); + } + return { + hash, + }; + } catch (error: any) { + const modifiedError = cleanEvmError(error); + const session = this.session; + const context = { + namspaces: session?.namespaces, + peering: session?.peer?.metadata, + code: error?.code, + }; + modifiedError.context = context; + throw modifiedError; + } + } + + private isNetworkAndAccountExistInSession(requestedFor: { + address: string; + chainId: string | null; + }) { + const { address, chainId } = requestedFor; + + if (!chainId) { + console.log('isNetworkAndAccountExistInSession', requestedFor); + throw new Error( + 'You need to set your chain for signing message/transaction.' + ); + } + + /* + * TODO: We need to make sure we are using a single format for chain ids, it should be hex or number. + * This is a quick fix for evm. + */ + const chainIdNumber = chainId.startsWith('0x') + ? String(parseInt(chainId)) + : chainId; + + const caipAddress = new AccountId({ + chainId: { + namespace: NAMESPACE_NAME, + reference: chainIdNumber, + }, + address, + }); + const addresses = this.session.namespaces[NAMESPACE_NAME]?.accounts.map( + (address) => address.toLowerCase() + ); + + if (!addresses || !addresses.includes(caipAddress.toString())) { + console.warn( + 'Available adresses and requested address:', + addresses, + caipAddress.toString(), + chainId, + address + ); + throw new Error( + `Your requested address doesn't exist on your wallect connect session. Please reconnect your wallet.` + ); + } + + const caipChainId = new ChainId({ + namespace: NAMESPACE_NAME, + reference: chainIdNumber, + }); + + return { + chainId: chainIdNumber, + address, + caipChainId: caipChainId.toString(), + }; + } +} + +export default EVMSigner; diff --git a/wallets/provider-walletconnect-2/src/signers/helper.ts b/wallets/provider-walletconnect-2/src/signers/helper.ts new file mode 100644 index 0000000000..20bf3721a8 --- /dev/null +++ b/wallets/provider-walletconnect-2/src/signers/helper.ts @@ -0,0 +1,77 @@ +import type { BlockchainMeta } from 'rango-types'; + +import { TendermintTxTracer } from '@keplr-wallet/cosmos'; +import { simpleFetch } from '@keplr-wallet/simple-fetch'; +import { cosmosBlockchains } from 'rango-types'; + +export async function sendTx( + chainId: string, + tx: unknown, + mode: 'async' | 'sync' | 'block', + supportedChains: BlockchainMeta[] +): Promise { + console.log({ chainId, tx, mode }); + + const cosmos = cosmosBlockchains(supportedChains); + const chainInfo = cosmos.find((item) => item.chainId === chainId)?.info; + const isProtoTx = Buffer.isBuffer(tx) || tx instanceof Uint8Array; + + console.log({ chainInfo, isProtoTx }); + + if (!chainInfo) { + throw new Error('Chain info is undefined from server'); + } + const params = isProtoTx + ? { + tx_bytes: Buffer.from(tx as any).toString('base64'), + mode: (() => { + switch (mode) { + case 'async': + return 'BROADCAST_MODE_ASYNC'; + case 'block': + return 'BROADCAST_MODE_BLOCK'; + case 'sync': + return 'BROADCAST_MODE_SYNC'; + default: + return 'BROADCAST_MODE_UNSPECIFIED'; + } + })(), + } + : { + tx, + mode: mode, + }; + + try { + const result = await simpleFetch( + chainInfo.rest, + isProtoTx ? '/cosmos/tx/v1beta1/txs' : '/txs', + { + method: 'POST', + headers: { + 'content-type': 'application/json', + }, + body: JSON.stringify(params), + } + ); + + const txResponse = isProtoTx ? result.data['tx_response'] : result.data; + + if (txResponse.code != null && txResponse.code !== 0) { + throw new Error(txResponse['raw_log']); + } + + const txHash = Buffer.from(txResponse.txhash, 'hex'); + + const txTracer = new TendermintTxTracer(chainInfo.rpc, '/websocket'); + // eslint-disable-next-line @typescript-eslint/no-floating-promises + txTracer.traceTx(txHash).then(() => { + txTracer.close(); + }); + + return txHash; + } catch (e) { + console.log(e); + throw e; + } +} diff --git a/wallets/provider-walletconnect-2/src/signers/mock.ts b/wallets/provider-walletconnect-2/src/signers/mock.ts new file mode 100644 index 0000000000..c1dfc7fb2e --- /dev/null +++ b/wallets/provider-walletconnect-2/src/signers/mock.ts @@ -0,0 +1,3798 @@ +import type { BlockchainMeta } from 'rango-types'; + +export const supportedChains: BlockchainMeta[] = [ + { + name: 'BSC', + defaultDecimals: 18, + addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], + feeAssets: [ + { + blockchain: 'BSC', + symbol: 'BNB', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/binance.svg', + displayName: 'BSC', + shortName: 'BSC', + sort: 1, + color: '#F3BA2F', + enabled: true, + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + type: 'EVM', + chainId: '0x38', + info: { + infoType: 'EvmMetaInfo', + chainName: 'Binance Smart Chain Mainnet', + nativeCurrency: { + name: 'BNB', + symbol: 'BNB', + decimals: 18, + }, + rpcUrls: ['https://bsc-dataseed1.ninicoin.io'], + blockExplorerUrls: ['https://bscscan.com'], + addressUrl: 'https://bscscan.com/address/{wallet}', + transactionUrl: 'https://bscscan.com/tx/{txHash}', + enableGasV2: true, + }, + }, + { + name: 'POLYGON', + defaultDecimals: 18, + addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], + feeAssets: [ + { + blockchain: 'POLYGON', + symbol: 'MATIC', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/polygon.svg', + displayName: 'Polygon', + shortName: 'Polygon', + sort: 2, + color: '#8247E5', + enabled: true, + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + type: 'EVM', + chainId: '0x89', + info: { + infoType: 'EvmMetaInfo', + chainName: 'Polygon Mainnet', + nativeCurrency: { + name: 'MATIC', + symbol: 'MATIC', + decimals: 18, + }, + rpcUrls: ['https://polygon-rpc.com'], + blockExplorerUrls: ['https://polygonscan.com'], + addressUrl: 'https://polygonscan.com/address/{wallet}', + transactionUrl: 'https://polygonscan.com/tx/{txHash}', + enableGasV2: true, + }, + }, + { + name: 'ETH', + defaultDecimals: 18, + addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], + feeAssets: [ + { + blockchain: 'ETH', + symbol: 'ETH', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/ethereum.svg', + displayName: 'Ethereum', + shortName: 'ETH', + sort: 3, + color: '#ecf0f1', + enabled: true, + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + type: 'EVM', + chainId: '0x1', + info: { + infoType: 'EvmMetaInfo', + chainName: 'Ethereum Mainnet', + nativeCurrency: { + name: 'ETH', + symbol: 'ETH', + decimals: 18, + }, + rpcUrls: ['https://rpc.ankr.com/eth'], + blockExplorerUrls: ['https://etherscan.io'], + addressUrl: 'https://etherscan.io/address/{wallet}', + transactionUrl: 'https://etherscan.io/tx/{txHash}', + enableGasV2: true, + }, + }, + { + name: 'OSMOSIS', + defaultDecimals: 6, + addressPatterns: ['^(osmo1)[0-9a-z]{38}$'], + feeAssets: [ + { + blockchain: 'OSMOSIS', + symbol: 'OSMO', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/osmosis.svg', + displayName: 'Osmosis', + shortName: 'Osmosis', + sort: 4, + color: '#7901B4', + enabled: true, + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + type: 'COSMOS', + chainId: 'osmosis-1', + info: { + infoType: 'CosmosMetaInfo', + blockExplorerUrls: ['https://www.mintscan.io/cosmos/'], + addressUrl: 'https://www.mintscan.io/cosmos/account/{wallet}', + transactionUrl: 'https://www.mintscan.io/cosmos/txs/{txHash}', + experimental: false, + rpc: 'https://rpc-osmosis.keplr.app', + rest: 'https://lcd-osmosis.keplr.app', + cosmostationLcdUrl: 'https://lcd-osmosis.cosmostation.io', + cosmostationApiUrl: 'https://api-osmosis.cosmostation.io', + cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', + mintScanName: 'osmosis', + chainName: 'Osmosis', + stakeCurrency: { + coinDenom: 'OSMO', + coinMinimalDenom: 'uosmo', + coinDecimals: 6, + coinGeckoId: 'pool:uosmo', + coinImageUrl: '/tokens/blockchain/osmosis.svg', + }, + bip44: { + coinType: 118, + }, + bech32Config: { + bech32PrefixAccAddr: 'osmo', + bech32PrefixAccPub: 'osmopub', + bech32PrefixValAddr: 'osmovaloper', + bech32PrefixValPub: 'osmovaloperpub', + bech32PrefixConsAddr: 'osmovalcons', + bech32PrefixConsPub: 'osmovalconspub', + }, + currencies: [ + { + coinDenom: 'OSMO', + coinMinimalDenom: 'uosmo', + coinDecimals: 6, + coinGeckoId: 'pool:uosmo', + coinImageUrl: '/tokens/blockchain/osmosis.svg', + }, + { + coinDenom: 'ION', + coinMinimalDenom: 'uion', + coinDecimals: 6, + coinGeckoId: 'pool:uion', + coinImageUrl: '/tokens/blockchain/ion.png', + }, + ], + feeCurrencies: [ + { + coinDenom: 'OSMO', + coinMinimalDenom: 'uosmo', + coinDecimals: 6, + coinGeckoId: 'pool:uosmo', + coinImageUrl: '/tokens/blockchain/osmosis.svg', + }, + ], + features: ['stargate', 'ibc-transfer'], + explorerUrlToTx: 'https://www.mintscan.io/osmosis/txs/{txHash}', + gasPriceStep: { + low: 0, + average: 0.025, + high: 0.04, + }, + }, + }, + { + name: 'JUNO', + defaultDecimals: 6, + addressPatterns: ['^(juno1)[0-9a-z]{38}$'], + feeAssets: [ + { + blockchain: 'JUNO', + symbol: 'JUNO', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/juno.svg', + displayName: 'Juno', + shortName: 'Juno', + sort: 5, + color: '#f0827d', + enabled: true, + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + type: 'COSMOS', + chainId: 'juno-1', + info: { + infoType: 'CosmosMetaInfo', + blockExplorerUrls: ['https://www.mintscan.io/cosmos/'], + addressUrl: 'https://www.mintscan.io/cosmos/account/{wallet}', + transactionUrl: 'https://www.mintscan.io/cosmos/txs/{txHash}', + experimental: false, + rpc: 'https://rpc-juno.itastakers.com:443/', + rest: 'https://lcd-juno.keplr.app', + cosmostationLcdUrl: 'https://lcd-juno.cosmostation.io', + cosmostationApiUrl: 'https://api-juno.cosmostation.io', + cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', + mintScanName: 'juno', + chainName: 'Juno', + stakeCurrency: { + coinDenom: 'JUNO', + coinMinimalDenom: 'ujuno', + coinDecimals: 6, + coinGeckoId: 'juno-network', + coinImageUrl: '/tokens/blockchain/JUNO.png', + }, + bip44: { + coinType: 118, + }, + bech32Config: { + bech32PrefixAccAddr: 'juno', + bech32PrefixAccPub: 'junopub', + bech32PrefixValAddr: 'junovaloper', + bech32PrefixValPub: 'junovaloperpub', + bech32PrefixConsAddr: 'junovalcons', + bech32PrefixConsPub: 'junovalconspub', + }, + currencies: [ + { + coinDenom: 'JUNO', + coinMinimalDenom: 'ujuno', + coinDecimals: 6, + coinGeckoId: 'juno-network', + coinImageUrl: '/tokens/blockchain/JUNO.png', + }, + ], + feeCurrencies: [ + { + coinDenom: 'JUNO', + coinMinimalDenom: 'ujuno', + coinDecimals: 6, + coinGeckoId: 'juno-network', + coinImageUrl: '/tokens/blockchain/JUNO.png', + }, + ], + features: ['stargate', 'ibc-transfer'], + explorerUrlToTx: 'https://www.mintscan.io/juno/txs/{txHash}', + gasPriceStep: { + low: 0.001, + average: 0.0025, + high: 0.004, + }, + }, + }, + { + name: 'AVAX_CCHAIN', + defaultDecimals: 18, + addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], + feeAssets: [ + { + blockchain: 'AVAX_CCHAIN', + symbol: 'AVAX', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/avax_cchain.svg', + displayName: 'Avalanche', + shortName: 'Avax', + sort: 6, + color: '#e84142', + enabled: true, + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + type: 'EVM', + chainId: '0xa86a', + info: { + infoType: 'EvmMetaInfo', + chainName: 'Avalanche C-Chain', + nativeCurrency: { + name: 'AVAX', + symbol: 'AVAX', + decimals: 18, + }, + rpcUrls: ['https://api.avax.network/ext/bc/C/rpc'], + blockExplorerUrls: ['https://snowtrace.io'], + addressUrl: 'https://snowtrace.io/address/{wallet}', + transactionUrl: 'https://snowtrace.io/tx/{txHash}', + enableGasV2: true, + }, + }, + { + name: 'ARBITRUM', + defaultDecimals: 18, + addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], + feeAssets: [ + { + blockchain: 'ARBITRUM', + symbol: 'ETH', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/arbitrum.svg', + displayName: 'Arbitrum', + shortName: 'Arbitrum', + sort: 7, + color: '#28a0f0', + enabled: true, + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + type: 'EVM', + chainId: '0xa4b1', + info: { + infoType: 'EvmMetaInfo', + chainName: 'Arbitrum One', + nativeCurrency: { + name: 'ETH', + symbol: 'ETH', + decimals: 18, + }, + rpcUrls: ['https://arb1.arbitrum.io/rpc'], + blockExplorerUrls: ['https://arbiscan.io'], + addressUrl: 'https://arbiscan.io/address/{wallet}', + transactionUrl: 'https://arbiscan.io/tx/{txHash}', + enableGasV2: true, + }, + }, + { + name: 'COSMOS', + defaultDecimals: 6, + addressPatterns: ['^(cosmos1)[0-9a-z]{38}$'], + feeAssets: [ + { + blockchain: 'COSMOS', + symbol: 'ATOM', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/cosmos.svg', + displayName: 'Cosmos', + shortName: 'Cosmos', + sort: 8, + color: '#2E3148', + enabled: true, + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + type: 'COSMOS', + chainId: 'cosmoshub-4', + info: { + infoType: 'CosmosMetaInfo', + blockExplorerUrls: ['https://www.mintscan.io/cosmos/'], + addressUrl: 'https://www.mintscan.io/cosmos/account/{wallet}', + transactionUrl: 'https://www.mintscan.io/cosmos/txs/{txHash}', + experimental: false, + rpc: 'https://cosmos-rpc.polkachu.com', + rest: 'https://lcd-cosmoshub.keplr.app', + cosmostationLcdUrl: 'https://lcd-cosmos.cosmostation.io', + cosmostationApiUrl: 'https://api-cosmos.cosmostation.io', + cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', + mintScanName: 'cosmos', + chainName: 'Cosmos', + stakeCurrency: { + coinDenom: 'ATOM', + coinMinimalDenom: 'uatom', + coinDecimals: 6, + coinGeckoId: 'cosmos', + coinImageUrl: '/tokens/blockchain/cosmos.svg', + }, + bip44: { + coinType: 118, + }, + bech32Config: { + bech32PrefixAccAddr: 'cosmos', + bech32PrefixAccPub: 'cosmospub', + bech32PrefixValAddr: 'cosmosvaloper', + bech32PrefixValPub: 'cosmosvaloperpub', + bech32PrefixConsAddr: 'cosmosvalcons', + bech32PrefixConsPub: 'cosmosvalconspub', + }, + currencies: [ + { + coinDenom: 'ATOM', + coinMinimalDenom: 'uatom', + coinDecimals: 6, + coinGeckoId: 'cosmos', + coinImageUrl: '/tokens/blockchain/cosmos.svg', + }, + ], + feeCurrencies: [ + { + coinDenom: 'ATOM', + coinMinimalDenom: 'uatom', + coinDecimals: 6, + coinGeckoId: 'cosmos', + coinImageUrl: '/tokens/blockchain/cosmos.svg', + }, + ], + features: ['stargate', 'ibc-transfer'], + explorerUrlToTx: 'https://www.mintscan.io/cosmos/txs/{txHash}', + gasPriceStep: { + low: 0.01, + average: 0.025, + high: 0.04, + }, + }, + }, + { + name: 'TERRA_CLASSIC', + defaultDecimals: 6, + addressPatterns: ['^(terra1)[0-9a-z]{38}$'], + feeAssets: [ + { + blockchain: 'TERRA_CLASSIC', + symbol: 'LUNC', + address: null, + }, + { + blockchain: 'TERRA_CLASSIC', + symbol: 'UST', + address: null, + }, + { + blockchain: 'TERRA_CLASSIC', + symbol: 'EUT', + address: null, + }, + { + blockchain: 'TERRA_CLASSIC', + symbol: 'KRT', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/terraclassic.svg', + displayName: 'Terra', + shortName: 'Terra', + sort: 8, + color: '#5493F7', + enabled: false, + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + type: 'COSMOS', + chainId: 'columbus-5', + info: { + infoType: 'CosmosMetaInfo', + blockExplorerUrls: ['https://www.mintscan.io/cosmos/'], + addressUrl: 'https://www.mintscan.io/cosmos/account/{wallet}', + transactionUrl: 'https://www.mintscan.io/cosmos/txs/{txHash}', + experimental: true, + rpc: 'https://rpc-columbus.keplr.app', + rest: 'https://lcd-columbus.keplr.app', + cosmostationLcdUrl: null, + cosmostationApiUrl: 'https://terra-classic-lcd.publicnode.com', + cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', + mintScanName: null, + chainName: 'Terra', + stakeCurrency: { + coinDenom: 'LUNC', + coinMinimalDenom: 'uluna', + coinDecimals: 6, + coinGeckoId: 'terra-luna', + coinImageUrl: '/tokens/blockchain/LUNA.png', + }, + bip44: { + coinType: 330, + }, + bech32Config: { + bech32PrefixAccAddr: 'terra', + bech32PrefixAccPub: 'terrapub', + bech32PrefixValAddr: 'terravaloper', + bech32PrefixValPub: 'terravaloperpub', + bech32PrefixConsAddr: 'terravalcons', + bech32PrefixConsPub: 'terravalconspub', + }, + currencies: [ + { + coinDenom: 'LUNC', + coinMinimalDenom: 'uluna', + coinDecimals: 6, + coinGeckoId: 'terra-luna', + coinImageUrl: '/tokens/blockchain/LUNA.png', + }, + { + coinDenom: 'UST', + coinMinimalDenom: 'uusd', + coinDecimals: 6, + coinGeckoId: 'terrausd', + coinImageUrl: '/tokens/blockchain/UST.png', + }, + ], + feeCurrencies: [ + { + coinDenom: 'LUNC', + coinMinimalDenom: 'uluna', + coinDecimals: 6, + coinGeckoId: 'terra-luna', + coinImageUrl: '/tokens/blockchain/LUNA.png', + }, + { + coinDenom: 'UST', + coinMinimalDenom: 'uusd', + coinDecimals: 6, + coinGeckoId: 'terrausd', + coinImageUrl: '/tokens/blockchain/UST.png', + }, + ], + features: ['stargate', 'ibc-transfer', 'no-legacy-stdTx'], + explorerUrlToTx: 'https://finder.terra.money/columbus-5/tx/{txHash}', + gasPriceStep: { + low: 0.0075, + average: 0.0075, + high: 0.0075, + }, + }, + }, + { + name: 'FANTOM', + defaultDecimals: 18, + addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], + feeAssets: [ + { + blockchain: 'FANTOM', + symbol: 'FTM', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/fantom.png', + displayName: 'Fantom', + shortName: 'Fantom', + sort: 9, + color: '#337afe', + enabled: true, + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + type: 'EVM', + chainId: '0xfa', + info: { + infoType: 'EvmMetaInfo', + chainName: 'Fantom Opera', + nativeCurrency: { + name: 'FTM', + symbol: 'FTM', + decimals: 18, + }, + rpcUrls: ['https://rpc.ftm.tools'], + blockExplorerUrls: ['https://ftmscan.com'], + addressUrl: 'https://ftmscan.com/address/{wallet}', + transactionUrl: 'https://ftmscan.com/tx/{txHash}', + enableGasV2: true, + }, + }, + { + name: 'OPTIMISM', + defaultDecimals: 18, + addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], + feeAssets: [ + { + blockchain: 'OPTIMISM', + symbol: 'ETH', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/optimism.svg', + displayName: 'Optimism', + shortName: 'Optimism', + sort: 10, + color: '#FF0420', + enabled: true, + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + type: 'EVM', + chainId: '0xa', + info: { + infoType: 'EvmMetaInfo', + chainName: 'Optimism', + nativeCurrency: { + name: 'ETH', + symbol: 'ETH', + decimals: 18, + }, + rpcUrls: ['https://mainnet.optimism.io'], + blockExplorerUrls: ['https://optimistic.etherscan.io'], + addressUrl: 'https://optimistic.etherscan.io/address/{wallet}', + transactionUrl: 'https://optimistic.etherscan.io/tx/{txHash}', + enableGasV2: true, + }, + }, + { + name: 'OKC', + defaultDecimals: 18, + addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], + feeAssets: [ + { + blockchain: 'OKC', + symbol: 'OKT', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/okx.png', + displayName: 'OKX Chain (OKC)', + shortName: 'Okx', + sort: 11, + color: '#29a0f0', + enabled: true, + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + type: 'EVM', + chainId: '0x42', + info: { + infoType: 'EvmMetaInfo', + chainName: 'OKX Chain', + nativeCurrency: { + name: 'OKT', + symbol: 'OKT', + decimals: 18, + }, + rpcUrls: ['https://exchainrpc.okex.org'], + blockExplorerUrls: ['https://www.oklink.com/en/okc'], + addressUrl: 'https://www.oklink.com/en/okc/address/{wallet}', + transactionUrl: 'https://www.oklink.com/en/okc/tx/{txHash}', + enableGasV2: true, + }, + }, + { + name: 'STARKNET', + defaultDecimals: 18, + addressPatterns: ['^(0x)[0-9A-Fa-f]{32,64}$'], + feeAssets: [ + { + blockchain: 'STARKNET', + symbol: 'ETH', + address: + '0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7', + }, + ], + logo: 'https://api.rango.exchange/blockchains/starknet.svg', + displayName: 'StarkNet', + shortName: 'StarkNet', + sort: 11, + color: '#708DD2', + enabled: true, + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + type: 'STARKNET', + chainId: '0x534e5f4d41494e', + info: { + infoType: 'StarkNetMetaInfo', + chainName: 'StarkNet Mainnet', + nativeCurrency: { + name: 'ETH', + symbol: 'ETH', + decimals: 18, + }, + blockExplorerUrls: ['https://starkscan.co'], + addressUrl: 'https://starkscan.co/contract/{wallet}', + transactionUrl: 'https://starkscan.co/tx/{txHash}', + }, + }, + { + name: 'SOLANA', + defaultDecimals: 9, + addressPatterns: ['^[1-9A-HJ-NP-Za-km-z]{32,44}$'], + feeAssets: [ + { + blockchain: 'SOLANA', + symbol: 'SOL', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/solana.svg', + displayName: 'Solana', + shortName: 'Solana', + sort: 11, + color: '#708DD2', + enabled: true, + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + type: 'SOLANA', + chainId: 'mainnet-beta', + info: null, + }, + { + name: 'CRONOS', + defaultDecimals: 18, + addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], + feeAssets: [ + { + blockchain: 'CRONOS', + symbol: 'CRO', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/cronos.svg', + displayName: 'Cronos', + shortName: 'Cronos', + sort: 12, + color: '#1a90ff', + enabled: true, + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + type: 'EVM', + chainId: '0x19', + info: { + infoType: 'EvmMetaInfo', + chainName: 'Cronos Mainnet Beta', + nativeCurrency: { + name: 'CRO', + symbol: 'CRO', + decimals: 18, + }, + rpcUrls: ['https://evm.cronos.org'], + blockExplorerUrls: ['https://cronoscan.com'], + addressUrl: 'https://cronoscan.com/address/{wallet}', + transactionUrl: 'https://cronoscan.com/tx/{txHash}', + enableGasV2: true, + }, + }, + { + name: 'MOONRIVER', + defaultDecimals: 18, + addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], + feeAssets: [ + { + blockchain: 'MOONRIVER', + symbol: 'MOVR', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/moonriver.svg', + displayName: 'MoonRiver', + shortName: 'MoonRiver', + sort: 13, + color: '#F3B404', + enabled: true, + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + type: 'EVM', + chainId: '0x505', + info: { + infoType: 'EvmMetaInfo', + chainName: 'MoonRiver', + nativeCurrency: { + name: 'MOVR', + symbol: 'MOVR', + decimals: 18, + }, + rpcUrls: ['https://rpc.moonriver.moonbeam.network'], + blockExplorerUrls: ['https://moonriver.moonscan.io'], + addressUrl: 'https://moonriver.moonscan.io/address/{wallet}', + transactionUrl: 'https://moonriver.moonscan.io/tx/{txHash}', + enableGasV2: true, + }, + }, + { + name: 'ZKSYNC', + defaultDecimals: 18, + addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], + feeAssets: [ + { + blockchain: 'ZKSYNC', + symbol: 'ETH', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/zksync.png', + displayName: 'zkSync era', + shortName: 'zkSync', + sort: 13, + color: '#2D2925', + enabled: true, + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + type: 'EVM', + chainId: '0x144', + info: { + infoType: 'EvmMetaInfo', + chainName: 'zkSync', + nativeCurrency: { + name: 'ETH', + symbol: 'ETH', + decimals: 18, + }, + rpcUrls: ['https://mainnet.era.zksync.io'], + blockExplorerUrls: ['https://explorer.zksync.io'], + addressUrl: 'https://explorer.zksync.io/address/{wallet}', + transactionUrl: 'https://explorer.zksync.io/tx/{txHash}', + enableGasV2: true, + }, + }, + { + name: 'MOONBEAM', + defaultDecimals: 18, + addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], + feeAssets: [ + { + blockchain: 'MOONBEAM', + symbol: 'GLMR', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/moonbeam.png', + displayName: 'MoonBeam', + shortName: 'MoonBeam', + sort: 14, + color: '#B3206B', + enabled: true, + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + type: 'EVM', + chainId: '0x504', + info: { + infoType: 'EvmMetaInfo', + chainName: 'MoonBeam', + nativeCurrency: { + name: 'GLMR', + symbol: 'GLMR', + decimals: 18, + }, + rpcUrls: ['https://rpc.api.moonbeam.network'], + blockExplorerUrls: ['https://moonbeam.moonscan.io'], + addressUrl: 'https://moonbeam.moonscan.io/address/{wallet}', + transactionUrl: 'https://moonbeam.moonscan.io/tx/{txHash}', + enableGasV2: true, + }, + }, + { + name: 'POLKADOT', + defaultDecimals: 10, + addressPatterns: ['^(1)[0-9a-z-A-Z]{44,50}$'], + feeAssets: [], + logo: 'https://api.rango.exchange/blockchains/polkadot.svg', + displayName: 'Polkadot', + shortName: 'Polkadot', + sort: 14, + color: '#E6007A', + enabled: false, + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + type: 'TRANSFER', + chainId: null, + info: null, + }, + { + name: 'AURORA', + defaultDecimals: 18, + addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], + feeAssets: [ + { + blockchain: 'AURORA', + symbol: 'ETH', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/aurora.svg', + displayName: 'Aurora', + shortName: 'Aurora', + sort: 15, + color: '#78d64b', + enabled: true, + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + type: 'EVM', + chainId: '0x4e454152', + info: { + infoType: 'EvmMetaInfo', + chainName: 'Aurora Mainnet', + nativeCurrency: { + name: 'ETH', + symbol: 'ETH', + decimals: 18, + }, + rpcUrls: ['https://mainnet.aurora.dev'], + blockExplorerUrls: ['https://explorer.mainnet.aurora.dev'], + addressUrl: 'https://explorer.mainnet.aurora.dev/address/{wallet}', + transactionUrl: 'https://explorer.mainnet.aurora.dev/tx/{txHash}', + enableGasV2: true, + }, + }, + { + name: 'DOGE', + defaultDecimals: 8, + addressPatterns: ['^(D|A|9)[a-km-zA-HJ-NP-Z1-9]{33,34}$'], + feeAssets: [ + { + blockchain: 'DOGE', + symbol: 'DOGE', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/doge.svg', + displayName: 'Doge', + shortName: 'Doge', + sort: 15, + color: '#BA9F33', + enabled: false, + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + type: 'TRANSFER', + chainId: null, + info: null, + }, + { + name: 'HARMONY', + defaultDecimals: 18, + addressPatterns: ['^(one1)[0-9a-z]{38}$', '^(0x)[0-9A-Fa-f]{40}$'], + feeAssets: [ + { + blockchain: 'HARMONY', + symbol: 'ONE', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/harmony.svg', + displayName: 'Harmony', + shortName: 'Harmony', + sort: 15, + color: '#50AEE9', + enabled: true, + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + type: 'EVM', + chainId: '0x63564c40', + info: { + infoType: 'EvmMetaInfo', + chainName: 'Harmony Mainnet', + nativeCurrency: { + name: 'ONE', + symbol: 'ONE', + decimals: 18, + }, + rpcUrls: ['https://rpc.ankr.com/harmony'], + blockExplorerUrls: ['https://explorer.harmony.one'], + addressUrl: 'https://explorer.harmony.one/address/{wallet}', + transactionUrl: 'https://explorer.harmony.one/tx/{txHash}', + enableGasV2: true, + }, + }, + { + name: 'EVMOS', + defaultDecimals: 18, + addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], + feeAssets: [ + { + blockchain: 'EVMOS', + symbol: 'EVMOS', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/evmos.png', + displayName: 'Evmos', + shortName: 'Evmos', + sort: 15, + color: '#2D2925', + enabled: true, + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + type: 'EVM', + chainId: '0x2329', + info: { + infoType: 'EvmMetaInfo', + chainName: 'Evmos', + nativeCurrency: { + name: 'EVMOS', + symbol: 'EVMOS', + decimals: 18, + }, + rpcUrls: ['https://eth.bd.evmos.org:8545'], + blockExplorerUrls: ['https://evm.evmos.org'], + addressUrl: 'https://evm.evmos.org/address/{wallet}', + transactionUrl: 'https://evm.evmos.org/tx/{txHash}', + enableGasV2: true, + }, + }, + { + name: 'POLYGONZK', + defaultDecimals: 18, + addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], + feeAssets: [ + { + blockchain: 'POLYGONZK', + symbol: 'ETH', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/zkevmpolygon.png', + displayName: 'polygon zkEVM', + shortName: 'polygon zkEVM', + sort: 15, + color: '#8247e5', + enabled: true, + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + type: 'EVM', + chainId: '0x44d', + info: { + infoType: 'EvmMetaInfo', + chainName: 'Polygon zkEVM Mainnet', + nativeCurrency: { + name: 'ETH', + symbol: 'ETH', + decimals: 18, + }, + rpcUrls: ['https://zkevm-rpc.com'], + blockExplorerUrls: ['https://zkevm.polygonscan.com'], + addressUrl: 'https://zkevm.polygonscan.com/address/{wallet}', + transactionUrl: 'https://zkevm.polygonscan.com/tx/{txHash}', + enableGasV2: true, + }, + }, + { + name: 'HECO', + defaultDecimals: 18, + addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], + feeAssets: [ + { + blockchain: 'HECO', + symbol: 'HT', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/heco.png', + displayName: 'Heco', + shortName: 'Heco', + sort: 15, + color: '#4CA852', + enabled: true, + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + type: 'EVM', + chainId: '0x80', + info: { + infoType: 'EvmMetaInfo', + chainName: 'Huobi ECO Chain Mainnet', + nativeCurrency: { + name: 'HT', + symbol: 'HT', + decimals: 18, + }, + rpcUrls: ['https://http-mainnet.hecochain.com'], + blockExplorerUrls: ['https://hecoinfo.com'], + addressUrl: 'https://hecoinfo.com/address/{wallet}', + transactionUrl: 'https://hecoinfo.com/tx/{txHash}', + enableGasV2: true, + }, + }, + { + name: 'TRON', + defaultDecimals: 18, + addressPatterns: ['^T[1-9A-HJ-NP-Za-km-z]{33}$'], + feeAssets: [ + { + blockchain: 'TRON', + symbol: 'TRX', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/tron.svg', + displayName: 'Tron', + shortName: 'Tron', + sort: 16, + color: '#FF060A', + enabled: true, + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + type: 'TRON', + chainId: '0x2b6653dc', + info: { + infoType: 'EvmMetaInfo', + chainName: 'TRON Mainnet', + nativeCurrency: { + name: 'TRX', + symbol: 'TRX', + decimals: 6, + }, + rpcUrls: ['https://api.trongrid.io/jsonrpc'], + blockExplorerUrls: ['https://tronscan.org/#'], + addressUrl: 'https://tronscan.org/#/address/{wallet}', + transactionUrl: 'https://tronscan.org/#/tx/{txHash}', + enableGasV2: true, + }, + }, + { + name: 'SIF', + defaultDecimals: 18, + addressPatterns: ['^(sif1)[0-9a-z]{38}$'], + feeAssets: [ + { + blockchain: 'SIF', + symbol: 'ROWAN', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/sif.png', + displayName: 'Sifchain', + shortName: 'Sifchain', + sort: 16, + color: '#CAAA3A', + enabled: true, + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + type: 'COSMOS', + chainId: 'sifchain-1', + info: { + infoType: 'CosmosMetaInfo', + blockExplorerUrls: ['https://www.mintscan.io/cosmos/'], + addressUrl: 'https://www.mintscan.io/cosmos/account/{wallet}', + transactionUrl: 'https://www.mintscan.io/cosmos/txs/{txHash}', + experimental: false, + rpc: 'https://rpc.sifchain.finance', + rest: 'https://api-sifchain-ia.cosmosia.notional.ventures/', + cosmostationLcdUrl: 'https://lcd-sifchain.cosmostation.io', + cosmostationApiUrl: 'https://api.mintscan.io/v1/sifchain', + cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', + mintScanName: 'sifchain', + chainName: 'Sifchain', + stakeCurrency: { + coinDenom: 'ROWAN', + coinMinimalDenom: 'rowan', + coinDecimals: 18, + coinGeckoId: '', + coinImageUrl: '', + }, + bip44: { + coinType: 118, + }, + bech32Config: { + bech32PrefixAccAddr: 'sif', + bech32PrefixAccPub: 'sifpub', + bech32PrefixValAddr: 'sifvaloper', + bech32PrefixValPub: 'sifvaloperpub', + bech32PrefixConsAddr: 'sifvalcons', + bech32PrefixConsPub: 'sifvalconspub', + }, + currencies: [ + { + coinDenom: 'ROWAN', + coinMinimalDenom: 'rowan', + coinDecimals: 18, + coinGeckoId: '', + coinImageUrl: '', + }, + ], + feeCurrencies: [ + { + coinDenom: 'ROWAN', + coinMinimalDenom: 'rowan', + coinDecimals: 18, + coinGeckoId: '', + coinImageUrl: '', + }, + ], + features: ['stargate', 'ibc-transfer'], + explorerUrlToTx: 'https://www.mintscan.io/sifchain/txs/{txHash}', + gasPriceStep: { + low: 1000000000000, + average: 1500000000000, + high: 2000000000000, + }, + }, + }, + { + name: 'MAYA', + defaultDecimals: 8, + addressPatterns: ['^(maya1)[0-9a-z]{38}$'], + feeAssets: [ + { + blockchain: 'MAYA', + symbol: 'CACAO', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/maya.jpg', + displayName: 'MayaChain', + shortName: 'MayaChain', + sort: 17, + color: '#1ae6e6', + enabled: true, + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + type: 'TRANSFER', + chainId: null, + info: null, + }, + { + name: 'THOR', + defaultDecimals: 8, + addressPatterns: ['^(thor1)[0-9a-z]{38}$'], + feeAssets: [ + { + blockchain: 'THOR', + symbol: 'RUNE', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/thorchain.svg', + displayName: 'Thorchain', + shortName: 'Thorchain', + sort: 17, + color: '#1AE6CB', + enabled: true, + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + type: 'TRANSFER', + chainId: null, + info: null, + }, + { + name: 'BRISE', + defaultDecimals: 18, + addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], + feeAssets: [ + { + blockchain: 'BRISE', + symbol: 'BRISE', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/bitgert.png', + displayName: 'Brise', + shortName: 'Brise', + sort: 18, + color: '#0693E3', + enabled: true, + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + type: 'EVM', + chainId: '0x7f08', + info: { + infoType: 'EvmMetaInfo', + chainName: 'Brise', + nativeCurrency: { + name: 'BRISE', + symbol: 'BRISE', + decimals: 18, + }, + rpcUrls: ['https://rpc.icecreamswap.com'], + blockExplorerUrls: ['https://brisescan.com/'], + addressUrl: 'https://brisescan.com//address/{wallet}', + transactionUrl: 'https://brisescan.com//tx/{txHash}', + enableGasV2: true, + }, + }, + { + name: 'BNB', + defaultDecimals: 8, + addressPatterns: ['^(bnb1)[0-9a-z]{38}$'], + feeAssets: [ + { + blockchain: 'BNB', + symbol: 'BNB', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/bnb.svg', + displayName: 'Binance Chain', + shortName: 'BNB', + sort: 18, + color: '#F3BA2F', + enabled: true, + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + type: 'COSMOS', + chainId: null, + info: null, + }, + { + name: 'STARGAZE', + defaultDecimals: 6, + addressPatterns: ['^(stars1)[0-9a-z]{38}$'], + feeAssets: [ + { + blockchain: 'STARGAZE', + symbol: 'STARS', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/stargaze.png', + displayName: 'Stargaze', + shortName: 'Stargaze', + sort: 19, + color: '#231B60', + enabled: true, + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + type: 'COSMOS', + chainId: 'stargaze-1', + info: { + infoType: 'CosmosMetaInfo', + blockExplorerUrls: ['https://www.mintscan.io/cosmos/'], + addressUrl: 'https://www.mintscan.io/cosmos/account/{wallet}', + transactionUrl: 'https://www.mintscan.io/cosmos/txs/{txHash}', + experimental: false, + rpc: 'https://rpc.stargaze-apis.com', + rest: 'https://rest.stargaze-apis.com', + cosmostationLcdUrl: 'https://lcd-stargaze.cosmostation.io', + cosmostationApiUrl: 'https://api-stargaze.cosmostation.io', + cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', + mintScanName: 'stargaze', + chainName: 'Stargaze', + stakeCurrency: { + coinDenom: 'STARS', + coinMinimalDenom: 'ustars', + coinDecimals: 6, + coinGeckoId: 'pool:ustars', + coinImageUrl: '/tokens/blockchain/STARS.png', + }, + bip44: { + coinType: 118, + }, + bech32Config: { + bech32PrefixAccAddr: 'stars', + bech32PrefixAccPub: 'starspub', + bech32PrefixValAddr: 'starsvaloper', + bech32PrefixValPub: 'starsvaloperpub', + bech32PrefixConsAddr: 'starsvalcons', + bech32PrefixConsPub: 'starsvalconspub', + }, + currencies: [ + { + coinDenom: 'STARS', + coinMinimalDenom: 'ustars', + coinDecimals: 6, + coinGeckoId: 'pool:ustars', + coinImageUrl: '/tokens/blockchain/STARS.png', + }, + ], + feeCurrencies: [ + { + coinDenom: 'STARS', + coinMinimalDenom: 'ustars', + coinDecimals: 6, + coinGeckoId: 'pool:ustars', + coinImageUrl: '/tokens/blockchain/STARS.png', + }, + ], + features: ['stargate', 'ibc-transfer', 'no-legacy-stdTx'], + explorerUrlToTx: 'https://www.mintscan.io/stargaze/txs/{txHash}', + gasPriceStep: { + low: 1, + average: 1, + high: 1, + }, + }, + }, + { + name: 'BTC', + defaultDecimals: 8, + addressPatterns: [ + '^[13][a-km-zA-HJ-NP-Z1-9]{25,34}$|^(bc1)[0-9A-Za-z]{39,59}$', + ], + feeAssets: [ + { + blockchain: 'BTC', + symbol: 'BTC', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/btc.svg', + displayName: 'Bitcoin', + shortName: 'BTC', + sort: 20, + color: '#F7931A', + enabled: true, + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + type: 'TRANSFER', + chainId: null, + info: null, + }, + { + name: 'CRYPTO_ORG', + defaultDecimals: 8, + addressPatterns: ['^(cro1)[0-9a-z]{38}$'], + feeAssets: [ + { + blockchain: 'CRYPTO_ORG', + symbol: 'CRO', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/crypto_org.png', + displayName: 'Crypto.org', + shortName: 'Crypto.org', + sort: 21, + color: '#103F68', + enabled: true, + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + type: 'COSMOS', + chainId: 'crypto-org-chain-mainnet-1', + info: { + infoType: 'CosmosMetaInfo', + blockExplorerUrls: ['https://www.mintscan.io/cosmos/'], + addressUrl: 'https://www.mintscan.io/cosmos/account/{wallet}', + transactionUrl: 'https://www.mintscan.io/cosmos/txs/{txHash}', + experimental: false, + rpc: 'https://rpc-crypto-org.keplr.app', + rest: 'https://lcd-crypto-org.keplr.app', + cosmostationLcdUrl: 'https://lcd-cryptocom.cosmostation.io', + cosmostationApiUrl: 'https://api-cryptocom.cosmostation.io', + cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', + mintScanName: 'crypto-org', + chainName: 'Crypto.org', + stakeCurrency: { + coinDenom: 'CRO', + coinMinimalDenom: 'basecro', + coinDecimals: 8, + coinGeckoId: 'crypto-com-chain', + coinImageUrl: '/tokens/blockchain/cro.png', + }, + bip44: { + coinType: 394, + }, + bech32Config: { + bech32PrefixAccAddr: 'cro', + bech32PrefixAccPub: 'cropub', + bech32PrefixValAddr: 'crovaloper', + bech32PrefixValPub: 'crovaloperpub', + bech32PrefixConsAddr: 'crovalcons', + bech32PrefixConsPub: 'crovalconspub', + }, + currencies: [ + { + coinDenom: 'CRO', + coinMinimalDenom: 'basecro', + coinDecimals: 8, + coinGeckoId: 'crypto-com-chain', + coinImageUrl: '/tokens/blockchain/cro.png', + }, + ], + feeCurrencies: [ + { + coinDenom: 'CRO', + coinMinimalDenom: 'basecro', + coinDecimals: 8, + coinGeckoId: 'crypto-com-chain', + coinImageUrl: '/tokens/blockchain/cro.png', + }, + ], + features: ['stargate', 'ibc-transfer'], + explorerUrlToTx: 'https://www.mintscan.io/crypto-org/txs/{txHash}', + gasPriceStep: { + low: 0.025, + average: 0.03, + high: 0.04, + }, + }, + }, + { + name: 'CHIHUAHUA', + defaultDecimals: 6, + addressPatterns: ['^(chihuahua1)[0-9a-z]{38}$'], + feeAssets: [ + { + blockchain: 'CHIHUAHUA', + symbol: 'HUAHUA', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/chihuahua.png', + displayName: 'Chihuahua', + shortName: 'Chihuahua', + sort: 22, + color: '#EFC92B', + enabled: true, + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + type: 'COSMOS', + chainId: 'chihuahua-1', + info: { + infoType: 'CosmosMetaInfo', + blockExplorerUrls: ['https://www.mintscan.io/cosmos/'], + addressUrl: 'https://www.mintscan.io/cosmos/account/{wallet}', + transactionUrl: 'https://www.mintscan.io/cosmos/txs/{txHash}', + experimental: true, + rpc: 'https://rpc.chihuahua.wtf/', + rest: 'https://api.chihuahua.wtf/', + cosmostationLcdUrl: 'https://lcd-chihuahua.cosmostation.io', + cosmostationApiUrl: 'https://api-chihuahua.cosmostation.io', + cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', + mintScanName: 'chihuahua', + chainName: 'Chihuahua', + stakeCurrency: { + coinDenom: 'HUAHUA', + coinMinimalDenom: 'uhuahua', + coinDecimals: 6, + coinGeckoId: 'pool:uhuahua', + coinImageUrl: '/tokens/blockchain/HUAHUA.svg', + }, + bip44: { + coinType: 118, + }, + bech32Config: { + bech32PrefixAccAddr: 'chihuahua', + bech32PrefixAccPub: 'chihuahuapub', + bech32PrefixValAddr: 'chihuahuavaloper', + bech32PrefixValPub: 'chihuahuavaloperpub', + bech32PrefixConsAddr: 'chihuahuavalcons', + bech32PrefixConsPub: 'chihuahuavalconspub', + }, + currencies: [ + { + coinDenom: 'HUAHUA', + coinMinimalDenom: 'uhuahua', + coinDecimals: 6, + coinGeckoId: 'pool:uhuahua', + coinImageUrl: '/tokens/blockchain/HUAHUA.svg', + }, + ], + feeCurrencies: [ + { + coinDenom: 'HUAHUA', + coinMinimalDenom: 'uhuahua', + coinDecimals: 6, + coinGeckoId: 'pool:uhuahua', + coinImageUrl: '/tokens/blockchain/HUAHUA.svg', + }, + ], + features: ['stargate', 'ibc-transfer', 'no-legacy-stdTx'], + explorerUrlToTx: 'https://ping.pub/chihuahua/tx/{txHash}', + gasPriceStep: { + low: 0.025, + average: 0.03, + high: 0.035, + }, + }, + }, + { + name: 'BANDCHAIN', + defaultDecimals: 6, + addressPatterns: ['^(band1)[0-9a-z]{38}$'], + feeAssets: [ + { + blockchain: 'BANDCHAIN', + symbol: 'BAND', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/bandchain.svg', + displayName: 'BandChain', + shortName: 'BandChain', + sort: 23, + color: '#4520E6', + enabled: true, + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + type: 'COSMOS', + chainId: 'laozi-mainnet', + info: { + infoType: 'CosmosMetaInfo', + blockExplorerUrls: ['https://www.mintscan.io/cosmos/'], + addressUrl: 'https://www.mintscan.io/cosmos/account/{wallet}', + transactionUrl: 'https://www.mintscan.io/cosmos/txs/{txHash}', + experimental: true, + rpc: 'https://rpc.laozi3.bandchain.org/', + rest: 'https://lcd-band.cosmostation.io', + cosmostationLcdUrl: 'https://lcd-band.cosmostation.io', + cosmostationApiUrl: 'https://api-band.cosmostation.io', + cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', + mintScanName: 'band', + chainName: 'BandChain', + stakeCurrency: { + coinDenom: 'BAND', + coinMinimalDenom: 'uband', + coinDecimals: 6, + coinGeckoId: 'band-protocol', + coinImageUrl: '/tokens/blockchain/BAND.svg', + }, + bip44: { + coinType: 494, + }, + bech32Config: { + bech32PrefixAccAddr: 'band', + bech32PrefixAccPub: 'bandpub', + bech32PrefixValAddr: 'bandvaloper', + bech32PrefixValPub: 'bandvaloperpub', + bech32PrefixConsAddr: 'bandvalcons', + bech32PrefixConsPub: 'bandvalconspub', + }, + currencies: [ + { + coinDenom: 'BAND', + coinMinimalDenom: 'uband', + coinDecimals: 6, + coinGeckoId: 'band-protocol', + coinImageUrl: '/tokens/blockchain/BAND.svg', + }, + ], + feeCurrencies: [ + { + coinDenom: 'BAND', + coinMinimalDenom: 'uband', + coinDecimals: 6, + coinGeckoId: 'band-protocol', + coinImageUrl: '/tokens/blockchain/BAND.svg', + }, + ], + features: ['stargate', 'ibc-transfer', 'no-legacy-stdTx'], + explorerUrlToTx: 'https://cosmoscan.io/tx/{txHash}', + gasPriceStep: null, + }, + }, + { + name: 'COMDEX', + defaultDecimals: 6, + addressPatterns: ['^(comdex1)[0-9a-z]{38}$'], + feeAssets: [ + { + blockchain: 'COMDEX', + symbol: 'CMDX', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/comdex.svg', + displayName: 'Comdex', + shortName: 'Comdex', + sort: 23, + color: '#FE4350', + enabled: true, + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + type: 'COSMOS', + chainId: 'comdex-1', + info: { + infoType: 'CosmosMetaInfo', + blockExplorerUrls: ['https://www.mintscan.io/cosmos/'], + addressUrl: 'https://www.mintscan.io/cosmos/account/{wallet}', + transactionUrl: 'https://www.mintscan.io/cosmos/txs/{txHash}', + experimental: true, + rpc: 'https://rpc.comdex.one', + rest: 'https://rest.comdex.one', + cosmostationLcdUrl: 'https://lcd-comdex.cosmostation.io', + cosmostationApiUrl: 'https://api-comdex.cosmostation.io', + cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', + mintScanName: 'comdex', + chainName: 'Comdex', + stakeCurrency: { + coinDenom: 'CMDX', + coinMinimalDenom: 'ucmdx', + coinDecimals: 6, + coinGeckoId: 'comdex', + coinImageUrl: '/tokens/blockchain/CMDX.png', + }, + bip44: { + coinType: 118, + }, + bech32Config: { + bech32PrefixAccAddr: 'comdex', + bech32PrefixAccPub: 'comdexpub', + bech32PrefixValAddr: 'comdexvaloper', + bech32PrefixValPub: 'comdexvaloperpub', + bech32PrefixConsAddr: 'comdexvalcons', + bech32PrefixConsPub: 'comdexvalconspub', + }, + currencies: [ + { + coinDenom: 'CMDX', + coinMinimalDenom: 'ucmdx', + coinDecimals: 6, + coinGeckoId: 'comdex', + coinImageUrl: '/tokens/blockchain/CMDX.png', + }, + ], + feeCurrencies: [ + { + coinDenom: 'CMDX', + coinMinimalDenom: 'ucmdx', + coinDecimals: 6, + coinGeckoId: 'comdex', + coinImageUrl: '/tokens/blockchain/CMDX.png', + }, + ], + features: ['stargate', 'ibc-transfer', 'no-legacy-stdTx'], + explorerUrlToTx: 'https://www.mintscan.io/comdex/txs/{txHash}', + gasPriceStep: null, + }, + }, + { + name: 'REGEN', + defaultDecimals: 6, + addressPatterns: ['^(regen1)[0-9a-z]{38}$'], + feeAssets: [ + { + blockchain: 'REGEN', + symbol: 'REGEN', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/regen.png', + displayName: 'Regen Network', + shortName: 'Regen Network', + sort: 24, + color: '#4FB573', + enabled: true, + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + type: 'COSMOS', + chainId: 'regen-1', + info: { + infoType: 'CosmosMetaInfo', + blockExplorerUrls: ['https://www.mintscan.io/cosmos/'], + addressUrl: 'https://www.mintscan.io/cosmos/account/{wallet}', + transactionUrl: 'https://www.mintscan.io/cosmos/txs/{txHash}', + experimental: false, + rpc: 'https://rpc-regen.keplr.app', + rest: 'https://lcd-regen.keplr.app', + cosmostationLcdUrl: 'https://lcd-regen.keplr.app', + cosmostationApiUrl: 'https://api-regen.cosmostation.io/', + cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', + mintScanName: 'regen', + chainName: 'Regen Network', + stakeCurrency: { + coinDenom: 'REGEN', + coinMinimalDenom: 'uregen', + coinDecimals: 6, + coinGeckoId: 'pool:uregen', + coinImageUrl: '/tokens/blockchain/regen.png', + }, + bip44: { + coinType: 118, + }, + bech32Config: { + bech32PrefixAccAddr: 'regen', + bech32PrefixAccPub: 'regenpub', + bech32PrefixValAddr: 'regenvaloper', + bech32PrefixValPub: 'regenvaloperpub', + bech32PrefixConsAddr: 'regenvalcons', + bech32PrefixConsPub: 'regenvalconspub', + }, + currencies: [ + { + coinDenom: 'REGEN', + coinMinimalDenom: 'uregen', + coinDecimals: 6, + coinGeckoId: 'pool:uregen', + coinImageUrl: '/tokens/blockchain/regen.png', + }, + ], + feeCurrencies: [ + { + coinDenom: 'REGEN', + coinMinimalDenom: 'uregen', + coinDecimals: 6, + coinGeckoId: 'pool:uregen', + coinImageUrl: '/tokens/blockchain/regen.png', + }, + ], + features: ['stargate', 'ibc-transfer'], + explorerUrlToTx: 'https://regen.aneka.io/txs/{txHash}', + gasPriceStep: { + low: 0.015, + average: 0.025, + high: 0.04, + }, + }, + }, + { + name: 'IRIS', + defaultDecimals: 6, + addressPatterns: ['^(iaa1)[0-9a-z]{38}$'], + feeAssets: [ + { + blockchain: 'IRIS', + symbol: 'IRIS', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/iris.png', + displayName: 'IRISnet', + shortName: 'IRISnet', + sort: 25, + color: '#8A4A8E', + enabled: true, + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + type: 'COSMOS', + chainId: 'irishub-1', + info: { + infoType: 'CosmosMetaInfo', + blockExplorerUrls: ['https://www.mintscan.io/cosmos/'], + addressUrl: 'https://www.mintscan.io/cosmos/account/{wallet}', + transactionUrl: 'https://www.mintscan.io/cosmos/txs/{txHash}', + experimental: false, + rpc: 'https://rpc-iris.keplr.app', + rest: 'https://lcd-iris.keplr.app', + cosmostationLcdUrl: 'https://lcd-iris.cosmostation.io', + cosmostationApiUrl: 'https://api-iris.cosmostation.io', + cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', + mintScanName: 'iris', + chainName: 'IRISnet', + stakeCurrency: { + coinDenom: 'IRIS', + coinMinimalDenom: 'uiris', + coinDecimals: 6, + coinGeckoId: 'iris-network', + coinImageUrl: '/tokens/blockchain/iris.svg', + }, + bip44: { + coinType: 118, + }, + bech32Config: { + bech32PrefixAccAddr: 'iaa', + bech32PrefixAccPub: 'iaapub', + bech32PrefixValAddr: 'iaavaloper', + bech32PrefixValPub: 'iaavaloperpub', + bech32PrefixConsAddr: 'iaavalcons', + bech32PrefixConsPub: 'iaavalconspub', + }, + currencies: [ + { + coinDenom: 'IRIS', + coinMinimalDenom: 'uiris', + coinDecimals: 6, + coinGeckoId: 'iris-network', + coinImageUrl: '/tokens/blockchain/iris.svg', + }, + ], + feeCurrencies: [ + { + coinDenom: 'IRIS', + coinMinimalDenom: 'uiris', + coinDecimals: 6, + coinGeckoId: 'iris-network', + coinImageUrl: '/tokens/blockchain/iris.svg', + }, + ], + features: ['stargate', 'ibc-transfer'], + explorerUrlToTx: 'https://www.mintscan.io/iris/txs/{txHash}', + gasPriceStep: { + low: 0.2, + average: 0.3, + high: 0.4, + }, + }, + }, + { + name: 'EMONEY', + defaultDecimals: 6, + addressPatterns: ['^(emoney1)[0-9a-z]{38}$'], + feeAssets: [ + { + blockchain: 'EMONEY', + symbol: 'NGM', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/emoney.svg', + displayName: 'e-Money', + shortName: 'e-Money', + sort: 25, + color: '#DFF5EF', + enabled: true, + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + type: 'COSMOS', + chainId: 'emoney-3', + info: { + infoType: 'CosmosMetaInfo', + blockExplorerUrls: ['https://www.mintscan.io/cosmos/'], + addressUrl: 'https://www.mintscan.io/cosmos/account/{wallet}', + transactionUrl: 'https://www.mintscan.io/cosmos/txs/{txHash}', + experimental: true, + rpc: 'https://rpc-emoney.keplr.app', + rest: 'https://lcd-emoney.keplr.app', + cosmostationLcdUrl: 'https://lcd-emoney.cosmostation.io', + cosmostationApiUrl: 'https://api-emoney.cosmostation.io', + cosmostationDenomTracePath: + '/ibc/applications/transfer/v1beta1/denom_traces/', + mintScanName: 'emoney', + chainName: 'e-Money', + stakeCurrency: { + coinDenom: 'NGM', + coinMinimalDenom: 'ungm', + coinDecimals: 6, + coinGeckoId: 'e-money', + coinImageUrl: '/tokens/blockchain/NGM.png', + }, + bip44: { + coinType: 118, + }, + bech32Config: { + bech32PrefixAccAddr: 'emoney', + bech32PrefixAccPub: 'emoneypub', + bech32PrefixValAddr: 'emoneyvaloper', + bech32PrefixValPub: 'emoneyvaloperpub', + bech32PrefixConsAddr: 'emoneyvalcons', + bech32PrefixConsPub: 'emoneyvalconspub', + }, + currencies: [ + { + coinDenom: 'NGM', + coinMinimalDenom: 'ungm', + coinDecimals: 6, + coinGeckoId: 'e-money', + coinImageUrl: '/tokens/blockchain/NGM.png', + }, + { + coinDenom: 'EEUR', + coinMinimalDenom: 'eeur', + coinDecimals: 6, + coinGeckoId: 'e-money-eur', + coinImageUrl: '/tokens/blockchain/EEUR.png', + }, + ], + feeCurrencies: [ + { + coinDenom: 'NGM', + coinMinimalDenom: 'ungm', + coinDecimals: 6, + coinGeckoId: 'e-money', + coinImageUrl: '/tokens/blockchain/NGM.png', + }, + ], + features: ['stargate', 'ibc-transfer'], + explorerUrlToTx: 'https://emoney.bigdipper.live/transactions/{txHash}', + gasPriceStep: { + low: 1, + average: 1, + high: 1, + }, + }, + }, + { + name: 'GNOSIS', + defaultDecimals: 18, + addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], + feeAssets: [ + { + blockchain: 'GNOSIS', + symbol: 'XDAI', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/gnosis.svg', + displayName: 'Gnosis', + shortName: 'Gnosis', + sort: 26, + color: '#3E6957', + enabled: true, + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + type: 'EVM', + chainId: '0x64', + info: { + infoType: 'EvmMetaInfo', + chainName: 'Gnosis Chain', + nativeCurrency: { + name: 'XDAI', + symbol: 'XDAI', + decimals: 18, + }, + rpcUrls: ['https://rpc.gnosischain.com'], + blockExplorerUrls: ['https://blockscout.com/xdai/mainnet'], + addressUrl: 'https://blockscout.com/xdai/mainnet/address/{wallet}', + transactionUrl: 'https://blockscout.com/xdai/mainnet/tx/{txHash}', + enableGasV2: true, + }, + }, + { + name: 'LTC', + defaultDecimals: 8, + addressPatterns: ['^(L|M|3)[A-Za-z0-9]{33}$|^(ltc1)[0-9A-Za-z]{39}$'], + feeAssets: [ + { + blockchain: 'LTC', + symbol: 'LTC', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/ltc.svg', + displayName: 'LiteCoin', + shortName: 'LTC', + sort: 27, + color: '#345D9D', + enabled: true, + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + type: 'TRANSFER', + chainId: null, + info: null, + }, + { + name: 'BCH', + defaultDecimals: 8, + addressPatterns: ['^[13][a-km-zA-HJ-NP-Z1-9]{25,34}$|^[0-9A-Za-z]{42,42}$'], + feeAssets: [ + { + blockchain: 'BCH', + symbol: 'BCH', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/bch.svg', + displayName: 'Bitcoin Cash', + shortName: 'BCH', + sort: 28, + color: '#0AC18E', + enabled: true, + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + type: 'TRANSFER', + chainId: null, + info: null, + }, + { + name: 'FUSE', + defaultDecimals: 18, + addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], + feeAssets: [ + { + blockchain: 'FUSE', + symbol: 'FUSE', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/fuse.png', + displayName: 'Fuse', + shortName: 'Fuse', + sort: 29, + color: '#C5F9AD', + enabled: true, + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + type: 'EVM', + chainId: '0x7a', + info: { + infoType: 'EvmMetaInfo', + chainName: 'Fuse Mainnet', + nativeCurrency: { + name: 'FUSE', + symbol: 'FUSE', + decimals: 18, + }, + rpcUrls: ['https://rpc.fuse.io'], + blockExplorerUrls: ['https://explorer.fuse.io'], + addressUrl: 'https://explorer.fuse.io/address/{wallet}', + transactionUrl: 'https://explorer.fuse.io/tx/{txHash}', + enableGasV2: true, + }, + }, + { + name: 'BITSONG', + defaultDecimals: 6, + addressPatterns: ['^(bitsong1)[0-9a-z]{38}$'], + feeAssets: [ + { + blockchain: 'BITSONG', + symbol: 'BTSG', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/bitsong.svg', + displayName: 'BitSong', + shortName: 'BitSong', + sort: 29, + color: '#FF005C', + enabled: true, + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + type: 'COSMOS', + chainId: 'bitsong-2b', + info: { + infoType: 'CosmosMetaInfo', + blockExplorerUrls: ['https://www.mintscan.io/cosmos/'], + addressUrl: 'https://www.mintscan.io/cosmos/account/{wallet}', + transactionUrl: 'https://www.mintscan.io/cosmos/txs/{txHash}', + experimental: true, + rpc: 'https://rpc.explorebitsong.com', + rest: 'https://lcd.explorebitsong.com', + cosmostationLcdUrl: 'https://lcd-bitsong.cosmostation.io', + cosmostationApiUrl: 'https://api-bitsong.cosmostation.io', + cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', + mintScanName: 'bitsong', + chainName: 'BitSong', + stakeCurrency: { + coinDenom: 'BTSG', + coinMinimalDenom: 'ubtsg', + coinDecimals: 6, + coinGeckoId: 'pool:ubtsg', + coinImageUrl: '/tokens/blockchain/BTSG.png', + }, + bip44: { + coinType: 639, + }, + bech32Config: { + bech32PrefixAccAddr: 'bitsong', + bech32PrefixAccPub: 'bitsongpub', + bech32PrefixValAddr: 'bitsongvaloper', + bech32PrefixValPub: 'bitsongvaloperpub', + bech32PrefixConsAddr: 'bitsongvalcons', + bech32PrefixConsPub: 'bitsongvalconspub', + }, + currencies: [ + { + coinDenom: 'BTSG', + coinMinimalDenom: 'ubtsg', + coinDecimals: 6, + coinGeckoId: 'pool:ubtsg', + coinImageUrl: '/tokens/blockchain/BTSG.png', + }, + ], + feeCurrencies: [ + { + coinDenom: 'BTSG', + coinMinimalDenom: 'ubtsg', + coinDecimals: 6, + coinGeckoId: 'pool:ubtsg', + coinImageUrl: '/tokens/blockchain/BTSG.png', + }, + ], + features: ['stargate', 'ibc-transfer', 'no-legacy-stdTx', 'ibc-go'], + explorerUrlToTx: 'https://explorebitsong.com/transactions/{txHash}', + gasPriceStep: null, + }, + }, + { + name: 'AKASH', + defaultDecimals: 6, + addressPatterns: ['^(akash1)[0-9a-z]{38}$'], + feeAssets: [ + { + blockchain: 'AKASH', + symbol: 'AKT', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/akash.svg', + displayName: 'Akash', + shortName: 'Akash', + sort: 30, + color: '#ED3524', + enabled: true, + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + type: 'COSMOS', + chainId: 'akashnet-2', + info: { + infoType: 'CosmosMetaInfo', + blockExplorerUrls: ['https://www.mintscan.io/cosmos/'], + addressUrl: 'https://www.mintscan.io/cosmos/account/{wallet}', + transactionUrl: 'https://www.mintscan.io/cosmos/txs/{txHash}', + experimental: false, + rpc: 'https://rpc-akash.keplr.app', + rest: 'https://lcd-akash.keplr.app', + cosmostationLcdUrl: 'https://lcd-akash.cosmostation.io', + cosmostationApiUrl: 'https://api-akash.cosmostation.io', + cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', + mintScanName: 'akash', + chainName: 'Akash', + stakeCurrency: { + coinDenom: 'AKT', + coinMinimalDenom: 'uakt', + coinDecimals: 6, + coinGeckoId: 'akash-network', + coinImageUrl: '/tokens/blockchain/akt.svg', + }, + bip44: { + coinType: 118, + }, + bech32Config: { + bech32PrefixAccAddr: 'akash', + bech32PrefixAccPub: 'akashpub', + bech32PrefixValAddr: 'akashvaloper', + bech32PrefixValPub: 'akashvaloperpub', + bech32PrefixConsAddr: 'akashvalcons', + bech32PrefixConsPub: 'akashvalconspub', + }, + currencies: [ + { + coinDenom: 'AKT', + coinMinimalDenom: 'uakt', + coinDecimals: 6, + coinGeckoId: 'akash-network', + coinImageUrl: '/tokens/blockchain/akt.svg', + }, + ], + feeCurrencies: [ + { + coinDenom: 'AKT', + coinMinimalDenom: 'uakt', + coinDecimals: 6, + coinGeckoId: 'akash-network', + coinImageUrl: '/tokens/blockchain/akt.svg', + }, + ], + features: ['stargate', 'ibc-transfer'], + explorerUrlToTx: 'https://www.mintscan.io/akash/txs/{txHash}', + gasPriceStep: { + low: 0.001, + average: 0.0025, + high: 0.004, + }, + }, + }, + { + name: 'KI', + defaultDecimals: 6, + addressPatterns: ['^(ki1)[0-9a-z]{38}$'], + feeAssets: [ + { + blockchain: 'KI', + symbol: 'XKI', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/ki.png', + displayName: 'Ki', + shortName: 'Ki', + sort: 30, + color: '#0F2B3D', + enabled: true, + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + type: 'COSMOS', + chainId: 'kichain-2', + info: { + infoType: 'CosmosMetaInfo', + blockExplorerUrls: ['https://www.mintscan.io/cosmos/'], + addressUrl: 'https://www.mintscan.io/cosmos/account/{wallet}', + transactionUrl: 'https://www.mintscan.io/cosmos/txs/{txHash}', + experimental: true, + rpc: 'https://rpc-mainnet.blockchain.ki', + rest: 'https://api-mainnet.blockchain.ki', + cosmostationLcdUrl: 'https://lcd-kichain.cosmostation.io', + cosmostationApiUrl: 'https://api-kichain.cosmostation.io', + cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', + mintScanName: 'ki-chain', + chainName: 'Ki', + stakeCurrency: { + coinDenom: 'XKI', + coinMinimalDenom: 'uxki', + coinDecimals: 6, + coinGeckoId: 'pool:uxki', + coinImageUrl: '/tokens/blockchain/XKI.png', + }, + bip44: { + coinType: 118, + }, + bech32Config: { + bech32PrefixAccAddr: 'ki', + bech32PrefixAccPub: 'kipub', + bech32PrefixValAddr: 'kivaloper', + bech32PrefixValPub: 'kivaloperpub', + bech32PrefixConsAddr: 'kivalcons', + bech32PrefixConsPub: 'kivalconspub', + }, + currencies: [ + { + coinDenom: 'XKI', + coinMinimalDenom: 'uxki', + coinDecimals: 6, + coinGeckoId: 'pool:uxki', + coinImageUrl: '/tokens/blockchain/XKI.png', + }, + ], + feeCurrencies: [ + { + coinDenom: 'XKI', + coinMinimalDenom: 'uxki', + coinDecimals: 6, + coinGeckoId: 'pool:uxki', + coinImageUrl: '/tokens/blockchain/XKI.png', + }, + ], + features: ['stargate', 'ibc-transfer'], + explorerUrlToTx: 'https://www.mintscan.io/ki-chain/txs/{txHash}', + gasPriceStep: null, + }, + }, + { + name: 'PERSISTENCE', + defaultDecimals: 6, + addressPatterns: ['^(persistence1)[0-9a-z]{38}$'], + feeAssets: [ + { + blockchain: 'PERSISTENCE', + symbol: 'XPRT', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/persistence.png', + displayName: 'Persistence', + shortName: 'Persistence', + sort: 31, + color: '#383838', + enabled: true, + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + type: 'COSMOS', + chainId: 'core-1', + info: { + infoType: 'CosmosMetaInfo', + blockExplorerUrls: ['https://www.mintscan.io/cosmos/'], + addressUrl: 'https://www.mintscan.io/cosmos/account/{wallet}', + transactionUrl: 'https://www.mintscan.io/cosmos/txs/{txHash}', + experimental: false, + rpc: 'https://rpc-persistence.keplr.app', + rest: 'https://lcd-persistence.keplr.app', + cosmostationLcdUrl: 'https://lcd-persistence.cosmostation.io', + cosmostationApiUrl: 'https://api-persistence.cosmostation.io', + cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', + mintScanName: 'persistence', + chainName: 'Persistence', + stakeCurrency: { + coinDenom: 'XPRT', + coinMinimalDenom: 'uxprt', + coinDecimals: 6, + coinGeckoId: 'persistence', + coinImageUrl: '/tokens/blockchain/xprt.png', + }, + bip44: { + coinType: 750, + }, + bech32Config: { + bech32PrefixAccAddr: 'persistence', + bech32PrefixAccPub: 'persistencepub', + bech32PrefixValAddr: 'persistencevaloper', + bech32PrefixValPub: 'persistencevaloperpub', + bech32PrefixConsAddr: 'persistencevalcons', + bech32PrefixConsPub: 'persistencevalconspub', + }, + currencies: [ + { + coinDenom: 'XPRT', + coinMinimalDenom: 'uxprt', + coinDecimals: 6, + coinGeckoId: 'persistence', + coinImageUrl: '/tokens/blockchain/xprt.png', + }, + ], + feeCurrencies: [ + { + coinDenom: 'XPRT', + coinMinimalDenom: 'uxprt', + coinDecimals: 6, + coinGeckoId: 'persistence', + coinImageUrl: '/tokens/blockchain/xprt.png', + }, + ], + features: ['stargate', 'ibc-transfer'], + explorerUrlToTx: 'https://www.mintscan.io/persistence/txs/{txHash}', + gasPriceStep: { + low: 0, + average: 0.025, + high: 0.04, + }, + }, + }, + { + name: 'MEDIBLOC', + defaultDecimals: 6, + addressPatterns: ['^(panacea1)[0-9a-z]{38}$'], + feeAssets: [ + { + blockchain: 'MEDIBLOC', + symbol: 'MED', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/medibloc.png', + displayName: 'MediBloc', + shortName: 'MediBloc', + sort: 31, + color: '#4B66DC', + enabled: true, + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + type: 'COSMOS', + chainId: 'panacea-3', + info: { + infoType: 'CosmosMetaInfo', + blockExplorerUrls: ['https://www.mintscan.io/cosmos/'], + addressUrl: 'https://www.mintscan.io/cosmos/account/{wallet}', + transactionUrl: 'https://www.mintscan.io/cosmos/txs/{txHash}', + experimental: true, + rpc: 'https://rpc.gopanacea.org', + rest: 'https://api.gopanacea.org', + cosmostationLcdUrl: 'https://lcd-medibloc.cosmostation.io', + cosmostationApiUrl: 'https://api-medibloc.cosmostation.io', + cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', + mintScanName: 'medibloc', + chainName: 'MediBloc', + stakeCurrency: { + coinDenom: 'MED', + coinMinimalDenom: 'umed', + coinDecimals: 6, + coinGeckoId: 'medibloc', + coinImageUrl: '/tokens/blockchain/MED.png', + }, + bip44: { + coinType: 118, + }, + bech32Config: { + bech32PrefixAccAddr: 'panacea', + bech32PrefixAccPub: 'panaceapub', + bech32PrefixValAddr: 'panaceavaloper', + bech32PrefixValPub: 'panaceavaloperpub', + bech32PrefixConsAddr: 'panaceavalcons', + bech32PrefixConsPub: 'panaceavalconspub', + }, + currencies: [ + { + coinDenom: 'MED', + coinMinimalDenom: 'umed', + coinDecimals: 6, + coinGeckoId: 'medibloc', + coinImageUrl: '/tokens/blockchain/MED.png', + }, + ], + feeCurrencies: [ + { + coinDenom: 'MED', + coinMinimalDenom: 'umed', + coinDecimals: 6, + coinGeckoId: 'medibloc', + coinImageUrl: '/tokens/blockchain/MED.png', + }, + ], + features: ['stargate', 'ibc-transfer'], + explorerUrlToTx: 'https://www.mintscan.io/medibloc/txs/{txHash}', + gasPriceStep: { + low: 5, + average: 7, + high: 9, + }, + }, + }, + { + name: 'KUJIRA', + defaultDecimals: 6, + addressPatterns: ['^(kujira1)[0-9a-z]{38}$'], + feeAssets: [ + { + blockchain: 'KUJIRA', + symbol: 'KUJI', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/kuji.svg', + displayName: 'Kujira', + shortName: 'Kujira', + sort: 31, + color: '#DF3935', + enabled: true, + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + type: 'COSMOS', + chainId: 'kaiyo-1', + info: { + infoType: 'CosmosMetaInfo', + blockExplorerUrls: ['https://www.mintscan.io/cosmos/'], + addressUrl: 'https://www.mintscan.io/cosmos/account/{wallet}', + transactionUrl: 'https://www.mintscan.io/cosmos/txs/{txHash}', + experimental: true, + rpc: 'https://kujira-rpc.lavenderfive.com', + rest: 'https://kujira-api.lavenderfive.com', + cosmostationLcdUrl: 'https://lcd-kujira.cosmostation.io', + cosmostationApiUrl: 'https://api-kujira.cosmostation.io', + cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', + mintScanName: 'kujira', + chainName: 'Kujira', + stakeCurrency: { + coinDenom: 'KUJI', + coinMinimalDenom: 'ukuji', + coinDecimals: 6, + coinGeckoId: 'kujira', + coinImageUrl: '/tokens/blockchain/kuji.svg', + }, + bip44: { + coinType: 118, + }, + bech32Config: { + bech32PrefixAccAddr: 'kujira', + bech32PrefixAccPub: 'kujirapub', + bech32PrefixValAddr: 'kujiravaloper', + bech32PrefixValPub: 'kujiravaloperpub', + bech32PrefixConsAddr: 'kujiravalcons', + bech32PrefixConsPub: 'kujiravalconspub', + }, + currencies: [ + { + coinDenom: 'KUJI', + coinMinimalDenom: 'ukuji', + coinDecimals: 6, + coinGeckoId: 'kujira', + coinImageUrl: '/tokens/blockchain/kuji.png', + }, + ], + feeCurrencies: [ + { + coinDenom: 'KUJI', + coinMinimalDenom: 'ukuji', + coinDecimals: 6, + coinGeckoId: 'kujira', + coinImageUrl: '/tokens/blockchain/kuji.png', + }, + ], + features: ['stargate', 'ibc-transfer'], + explorerUrlToTx: 'https://finder.kujira.app/kaiyo-1/tx/{txHash}', + gasPriceStep: { + low: 0.01, + average: 0.025, + high: 0.03, + }, + }, + }, + { + name: 'SENTINEL', + defaultDecimals: 6, + addressPatterns: ['^(sent1)[0-9a-z]{38}$'], + feeAssets: [ + { + blockchain: 'SENTINEL', + symbol: 'DVPN', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/sentinel.png', + displayName: 'Sentinel', + shortName: 'Sentinel', + sort: 32, + color: '#142E51', + enabled: true, + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + type: 'COSMOS', + chainId: 'sentinelhub-2', + info: { + infoType: 'CosmosMetaInfo', + blockExplorerUrls: ['https://www.mintscan.io/cosmos/'], + addressUrl: 'https://www.mintscan.io/cosmos/account/{wallet}', + transactionUrl: 'https://www.mintscan.io/cosmos/txs/{txHash}', + experimental: false, + rpc: 'https://rpc-sentinel.keplr.app', + rest: 'https://lcd-sentinel.keplr.app', + cosmostationLcdUrl: 'https://lcd-sentinel.cosmostation.io', + cosmostationApiUrl: 'https://api-sentinel.cosmostation.io', + cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', + mintScanName: 'sentinel', + chainName: 'Sentinel', + stakeCurrency: { + coinDenom: 'DVPN', + coinMinimalDenom: 'udvpn', + coinDecimals: 6, + coinGeckoId: 'sentinel', + coinImageUrl: '/tokens/blockchain/dvpn.png', + }, + bip44: { + coinType: 118, + }, + bech32Config: { + bech32PrefixAccAddr: 'sent', + bech32PrefixAccPub: 'sentpub', + bech32PrefixValAddr: 'sentvaloper', + bech32PrefixValPub: 'sentvaloperpub', + bech32PrefixConsAddr: 'sentvalcons', + bech32PrefixConsPub: 'sentvalconspub', + }, + currencies: [ + { + coinDenom: 'DVPN', + coinMinimalDenom: 'udvpn', + coinDecimals: 6, + coinGeckoId: 'sentinel', + coinImageUrl: '/tokens/blockchain/dvpn.png', + }, + ], + feeCurrencies: [ + { + coinDenom: 'DVPN', + coinMinimalDenom: 'udvpn', + coinDecimals: 6, + coinGeckoId: 'sentinel', + coinImageUrl: '/tokens/blockchain/dvpn.png', + }, + ], + features: ['stargate', 'ibc-transfer'], + explorerUrlToTx: 'https://www.mintscan.io/sentinel/txs/{txHash}', + gasPriceStep: { + low: 0.1, + average: 0.25, + high: 0.4, + }, + }, + }, + { + name: 'INJECTIVE', + defaultDecimals: 6, + addressPatterns: ['^(inj1)[0-9a-z]{38}$'], + feeAssets: [ + { + blockchain: 'INJECTIVE', + symbol: 'INJ', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/injective.svg', + displayName: 'Injective', + shortName: 'Injective', + sort: 33, + color: '#29B2F4', + enabled: true, + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + type: 'COSMOS', + chainId: 'injective-1', + info: { + infoType: 'CosmosMetaInfo', + blockExplorerUrls: ['https://www.mintscan.io/cosmos/'], + addressUrl: 'https://www.mintscan.io/cosmos/account/{wallet}', + transactionUrl: 'https://www.mintscan.io/cosmos/txs/{txHash}', + experimental: true, + rpc: 'https://tm.injective.network', + rest: 'https://lcd.injective.network', + cosmostationLcdUrl: 'https://lcd-inj.cosmostation.io', + cosmostationApiUrl: 'https://api-inj.cosmostation.io', + cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', + mintScanName: 'injective', + chainName: 'Injective', + stakeCurrency: { + coinDenom: 'INJ', + coinMinimalDenom: 'uinj', + coinDecimals: 18, + coinGeckoId: 'injective', + coinImageUrl: '/tokens/INJECTIVE/inj.svg', + }, + bip44: { + coinType: 529, + }, + bech32Config: { + bech32PrefixAccAddr: 'inj', + bech32PrefixAccPub: 'injpub', + bech32PrefixValAddr: 'injvaloper', + bech32PrefixValPub: 'injvaloperpub', + bech32PrefixConsAddr: 'injvalcons', + bech32PrefixConsPub: 'injvalconspub', + }, + currencies: [ + { + coinDenom: 'INJ', + coinMinimalDenom: 'uinj', + coinDecimals: 18, + coinGeckoId: 'injective', + coinImageUrl: '/tokens/INJECTIVE/inj.svg', + }, + ], + feeCurrencies: [ + { + coinDenom: 'INJ', + coinMinimalDenom: 'uinj', + coinDecimals: 18, + coinGeckoId: 'injective', + coinImageUrl: '/tokens/INJECTIVE/inj.svg', + }, + ], + features: ['stargate', 'ibc-transfer'], + explorerUrlToTx: 'https://www.mintscan.io/injective/txs/{txHash}', + gasPriceStep: { + low: 500000000, + average: 500000000, + high: 500000000, + }, + }, + }, + { + name: 'SECRET', + defaultDecimals: 6, + addressPatterns: ['^(secret1)[0-9a-z]{38}$'], + feeAssets: [ + { + blockchain: 'SECRET', + symbol: 'SCRT', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/secret.svg', + displayName: 'Secret', + shortName: 'Secret', + sort: 34, + color: '#1B1B1B', + enabled: true, + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + type: 'COSMOS', + chainId: 'secret-4', + info: { + infoType: 'CosmosMetaInfo', + blockExplorerUrls: ['https://www.mintscan.io/cosmos/'], + addressUrl: 'https://www.mintscan.io/cosmos/account/{wallet}', + transactionUrl: 'https://www.mintscan.io/cosmos/txs/{txHash}', + experimental: false, + rpc: 'https://rpc-secret.keplr.app', + rest: 'https://lcd-secret.keplr.app', + cosmostationLcdUrl: 'https://lcd-secret.cosmostation.io', + cosmostationApiUrl: 'https://api-secret.cosmostation.io', + cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', + mintScanName: 'secret', + chainName: 'Secret', + stakeCurrency: { + coinDenom: 'SCRT', + coinMinimalDenom: 'uscrt', + coinDecimals: 6, + coinGeckoId: 'secret', + coinImageUrl: 'https://dhj8dql1kzq2v.cloudfront.net/white/secret.png', + }, + bip44: { + coinType: 529, + }, + bech32Config: { + bech32PrefixAccAddr: 'secret', + bech32PrefixAccPub: 'secretpub', + bech32PrefixValAddr: 'secretvaloper', + bech32PrefixValPub: 'secretvaloperpub', + bech32PrefixConsAddr: 'secretvalcons', + bech32PrefixConsPub: 'secretvalconspub', + }, + currencies: [ + { + coinDenom: 'SCRT', + coinMinimalDenom: 'uscrt', + coinDecimals: 6, + coinGeckoId: 'secret', + coinImageUrl: 'https://dhj8dql1kzq2v.cloudfront.net/white/secret.png', + }, + ], + feeCurrencies: [ + { + coinDenom: 'SCRT', + coinMinimalDenom: 'uscrt', + coinDecimals: 6, + coinGeckoId: 'secret', + coinImageUrl: 'https://dhj8dql1kzq2v.cloudfront.net/white/secret.png', + }, + ], + features: ['secretwasm'], + explorerUrlToTx: 'https://www.mintscan.io/injective/txs/{txHash}', + gasPriceStep: { + low: 0.1, + average: 0.25, + high: 0.3, + }, + }, + }, + { + name: 'KONSTELLATION', + defaultDecimals: 6, + addressPatterns: ['^(darc1)[0-9a-z]{38}$'], + feeAssets: [ + { + blockchain: 'KONSTELLATION', + symbol: 'DARC', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/konstellation.svg', + displayName: 'Konstellation', + shortName: 'Konstellation', + sort: 35, + color: '#3D7BC2', + enabled: true, + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + type: 'COSMOS', + chainId: 'darchub', + info: { + infoType: 'CosmosMetaInfo', + blockExplorerUrls: ['https://www.mintscan.io/cosmos/'], + addressUrl: 'https://www.mintscan.io/cosmos/account/{wallet}', + transactionUrl: 'https://www.mintscan.io/cosmos/txs/{txHash}', + experimental: true, + rpc: 'https://node1.konstellation.tech:26657', + rest: 'https://node1.konstellation.tech:1318', + cosmostationLcdUrl: 'https://api-konstellation.cosmostation.io', + cosmostationApiUrl: 'https://api-konstellation.cosmostation.io', + cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', + mintScanName: 'konstellation', + chainName: 'Konstellation', + stakeCurrency: { + coinDenom: 'DARC', + coinMinimalDenom: 'udarc', + coinDecimals: 6, + coinGeckoId: 'pool:udarc', + coinImageUrl: '/tokens/blockchain/DARC.png', + }, + bip44: { + coinType: 118, + }, + bech32Config: { + bech32PrefixAccAddr: 'darc', + bech32PrefixAccPub: 'darcpub', + bech32PrefixValAddr: 'darcvaloper', + bech32PrefixValPub: 'darcvaloperpub', + bech32PrefixConsAddr: 'darcvalcons', + bech32PrefixConsPub: 'darcvalconspub', + }, + currencies: [ + { + coinDenom: 'DARC', + coinMinimalDenom: 'udarc', + coinDecimals: 6, + coinGeckoId: 'pool:udarc', + coinImageUrl: '/tokens/blockchain/DARC.png', + }, + ], + feeCurrencies: [ + { + coinDenom: 'DARC', + coinMinimalDenom: 'udarc', + coinDecimals: 6, + coinGeckoId: 'pool:udarc', + coinImageUrl: '/tokens/blockchain/DARC.png', + }, + ], + features: ['stargate', 'ibc-transfer', 'no-legacy-stdTx'], + explorerUrlToTx: 'https://www.mintscan.io/konstellation/txs/{txHash}', + gasPriceStep: null, + }, + }, + { + name: 'STARNAME', + defaultDecimals: 6, + addressPatterns: ['^(star1)[0-9a-z]{38}$'], + feeAssets: [ + { + blockchain: 'STARNAME', + symbol: 'IOV', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/starname.png', + displayName: 'Starname', + shortName: 'Starname', + sort: 35, + color: '#BC64BB', + enabled: true, + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + type: 'COSMOS', + chainId: 'iov-mainnet-ibc', + info: { + infoType: 'CosmosMetaInfo', + blockExplorerUrls: ['https://www.mintscan.io/cosmos/'], + addressUrl: 'https://www.mintscan.io/cosmos/account/{wallet}', + transactionUrl: 'https://www.mintscan.io/cosmos/txs/{txHash}', + experimental: false, + rpc: 'https://rpc-iov.keplr.app', + rest: 'https://lcd-iov.keplr.app', + cosmostationLcdUrl: 'https://lcd-iov.cosmostation.io', + cosmostationApiUrl: 'https://api-iov.cosmostation.io', + cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', + mintScanName: 'starname', + chainName: 'Starname', + stakeCurrency: { + coinDenom: 'IOV', + coinMinimalDenom: 'uiov', + coinDecimals: 6, + coinGeckoId: 'starname', + coinImageUrl: '/tokens/blockchain/IOV.png', + }, + bip44: { + coinType: 494, + }, + bech32Config: { + bech32PrefixAccAddr: 'star', + bech32PrefixAccPub: 'starpub', + bech32PrefixValAddr: 'starvaloper', + bech32PrefixValPub: 'starvaloperpub', + bech32PrefixConsAddr: 'starvalcons', + bech32PrefixConsPub: 'starvalconspub', + }, + currencies: [ + { + coinDenom: 'IOV', + coinMinimalDenom: 'uiov', + coinDecimals: 6, + coinGeckoId: 'starname', + coinImageUrl: '/tokens/blockchain/IOV.png', + }, + ], + feeCurrencies: [ + { + coinDenom: 'IOV', + coinMinimalDenom: 'uiov', + coinDecimals: 6, + coinGeckoId: 'starname', + coinImageUrl: '/tokens/blockchain/IOV.png', + }, + ], + features: ['stargate', 'ibc-transfer'], + explorerUrlToTx: 'https://www.mintscan.io/starname/txs/{txHash}', + gasPriceStep: { + low: 1, + average: 2, + high: 3, + }, + }, + }, + { + name: 'BITCANNA', + defaultDecimals: 6, + addressPatterns: ['^(bcna1)[0-9a-z]{38}$'], + feeAssets: [ + { + blockchain: 'BITCANNA', + symbol: 'BCNA', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/bitcanna.svg', + displayName: 'BitCanna', + shortName: 'BitCanna', + sort: 36, + color: '#3CC194', + enabled: true, + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + type: 'COSMOS', + chainId: 'bitcanna-1', + info: { + infoType: 'CosmosMetaInfo', + blockExplorerUrls: ['https://www.mintscan.io/cosmos/'], + addressUrl: 'https://www.mintscan.io/cosmos/account/{wallet}', + transactionUrl: 'https://www.mintscan.io/cosmos/txs/{txHash}', + experimental: true, + rpc: 'https://rpc.bitcanna.io', + rest: 'https://lcd.bitcanna.io', + cosmostationLcdUrl: 'https://lcd-bitcanna.cosmostation.io', + cosmostationApiUrl: 'https://api-bitcanna.cosmostation.io', + cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', + mintScanName: 'bitcanna', + chainName: 'BitCanna', + stakeCurrency: { + coinDenom: 'BCNA', + coinMinimalDenom: 'ubcna', + coinDecimals: 6, + coinGeckoId: 'bitcanna', + coinImageUrl: '/tokens/blockchain/BCNA.png', + }, + bip44: { + coinType: 118, + }, + bech32Config: { + bech32PrefixAccAddr: 'bcna', + bech32PrefixAccPub: 'bcnapub', + bech32PrefixValAddr: 'bcnavaloper', + bech32PrefixValPub: 'bcnavaloperpub', + bech32PrefixConsAddr: 'bcnavalcons', + bech32PrefixConsPub: 'bcnavalconspub', + }, + currencies: [ + { + coinDenom: 'BCNA', + coinMinimalDenom: 'ubcna', + coinDecimals: 6, + coinGeckoId: 'bitcanna', + coinImageUrl: '/tokens/blockchain/BCNA.png', + }, + ], + feeCurrencies: [ + { + coinDenom: 'BCNA', + coinMinimalDenom: 'ubcna', + coinDecimals: 6, + coinGeckoId: 'bitcanna', + coinImageUrl: '/tokens/blockchain/BCNA.png', + }, + ], + features: ['stargate', 'ibc-transfer', 'no-legacy-stdTx'], + explorerUrlToTx: 'https://www.mintscan.io/bitcanna/txs/{txHash}', + gasPriceStep: null, + }, + }, + { + name: 'UMEE', + defaultDecimals: 6, + addressPatterns: ['^(umee1)[0-9a-z]{38}$'], + feeAssets: [ + { + blockchain: 'UMEE', + symbol: 'UMEE', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/umee.svg', + displayName: 'Umee', + shortName: 'Umee', + sort: 36, + color: '#D2B6FF', + enabled: true, + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + type: 'COSMOS', + chainId: 'umee-1', + info: { + infoType: 'CosmosMetaInfo', + blockExplorerUrls: ['https://www.mintscan.io/cosmos/'], + addressUrl: 'https://www.mintscan.io/cosmos/account/{wallet}', + transactionUrl: 'https://www.mintscan.io/cosmos/txs/{txHash}', + experimental: false, + rpc: 'https://api.barnacle.mainnet.network.umee.cc', + rest: 'https://lcd-umee.cosmostation.io', + cosmostationLcdUrl: 'https://lcd-umee.cosmostation.io', + cosmostationApiUrl: 'https://api-umee.cosmostation.io', + cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', + mintScanName: 'umee', + chainName: 'Umee', + stakeCurrency: { + coinDenom: 'UMEE', + coinMinimalDenom: 'uumee', + coinDecimals: 6, + coinGeckoId: 'pool:uumee', + coinImageUrl: '/tokens/blockchain/UMEE.png', + }, + bip44: { + coinType: 118, + }, + bech32Config: { + bech32PrefixAccAddr: 'umee', + bech32PrefixAccPub: 'umeepub', + bech32PrefixValAddr: 'umeevaloper', + bech32PrefixValPub: 'umeevaloperpub', + bech32PrefixConsAddr: 'umeevalcons', + bech32PrefixConsPub: 'umeevalconspub', + }, + currencies: [ + { + coinDenom: 'UMEE', + coinMinimalDenom: 'uumee', + coinDecimals: 6, + coinGeckoId: 'pool:uumee', + coinImageUrl: '/tokens/blockchain/UMEE.png', + }, + ], + feeCurrencies: [ + { + coinDenom: 'UMEE', + coinMinimalDenom: 'uumee', + coinDecimals: 6, + coinGeckoId: 'pool:uumee', + coinImageUrl: '/tokens/blockchain/UMEE.png', + }, + ], + features: ['stargate', 'ibc-transfer', 'no-legacy-stdTx'], + explorerUrlToTx: 'https://www.mintscan.io/umee/txs/{txHash}', + gasPriceStep: { + low: 0.05, + average: 0.06, + high: 0.1, + }, + }, + }, + { + name: 'DESMOS', + defaultDecimals: 6, + addressPatterns: ['^(desmos1)[0-9a-z]{38}$'], + feeAssets: [ + { + blockchain: 'DESMOS', + symbol: 'DSM', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/desmos.svg', + displayName: 'Desmos', + shortName: 'Desmos', + sort: 37, + color: '#DF6952', + enabled: true, + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + type: 'COSMOS', + chainId: 'desmos-mainnet', + info: { + infoType: 'CosmosMetaInfo', + blockExplorerUrls: ['https://www.mintscan.io/cosmos/'], + addressUrl: 'https://www.mintscan.io/cosmos/account/{wallet}', + transactionUrl: 'https://www.mintscan.io/cosmos/txs/{txHash}', + experimental: true, + rpc: 'https://rpc.mainnet.desmos.network', + rest: 'https://api.mainnet.desmos.network', + cosmostationLcdUrl: 'https://lcd-desmos.cosmostation.io', + cosmostationApiUrl: 'https://api-desmos.cosmostation.io', + cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', + mintScanName: 'desmos', + chainName: 'Desmos', + stakeCurrency: { + coinDenom: 'DSM', + coinMinimalDenom: 'udsm', + coinDecimals: 6, + coinGeckoId: 'pool:udsm', + coinImageUrl: '/tokens/blockchain/DSM.png', + }, + bip44: { + coinType: 852, + }, + bech32Config: { + bech32PrefixAccAddr: 'desmos', + bech32PrefixAccPub: 'desmospub', + bech32PrefixValAddr: 'desmosvaloper', + bech32PrefixValPub: 'desmosvaloperpub', + bech32PrefixConsAddr: 'desmosvalcons', + bech32PrefixConsPub: 'desmosvalconspub', + }, + currencies: [ + { + coinDenom: 'DSM', + coinMinimalDenom: 'udsm', + coinDecimals: 6, + coinGeckoId: 'pool:udsm', + coinImageUrl: '/tokens/blockchain/DSM.png', + }, + ], + feeCurrencies: [ + { + coinDenom: 'DSM', + coinMinimalDenom: 'udsm', + coinDecimals: 6, + coinGeckoId: 'pool:udsm', + coinImageUrl: '/tokens/blockchain/DSM.png', + }, + ], + features: ['stargate', 'ibc-transfer', 'no-legacy-stdTx', 'ibc-go'], + explorerUrlToTx: 'https://explorer.desmos.network/transactions/{txHash}', + gasPriceStep: null, + }, + }, + { + name: 'LUMNETWORK', + defaultDecimals: 6, + addressPatterns: ['^(lum1)[0-9a-z]{38}$'], + feeAssets: [ + { + blockchain: 'LUMNETWORK', + symbol: 'LUM', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/lumnetwork.png', + displayName: 'Lum Network', + shortName: 'Lum Network', + sort: 38, + color: '#1B42B4', + enabled: true, + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + type: 'COSMOS', + chainId: 'lum-network-1', + info: { + infoType: 'CosmosMetaInfo', + blockExplorerUrls: ['https://www.mintscan.io/cosmos/'], + addressUrl: 'https://www.mintscan.io/cosmos/account/{wallet}', + transactionUrl: 'https://www.mintscan.io/cosmos/txs/{txHash}', + experimental: true, + rpc: 'https://node0.mainnet.lum.network/rpc', + rest: 'https://node0.mainnet.lum.network/rest', + cosmostationLcdUrl: 'https://lcd-lum.cosmostation.io', + cosmostationApiUrl: 'https://api-lum.cosmostation.io', + cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', + mintScanName: 'lum', + chainName: 'Lum Network', + stakeCurrency: { + coinDenom: 'LUM', + coinMinimalDenom: 'ulum', + coinDecimals: 6, + coinGeckoId: 'pool:ulum', + coinImageUrl: '/tokens/blockchain/LUM.png', + }, + bip44: { + coinType: 118, + }, + bech32Config: { + bech32PrefixAccAddr: 'lum', + bech32PrefixAccPub: 'lumpub', + bech32PrefixValAddr: 'lumvaloper', + bech32PrefixValPub: 'lumvaloperpub', + bech32PrefixConsAddr: 'lumvalcons', + bech32PrefixConsPub: 'lumvalconspub', + }, + currencies: [ + { + coinDenom: 'LUM', + coinMinimalDenom: 'ulum', + coinDecimals: 6, + coinGeckoId: 'pool:ulum', + coinImageUrl: '/tokens/blockchain/LUM.png', + }, + ], + feeCurrencies: [ + { + coinDenom: 'LUM', + coinMinimalDenom: 'ulum', + coinDecimals: 6, + coinGeckoId: 'pool:ulum', + coinImageUrl: '/tokens/blockchain/LUM.png', + }, + ], + features: ['stargate', 'ibc-transfer', 'no-legacy-stdTx', 'ibc-go'], + explorerUrlToTx: 'https://www.mintscan.io/lum/txs/{txHash}', + gasPriceStep: null, + }, + }, + { + name: 'BOBA', + defaultDecimals: 18, + addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], + feeAssets: [ + { + blockchain: 'BOBA', + symbol: 'ETH', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/boba.png', + displayName: 'Boba', + shortName: 'Boba', + sort: 39, + color: '#ccff00', + enabled: true, + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + type: 'EVM', + chainId: '0x120', + info: { + infoType: 'EvmMetaInfo', + chainName: 'Boba Network', + nativeCurrency: { + name: 'ETH', + symbol: 'ETH', + decimals: 18, + }, + rpcUrls: ['https://mainnet.boba.network'], + blockExplorerUrls: ['https://bobascan.com/'], + addressUrl: 'https://bobascan.com//address/{wallet}', + transactionUrl: 'https://bobascan.com//tx/{txHash}', + enableGasV2: true, + }, + }, + { + name: 'AXELAR', + defaultDecimals: 6, + addressPatterns: ['^(axelar1)[0-9a-z]{38}$'], + feeAssets: [ + { + blockchain: 'AXELAR', + symbol: 'AXL', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/axelar.png', + displayName: 'Axelar', + shortName: 'Axelar', + sort: 40, + color: '#15181C', + enabled: false, + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + type: 'COSMOS', + chainId: 'axelar-dojo-1', + info: { + infoType: 'CosmosMetaInfo', + blockExplorerUrls: ['https://www.mintscan.io/cosmos/'], + addressUrl: 'https://www.mintscan.io/cosmos/account/{wallet}', + transactionUrl: 'https://www.mintscan.io/cosmos/txs/{txHash}', + experimental: false, + rpc: 'https://mainnet-rpc-router.axelar-dev.workers.dev/chain/axelar', + rest: 'https://axelar-lcd.quickapi.com', + cosmostationLcdUrl: 'https://axelar-lcd.quickapi.com', + cosmostationApiUrl: + 'https://mainnet-rpc-router.axelar-dev.workers.dev/chain/axelar', + cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', + mintScanName: 'axelar', + chainName: 'Axelar', + stakeCurrency: { + coinDenom: 'AXL', + coinMinimalDenom: 'uaxl', + coinDecimals: 6, + coinGeckoId: 'axelar', + coinImageUrl: '/tokens/blockchain/axl.png', + }, + bip44: { + coinType: 118, + }, + bech32Config: { + bech32PrefixAccAddr: 'axl', + bech32PrefixAccPub: 'axlpub', + bech32PrefixValAddr: 'axlvaloper', + bech32PrefixValPub: 'axlvaloperpub', + bech32PrefixConsAddr: 'axlvalcons', + bech32PrefixConsPub: 'axlvalconspub', + }, + currencies: [ + { + coinDenom: 'AXL', + coinMinimalDenom: 'uaxl', + coinDecimals: 6, + coinGeckoId: 'axelar', + coinImageUrl: '/tokens/blockchain/axl.png', + }, + ], + feeCurrencies: [ + { + coinDenom: 'AXL', + coinMinimalDenom: 'uaxl', + coinDecimals: 6, + coinGeckoId: 'axelar', + coinImageUrl: '/tokens/blockchain/axl.png', + }, + ], + features: ['stargate', 'ibc-transfer'], + explorerUrlToTx: 'https://www.mintscan.io/axelar/txs/{txHash}', + gasPriceStep: { + low: 0.007, + average: 0.007, + high: 0.01, + }, + }, + }, + { + name: 'STRIDE', + defaultDecimals: 6, + addressPatterns: ['^(stride1)[0-9a-z]{38}$'], + feeAssets: [ + { + blockchain: 'STRIDE', + symbol: 'STRD', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/stride.svg', + displayName: 'Stride', + shortName: 'Stride', + sort: 41, + color: '#D63178', + enabled: true, + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + type: 'COSMOS', + chainId: 'stride-1', + info: { + infoType: 'CosmosMetaInfo', + blockExplorerUrls: ['https://www.mintscan.io/cosmos/'], + addressUrl: 'https://www.mintscan.io/cosmos/account/{wallet}', + transactionUrl: 'https://www.mintscan.io/cosmos/txs/{txHash}', + experimental: false, + rpc: 'https://rpc-stride.keplr.app', + rest: 'https://lcd-stride.keplr.app', + cosmostationLcdUrl: 'https://lcd-stride.cosmostation.io', + cosmostationApiUrl: 'https://api-stride.cosmostation.io', + cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', + mintScanName: 'stride', + chainName: 'Stride', + stakeCurrency: { + coinDenom: 'STRD', + coinMinimalDenom: 'ustrd', + coinDecimals: 6, + coinGeckoId: 'stride', + coinImageUrl: '', + }, + bip44: { + coinType: 118, + }, + bech32Config: { + bech32PrefixAccAddr: 'stride', + bech32PrefixAccPub: 'stridepub', + bech32PrefixValAddr: 'stridevaloper', + bech32PrefixValPub: 'stridevaloperpub', + bech32PrefixConsAddr: 'stridevalcons', + bech32PrefixConsPub: 'stridevalconspub', + }, + currencies: [ + { + coinDenom: 'STRD', + coinMinimalDenom: 'ustrd', + coinDecimals: 6, + coinGeckoId: 'stride', + coinImageUrl: '', + }, + { + coinDenom: 'stATOM', + coinMinimalDenom: 'stuatom', + coinDecimals: 6, + coinGeckoId: 'stride-staked-atom', + coinImageUrl: '', + }, + { + coinDenom: 'stOSMO', + coinMinimalDenom: 'stuosmo', + coinDecimals: 6, + coinGeckoId: 'stride-staked-osmo', + coinImageUrl: '', + }, + { + coinDenom: 'stJUNO', + coinMinimalDenom: 'stujuno', + coinDecimals: 6, + coinGeckoId: 'stride-staked-juno', + coinImageUrl: '', + }, + { + coinDenom: 'stSTARS', + coinMinimalDenom: 'stustars', + coinDecimals: 6, + coinGeckoId: '', + coinImageUrl: '', + }, + { + coinDenom: 'stEVMOS', + coinMinimalDenom: 'staevmos', + coinDecimals: 18, + coinGeckoId: '', + coinImageUrl: '', + }, + { + coinDenom: 'stLUNA', + coinMinimalDenom: 'stuluna', + coinDecimals: 6, + coinGeckoId: '', + coinImageUrl: '', + }, + ], + feeCurrencies: [ + { + coinDenom: 'STRD', + coinMinimalDenom: 'ustrd', + coinDecimals: 6, + coinGeckoId: 'stride', + coinImageUrl: '', + }, + ], + features: ['ibc-transfer'], + explorerUrlToTx: 'https://www.mintscan.io/stride/txs/{txHash}', + gasPriceStep: { + low: 0.001, + average: 0.0025, + high: 0.04, + }, + }, + }, + { + name: 'KCC', + defaultDecimals: 18, + addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], + feeAssets: [ + { + blockchain: 'KCC', + symbol: 'KCS', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/kcc.png', + displayName: 'Kcc', + shortName: 'Kcc', + sort: 41, + color: '#ccff00', + enabled: true, + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + type: 'EVM', + chainId: '0x141', + info: { + infoType: 'EvmMetaInfo', + chainName: 'Kcc Network', + nativeCurrency: { + name: 'KCS', + symbol: 'KCS', + decimals: 18, + }, + rpcUrls: ['https://rpc-mainnet.kcc.network/'], + blockExplorerUrls: ['https://explorer.kcc.io/en'], + addressUrl: 'https://explorer.kcc.io/en/address/{wallet}', + transactionUrl: 'https://explorer.kcc.io/en/tx/{txHash}', + enableGasV2: true, + }, + }, + { + name: 'MARS', + defaultDecimals: 6, + addressPatterns: ['^(mars1)[0-9a-z]{38}$'], + feeAssets: [ + { + blockchain: 'MARS', + symbol: 'MARS', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/mars.svg', + displayName: 'Mars', + shortName: 'Mars', + sort: 42, + color: '#CB4B3D', + enabled: true, + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + type: 'COSMOS', + chainId: 'mars-1', + info: { + infoType: 'CosmosMetaInfo', + blockExplorerUrls: ['https://www.mintscan.io/cosmos/'], + addressUrl: 'https://www.mintscan.io/cosmos/account/{wallet}', + transactionUrl: 'https://www.mintscan.io/cosmos/txs/{txHash}', + experimental: false, + rpc: 'https://rpc-mars.keplr.app', + rest: 'https://lcd-mars.keplr.app', + cosmostationLcdUrl: 'https://lcd-mars-protocol.cosmostation.io', + cosmostationApiUrl: 'https://api-mars-protocol.cosmostation.io', + cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', + mintScanName: 'mars-protocol', + chainName: 'Mars', + stakeCurrency: { + coinDenom: 'MARS', + coinMinimalDenom: 'umars', + coinDecimals: 6, + coinGeckoId: 'mars-protocol-a7fcbcfb-fd61-4017-92f0-7ee9f9cc6da3', + coinImageUrl: '/tokens/blockchain/mars.svg', + }, + bip44: { + coinType: 118, + }, + bech32Config: { + bech32PrefixAccAddr: 'mars', + bech32PrefixAccPub: 'marspub', + bech32PrefixValAddr: 'marsvaloper', + bech32PrefixValPub: 'marsvaloperpub', + bech32PrefixConsAddr: 'marsvalcons', + bech32PrefixConsPub: 'marsvalconspub', + }, + currencies: [ + { + coinDenom: 'MARS', + coinMinimalDenom: 'umars', + coinDecimals: 6, + coinGeckoId: 'mars-protocol-a7fcbcfb-fd61-4017-92f0-7ee9f9cc6da3', + coinImageUrl: '/tokens/blockchain/mars.svg', + }, + ], + feeCurrencies: [ + { + coinDenom: 'MARS', + coinMinimalDenom: 'umars', + coinDecimals: 6, + coinGeckoId: 'mars-protocol-a7fcbcfb-fd61-4017-92f0-7ee9f9cc6da3', + coinImageUrl: '/tokens/blockchain/mars.svg', + }, + ], + features: ['ibc-transfer'], + explorerUrlToTx: 'https://www.mintscan.io/mars-protocol/txs/{txHash}', + gasPriceStep: { + low: 0.001, + average: 0.0025, + high: 0.01, + }, + }, + }, + { + name: 'TERRA', + defaultDecimals: 6, + addressPatterns: ['^(terra1)[0-9a-z]{38}$'], + feeAssets: [ + { + blockchain: 'TERRA', + symbol: 'LUNA', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/terra.png', + displayName: 'Terra 2.0', + shortName: 'Terra 2.0', + sort: 43, + color: '#5493F7', + enabled: true, + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + type: 'COSMOS', + chainId: 'phoenix-1', + info: { + infoType: 'CosmosMetaInfo', + blockExplorerUrls: ['https://www.mintscan.io/cosmos/'], + addressUrl: 'https://www.mintscan.io/cosmos/account/{wallet}', + transactionUrl: 'https://www.mintscan.io/cosmos/txs/{txHash}', + experimental: false, + rpc: 'https://rpc-phoenix.keplr.app', + rest: 'https://lcd-phoenix.keplr.app', + cosmostationLcdUrl: 'https://phoenix-lcd.terra.dev', + cosmostationApiUrl: null, + cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', + mintScanName: null, + chainName: 'Terra 2.0', + stakeCurrency: { + coinDenom: 'LUNA', + coinMinimalDenom: 'uluna', + coinDecimals: 6, + coinGeckoId: 'terra-luna-2', + coinImageUrl: '', + }, + bip44: { + coinType: 330, + }, + bech32Config: { + bech32PrefixAccAddr: 'terra', + bech32PrefixAccPub: 'terrapub', + bech32PrefixValAddr: 'terravaloper', + bech32PrefixValPub: 'terravaloperpub', + bech32PrefixConsAddr: 'terravalcons', + bech32PrefixConsPub: 'terravalconspub', + }, + currencies: [ + { + coinDenom: 'LUNA', + coinMinimalDenom: 'uluna', + coinDecimals: 6, + coinGeckoId: 'terra-luna-2', + coinImageUrl: '', + }, + ], + feeCurrencies: [ + { + coinDenom: 'LUNA', + coinMinimalDenom: 'uluna', + coinDecimals: 6, + coinGeckoId: 'terra-luna-2', + coinImageUrl: '', + }, + ], + features: ['cosmwasm', 'ibc-transfer'], + explorerUrlToTx: 'https://finder.terra.money/mainnet/txs/{txHash}', + gasPriceStep: { + low: 0.0125, + average: 0.015, + high: 0.15, + }, + }, + }, + { + name: 'TELOS', + defaultDecimals: 18, + addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], + feeAssets: [ + { + blockchain: 'TELOS', + symbol: 'TLOS', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/telos.png', + displayName: 'Telos', + shortName: 'Telos', + sort: 49, + color: '#6144ae', + enabled: true, + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + type: 'EVM', + chainId: '0x28', + info: { + infoType: 'EvmMetaInfo', + chainName: 'Telos Mainnet', + nativeCurrency: { + name: 'TLOS', + symbol: 'TLOS', + decimals: 18, + }, + rpcUrls: ['https://mainnet.telos.net/evm'], + blockExplorerUrls: ['https://www.teloscan.io'], + addressUrl: 'https://www.teloscan.io/address/{wallet}', + transactionUrl: 'https://www.teloscan.io/tx/{txHash}', + enableGasV2: true, + }, + }, + { + name: 'BOBA_BNB', + defaultDecimals: 18, + addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], + feeAssets: [ + { + blockchain: 'BOBA_BNB', + symbol: 'BOBA', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/boba.png', + displayName: 'Boba Bnb', + shortName: 'Boba Bnb', + sort: 63, + color: '#ccff00', + enabled: true, + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + type: 'EVM', + chainId: '0xdbe0', + info: { + infoType: 'EvmMetaInfo', + chainName: 'Boba Bnb Network', + nativeCurrency: { + name: 'BOBA', + symbol: 'BOBA', + decimals: 18, + }, + rpcUrls: ['https://bnb.boba.network'], + blockExplorerUrls: ['https://blockexplorer.bnb.boba.network'], + addressUrl: 'https://blockexplorer.bnb.boba.network/address/{wallet}', + transactionUrl: 'https://blockexplorer.bnb.boba.network/tx/{txHash}', + enableGasV2: true, + }, + }, + { + name: 'BOBA_BEAM', + defaultDecimals: 18, + addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], + feeAssets: [ + { + blockchain: 'BOBA_BEAM', + symbol: 'BOBA', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/boba.png', + displayName: 'Boba Beam', + shortName: 'Boba Beam', + sort: 64, + color: '#ccff00', + enabled: false, + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + type: 'EVM', + chainId: '0x50e', + info: { + infoType: 'EvmMetaInfo', + chainName: 'Boba Beam Network', + nativeCurrency: { + name: 'BOBA', + symbol: 'BOBA', + decimals: 18, + }, + rpcUrls: ['https://bobabeam.boba.network'], + blockExplorerUrls: ['https://blockexplorer.bobabeam.boba.network'], + addressUrl: + 'https://blockexplorer.bobabeam.boba.network/address/{wallet}', + transactionUrl: 'https://blockexplorer.bobabeam.boba.network/tx/{txHash}', + enableGasV2: true, + }, + }, + { + name: 'BOBA_AVALANCHE', + defaultDecimals: 18, + addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], + feeAssets: [ + { + blockchain: 'BOBA_AVALANCHE', + symbol: 'BOBA', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/boba.png', + displayName: 'Boba Avalanche', + shortName: 'Boba Avalanche', + sort: 65, + color: '#ccff00', + enabled: true, + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + //@ts-ignore + type: 'EVM', + chainId: '0xa918', + info: { + infoType: 'EvmMetaInfo', + chainName: 'Boba Avalanche Network', + nativeCurrency: { + name: 'BOBA', + symbol: 'BOBA', + decimals: 18, + }, + rpcUrls: ['https://avax.boba.network'], + blockExplorerUrls: ['https://blockexplorer.avax.boba.network'], + addressUrl: 'https://blockexplorer.avax.boba.network/address/{wallet}', + transactionUrl: 'https://blockexplorer.avax.boba.network/tx/{txHash}', + enableGasV2: true, + }, + }, +]; diff --git a/wallets/provider-walletconnect-2/src/signers/solana.ts b/wallets/provider-walletconnect-2/src/signers/solana.ts new file mode 100644 index 0000000000..a421750dcc --- /dev/null +++ b/wallets/provider-walletconnect-2/src/signers/solana.ts @@ -0,0 +1,160 @@ +import type { SolanaWeb3Signer } from '@rango-dev/signer-solana'; +import type { Transaction, VersionedTransaction } from '@solana/web3.js'; +import type { SignClient } from '@walletconnect/sign-client/dist/types/client'; +import type { SessionTypes } from '@walletconnect/types'; +import type { GenericSigner, SolanaTransaction } from 'rango-types'; + +import { generalSolanaTransactionExecutor } from '@rango-dev/signer-solana'; +import { PublicKey } from '@solana/web3.js'; +import base58 from 'bs58'; +import { AccountId, ChainId } from 'caip'; +import { SignerError, SignerErrorCode } from 'rango-types'; + +import { NAMESPACES, SolanaRPCMethods } from '../constants.js'; + +const NAMESPACE_NAME = NAMESPACES.SOLANA; +class SOLANASigner implements GenericSigner { + private client: SignClient; + private session: SessionTypes.Struct; + + constructor(client: SignClient, session: SessionTypes.Struct) { + this.client = client; + this.session = session; + } + + public async signMessage( + msg: string, + address: string, + chainId: string | null + ): Promise { + const requestedFor = this.isNetworkAndAccountExistInSession({ + address, + chainId, + }); + + const caipChainId = new ChainId({ + namespace: NAMESPACE_NAME, + reference: requestedFor.chainId, + }); + + try { + const message = base58.encode(new TextEncoder().encode(msg)); + const pubkey = new PublicKey(address); + const { signature } = await this.client.request<{ + signature: string; + }>({ + topic: this.session.topic, + chainId: caipChainId.toString(), + request: { + method: SolanaRPCMethods.SIGN_MESSAGE, + params: { + message, + pubkey, + }, + }, + }); + + return signature; + } catch (error) { + throw new SignerError(SignerErrorCode.SIGN_TX_ERROR, undefined, error); + } + } + + async signAndSendTx( + tx: SolanaTransaction, + address: string, + chainId: string | null + ): Promise<{ hash: string }> { + const requestedFor = this.isNetworkAndAccountExistInSession({ + address, + chainId, + }); + const DefaultSolanaSigner: SolanaWeb3Signer = async ( + solanaWeb3Transaction: Transaction | VersionedTransaction + ) => { + const response: { signature: string } = await this.client.request({ + topic: this.session.topic, + chainId: requestedFor.caipChainId, + request: { + method: SolanaRPCMethods.SIGN_TRANSACTION, + params: solanaWeb3Transaction, + }, + }); + + const publicKey = new PublicKey(tx.from); + const sign = base58.decode(response.signature); + + solanaWeb3Transaction.addSignature(publicKey, Buffer.from(sign)); + const raw = solanaWeb3Transaction.serialize(); + return raw; + }; + + const hash = await generalSolanaTransactionExecutor( + tx, + DefaultSolanaSigner + ); + return { hash }; + } + + private isNetworkAndAccountExistInSession(requestedFor: { + address: string; + chainId: string | null; + }) { + const { address, chainId } = requestedFor; + + /* + * TODO: solana chain id in supported blockchains("mainnet-beta") is different from solana chain id is here ("5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp") + * # Solana Mainnet + * solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvd + * refrence: https://github.com/ChainAgnostic/namespaces/blob/main/solana/caip2.md + */ + + let solana_chain_id = chainId; + this.session.namespaces[NAMESPACE_NAME]?.accounts.map((account) => { + const sol_account = account.split(':'); + if (sol_account[2] === address) { + solana_chain_id = sol_account[1]; + } + }); + + if (!solana_chain_id) { + throw new Error( + 'You need to set your chain for signing message/transaction.' + ); + } + const caipAddress = new AccountId({ + chainId: { + namespace: NAMESPACE_NAME, + reference: solana_chain_id, + }, + address, + }); + + const addresses = this.session.namespaces[NAMESPACE_NAME]?.accounts.map( + (address) => address + ); + if (!addresses || !addresses.includes(caipAddress.toString())) { + console.warn( + 'Available adresses and requested address:', + addresses, + caipAddress.toString() + ); + throw new Error( + `Your requested address doesn't exist on your wallect connect session. Please reconnect your wallet.` + ); + } + + const caipChainId = new ChainId({ + namespace: NAMESPACE_NAME, + reference: solana_chain_id, + }); + + return { + chainId: solana_chain_id, + address, + caipChainId: caipChainId.toString(), + }; + } +} + +export default SOLANASigner; diff --git a/wallets/provider-walletconnect-2/src/types.ts b/wallets/provider-walletconnect-2/src/types.ts new file mode 100644 index 0000000000..d33a49e383 --- /dev/null +++ b/wallets/provider-walletconnect-2/src/types.ts @@ -0,0 +1,30 @@ +import type { SignClient } from '@walletconnect/sign-client/dist/types/client'; +import type { ProposalTypes, SessionTypes } from '@walletconnect/types'; +import type { BlockchainMeta, CosmosBlockchainMeta } from 'rango-types'; + +export interface Environments extends Record { + WC_PROJECT_ID: string; + // This is useful for directly opening a listed WC wallet. you will need to pass a url. + DISABLE_MODAL_AND_OPEN_LINK?: string; +} +export interface WCInstance { + client: SignClient; + session: SessionTypes.Struct | null; + request: (params: any) => Promise; +} + +export interface CreateSessionParams { + requiredNamespaces: ProposalTypes.RequiredNamespaces; + optionalNamespaces?: ProposalTypes.OptionalNamespaces; + pairingTopic?: string; +} + +export interface ConnectParams { + meta: BlockchainMeta[]; + envs: Environments; +} + +export interface CosmosMeta extends CosmosBlockchainMeta { + // forcing the chainId to be `string` only. + chainId: string; +} diff --git a/wallets/provider-walletconnect-2/src/wc-types.d.ts b/wallets/provider-walletconnect-2/src/wc-types.d.ts new file mode 100644 index 0000000000..931bdd987b --- /dev/null +++ b/wallets/provider-walletconnect-2/src/wc-types.d.ts @@ -0,0 +1,31 @@ +// see notes.md for more details. +import type { + ConfigCtrlState, + ThemeCtrlState, +} from '@walletconnect/modal-core'; +/** + * Types + */ +export type WalletConnectModalConfig = ConfigCtrlState & ThemeCtrlState; + +/** + * Client + */ +export declare class WalletConnectModal { + openModal: ( + options?: // eslint-disable-next-line @typescript-eslint/consistent-type-imports + | import('@walletconnect/modal-core/dist/_types/src/controllers/ModalCtrl').OpenOptions + | undefined + ) => Promise; + closeModal: () => void; + subscribeModal: ( + callback: ( + // eslint-disable-next-line @typescript-eslint/consistent-type-imports + newState: import('@walletconnect/modal-core/dist/_types/src/types/controllerTypes').ModalCtrlState + ) => void + ) => () => void; + + setTheme: (theme: ThemeCtrlState) => void; + private initUi; + constructor(config: WalletConnectModalConfig); +} diff --git a/wallets/provider-walletconnect-2/tsconfig.build.json b/wallets/provider-walletconnect-2/tsconfig.build.json new file mode 100644 index 0000000000..3eeafb479b --- /dev/null +++ b/wallets/provider-walletconnect-2/tsconfig.build.json @@ -0,0 +1,10 @@ +{ + "extends": "../../tsconfig.bundler.json", + "include": ["src"], + "files": ["../../global-wallets-env.d.ts"], + "compilerOptions": { + "outDir": "dist", + "rootDir": "./src", + "lib": ["dom", "esnext"] + } +} diff --git a/wallets/provider-walletconnect-2/tsconfig.json b/wallets/provider-walletconnect-2/tsconfig.json new file mode 100644 index 0000000000..a3a0b0f59d --- /dev/null +++ b/wallets/provider-walletconnect-2/tsconfig.json @@ -0,0 +1 @@ +{ "extends": "./tsconfig.build.json", "include": ["src", "tests"] } diff --git a/wallets/provider-walletconnect/package.json b/wallets/provider-walletconnect/package.json deleted file mode 100644 index 7e8f8c8ee4..0000000000 --- a/wallets/provider-walletconnect/package.json +++ /dev/null @@ -1,52 +0,0 @@ -{ - "name": "@rango-dev/provider-walletconnect", - "version": "0.1.12", - "license": "MIT", - "module": "dist/provider-walletconnect.esm.js", - "main": "dist/index.js", - "typings": "dist/index.d.ts", - "files": [ - "dist", - "src" - ], - "scripts": { - "start": "tsdx watch", - "build": "tsdx build --tsconfig ./tsconfig.json", - "test": "tsdx test --passWithNoTests", - "lint": "tsdx lint", - "size": "size-limit", - "analyze": "size-limit --why" - }, - "husky": { - "hooks": { - "pre-commit": "tsdx lint" - } - }, - "prettier": { - "printWidth": 80, - "semi": true, - "singleQuote": true, - "trailingComma": "es5" - }, - "size-limit": [ - { - "path": "dist/provider-walletconnect.cjs.production.min.js", - "limit": "10 KB" - }, - { - "path": "dist/provider-walletconnect.esm.js", - "limit": "10 KB" - } - ], - "dependencies": { - "@rango-dev/signer-evm": "^0.1.11", - "@rango-dev/wallets-shared": "^0.1.11", - "@walletconnect/client": "^1.8.0", - "@walletconnect/jsonrpc-utils": "^1.0.4", - "@walletconnect/qrcode-modal": "^1.8.0", - "rango-types": "^0.1.28" - }, - "publishConfig": { - "access": "public" - } -} diff --git a/wallets/provider-walletconnect/readme.md b/wallets/provider-walletconnect/readme.md deleted file mode 100644 index 0c3ba11013..0000000000 --- a/wallets/provider-walletconnect/readme.md +++ /dev/null @@ -1 +0,0 @@ -# @rango-dev/provider-walletconnect diff --git a/wallets/provider-walletconnect/src/helpers.ts b/wallets/provider-walletconnect/src/helpers.ts deleted file mode 100644 index 8e8da33543..0000000000 --- a/wallets/provider-walletconnect/src/helpers.ts +++ /dev/null @@ -1,91 +0,0 @@ -import WalletConnectClient from '@walletconnect/client'; -import QRCodeModal from '@walletconnect/qrcode-modal'; - -const BRIDGE_URL = 'https://bridge.walletconnect.org'; - -export function supportsForSwitchNetworkRequest(provider: any): boolean { - const wallets = ['metamask']; - const connectedWallet = provider.peerMeta ? provider.peerMeta.name : ''; - - return wallets.some((wallet) => { - return connectedWallet.toLowerCase().includes(wallet); - }); -} - -export function makeConnection(options: { - force?: boolean; - chainId?: number; - provider: any; -}): Promise { - const { force = false, chainId, provider } = options; - const clientOptions = { - bridge: BRIDGE_URL, - // This property will be filled when we are using `.setMeta` inside `provider.tsx`. - rpc: [], - qrcodeModal: QRCodeModal, - }; - - return new Promise((resolve, reject) => { - /* - There are two types of making connection: - 1. Normal Connection: - Pickup the availabe session or create a new session if it's not connected yet. - 2. Forced Connection: - In some cases like switching network, we need to create a new session anyways, - Even the connection is already made. - */ - (async () => { - // If `force` is true, Creating a new instance, - // Otherwise try to use old connection if availabe - // (returns null if there is no old connection) - let currentProvider = force ? new WalletConnectClient(clientOptions) : provider; - const hasProvider = !!currentProvider; - const onCloseModal = () => { - reject(new Error('QRCode modal has been closed.')); - }; - - // If force is false, there are some cases that this.provider is null - // Like connection for the first time. - if (!hasProvider) { - currentProvider = new WalletConnectClient(clientOptions); - } - - // if a connection is not established, try to make a new session. - if (!currentProvider.connected) { - const session_options = chainId - ? { - chainId, - } - : undefined; - - // The current promise will be rejected if user close the modal. - currentProvider.on('modal_closed', onCloseModal); - - /* - `createSession` will make a new session, but it doesn't means - the connection has been established. The only way we can make sure - a session has been created and the connection is ready, - is using the `connect` event after successfully creating the session. - */ - await currentProvider - .createSession(session_options) - .then(() => { - currentProvider.on('connect', (error: any, _payload: any) => { - if (error) { - return reject(error); - } - - currentProvider.off('modal_closed', onCloseModal); - resolve(currentProvider); - }); - }) - .catch(reject); - } else { - /* - Connection is established, we will use the current session without creating a new one. - */ - resolve(currentProvider); - } - })(); - }); -} diff --git a/wallets/provider-walletconnect/src/index.ts b/wallets/provider-walletconnect/src/index.ts deleted file mode 100644 index f326d718b5..0000000000 --- a/wallets/provider-walletconnect/src/index.ts +++ /dev/null @@ -1,177 +0,0 @@ -import { makeConnection, supportsForSwitchNetworkRequest } from './helpers'; -import { - WalletType, - CanSwitchNetwork, - Connect, - Disconnect, - GetInstance, - Subscribe, - SwitchNetwork, - WalletConfig, - convertEvmBlockchainMetaToEvmChainInfo, - canSwitchNetworkToEvm, - switchOrAddNetworkForMetamaskCompatibleWallets, - WalletInfo, -} from '@rango-dev/wallets-shared'; -import { formatJsonRpcRequest } from '@walletconnect/jsonrpc-utils'; -import signer from './signer'; -import { - SignerFactory, - EvmBlockchainMeta, - BlockchainMeta, - evmBlockchains, -} from 'rango-types'; - -const WALLET = WalletType.WALLET_CONNECT; - -export const config: WalletConfig = { - type: WALLET, - checkInstallation: false, - isAsyncInstance: true, -}; - -export const getInstance: GetInstance = async ({ - network, - currentProvider, - meta, -}) => { - // If `network` is provided, trying to get chainId - const evm_chain_info = convertEvmBlockchainMetaToEvmChainInfo( - meta as EvmBlockchainMeta[] - ); - const info = network ? evm_chain_info[network] : undefined; - const requestedChainId = info?.chainId ? parseInt(info?.chainId) : undefined; - - const nextInstance = await makeConnection({ - provider: currentProvider, - chainId: requestedChainId, - }); - - return nextInstance; -}; - -export const connect: Connect = async ({ instance }) => { - const accounts = instance.accounts; - const chainId = instance.chainId; - - return { - accounts, - chainId, - }; -}; - -export const subscribe: Subscribe = async ({ - instance, - updateChainId, - updateAccounts, - disconnect, -}) => { - // Subscribe to connection events - instance.on('connect', (error: any, payload: any) => { - if (error) { - throw error; - } - - // Get provided accounts and chainId - const { accounts, chainId } = payload.params[0]; - - updateAccounts(accounts); - updateChainId(chainId); - }); - - instance.on('session_update', (error: any, payload: any) => { - if (error) { - throw error; - } - - // Get updated accounts and chainId - const { accounts, chainId } = payload.params[0]; - updateAccounts(accounts); - updateChainId(chainId); - }); - - instance.on('disconnect', (error: any, _payload: any) => { - if (error) { - throw error; - } - - disconnect(); - }); -}; - -export const switchNetwork: SwitchNetwork = async ({ - instance, - meta, - network, - newInstance, -}) => { - const evm_chain_info = convertEvmBlockchainMetaToEvmChainInfo( - meta as EvmBlockchainMeta[] - ); - - /* - There are two methods for switch network - 1. Wallet supports `wallet_switchEthereumChain` rpc method. like Metamask - 2. Kill the current session and making a new session with new chain. - */ - if (supportsForSwitchNetworkRequest(instance)) { - /* - `switchOrAddNetworkForMetamaskCompatibleWallets` needs a web3-provider interface. - And uses `request` method. Here we are making something it can use. - */ - - const simulatedWeb3Instance = { - request: (payload: any): Promise => { - const rpcRequest = formatJsonRpcRequest(payload.method, payload.params); - return instance.sendCustomRequest(rpcRequest); - }, - }; - - await switchOrAddNetworkForMetamaskCompatibleWallets( - simulatedWeb3Instance, - network, - evm_chain_info - ); - } else { - // Kill the old session, make a new session with requested network. - - // Remove `discconect` listener, because it will reset the state - // But we decided to show user is connect to wallet and - // Only kill the session and instance. - instance.off('disconnect'); - - await instance.killSession(); - - if (!!newInstance) { - await newInstance({ force: true, network }); - } - } -}; - -export const canSwitchNetworkTo: CanSwitchNetwork = canSwitchNetworkToEvm; - -export const disconnect: Disconnect = async ({ instance, destroyInstance }) => { - if (instance && instance.peerMeta) { - await instance.killSession().catch(() => { - /* Ignore error. */ - }); - - destroyInstance(); - } -}; - -export const getSigners: (provider: any) => SignerFactory = signer; - -export const getWalletInfo: (allBlockChains: BlockchainMeta[]) => WalletInfo = ( - allBlockChains -) => { - const evms = evmBlockchains(allBlockChains); - return { - name: 'WalletConnect', - img: 'https://raw.githubusercontent.com/rango-exchange/rango-types/main/assets/icons/wallets/walletconnect.svg', - installLink: '', - color: '#b2dbff', - supportedChains: evms, - showOnMobile: true, - }; -}; diff --git a/wallets/provider-walletconnect/src/signer.ts b/wallets/provider-walletconnect/src/signer.ts deleted file mode 100644 index 7ae6c242f8..0000000000 --- a/wallets/provider-walletconnect/src/signer.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { DefaultEvmSigner } from '@rango-dev/signer-evm'; -import { Network, getNetworkInstance } from '@rango-dev/wallets-shared'; -import { SignerFactory, TransactionType as TxType } from 'rango-types'; - -export default function getSigners(provider: any): SignerFactory { - const ethProvider = getNetworkInstance(provider, Network.ETHEREUM); - const signers = new SignerFactory(); - signers.registerSigner(TxType.EVM, new DefaultEvmSigner(ethProvider)); - return signers; -} diff --git a/wallets/provider-walletconnect/tsconfig.json b/wallets/provider-walletconnect/tsconfig.json deleted file mode 100644 index 365489616a..0000000000 --- a/wallets/provider-walletconnect/tsconfig.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs - "include": ["src", "types", "../../global-wallets-env.d.ts"], - "compilerOptions": { - "module": "esnext", - "lib": ["dom", "esnext"], - "importHelpers": true, - // output .d.ts declaration files for consumers - "declaration": true, - // output .js.map sourcemap files for consumers - "sourceMap": true, - // match output dir to input dir. e.g. dist/index instead of dist/src/index - "rootDir": "./src", - // stricter type-checking for stronger correctness. Recommended by TS - "strict": true, - // linter checks for common issues - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true, - // noUnused* overlap with @typescript-eslint/no-unused-vars, can disable if duplicative - "noUnusedLocals": true, - "noUnusedParameters": true, - // use Node's module resolution algorithm, instead of the legacy TS one - "moduleResolution": "node", - // transpile JSX to React.createElement - "jsx": "react", - // interop between ESM and CJS modules. Recommended by TS - "esModuleInterop": true, - // significant perf increase by skipping checking .d.ts files, particularly those in node_modules. Recommended by TS - "skipLibCheck": true, - // error out if import and file system have a casing mismatch. Recommended by TS - "forceConsistentCasingInFileNames": true, - // `tsdx build` ignores this option, but it is commonly used when type-checking separately with `tsc` - "noEmit": true, - } -} diff --git a/wallets/provider-xdefi/CHANGELOG.md b/wallets/provider-xdefi/CHANGELOG.md new file mode 100644 index 0000000000..6a330b5337 --- /dev/null +++ b/wallets/provider-xdefi/CHANGELOG.md @@ -0,0 +1,204 @@ +# [0.41.0](https://github.com/rango-exchange/rango-client/compare/provider-xdefi@0.40.0...provider-xdefi@0.41.0) (2024-12-30) + + +### Features + +* update ctrl wallet name and info ([fcde421](https://github.com/rango-exchange/rango-client/commit/fcde42144a995ec655388b95b606abc669a8c1a8)) + + + +# [0.40.0](https://github.com/rango-exchange/rango-client/compare/provider-xdefi@0.39.0...provider-xdefi@0.40.0) (2024-11-27) + + +### Features + +* add ton connect provider ([2a2dbb7](https://github.com/rango-exchange/rango-client/commit/2a2dbb79022263f19446ced49d298e04d63f927f)) + + + +# [0.39.0](https://github.com/rango-exchange/rango-client/compare/provider-xdefi@0.38.1...provider-xdefi@0.39.0) (2024-11-12) + + + +## [0.38.1](https://github.com/rango-exchange/rango-client/compare/provider-xdefi@0.38.0...provider-xdefi@0.38.1) (2024-11-06) + + + +# [0.38.0](https://github.com/rango-exchange/rango-client/compare/provider-xdefi@0.37.1...provider-xdefi@0.38.0) (2024-10-12) + + +### Bug Fixes + +* bump sdk and fix type issues ([d442208](https://github.com/rango-exchange/rango-client/commit/d4422083bf5dd27d5f509ce1db7f9560d05428c8)) +* resolve issues with the sign message method for certain solana providers ([cbe83a3](https://github.com/rango-exchange/rango-client/commit/cbe83a3da8b48560b206fc2a7fa7cf062cdeaa23)) + + +### Performance Improvements + +* enable code splitting in build process ([fe5a41e](https://github.com/rango-exchange/rango-client/commit/fe5a41e0e297298de11cd74ca5825544742aa03a)) +* lazy load signer packages ([7b88f18](https://github.com/rango-exchange/rango-client/commit/7b88f1834f7b29b4b81ab6c81a07bb88e8ccf55c)) + + + +## [0.37.1](https://github.com/rango-exchange/rango-client/compare/provider-xdefi@0.37.0...provider-xdefi@0.37.1) (2024-10-05) + + +### Bug Fixes + +* remove null memo from utxo transactions ([89d1a5b](https://github.com/rango-exchange/rango-client/commit/89d1a5b4a4bce700da48ad2089edf700de188f9c)) + + + +# [0.37.0](https://github.com/rango-exchange/rango-client/compare/provider-xdefi@0.36.0...provider-xdefi@0.37.0) (2024-09-10) + + + +# [0.36.0](https://github.com/rango-exchange/rango-client/compare/provider-xdefi@0.35.1...provider-xdefi@0.36.0) (2024-08-11) + + +### Features + +* implement sign message method for providers with a custom signer ([cf9515f](https://github.com/rango-exchange/rango-client/commit/cf9515feb5d3754aac9c228fe83315daf1350c85)) + + + +## [0.35.1](https://github.com/rango-exchange/rango-client/compare/provider-xdefi@0.35.0...provider-xdefi@0.35.1) (2024-07-14) + + + +# [0.35.0](https://github.com/rango-exchange/rango-client/compare/provider-xdefi@0.33.2...provider-xdefi@0.35.0) (2024-07-09) + + + +# [0.34.0](https://github.com/rango-exchange/rango-client/compare/provider-xdefi@0.33.2...provider-xdefi@0.34.0) (2024-06-01) + + + +## [0.33.2](https://github.com/rango-exchange/rango-client/compare/provider-xdefi@0.33.1...provider-xdefi@0.33.2) (2024-05-26) + + + +## [0.33.1](https://github.com/rango-exchange/rango-client/compare/provider-xdefi@0.33.0...provider-xdefi@0.33.1) (2024-05-25) + + + +# [0.33.0](https://github.com/rango-exchange/rango-client/compare/provider-xdefi@0.32.1...provider-xdefi@0.33.0) (2024-05-14) + + + +## [0.32.1](https://github.com/rango-exchange/rango-client/compare/provider-xdefi@0.32.0...provider-xdefi@0.32.1) (2024-04-24) + + + +# [0.32.0](https://github.com/rango-exchange/rango-client/compare/provider-xdefi@0.31.0...provider-xdefi@0.32.0) (2024-04-24) + + + +# [0.31.0](https://github.com/rango-exchange/rango-client/compare/provider-xdefi@0.30.0...provider-xdefi@0.31.0) (2024-04-23) + + +### Bug Fixes + +* resolve conflicts between evm providers ([9a6734c](https://github.com/rango-exchange/rango-client/commit/9a6734cf1537bf0504cf9058d4d775313a9e8e80)) + + + +# [0.30.0](https://github.com/rango-exchange/rango-client/compare/provider-xdefi@0.29.0...provider-xdefi@0.30.0) (2024-04-09) + + +### Bug Fixes + +* fix the connection problem that happens when another wallet takes over the requested one ([42df212](https://github.com/rango-exchange/rango-client/commit/42df2120aadd84c95045b0bf76844c19305fb59a)) + + + +# [0.29.0](https://github.com/rango-exchange/rango-client/compare/provider-xdefi@0.28.0...provider-xdefi@0.29.0) (2024-03-12) + + +### Features + +* add new chains to xdefi ([f780a9f](https://github.com/rango-exchange/rango-client/commit/f780a9f5ad5b4d42b5ea63cfc382059963f5332e)) + + + +# [0.28.0](https://github.com/rango-exchange/rango-client/compare/provider-xdefi@0.27.0...provider-xdefi@0.28.0) (2024-02-20) + + + +# [0.27.0](https://github.com/rango-exchange/rango-client/compare/provider-xdefi@0.26.0...provider-xdefi@0.27.0) (2024-02-07) + + + +# [0.26.0](https://github.com/rango-exchange/rango-client/compare/provider-xdefi@0.25.0...provider-xdefi@0.26.0) (2024-01-22) + + +### Bug Fixes + +* cleanup wallets' subscriber when setProvider get null ([88d6a42](https://github.com/rango-exchange/rango-client/commit/88d6a423c49b34b3d9ff567e22df36c3b009bb76)) + + + +# [0.25.0](https://github.com/rango-exchange/rango-client/compare/provider-xdefi@0.23.0...provider-xdefi@0.25.0) (2023-12-24) + + +### Bug Fixes + +* fix HMR for widget and playground ([8524820](https://github.com/rango-exchange/rango-client/commit/8524820f10cf0b8921f3db0c4f620ff98daa4103)) + + + +# [0.14.0](https://github.com/rango-exchange/rango-client/compare/provider-xdefi@0.13.0...provider-xdefi@0.14.0) (2023-08-03) + + + +# [0.13.0](https://github.com/rango-exchange/rango-client/compare/provider-xdefi@0.12.0...provider-xdefi@0.13.0) (2023-08-01) + + + +# [0.9.0](https://github.com/rango-exchange/rango-client/compare/provider-xdefi@0.8.0...provider-xdefi@0.9.0) (2023-07-31) + + + +# [0.7.0](https://github.com/rango-exchange/rango-client/compare/provider-xdefi@0.6.0...provider-xdefi@0.7.0) (2023-07-11) + + + +# [0.6.0](https://github.com/rango-exchange/rango-client/compare/provider-xdefi@0.5.0...provider-xdefi@0.6.0) (2023-07-11) + + +### Bug Fixes + +* bnb bug in xdefi signer ([6e4eeb3](https://github.com/rango-exchange/rango-client/commit/6e4eeb3006345d1e1f9a99c33803bee97f1af9db)) + + +### Reverts + +* Revert "support for rango-types cjs format" ([ed4e050](https://github.com/rango-exchange/rango-client/commit/ed4e050bfc0dcde7aeffa6b0d73b02080a5721eb)) + + + +# [0.5.0](https://github.com/rango-exchange/rango-client/compare/provider-xdefi@0.4.0...provider-xdefi@0.5.0) (2023-05-31) + + + +# [0.4.0](https://github.com/rango-exchange/rango-client/compare/provider-xdefi@0.3.0...provider-xdefi@0.4.0) (2023-05-31) + + + +# [0.3.0](https://github.com/rango-exchange/rango-client/compare/provider-xdefi@0.2.0...provider-xdefi@0.3.0) (2023-05-30) + + + +# [0.2.0](https://github.com/rango-exchange/rango-client/compare/provider-xdefi@0.1.15...provider-xdefi@0.2.0) (2023-05-30) + + + +## [0.1.14](https://github.com/rango-exchange/rango-client/compare/provider-xdefi@0.1.13...provider-xdefi@0.1.14) (2023-05-15) + + +### Bug Fixes + +* update rango-types and fix notification bugs ([993f185](https://github.com/rango-exchange/rango-client/commit/993f185e0b8c5e5e15a2c65ba2d85d1f9c8daa90)) + + + diff --git a/wallets/provider-xdefi/package.json b/wallets/provider-xdefi/package.json index 437270ce52..e0433d1fc7 100644 --- a/wallets/provider-xdefi/package.json +++ b/wallets/provider-xdefi/package.json @@ -1,50 +1,34 @@ { "name": "@rango-dev/provider-xdefi", - "version": "0.1.12", + "version": "0.40.1-next.6", "license": "MIT", - "module": "dist/provider-xdefi.esm.js", - "main": "dist/index.js", + "type": "module", + "source": "./src/index.ts", + "main": "./dist/index.js", + "exports": { + ".": "./dist/index.js" + }, "typings": "dist/index.d.ts", "files": [ "dist", "src" ], "scripts": { - "start": "tsdx watch", - "build": "tsdx build --tsconfig ./tsconfig.json", - "test": "tsdx test --passWithNoTests", - "lint": "tsdx lint", - "size": "size-limit", - "analyze": "size-limit --why" - }, - "husky": { - "hooks": { - "pre-commit": "tsdx lint" - } + "build": "node ../../scripts/build/command.mjs --path wallets/provider-xdefi --splitting", + "ts-check": "tsc --declaration --emitDeclarationOnly -p ./tsconfig.json", + "clean": "rimraf dist", + "format": "prettier --write '{.,src}/**/*.{ts,tsx}'", + "lint": "eslint \"**/*.{ts,tsx}\" --ignore-path ../../.eslintignore" }, - "prettier": { - "printWidth": 80, - "semi": true, - "singleQuote": true, - "trailingComma": "es5" - }, - "size-limit": [ - { - "path": "dist/provider-xdefi.cjs.production.min.js", - "limit": "10 KB" - }, - { - "path": "dist/provider-xdefi.esm.js", - "limit": "10 KB" - } - ], "dependencies": { - "@rango-dev/signer-evm": "^0.1.11", - "@rango-dev/signer-solana": "^0.1.11", - "@rango-dev/wallets-shared": "^0.1.11", - "rango-types": "^0.1.28" + "@rango-dev/signer-cosmos": "^0.30.1", + "@rango-dev/signer-evm": "^0.32.0", + "@rango-dev/signer-solana": "^0.35.1-next.0", + "@rango-dev/wallets-shared": "^0.40.1-next.6", + "bs58": "^5.0.0", + "rango-types": "^0.1.74" }, "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/wallets/provider-xdefi/src/constants.ts b/wallets/provider-xdefi/src/constants.ts index 098f181fcd..64dae10667 100644 --- a/wallets/provider-xdefi/src/constants.ts +++ b/wallets/provider-xdefi/src/constants.ts @@ -1,14 +1,26 @@ import { - Network, + Networks, XDEFI_WALLET_SUPPORTED_NATIVE_CHAINS, } from '@rango-dev/wallets-shared'; export const SUPPORTED_NETWORKS = XDEFI_WALLET_SUPPORTED_NATIVE_CHAINS; export const SUPPORTED_ETH_CHAINS = [ - Network.POLYGON, - Network.ETHEREUM, - Network.BSC, - Network.AVAX_CCHAIN, - Network.FANTOM, - Network.ARBITRUM, + Networks.POLYGON, + Networks.ETHEREUM, + Networks.BSC, + Networks.AVAX_CCHAIN, + Networks.FANTOM, + Networks.ARBITRUM, +]; +export const SUPPORTED_COSMOS_CHAINS = [ + Networks.COSMOS, + Networks.AKASH, + Networks.AXELAR, + Networks.CRYPTO_ORG, + Networks.JUNO, + Networks.KUJIRA, + Networks.MARS, + Networks.OSMOSIS, + Networks.STARGAZE, + Networks.STRIDE, ]; diff --git a/wallets/provider-xdefi/src/cosmos-signer.ts b/wallets/provider-xdefi/src/cosmos-signer.ts index 6b04626523..a709678e7a 100644 --- a/wallets/provider-xdefi/src/cosmos-signer.ts +++ b/wallets/provider-xdefi/src/cosmos-signer.ts @@ -1,8 +1,12 @@ -import { CosmosTransaction, GenericSigner, SignerError } from 'rango-types'; -import { xdefiTransfer } from './helpers'; +import type { CosmosTransaction, GenericSigner } from 'rango-types'; -// TODO - replace with real type -// tslint:disable-next-line: no-any +import { getNetworkInstance, Networks } from '@rango-dev/wallets-shared'; +import { SignerError, SignerErrorCode } from 'rango-types'; + +/* + * TODO - replace with real type + * tslint:disable-next-line: no-any + */ type CosmosExternalProvider = any; export class CustomCosmosSigner implements GenericSigner { @@ -11,27 +15,35 @@ export class CustomCosmosSigner implements GenericSigner { this.provider = provider; } - async signMessage(): Promise { - throw SignerError.UnimplementedError('signMessage'); + async signMessage( + msg: string, + address: string, + chainId: string | null + ): Promise { + try { + if (!chainId) { + throw Error('ChainId is required'); + } + const { signature } = await this.provider.signArbitrary( + chainId, + address, + msg + ); + return signature; + } catch (error) { + throw new SignerError(SignerErrorCode.SIGN_TX_ERROR, undefined, error); + } } - - async signAndSendTx(tx: CosmosTransaction): Promise { - if (tx.rawTransfer === null) - throw SignerError.AssertionFailed('rawTransfer obj can not be null'); - - const from = tx.fromWalletAddress; - const { method, memo, recipient, decimals, amount, asset } = tx.rawTransfer; - const blockchain = tx.blockChain; - return xdefiTransfer( - blockchain, - asset.ticker, - from, - amount, - decimals, - recipient, - this.provider, - method, - memo + async signAndSendTx(tx: CosmosTransaction): Promise<{ hash: string }> { + const { executeCosmosTransaction } = await import( + '@rango-dev/signer-cosmos' ); + + if (tx.rawTransfer === null) { + const cosmosProvider = getNetworkInstance(this.provider, Networks.COSMOS); + const hash = await executeCosmosTransaction(tx, cosmosProvider); + return { hash }; + } + throw Error('raw transfer is not null for cosmos transactions'); } } diff --git a/wallets/provider-xdefi/src/helpers.ts b/wallets/provider-xdefi/src/helpers.ts index d2cd270545..d50e83c752 100644 --- a/wallets/provider-xdefi/src/helpers.ts +++ b/wallets/provider-xdefi/src/helpers.ts @@ -1,40 +1,73 @@ -import { Network, ProviderConnectResult } from '@rango-dev/wallets-shared'; -import { SUPPORTED_ETH_CHAINS, SUPPORTED_NETWORKS } from './constants'; +import type { Network, ProviderConnectResult } from '@rango-dev/wallets-shared'; + +import { Networks } from '@rango-dev/wallets-shared'; import { SignerError, SignerErrorCode } from 'rango-types'; +import { SUPPORTED_ETH_CHAINS, SUPPORTED_NETWORKS } from './constants.js'; + type Provider = Map; export function xdefi() { - const { xfi, ethereum } = window; + const { xfi } = window; - if (!xfi) return null; + if (!xfi) { + return null; + } const instances = new Map(); - if (xfi.bitcoin) instances.set(Network.BTC, xfi.bitcoin); - if (xfi.litecoin) instances.set(Network.LTC, xfi.litecoin); - if (xfi.thorchain) instances.set(Network.THORCHAIN, xfi.thorchain); - if (xfi.bitcoincash) instances.set(Network.BCH, xfi.bitcoincash); - if (xfi.binance) instances.set(Network.BINANCE, xfi.binance); - if (ethereum.__XDEFI) instances.set(Network.ETHEREUM, ethereum); - if (xfi.dogecoin) instances.set(Network.DOGE, xfi.dogecoin); - if (xfi.solana) instances.set(Network.SOLANA, xfi.solana); + if (xfi.bitcoin) { + instances.set(Networks.BTC, xfi.bitcoin); + } + if (xfi.litecoin) { + instances.set(Networks.LTC, xfi.litecoin); + } + if (xfi.thorchain) { + instances.set(Networks.THORCHAIN, xfi.thorchain); + } + if (xfi.bitcoincash) { + instances.set(Networks.BCH, xfi.bitcoincash); + } + if (xfi.ethereum) { + instances.set(Networks.ETHEREUM, xfi.ethereum); + } + if (xfi.dogecoin) { + instances.set(Networks.DOGE, xfi.dogecoin); + } + if (xfi.solana) { + instances.set(Networks.SOLANA, xfi.solana); + } + if (xfi.mayachain) { + instances.set(Networks.MAYA, xfi.mayachain); + } + if (xfi.keplr) { + instances.set(Networks.COSMOS, xfi.keplr); + } return instances; } export function getEthChainsInstance(netowrk: Network | null): Network | null { - if (!netowrk) return null; - return SUPPORTED_ETH_CHAINS.includes(netowrk) ? Network.ETHEREUM : null; + if (!netowrk) { + return null; + } + return SUPPORTED_ETH_CHAINS.includes(netowrk as Networks) + ? Networks.ETHEREUM + : null; } export async function getNonEvmAccounts( instances: Provider ): Promise { const nonEvmNetworks = SUPPORTED_NETWORKS.filter( - (net: Network) => net !== Network.ETHEREUM + (net: Network) => net !== Networks.ETHEREUM ); - const promises: Promise[] = nonEvmNetworks.map( - (network: Network) => { + const promises: Promise[] = nonEvmNetworks + .filter( + (network: Network) => + // Ensure the instance is defined + instances.get(network) !== undefined + ) + .map(async (network: Network) => { return new Promise((resolve, reject) => { const instance = instances.get(network); instance.request( @@ -43,7 +76,7 @@ export async function getNonEvmAccounts( params: [], }, (error: any, accounts: any) => { - if (!!error) { + if (error) { reject(error); return error; } @@ -57,15 +90,14 @@ export async function getNonEvmAccounts( } ); }); - } - ); + }); const results = await Promise.all(promises); return results; } -export function xdefiTransfer( +export async function xdefiTransfer( blockchain: string, ticker: string, from: string, @@ -74,7 +106,7 @@ export function xdefiTransfer( recipientAddress: string | null, provider: any, method: string, - memo: string | null + memo?: string ): Promise { return new Promise(function (resolve, reject) { const params = { @@ -82,18 +114,21 @@ export function xdefiTransfer( from: from, amount: { amount: amount, decimals: decimals }, memo: memo, - // recipient: to, } as any; - if (recipientAddress) params.recipient = recipientAddress; + if (recipientAddress) { + params.recipient = recipientAddress; + } provider.request( { method: method, params: [params] }, (error: any, result: any) => { - if (error) + if (error) { reject( new SignerError(SignerErrorCode.SEND_TX_ERROR, undefined, error) ); - else resolve(result); + } else { + resolve(result); + } } ); }); diff --git a/wallets/provider-xdefi/src/index.ts b/wallets/provider-xdefi/src/index.ts index 879902b7f1..a4abca6956 100644 --- a/wallets/provider-xdefi/src/index.ts +++ b/wallets/provider-xdefi/src/index.ts @@ -1,28 +1,35 @@ -import { - getBlockChainNameFromId, - Network, - WalletType, +import type { + CanEagerConnect, CanSwitchNetwork, Connect, ProviderConnectResult, Subscribe, SwitchNetwork, + WalletInfo, +} from '@rango-dev/wallets-shared'; + +import { + canEagerlyConnectToEvm, canSwitchNetworkToEvm, chooseInstance, + getBlockChainNameFromId, + getCosmosAccounts, getEvmAccounts, - switchNetworkForEvm, getSolanaAccounts, + Networks, + switchNetworkForEvm, + WalletTypes, XDEFI_WALLET_SUPPORTED_NATIVE_CHAINS, - WalletInfo, } from '@rango-dev/wallets-shared'; -import { SUPPORTED_ETH_CHAINS } from './constants'; +import { type BlockchainMeta, type SignerFactory } from 'rango-types'; +import { cosmosBlockchains, isCosmosBlockchain } from 'rango-types'; -import { getNonEvmAccounts, xdefi as xdefi_instances } from './helpers'; -import signer from './signer'; -import { SignerFactory, BlockchainMeta } from 'rango-types'; +import { SUPPORTED_COSMOS_CHAINS, SUPPORTED_ETH_CHAINS } from './constants.js'; +import { getNonEvmAccounts, xdefi as xdefi_instances } from './helpers.js'; +import signer from './signer.js'; -const DEFAULT_NETWORK = Network.ETHEREUM; -const WALLET = WalletType.XDEFI; +const DEFAULT_NETWORK = Networks.ETHEREUM; +const WALLET = WalletTypes.XDEFI; export const config = { type: WALLET, @@ -32,11 +39,9 @@ export const config = { export const getInstance = xdefi_instances; export const connect: Connect = async ({ instance, meta }) => { - const ethInstance = chooseInstance(instance, meta, Network.ETHEREUM); - const solInstance = chooseInstance(instance, meta, Network.SOLANA); - if (!ethInstance || !ethInstance.__XDEFI) { - throw new Error("Please 'Prioritise' XDEFI and refresh the page."); - } + const ethInstance = chooseInstance(instance, meta, Networks.ETHEREUM); + const solInstance = chooseInstance(instance, meta, Networks.SOLANA); + const cosmosInstance = chooseInstance(instance, meta, Networks.COSMOS); const evmResult = await getEvmAccounts(ethInstance); const nonEvmResults = await getNonEvmAccounts(instance); @@ -45,7 +50,33 @@ export const connect: Connect = async ({ instance, meta }) => { meta, }); - return [evmResult, ...nonEvmResults, solanaAccounts as ProviderConnectResult]; + const cosmosAccounts: ProviderConnectResult[] = []; + if (cosmosInstance) { + const cosmosBlockchainMeta = meta.filter( + (blockchainMeta: BlockchainMeta) => + isCosmosBlockchain(blockchainMeta) && + SUPPORTED_COSMOS_CHAINS.includes(blockchainMeta.name as Networks) + ); + const requestedNetwork = Networks.COSMOS; + + const cosmosResult = await getCosmosAccounts({ + instance: cosmosInstance, + meta: cosmosBlockchainMeta, + network: requestedNetwork, + }); + if (Array.isArray(cosmosResult)) { + cosmosAccounts.push(...cosmosResult); + } else { + cosmosAccounts.push(cosmosResult); + } + } + + return [ + evmResult, + ...nonEvmResults, + solanaAccounts as ProviderConnectResult, + ...cosmosAccounts, + ]; }; export const subscribe: Subscribe = ({ @@ -54,49 +85,78 @@ export const subscribe: Subscribe = ({ updateChainId, connect, }) => { - const eth = chooseInstance(instance, meta, Network.ETHEREUM); - eth?.on('chainChanged', (chainId: string) => { - const network = getBlockChainNameFromId(chainId, meta) || Network.Unknown; + const handleChainChanged = (chainId: string) => { + const network = getBlockChainNameFromId(chainId, meta) || Networks.Unknown; + /* + *TODO: + *We are calling `connect` here because signer can't detect + *currect network, I guess the bug is in our signer and it + *gets the wrong network by calling a wrong method or something. + *Anyways, this works for now, maybe we can reconsider it in future + *Whenever we refactored the signer code as well. + */ + /* - TODO: - We are calling `connect` here because signer can't detect - currect network, I guess the bug is in our signer and it - gets the wrong network by calling a wrong method or something. - Anyways, this works for now, maybe we can reconsider it in future - Whenever we refactored the signer code as well. - */ - - // we need to update `network` first, if not, it will goes through - // the switching network and will open unneccessary pop ups. + * we need to update `network` first, if not, it will goes through + * the switching network and will open unneccessary pop ups. + */ updateChainId(chainId); connect(network); - }); + }; + const eth = chooseInstance(instance, meta, Networks.ETHEREUM); + eth?.on?.('chainChanged', handleChainChanged); + + return () => { + eth?.off?.('chainChanged', handleChainChanged); + }; }; export const switchNetwork: SwitchNetwork = switchNetworkForEvm; export const canSwitchNetworkTo: CanSwitchNetwork = canSwitchNetworkToEvm; -export const getSigners: (provider: any) => SignerFactory = signer; +export const getSigners: (provider: any) => Promise = signer; +export const canEagerConnect: CanEagerConnect = async ({ instance, meta }) => { + const evm_instance = chooseInstance(instance, meta, Networks.ETHEREUM); + if (evm_instance) { + return canEagerlyConnectToEvm({ instance: evm_instance, meta }); + } + return Promise.resolve(false); +}; export const getWalletInfo: (allBlockChains: BlockchainMeta[]) => WalletInfo = ( allBlockChains -) => ({ - name: 'XDefi', - img: 'https://raw.githubusercontent.com/rango-exchange/rango-types/main/assets/icons/wallets/xdefi.png', - installLink: { - CHROME: - 'https://chrome.google.com/webstore/detail/xdefi-wallet/hmeobnfnfcmdkdcmlblgagmfpfboieaf', - BRAVE: - 'https://chrome.google.com/webstore/detail/xdefi-wallet/hmeobnfnfcmdkdcmlblgagmfpfboieaf', - DEFAULT: 'https://xdefi.io/', - }, - color: '#0646c7', - supportedChains: allBlockChains.filter((blockchainMeta) => - [ - ...SUPPORTED_ETH_CHAINS, - ...XDEFI_WALLET_SUPPORTED_NATIVE_CHAINS, - Network.SOLANA, - ].includes(blockchainMeta.name as Network) - ), -}); +) => { + const supportedCosmosChains = cosmosBlockchains(allBlockChains).filter( + (blockchainMeta: BlockchainMeta) => + !!blockchainMeta.info && + SUPPORTED_COSMOS_CHAINS.includes(blockchainMeta.name as Networks) + ); + + const supportedChains = [ + ...allBlockChains.filter((blockchainMeta) => + [ + ...SUPPORTED_ETH_CHAINS, + ...XDEFI_WALLET_SUPPORTED_NATIVE_CHAINS, + Networks.SOLANA, + ].includes(blockchainMeta.name as Networks) + ), + ...supportedCosmosChains, + ]; + return { + name: 'Ctrl', + img: 'https://raw.githubusercontent.com/rango-exchange/assets/main/wallets/xdefi/icon.svg', + installLink: { + CHROME: + 'https://chromewebstore.google.com/detail/ctrl-wallet/hmeobnfnfcmdkdcmlblgagmfpfboieaf', + BRAVE: + 'https://chromewebstore.google.com/detail/ctrl-wallet/hmeobnfnfcmdkdcmlblgagmfpfboieaf', + DEFAULT: 'https://ctrl.xyz/', + }, + color: '#0646c7', + supportedChains, + }; +}; + +// it is required in /examples/queue-manager-demo +export { SUPPORTED_ETH_CHAINS } from './constants.js'; diff --git a/wallets/provider-xdefi/src/signer.ts b/wallets/provider-xdefi/src/signer.ts index 5a8c4a9ef5..f40627c282 100644 --- a/wallets/provider-xdefi/src/signer.ts +++ b/wallets/provider-xdefi/src/signer.ts @@ -1,18 +1,25 @@ -import { DefaultEvmSigner } from '@rango-dev/signer-evm'; -import { DefaultSolanaSigner } from '@rango-dev/signer-solana'; -import { Network, getNetworkInstance } from '@rango-dev/wallets-shared'; -import { SignerFactory, TransactionType as TxType } from 'rango-types'; -import { CustomCosmosSigner } from './cosmos-signer'; -import { CustomTransferSigner } from './utxo-signer'; +import type { SignerFactory } from 'rango-types'; + +import { getNetworkInstance, Networks } from '@rango-dev/wallets-shared'; +import { DefaultSignerFactory, TransactionType as TxType } from 'rango-types'; + +import { CustomCosmosSigner } from './cosmos-signer.js'; +import { CustomSolanaSigner } from './solana-signer.js'; +import { CustomTransferSigner } from './utxo-signer.js'; + +export default async function getSigners( + provider: any +): Promise { + const ethProvider = getNetworkInstance(provider, Networks.ETHEREUM); + const solProvider = getNetworkInstance(provider, Networks.SOLANA); + + const signers = new DefaultSignerFactory(); + const { DefaultEvmSigner } = await import('@rango-dev/signer-evm'); -export default function getSigners(provider: any): SignerFactory { - const ethProvider = getNetworkInstance(provider, Network.ETHEREUM); - const solProvider = getNetworkInstance(provider, Network.SOLANA); - const cosmosProvider = getNetworkInstance(provider, Network.COSMOS); - const signers = new SignerFactory(); signers.registerSigner(TxType.EVM, new DefaultEvmSigner(ethProvider)); - signers.registerSigner(TxType.SOLANA, new DefaultSolanaSigner(solProvider)); - signers.registerSigner(TxType.COSMOS, new CustomCosmosSigner(cosmosProvider)); + signers.registerSigner(TxType.SOLANA, new CustomSolanaSigner(solProvider)); + // passed provider for transfer as it comprises several signers + signers.registerSigner(TxType.COSMOS, new CustomCosmosSigner(provider)); // passed provider for transfer as it comprises several signers signers.registerSigner(TxType.TRANSFER, new CustomTransferSigner(provider)); return signers; diff --git a/wallets/provider-xdefi/src/solana-signer.ts b/wallets/provider-xdefi/src/solana-signer.ts new file mode 100644 index 0000000000..2713bc04ec --- /dev/null +++ b/wallets/provider-xdefi/src/solana-signer.ts @@ -0,0 +1,17 @@ +import { DefaultSolanaSigner } from '@rango-dev/signer-solana'; +import base58 from 'bs58'; + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +type SolanaExternalProvider = any; + +export class CustomSolanaSigner extends DefaultSolanaSigner { + constructor(provider: SolanaExternalProvider) { + super(provider); + } + + async signMessage(msg: string): Promise { + const encodedMessage = new TextEncoder().encode(msg); + const { signature } = await this.provider.signMessage(encodedMessage); + return base58.encode(signature); + } +} diff --git a/wallets/provider-xdefi/src/utxo-signer.ts b/wallets/provider-xdefi/src/utxo-signer.ts index cb07bdf5e6..c6f113c4eb 100644 --- a/wallets/provider-xdefi/src/utxo-signer.ts +++ b/wallets/provider-xdefi/src/utxo-signer.ts @@ -1,13 +1,18 @@ -import { GenericSigner, SignerError, Transfer } from 'rango-types'; -import { xdefiTransfer } from './helpers'; +import type { Networks } from '@rango-dev/wallets-shared'; +import type { GenericSigner, Transfer } from 'rango-types'; + import { - Network, - XDEFI_WALLET_SUPPORTED_NATIVE_CHAINS, getNetworkInstance, + XDEFI_WALLET_SUPPORTED_NATIVE_CHAINS, } from '@rango-dev/wallets-shared'; +import { SignerError } from 'rango-types'; -// TODO - replace with real type -// tslint:disable-next-line: no-any +import { xdefiTransfer } from './helpers.js'; + +/* + * TODO - replace with real type + * tslint:disable-next-line: no-any + */ type TransferExternalProvider = any; export class CustomTransferSigner implements GenericSigner { @@ -20,18 +25,18 @@ export class CustomTransferSigner implements GenericSigner { throw SignerError.UnimplementedError('signMessage'); } - async signAndSendTx(tx: Transfer): Promise { + async signAndSendTx(tx: Transfer): Promise<{ hash: string }> { const { blockchain } = tx.asset; // Everything except ETH - if (!XDEFI_WALLET_SUPPORTED_NATIVE_CHAINS.includes(blockchain as Network)) + if ( + !XDEFI_WALLET_SUPPORTED_NATIVE_CHAINS.includes(blockchain as Networks) + ) { throw new Error( `blockchain: ${blockchain} transfer not implemented yet.` ); - const transferProvider = getNetworkInstance( - this.provider, - blockchain as Network - ); + } + const transferProvider = getNetworkInstance(this.provider, blockchain); const { method, @@ -43,7 +48,7 @@ export class CustomTransferSigner implements GenericSigner { asset, } = tx; - return xdefiTransfer( + const hash = await xdefiTransfer( blockchain, asset.ticker, from, @@ -52,7 +57,8 @@ export class CustomTransferSigner implements GenericSigner { recipientAddress, transferProvider, method, - memo + memo ?? undefined ); + return { hash }; } } diff --git a/wallets/provider-xdefi/tsconfig.build.json b/wallets/provider-xdefi/tsconfig.build.json new file mode 100644 index 0000000000..d9181ce0cd --- /dev/null +++ b/wallets/provider-xdefi/tsconfig.build.json @@ -0,0 +1,11 @@ +{ + // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs + "extends": "../../tsconfig.libnext.json", + "include": ["src", "types", "../../global-wallets-env.d.ts"], + "compilerOptions": { + "outDir": "dist", + "rootDir": "./src", + "lib": ["dom", "esnext"] + // match output dir to input dir. e.g. dist/index instead of dist/src/index + } +} diff --git a/wallets/provider-xdefi/tsconfig.json b/wallets/provider-xdefi/tsconfig.json index 365489616a..a3a0b0f59d 100644 --- a/wallets/provider-xdefi/tsconfig.json +++ b/wallets/provider-xdefi/tsconfig.json @@ -1,35 +1 @@ -{ - // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs - "include": ["src", "types", "../../global-wallets-env.d.ts"], - "compilerOptions": { - "module": "esnext", - "lib": ["dom", "esnext"], - "importHelpers": true, - // output .d.ts declaration files for consumers - "declaration": true, - // output .js.map sourcemap files for consumers - "sourceMap": true, - // match output dir to input dir. e.g. dist/index instead of dist/src/index - "rootDir": "./src", - // stricter type-checking for stronger correctness. Recommended by TS - "strict": true, - // linter checks for common issues - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true, - // noUnused* overlap with @typescript-eslint/no-unused-vars, can disable if duplicative - "noUnusedLocals": true, - "noUnusedParameters": true, - // use Node's module resolution algorithm, instead of the legacy TS one - "moduleResolution": "node", - // transpile JSX to React.createElement - "jsx": "react", - // interop between ESM and CJS modules. Recommended by TS - "esModuleInterop": true, - // significant perf increase by skipping checking .d.ts files, particularly those in node_modules. Recommended by TS - "skipLibCheck": true, - // error out if import and file system have a casing mismatch. Recommended by TS - "forceConsistentCasingInFileNames": true, - // `tsdx build` ignores this option, but it is commonly used when type-checking separately with `tsc` - "noEmit": true, - } -} +{ "extends": "./tsconfig.build.json", "include": ["src", "tests"] } diff --git a/wallets/react/CHANGELOG.md b/wallets/react/CHANGELOG.md new file mode 100644 index 0000000000..3aabf838dd --- /dev/null +++ b/wallets/react/CHANGELOG.md @@ -0,0 +1,109 @@ +# [0.27.0](https://github.com/rango-exchange/rango-client/compare/wallets-react@0.26.0...wallets-react@0.27.0) (2024-12-30) + + + +# [0.26.0](https://github.com/rango-exchange/rango-client/compare/wallets-react@0.25.0...wallets-react@0.26.0) (2024-11-27) + + + +# [0.25.0](https://github.com/rango-exchange/rango-client/compare/wallets-react@0.24.0...wallets-react@0.25.0) (2024-11-12) + + + +# [0.24.0](https://github.com/rango-exchange/rango-client/compare/wallets-react@0.23.0...wallets-react@0.24.0) (2024-10-12) + + +### Bug Fixes + +* bump sdk and fix type issues ([d442208](https://github.com/rango-exchange/rango-client/commit/d4422083bf5dd27d5f509ce1db7f9560d05428c8)) + + +### Performance Improvements + +* lazy load signer packages ([7b88f18](https://github.com/rango-exchange/rango-client/commit/7b88f1834f7b29b4b81ab6c81a07bb88e8ccf55c)) + + + +# [0.23.0](https://github.com/rango-exchange/rango-client/compare/wallets-react@0.22.0...wallets-react@0.23.0) (2024-09-10) + + + +# [0.22.0](https://github.com/rango-exchange/rango-client/compare/wallets-react@0.21.1...wallets-react@0.22.0) (2024-08-11) + + + +## [0.21.1](https://github.com/rango-exchange/rango-client/compare/wallets-react@0.21.0...wallets-react@0.21.1) (2024-07-14) + + + +# [0.21.0](https://github.com/rango-exchange/rango-client/compare/wallets-react@0.19.0...wallets-react@0.21.0) (2024-07-09) + + +### Features + +* add a modal for setting custom derivation path for ledger ([5b74ec0](https://github.com/rango-exchange/rango-client/commit/5b74ec049393ed74e3e7547edc72b68bd70b7dce)) + + + +# [0.20.0](https://github.com/rango-exchange/rango-client/compare/wallets-react@0.19.0...wallets-react@0.20.0) (2024-06-01) + + + +# [0.19.0](https://github.com/rango-exchange/rango-client/compare/wallets-react@0.18.0...wallets-react@0.19.0) (2024-05-14) + + +### Features + +* add solana to ledger ([77b6695](https://github.com/rango-exchange/rango-client/commit/77b6695758165f9258a0ba5bd3b2cf39b0b2aab5)) + + + +# [0.18.0](https://github.com/rango-exchange/rango-client/compare/wallets-react@0.17.0...wallets-react@0.18.0) (2024-04-24) + + + +# [0.17.0](https://github.com/rango-exchange/rango-client/compare/wallets-react@0.16.0...wallets-react@0.17.0) (2024-04-23) + + + +# [0.16.0](https://github.com/rango-exchange/rango-client/compare/wallets-react@0.15.0...wallets-react@0.16.0) (2024-04-09) + + + +# [0.15.0](https://github.com/rango-exchange/rango-client/compare/wallets-react@0.14.0...wallets-react@0.15.0) (2024-03-12) + + +### Bug Fixes + +* fix wallet connect namespace and switch network ([c8f31b3](https://github.com/rango-exchange/rango-client/commit/c8f31b3ddf4ceeaf745bc089f530b6a4b1eb9637)) + + + +# [0.14.0](https://github.com/rango-exchange/rango-client/compare/wallets-react@0.13.0...wallets-react@0.14.0) (2024-02-20) + + + +# [0.13.0](https://github.com/rango-exchange/rango-client/compare/wallets-react@0.12.0...wallets-react@0.13.0) (2024-02-07) + + + +# [0.12.0](https://github.com/rango-exchange/rango-client/compare/wallets-react@0.11.0...wallets-react@0.12.0) (2024-01-22) + + +### Bug Fixes + +* cleanup wallets' subscriber when setProvider get null ([88d6a42](https://github.com/rango-exchange/rango-client/commit/88d6a423c49b34b3d9ff567e22df36c3b009bb76)) + + + +# [0.11.0](https://github.com/rango-exchange/rango-client/compare/wallets-react@0.10.0...wallets-react@0.11.0) (2023-12-24) + + +### Bug Fixes + +* fix HMR for widget and playground ([8524820](https://github.com/rango-exchange/rango-client/commit/8524820f10cf0b8921f3db0c4f620ff98daa4103)) +* handle safe wallet in widget ([52fcca4](https://github.com/rango-exchange/rango-client/commit/52fcca49315f7e2edb4655ae7b9cd0792c2800d7)) +* handle switch network flow for wallet-connect ([8c4a17b](https://github.com/rango-exchange/rango-client/commit/8c4a17b47b2919820a4e0726f6d1c48b8994abe3)) + + + diff --git a/wallets/react/package.json b/wallets/react/package.json new file mode 100644 index 0000000000..23b74be341 --- /dev/null +++ b/wallets/react/package.json @@ -0,0 +1,44 @@ +{ + "name": "@rango-dev/wallets-react", + "version": "0.26.1-next.9", + "license": "MIT", + "type": "module", + "source": "./src/index.ts", + "main": "./dist/index.js", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "default": "./dist/index.js" + } + }, + "files": [ + "dist", + "src" + ], + "scripts": { + "build": "node ../../scripts/build/command.mjs --path wallets/react", + "ts-check": "tsc --declaration --emitDeclarationOnly -p ./tsconfig.json", + "clean": "rimraf dist", + "format": "prettier --write '{.,src}/**/*.{ts,tsx}'", + "lint": "eslint \"**/*.{ts,tsx}\" --ignore-path ../../.eslintignore", + "test": "vitest", + "coverage": "vitest run --coverage" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0" + }, + "dependencies": { + "@rango-dev/wallets-core": "^0.40.1-next.8", + "@rango-dev/wallets-shared": "^0.40.1-next.6", + "rango-types": "^0.1.74" + }, + "devDependencies": { + "@types/react": "^18.0.25", + "@types/react-dom": "^18.0.25" + }, + "publishConfig": { + "access": "public" + } +} diff --git a/wallets/react/readme.md b/wallets/react/readme.md new file mode 100644 index 0000000000..fa9ffcfd00 --- /dev/null +++ b/wallets/react/readme.md @@ -0,0 +1,3 @@ +# @rango-dev/wallets-react + +React package for handling web3 wallets supported by Rango diff --git a/wallets/react/src/hub/autoConnect.ts b/wallets/react/src/hub/autoConnect.ts new file mode 100644 index 0000000000..5c51e249b8 --- /dev/null +++ b/wallets/react/src/hub/autoConnect.ts @@ -0,0 +1,186 @@ +import type { AllProxiedNamespaces } from './types.js'; +import type { UseAdapterParams } from './useHubAdapter.js'; +import type { Hub } from '@rango-dev/wallets-core'; +import type { + LegacyNamespaceInputForConnect, + LegacyProviderInterface, +} from '@rango-dev/wallets-core/legacy'; +import type { Namespace } from '@rango-dev/wallets-core/namespaces/common'; +import type { WalletType } from '@rango-dev/wallets-shared'; + +import { + legacyEagerConnectHandler, + legacyIsEvmNamespace, +} from '@rango-dev/wallets-core/legacy'; + +import { HUB_LAST_CONNECTED_WALLETS } from '../legacy/mod.js'; + +import { sequentiallyRun } from './helpers.js'; +import { LastConnectedWalletsFromStorage } from './lastConnectedWallets.js'; +import { convertNamespaceNetworkToEvmChainId } from './utils.js'; + +/** + * Run `.connect` action on some selected namespaces (passed as param) for a provider. + */ +async function eagerConnect( + type: string, + namespacesInput: LegacyNamespaceInputForConnect[] | undefined, + params: { + getHub: () => Hub; + allBlockChains: UseAdapterParams['allBlockChains']; + } +) { + const { getHub, allBlockChains } = params; + const wallet = getHub().get(type); + if (!wallet) { + throw new Error( + `You should add ${type} to provider first then call 'connect'.` + ); + } + + if (!namespacesInput) { + throw new Error('Passing namespace to `connect` is required. '); + } + + const targetNamespaces: [ + LegacyNamespaceInputForConnect, + AllProxiedNamespaces + ][] = []; + namespacesInput.forEach((namespaceInput) => { + const targetNamespace: Namespace = namespaceInput.namespace; + + const result = wallet.findByNamespace(targetNamespace); + + if (!result) { + throw new Error( + `We couldn't find any provider matched with your request namespace. (requested namespace: ${namespaceInput.namespace})` + ); + } + + targetNamespaces.push([namespaceInput, result]); + }); + + const finalResult = targetNamespaces.map(([info, namespace]) => { + const evmChain = legacyIsEvmNamespace(info) + ? convertNamespaceNetworkToEvmChainId(info, allBlockChains || []) + : undefined; + const chain = evmChain || info.network; + + return async () => await namespace.connect(chain); + }); + + /** + * Sometimes calling methods on a instance in parallel, would cause an error in wallet. + * We are running a method at a time to make sure we are covering this. + * e.g. when we are trying to eagerConnect evm and solana on phantom at the same time, the last namespace throw an error. + */ + return await sequentiallyRun(finalResult); +} + +/* + * + * Get last connected wallets from storage then run `.connect` on them if `.canEagerConnect` returns true. + * + * Note 1: + * - It currently use `.getInstance`, `.canEagerConenct` and `getWalletInfo()`.supported chains from legacy provider implementation. + * - For each namespace, we don't have a separate `.canEagerConnect`. it's only one and will be used for all namespaces. + */ +export async function autoConnect(deps: { + getHub: () => Hub; + allBlockChains: UseAdapterParams['allBlockChains']; + getLegacyProvider: (type: string) => LegacyProviderInterface; + wallets?: (WalletType | LegacyProviderInterface)[]; +}): Promise { + const { getHub, allBlockChains, getLegacyProvider, wallets } = deps; + + // Getting connected wallets from storage + const lastConnectedWalletsFromStorage = new LastConnectedWalletsFromStorage( + HUB_LAST_CONNECTED_WALLETS + ); + const lastConnectedWallets = lastConnectedWalletsFromStorage.list(); + const walletIds = Object.keys(lastConnectedWallets); + + const walletsToRemoveFromPersistance: string[] = []; + + if (walletIds.length) { + const eagerConnectQueue: any[] = []; + + // Run `.connect` if `.canEagerConnect` returns `true`. + walletIds.forEach((providerName) => { + if (wallets && !wallets.includes(providerName)) { + console.warn( + 'Trying to run auto connect for a wallet which is not included in config. Desired wallet:', + providerName + ); + walletsToRemoveFromPersistance.push(providerName); + return; + } + + const legacyProvider = getLegacyProvider(providerName); + + let legacyInstance: any; + try { + legacyInstance = legacyProvider.getInstance(); + } catch (e) { + console.warn( + "It seems instance isn't available yet. This can happens when extension not loaded yet (sometimes when opening browser for first time) or extension is disabled." + ); + return; + } + + const namespaces: LegacyNamespaceInputForConnect[] = lastConnectedWallets[ + providerName + ].map((namespace) => ({ + namespace: namespace.namsepace, + network: namespace.network, + })); + + const canEagerConnect = async () => { + if (!legacyProvider.canEagerConnect) { + throw new Error( + `${providerName} provider hasn't implemented canEagerConnect.` + ); + } + return await legacyProvider.canEagerConnect({ + instance: legacyInstance, + meta: legacyProvider.getWalletInfo(allBlockChains || []) + .supportedChains, + }); + }; + const connectHandler = async () => { + return eagerConnect(providerName, namespaces, { + allBlockChains, + getHub, + }); + }; + + eagerConnectQueue.push( + legacyEagerConnectHandler({ + canEagerConnect, + connectHandler, + providerName, + }).catch((e) => { + walletsToRemoveFromPersistance.push(providerName); + throw e; + }) + ); + }); + + await Promise.allSettled(eagerConnectQueue); + + /* + *After successfully connecting to at least one wallet, + *we will removing the other wallets from persistence. + *If we are unable to connect to any wallet, + *the persistence will not be removed and the eager connection will be retried with another page load. + */ + const canRestoreAnyConnection = + walletIds.length > walletsToRemoveFromPersistance.length; + + if (canRestoreAnyConnection) { + lastConnectedWalletsFromStorage.removeWallets( + walletsToRemoveFromPersistance + ); + } + } +} diff --git a/wallets/react/src/hub/constants.ts b/wallets/react/src/hub/constants.ts new file mode 100644 index 0000000000..325f9c5f4e --- /dev/null +++ b/wallets/react/src/hub/constants.ts @@ -0,0 +1,2 @@ +export const LEGACY_LAST_CONNECTED_WALLETS = 'last-connected-wallets'; +export const HUB_LAST_CONNECTED_WALLETS = 'hub-v1-last-connected-wallets'; diff --git a/wallets/react/src/hub/helpers.ts b/wallets/react/src/hub/helpers.ts new file mode 100644 index 0000000000..2a9cfa6c7a --- /dev/null +++ b/wallets/react/src/hub/helpers.ts @@ -0,0 +1,67 @@ +import type { AllProxiedNamespaces } from './types.js'; +import type { + Accounts, + AccountsWithActiveChain, +} from '@rango-dev/wallets-core/namespaces/common'; + +import { legacyFormatAddressWithNetwork as formatAddressWithNetwork } from '@rango-dev/wallets-core/legacy'; +import { CAIP } from '@rango-dev/wallets-core/utils'; + +export function mapCaipNamespaceToLegacyNetworkName( + chainId: CAIP.ChainIdParams | string +): string { + if (typeof chainId === 'string') { + return chainId; + } + const useNamespaceAsNetworkFor = ['solana']; + + if (useNamespaceAsNetworkFor.includes(chainId.namespace.toLowerCase())) { + return chainId.namespace.toUpperCase(); + } + + if (chainId.namespace.toLowerCase() === 'eip155') { + return 'ETH'; + } + + return chainId.reference; +} + +/** + * CAIP's accountId has a format like this: eip155:1:0xab16a96D359eC26a11e2C2b3d8f8B8942d5Bfcdb + * Legacy format is something like this: ETH:0xab16a96D359eC26a11e2C2b3d8f8B8942d5Bfcdb + * This function will try to convert this two format. + * + * @see https://github.com/ChainAgnostic/CAIPs/blob/main/CAIPs/caip-10.md + */ +export function fromAccountIdToLegacyAddressFormat(account: string): string { + const { chainId, address } = CAIP.AccountId.parse(account); + const network = mapCaipNamespaceToLegacyNetworkName(chainId); + return formatAddressWithNetwork(address, network); +} + +/** + * Getting a list of (lazy) promises and run them one after another. + */ +export async function sequentiallyRun Promise>( + promises: Array +): Promise Promise ? R : never>> { + const result = await promises.reduce(async (prev, task) => { + const previousResults = await prev; + const taskResult = await task(); + + return [...previousResults, taskResult]; + }, Promise.resolve([]) as Promise); + return result; +} + +export function isConnectResultEvm( + result: Awaited> +): result is AccountsWithActiveChain { + return typeof result === 'object' && !Array.isArray(result); +} + +export function isConnectResultSolana( + result: Awaited> +): result is Accounts { + return Array.isArray(result); +} diff --git a/wallets/react/src/hub/lastConnectedWallets.ts b/wallets/react/src/hub/lastConnectedWallets.ts new file mode 100644 index 0000000000..6c50600337 --- /dev/null +++ b/wallets/react/src/hub/lastConnectedWallets.ts @@ -0,0 +1,124 @@ +import type { Namespace } from '@rango-dev/wallets-core/namespaces/common'; + +import { Persistor } from '@rango-dev/wallets-core/legacy'; + +import { + HUB_LAST_CONNECTED_WALLETS, + LEGACY_LAST_CONNECTED_WALLETS, +} from './constants.js'; + +export interface NamespaceInput { + namsepace: Namespace; + network: string | undefined; +} + +export interface LastConnectedWalletsStorage { + [providerId: string]: NamespaceInput[]; +} + +export type LegacyLastConnectedWalletsStorage = string[]; + +/** + * We are doing some certain actions on storage for `last-connected-wallets` key. + * This class helps us to define them in one place and also it has support for both legacy and hub. + */ +export class LastConnectedWalletsFromStorage { + #storageKey: string; + + constructor(storageKey: string) { + this.#storageKey = storageKey; + } + + addWallet(providerId: string, namespaces: NamespaceInput[]): void { + if (this.#storageKey === HUB_LAST_CONNECTED_WALLETS) { + return this.#addWalletToHub(providerId, namespaces); + } else if (this.#storageKey === LEGACY_LAST_CONNECTED_WALLETS) { + return this.#addWalletToLegacy(providerId); + } + throw new Error('Not implemented'); + } + removeWallets(providerIds?: string[]): void { + if (this.#storageKey === HUB_LAST_CONNECTED_WALLETS) { + return this.#removeWalletsFromHub(providerIds); + } else if (this.#storageKey === LEGACY_LAST_CONNECTED_WALLETS) { + return this.#removeWalletsFromLegacy(providerIds); + } + throw new Error('Not implemented'); + } + list(): LastConnectedWalletsStorage { + if (this.#storageKey === HUB_LAST_CONNECTED_WALLETS) { + return this.#listFromHub(); + } else if (this.#storageKey === LEGACY_LAST_CONNECTED_WALLETS) { + return this.#listFromLegacy(); + } + throw new Error('Not implemented'); + } + + #listFromLegacy(): LastConnectedWalletsStorage { + const persistor = new Persistor(); + const lastConnectedWallets = + persistor.getItem(LEGACY_LAST_CONNECTED_WALLETS) || []; + const output: LastConnectedWalletsStorage = {}; + lastConnectedWallets.forEach((provider) => { + // Setting empty namespaces + output[provider] = []; + }); + return output; + } + #listFromHub(): LastConnectedWalletsStorage { + const persistor = new Persistor(); + const lastConnectedWallets = + persistor.getItem(HUB_LAST_CONNECTED_WALLETS) || {}; + return lastConnectedWallets; + } + #addWalletToHub(providerId: string, namespaces: NamespaceInput[]): void { + const storage = new Persistor(); + const data = storage.getItem(this.#storageKey) || {}; + + storage.setItem(this.#storageKey, { + ...data, + [providerId]: namespaces, + }); + } + #addWalletToLegacy(providerId: string): void { + const storage = new Persistor(); + const data = storage.getItem(this.#storageKey) || []; + + storage.setItem(LEGACY_LAST_CONNECTED_WALLETS, data.concat(providerId)); + } + #removeWalletsFromHub(providerIds?: string[]): void { + const persistor = new Persistor(); + const storageState = persistor.getItem(this.#storageKey) || {}; + + // Remove all wallets + if (!providerIds) { + persistor.setItem(this.#storageKey, {}); + return; + } + + // Remove some of the wallets + providerIds.forEach((providerId) => { + if (storageState[providerId]) { + delete storageState[providerId]; + } + }); + + persistor.setItem(this.#storageKey, storageState); + } + #removeWalletsFromLegacy(providerIds?: string[]): void { + const persistor = new Persistor(); + const storageState = persistor.getItem(this.#storageKey) || []; + + // Remove all wallets + if (!providerIds) { + persistor.setItem(this.#storageKey, []); + return; + } + + // Remove some of the wallets + persistor.setItem( + LEGACY_LAST_CONNECTED_WALLETS, + storageState.filter((wallet) => !providerIds.includes(wallet)) + ); + } +} diff --git a/wallets/react/src/hub/mod.ts b/wallets/react/src/hub/mod.ts new file mode 100644 index 0000000000..019b402a10 --- /dev/null +++ b/wallets/react/src/hub/mod.ts @@ -0,0 +1,2 @@ +export { separateLegacyAndHubProviders, findProviderByType } from './utils.js'; +export { useHubAdapter } from './useHubAdapter.js'; diff --git a/wallets/react/src/hub/types.ts b/wallets/react/src/hub/types.ts new file mode 100644 index 0000000000..b412ca477b --- /dev/null +++ b/wallets/react/src/hub/types.ts @@ -0,0 +1,12 @@ +import type { + CommonNamespaces, + FindProxiedNamespace, + ProviderInfo, +} from '@rango-dev/wallets-core'; + +export type AllProxiedNamespaces = FindProxiedNamespace< + keyof CommonNamespaces, + CommonNamespaces +>; + +export type ExtensionLink = keyof ProviderInfo['extensions']; diff --git a/wallets/react/src/hub/useHubAdapter.ts b/wallets/react/src/hub/useHubAdapter.ts new file mode 100644 index 0000000000..11a9ea6c78 --- /dev/null +++ b/wallets/react/src/hub/useHubAdapter.ts @@ -0,0 +1,353 @@ +import type { AllProxiedNamespaces, ExtensionLink } from './types.js'; +import type { Providers } from '../index.js'; +import type { Provider } from '@rango-dev/wallets-core'; +import type { LegacyNamespaceInputForConnect } from '@rango-dev/wallets-core/legacy'; +import type { VersionedProviders } from '@rango-dev/wallets-core/utils'; + +import { type WalletInfo } from '@rango-dev/wallets-shared'; +import { useEffect, useRef, useState } from 'react'; + +import { + type ConnectResult, + HUB_LAST_CONNECTED_WALLETS, + type ProviderContext, + type ProviderProps, +} from '../legacy/mod.js'; +import { useAutoConnect } from '../legacy/useAutoConnect.js'; + +import { autoConnect } from './autoConnect.js'; +import { fromAccountIdToLegacyAddressFormat } from './helpers.js'; +import { + LastConnectedWalletsFromStorage, + type NamespaceInput, +} from './lastConnectedWallets.js'; +import { useHubRefs } from './useHubRefs.js'; +import { + checkHubStateAndTriggerEvents, + getLegacyProvider, + transformHubResultToLegacyResult, + tryConvertNamespaceNetworkToChainInfo, +} from './utils.js'; + +export type UseAdapterParams = Omit & { + providers: Provider[]; + /** This is only will be used to access some parts of the legacy provider that doesn't exists in Hub. */ + allVersionedProviders: VersionedProviders[]; +}; + +export function useHubAdapter(params: UseAdapterParams): ProviderContext { + const { getStore, getHub } = useHubRefs(params.providers); + const [, rerender] = useState(0); + // useEffect will run `subscribe` once, so we need a reference and mutate the value if it's changes. + const dataRef = useRef({ + onUpdateState: params.onUpdateState, + allVersionedProviders: params.allVersionedProviders, + allBlockChains: params.allBlockChains, + }); + + useEffect(() => { + dataRef.current = { + onUpdateState: params.onUpdateState, + allVersionedProviders: params.allVersionedProviders, + allBlockChains: params.allBlockChains, + }; + }, [params]); + + // Initialize instances + useEffect(() => { + const runOnInit = () => { + getHub().init(); + + rerender((currentRender) => currentRender + 1); + }; + + // Then will call init whenever page is ready. + const initHubWhenPageIsReady = (event: Event) => { + // Then will call init whenever page is ready. + if ( + event.target && + (event.target as Document).readyState === 'complete' + ) { + runOnInit(); + document.removeEventListener( + 'readystatechange', + initHubWhenPageIsReady + ); + } + }; + + // Try to run, maybe it's ready. + runOnInit(); + + /* + * Try again when the page has been completely loaded. + * Some of wallets, take some time to be fully injected and loaded. + */ + document.addEventListener('readystatechange', initHubWhenPageIsReady); + + getStore().subscribe((curr, prev) => { + if (dataRef.current.onUpdateState) { + checkHubStateAndTriggerEvents( + getHub(), + curr, + prev, + dataRef.current.onUpdateState, + dataRef.current.allVersionedProviders, + dataRef.current.allBlockChains + ); + } + rerender((currentRender) => currentRender + 1); + }); + }, []); + + useAutoConnect({ + autoConnect: params.autoConnect, + allBlockChains: params.allBlockChains, + autoConnectHandler: () => { + void autoConnect({ + getLegacyProvider: getLegacyProvider.bind( + null, + params.allVersionedProviders + ), + allBlockChains: params.allBlockChains, + getHub, + wallets: params.configs?.wallets, + }); + }, + }); + + const lastConnectedWalletsFromStorage = new LastConnectedWalletsFromStorage( + HUB_LAST_CONNECTED_WALLETS + ); + + const api: ProviderContext = { + canSwitchNetworkTo(type, network) { + const provider = getLegacyProvider(params.allVersionedProviders, type); + const switchTo = provider.canSwitchNetworkTo; + + if (!switchTo) { + return false; + } + + return switchTo({ + network, + meta: params.allBlockChains || [], + provider: provider.getInstance(), + }); + }, + async connect(type, namespaces) { + const wallet = getHub().get(type); + if (!wallet) { + throw new Error( + `You should add ${type} to provider first then call 'connect'.` + ); + } + + if (!namespaces) { + throw new Error('Passing namespace to `connect` is required.'); + } + + // Check `namespace` and look into hub to see how it can match given namespace to hub namespace. + const targetNamespaces: [ + LegacyNamespaceInputForConnect, + AllProxiedNamespaces + ][] = []; + namespaces.forEach((namespace) => { + const targetNamespace = namespace.namespace; + + const result = wallet.findByNamespace(targetNamespace); + + if (!result) { + throw new Error( + `We couldn't find any provider matched with your request namespace. (requested namespace: ${namespace.namespace})` + ); + } + + targetNamespaces.push([namespace, result]); + }); + + // Keeping only namespaces that connected successfully, then we'll store them on storage for auto connect functionality. + const successfulyConnectedNamespaces: NamespaceInput[] = []; + + // Try to run `connect` on matched namespaces + const connectResultFromTargetNamespaces = targetNamespaces.map( + async ([namespaceInput, namespace]) => { + const network = tryConvertNamespaceNetworkToChainInfo( + namespaceInput, + params.allBlockChains || [] + ); + + /* + * `connect` can have different interfaces (e.g. Solana -> .connect(), EVM -> .connect("0x1") ), + * our assumption here is all the `connect` hasn't chain or if they have, they will accept it in first argument. + * By this assumption, always passing a chain should be problematic since it will be ignored if the namespace's `connect` hasn't chain. + */ + const result = namespace.connect(network); + return result + .then(transformHubResultToLegacyResult) + .then((res) => { + successfulyConnectedNamespaces.push({ + namsepace: namespaceInput.namespace, + network: namespaceInput.network, + }); + return res; + }); + } + ); + + // If Provider has support for auto connect, we will add the wallet to storage. + const legacyProvider = getLegacyProvider( + params.allVersionedProviders, + type + ); + + if (legacyProvider.canEagerConnect) { + void Promise.allSettled(connectResultFromTargetNamespaces).then(() => { + if (successfulyConnectedNamespaces.length > 0) { + lastConnectedWalletsFromStorage.addWallet( + type, + successfulyConnectedNamespaces + ); + } + }); + } + + const connectResultWithLegacyFormat = await Promise.all( + connectResultFromTargetNamespaces + ); + + return connectResultWithLegacyFormat; + }, + async disconnect(type) { + const wallet = getHub().get(type); + if (!wallet) { + throw new Error( + `You should add ${type} to provider first then call 'connect'.` + ); + } + + wallet.getAll().forEach((namespace) => { + return namespace.disconnect(); + }); + + if (params.autoConnect) { + lastConnectedWalletsFromStorage.removeWallets([type]); + } + }, + disconnectAll() { + throw new Error('`disconnectAll` not implemented'); + }, + async getSigners(type) { + const provider = getLegacyProvider(params.allVersionedProviders, type); + return provider.getSigners(provider.getInstance()); + }, + getWalletInfo(type) { + const wallet = getHub().get(type); + if (!wallet) { + throw new Error(`You should add ${type} to provider first.`); + } + + const info = wallet.info(); + if (!info) { + throw new Error('Your provider should have required `info`.'); + } + + const provider = getLegacyProvider(params.allVersionedProviders, type); + + const installLink: Exclude = { + DEFAULT: '', + }; + + // `extensions` in legacy format was uppercase and also `DEFAULT` was used instead of `homepage` + Object.keys(info.extensions).forEach((k) => { + const key = k as ExtensionLink; + + if (info.extensions[key] === 'homepage') { + installLink.DEFAULT = info.extensions[key] || ''; + } + + const allowedKeys: ExtensionLink[] = [ + 'firefox', + 'chrome', + 'brave', + 'edge', + ]; + if (allowedKeys.includes(key)) { + const upperCasedKey = key.toUpperCase() as keyof Exclude< + WalletInfo['installLink'], + string + >; + installLink[upperCasedKey] = info.extensions[key] || ''; + } + }); + + const walletInfoFromLegacy = provider.getWalletInfo( + params.allBlockChains || [] + ); + + return { + name: info.name, + img: info.icon, + installLink: installLink, + // We don't have this values anymore, fill them with some values that communicate this. + color: 'red', + supportedChains: walletInfoFromLegacy.supportedChains, + isContractWallet: false, + mobileWallet: false, + // if set to false here, it will not show the wallet in mobile in anyways. to be compatible with old behavior, undefined is more appropirate. + showOnMobile: undefined, + needsNamespace: walletInfoFromLegacy.needsNamespace, + needsDerivationPath: walletInfoFromLegacy.needsDerivationPath, + + isHub: true, + properties: wallet.info()?.properties, + }; + }, + providers() { + const output: Providers = {}; + + Array.from(getHub().getAll().keys()).forEach((id) => { + try { + const provider = getLegacyProvider(params.allVersionedProviders, id); + output[id] = provider.getInstance(); + } catch (e) { + console.warn(e); + } + }); + + return output; + }, + state(type) { + const result = getHub().state(); + const provider = result[type]; + + if (!provider) { + throw new Error( + `It seems your requested provider doesn't exist in hub. Provider Id: ${type}` + ); + } + + const accounts = provider.namespaces + .filter((namespace) => namespace.connected) + .flatMap((namespace) => + namespace.accounts?.map(fromAccountIdToLegacyAddressFormat) + ) + .filter((account): account is string => !!account); + + const coreState = { + connected: provider.connected, + connecting: provider.connecting, + installed: provider.installed, + reachable: true, + accounts: accounts, + network: null, + }; + return coreState; + }, + suggestAndConnect(_type, _network): never { + throw new Error('`suggestAndConnect` is not implemented'); + }, + }; + + return api; +} diff --git a/wallets/react/src/hub/useHubRefs.ts b/wallets/react/src/hub/useHubRefs.ts new file mode 100644 index 0000000000..dfac0a07aa --- /dev/null +++ b/wallets/react/src/hub/useHubRefs.ts @@ -0,0 +1,53 @@ +import type { Provider, Store } from '@rango-dev/wallets-core'; + +import { createStore, Hub } from '@rango-dev/wallets-core'; +import { useRef } from 'react'; + +import { checkProviderListsEquality } from './utils.js'; + +export function useHubRefs(providers: Provider[]) { + const store = useRef(null); + + const hub = useRef(null); + + function createHub() { + const createdHub = new Hub({ + store: getStore(), + }); + /* + * First add providers to hub + * This helps to `getWalletInfo` be usable, before initialize. + */ + providers.forEach((provider) => { + createdHub.add(provider.id, provider); + }); + hub.current = createdHub; + return createdHub; + } + + // https://react.dev/reference/react/useRef#avoiding-recreating-the-ref-contents + function getStore() { + if (store.current !== null) { + return store.current; + } + const createdStore = createStore(); + store.current = createdStore; + return createdStore; + } + + function getHub(): Hub { + const hubProviders = hub.current?.getAll(); + + if ( + !hub.current || + !hubProviders || + // If hub does not contain a provider, it should be added + !checkProviderListsEquality(Array.from(hubProviders.values()), providers) + ) { + return createHub(); + } + return hub.current; + } + + return { getStore, getHub }; +} diff --git a/wallets/react/src/hub/utils.ts b/wallets/react/src/hub/utils.ts new file mode 100644 index 0000000000..696ee086db --- /dev/null +++ b/wallets/react/src/hub/utils.ts @@ -0,0 +1,322 @@ +import type { AllProxiedNamespaces } from './types.js'; +import type { ConnectResult, ProviderProps } from '../legacy/mod.js'; +import type { Hub, Provider, State } from '@rango-dev/wallets-core'; +import type { + LegacyNamespaceInputForConnect, + LegacyProviderInterface, + LegacyEventHandler as WalletEventHandler, +} from '@rango-dev/wallets-core/legacy'; + +import { + guessProviderStateSelector, + namespaceStateSelector, +} from '@rango-dev/wallets-core'; +import { LegacyEvents as Events } from '@rango-dev/wallets-core/legacy'; +import { + generateStoreId, + type VersionedProviders, +} from '@rango-dev/wallets-core/utils'; +import { pickVersion } from '@rango-dev/wallets-core/utils'; +import { + type AddEthereumChainParameter, + convertEvmBlockchainMetaToEvmChainInfo, +} from '@rango-dev/wallets-shared'; +import { type BlockchainMeta, isEvmBlockchain } from 'rango-types'; + +import { + fromAccountIdToLegacyAddressFormat, + isConnectResultEvm, + isConnectResultSolana, +} from './helpers.js'; + +/* Gets a list of hub and legacy providers and returns a tuple which separates them. */ +export function separateLegacyAndHubProviders( + providers: VersionedProviders[], + options?: { isExperimentalEnabled?: boolean } +): [LegacyProviderInterface[], Provider[]] { + const LEGACY_VERSION = '0.0.0'; + const HUB_VERSION = '1.0.0'; + const { isExperimentalEnabled = false } = options || {}; + + if (isExperimentalEnabled) { + const legacyProviders: LegacyProviderInterface[] = []; + const hubProviders: Provider[] = []; + + providers.forEach((provider) => { + try { + const target = pickVersion(provider, HUB_VERSION); + hubProviders.push(target[1]); + } catch { + const target = pickVersion(provider, LEGACY_VERSION); + legacyProviders.push(target[1]); + } + }); + + return [legacyProviders, hubProviders]; + } + + const legacyProviders = providers.map( + (provider) => pickVersion(provider, LEGACY_VERSION)[1] + ); + return [legacyProviders, []]; +} + +export function findProviderByType( + providers: Provider[], + type: string +): Provider | undefined { + return providers.find((provider) => provider.id === type); +} + +/** + * We will call this function on hub's `subscribe`. + * it will check states and will emit legacy events for backward compatibility. + */ +export function checkHubStateAndTriggerEvents( + hub: Hub, + currentState: State, + previousState: State, + onUpdateState: WalletEventHandler, + allProviders: VersionedProviders[], + allBlockChains: ProviderProps['allBlockChains'] +): void { + hub.getAll().forEach((provider, providerId) => { + const currentProviderState = guessProviderStateSelector( + currentState, + providerId + ); + const previousProviderState = guessProviderStateSelector( + previousState, + providerId + ); + + let accounts: string[] | null = []; + /* + * We don't rely `accounts` to make sure we will trigger proper event on this case: + * previous value: [0x...] + * current value: [] + */ + let hasAccountChanged = false; + let hasNetworkChanged = false; + let hasProviderDisconnected = false; + // It will pick the last network from namespaces. + let maybeNetwork = null; + provider.getAll().forEach((namespace) => { + const storeId = generateStoreId(providerId, namespace.namespaceId); + const currentNamespaceState = namespaceStateSelector( + currentState, + storeId + ); + const previousNamespaceState = namespaceStateSelector( + previousState, + storeId + ); + + if (currentNamespaceState.network !== null) { + maybeNetwork = currentNamespaceState.network; + } + + // Check for network + if (currentNamespaceState.network !== previousNamespaceState.network) { + hasNetworkChanged = true; + } + + // TODO: `accounts` has been frozen, we should check and find where object.freeze() is calling. + + // Check for accounts + if ( + previousNamespaceState.accounts?.slice().sort().toString() !== + currentNamespaceState.accounts?.slice().sort().toString() + ) { + if (currentNamespaceState.accounts) { + const formattedAddresses = currentNamespaceState.accounts.map( + fromAccountIdToLegacyAddressFormat + ); + + if (accounts) { + accounts = [...accounts, ...formattedAddresses]; + } else { + accounts = [...formattedAddresses]; + } + + hasAccountChanged = true; + } else { + accounts = null; + hasProviderDisconnected = true; + } + } + }); + + let legacyProvider; + try { + legacyProvider = getLegacyProvider(allProviders, providerId); + } catch (e) { + console.warn( + 'Having legacy provider is required for including some information like supported chain. ', + e + ); + } + + const coreState = { + connected: currentProviderState.connected, + connecting: currentProviderState.connecting, + installed: currentProviderState.installed, + accounts: accounts, + network: maybeNetwork, + reachable: true, + }; + + const eventInfo = { + supportedBlockchains: + legacyProvider?.getWalletInfo(allBlockChains || []).supportedChains || + [], + isContractWallet: false, + isHub: true, + }; + + if (previousProviderState.installed !== currentProviderState.installed) { + onUpdateState( + providerId, + Events.INSTALLED, + currentProviderState.installed, + coreState, + eventInfo + ); + } + if (previousProviderState.connecting !== currentProviderState.connecting) { + onUpdateState( + providerId, + Events.CONNECTING, + currentProviderState.connecting, + coreState, + eventInfo + ); + } + if (previousProviderState.connected !== currentProviderState.connected) { + onUpdateState( + providerId, + Events.CONNECTED, + currentProviderState.connected, + coreState, + eventInfo + ); + } + if (hasAccountChanged) { + onUpdateState( + providerId, + Events.ACCOUNTS, + accounts, + coreState, + eventInfo + ); + } + if (hasProviderDisconnected) { + onUpdateState(providerId, Events.ACCOUNTS, null, coreState, eventInfo); + } + if (hasNetworkChanged) { + onUpdateState( + providerId, + Events.NETWORK, + maybeNetwork, + coreState, + eventInfo + ); + } + }); +} + +export function getLegacyProvider( + allProviders: VersionedProviders[], + type: string +): LegacyProviderInterface { + const [legacy] = separateLegacyAndHubProviders(allProviders); + const provider = legacy.find((legacyProvider) => { + return legacyProvider.config.type === type; + }); + + if (!provider) { + console.warn( + `You have a provider that doesn't have legacy provider. It causes some problems since we need some legacy functionality. Provider Id: ${type}` + ); + throw new Error( + `You need to have legacy implementation to use some methods. Provider Id: ${type}` + ); + } + + return provider; +} + +/** + * In legacy mode, for those who have switch network functionality (like evm), we are using an enum for network names + * this enum only has meaning for us, and when we are going to connect an instance (e.g. window.ethereum) we should pass chain id. + */ +export function convertNamespaceNetworkToEvmChainId( + namespace: LegacyNamespaceInputForConnect, + meta: BlockchainMeta[] +) { + if (!namespace.network) { + return undefined; + } + + const evmBlockchainsList = meta.filter(isEvmBlockchain); + const evmChains = convertEvmBlockchainMetaToEvmChainInfo(evmBlockchainsList); + + return evmChains[namespace.network]; +} + +/** + * We are passing an string for chain id (e.g. ETH, POLYGON), but wallet's instances (e.g. window.ethereum) needs chainId (e.g. 0x1). + * This function will help us to map these strings to proper hex ids. + * + * If you need same functionality for other blockchain types (e.g. Cosmos), You can make a separate function and add it here. + */ +export function tryConvertNamespaceNetworkToChainInfo( + namespace: LegacyNamespaceInputForConnect, + meta: BlockchainMeta[] +): string | AddEthereumChainParameter | undefined { + // `undefined` means it's not evm or we couldn't find it in meta. + const evmChain = convertNamespaceNetworkToEvmChainId(namespace, meta); + const network = evmChain || namespace.network; + + return network; +} + +export function transformHubResultToLegacyResult( + res: Awaited> +): ConnectResult { + if (isConnectResultEvm(res)) { + return { + accounts: res.accounts, + network: res.network, + provider: undefined, + }; + } else if (isConnectResultSolana(res)) { + return { + accounts: res, + network: null, + provider: undefined, + }; + } + + return { + accounts: [res], + network: null, + provider: undefined, + }; +} + +export function checkProviderListsEquality( + providerList1: Provider[], + providerList2: Provider[] +) { + const providerIds1 = providerList1 + .map((provider) => provider.id) + .sort() + .toString(); + const providerIds2 = providerList2 + .map((provider) => provider.id) + .sort() + .toString(); + + return providerIds1 === providerIds2; +} diff --git a/wallets/react/src/index.ts b/wallets/react/src/index.ts new file mode 100644 index 0000000000..11d9f03d93 --- /dev/null +++ b/wallets/react/src/index.ts @@ -0,0 +1,5 @@ +export * from './legacy/helpers.js'; +export { default as Provider } from './provider.js'; +export { useWallets } from './legacy/hooks.js'; +export * from './legacy/types.js'; +export { separateLegacyAndHubProviders } from './hub/mod.js'; diff --git a/wallets/react/src/legacy/autoConnect.ts b/wallets/react/src/legacy/autoConnect.ts new file mode 100644 index 0000000000..2d04d78a33 --- /dev/null +++ b/wallets/react/src/legacy/autoConnect.ts @@ -0,0 +1,78 @@ +import type { WalletActions, WalletProviders } from './types.js'; +import type { LegacyWallet as Wallet } from '@rango-dev/wallets-core/legacy'; +import type { WalletConfig, WalletType } from '@rango-dev/wallets-shared'; + +import { LastConnectedWalletsFromStorage } from '../hub/lastConnectedWallets.js'; + +import { LEGACY_LAST_CONNECTED_WALLETS } from './mod.js'; + +/* + *If a wallet has multiple providers and one of them can be eagerly connected, + *then the whole wallet will support it at that point and we try to connect to that wallet as usual in eagerConnect method. + */ +export async function autoConnect( + wallets: WalletProviders, + getWalletInstance: (wallet: { + actions: WalletActions; + config: WalletConfig; + }) => Wallet +) { + const lastConnectedWalletsFromStorage = new LastConnectedWalletsFromStorage( + LEGACY_LAST_CONNECTED_WALLETS + ); + + const lastConnectedWallets = lastConnectedWalletsFromStorage.list(); + const walletIds = Object.keys(lastConnectedWallets); + + if (walletIds.length) { + const eagerConnectQueue: { + walletType: WalletType; + eagerConnect: () => Promise; + }[] = []; + + walletIds.forEach((walletType) => { + const wallet = wallets.get(walletType); + + if (!!wallet) { + const walletInstance = getWalletInstance(wallet); + eagerConnectQueue.push({ + walletType, + eagerConnect: walletInstance.eagerConnect.bind(walletInstance), + }); + } + }); + + const result = await Promise.allSettled( + eagerConnectQueue.map(async ({ eagerConnect }) => eagerConnect()) + ); + + const canRestoreAnyConnection = !!result.find( + ({ status }) => status === 'fulfilled' + ); + + /* + *After successfully connecting to at least one wallet, + *we will removing the other wallets from persistence. + *If we are unable to connect to any wallet, + *the persistence will not be removed and the eager connection will be retried with another page load. + */ + if (canRestoreAnyConnection) { + const walletsToRemoveFromPersistance: WalletType[] = []; + result.forEach((settleResult, index) => { + const { status } = settleResult; + + if (status === 'rejected') { + walletsToRemoveFromPersistance.push( + eagerConnectQueue[index].walletType + ); + } + }); + + if (walletsToRemoveFromPersistance.length) { + lastConnectedWalletsFromStorage.removeWallets( + walletsToRemoveFromPersistance + ); + } + } + } +} diff --git a/wallets/react/src/legacy/context.ts b/wallets/react/src/legacy/context.ts new file mode 100644 index 0000000000..41468366b4 --- /dev/null +++ b/wallets/react/src/legacy/context.ts @@ -0,0 +1,36 @@ +import type { ProviderContext } from './types.js'; + +import { createContext } from 'react'; + +const defaultErrorMesssage = "Context hasn't been initialized yet."; +const defaultContext: ProviderContext = { + async connect() { + throw new Error(defaultErrorMesssage); + }, + async disconnect() { + throw new Error(defaultErrorMesssage); + }, + async disconnectAll() { + throw new Error(defaultErrorMesssage); + }, + async suggestAndConnect() { + throw new Error(defaultErrorMesssage); + }, + state() { + throw new Error(defaultErrorMesssage); + }, + canSwitchNetworkTo() { + throw new Error(defaultErrorMesssage); + }, + providers() { + throw new Error(defaultErrorMesssage); + }, + getWalletInfo() { + throw new Error(defaultErrorMesssage); + }, + getSigners() { + throw new Error(defaultErrorMesssage); + }, +}; + +export const WalletContext = createContext(defaultContext); diff --git a/wallets/react/src/legacy/helpers.ts b/wallets/react/src/legacy/helpers.ts new file mode 100644 index 0000000000..5fdbc48a5d --- /dev/null +++ b/wallets/react/src/legacy/helpers.ts @@ -0,0 +1,183 @@ +import type { + ProviderInterface, + State, + WalletActions, + WalletProviders, +} from './types.js'; +import type { + LegacyOptions as Options, + LegacyEventHandler as WalletEventHandler, + LegacyState as WalletState, +} from '@rango-dev/wallets-core/legacy'; +import type { WalletType } from '@rango-dev/wallets-shared'; + +import { Persistor } from '@rango-dev/wallets-core/legacy'; + +import { LEGACY_LAST_CONNECTED_WALLETS } from '../hub/constants.js'; +import { LastConnectedWalletsFromStorage } from '../hub/lastConnectedWallets.js'; + +export function choose(wallets: any[], type: WalletType): any | null { + return wallets.find((wallet) => wallet.type === type) || null; +} + +export const defaultWalletState: WalletState = { + connected: false, + connecting: false, + reachable: false, + installed: false, + accounts: null, + network: null, +}; + +export function stateReducer(state: State, action: any) { + if (action.type === 'new_state') { + // TODO fix problem and remove ts-ignore + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + const target_wallet = state[action.wallet]; + if (!target_wallet) { + return { + ...state, + [action.wallet]: { + ...defaultWalletState, + [action.name]: action.value, + }, + }; + } + + return { + ...state, + [action.wallet]: { + ...target_wallet, + [action.name]: action.value, + }, + }; + } + + return state; +} + +export function connectedWallets(providersState: State): WalletType[] { + return Object.entries(providersState) + .filter(([, wallet_state]) => { + return wallet_state?.connected; + }) + .map(([type]) => { + return type; + }); +} + +export function availableWallets(providersState: State): WalletType[] { + return Object.entries(providersState).map(([type]) => { + return type; + }); +} + +export function checkWalletProviders( + list: ProviderInterface[] +): WalletProviders { + const wallets: WalletProviders = new Map(); + + list.forEach((provider) => { + const { config, ...actions } = provider; + wallets.set(config.type, { + actions, + config, + }); + }); + + return wallets; +} + +/* eslint-disable @typescript-eslint/ban-types */ +export function isAsync(fn: Function) { + return fn?.constructor?.name === 'AsyncFunction'; +} + +export function needsCheckInstallation(options: Options) { + const { checkInstallation = true } = options.config; + return checkInstallation; +} + +export async function tryPersistWallet({ + type, + walletActions, + getState, +}: { + type: WalletType; + walletActions: WalletActions; + getState: (walletType: WalletType) => WalletState; +}) { + if (walletActions.canEagerConnect) { + const lastConnectedWalletsFromStorage = new LastConnectedWalletsFromStorage( + LEGACY_LAST_CONNECTED_WALLETS + ); + const lastConnectedWallets = lastConnectedWalletsFromStorage.list(); + const walletAlreadyPersisted = !!lastConnectedWallets[type]; + + /* + *If on the last attempt we are unable to eagerly connect to any wallet and the user connects any wallet manualy, + *persistance will be outdated and will need to be removed. + */ + if (walletAlreadyPersisted && !getState(type).connected) { + clearPersistance(); + } + + if (!walletAlreadyPersisted) { + lastConnectedWalletsFromStorage.addWallet(type, []); + } + } +} + +export function tryRemoveWalletFromPersistance({ + type, + walletActions, +}: { + type: WalletType; + walletActions: WalletActions; +}) { + if (walletActions.canEagerConnect) { + const lastConnectedWalletsFromStorage = new LastConnectedWalletsFromStorage( + LEGACY_LAST_CONNECTED_WALLETS + ); + lastConnectedWalletsFromStorage.removeWallets([type]); + } +} + +export function clearPersistance() { + const persistor = new Persistor(); + const wallets = persistor.getItem(LEGACY_LAST_CONNECTED_WALLETS); + if (wallets) { + persistor.removeItem(LEGACY_LAST_CONNECTED_WALLETS); + } +} + +/* + *Our event handler includes an internal state updater, and a notifier + *for the outside listener. + *On creating first wallet refrence, and on chaning `props.onUpdateState` + *we are using this function. + */ +export function makeEventHandler( + dispatcher: any, + onUpdateState?: WalletEventHandler +) { + const handler: WalletEventHandler = ( + type, + name, + value, + coreState, + supportedChains + ) => { + const action = { type: 'new_state', wallet: type, name, value }; + // Update state + dispatcher(action); + + // Giving the event to the outside listener + if (onUpdateState) { + onUpdateState(type, name, value, coreState, supportedChains); + } + }; + + return handler; +} diff --git a/wallets/react/src/legacy/hooks.ts b/wallets/react/src/legacy/hooks.ts new file mode 100644 index 0000000000..d167728152 --- /dev/null +++ b/wallets/react/src/legacy/hooks.ts @@ -0,0 +1,54 @@ +import type { ProviderContext, WalletActions, WalletConfig } from './types.js'; +import type { LegacyEventHandler as WalletEventHandler } from '@rango-dev/wallets-core/legacy'; + +import { LegacyWallet as Wallet } from '@rango-dev/wallets-core/legacy'; +import { useContext, useRef } from 'react'; + +import { WalletContext } from './context.js'; + +export type GetWalletInstance = (wallet: { + actions: WalletActions; + config: WalletConfig; +}) => Wallet; + +export function useInitializers( + onChangeState: WalletEventHandler +): GetWalletInstance { + const availableWallets = useRef<{ + [key: string]: Wallet | undefined; + }>({}); + + /* + * If `wallet` hasn't been added to `availableWallets`, + * Get a instance of `Wallet` and save the refrence in `availableWallets`. + * Otherwise, return the already created instance. + */ + function updater(wallet: { + actions: WalletActions; + config: WalletConfig; + }): Wallet { + const type = wallet.config.type; + // We only update, if there is no instance available. + if (typeof availableWallets.current[type] === 'undefined') { + availableWallets.current[type] = new Wallet( + { + config: wallet.config, + handler: onChangeState, + }, + wallet.actions + ); + } + + return availableWallets.current[type]!; + } + + return updater; +} + +export function useWallets(): ProviderContext { + const context = useContext(WalletContext); + if (!context) { + throw Error('useWallet can only be used within the Provider component'); + } + return context; +} diff --git a/wallets/react/src/legacy/mod.ts b/wallets/react/src/legacy/mod.ts new file mode 100644 index 0000000000..fb14a6809d --- /dev/null +++ b/wallets/react/src/legacy/mod.ts @@ -0,0 +1,13 @@ +export type { + ProviderProps, + ProviderContext, + ConnectResult, + ExtendedWalletInfo, +} from './types.js'; +export { + LEGACY_LAST_CONNECTED_WALLETS, + HUB_LAST_CONNECTED_WALLETS, +} from '../hub/constants.js'; + +export { WalletContext } from './context.js'; +export { useLegacyProviders } from './useLegacyProviders.js'; diff --git a/wallets/react/src/legacy/types.ts b/wallets/react/src/legacy/types.ts new file mode 100644 index 0000000000..2d649b1b50 --- /dev/null +++ b/wallets/react/src/legacy/types.ts @@ -0,0 +1,180 @@ +import type { ProviderInfo, VersionedProviders } from '@rango-dev/wallets-core'; +import type { + LegacyNamespaceInputForConnect, + LegacyProviderInterface, + LegacyNetwork as Network, + LegacyEventHandler as WalletEventHandler, + LegacyWalletInfo as WalletInfo, + LegacyState as WalletState, + LegacyWalletType as WalletType, +} from '@rango-dev/wallets-core/legacy'; +import type { BlockchainMeta, SignerFactory } from 'rango-types'; +import type { PropsWithChildren } from 'react'; + +export type State = { + [key: string]: WalletState | undefined; +}; + +export type ConnectResult = { + accounts: string[] | null; + network: Network | null; + provider: any; +}; + +export type Providers = { [type in WalletType]?: any }; + +export type ExtendedWalletInfo = WalletInfo & { + properties?: ProviderInfo['properties']; + isHub?: boolean; +}; + +export type ProviderContext = { + connect( + type: WalletType, + namespaces?: LegacyNamespaceInputForConnect[] + ): Promise; + disconnect(type: WalletType): Promise; + disconnectAll(): Promise[]>; + state(type: WalletType): WalletState; + canSwitchNetworkTo(type: WalletType, network: Network): boolean; + /** + * `Provider` in legacy terms means injected instances by wallets into window (e.g. window.ethereum) + * that can be retrieved by `getInstance`. + * + * Note 1: Providers are lazy evaluated, which means you need to call `connect` (or `state`) first, then the value will be shown in object. + * before doing that, it's a key (wallet name or we call it `type` to be more specific) with null value. (e.g. {metamask: null}) + */ + providers(): Providers; + getSigners(type: WalletType): Promise; + getWalletInfo(type: WalletType): ExtendedWalletInfo; + suggestAndConnect(type: WalletType, network: Network): Promise; +}; + +export type ProviderProps = PropsWithChildren<{ + onUpdateState?: WalletEventHandler; + allBlockChains?: BlockchainMeta[]; + autoConnect?: boolean; + providers: VersionedProviders[]; + configs?: { + isExperimentalEnabled?: boolean; + wallets?: (WalletType | LegacyProviderInterface)[]; + }; +}>; + +export enum Events { + CONNECTED = 'connected', + CONNECTING = 'connecting', + REACHABLE = 'reachable', + INSTALLED = 'installed', + ACCOUNTS = 'accounts', + NETWORK = 'network', +} + +export type ProviderConnectResult = { + accounts: string[]; + chainId: string; +}; + +export type GetInstanceOptions = { + network?: Network; + currentProvider: any; + meta: BlockchainMeta[]; + getState: () => WalletState; + /** + * We always get the instance once and reuse it whenever we needs. By using this option + * We can force the library to get a new instance and replace it with the old one. + * + * Originally, we used this option for wallet connect 1 and its switching network challenge. + */ + force?: boolean; + updateChainId: (chainId: number | string) => void; +}; + +export type GetInstance = + | (() => any) + | ((options: GetInstanceOptions) => Promise); +export type TryGetInstance = + | (() => any) + | ((options: Pick) => Promise); +export type Connect = (options: { + instance: any; + network?: Network; + meta: BlockchainMeta[]; +}) => Promise; + +export type Disconnect = (options: { + instance: any; + destroyInstance: () => void; +}) => Promise; + +type CleanupSubscribe = () => void; + +export type Subscribe = (options: { + instance: any; + state: WalletState; + meta: BlockchainMeta[]; + updateChainId: (chainId: string) => void; + updateAccounts: (accounts: string[], chainId?: string) => void; + connect: (network?: Network) => void; + disconnect: () => void; +}) => CleanupSubscribe | void; + +export type SwitchNetwork = (options: { + instance: any; + network: Network; + meta: BlockchainMeta[]; + newInstance?: TryGetInstance; + getState?: () => WalletState; + updateChainId: (chainId: string) => void; +}) => Promise; + +export type Suggest = (options: { + instance: any; + network: Network; + meta: BlockchainMeta[]; +}) => Promise; + +export type CanSwitchNetwork = (options: { + network: Network; + meta: BlockchainMeta[]; + provider: any; +}) => boolean; + +export type CanEagerConnect = (options: { + instance: any; + meta: BlockchainMeta[]; +}) => Promise; + +export interface WalletActions { + connect: Connect; + getInstance: any; + disconnect?: Disconnect; + subscribe?: Subscribe; + // unsubscribe, // coupled to subscribe. + + // Optional, but should be provided at the same time. + suggest?: Suggest; + switchNetwork?: SwitchNetwork; + getSigners: (provider: any) => Promise; + canSwitchNetworkTo?: CanSwitchNetwork; + canEagerConnect?: CanEagerConnect; + getWalletInfo(allBlockChains: BlockchainMeta[]): WalletInfo; +} + +export interface WalletConfig { + type: WalletType; + defaultNetwork?: Network; + checkInstallation?: boolean; + isAsyncInstance?: boolean; + isAsyncSwitchNetwork?: boolean; +} + +export type WalletProviders = Map< + WalletType, + { + actions: WalletActions; + config: WalletConfig; + } +>; + +export type ProviderInterface = { config: WalletConfig } & WalletActions; diff --git a/wallets/react/src/legacy/useAutoConnect.ts b/wallets/react/src/legacy/useAutoConnect.ts new file mode 100644 index 0000000000..6963425433 --- /dev/null +++ b/wallets/react/src/legacy/useAutoConnect.ts @@ -0,0 +1,23 @@ +import type { ProviderProps } from './types.js'; + +import { useEffect, useRef } from 'react'; + +import { shouldTryAutoConnect } from './utils.js'; + +export function useAutoConnect( + props: Pick & { + /** + * A function to run autoConnect on instances + */ + autoConnectHandler: () => void; + } +) { + const autoConnectInitiated = useRef(false); + + useEffect(() => { + if (shouldTryAutoConnect(props) && !autoConnectInitiated.current) { + autoConnectInitiated.current = true; + props.autoConnectHandler(); + } + }, [props.autoConnect, props.allBlockChains]); +} diff --git a/wallets/react/src/legacy/useLegacyProviders.ts b/wallets/react/src/legacy/useLegacyProviders.ts new file mode 100644 index 0000000000..c93cbc084a --- /dev/null +++ b/wallets/react/src/legacy/useLegacyProviders.ts @@ -0,0 +1,235 @@ +import type { ProviderContext, ProviderProps } from './types.js'; +import type { LegacyProviderInterface } from '@rango-dev/wallets-core/legacy'; +import type { WalletType } from '@rango-dev/wallets-shared'; + +import { useEffect, useReducer } from 'react'; + +import { autoConnect } from './autoConnect.js'; +import { + availableWallets, + checkWalletProviders, + clearPersistance, + connectedWallets, + defaultWalletState, + makeEventHandler, + stateReducer, + tryPersistWallet, + tryRemoveWalletFromPersistance, +} from './helpers.js'; +import { useInitializers } from './hooks.js'; +import { useAutoConnect } from './useAutoConnect.js'; + +export type LegacyProviderProps = Omit & { + providers: LegacyProviderInterface[]; +}; + +export function useLegacyProviders( + props: LegacyProviderProps +): ProviderContext { + const [providersState, dispatch] = useReducer(stateReducer, {}); + + // Get (or add) wallet instance (`provider`s will be wrapped in a `Wallet`) + const getWalletInstance = useInitializers( + makeEventHandler(dispatch, props.onUpdateState) + ); + + // Getting providers from props and put all of them in a `Map` with an appropriate interface. + const listOfProviders = props.providers; + const wallets = checkWalletProviders(listOfProviders); + + useAutoConnect({ + allBlockChains: props.allBlockChains, + autoConnect: props.autoConnect, + autoConnectHandler: async () => autoConnect(wallets, getWalletInstance), + }); + + // Final API we put in context and it will be available to use for users. + const api: ProviderContext = { + async connect(type, namespaces) { + const wallet = wallets.get(type); + if (!wallet) { + throw new Error(`You should add ${type} to provider first.`); + } + + // Legacy providers doesn't implemented multiple namespaces, so it will always be one value. + let network = undefined; + if (namespaces && namespaces.length > 0) { + /* + * This may not be safe in cases there are two `network` for namespaces, the first one will be picked always. + * But since legacy provider only accepts one value, it shouldn't be happened when we are using legacy mode. + */ + network = namespaces.find((ns) => !!ns.network)?.network; + } + + const walletInstance = getWalletInstance(wallet); + const result = await walletInstance.connect(network, namespaces); + if (props.autoConnect) { + void tryPersistWallet({ + type, + walletActions: wallet.actions, + getState: api.state, + }); + } + + return [result]; + }, + async disconnect(type) { + const wallet = wallets.get(type); + if (!wallet) { + throw new Error(`You should add ${type} to provider first.`); + } + + const walletInstance = getWalletInstance(wallet); + await walletInstance.disconnect(); + if (props.autoConnect) { + tryRemoveWalletFromPersistance({ type, walletActions: wallet.actions }); + } + }, + async disconnectAll() { + const disconnect_promises: Promise[] = []; + + /* + * When a wallet is initializing, a record will be added to `providersState` + * So we use them to know what wallet has been initialized then we need to + * filter connected wallets only. + */ + connectedWallets(providersState).forEach((type) => { + const wallet = wallets.get(type); + + if (wallet) { + const walletInstance = getWalletInstance(wallet); + disconnect_promises.push(walletInstance.disconnect()); + } + }); + + if (props.autoConnect) { + clearPersistance(); + } + return await Promise.allSettled(disconnect_promises); + }, + + async suggestAndConnect(type, network) { + const wallet = wallets.get(type); + if (!wallet) { + throw new Error(`You should add ${type} to provider first.`); + } + const walletInstance = getWalletInstance(wallet); + const result = await walletInstance.suggestAndConnect(network); + + return result; + }, + + state(type) { + return providersState[type] || defaultWalletState; + }, + canSwitchNetworkTo(type, network) { + const wallet = wallets.get(type); + if (!wallet) { + return false; + } + + const walletInstance = getWalletInstance(wallet); + return walletInstance.canSwitchNetworkTo + ? walletInstance.canSwitchNetworkTo(network, walletInstance.provider) + : false; + }, + providers() { + const providers: { [type in WalletType]?: any } = {}; + availableWallets(providersState).forEach((type) => { + const wallet = wallets.get(type); + if (wallet) { + const walletInstance = getWalletInstance(wallet); + providers[type] = walletInstance.provider; + } + }); + + return providers; + }, + getWalletInfo(type) { + const wallet = wallets.get(type); + if (!wallet) { + throw new Error(`You should add ${type} to provider first.`); + } + + /* + * Get wallet info could be used in render methods to show wallets data + * So, addWalletRef method shouldn't be called in this method + */ + + return wallet.actions.getWalletInfo(props.allBlockChains || []); + }, + async getSigners(type) { + const wallet = wallets.get(type); + + if (!wallet) { + throw new Error(`You should add ${type} to provider first.`); + } + const walletInstance = getWalletInstance(wallet); + const provider = walletInstance.provider; + const result = walletInstance.getSigners(provider); + + return result; + }, + }; + + // Initialize instances + useEffect(() => { + wallets.forEach((wallet) => { + const walletInstance = getWalletInstance(wallet); + const runOnInit = () => { + if (walletInstance.onInit) { + walletInstance.onInit(); + } + }; + + const initWhenPageIsReady = (event: Event) => { + if ( + event.target && + (event.target as Document).readyState === 'complete' + ) { + runOnInit(); + + document.removeEventListener('readystatechange', initWhenPageIsReady); + } + }; + + // Try to run, maybe it's ready. + runOnInit(); + + /* + * Try again when the page has been completely loaded. + * Some of wallets, take some time to be fully injected and loaded. + */ + document.addEventListener('readystatechange', initWhenPageIsReady); + }); + }, []); + + // Setting supported blockchains on instances + useEffect(() => { + const allBlockChains = props.allBlockChains; + if (allBlockChains) { + wallets.forEach((wallet) => { + const walletInstance = getWalletInstance(wallet); + const walletInfo = walletInstance.getWalletInfo( + props.allBlockChains || [] + ); + walletInstance.setInfo({ + supportedBlockchains: walletInfo.supportedChains, + isContractWallet: !!walletInfo.isContractWallet, + }); + }); + } + }, [props.allBlockChains]); + + // Setting event handler on instances + useEffect(() => { + wallets.forEach((wallet) => { + const walletInstance = getWalletInstance(wallet); + walletInstance.setHandler( + makeEventHandler(dispatch, props.onUpdateState) + ); + }); + }, [props.onUpdateState]); + + return api; +} diff --git a/wallets/react/src/legacy/utils.ts b/wallets/react/src/legacy/utils.ts new file mode 100644 index 0000000000..dc31871344 --- /dev/null +++ b/wallets/react/src/legacy/utils.ts @@ -0,0 +1,7 @@ +import type { ProviderProps } from './types.js'; + +export function shouldTryAutoConnect( + props: Pick +): boolean { + return !!props.allBlockChains?.length && !!props.autoConnect; +} diff --git a/wallets/react/src/provider.tsx b/wallets/react/src/provider.tsx new file mode 100644 index 0000000000..7f25e92fd8 --- /dev/null +++ b/wallets/react/src/provider.tsx @@ -0,0 +1,18 @@ +import type { ProviderProps } from './legacy/types.js'; + +import React from 'react'; + +import { WalletContext } from './legacy/context.js'; +import { useProviders } from './useProviders.js'; + +function Provider(props: ProviderProps) { + const api = useProviders(props); + + return ( + + {props.children} + + ); +} + +export default Provider; diff --git a/wallets/react/src/test-utils/env.ts b/wallets/react/src/test-utils/env.ts new file mode 100644 index 0000000000..53c44f8b66 --- /dev/null +++ b/wallets/react/src/test-utils/env.ts @@ -0,0 +1,10 @@ +const TEST_ENVIRONMENT_AGENT = 'HappyDOM/0.0.0'; + +/** + * Detecting wether our code is running in a test environment or not. + * + * Note: This is only useful when HappyDOM or jsdom has been added to test runner. + */ +export function isRunningInTestEnvironmentWithDom(): boolean { + return navigator.userAgent.includes(TEST_ENVIRONMENT_AGENT); +} diff --git a/wallets/react/src/test-utils/fixtures.ts b/wallets/react/src/test-utils/fixtures.ts new file mode 100644 index 0000000000..5acd25824c --- /dev/null +++ b/wallets/react/src/test-utils/fixtures.ts @@ -0,0 +1,238 @@ +import type { LegacyProviderInterface } from '@rango-dev/wallets-core/legacy'; +import type { BlockchainMeta, GenericSigner } from 'rango-types'; +import type { EvmTransaction } from 'rango-types/mainApi'; + +import { DefaultSignerFactory, TransactionType } from 'rango-types'; + +export const legacyAddress = '0x000000000000000000000000000000000000dead'; + +export class MockEvmSigner implements GenericSigner { + async signMessage( + _msg: string, + _address: string, + _chainId: string | null + ): Promise { + return '0x'; + } + async signAndSendTx( + _tx: EvmTransaction, + _address: string, + _chainId: string | null + ): Promise<{ hash: string; response?: any }> { + return { + hash: '0x', + }; + } +} + +export const legacyProvider: LegacyProviderInterface = { + config: { + type: 'legacy-garbage', + }, + async connect({ network }) { + // we added a timeout to simulate requesting to extension for connection. + return await new Promise((resolve, reject) => { + setTimeout(() => { + // This is useful for simulating error scenarios. + if (network === 'When Airdrop?') { + reject( + 'please stay tuned we shall announce the detailed information soon.' + ); + } else { + resolve([ + { + accounts: [legacyAddress], + chainId: network || '', + }, + ]); + } + // eslint-disable-next-line @typescript-eslint/no-magic-numbers + }, 10); + }); + }, + getInstance() { + return {}; + }, + async getSigners() { + const signers = new DefaultSignerFactory(); + signers.registerSigner(TransactionType.EVM, new MockEvmSigner()); + return signers; + }, + getWalletInfo() { + return { + name: 'legacy garbage wallet', + color: '#000', + img: 'https://...', + installLink: 'https://...', + supportedChains: [], + }; + }, +}; + +export const blockchainsMeta: BlockchainMeta[] = [ + { + name: 'BTC', + defaultDecimals: 8, + addressPatterns: [ + '^[13][a-km-zA-HJ-NP-Z1-9]{25,34}$|^(bc1)[0-9A-Za-z]{39,59}$', + ], + feeAssets: [ + { + blockchain: 'BTC', + symbol: 'BTC', + address: null, + }, + ], + logo: 'https://raw.githubusercontent.com/rango-exchange/assets/main/blockchains/BTC/icon.svg', + displayName: 'Bitcoin', + shortName: 'BTC', + sort: 12, + color: '#F7931A', + enabled: true, + type: TransactionType.TRANSFER, + chainId: null, + info: { + infoType: 'TransferMetaInfo', + blockExplorerUrls: ['https://www.blockchain.com/btc/'], + addressUrl: 'https://www.blockchain.com/btc/address/{wallet}', + transactionUrl: 'https://www.blockchain.com/btc/tx/{txHash}', + }, + }, + { + name: 'ETH', + defaultDecimals: 18, + addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], + feeAssets: [ + { + blockchain: 'ETH', + symbol: 'ETH', + address: null, + }, + ], + logo: 'https://raw.githubusercontent.com/rango-exchange/assets/main/blockchains/ETH/icon.svg', + displayName: 'Ethereum', + shortName: 'ETH', + sort: 0, + color: '#ecf0f1', + enabled: true, + type: TransactionType.EVM, + chainId: '0x1', + info: { + infoType: 'EvmMetaInfo', + chainName: 'Ethereum Mainnet', + nativeCurrency: { + name: 'ETH', + symbol: 'ETH', + decimals: 18, + }, + rpcUrls: ['https://rpc.ankr.com/eth'], + blockExplorerUrls: ['https://etherscan.io'], + addressUrl: 'https://etherscan.io/address/{wallet}', + transactionUrl: 'https://etherscan.io/tx/{txHash}', + enableGasV2: true, + }, + }, + { + name: 'SOLANA', + defaultDecimals: 9, + addressPatterns: ['^[1-9A-HJ-NP-Za-km-z]{32,44}$'], + feeAssets: [ + { + blockchain: 'SOLANA', + symbol: 'SOL', + address: null, + }, + ], + logo: 'https://raw.githubusercontent.com/rango-exchange/assets/main/blockchains/SOLANA/icon.svg', + displayName: 'Solana', + shortName: 'Solana', + sort: 20, + color: '#708DD2', + enabled: true, + type: TransactionType.SOLANA, + chainId: 'mainnet-beta', + info: { + infoType: 'SolanaMetaInfo', + blockExplorerUrls: ['https://solscan.io/'], + addressUrl: 'https://solscan.io/account/{wallet}', + transactionUrl: 'https://solscan.io/tx/{txHash}', + }, + }, + { + name: 'COSMOS', + defaultDecimals: 6, + addressPatterns: ['^(cosmos1)[0-9a-z]{38}$'], + feeAssets: [ + { + blockchain: 'COSMOS', + symbol: 'ATOM', + address: null, + }, + ], + logo: 'https://raw.githubusercontent.com/rango-exchange/assets/main/blockchains/COSMOS/icon.svg', + displayName: 'Cosmos', + shortName: 'Cosmos', + sort: 15, + color: '#2E3148', + enabled: true, + type: TransactionType.COSMOS, + chainId: 'cosmoshub-4', + info: { + infoType: 'CosmosMetaInfo', + experimental: false, + rpc: 'https://cosmos-rpc.polkachu.com', + rest: 'https://lcd-cosmoshub.blockapsis.com', + cosmostationLcdUrl: 'https://lcd-cosmoshub.blockapsis.com', + cosmostationApiUrl: 'https://cosmos-rpc.polkachu.com', + cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', + mintScanName: 'cosmos', + chainName: 'Cosmos', + stakeCurrency: { + coinDenom: 'ATOM', + coinMinimalDenom: 'uatom', + coinDecimals: 6, + coinGeckoId: 'cosmos', + coinImageUrl: '/tokens/blockchain/cosmos.svg', + }, + bip44: { + coinType: 118, + }, + bech32Config: { + bech32PrefixAccAddr: 'cosmos', + bech32PrefixAccPub: 'cosmospub', + bech32PrefixValAddr: 'cosmosvaloper', + bech32PrefixValPub: 'cosmosvaloperpub', + bech32PrefixConsAddr: 'cosmosvalcons', + bech32PrefixConsPub: 'cosmosvalconspub', + }, + currencies: [ + { + coinDenom: 'ATOM', + coinMinimalDenom: 'uatom', + coinDecimals: 6, + coinGeckoId: 'cosmos', + coinImageUrl: '/tokens/blockchain/cosmos.svg', + }, + ], + feeCurrencies: [ + { + coinDenom: 'ATOM', + coinMinimalDenom: 'uatom', + coinDecimals: 6, + coinGeckoId: 'cosmos', + coinImageUrl: '/tokens/blockchain/cosmos.svg', + }, + ], + features: ['stargate', 'ibc-transfer'], + explorerUrlToTx: 'https://www.mintscan.io/cosmos/txs/{txHash}', + gasPriceStep: { + low: 0.01, + average: 0.025, + high: 0.04, + }, + blockExplorerUrls: ['https://www.mintscan.io/cosmos/'], + addressUrl: 'https://www.mintscan.io/cosmos/account/{wallet}', + transactionUrl: 'https://www.mintscan.io/cosmos/txs/{txHash}', + }, + }, +]; diff --git a/wallets/react/src/useProviders.ts b/wallets/react/src/useProviders.ts new file mode 100644 index 0000000000..686ce1ad50 --- /dev/null +++ b/wallets/react/src/useProviders.ts @@ -0,0 +1,120 @@ +import type { + ExtendedWalletInfo, + ProviderContext, + ProviderProps, + Providers, +} from './index.js'; +import type { ConnectResult } from './legacy/mod.js'; +import type { LegacyState } from '@rango-dev/wallets-core/legacy'; +import type { SignerFactory } from 'rango-types'; + +import { + findProviderByType, + separateLegacyAndHubProviders, + useHubAdapter, +} from './hub/mod.js'; +import { useLegacyProviders } from './legacy/mod.js'; + +/* + * We have two separate interface for our providers: legacy and hub. + * This hook sits between this two interface by keeping old interface as main API and try to add Hub providers by using an adapter. + * For gradual migrating and backward compatibility, we are supporting hub by an adapter besides of the old one. + */ +function useProviders(props: ProviderProps) { + const { providers, ...restProps } = props; + const [legacyProviders, hubProviders] = separateLegacyAndHubProviders( + providers, + { + isExperimentalEnabled: restProps.configs?.isExperimentalEnabled, + } + ); + + const legacyApi = useLegacyProviders({ + ...restProps, + providers: legacyProviders, + }); + const hubApi = useHubAdapter({ + ...restProps, + providers: hubProviders, + allVersionedProviders: providers, + }); + + const api: ProviderContext = { + canSwitchNetworkTo(type, network): boolean { + if (findProviderByType(hubProviders, type)) { + return hubApi.canSwitchNetworkTo(type, network); + } + return legacyApi.canSwitchNetworkTo(type, network); + }, + async connect(type, network): Promise { + const hubProvider = findProviderByType(hubProviders, type); + if (hubProvider) { + return await hubApi.connect(type, network); + } + + return await legacyApi.connect(type, network); + }, + async disconnect(type): Promise { + const hubProvider = findProviderByType(hubProviders, type); + if (hubProvider) { + return await hubApi.disconnect(type); + } + + return await legacyApi.disconnect(type); + }, + async disconnectAll() { + return await Promise.allSettled([ + hubApi.disconnectAll(), + legacyApi.disconnectAll(), + ]); + }, + async getSigners(type): Promise { + const hubProvider = findProviderByType(hubProviders, type); + if (hubProvider) { + return hubApi.getSigners(type); + } + return legacyApi.getSigners(type); + }, + getWalletInfo(type): ExtendedWalletInfo { + const hubProvider = findProviderByType(hubProviders, type); + if (hubProvider) { + return hubApi.getWalletInfo(type); + } + + return legacyApi.getWalletInfo(type); + }, + providers(): Providers { + let output: Providers = {}; + if (hubProviders.length > 0) { + output = { ...output, ...hubApi.providers() }; + } + if (legacyProviders.length > 0) { + output = { ...output, ...legacyApi.providers() }; + } + + return output; + }, + state(type): LegacyState { + const hubProvider = findProviderByType(hubProviders, type); + + if (hubProvider) { + return hubApi.state(type); + } + + return legacyApi.state(type); + }, + async suggestAndConnect(type, network): Promise { + const hubProvider = findProviderByType(hubProviders, type); + + if (hubProvider) { + return hubApi.suggestAndConnect(type, network); + } + + return await legacyApi.suggestAndConnect(type, network); + }, + }; + + return api; +} + +export { useProviders }; diff --git a/wallets/react/tests/legacy.test.tsx b/wallets/react/tests/legacy.test.tsx new file mode 100644 index 0000000000..989380ca06 --- /dev/null +++ b/wallets/react/tests/legacy.test.tsx @@ -0,0 +1,260 @@ +import { legacyProviderImportsToVersionsInterface } from '@rango-dev/wallets-core/utils'; +import { renderHook } from '@testing-library/react-hooks'; +import { TransactionType } from 'rango-types'; +import React from 'react'; +import { describe, expect, test, vi } from 'vitest'; + +import { Provider, useWallets } from '../src/index.js'; +import { + blockchainsMeta, + legacyAddress, + legacyProvider, +} from '../src/test-utils/fixtures.js'; + +describe('check legacy is working correctly', () => { + test("initialize legacy provider and it's accessible", async () => { + const wrapper = ({ children }: any) => { + const list = [legacyProviderImportsToVersionsInterface(legacyProvider)]; + + return {children}; + }; + + const { result } = renderHook(() => useWallets(), { + wrapper, + }); + + // providers are evaluated lazily, so before calling `connect` its value is `null` + expect(result.current.providers()['legacy-garbage']).toBe(null); + + // while try to connect, `provider` will be initialized. + await result.current.connect('legacy-garbage'); + expect(result.current.providers()['legacy-garbage']).toStrictEqual( + legacyProvider.getInstance() + ); + }); + + test.todo('check allBlockchains works correctly', () => { + // + }); + + test.todo('check onUpdateState works correctly', () => { + // + }); + + test.todo('change props value after initializing', () => { + // + }); +}); + +describe('check legacy connect method is working', () => { + test('throw an error if trying to connect to an undefined wallet', async () => { + const wrapper = ({ children }: any) => { + const list = [legacyProviderImportsToVersionsInterface(legacyProvider)]; + + return {children}; + }; + + const { result } = renderHook(() => useWallets(), { + wrapper, + }); + + await expect(result.current.connect('whatever')).rejects.toThrow( + 'You should add' + ); + }); + + test('will be ignored and use first namespace when passing multiple namespaces', async () => { + const wrapper = ({ children }: any) => { + const list = [legacyProviderImportsToVersionsInterface(legacyProvider)]; + + return {children}; + }; + + const { result } = renderHook(() => useWallets(), { + wrapper, + }); + + const connectResult = await result.current.connect('legacy-garbage', [ + { + namespace: 'EVM', + network: 'eth', + }, + { + namespace: 'EVM', + network: 'arb', + }, + ]); + + expect(connectResult).toHaveLength(1); + expect(connectResult[0].network).toBe('eth'); + }); + test('update internal states correctly', async () => { + const wrapper = ({ children }: any) => { + const list = [legacyProviderImportsToVersionsInterface(legacyProvider)]; + + return ( + + {children} + + ); + }; + + const { result } = renderHook(() => useWallets(), { + wrapper, + }); + + const initialState = { + installed: true, + connecting: false, + connected: false, + accounts: null, + network: null, + }; + expect(result.current.state('legacy-garbage')).toMatchObject(initialState); + + // connecting successfully. + await result.current.connect('legacy-garbage', [ + { namespace: 'EVM', network: 'ETH' }, + ]); + + expect(result.current.state('legacy-garbage')).toMatchObject({ + installed: true, + connecting: false, + connected: true, + accounts: [`ETH:${legacyAddress}`], + network: 'ETH', + }); + + // unsuccessful connection + await expect( + result.current.connect('legacy-garbage', [ + { namespace: 'EVM', network: 'When Airdrop?' }, + ]) + ).rejects.toThrowError(); + // state should be reset + expect(result.current.state('legacy-garbage')).toMatchObject(initialState); + }); + + test.todo("throw error when it's already on connecting", async () => { + // + }); + + test.todo('ensure extra context added to `connect` function', async () => { + // make sure correct values passed to `provider connect fn`: { instance, network, meta, namespaces} + }); + + test.todo( + 'return multiple result from connect should handle network and accounts correctly ', + async () => { + // if connect fn returns array, it has own logic. + } + ); + + test.todo('return empty result from connect', async () => { + // if connect fn return empty array, state shouldn't be updated. + }); + + test.todo('suggestAndConnect', async () => { + // + }); +}); + +describe('check legacy switching network', () => { + test('switch network & canSwitchNetworkTo', async () => { + const switchNetwork = vi.fn(); + + const wrapper = ({ children }: any) => { + const extendLegacyProvider = { ...legacyProvider }; + extendLegacyProvider.canSwitchNetworkTo = ({ meta, network }) => { + return !!meta.find((blockchain) => blockchain.name === network); + }; + extendLegacyProvider.getWalletInfo = (allBlockChains) => { + const base = legacyProvider.getWalletInfo(allBlockChains); + return { + ...base, + supportedChains: blockchainsMeta, + }; + }; + extendLegacyProvider.switchNetwork = async () => { + switchNetwork(); + }; + + const list = [ + legacyProviderImportsToVersionsInterface(extendLegacyProvider), + ]; + + return ( + + {children} + + ); + }; + + const { result } = renderHook(() => useWallets(), { + wrapper, + }); + + // First we should connect to any network + await result.current.connect('legacy-garbage', [ + { + namespace: 'EVM', + network: 'ETH', + }, + ]); + + expect(result.current.state('legacy-garbage')).toMatchObject({ + network: 'ETH', + }); + + expect(result.current.canSwitchNetworkTo('legacy-garbage', 'COSMOS')).toBe( + true + ); + expect( + result.current.canSwitchNetworkTo('legacy-garbage', 'whatever') + ).toBe(false); + + // Then passing a different network name, will trigger switch network. + await result.current.connect('legacy-garbage', [ + { + namespace: 'EVM', + network: 'COSMOS', + }, + ]); + + expect(switchNetwork).toBeCalledTimes(1); + + expect(result.current.state('legacy-garbage')).toMatchObject({ + network: 'COSMOS', + }); + }); +}); + +describe('check functionality related to connect', () => { + test.todo('disconnect & disconnectAll', async () => { + // + }); + + test.todo('autoConnect', async () => { + // connect method has an `if` for persisting wallet, check that as well. + }); +}); + +describe('check signers', () => { + test('should signers be accessible', async () => { + const wrapper = ({ children }: any) => { + const list = [legacyProviderImportsToVersionsInterface(legacyProvider)]; + + return {children}; + }; + + const { result } = renderHook(() => useWallets(), { + wrapper, + }); + + const signers = await result.current.getSigners('legacy-garbage'); + expect( + await signers.getSigner(TransactionType.EVM).signMessage('', '', null) + ).toBeTypeOf('string'); + expect(() => signers.getSigner(TransactionType.SOLANA)).toThrowError(); + }); +}); diff --git a/wallets/react/tsconfig.build.json b/wallets/react/tsconfig.build.json new file mode 100644 index 0000000000..db5e51b076 --- /dev/null +++ b/wallets/react/tsconfig.build.json @@ -0,0 +1,11 @@ +{ + // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs + "extends": "../../tsconfig.libnext.json", + "include": ["src"], + "compilerOptions": { + "outDir": "dist", + "rootDir": "./src", + "jsx": "react" + // match output dir to input dir. e.g. dist/index instead of dist/src/index + } +} diff --git a/wallets/react/tsconfig.json b/wallets/react/tsconfig.json new file mode 100644 index 0000000000..a3a0b0f59d --- /dev/null +++ b/wallets/react/tsconfig.json @@ -0,0 +1 @@ +{ "extends": "./tsconfig.build.json", "include": ["src", "tests"] } diff --git a/wallets/readme.md b/wallets/readme.md index 83edba5639..625853f89a 100644 --- a/wallets/readme.md +++ b/wallets/readme.md @@ -1,25 +1,165 @@ -# Status - -| Wallet | Supported Chains | Not Implemented | Source | -| -------------- | ------------------------------------------------------- | ----------------------------------- | ------------------------------------------ | -| Binance Wallet | Binance,BSC,ETH | - | https://www.bnbchain.org/en/binance-wallet | -| Brave | EVM, Solana | - | https://brave.com/wallet/ | -| Clover | EVM, Solana,Polkadot,Kadena,Aptos,BTC,Doge | Polkadot,Kadena,Aptos,BTC,Doge | https://wallet.clover.finance | -| Coin98 | EVM,Solana,Cosmos,TRON,Ton,Thorchain,Terra,BTC | Cosmos,TRON,Ton,Thorchain,Terra,BTC | https://coin98.com/wallet | -| Coinbase | EVM,Solana | - | https://www.coinbase.com/wallet | -| Cosmostation | EVM,Cosmos,Aptos,Sui | Aptos,Sui | https://cosmostation.io/ | -| Exodus | BTC,ETH,BSC,Fantom,Cardano,Polygon,Solana,Avax,Algorand | BTC,Fantom,Cardano,Algorand | https://www.exodus.com/ | -| Frontier | EVM,Solana,Cosmos,Polkadot | Cosmos,Polkadot | https://frontier.xyz/ | -| Keplr | Cosmos | - | https://www.keplr.app/ | -| Kucoin | - | - | https://kuwallet.com/ | -| Leap Cosmos | Cosmos | Cosmos | https://www.leapwallet.io/cosmos | -| Math Wallet | BTC,EVM,Solana,Aptos,Tron,Polkadot,Cosmos | BTC,Aptos,Tron,Polkadot,Cosmos | https://mathwallet.org/en-us/ | -| Metamask | EVM | - | - | -| OKX | - | - | https://www.okx.com/web3 | -| Phantom | Solana | - | - | -| SafePal | EVM,Solana,BTC,Tron,LTC,Doge,Aptos,TON | BTC,Tron,LTC,Doge,Aptos,TON | https://www.safepal.com/ | -| TokenPocket | EVM | - | https://extension.tokenpocket.pro/#/ | -| TronLink | - | - | - | -| Trust Wallet | EVM,Solana | Solana | https://trustwallet.com/ | -| Wallet Connect | - | - | - | -| XDefi | EVM,Solana,Binance,BTC,LTC,Thorchain,Terra,Doge | Doge | https://www.xdefi.io/ | +# Introduction + +A single interface for Web 3.0 wallets that seamlessly integrates 20+ wallets, bringing 50+ blockchains to handle complex tasks such as connecting wallets and performing transactions. + +# Getting Started + +First, you need to add `@rango-dev/wallets-react` to your project + +``` +yarn add @rango-dev/wallets-react + +# or using NPM +npm install @rango-dev/wallets-react +``` + +You can only add some specific wallets you need or add all of them at once using: + +``` +yarn add @rango-dev/provider-all +``` + +If you need some specific wallets, take a look at `/wallets/` directory to see the list of available wallets (starts with `provider-*`). +For example, if you only need `phantom` and `metamask`, you can only add them separately using: + +``` +yarn add @rango-dev/provider-metamask +yarn add @rango-dev/provider-phantom +``` + +Then you need to pass them as a list to `wallets-react`. see next section. + +# Usage + +After adding the dependencies, you can use them. Using all supported wallets (`provider-all`): + +```js +import { Provider } from '@rango-dev/wallets-react'; +import { allProviders } from '@rango-dev/provider-all'; + +const providers = allProviders(); + +export function App() { + const blockchains = [...] // An array of blockchains + return ( + + ... + + ); +} + +``` + +or some specific wallets: + +```js +import { Provider } from '@rango-dev/wallets-react'; +import * as metamask from '@rango-dev/provider-metamask'; +import * as phantom from '@rango-dev/provider-phantom'; + + +const providers = [metamask, phantom]; + +export function App() { + const blockchains = [...] // An array of blockchains + return ( + + ... + + ); +} +``` + +and now you can access to wallets by using `useWallets`. + +```js +import { useWallets } from '@rango-dev/wallets-react'; + +function Example() { + const { connect, state, disconnect } = useWallets(); + const walletState = state('metamask'); + + const handleConnectWallet = async () => { + if (walletState.connecting) return; + try { + if (!walletState.connected) { + if (walletState.installed) { + await connect(type); + } + } else { + disconnect('metamask'); + } + } catch (err) { + setError('Error: ' + (err.message || 'Failed to connect wallet')); + } + }; + + return ; +} +``` + +# Auto-Connect + +With the use of auto-connect, after reloading the app, wallet provider will automatically attempt to connect to the last connected wallets. To use the auto-connect feature, you need to pass the `autoConnect` property to wallet provider: + +```js +import { Provider } from '@rango-dev/wallets-react'; +import { allProviders } from '@rango-dev/provider-all'; + +const providers = allProviders(); + +export function App() { + const blockchains = [...] // An array of blockchains + return ( + + ... + + ); +} + +``` + +For better user experience, wallet provider tries to connect to a wallet only when that wallet doesn’t need to open a confirmation pop-up. Please note that only some wallets support this feature for now. + +# Example + +- Demo for wallets: [Source](https://github.com/rango-exchange/rango-client/tree/next/wallets/demo) + +# Supported Wallets + +| Wallet | Supported Chains | Not Implemented | Auto Connect Support | Source | +| ------------- | ------------------------------------------------------------ | ------------------------------------------------- | -------------------- | ------------------------------------ | +| ArgentX | Starknet | - | ✓ | https://www.argent.xyz/ | +| Bitget | Bitcoin,EVM,Tron,Solana,Cosmos,Aptos,Sui | Bitcoin,Solana,Cosmos,Aptos,Sui | ✓ | https://web3.bitget.com/ | +| Braavos | Starknet | - | ✓ | https://braavos.app/ | +| Brave | EVM, Solana | - | ✓ | https://brave.com/wallet/ | +| Clover | EVM, Solana,Polkadot,Kadena,Aptos,BTC,Doge | Polkadot,Kadena,Aptos,BTC,Doge | ✓ | https://wallet.clover.finance | +| Coin98 | EVM,Solana,Cosmos,TRON,Ton,Thorchain,Terra,BTC,Sui,Aptos,Sei | Cosmos,TRON,Ton,Thorchain,Terra,BTC,Sui,Aptos,Sei | ✗ | https://coin98.com/wallet | +| Coinbase | EVM,Solana | - | ✓ | https://www.coinbase.com/wallet | +| Cosmostation | EVM,Cosmos,Aptos,Sui | Aptos,Sui | ✓ | https://cosmostation.io/ | +| Enkrypt | EVM | BTC,Polkadot | ✓ | https://www.enkrypt.com/ | +| Exodus | BTC,Evm,Cardano,Solana,Algorand | BTC,Cardano,Algorand | ✓ | https://www.exodus.com/ | +| Frontier | EVM,Solana,Cosmos,Polkadot | Cosmos,Polkadot | ✓ | https://frontier.xyz/ | +| Halo | - | - | ✗ | https://halo.social/ | +| Keplr | Cosmos | - | ✗ | https://www.keplr.app/ | +| Leap Cosmos | Cosmos | Cosmos | ✗ | https://www.leapwallet.io/cosmos | +| Ledger | Ethereum,Solana | - | ✗ | https://www.ledger.com/ | +| Math Wallet | BTC,EVM,Solana,Aptos,Tron,Polkadot,Cosmos | BTC,Aptos,Tron,Polkadot,Cosmos | ✓ | https://mathwallet.org/en-us/ | +| Metamask | EVM | - | ✓ | - | +| OKX | EVM,Solana,Cosmos | Cosmos | ✓ | https://www.okx.com/web3 | +| Phantom | Solana,Ethereum,Polygon | Ethereum,Polygon | ✓ | - | +| Rabby | EVM | - | ✓ | https://rabby.io/ | +| Safe | EVM | - | ✓ | https://safe.global/ | +| SafePal | EVM,Solana,BTC,Tron,LTC,Doge,Aptos,TON | BTC,Tron,LTC,Doge,Aptos,TON | ✗ | https://www.safepal.com/ | +| Solflare | Solana | - | ✗ | https://solflare.com | +| Solflare Snap | Solana | - | ✗ | https://solflare.com/metamask | +| Station | Terra Classic, Terra | - | ✗ | https://station.terra.money/ | +| Taho | ETH,Polygon,Arbitrum,Arbitrum,Avax,Binance,Fantom | Fantom | ✗ | https://taho.xyz/ | +| TokenPocket | EVM | - | ✓ | https://extension.tokenpocket.pro/#/ | +| Tomo | EVM,Cosmos,BTC | Cosmos,BTC | ✓ | https://tomo.inc/ | +| Trezor | Ethereum,Solana | Solana | ✗ | https://trezor.io/ | + +| TronLink | Tron | - | ✗ | - | +| Trust Wallet | EVM,Solana | Solana | ✓ | https://trustwallet.com/ | +| Wallet Connect | Evm,Solana,Cosmos | Solana,Cosmos | ✗ | - | +| XDefi | EVM,Solana,Binance,BTC,LTC,Thorchain,Terra,Doge,Cosmos,Akash,Axelar,Crypto.org,Juno,Kujira,Mars,Osmosis,Stargaze,Stride | | ✓ | https://www.xdefi.io/ | diff --git a/wallets/shared/CHANGELOG.md b/wallets/shared/CHANGELOG.md new file mode 100644 index 0000000000..118063599f --- /dev/null +++ b/wallets/shared/CHANGELOG.md @@ -0,0 +1,244 @@ +# [0.41.0](https://github.com/rango-exchange/rango-client/compare/wallets-shared@0.40.0...wallets-shared@0.41.0) (2024-12-30) + + +### Bug Fixes + +* fix ctrl wallet fail to connect problem ([f1bfedc](https://github.com/rango-exchange/rango-client/commit/f1bfedcf4e9bf4cf55c2bee7c954b83dbbb6376c)) + + + +# [0.40.0](https://github.com/rango-exchange/rango-client/compare/wallets-shared@0.39.0...wallets-shared@0.40.0) (2024-11-27) + + +### Features + +* add ton connect provider ([2a2dbb7](https://github.com/rango-exchange/rango-client/commit/2a2dbb79022263f19446ced49d298e04d63f927f)) + + + +# [0.39.0](https://github.com/rango-exchange/rango-client/compare/wallets-shared@0.38.0...wallets-shared@0.39.0) (2024-11-12) + + + +# [0.38.0](https://github.com/rango-exchange/rango-client/compare/wallets-shared@0.37.0...wallets-shared@0.38.0) (2024-10-12) + + +### Bug Fixes + +* bump sdk and fix type issues ([d442208](https://github.com/rango-exchange/rango-client/commit/d4422083bf5dd27d5f509ce1db7f9560d05428c8)) +* cosmostation wallet connection error ([b3747ba](https://github.com/rango-exchange/rango-client/commit/b3747ba77d06a5c02ce670affb337771e606434b)) + + + +# [0.37.0](https://github.com/rango-exchange/rango-client/compare/wallets-shared@0.36.0...wallets-shared@0.37.0) (2024-09-10) + + + +# [0.36.0](https://github.com/rango-exchange/rango-client/compare/wallets-shared@0.35.1...wallets-shared@0.36.0) (2024-08-11) + + +### Features + +* integrate solflare wallet ([fb6aaf1](https://github.com/rango-exchange/rango-client/commit/fb6aaf1c255149df18a75a7bfb16fc83c23b85a8)) + + + +## [0.35.1](https://github.com/rango-exchange/rango-client/compare/wallets-shared@0.35.0...wallets-shared@0.35.1) (2024-07-14) + + + +# [0.35.0](https://github.com/rango-exchange/rango-client/compare/wallets-shared@0.33.0...wallets-shared@0.35.0) (2024-07-09) + + +### Bug Fixes + +* fix the bug where xdefi is not displayed for experimental networks ([723eb2d](https://github.com/rango-exchange/rango-client/commit/723eb2dc3bfacce8753eeee011910b595d45028d)) + + +### Features + +* add a modal for setting custom derivation path for ledger ([5b74ec0](https://github.com/rango-exchange/rango-client/commit/5b74ec049393ed74e3e7547edc72b68bd70b7dce)) +* add support for Trezor hardware wallet ([6edecbb](https://github.com/rango-exchange/rango-client/commit/6edecbb14fd008fc741c892bfa3e025c10160b9b)) +* integrate rabby wallet extension ([145fb8f](https://github.com/rango-exchange/rango-client/commit/145fb8ffbbf5e46e7e8386aeffcefc8f4ddb22e7)) +* integrate tomo wallet extension ([9f0f065](https://github.com/rango-exchange/rango-client/commit/9f0f0650fcd213a621dcc6ddca3e32424c1a5ada)) + + + +# [0.34.0](https://github.com/rango-exchange/rango-client/compare/wallets-shared@0.33.0...wallets-shared@0.34.0) (2024-06-01) + + + +# [0.33.0](https://github.com/rango-exchange/rango-client/compare/wallets-shared@0.32.0...wallets-shared@0.33.0) (2024-05-14) + + +### Features + +* add solana to ledger ([77b6695](https://github.com/rango-exchange/rango-client/commit/77b6695758165f9258a0ba5bd3b2cf39b0b2aab5)) + + + +# [0.32.0](https://github.com/rango-exchange/rango-client/compare/wallets-shared@0.31.0...wallets-shared@0.32.0) (2024-04-24) + + +### Features + +* add ethereum for ledger ([084aae2](https://github.com/rango-exchange/rango-client/commit/084aae28adaf0310dffe3a3100dd783252393053)) + + + +# [0.31.0](https://github.com/rango-exchange/rango-client/compare/wallets-shared@0.30.0...wallets-shared@0.31.0) (2024-04-23) + + +### Bug Fixes + +* resolve conflicts between evm providers ([9a6734c](https://github.com/rango-exchange/rango-client/commit/9a6734cf1537bf0504cf9058d4d775313a9e8e80)) + + +### Features + +* add solflare snap connect and signer ([42aa2b0](https://github.com/rango-exchange/rango-client/commit/42aa2b039dd910e8e44db473e1acd28689a8b43b)) + + + +# [0.30.0](https://github.com/rango-exchange/rango-client/compare/wallets-shared@0.29.0...wallets-shared@0.30.0) (2024-04-09) + + +### Bug Fixes + +* fix the connection problem that happens when another wallet takes over the requested one ([42df212](https://github.com/rango-exchange/rango-client/commit/42df2120aadd84c95045b0bf76844c19305fb59a)) + + + +# [0.29.0](https://github.com/rango-exchange/rango-client/compare/wallets-shared@0.28.0...wallets-shared@0.29.0) (2024-03-12) + + +### Bug Fixes + +* fix wallet connect namespace and switch network ([c8f31b3](https://github.com/rango-exchange/rango-client/commit/c8f31b3ddf4ceeaf745bc089f530b6a4b1eb9637)) + + +### Features + +* add new chains to xdefi ([f780a9f](https://github.com/rango-exchange/rango-client/commit/f780a9f5ad5b4d42b5ea63cfc382059963f5332e)) + + + +# [0.28.0](https://github.com/rango-exchange/rango-client/compare/wallets-shared@0.27.0...wallets-shared@0.28.0) (2024-02-20) + + +### Bug Fixes + +* fix some swap messages in widget-embedded ([f859190](https://github.com/rango-exchange/rango-client/commit/f85919050b0c8f3bb0f91d4f3b87a58cca29601b)) + + +### Features + +* add cosmos account and signer for math wallet ([e43a489](https://github.com/rango-exchange/rango-client/commit/e43a48936a63804d688f3ad1408244d7f2ff32f2)) + + + +# [0.27.0](https://github.com/rango-exchange/rango-client/compare/wallets-shared@0.26.0...wallets-shared@0.27.0) (2024-02-07) + + +### Bug Fixes + +* add ethers to shared package ([5990eff](https://github.com/rango-exchange/rango-client/commit/5990eff3a5cc90d915fafa1048ef02ddeacf225d)) + + + +# [0.26.0](https://github.com/rango-exchange/rango-client/compare/wallets-shared@0.25.0...wallets-shared@0.26.0) (2024-01-22) + + +### Bug Fixes + +* cleanup wallets' subscriber when setProvider get null ([88d6a42](https://github.com/rango-exchange/rango-client/commit/88d6a423c49b34b3d9ff567e22df36c3b009bb76)) + + +### Features + +* add default injected wallet ([238977c](https://github.com/rango-exchange/rango-client/commit/238977c0e3cd09feba9f2557f1b099b9af3afb0d)) + + + +# [0.25.0](https://github.com/rango-exchange/rango-client/compare/wallets-shared@0.23.0...wallets-shared@0.25.0) (2023-12-24) + + +### Bug Fixes + +* fix HMR for widget and playground ([8524820](https://github.com/rango-exchange/rango-client/commit/8524820f10cf0b8921f3db0c4f620ff98daa4103)) +* handle safe wallet in widget ([52fcca4](https://github.com/rango-exchange/rango-client/commit/52fcca49315f7e2edb4655ae7b9cd0792c2800d7)) +* handle switch network flow for wallet-connect ([8c4a17b](https://github.com/rango-exchange/rango-client/commit/8c4a17b47b2919820a4e0726f6d1c48b8994abe3)) + + + +# [0.14.0](https://github.com/rango-exchange/rango-client/compare/wallets-shared@0.13.0...wallets-shared@0.14.0) (2023-08-03) + + + +# [0.13.0](https://github.com/rango-exchange/rango-client/compare/wallets-shared@0.12.0...wallets-shared@0.13.0) (2023-08-01) + + + +# [0.9.0](https://github.com/rango-exchange/rango-client/compare/wallets-shared@0.8.0...wallets-shared@0.9.0) (2023-07-31) + + +### Features + +* add project id as a external value ([0c80404](https://github.com/rango-exchange/rango-client/commit/0c80404a8cacb6c5b0338dea1e416b0b11db254b)) +* support braavos wallet ([fb38ebe](https://github.com/rango-exchange/rango-client/commit/fb38ebef00a33b92cabf506c88ef83d8c77cce84)) +* Support for WalletConnect 2 ([faedef0](https://github.com/rango-exchange/rango-client/commit/faedef0b5e6fc3c5ef881cbbe4ec05334cc1c910)) +* support safe wallet ([d04cbcd](https://github.com/rango-exchange/rango-client/commit/d04cbcd2a612755563512d9dff6f2312088d8b4d)) + + + +# [0.7.0](https://github.com/rango-exchange/rango-client/compare/wallets-shared@0.6.0...wallets-shared@0.7.0) (2023-07-11) + + + +# [0.6.0](https://github.com/rango-exchange/rango-client/compare/wallets-shared@0.5.0...wallets-shared@0.6.0) (2023-07-11) + + +### Features + +* add bitkeep wallet ([c02c3df](https://github.com/rango-exchange/rango-client/commit/c02c3dfd236070295eada74aeb97514f8dacd0ed)) + + +### Reverts + +* Revert "support for rango-types cjs format" ([ed4e050](https://github.com/rango-exchange/rango-client/commit/ed4e050bfc0dcde7aeffa6b0d73b02080a5721eb)) + + + +# [0.5.0](https://github.com/rango-exchange/rango-client/compare/wallets-shared@0.4.0...wallets-shared@0.5.0) (2023-05-31) + + + +# [0.4.0](https://github.com/rango-exchange/rango-client/compare/wallets-shared@0.3.0...wallets-shared@0.4.0) (2023-05-31) + + + +# [0.3.0](https://github.com/rango-exchange/rango-client/compare/wallets-shared@0.2.0...wallets-shared@0.3.0) (2023-05-30) + + + +# [0.2.0](https://github.com/rango-exchange/rango-client/compare/wallets-shared@0.1.14...wallets-shared@0.2.0) (2023-05-30) + + +### Bug Fixes + +* fix bug of duplicate modals for wallet connect ([efb5482](https://github.com/rango-exchange/rango-client/commit/efb54827fd51e6c6c8f42c6abf33c3d7610755e8)) +* fix can switch network for wallet connect ([e3cdeac](https://github.com/rango-exchange/rango-client/commit/e3cdeacd836e254ea2d5384aab4b624a3e7259eb)) + + + +## [0.1.13](https://github.com/rango-exchange/rango-client/compare/wallets-shared@0.1.12...wallets-shared@0.1.13) (2023-05-15) + + +### Bug Fixes + +* check and version promise should be called ([c9317b5](https://github.com/rango-exchange/rango-client/commit/c9317b5f5b177216f64314aa00208a382ef2829f)) +* refactor station wallet ([580a2af](https://github.com/rango-exchange/rango-client/commit/580a2af692f63a85921d69152464143551b3f748)) +* update rango-types and fix notification bugs ([993f185](https://github.com/rango-exchange/rango-client/commit/993f185e0b8c5e5e15a2c65ba2d85d1f9c8daa90)) + + + diff --git a/wallets/shared/package.json b/wallets/shared/package.json index 49653804b8..01c48388b2 100644 --- a/wallets/shared/package.json +++ b/wallets/shared/package.json @@ -1,47 +1,37 @@ { "name": "@rango-dev/wallets-shared", - "version": "0.1.11", + "version": "0.40.1-next.6", "license": "MIT", - "module": "dist/wallets-shared.esm.js", - "main": "dist/index.js", + "type": "module", + "source": "./src/index.ts", + "main": "./dist/index.js", "typings": "dist/index.d.ts", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "default": "./dist/index.js" + } + }, "files": [ "dist", "src" ], "scripts": { - "dev": "tsdx watch", - "build": "tsdx build --tsconfig ./tsconfig.json", - "test": "tsdx test", - "lint": "tsdx lint", - "size": "size-limit", - "analyze": "size-limit --why" - }, - "husky": { - "hooks": { - "pre-commit": "tsdx lint" - } + "build": "node ../../scripts/build/command.mjs --path wallets/shared", + "ts-check": "tsc --declaration --emitDeclarationOnly -p ./tsconfig.json", + "clean": "rimraf dist", + "format": "prettier --write '{.,src}/**/*.{ts,tsx}'", + "lint": "eslint \"**/*.{ts,tsx}\" --ignore-path ../../.eslintignore", + "test": "vitest", + "test:watch": "vitest --watch", + "test:coverage": "vitest run --coverage" }, - "prettier": { - "printWidth": 80, - "semi": true, - "singleQuote": true, - "trailingComma": "es5" - }, - "size-limit": [ - { - "path": "dist/wallets-shared.cjs.production.min.js", - "limit": "10 KB" - }, - { - "path": "dist/wallets-shared.esm.js", - "limit": "10 KB" - } - ], "dependencies": { - "rango-types": "^0.1.28" + "@rango-dev/wallets-core": "^0.40.1-next.8", + "ethers": "^6.13.2", + "rango-types": "^0.1.74" }, "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/wallets/shared/readme.md b/wallets/shared/readme.md index e649a0df4d..59373e343e 100644 --- a/wallets/shared/readme.md +++ b/wallets/shared/readme.md @@ -1 +1,3 @@ -# @rango-dev/wallets-shared \ No newline at end of file +# @rango-dev/wallets-shared + +This package is a shared library containing related types and utility functions used by wallet connectors. diff --git a/wallets/shared/src/getCosmosAccounts.ts b/wallets/shared/src/getCosmosAccounts.ts index 6eba058dd3..82be1569b0 100644 --- a/wallets/shared/src/getCosmosAccounts.ts +++ b/wallets/shared/src/getCosmosAccounts.ts @@ -1,11 +1,12 @@ -import { +import type { Connect, ProviderConnectResult, Suggest } from './rango.js'; +import type { Keplr as InstanceType } from '@keplr-wallet/types'; +import type { BlockchainMeta, CosmosBlockchainMeta, CosmosChainInfo, } from 'rango-types'; -import { deepCopy } from './helpers'; -import { Connect, ProviderConnectResult } from './rango'; -import { Keplr as InstanceType } from '@keplr-wallet/types'; + +import { deepCopy } from './helpers.js'; export interface CosmosInfo extends Omit { chainId: string; @@ -20,9 +21,11 @@ interface CosmosBlockchainMetaWithChainId chainId: string; } +const GET_ACCOUNTS_TIMEOUT = 1000; + const getCosmosMainChainsIds = (blockchains: CosmosBlockchainMeta[]) => blockchains - .filter((blockchain) => !blockchain.info?.experimental) + .filter((blockchain) => blockchain.info && !blockchain.info.experimental) .map((blockchain) => blockchain.chainId) .filter((chainId): chainId is string => !!chainId); @@ -57,7 +60,9 @@ export const getCosmosExperimentalChainInfo = ( ...currency, coinImageUrl: window.location.origin + currency.coinImageUrl, })); - if (!info.gasPriceStep) delete info.gasPriceStep; + if (!info.gasPriceStep) { + delete info.gasPriceStep; + } const { experimental, ...otherProperties } = info; return ( (cosmosExperimentalChainsInfo[blockchain.name] = { @@ -88,13 +93,21 @@ async function getMainAccounts({ }; }) .filter(Boolean); - const accountsPromises = offlineSigners.map(({ signer }) => - signer.getAccounts() + const timeout = new Promise((_, reject) => + setTimeout( + () => reject(new Error('Timeout while fetching accounts')), + GET_ACCOUNTS_TIMEOUT + ) + ); + const accountsPromises = offlineSigners.map(async ({ signer }) => + Promise.race([signer.getAccounts(), timeout]) ); const availableAccountForChains = await Promise.allSettled(accountsPromises); const resolvedAccounts: ProviderConnectResult[] = []; availableAccountForChains.forEach((result, index) => { - if (result.status !== 'fulfilled') return; + if (result.status !== 'fulfilled') { + return; + } const accounts = result.value; const { chainId } = offlineSigners[index]; @@ -125,14 +138,16 @@ async function tryRequestMiscAccounts({ chainId, }; }); - const accountsPromises = offlineSigners.map(({ signer }) => + const accountsPromises = offlineSigners.map(async ({ signer }) => signer.getAccounts() ); const availableAccountForChains = await Promise.allSettled(accountsPromises); const resolvedAccounts: ProviderConnectResult[] = []; availableAccountForChains.forEach((result, index) => { - if (result.status !== 'fulfilled') return; + if (result.status !== 'fulfilled') { + return; + } const accounts = result.value; const { chainId } = offlineSigners[index]; @@ -152,7 +167,6 @@ export const getCosmosAccounts: Connect = async ({ const chainInfo = network ? getCosmosExperimentalChainInfo(meta as CosmosBlockchainMeta[])[network] : null; - if (!!network && !chainInfo) { throw new Error( `You need to add ${network} to "COSMOS_EXPERIMENTAL_CHAINS_INFO" first.` @@ -163,13 +177,12 @@ export const getCosmosAccounts: Connect = async ({ if (!!chainInfo) { await instance.experimentalSuggestChain(chainInfo.info); } - // Getting main chains + target network let desiredChainIds: string[] = getCosmosMainChainsIds( meta as CosmosBlockchainMeta[] ); if (!!chainInfo) { - desiredChainIds.push(chainInfo!.id); + desiredChainIds.push(chainInfo.id); } desiredChainIds = Array.from(new Set(desiredChainIds)).filter(Boolean); @@ -192,3 +205,19 @@ export const getCosmosAccounts: Connect = async ({ const results = [...mainAccounts, ...miscAccounts]; return results; }; + +export const suggestCosmosChain: Suggest = async (options) => { + const { instance, meta, network } = options; + const chainInfo = network + ? getCosmosExperimentalChainInfo(meta as CosmosBlockchainMeta[])[network] + : null; + + if (!chainInfo) { + throw new Error( + `You need to add ${network} to "COSMOS_EXPERIMENTAL_CHAINS_INFO" first.` + ); + } + + // Asking for add experimental chain to wallet. + await instance.experimentalSuggestChain(chainInfo.info); +}; diff --git a/wallets/shared/src/helpers.ts b/wallets/shared/src/helpers.ts index abf3f7998b..90bc296743 100644 --- a/wallets/shared/src/helpers.ts +++ b/wallets/shared/src/helpers.ts @@ -1,20 +1,25 @@ -import { EvmBlockchainMeta } from 'rango-types'; -import { - EvmNetworksChainInfo, +import type { AddEthereumChainParameter, - Network, Connect, - Wallet, + EvmNetworksChainInfo, InstallObjects, -} from './rango'; + Network, + Wallet, +} from './rango.js'; +import type { EvmBlockchainMeta } from 'rango-types'; + +import { Networks } from './rango.js'; -export { isAddress as isEvmAddress } from 'ethers/lib/utils'; +export { isAddress as isEvmAddress } from 'ethers'; +// eslint-disable-next-line @typescript-eslint/no-explicit-any export function deepCopy(obj: any): any { let copy; // Handle the 3 simple types, and null or undefined - if (null == obj || 'object' != typeof obj) return obj; + if (null == obj || 'object' != typeof obj) { + return obj; + } // Handle Date if (obj instanceof Date) { @@ -36,8 +41,9 @@ export function deepCopy(obj: any): any { if (obj instanceof Object) { copy = {} as any; for (const attr in obj) { - if (Object.prototype.hasOwnProperty.call(obj, attr)) + if (Object.prototype.hasOwnProperty.call(obj, attr)) { copy[attr] = deepCopy(obj[attr]); + } } return copy; } @@ -58,17 +64,23 @@ export async function switchOrAddNetworkForMetamaskCompatibleWallets( params: [{ chainId: targetChain?.chainId }], }); } catch (switchError) { - // @ts-ignore - // To resolve this error: Catch clause variable type annotation must be any or unknown if specified + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + /* + * @ts-ignore + * To resolve this error: Catch clause variable type annotation must be any or unknown if specified + */ const error = switchError as { code: number }; if (!targetChain) { throw new Error( `It seems you don't have ${network} network on your wallet. Please add it manually.` ); + /* eslint-disable @typescript-eslint/no-magic-numbers */ } else if (error.code === 4902 || !error.code) { - // Note: on WalletConnect `code` is undefined so we have to use !switchError.code as fallback. - // This error code indicates that the chain has not been added to wallet. + /* + * Note: on WalletConnect `code` is undefined so we have to use !switchError.code as fallback. + * This error code indicates that the chain has not been added to wallet. + */ await instance.request({ method: 'wallet_addEthereumChain', params: [targetChain], @@ -78,7 +90,7 @@ export async function switchOrAddNetworkForMetamaskCompatibleWallets( } } -export function timeout( +export async function timeout( forPromise: Promise, time: number ): Promise { @@ -119,10 +131,12 @@ export const evmChainsToRpcMap = ( Object.keys(evmNetworkChainInfo).map((chainName) => { const info = evmNetworkChainInfo[chainName]; - // This `if` is only used for satisfying typescript, - // Because we iterating over Object.keys(EVM_NETWORKS_CHAIN_INFO) - // And obviously it cannot be `undefined` and always has a value. - if (!!info) { + /* + * This `if` is only used for satisfying typescript, + * Because we iterating over Object.keys(EVM_NETWORKS_CHAIN_INFO) + * And obviously it cannot be `undefined` and always has a value. + */ + if (info) { return [parseInt(info.chainId), info.rpcUrls[0]]; } return [0, '']; @@ -133,50 +147,15 @@ export const evmChainsToRpcMap = ( export const getSolanaAccounts: Connect = async ({ instance }) => { // Asking for account from wallet. - try { - var solanaResponse = await instance.connect(); - } catch (e) { - throw e; - } + const solanaResponse = await instance.connect(); const account = solanaResponse.publicKey.toString(); return { accounts: [account], - chainId: Network.SOLANA, + chainId: Networks.SOLANA, }; }; -export function getCoinbaseInstance( - lookingFor: 'coinbase' | 'metamask' = 'coinbase' -) { - const { ethereum, coinbaseSolana } = window; - const instances = new Map(); - if (!!ethereum) { - const checker = - lookingFor === 'metamask' ? 'isMetaMask' : 'isCoinbaseWallet'; - - // If only Coinbase Wallet is installed - if (lookingFor === 'coinbase' && ethereum[checker]) { - instances.set(Network.ETHEREUM, ethereum); - } - // If Coinbase Wallet and Metamask is installed at the same time. - else if (ethereum.providers?.length) { - const ethInstance = ethereum.providers.find((provider: any) => { - return provider[checker]; - }); - instances.set(Network.ETHEREUM, ethInstance); - } - } - if (!!coinbaseSolana && lookingFor === 'coinbase') - instances.set(Network.SOLANA, coinbaseSolana); - - if (instances.size === 0) return null; - - if (lookingFor === 'metamask') return instances.get(Network.ETHEREUM); - - return instances; -} - export function sortWalletsBasedOnState(wallets: Wallet[]): Wallet[] { return wallets.sort( (a, b) => @@ -190,7 +169,9 @@ function isBrave() { const nav: any = navigator; if (nav.brave && nav.brave.isBrave) { nav.brave.isBrave().then((res: boolean) => { - if (res) isBrave = true; + if (res) { + isBrave = true; + } }); } @@ -200,19 +181,18 @@ function isBrave() { export function detectInstallLink(install: InstallObjects | string): string { if (typeof install !== 'object') { return install; - } else { - let link; - if (isBrave()) { - link = install.BRAVE; - } else if (navigator.userAgent?.toLowerCase().indexOf('chrome') !== -1) { - link = install.CHROME; - } else if (navigator.userAgent?.toLowerCase().indexOf('firefox') !== -1) { - link = install.FIREFOX; - } else if (navigator.userAgent?.toLowerCase().indexOf('edge') !== -1) { - link = install.EDGE; - } - return link || install.DEFAULT; } + let link; + if (isBrave()) { + link = install.BRAVE; + } else if (navigator.userAgent?.toLowerCase().indexOf('chrome') !== -1) { + link = install.CHROME; + } else if (navigator.userAgent?.toLowerCase().indexOf('firefox') !== -1) { + link = install.FIREFOX; + } else if (navigator.userAgent?.toLowerCase().indexOf('edge') !== -1) { + link = install.EDGE; + } + return link || install.DEFAULT; } export function detectMobileScreens(): boolean { @@ -220,3 +200,26 @@ export function detectMobileScreens(): boolean { navigator.userAgent ); } + +/** + * Sample inputs are: + * - "metamask-ETH" + * - "metamask-BSC-BSC:0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + * - "token-pocket-BSC-BSC:0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + * Returns "wallet and network" separately, even if the wallet is dashed inside. + * + */ + +export function splitWalletNetwork(input: string): string[] { + const removedAddressInput = input?.split(':')[0] || ''; + const splittedInput = removedAddressInput.split('-'); + const network = splittedInput[splittedInput.length - 1]; + const walletNetwork = splittedInput.slice(0, -1); + + if (walletNetwork[walletNetwork.length - 1] === network) { + walletNetwork.pop(); + } + const wallet = walletNetwork.join('-'); + + return [wallet, network]; +} diff --git a/wallets/shared/src/index.ts b/wallets/shared/src/index.ts index 68f5fd78be..c67762b360 100644 --- a/wallets/shared/src/index.ts +++ b/wallets/shared/src/index.ts @@ -1,4 +1,4 @@ -export * from './helpers'; -export * from './providers'; -export * from './rango'; -export * from './getCosmosAccounts'; +export * from './helpers.js'; +export * from './providers.js'; +export * from './rango.js'; +export * from './getCosmosAccounts.js'; diff --git a/wallets/shared/src/providers.ts b/wallets/shared/src/providers.ts index b8f545fcf3..1680894151 100644 --- a/wallets/shared/src/providers.ts +++ b/wallets/shared/src/providers.ts @@ -1,7 +1,21 @@ -import { Network, CanSwitchNetwork, Subscribe, SwitchNetwork } from './rango'; -import { convertEvmBlockchainMetaToEvmChainInfo } from './helpers'; -import { switchOrAddNetworkForMetamaskCompatibleWallets } from './helpers'; -import { BlockchainMeta, isEvmBlockchain } from 'rango-types'; +import type { + CanEagerConnect, + CanSwitchNetwork, + Network, + Providers, + Subscribe, + SwitchNetwork, + WalletType, +} from './rango.js'; +import type { BlockchainMeta } from 'rango-types'; + +import { isEvmBlockchain } from 'rango-types'; + +import { + convertEvmBlockchainMetaToEvmChainInfo, + switchOrAddNetworkForMetamaskCompatibleWallets, +} from './helpers.js'; +import { Networks } from './rango.js'; export async function getEvmAccounts(instance: any) { const [accounts, chainId] = await Promise.all([ @@ -21,20 +35,47 @@ export const subscribeToEvm: Subscribe = ({ updateChainId, updateAccounts, }) => { - instance?.on('accountsChanged', (addresses: string[]) => { - // TODO: after enabling autoconnect, we can consider this condition - // to be removed. - // The problem was if a user already connected its wallet, - // Metamask is triggering this event on first load, so when autoconnect is disabled, - // it's automaticlally change the state of wallet to `connected`. + const handleAccountsChanged = (addresses: string[]) => { + /* + * TODO: after enabling autoconnect, we can consider this condition + * to be removed. + * The problem was if a user already connected its wallet, + * Metamask is triggering this event on first load, so when autoconnect is disabled, + * it's automaticlally change the state of wallet to `connected`. + */ if (state.connected) { updateAccounts(addresses); } - }); + }; - instance?.on('chainChanged', (chainId: string) => { + const handleChainChanged = (chainId: string) => { updateChainId(chainId); - }); + }; + + instance?.on?.('accountsChanged', handleAccountsChanged); + + instance?.on?.('chainChanged', handleChainChanged); + + const cleanup = () => { + instance?.off?.('accountsChanged', handleAccountsChanged); + instance?.off?.('chainChanged', handleChainChanged); + }; + + return cleanup; +}; + +export const canEagerlyConnectToEvm: CanEagerConnect = async ({ instance }) => { + try { + const accounts: string[] = await instance.request({ + method: 'eth_accounts', + }); + if (accounts.length) { + return true; + } + return false; + } catch (error) { + return false; + } }; export const switchNetworkForEvm: SwitchNetwork = async ({ @@ -43,7 +84,7 @@ export const switchNetworkForEvm: SwitchNetwork = async ({ meta, }) => { const evmBlockchains = meta.filter(isEvmBlockchain); - const evmInstance = getNetworkInstance(instance, Network.ETHEREUM); + const evmInstance = getNetworkInstance(instance, Networks.ETHEREUM); await switchOrAddNetworkForMetamaskCompatibleWallets( evmInstance, network, @@ -62,13 +103,17 @@ export function getEthChainsInstance( network: Network | null, meta: BlockchainMeta[] ): Network | null { - if (!network) return null; + if (!network) { + return null; + } const evmBlockchains = evmNetworkNames(meta); - return evmBlockchains.includes(network) ? Network.ETHEREUM : null; + return evmBlockchains.includes(network) ? Networks.ETHEREUM : null; } function isEvmNetwork(network: Network | null, meta: BlockchainMeta[]) { - if (!network) return false; + if (!network) { + return false; + } return evmNetworkNames(meta).includes(network); } @@ -79,7 +124,7 @@ export function chooseInstance( network?: Network | null ) { // If there is no `network` we fallback to default network. - network = network || Network.ETHEREUM; + network = network || Networks.ETHEREUM; const instance_network_name = isEvmNetwork(network, meta) ? getEthChainsInstance(network, meta) : network; @@ -94,3 +139,21 @@ export function chooseInstance( export function getNetworkInstance(provider: any, network: Network) { return provider.size ? provider.get(network) : provider; } + +/** + * On our implementation for `wallets` package, We keep the instance in 2 ways + * If it's a single chain wallet, it returns the instance directly, + * If it's a multichain wallet, it returns a `Map` of instances. + * This function will get the `ETHEREUM` instance in both types. + */ +export function getEvmProvider(providers: Providers, type: WalletType): any { + if (type && providers[type]) { + // we need this because provider can return an instance or a map of instances, so what you are doing here is try to detect that. + if (providers[type].size) { + return providers[type].get(Networks.ETHEREUM); + } + + return providers[type]; + } + return null; +} diff --git a/wallets/shared/src/rango.ts b/wallets/shared/src/rango.ts index 228fc523af..2654d9a580 100644 --- a/wallets/shared/src/rango.ts +++ b/wallets/shared/src/rango.ts @@ -1,143 +1,169 @@ -import { BlockchainMeta, EvmBlockchainMeta } from 'rango-types'; +import type { + LegacyNetwork as Network, + LegacyWalletInfo as WalletInfo, + LegacyWalletType as WalletType, +} from '@rango-dev/wallets-core/legacy'; +import type { Namespace } from '@rango-dev/wallets-core/namespaces/common'; +import type { BlockchainMeta, EvmBlockchainMeta } from 'rango-types'; + +import { LegacyNetworks as Networks } from '@rango-dev/wallets-core/legacy'; + +export type { + LegacyNetwork as Network, + LegacyConnect as Connect, + LegacyDisconnect as Disconnect, + LegacySubscribe as Subscribe, + LegacyCanEagerConnect as CanEagerConnect, + LegacySwitchNetwork as SwitchNetwork, + LegacySuggest as Suggest, + LegacyCanSwitchNetwork as CanSwitchNetwork, + LegacyInstallObjects as InstallObjects, + LegacyWalletInfo as WalletInfo, + LegacyWalletType as WalletType, + LegacyNamespaceData as NamespaceData, +} from '@rango-dev/wallets-core/legacy'; + +export { + LegacyNetworks as Networks, + legacyGetBlockChainNameFromId as getBlockChainNameFromId, +} from '@rango-dev/wallets-core/legacy'; export const IS_DEV = !process.env.NODE_ENV || process.env.NODE_ENV === 'development'; -export const getBlockChainNameFromId = ( - chainId: string | number, - blockchains: BlockchainMeta[] -): Network | null => { - chainId = - typeof chainId === 'string' && chainId.startsWith('0x') - ? parseInt(chainId) - : chainId; - - // Sometimes providers are passing `Network` as chainId. - // If chainId is a `Network`, we return itself. - const allNetworks = Object.values(Network) as string[]; - if (allNetworks.includes(String(chainId))) return chainId as Network; - - if (chainId === 'Binance-Chain-Tigris') return Network.BINANCE; - return ( - (blockchains - .filter((blockchainMeta) => !!blockchainMeta.chainId) - .find((blockchainMeta) => { - const blockchainChainId = blockchainMeta.chainId?.startsWith('0x') - ? parseInt(blockchainMeta.chainId) - : blockchainMeta.chainId; - return blockchainChainId == chainId; - })?.name as Network) || null - ); -}; - -export const getBlockchainChainIdByName = ( - netwok: Network, - allBlockChains: AllBlockchains -) => allBlockChains[netwok]?.chainId || null; - export const uint8ArrayToHex = (buffer: Uint8Array): string => { return Buffer.from(buffer).toString('hex'); }; -export enum WalletType { +export enum WalletTypes { + DEFAULT = 'default', META_MASK = 'metamask', - WALLET_CONNECT = 'wallet-connect', + WALLET_CONNECT_2 = 'wallet-connect-2', TRUST_WALLET = 'trust-wallet', - TERRA_STATION = 'terra-station', KEPLR = 'keplr', PHANTOM = 'phantom', - FRONTIER = 'frontier', + BITGET = 'bitget', + TRON_LINK = 'tron-link', COINBASE = 'coinbase', XDEFI = 'xdefi', - BINANCE_CHAIN = 'binance-chain', - LEAP = 'leap', - LEAP_COSMOS = 'leap-cosmos', CLOVER = 'clover', + ARGENTX = 'argentx', + FRONTIER = 'frontier', COSMOSTATION = 'cosmostation', COIN98 = 'coin98', SAFEPAL = 'safepal', + SAFE = 'safe', TOKEN_POCKET = 'token-pocket', BRAVE = 'brave', + BRAAVOS = 'braavos', MATH = 'math', EXODUS = 'exodus', OKX = 'okx', - ARGENTX = 'argentx', - TRON_LINK = 'tron-link', - KUCOIN = 'kucoin', - UNKNOWN = 'unknown', + HALO = 'halo', + LEAP = 'leap', + LEAP_COSMOS = 'leap-cosmos', + STATION = 'station', + ENKRYPT = 'enkrypt', + TAHO = 'taho', + MY_TON_WALLET = 'mytonwallet', + SOLFLARE_SNAP = 'solflare-snap', + LEDGER = 'ledger', + Rabby = 'rabby', + TOMO = 'tomo', + TREZOR = 'trezor', + SOLFLARE = 'solflare', + TON_CONNECT = 'tonconnect', } -export enum Network { - BTC = 'BTC', - BSC = 'BSC', - LTC = 'LTC', - THORCHAIN = 'THOR', - BCH = 'BCH', - BINANCE = 'BNB', - ETHEREUM = 'ETH', - POLYGON = 'POLYGON', - TERRA = 'TERRA', - POLKADOT = '', - TRON = 'TRON', - DOGE = 'DOGE', - HARMONY = 'HARMONY', - AVAX_CCHAIN = 'AVAX_CCHAIN', - FANTOM = 'FANTOM', - MOONBEAM = 'MOONBEAM', - ARBITRUM = 'ARBITRUM', - BOBA = 'BOBA', - OPTIMISM = 'OPTIMISM', - FUSE = 'FUSE', - CRONOS = 'CRONOS', - SOLANA = 'SOLANA', - MOONRIVER = 'MOONRIVER', - GNOSIS = 'GNOSIS', - COSMOS = 'COSMOS', - OSMOSIS = 'OSMOSIS', - AKASH = 'AKASH', - IRIS = 'IRIS', - PERSISTENCE = 'PERSISTENCE', - SENTINEL = 'SENTINEL', - REGEN = 'REGEN', - CRYPTO_ORG = 'CRYPTO_ORG', - SIF = 'SIF', - CHIHUAHUA = 'CHIHUAHUA', - JUNO = 'JUNO', - KUJIRA = 'KUJIRA', - STARNAME = 'STARNAME', - COMDEX = 'COMDEX', - STARGAZE = 'STARGAZE', - DESMOS = 'DESMOS', - BITCANNA = 'BITCANNA', - SECRET = 'SECRET', - INJECTIVE = 'INJECTIVE', - LUMNETWORK = 'LUMNETWORK', - BANDCHAIN = 'BANDCHAIN', - EMONEY = 'EMONEY', - BITSONG = 'BITSONG', - KI = 'KI', - MEDIBLOC = 'MEDIBLOC', - KONSTELLATION = 'KONSTELLATION', - UMEE = 'UMEE', - STARKNET = 'STARKNET', +export const namespaces: Record< + Namespace, + { mainBlockchain: string; title: string; derivationPaths?: DerivationPath[] } +> = { + EVM: { + mainBlockchain: 'ETH', + title: 'Ethereum', + derivationPaths: [ + { + id: 'metamask', + label: `Metamask (m/44'/60'/0'/0/index)`, + generateDerivationPath: (index: string) => `44'/60'/0'/0/${index}`, + }, + { + id: 'ledgerLive', + label: `LedgerLive (m/44'/60'/index'/0/0)`, + generateDerivationPath: (index: string) => `44'/60'/${index}'/0/0`, + }, + { + id: 'legacy', + label: `Legacy (m/44'/60'/0'/index)`, + generateDerivationPath: (index: string) => `44'/60'/0'/${index}`, + }, + ], + }, + Solana: { + mainBlockchain: 'SOLANA', + title: 'Solana', + derivationPaths: [ + { + id: `(m/44'/501'/index')`, + label: `(m/44'/501'/index')`, + generateDerivationPath: (index: string) => `44'/501'/${index}'`, + }, + { + id: `(m/44'/501'/0'/index)`, + label: `(m/44'/501'/0'/index)`, + generateDerivationPath: (index: string) => `44'/501'/0'/${index}`, + }, + ], + }, + Cosmos: { + mainBlockchain: 'COSMOS', + title: 'Cosmos', + }, + UTXO: { + mainBlockchain: 'BTC', + title: 'Utxo', + }, + Starknet: { + title: 'Starknet', + mainBlockchain: 'STARKNET', + }, + Tron: { + title: 'Tron', + mainBlockchain: 'TRON', + }, + Ton: { + title: 'Ton', + mainBlockchain: 'TON', + }, +}; - // Using instead of null - Unknown = 'Unkown', -} +export type DerivationPath = { + id: string; + label: string; + generateDerivationPath: (index: string) => string; +}; -export const XDEFI_WALLET_SUPPORTED_NATIVE_CHAINS = [ - Network.BTC, - Network.LTC, - Network.THORCHAIN, - Network.BCH, - Network.BINANCE, +export const XDEFI_WALLET_SUPPORTED_NATIVE_CHAINS: string[] = [ + Networks.BTC, + Networks.LTC, + Networks.THORCHAIN, + Networks.BCH, + Networks.MAYA, + Networks.DOGE, ]; -export const KEPLR_COMPATIBLE_WALLETS = [ - WalletType.KEPLR, - WalletType.COSMOSTATION, +export const KEPLR_COMPATIBLE_WALLETS: string[] = [ + WalletTypes.KEPLR, + WalletTypes.COSMOSTATION, + WalletTypes.LEAP_COSMOS, + WalletTypes.XDEFI, ]; +export const DEFAULT_COSMOS_RPC_URL = 'https://cosmos-rpc.polkachu.com'; +export const ETHEREUM_CHAIN_ID = '0x1'; +export const DEFAULT_ETHEREUM_RPC_URL = 'https://rpc.ankr.com/eth'; + export type Asset = { blockchain: Network; symbol: string; @@ -185,6 +211,7 @@ export interface WalletConfig { defaultNetwork?: Network; checkInstallation?: boolean; isAsyncInstance?: boolean; + isAsyncSwitchNetwork?: boolean; } export type GetInstanceOptions = { @@ -192,6 +219,8 @@ export type GetInstanceOptions = { currentProvider: any; meta: BlockchainMeta[]; force?: boolean; + updateChainId: (chainId: number | string) => void; + getState: () => WalletState; }; export type TryGetInstance = @@ -207,59 +236,11 @@ export type ProviderConnectResult = { chainId: string; }; -export type Connect = (options: { - instance: any; - network?: Network; - meta: BlockchainMeta[]; -}) => Promise; - -export type Disconnect = (options: { - instance: any; - destroyInstance: () => void; -}) => Promise; - -export type Subscribe = (options: { - instance: any; - state: WalletState; - meta: BlockchainMeta[]; - updateChainId: (chainId: string) => void; - updateAccounts: (accounts: string[], chainId?: string) => void; - connect: (network?: Network) => void; - disconnect: () => void; -}) => void; - -export type SwitchNetwork = (options: { - instance: any; - network: Network; - meta: BlockchainMeta[]; - newInstance?: TryGetInstance; -}) => Promise; - -export type CanSwitchNetwork = (options: { - network: Network; - meta: BlockchainMeta[]; -}) => boolean; - -export type InstallObjects = { - CHROME?: string; - FIREFOX?: string; - EDGE?: string; - BRAVE?: string; - DEFAULT: string; -}; - -export type WalletInfo = { - name: string; - img: string; - installLink: InstallObjects | string; - color: string; - supportedChains: BlockchainMeta[]; - showOnMobile?: boolean; -}; - export interface Wallet { type: WalletType; extensionAvailable: boolean; connected: boolean; - info: Omit; + info: Omit; } + +export type Providers = { [type in WalletType]?: any }; diff --git a/wallets/shared/tests/providers/index.test.ts b/wallets/shared/tests/providers/index.test.ts new file mode 100644 index 0000000000..4f57c732d6 --- /dev/null +++ b/wallets/shared/tests/providers/index.test.ts @@ -0,0 +1,37 @@ +import { describe, beforeEach, it, expect } from 'vitest'; +import { + canEagerlyConnectToEvm, + getEvmAccounts, +} from '@rango-dev/wallets-shared'; +import { MockEvmProvider } from '../../../../test-utils/mock.evm.provider'; + +describe('Test EVM Provider', function test() { + const address = '0xB98bD7C7f656290071E52D1aA617D9cB4467Fd6D'; + const privateKey = + 'de926db3012af759b4f24b5a51ef6afa397f04670f634aa4f48d4480417007f3'; + let instance; + + beforeEach(() => { + instance = new MockEvmProvider({ + address, + privateKey, + networkVersion: 31, + debug: false, + }); + }); + + it('get EVM accounts', async () => { + const result = await getEvmAccounts(instance); + expect(result).not.toBe(undefined); + expect(result.accounts).toEqual([address]); + }); + + it('can eagerly connect to Evm', async () => { + expect( + await canEagerlyConnectToEvm({ + instance, + meta: [], + }) + ).toEqual(true); + }); +}); diff --git a/wallets/shared/tsconfig.build.json b/wallets/shared/tsconfig.build.json new file mode 100644 index 0000000000..10a6efec4c --- /dev/null +++ b/wallets/shared/tsconfig.build.json @@ -0,0 +1,10 @@ +{ + // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs + "extends": "../../tsconfig.libnext.json", + "include": ["src", "../../global-wallets-env.d.ts"], + "compilerOptions": { + "outDir": "dist", + "rootDir": "./src", + "lib": ["dom", "esnext"] + } +} diff --git a/wallets/shared/tsconfig.json b/wallets/shared/tsconfig.json index 365489616a..d8faaf5080 100644 --- a/wallets/shared/tsconfig.json +++ b/wallets/shared/tsconfig.json @@ -1,35 +1,3 @@ { - // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs - "include": ["src", "types", "../../global-wallets-env.d.ts"], - "compilerOptions": { - "module": "esnext", - "lib": ["dom", "esnext"], - "importHelpers": true, - // output .d.ts declaration files for consumers - "declaration": true, - // output .js.map sourcemap files for consumers - "sourceMap": true, - // match output dir to input dir. e.g. dist/index instead of dist/src/index - "rootDir": "./src", - // stricter type-checking for stronger correctness. Recommended by TS - "strict": true, - // linter checks for common issues - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true, - // noUnused* overlap with @typescript-eslint/no-unused-vars, can disable if duplicative - "noUnusedLocals": true, - "noUnusedParameters": true, - // use Node's module resolution algorithm, instead of the legacy TS one - "moduleResolution": "node", - // transpile JSX to React.createElement - "jsx": "react", - // interop between ESM and CJS modules. Recommended by TS - "esModuleInterop": true, - // significant perf increase by skipping checking .d.ts files, particularly those in node_modules. Recommended by TS - "skipLibCheck": true, - // error out if import and file system have a casing mismatch. Recommended by TS - "forceConsistentCasingInFileNames": true, - // `tsdx build` ignores this option, but it is commonly used when type-checking separately with `tsc` - "noEmit": true, - } + "extends": "./tsconfig.build.json" } diff --git a/wallets/wallets-adapter-demo/package.json b/wallets/wallets-adapter-demo/package.json deleted file mode 100644 index 492fe37d35..0000000000 --- a/wallets/wallets-adapter-demo/package.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "name": "@rango-dev/wallets-adapter-demo", - "version": "0.1.12", - "license": "MIT", - "private": true, - "source": "public/index.html", - "browserslist": "> 0.5%, last 2 versions, not dead", - "scripts": { - "dev": "parcel --cache-dir=.parcel-cache", - "build": "parcel build --cache-dir=.parcel-cache" - }, - "dependencies": { - "@rango-dev/provider-all": "^0.1.12", - "@rango-dev/wallets-adapter": "^0.1.12", - "parcel": "^2.8.0", - "rango-sdk": "^0.1.20", - "react": "^18.2.0", - "react-dom": "^18.2.0" - }, - "@parcel/transformer-js": { - "inlineEnvironment": false - }, - "publishConfig": { - "access": "public" - } -} diff --git a/wallets/wallets-adapter-demo/src/App.tsx b/wallets/wallets-adapter-demo/src/App.tsx deleted file mode 100644 index cb9b8581d0..0000000000 --- a/wallets/wallets-adapter-demo/src/App.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import React, { useEffect, useState } from 'react'; -import { allProviders } from '@rango-dev/provider-all'; -import WalletsModal from './components/WalletsModal'; -import { RangoClient } from 'rango-sdk'; -import { AdapterProvider } from '@rango-dev/wallets-adapter'; - -const providers = allProviders(); -export function App() { - const client = new RangoClient(process.env.REACT_APP_API_KEY as string); - - // Because allBlockChains didn't use the BlockchainMeta type from rango-sdk, we have to use any type - const [blockchains, setBlockChains] = useState([]); - - useEffect(() => { - const getAllBlockchains = async () => { - try { - const res = await client.getAllMetadata(); - setBlockChains(res.blockchains); - } catch (e) { - console.log('failed on connect.', e); - } - }; - getAllBlockchains(); - }, []); - - return ( - - - - ); -} diff --git a/wallets/wallets-adapter-demo/src/index.tsx b/wallets/wallets-adapter-demo/src/index.tsx deleted file mode 100644 index 91404b6d7f..0000000000 --- a/wallets/wallets-adapter-demo/src/index.tsx +++ /dev/null @@ -1,7 +0,0 @@ -import React from 'react'; -import { createRoot } from 'react-dom/client'; -import { App } from './App'; - -const container = document.getElementById('app')!; -const root = createRoot(container); -root.render(); diff --git a/wallets/wallets-adapter/CHANGELOG.md b/wallets/wallets-adapter/CHANGELOG.md new file mode 100644 index 0000000000..77856b128d --- /dev/null +++ b/wallets/wallets-adapter/CHANGELOG.md @@ -0,0 +1,207 @@ +# [0.37.0](https://github.com/rango-exchange/rango-client/compare/wallets-adapter@0.36.0...wallets-adapter@0.37.0) (2024-12-30) + + + +# [0.36.0](https://github.com/rango-exchange/rango-client/compare/wallets-adapter@0.35.0...wallets-adapter@0.36.0) (2024-11-27) + + +### Features + +* add ton connect provider ([2a2dbb7](https://github.com/rango-exchange/rango-client/commit/2a2dbb79022263f19446ced49d298e04d63f927f)) + + + +# [0.35.0](https://github.com/rango-exchange/rango-client/compare/wallets-adapter@0.34.5...wallets-adapter@0.35.0) (2024-11-12) + + + +## [0.34.5](https://github.com/rango-exchange/rango-client/compare/wallets-adapter@0.34.4...wallets-adapter@0.34.5) (2024-11-06) + + + +## [0.34.4](https://github.com/rango-exchange/rango-client/compare/wallets-adapter@0.34.3...wallets-adapter@0.34.4) (2024-11-06) + + + +## [0.34.3](https://github.com/rango-exchange/rango-client/compare/wallets-adapter@0.34.2...wallets-adapter@0.34.3) (2024-11-06) + + + +## [0.34.2](https://github.com/rango-exchange/rango-client/compare/wallets-adapter@0.34.1...wallets-adapter@0.34.2) (2024-11-06) + + + +## [0.34.1](https://github.com/rango-exchange/rango-client/compare/wallets-adapter@0.34.0...wallets-adapter@0.34.1) (2024-10-30) + + + +# [0.34.0](https://github.com/rango-exchange/rango-client/compare/wallets-adapter@0.33.3...wallets-adapter@0.34.0) (2024-10-12) + + +### Bug Fixes + +* bump sdk and fix type issues ([d442208](https://github.com/rango-exchange/rango-client/commit/d4422083bf5dd27d5f509ce1db7f9560d05428c8)) + + +### Performance Improvements + +* lazy load signer packages ([7b88f18](https://github.com/rango-exchange/rango-client/commit/7b88f1834f7b29b4b81ab6c81a07bb88e8ccf55c)) + + + +## [0.33.3](https://github.com/rango-exchange/rango-client/compare/wallets-adapter@0.33.2...wallets-adapter@0.33.3) (2024-10-05) + + + +## [0.33.2](https://github.com/rango-exchange/rango-client/compare/wallets-adapter@0.33.1...wallets-adapter@0.33.2) (2024-09-25) + + + +## [0.33.1](https://github.com/rango-exchange/rango-client/compare/wallets-adapter@0.33.0...wallets-adapter@0.33.1) (2024-09-16) + + + +# [0.33.0](https://github.com/rango-exchange/rango-client/compare/wallets-adapter@0.32.0...wallets-adapter@0.33.0) (2024-09-10) + + + +# [0.32.0](https://github.com/rango-exchange/rango-client/compare/wallets-adapter@0.31.0...wallets-adapter@0.32.0) (2024-08-17) + + + +# [0.31.0](https://github.com/rango-exchange/rango-client/compare/wallets-adapter@0.30.1...wallets-adapter@0.31.0) (2024-08-11) + + + +## [0.30.1](https://github.com/rango-exchange/rango-client/compare/wallets-adapter@0.30.0...wallets-adapter@0.30.1) (2024-07-14) + + + +# [0.30.0](https://github.com/rango-exchange/rango-client/compare/wallets-adapter@0.28.2...wallets-adapter@0.30.0) (2024-07-09) + + +### Features + +* update wallets page to add filter by transaction types (category) ([0aa7c73](https://github.com/rango-exchange/rango-client/commit/0aa7c73333bd32912f7b2e90a660f3f43e64f4f7)) + + + +# [0.29.0](https://github.com/rango-exchange/rango-client/compare/wallets-adapter@0.28.2...wallets-adapter@0.29.0) (2024-06-01) + + +### Features + +* update wallets page to add filter by transaction types (category) ([0aa7c73](https://github.com/rango-exchange/rango-client/commit/0aa7c73333bd32912f7b2e90a660f3f43e64f4f7)) + + + +## [0.28.2](https://github.com/rango-exchange/rango-client/compare/wallets-adapter@0.28.1...wallets-adapter@0.28.2) (2024-05-26) + + + +## [0.28.1](https://github.com/rango-exchange/rango-client/compare/wallets-adapter@0.28.0...wallets-adapter@0.28.1) (2024-05-25) + + + +# [0.28.0](https://github.com/rango-exchange/rango-client/compare/wallets-adapter@0.27.1...wallets-adapter@0.28.0) (2024-05-14) + + + +## [0.27.1](https://github.com/rango-exchange/rango-client/compare/wallets-adapter@0.27.0...wallets-adapter@0.27.1) (2024-04-24) + + + +# [0.27.0](https://github.com/rango-exchange/rango-client/compare/wallets-adapter@0.26.0...wallets-adapter@0.27.0) (2024-04-24) + + + +# [0.26.0](https://github.com/rango-exchange/rango-client/compare/wallets-adapter@0.25.0...wallets-adapter@0.26.0) (2024-04-23) + + + +# [0.25.0](https://github.com/rango-exchange/rango-client/compare/wallets-adapter@0.24.0...wallets-adapter@0.25.0) (2024-04-09) + + + +# [0.24.0](https://github.com/rango-exchange/rango-client/compare/wallets-adapter@0.23.0...wallets-adapter@0.24.0) (2024-03-12) + + + +# [0.23.0](https://github.com/rango-exchange/rango-client/compare/wallets-adapter@0.22.1...wallets-adapter@0.23.0) (2024-02-20) + + + +## [0.22.1](https://github.com/rango-exchange/rango-client/compare/wallets-adapter@0.22.0...wallets-adapter@0.22.1) (2024-02-07) + + + +# [0.22.0](https://github.com/rango-exchange/rango-client/compare/wallets-adapter@0.21.0...wallets-adapter@0.22.0) (2024-02-05) + + + +# [0.21.0](https://github.com/rango-exchange/rango-client/compare/wallets-adapter@0.20.0...wallets-adapter@0.21.0) (2024-01-22) + + + +# [0.20.0](https://github.com/rango-exchange/rango-client/compare/wallets-adapter@0.19.0...wallets-adapter@0.20.0) (2023-12-24) + + + +# [0.12.0](https://github.com/rango-exchange/rango-client/compare/wallets-adapter@0.11.0...wallets-adapter@0.12.0) (2023-08-03) + + + +# [0.11.0](https://github.com/rango-exchange/rango-client/compare/wallets-adapter@0.8.0...wallets-adapter@0.11.0) (2023-08-01) + + + +# [0.9.0](https://github.com/rango-exchange/rango-client/compare/wallets-adapter@0.8.0...wallets-adapter@0.9.0) (2023-07-31) + + + +# [0.8.0](https://github.com/rango-exchange/rango-client/compare/wallets-adapter@0.7.0...wallets-adapter@0.8.0) (2023-07-11) + + + +# [0.7.0](https://github.com/rango-exchange/rango-client/compare/wallets-adapter@0.6.0...wallets-adapter@0.7.0) (2023-07-11) + + + +# [0.6.0](https://github.com/rango-exchange/rango-client/compare/wallets-adapter@0.5.0...wallets-adapter@0.6.0) (2023-07-11) + + +### Reverts + +* Revert "support for rango-types cjs format" ([ed4e050](https://github.com/rango-exchange/rango-client/commit/ed4e050bfc0dcde7aeffa6b0d73b02080a5721eb)) + + + +# [0.5.0](https://github.com/rango-exchange/rango-client/compare/wallets-adapter@0.4.0...wallets-adapter@0.5.0) (2023-05-31) + + + +# [0.4.0](https://github.com/rango-exchange/rango-client/compare/wallets-adapter@0.3.0...wallets-adapter@0.4.0) (2023-05-31) + + + +# [0.3.0](https://github.com/rango-exchange/rango-client/compare/wallets-adapter@0.2.0...wallets-adapter@0.3.0) (2023-05-30) + + + +# [0.2.0](https://github.com/rango-exchange/rango-client/compare/wallets-adapter@0.1.21...wallets-adapter@0.2.0) (2023-05-30) + + + +## [0.1.21](https://github.com/rango-exchange/rango-client/compare/wallets-adapter@0.1.20...wallets-adapter@0.1.21) (2023-05-15) + + + +## [0.1.14](https://github.com/rango-exchange/rango-client/compare/wallets-adapter@0.1.13...wallets-adapter@0.1.14) (2023-05-15) + + +### Bug Fixes + +* update rango-types and fix notification bugs ([993f185](https://github.com/rango-exchange/rango-client/commit/993f185e0b8c5e5e15a2c65ba2d85d1f9c8daa90)) + + + diff --git a/wallets/wallets-adapter/package.json b/wallets/wallets-adapter/package.json index 47a9637459..5383c701d9 100644 --- a/wallets/wallets-adapter/package.json +++ b/wallets/wallets-adapter/package.json @@ -1,54 +1,35 @@ { "name": "@rango-dev/wallets-adapter", - "version": "0.1.12", + "version": "0.36.1-next.12", "license": "MIT", - "module": "dist/wallets-adapter.esm.js", - "main": "dist/index.js", + "type": "module", + "module": "./dist/index.js", + "main": "./dist/index.js", + "exports": { + ".": "./dist/index.js" + }, "typings": "dist/index.d.ts", "files": [ "dist", "src" ], "scripts": { - "start": "tsdx watch", - "build": "tsdx build --tsconfig ./tsconfig.json", - "test": "tsdx test --passWithNoTests", - "lint": "tsdx lint", - "size": "size-limit", - "analyze": "size-limit --why" + "build": "node ../../scripts/build/command.mjs --path wallets/wallets-adapter", + "clean": "rimraf dist", + "format": "prettier --write '{.,src}/**/*.{ts,tsx}'", + "lint": "eslint \"**/*.{ts,tsx}\" --ignore-path ../../.eslintignore" }, "peerDependencies": { "react": ">=16" }, - "husky": { - "hooks": { - "pre-commit": "tsdx lint" - } - }, - "prettier": { - "printWidth": 80, - "semi": true, - "singleQuote": true, - "trailingComma": "es5" - }, - "size-limit": [ - { - "path": "dist/wallets-adapter.cjs.production.min.js", - "limit": "10 KB" - }, - { - "path": "dist/wallets-adapter.esm.js", - "limit": "10 KB" - } - ], "dependencies": { - "@rango-dev/provider-all": "^0.1.12", - "@rango-dev/ui": "^0.1.12", - "@rango-dev/wallets-core": "^0.1.12", - "@rango-dev/wallets-shared": "^0.1.11", - "rango-types": "^0.1.28" + "@rango-dev/provider-all": "^0.40.1-next.8", + "@rango-dev/ui": "^0.42.1-next.11", + "@rango-dev/wallets-react": "^0.26.1-next.9", + "@rango-dev/wallets-shared": "^0.40.1-next.6", + "rango-types": "^0.1.74" }, "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/wallets/wallets-adapter/src/adapter.tsx b/wallets/wallets-adapter/src/adapter.tsx index d7759cc83f..88764f876c 100644 --- a/wallets/wallets-adapter/src/adapter.tsx +++ b/wallets/wallets-adapter/src/adapter.tsx @@ -1,18 +1,21 @@ -import React, { - createContext, - PropsWithChildren, - useContext, - useReducer, -} from 'react'; -import { ProviderContext } from './types'; +import type { ProviderContext } from './types'; +import type { WalletType } from '@rango-dev/wallets-shared'; +import type { PropsWithChildren } from 'react'; + +import { useWallets } from '@rango-dev/wallets-react'; +import React, { createContext, useContext, useMemo, useReducer } from 'react'; + import { defaultState, state_reducer } from './helpers'; -import { useWallets } from '@rango-dev/wallets-core'; import Modal from './modal'; -import { WalletType } from '@rango-dev/wallets-shared'; + +// eslint-disable-next-line // @ts-ignore const AdapterContext = createContext({}); -function Adapter({ children, list }: PropsWithChildren<{ list: WalletType[] }>) { +function Adapter({ + children, + list, +}: PropsWithChildren<{ list: WalletType[] }>) { const [modalState, dispatch] = useReducer(state_reducer, defaultState); const { disconnectAll, @@ -21,29 +24,32 @@ function Adapter({ children, list }: PropsWithChildren<{ list: WalletType[] }>) getWalletInfo, providers, } = useWallets(); - const api: ProviderContext = { - onOpenModal() { - dispatch({ value: true }); - }, - onCloseModal() { - dispatch({ value: false }); - }, - async disconnectAll() { - return await disconnectAll(); - }, - canSwitchNetworkTo(type, network) { - return canSwitchNetworkTo(type, network); - }, - providers() { - return providers(); - }, - getWalletInfo(type) { - return getWalletInfo(type); - }, - getSigners(type) { - return getSigners(type); - }, - }; + const api = useMemo(() => { + const providerContext: ProviderContext = { + onOpenModal() { + dispatch({ value: true }); + }, + onCloseModal() { + dispatch({ value: false }); + }, + async disconnectAll() { + return await disconnectAll(); + }, + canSwitchNetworkTo(type: string, network: string) { + return canSwitchNetworkTo(type, network); + }, + providers() { + return providers(); + }, + getWalletInfo(type: string) { + return getWalletInfo(type); + }, + async getSigners(type: string) { + return getSigners(type); + }, + }; + return providerContext; + }, []); return ( {children} @@ -54,10 +60,11 @@ function Adapter({ children, list }: PropsWithChildren<{ list: WalletType[] }>) export function useAdapter(): ProviderContext { const context = useContext(AdapterContext); - if (!context) + if (!context) { throw Error( 'useModalAdapter can only be used within the Provider component' ); + } return context; } diff --git a/wallets/wallets-adapter/src/helpers.ts b/wallets/wallets-adapter/src/helpers.ts index a361f7fe5e..3b8693db08 100644 --- a/wallets/wallets-adapter/src/helpers.ts +++ b/wallets/wallets-adapter/src/helpers.ts @@ -1,9 +1,12 @@ -import { WalletInfo, WalletState, WalletType } from '@rango-dev/wallets-shared'; -import { ModalState, State } from './types'; -import { - WalletInfo as ModalWalletInfo, - WalletState as WalletStatus, -} from '@rango-dev/ui'; +import type { ModalState, State } from './types'; +import type { WalletInfo as ModalWalletInfo } from '@rango-dev/ui'; +import type { + WalletInfo, + WalletState, + WalletType, +} from '@rango-dev/wallets-shared'; + +import { WalletState as WalletStatus } from '@rango-dev/ui'; export const defaultState: ModalState = { open: false, @@ -31,34 +34,22 @@ export const getStateWallet = (state: State): WalletStatus => { } }; -export function getlistWallet( +export function mapWalletTypesToWalletInfo( getState: (type: WalletType) => WalletState, getWalletInfo: (type: WalletType) => WalletInfo, list: WalletType[] ): ModalWalletInfo[] { - const excludedWallets = [ - WalletType.UNKNOWN, - WalletType.TERRA_STATION, - WalletType.LEAP, - ]; - - return list - .filter((wallet) => !excludedWallets.includes(wallet)) - .map((type) => { - const { - name, - img: image, - installLink, - showOnMobile, - } = getWalletInfo(type); - const state = getStateWallet(getState(type)); - return { - name, - image, - installLink, - state, - type, - showOnMobile: showOnMobile || false, - }; - }); + return list.map((type) => { + const { name, img: image, installLink, showOnMobile } = getWalletInfo(type); + const state = getStateWallet(getState(type)); + return { + title: name, + image, + link: installLink, + state, + type, + showOnMobile: showOnMobile || false, + blockchainTypes: [], + }; + }); } diff --git a/wallets/wallets-adapter/src/modal.tsx b/wallets/wallets-adapter/src/modal.tsx index 1cc97b4d0c..5dbacd8d37 100644 --- a/wallets/wallets-adapter/src/modal.tsx +++ b/wallets/wallets-adapter/src/modal.tsx @@ -1,8 +1,11 @@ +import type { WalletType } from '@rango-dev/wallets-shared'; + import { ConnectWalletsModal } from '@rango-dev/ui'; -import { useWallets } from '@rango-dev/wallets-core'; -import { WalletType } from '@rango-dev/wallets-shared'; +import { useWallets } from '@rango-dev/wallets-react'; import React, { useState } from 'react'; -import { getlistWallet } from './helpers'; + +import { mapWalletTypesToWalletInfo } from './helpers'; + export interface PropTypes { open: boolean; onClose: () => void; @@ -14,7 +17,7 @@ function Modal(props: PropTypes) { const [walletMessage, setWalletErrorMessage] = useState(''); const { state, disconnect, getWalletInfo, connect } = useWallets(); - const allWallets = getlistWallet(state, getWalletInfo, list); + const allWallets = mapWalletTypesToWalletInfo(state, getWalletInfo, list); const onSelectWallet = async (type: WalletType) => { const wallet = state(type); diff --git a/wallets/wallets-adapter/src/provider.tsx b/wallets/wallets-adapter/src/provider.tsx index 7cbf56a634..94b36883b9 100644 --- a/wallets/wallets-adapter/src/provider.tsx +++ b/wallets/wallets-adapter/src/provider.tsx @@ -1,11 +1,16 @@ +import type { LegacyProviderInterface } from '@rango-dev/wallets-core/legacy'; +import type { ProviderProps } from '@rango-dev/wallets-react'; + +import { Provider } from '@rango-dev/wallets-react'; import React from 'react'; -import { ProviderProps, Provider } from '@rango-dev/wallets-core'; + import Adapter from './adapter'; -import { WalletProvider } from '@rango-dev/wallets-core'; function AdapterProvider({ children, ...props }: ProviderProps) { const list = props.providers.map( - (provider: WalletProvider) => provider.config.type + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore-next-line + (provider: LegacyProviderInterface) => provider.config.type ); return ( diff --git a/wallets/wallets-adapter/src/types.ts b/wallets/wallets-adapter/src/types.ts index 83b801ca3b..0d2048187a 100644 --- a/wallets/wallets-adapter/src/types.ts +++ b/wallets/wallets-adapter/src/types.ts @@ -1,6 +1,11 @@ -import { Providers } from '@rango-dev/wallets-core'; -import { Network, WalletType, WalletInfo } from '@rango-dev/wallets-shared'; -import { SignerFactory } from 'rango-types'; +import type { Providers } from '@rango-dev/wallets-react'; +import type { + Network, + WalletInfo, + WalletType, +} from '@rango-dev/wallets-shared'; +import type { SignerFactory } from 'rango-types'; + export interface State { connected: boolean; connecting: boolean; @@ -16,7 +21,7 @@ export type ProviderContext = { disconnectAll(): Promise[]>; canSwitchNetworkTo(type: WalletType, network: Network): boolean; providers(): Providers; - getSigners(type: WalletType): SignerFactory; + getSigners(type: WalletType): Promise; getWalletInfo(type: WalletType): WalletInfo; }; diff --git a/wallets/wallets-adapter/tsconfig.build.json b/wallets/wallets-adapter/tsconfig.build.json new file mode 100644 index 0000000000..044aea9a33 --- /dev/null +++ b/wallets/wallets-adapter/tsconfig.build.json @@ -0,0 +1,11 @@ +{ + // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs + "extends": "../../tsconfig.lib.json", + "include": ["src", "types"], + "compilerOptions": { + "outDir": "dist", + "rootDir": "./src", + "lib": ["dom", "esnext"], + "jsx": "react" + } +} diff --git a/wallets/wallets-adapter/tsconfig.json b/wallets/wallets-adapter/tsconfig.json index 2c85b2d991..a3a0b0f59d 100644 --- a/wallets/wallets-adapter/tsconfig.json +++ b/wallets/wallets-adapter/tsconfig.json @@ -1,35 +1 @@ -{ - // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs - "include": ["src", "types"], - "compilerOptions": { - "module": "esnext", - "lib": ["dom", "esnext"], - "importHelpers": true, - // output .d.ts declaration files for consumers - "declaration": true, - // output .js.map sourcemap files for consumers - "sourceMap": true, - // match output dir to input dir. e.g. dist/index instead of dist/src/index - "rootDir": "./src", - // stricter type-checking for stronger correctness. Recommended by TS - "strict": true, - // linter checks for common issues - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true, - // noUnused* overlap with @typescript-eslint/no-unused-vars, can disable if duplicative - "noUnusedLocals": true, - "noUnusedParameters": true, - // use Node's module resolution algorithm, instead of the legacy TS one - "moduleResolution": "node", - // transpile JSX to React.createElement - "jsx": "react", - // interop between ESM and CJS modules. Recommended by TS - "esModuleInterop": true, - // significant perf increase by skipping checking .d.ts files, particularly those in node_modules. Recommended by TS - "skipLibCheck": true, - // error out if import and file system have a casing mismatch. Recommended by TS - "forceConsistentCasingInFileNames": true, - // `tsdx build` ignores this option, but it is commonly used when type-checking separately with `tsc` - "noEmit": true, - } -} +{ "extends": "./tsconfig.build.json", "include": ["src", "tests"] } diff --git a/widget/app/package.json b/widget/app/package.json new file mode 100644 index 0000000000..4cc7eb2a25 --- /dev/null +++ b/widget/app/package.json @@ -0,0 +1,29 @@ +{ + "name": "@rango-dev/widget-app", + "version": "0.24.0", + "license": "MIT", + "private": true, + "source": "public/index.html", + "main": "dist/index.html", + "targets": { + "main": false + }, + "browserslist": "> 0.5%, last 2 versions, not dead", + "scripts": { + "dev": "parcel -p 3002 --cache-dir=.parcel-cache --no-cache", + "build": "parcel build --cache-dir=.parcel-cache", + "ts-check": "tsc --declaration --emitDeclarationOnly -p ./tsconfig.json", + "clean": "rimraf .parcel-cache && rimraf dist", + "format": "prettier --write '{.,src}/**/*.{ts,tsx}'", + "lint": "eslint \"**/*.{ts,tsx}\" --ignore-path ../../.eslintignore" + }, + "devDependencies": {}, + "dependencies": { + "@rango-dev/logging-console": "^0.6.0", + "@rango-dev/logging-subscriber": "^0.6.0", + "@rango-dev/widget-embedded": "^0.36.1-next.16", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "react-router-dom": "^6.8.0" + } +} \ No newline at end of file diff --git a/widget/app/public/index.css b/widget/app/public/index.css new file mode 100644 index 0000000000..74ee787f4c --- /dev/null +++ b/widget/app/public/index.css @@ -0,0 +1,17 @@ +@import url('https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap'); + +html { + box-sizing: border-box; +} + +body { + padding: 0; + margin: 0; + background-color: transparent; +} + +#app { + min-height: 100vh; + display: flex; + justify-content: center; +} diff --git a/widget/app/public/index.html b/widget/app/public/index.html new file mode 100644 index 0000000000..2503831f79 --- /dev/null +++ b/widget/app/public/index.html @@ -0,0 +1,16 @@ + + + + + + Rango Widget + + + +
+ + + diff --git a/widget/app/src/App.tsx b/widget/app/src/App.tsx new file mode 100644 index 0000000000..e62489b538 --- /dev/null +++ b/widget/app/src/App.tsx @@ -0,0 +1,56 @@ +import type { WidgetConfig } from '@rango-dev/widget-embedded'; + +import { Widget } from '@rango-dev/widget-embedded'; +import React, { useRef } from 'react'; +import { Route, Routes, useSearchParams } from 'react-router-dom'; + +import { + TON_CONNECT_MANIFEST_URL, + TREZOR_MANIFEST, + WC_PROJECT_ID, +} from './constants'; + +export function App() { + const [searchParams] = useSearchParams(); + const configRef = useRef(); + const configParam = searchParams.get('config'); + + let config: WidgetConfig | undefined = undefined; + + if (!configRef.current) { + if (!!configParam) { + try { + config = JSON.parse(configParam, (_, value) => { + if (typeof value === 'string' && value[0] === '$') { + return value.replace('$', '#'); + } + return value; + }); + } catch (error) { + console.error('Widget config param is invalid!'); + } + } else { + /* + *TODO: + *The assumption here is this object won't be created on iframe so we are on dev mode. + *We should consider a more proper way. + */ + + config = { + apiKey: '', + walletConnectProjectId: WC_PROJECT_ID, + trezorManifest: TREZOR_MANIFEST, + tonConnect: { manifestUrl: TON_CONNECT_MANIFEST_URL }, + }; + } + if (!!config) { + configRef.current = config; + } + } + + return ( + + } /> + + ); +} diff --git a/widget/app/src/constants.ts b/widget/app/src/constants.ts new file mode 100644 index 0000000000..02a20ef1ea --- /dev/null +++ b/widget/app/src/constants.ts @@ -0,0 +1,7 @@ +export const WC_PROJECT_ID = 'e24844c5deb5193c1c14840a7af6a40b'; +export const TREZOR_MANIFEST = { + appUrl: 'https://widget.rango.exchange/', + email: 'hi+trezorwidget@rango.exchange', +}; +export const TON_CONNECT_MANIFEST_URL = + 'https://raw.githubusercontent.com/rango-exchange/assets/refs/heads/main/manifests/tonconnect/manifest.json'; diff --git a/widget/app/src/index.tsx b/widget/app/src/index.tsx new file mode 100644 index 0000000000..8f59f4fa77 --- /dev/null +++ b/widget/app/src/index.tsx @@ -0,0 +1,22 @@ +import { layer as consoleLayer } from '@rango-dev/logging-console'; +import { init, Level } from '@rango-dev/logging-subscriber'; +import React from 'react'; +import { createRoot } from 'react-dom/client'; +import { BrowserRouter } from 'react-router-dom'; + +import { App } from './App'; + +if (process.env.NODE_ENV === 'development') { + init([consoleLayer()], { + baseLevel: Level.Info, + }); +} + +const container = document.getElementById('app')!; +const root = createRoot(container); + +root.render( + + + +); diff --git a/widget/app/tsconfig.build.json b/widget/app/tsconfig.build.json new file mode 100644 index 0000000000..70719f8f2b --- /dev/null +++ b/widget/app/tsconfig.build.json @@ -0,0 +1,14 @@ +{ + // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs + "extends": "../../tsconfig.lib.json", + "include": ["src", "types"], + "compilerOptions": { + "module": "esnext", + "outDir": "dist", + "lib": ["dom", "esnext"], + // match output dir to input dir. e.g. dist/index instead of dist/src/index + "rootDir": "./src", + // transpile JSX to React.createElement + "jsx": "react" + } +} diff --git a/widget/app/tsconfig.json b/widget/app/tsconfig.json new file mode 100644 index 0000000000..a3a0b0f59d --- /dev/null +++ b/widget/app/tsconfig.json @@ -0,0 +1 @@ +{ "extends": "./tsconfig.build.json", "include": ["src", "tests"] } diff --git a/widget/charts/CHANGELOG.md b/widget/charts/CHANGELOG.md new file mode 100644 index 0000000000..a8322d4017 --- /dev/null +++ b/widget/charts/CHANGELOG.md @@ -0,0 +1,32 @@ +# [0.5.0](https://github.com/rango-exchange/rango-client/compare/charts@0.4.0...charts@0.5.0) (2024-12-30) + + + +# [0.4.0](https://github.com/rango-exchange/rango-client/compare/charts@0.3.0...charts@0.4.0) (2024-11-27) + + + +# [0.3.0](https://github.com/rango-exchange/rango-client/compare/charts@0.2.0...charts@0.3.0) (2024-11-12) + + +### Bug Fixes + +* improve y-axis display for bar charts with smaller data sets ([ad13491](https://github.com/rango-exchange/rango-client/commit/ad1349157f38d172ae2028981881ae4276ddab8d)) + + + +# 0.2.0 (2024-10-12) + + +### Bug Fixes + +* add chart icon and handle dark theme in BarChart component ([fd4f246](https://github.com/rango-exchange/rango-client/commit/fd4f24684e42deb1b47fb9a6584ac4f9a1519599)) +* add prepare data function for chart package ([a9f8c6b](https://github.com/rango-exchange/rango-client/commit/a9f8c6b092ca5343756e220238c943dbc369a62b)) + + +### Features + +* add chart package ([f5ae7e4](https://github.com/rango-exchange/rango-client/commit/f5ae7e449ec1e385188ff904e9d59862fa8ef1d2)) + + + diff --git a/widget/charts/package.json b/widget/charts/package.json new file mode 100644 index 0000000000..fff59aba2f --- /dev/null +++ b/widget/charts/package.json @@ -0,0 +1,41 @@ +{ + "name": "@rango-dev/charts", + "version": "0.4.1-next.10", + "license": "MIT", + "type": "module", + "source": "./src/index.ts", + "main": "./dist/index.js", + "exports": { + "types": "./dist/index.d.ts", + "default": "./dist/index.js" + }, + "typings": "./dist/index.d.ts", + "files": [ + "dist", + "src" + ], + "scripts": { + "build": "node ../../scripts/build/command.mjs --path widget/charts", + "ts-check": "tsc --declaration --emitDeclarationOnly -p ./tsconfig.json", + "clean": "rimraf dist", + "format": "prettier --write '{.,src}/**/*.{ts,tsx}'", + "lint": "eslint \"**/*.{ts,tsx}\" --ignore-path ../../.eslintignore" + }, + "peerDependencies": { + "react": ">=16", + "react-dom": ">=16" + }, + "dependencies": { + "@rango-dev/ui": "^0.42.1-next.11", + "@visx/axis": "2.18.0", + "@visx/event": "2.17.0", + "@visx/grid": "2.18.0", + "@visx/scale": "2.18.0", + "@visx/shape": "2.18.0", + "@visx/tooltip": "2.17.0", + "dayjs": "^1.11.6" + }, + "publishConfig": { + "access": "public" + } +} \ No newline at end of file diff --git a/widget/charts/readme.md b/widget/charts/readme.md new file mode 100644 index 0000000000..3eb8f61647 --- /dev/null +++ b/widget/charts/readme.md @@ -0,0 +1,4 @@ +# @rango-dev/charts + +Rango charts + diff --git a/widget/charts/src/components/BarChart/BarChart.constants.ts b/widget/charts/src/components/BarChart/BarChart.constants.ts new file mode 100644 index 0000000000..583d553b18 --- /dev/null +++ b/widget/charts/src/components/BarChart/BarChart.constants.ts @@ -0,0 +1,34 @@ +export const DEFAULT_MARGIN = { top: 40, right: 0, bottom: 0, left: 20 }; + +export const TOOLTIP_DELAY_MS = 100; +export const TOOLTIP_HIDE_DELAY_MS = 300; + +export const DEFAULT_CHART_COLORS: string[] = [ + '#469BF5', + '#29DABA', + '#D629DA', + '#4658F5', + '#9DF546', + '#F01DA8', + '#FF8B66', + '#44F1E6', + '#29DA7A', + '#F17606', + '#8B62FF', + '#F4C932', +]; + +export const bottomAxisData = { + desktop: { + 7: { numBottomAxis: 7, startBottomAxis: 0, intervalBottomAxis: 1 }, + 30: { numBottomAxis: 6, startBottomAxis: 4, intervalBottomAxis: 5 }, + 90: { numBottomAxis: 8, startBottomAxis: 5, intervalBottomAxis: 10 }, + }, + mobile: { + 7: { numBottomAxis: 3, startBottomAxis: 1, intervalBottomAxis: 2 }, + 30: { numBottomAxis: 3, startBottomAxis: 3, intervalBottomAxis: 10 }, + 90: { numBottomAxis: 3, startBottomAxis: 10, intervalBottomAxis: 30 }, + }, +}; + +export const MAX_BAR_BUCKETS = 10; diff --git a/widget/charts/src/components/BarChart/BarChart.helpers.ts b/widget/charts/src/components/BarChart/BarChart.helpers.ts new file mode 100644 index 0000000000..88cd56eaf1 --- /dev/null +++ b/widget/charts/src/components/BarChart/BarChart.helpers.ts @@ -0,0 +1,148 @@ +/* eslint-disable @typescript-eslint/no-magic-numbers */ +import type { + BarStackDataType, + ChartOptionsType, + ColorBucketMapType, + DailyDataType, +} from './BarChart.types.js'; + +import { MAX_BAR_BUCKETS } from './BarChart.constants.js'; + +export const getTotalValueDates = ( + data: BarStackDataType[], + buckets: string[] +) => { + const totalValueDates = data.reduce((accumulator, currentData) => { + const totalValuePerDate = buckets.reduce((dailyTotal, currentBucket) => { + dailyTotal += !isNaN(Number(currentData[currentBucket])) + ? Number(currentData[currentBucket]) + : 0; + return dailyTotal; + }, 0); + accumulator.push(totalValuePerDate); + return accumulator; + }, [] as number[]); + + return totalValueDates; +}; + +// Function to generate tick values at intervals of 5, starting from the 5th element +export const generateTickValues = ( + dates: string[], + start: number, + interval: number +) => { + const tickValues = []; + for (let i = start; i < dates.length; i += interval) { + tickValues.push(dates[i]); + } + return tickValues; +}; + +export const getTotalValue = (dataColumn: BarStackDataType) => { + let result = 0; + Object.keys(dataColumn).forEach((key) => { + if (key !== 'date') { + const value = dataColumn[key]; + if (!isNaN(Number(value))) { + result += Number(value); + } + } + }); + return result; +}; + +export const getDaysRange = (lengthValue: number) => { + if (lengthValue < 15) { + return 7; + } + if (lengthValue < 50) { + return 30; + } + return 90; +}; + +export const prepareBarChartData = (chartOption: ChartOptionsType) => { + const { dailyData, label = 'Count' } = chartOption; + const chartData: BarStackDataType[] = []; + const colorBucketMap: ColorBucketMapType = new Map(); + const buckets: string[] = []; + + const { barChartColors } = chartOption; + + // map sum of value for each bucket + const sumBucketMap = new Map(); + dailyData.forEach((dailyItem) => { + const keyItem = dailyItem.bucket || label; + + const sum = sumBucketMap.get(keyItem) || 0; + const newValue = dailyItem.value; + sumBucketMap.set(keyItem, sum + newValue); + }); + + const sortedBucket = Array.from(sumBucketMap).sort((a, b) => b[1] - a[1]); + + // get top buckets for stack bars + const topBucket = sortedBucket + .map((sortedItem) => sortedItem[0]) + .slice(0, MAX_BAR_BUCKETS); + + const bucketCount = sumBucketMap.size; + + // create map structure for assign color for each bucket + topBucket.forEach((bucketItem, index) => { + colorBucketMap.set( + bucketItem, + barChartColors[index % barChartColors.length] + ); + buckets.push(bucketItem); + }); + + if (bucketCount > MAX_BAR_BUCKETS) { + colorBucketMap.set('Others', barChartColors[barChartColors.length - 1]); + buckets.push('Others'); + } + + // create map structure for assign chart data for each date + const dateMap = new Map(); + dailyData.forEach((dailyItem) => { + if (!dateMap.has(dailyItem.date)) { + dateMap.set(dailyItem.date, []); + } + + const dateItem = dateMap.get(dailyItem.date); + dateItem?.push(dailyItem); + }); + + // create data result for bar stack chart + dateMap.forEach((dateDailyList, keyDate) => { + const dataItem: BarStackDataType = { date: keyDate }; + dateDailyList + .filter((dailyItem) => topBucket.includes(dailyItem.bucket || label)) + .forEach((topDailyItem) => { + const bucketValue = topDailyItem.value; + dataItem[topDailyItem.bucket || label] = bucketValue + ? bucketValue.toString() + : '0'; + }); + + topBucket.forEach((topItem) => { + if (!(topItem in dataItem)) { + dataItem[topItem] = '0'; + } + }); + + if (bucketCount > MAX_BAR_BUCKETS) { + const otherBuckets = dateDailyList.filter( + (dailyItem) => dailyItem.bucket && !topBucket.includes(dailyItem.bucket) + ); + const othersValue = otherBuckets + .map((dailyItem) => dailyItem.value) + .reduce((accumulator, currentValue) => accumulator + currentValue, 0); + dataItem['Others'] = othersValue.toString(); + } + + chartData.push(dataItem); + }); + return { chartData, colorBucketMap, buckets }; +}; diff --git a/widget/charts/src/components/BarChart/BarChart.styles.ts b/widget/charts/src/components/BarChart/BarChart.styles.ts new file mode 100644 index 0000000000..72f974bbbe --- /dev/null +++ b/widget/charts/src/components/BarChart/BarChart.styles.ts @@ -0,0 +1,55 @@ +import { darkTheme, styled } from '@rango-dev/ui'; + +export const Container = styled('div', { + position: 'relative', +}); + +export const TooltipContainer = styled('div', { + width: 165, + borderRadius: '$sm', + backgroundColor: '$background', + + $$color: '$colors$neutral500', + [`.${darkTheme} &`]: { + $$color: '$colors$neutral100', + }, + + boxShadow: '0px 5px 20px 0px $$color', +}); + +export const TooltipInfoRow = styled('div', { + display: 'flex', + alignItems: 'center', + fontSize: '$12', + justifyContent: 'space-between', + padding: '$8 $10', + fontWeight: '$medium', + color: '$foreground', +}); + +export const Line = styled('div', { + height: 1, + width: '100%', + backgroundColor: '$neutral300', +}); + +export const InfoContainer = styled('div', { + display: 'flex', + alignItems: 'center', + justifyContent: 'space-between', + fontSize: '$10', + padding: '$5 $10', + color: '$foreground', +}); + +export const Circle = styled('div', { + width: '$6', + height: '$6', + borderRadius: 3, +}); + +export const NameWrapper = styled('div', { + display: 'flex', + alignItems: 'center', + justifyContent: 'flex-start', +}); diff --git a/widget/charts/src/components/BarChart/BarChart.tsx b/widget/charts/src/components/BarChart/BarChart.tsx new file mode 100644 index 0000000000..a0fe3596dc --- /dev/null +++ b/widget/charts/src/components/BarChart/BarChart.tsx @@ -0,0 +1,387 @@ +/* eslint-disable @typescript-eslint/no-magic-numbers */ +import type { + BarChartPropTypes, + BarStackDataType, + TooltipDataType, +} from './BarChart.types.js'; +import type { BarGroupBar, SeriesPoint } from '@visx/shape/lib/types'; + +import { Divider } from '@rango-dev/ui'; +import { AxisBottom, AxisLeft } from '@visx/axis'; +import { localPoint } from '@visx/event'; +import { Grid } from '@visx/grid'; +import { Group } from '@visx/group'; +import { scaleBand, scaleLinear, scaleOrdinal } from '@visx/scale'; +import { BarStack } from '@visx/shape'; +import { TooltipWithBounds, useTooltip } from '@visx/tooltip'; +import dayjs from 'dayjs'; +import utc from 'dayjs/plugin/utc.js'; +import React, { Fragment, useEffect, useRef } from 'react'; + +import useIsMobile from '../../hooks/useIsMobile.js'; +import { + AmountConverter, + compactNumberFormat, +} from '../../utils/amountConverter.js'; +import { getDayOfMonth } from '../../utils/common.js'; + +import { + bottomAxisData, + DEFAULT_CHART_COLORS, + DEFAULT_MARGIN, + TOOLTIP_DELAY_MS, + TOOLTIP_HIDE_DELAY_MS, +} from './BarChart.constants.js'; +import { + generateTickValues, + getDaysRange, + getTotalValue, + getTotalValueDates, +} from './BarChart.helpers.js'; +import { + Circle, + Container, + InfoContainer, + Line, + NameWrapper, + TooltipContainer, + TooltipInfoRow, +} from './BarChart.styles.js'; + +dayjs.extend(utc); + +export const BarChart = (props: BarChartPropTypes) => { + const { + data, + width, + height, + colorBucketMap, + buckets, + margin = DEFAULT_MARGIN, + getLabel, + isDarkTheme = false, + } = props; + + const isMobile = useIsMobile(); + const daysRange = getDaysRange(data.length); + const bottomAxis = + width < 700 + ? bottomAxisData.mobile[daysRange] + : bottomAxisData.desktop[daysRange]; + + const { intervalBottomAxis, numBottomAxis, startBottomAxis } = bottomAxis; + + let tooltipTimeout: number; + const tooltipRef = useRef(null); + + // bounds + const xMax = width - margin.left - 20; + const yMax = height - margin.top - 30; + + // accessors + const getDate = (d: BarStackDataType) => d.date; + + // handle bottom axis data + const allDate = data.map(getDate); + + const bottomAxisValue = generateTickValues( + allDate, + startBottomAxis, + intervalBottomAxis + ); + + const { + tooltipOpen, + tooltipLeft, + tooltipTop, + tooltipData, + hideTooltip, + showTooltip, + } = useTooltip(); + + const totalValueDates = getTotalValueDates(data, buckets); + + // scales + const dateScale = scaleBand({ + domain: data.map(getDate), + paddingInner: daysRange === 7 ? 0.3 : 0.46, + paddingOuter: daysRange === 90 ? 1 : 0.3, + }); + + const totalValue = Math.max(...totalValueDates); + + const scaledMaxValue = totalValue + totalValue / 5; + const valueScale = scaleLinear({ + domain: [0, scaledMaxValue < 0.5 ? 0.5 : scaledMaxValue], + nice: true, + }); + const colorScale = scaleOrdinal({ + domain: buckets, + range: DEFAULT_CHART_COLORS, + }); + + useEffect(() => { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + function handleClickOutside(event: any) { + if ( + isMobile && + tooltipRef?.current && + !tooltipRef.current.contains(event.target) + ) { + hideTooltip(); + } + } + document.addEventListener('click', handleClickOutside, true); + return () => { + document.removeEventListener('click', handleClickOutside, true); + }; + }, [tooltipRef, isMobile]); + + dateScale.range([0, xMax]); + valueScale.range([yMax, 0]); + + if (width < 10) { + return null; + } + + const handleBarClick = ( + event: React.MouseEvent, + bar: Omit, 'key' | 'value'> & { + bar: SeriesPoint; + key: string; + }, + index: number + ) => { + if (isMobile) { + if (tooltipTimeout) { + clearTimeout(tooltipTimeout); + } + const eventSvgCoords = localPoint(event); + const left = bar.x + bar.width / 2; + setTimeout(() => { + showTooltip({ + tooltipData: { bar, hoveredIndex: index }, + tooltipTop: eventSvgCoords?.y, + tooltipLeft: left, + }); + }, TOOLTIP_DELAY_MS); + } + }; + + const handleMouseLeave = () => { + if (!isMobile) { + tooltipTimeout = window.setTimeout(() => { + hideTooltip(); + }, TOOLTIP_HIDE_DELAY_MS); + } + }; + + const handleMouseMove = ( + event: React.MouseEvent, + bar: Omit, 'key' | 'value'> & { + bar: SeriesPoint; + key: string; + }, + index: number + ) => { + if (!isMobile) { + if (tooltipTimeout) { + clearTimeout(tooltipTimeout); + } + /* + * TooltipInPortal expects coordinates to be relative to containerRef + * localPoint returns coordinates relative to the nearest SVG, which + * is what containerRef is set to in this example. + */ + const eventSvgCoords = localPoint(event); + const left = bar.x + bar.width / 2 + 40; + + // make sure to pass the index of the hovered bar + showTooltip({ + tooltipData: { bar, hoveredIndex: index }, + tooltipTop: eventSvgCoords?.y, + tooltipLeft: left, + }); + } + }; + + const getFormattedTotalValue = (data: BarStackDataType) => + AmountConverter(Number(getTotalValue(data).toFixed(2))); + + return ( + + + + + + + + {(barStacks) => { + /* + * barStacks returns an array of series objects broken down by key. + */ + return barStacks.map((barStack) => + /* + * each barStack contains an array of bars, which contain the data + * for only that series for a given data point. the number of bars in a + * given stack corresponds to the number of data points in our data array + */ + + barStack.bars.map((bar, index) => { + /* + * we can then assume that the data in each stack at a given index + * is related to the data in all other stacks at that index. + */ + const shouldBeHighlighted = + tooltipData?.hoveredIndex === index; + + /* + * we can then decide the opacity for our stacks based on whether the + * tooltip is open, and whether the stack being hovered matches the + * index passed to our tooltipData + */ + const shouldHavePartialOpacity = + !shouldBeHighlighted && tooltipOpen; + + const barColor = + colorBucketMap.get(barStack.key) || bar.color; + + return ( + handleBarClick(event, bar, index)} + onMouseLeave={handleMouseLeave} + onMouseMove={(event) => + handleMouseMove(event, bar, index) + } + /> + ); + }) + ); + }} + + + + getDayOfMonth(d)} + tickLabelProps={() => ({ + fontSize: isMobile ? 10 : 12, + fill: isDarkTheme ? '#B8B8B8' : '#A2A2A2', + textAnchor: 'middle', + })} + /> + + compactNumberFormat(Number(d))} + tickLabelProps={() => ({ + fontSize: isMobile ? 10 : 12, + fill: isDarkTheme ? '#B8B8B8' : '#A2A2A2', + textAnchor: 'middle', + })} + /> + + + {tooltipData && tooltipOpen && ( + + + {tooltipData?.bar.bar.data.date && ( + +
+ {dayjs + .utc(tooltipData.bar.bar.data.date) + .local() + .format('YYYY/MM/DD') + .toString()} +
+
+ {getLabel + ? getLabel(getFormattedTotalValue(tooltipData.bar.bar.data)) + : getFormattedTotalValue(tooltipData.bar.bar.data)} +
+
+ )} + {Array.from(colorBucketMap).map((mapItem) => { + const [bucketItem, bucketColor] = mapItem; + const value = tooltipData?.bar.bar.data[bucketItem]; + const formattedValue = !isNaN(Number(value)) + ? AmountConverter(Number(Number(value).toFixed(2))) + : '0'; + return ( + + + + + + + {bucketItem} + + + + + {getLabel ? getLabel(formattedValue) : formattedValue} + + + + ); + })} +
+
+ )} +
+ ); +}; diff --git a/widget/charts/src/components/BarChart/BarChart.types.ts b/widget/charts/src/components/BarChart/BarChart.types.ts new file mode 100644 index 0000000000..5d0d12de32 --- /dev/null +++ b/widget/charts/src/components/BarChart/BarChart.types.ts @@ -0,0 +1,44 @@ +import type { SeriesPoint } from '@visx/shape/lib/types/barStack.js'; + +export interface BarChartPropTypes { + data: BarStackDataType[]; + width: number; + height: number; + colorBucketMap: ColorBucketMapType; + buckets: string[]; + margin?: { top: number; right: number; bottom: number; left: number }; + getLabel?: (value: string) => string; + isDarkTheme?: boolean; +} + +export type BarStackDataType = { + [key: string]: string; +}; + +export type ColorBucketMapType = Map; + +export type TooltipDataType = { + bar: { + bar: SeriesPoint; + key: string; + index: number; + height: number; + width: number; + x: number; + y: number; + color: string; + }; + hoveredIndex: number; +}; + +export type DailyDataType = { + date: string; + bucket: string; + value: number; +}; + +export type ChartOptionsType = { + dailyData: DailyDataType[]; + barChartColors: string[]; + label?: string; +}; diff --git a/widget/charts/src/components/BarChart/index.ts b/widget/charts/src/components/BarChart/index.ts new file mode 100644 index 0000000000..67bfd2620a --- /dev/null +++ b/widget/charts/src/components/BarChart/index.ts @@ -0,0 +1,10 @@ +export { BarChart } from './BarChart.js'; +export { prepareBarChartData } from './BarChart.helpers.js'; + +export type { + BarStackDataType, + ColorBucketMapType, + BarChartPropTypes, + ChartOptionsType, + DailyDataType, +} from './BarChart.types.js'; diff --git a/widget/charts/src/hooks/useIsMobile.ts b/widget/charts/src/hooks/useIsMobile.ts new file mode 100644 index 0000000000..f6f909169a --- /dev/null +++ b/widget/charts/src/hooks/useIsMobile.ts @@ -0,0 +1,20 @@ +import { useEffect, useState } from 'react'; + +const useIsMobile = () => { + const [isMobile, setIsMobile] = useState(false); + + useEffect(() => { + const handleResize = () => { + const mobileBreakpoint = 640; + setIsMobile(window.innerWidth <= mobileBreakpoint); + }; + + handleResize(); + window.addEventListener('resize', handleResize); + return () => window.removeEventListener('resize', handleResize); + }, []); + + return isMobile; +}; + +export default useIsMobile; diff --git a/widget/charts/src/index.ts b/widget/charts/src/index.ts new file mode 100644 index 0000000000..3953db8778 --- /dev/null +++ b/widget/charts/src/index.ts @@ -0,0 +1,8 @@ +export type { + BarStackDataType, + ColorBucketMapType, + BarChartPropTypes, + ChartOptionsType, + DailyDataType, +} from './components/BarChart/index.js'; +export { BarChart, prepareBarChartData } from './components/BarChart/index.js'; diff --git a/widget/charts/src/utils/amountConverter.ts b/widget/charts/src/utils/amountConverter.ts new file mode 100644 index 0000000000..5676da932c --- /dev/null +++ b/widget/charts/src/utils/amountConverter.ts @@ -0,0 +1,47 @@ +const THRESHOLD = 1000; +const BASE_TEN = 10; +const PERCENTAGE_MULTIPLIER = 100; + +const unitList = ['', 'K', 'M', 'B']; +export function AmountConverter(number: number) { + const sign = Math.sign(number); + let unit = 0; + while (Math.abs(number) > THRESHOLD) { + unit = unit + 1; + number = Math.floor(Math.abs(number) / BASE_TEN) / PERCENTAGE_MULTIPLIER; + } + return sign * Math.abs(number) + unitList[unit]; +} + +export function getPercentageChange( + input: number | null, + output: number | null +) { + if (!input || !output) { + return null; + } + return parseFloat( + Number((output / input - 1) * PERCENTAGE_MULTIPLIER).toFixed(2) + ); +} + +export function numberWithCommas(number: number) { + if (!number || isNaN(number)) { + return number; + } + + return number.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ','); +} + +export function compactNumberFormat(number: number) { + if (!number || isNaN(number)) { + return '0'; + } + + const numberFormat = Intl.NumberFormat('en-US', { + notation: 'compact', + maximumFractionDigits: 1, + }).format(number); + + return numberFormat; +} diff --git a/widget/charts/src/utils/common.ts b/widget/charts/src/utils/common.ts new file mode 100644 index 0000000000..7e5c280c1c --- /dev/null +++ b/widget/charts/src/utils/common.ts @@ -0,0 +1,22 @@ +export const monthsShort = [ + 'Jan', + 'Feb', + 'Mar', + 'Apr', + 'May', + 'Jun', + 'Jul', + 'Aug', + 'Sep', + 'Oct', + 'Nov', + 'Dec', +]; + +export function getDayOfMonth(dateString: string) { + const date = new Date(dateString); + const monthName = date.toLocaleDateString('en-US', { month: 'short' }); + const dayNumber = date.getDate(); + + return `${dayNumber} ${monthName}`; +} diff --git a/widget/charts/tsconfig.build.json b/widget/charts/tsconfig.build.json new file mode 100644 index 0000000000..e00196ee35 --- /dev/null +++ b/widget/charts/tsconfig.build.json @@ -0,0 +1,11 @@ +{ + // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs + "extends": "../../tsconfig.libnext.json", + "include": ["src"], + "compilerOptions": { + "outDir": "dist", + "rootDir": "./src", + "jsx": "react", + "skipLibCheck": true + } +} diff --git a/widget/charts/tsconfig.json b/widget/charts/tsconfig.json new file mode 100644 index 0000000000..a3a0b0f59d --- /dev/null +++ b/widget/charts/tsconfig.json @@ -0,0 +1 @@ +{ "extends": "./tsconfig.build.json", "include": ["src", "tests"] } diff --git a/widget/embedded/CHANGELOG.md b/widget/embedded/CHANGELOG.md new file mode 100644 index 0000000000..80daf1d4af --- /dev/null +++ b/widget/embedded/CHANGELOG.md @@ -0,0 +1,577 @@ +# [0.37.0](https://github.com/rango-exchange/rango-client/compare/widget-embedded@0.36.0...widget-embedded@0.37.0) (2024-12-30) + + + +# [0.36.0](https://github.com/rango-exchange/rango-client/compare/widget-embedded@0.35.0...widget-embedded@0.36.0) (2024-11-27) + + +### Bug Fixes + +* fix error display for bad requests ([82c0381](https://github.com/rango-exchange/rango-client/commit/82c03811b64a9197680314ac4f506d8680afec0c)) +* improve ton signer and mytonwallet provider ([7027755](https://github.com/rango-exchange/rango-client/commit/7027755740426359f42b088b842dfd01590df5c3)) + + +### Features + +* add routing params to widget config ([2a89744](https://github.com/rango-exchange/rango-client/commit/2a8974440d1269d9a12700fc7100f1f78371d277)) +* add ton connect provider ([2a2dbb7](https://github.com/rango-exchange/rango-client/commit/2a2dbb79022263f19446ced49d298e04d63f927f)) +* display same source and destination token warning on widget ([979cb0d](https://github.com/rango-exchange/rango-client/commit/979cb0d20c0730be9c94c2cd96d66630ea8e86ba)) + + + +# [0.35.0](https://github.com/rango-exchange/rango-client/compare/widget-embedded@0.34.5...widget-embedded@0.35.0) (2024-11-12) + + +### Features + +* add more languages to widget ([bc37fe9](https://github.com/rango-exchange/rango-client/commit/bc37fe97586545f993d7a2675a43b64aaa743791)) + + + +## [0.34.5](https://github.com/rango-exchange/rango-client/compare/widget-embedded@0.34.4...widget-embedded@0.34.5) (2024-11-06) + + + +## [0.34.4](https://github.com/rango-exchange/rango-client/compare/widget-embedded@0.34.3...widget-embedded@0.34.4) (2024-11-06) + + + +## [0.34.3](https://github.com/rango-exchange/rango-client/compare/widget-embedded@0.34.2...widget-embedded@0.34.3) (2024-11-06) + + + +## [0.34.2](https://github.com/rango-exchange/rango-client/compare/widget-embedded@0.34.1...widget-embedded@0.34.2) (2024-11-06) + + + +## [0.34.1](https://github.com/rango-exchange/rango-client/compare/widget-embedded@0.34.0...widget-embedded@0.34.1) (2024-10-30) + + + +# [0.34.0](https://github.com/rango-exchange/rango-client/compare/widget-embedded@0.33.3...widget-embedded@0.34.0) (2024-10-12) + + +### Bug Fixes + +* bump sdk and fix type issues ([d442208](https://github.com/rango-exchange/rango-client/commit/d4422083bf5dd27d5f509ce1db7f9560d05428c8)) + + +### Features + +* add id property to buttons ([39824e3](https://github.com/rango-exchange/rango-client/commit/39824e3ce8b1804b9944eb0faf71da7cdccf59ea)) + + + +## [0.33.3](https://github.com/rango-exchange/rango-client/compare/widget-embedded@0.33.2...widget-embedded@0.33.3) (2024-10-05) + + + +## [0.33.2](https://github.com/rango-exchange/rango-client/compare/widget-embedded@0.33.1...widget-embedded@0.33.2) (2024-09-25) + + + +## [0.33.1](https://github.com/rango-exchange/rango-client/compare/widget-embedded@0.33.0...widget-embedded@0.33.1) (2024-09-16) + + + +# [0.33.0](https://github.com/rango-exchange/rango-client/compare/widget-embedded@0.32.1...widget-embedded@0.33.0) (2024-09-10) + + +### Bug Fixes + +* add slippage icon to setting page ([2e29351](https://github.com/rango-exchange/rango-client/commit/2e29351d957f4e751a25f66b7cb173e5d9956378)) +* clear timeout for success modal to avoid closing upcoming modals unexpectedly ([0d54a60](https://github.com/rango-exchange/rango-client/commit/0d54a6092e6a412b1497b9a3e26af6f669eea181)) +* correct translation bugs ([0107f1d](https://github.com/rango-exchange/rango-client/commit/0107f1df7a587d9910c5376c4f99acd23b95e1a4)) +* fix wallet state issue after retrying to fetch the balance following a failed attempt ([181bac3](https://github.com/rango-exchange/rango-client/commit/181bac3f54727847f8d16ff47164cce80aa64931)) +* if state is on connecting, we should call disconnect in terminateconnectingWallets as well ([ad16056](https://github.com/rango-exchange/rango-client/commit/ad1605631df82e4d692f7e75999b2a5c51216958)) +* improve header component to center the title properly ([a9929bb](https://github.com/rango-exchange/rango-client/commit/a9929bb518ccbb2033b646fbcb5c034852b039b2)) +* reset derivation path if it's string and switching from custom mode ([c94c71a](https://github.com/rango-exchange/rango-client/commit/c94c71a94f3ac910ca13433ea616ce548559dc58)) + + +### Features + +* export a new hook for handling required data for connect called useStateful ([0d00a45](https://github.com/rango-exchange/rango-client/commit/0d00a45b4434e0e2b53228a1d1c0be4fa579e21b)) +* export StatefulConnect components and helpers ([c28a94b](https://github.com/rango-exchange/rango-client/commit/c28a94bd2721b4dbd16f9471f1cb0ddc45aa8904)) + + + +## [0.32.1](https://github.com/rango-exchange/rango-client/compare/widget-embedded@0.32.0...widget-embedded@0.32.1) (2024-08-17) + + + +# [0.32.0](https://github.com/rango-exchange/rango-client/compare/widget-embedded@0.31.0...widget-embedded@0.32.0) (2024-08-17) + + +### Features + +* add functionality to support custom tokens ([a1aa0af](https://github.com/rango-exchange/rango-client/commit/a1aa0afed98f164488a3caffaaff2fd060ab8b3d)) + + + +# [0.31.0](https://github.com/rango-exchange/rango-client/compare/widget-embedded@0.30.1...widget-embedded@0.31.0) (2024-08-11) + + +### Bug Fixes + +* address the issue where the token list does not update when the balance changes ([d1fb4e4](https://github.com/rango-exchange/rango-client/commit/d1fb4e4bb57e97cd730cba4c33ca0b2202600c09)) +* fix bug in swap input handling empty value ([3c9b082](https://github.com/rango-exchange/rango-client/commit/3c9b082b7b548ddd3981fff100d4dc880581b98d)) +* fix flicker in playground ([6ae2d58](https://github.com/rango-exchange/rango-client/commit/6ae2d588ba36822856a43cea7cabc3618cf72c11)) +* fix missing usd value in estimated output ([a46d19a](https://github.com/rango-exchange/rango-client/commit/a46d19a80b4f6fc1ca29e289e1b6441e89aa730c)) +* fix sort logic of notifications ([ffcf4c2](https://github.com/rango-exchange/rango-client/commit/ffcf4c2d70da7887e17042f3e6fe46224cd21fe1)) +* fix wallet modal closing bug ([146f7e2](https://github.com/rango-exchange/rango-client/commit/146f7e24450be278aee53b03319399934cf84f17)) +* recalculate supported tokens even if it's empty list ([8ccda6b](https://github.com/rango-exchange/rango-client/commit/8ccda6b2e246425102e6f6ab5f0d1edd131c6794)) + + +### Features + +* add derivation path modal for trezor wallet ([364422f](https://github.com/rango-exchange/rango-client/commit/364422f099b202a27a529591c5e3628bbb35508d)) +* add filter and clear to widget history ([d43b603](https://github.com/rango-exchange/rango-client/commit/d43b603462feabf297d5be389fcaa35402d667b5)) +* add functionality to update the quote inputs from outside the widget ([d9722fb](https://github.com/rango-exchange/rango-client/commit/d9722fbd5629ecb760b94a3d4a9ad7c0a07687ad)) +* add preventable event and a new ui event called CLICK_CONNECT_WALLET ([e4363bb](https://github.com/rango-exchange/rango-client/commit/e4363bb6fb98d49b22c1b608ecf6d37650ff3035)) +* add the option to define a default custom destination for each blockchain in the widget config ([7982ab6](https://github.com/rango-exchange/rango-client/commit/7982ab633dcb5b07ee5c313c9414d68baa6cbc38)) +* changing the request ID copy process ([490cdfa](https://github.com/rango-exchange/rango-client/commit/490cdfa41131eea20d8a552f8f0714b77d21ac71)) +* hide balance and max button when no wallet connected ([80b2754](https://github.com/rango-exchange/rango-client/commit/80b27547376394a3070aea7065d4bb9652f454e4)) + + +### Performance Improvements + +* improve token list performance by caching target tokens on load and config change ([3cc55ff](https://github.com/rango-exchange/rango-client/commit/3cc55ff95dde1f87f53efb2496e995beeb943b00)) + + + +## [0.30.1](https://github.com/rango-exchange/rango-client/compare/widget-embedded@0.30.0...widget-embedded@0.30.1) (2024-07-14) + + + +# [0.30.0](https://github.com/rango-exchange/rango-client/compare/widget-embedded@0.28.2...widget-embedded@0.30.0) (2024-07-09) + + +### Bug Fixes + +* fix playground exported config bugs and slider color bug ([9505b63](https://github.com/rango-exchange/rango-client/commit/9505b6330363839aa5acc7abfdb6cd7288f946d6)) +* bug in updating input & output amount ([49c902b](https://github.com/rango-exchange/rango-client/commit/49c902be7adc1ba9ae7808f145ec975c724a728f)) +* exclud ledger on mobile and fix injected wallet bug ([a6d90aa](https://github.com/rango-exchange/rango-client/commit/a6d90aa01b7b1fcea01ab46d1a74583ff6f98ff8)) +* fix bug displaying the same token list for blockchains with the same number of tokens ([f4dc82f](https://github.com/rango-exchange/rango-client/commit/f4dc82f5f319f9133fac7d8a68023596a773cd96)) +* fix init config minor bug ([7d671e3](https://github.com/rango-exchange/rango-client/commit/7d671e336050cd4d4cc0589cfd83e341421fe859)) +* fix state of custom destination in playground ([ae9cd78](https://github.com/rango-exchange/rango-client/commit/ae9cd783aebc797ffa98e2cd0fb87744ae92caf8)) +* fix the automatic selection of the connected wallets in the confirm wallets modal ([0b85d81](https://github.com/rango-exchange/rango-client/commit/0b85d81bc9ce6ec055e832e37eb6289a1b107d39)) +* improve generate colors for tokens label and price impact color ([5f2893c](https://github.com/rango-exchange/rango-client/commit/5f2893c03b17af24a8b3886e12b1631b5cc208fb)) +* rerfactor numeric tooltip and fix missing translations ([59f1fb9](https://github.com/rango-exchange/rango-client/commit/59f1fb96027a9b51cea5f6362b247b6cf180d809)) +* resolve custom slippage bug ([54bef0f](https://github.com/rango-exchange/rango-client/commit/54bef0f6d73d1078ab170e8b049a6aa311fff02d)) +* sync notifications with persisted swaps ([2ecaf38](https://github.com/rango-exchange/rango-client/commit/2ecaf38750dacc828ebaee7f8348b502a7645a88)) +* update design for not-selected blockchain or token ([8915101](https://github.com/rango-exchange/rango-client/commit/8915101d4e7a7092fbb5f38bbd95789e124f8ae3)) + + +### Features + +* add a modal for setting custom derivation path for ledger ([5b74ec0](https://github.com/rango-exchange/rango-client/commit/5b74ec049393ed74e3e7547edc72b68bd70b7dce)) +* add an option to wallet connect provider to open a desktop wallet directly ([bee0a1f](https://github.com/rango-exchange/rango-client/commit/bee0a1f57ef5470564f6cdc379d00981e7d34b0a)) +* add custom solana rpc url to config ([8d46ebf](https://github.com/rango-exchange/rango-client/commit/8d46ebf4fcd58c7ecd180ea29c071176c0f863e9)) +* add more predefined fonts list from google fonts ([693f257](https://github.com/rango-exchange/rango-client/commit/693f25790497f6829dd74c800d3d5574d8ee0bed)) +* add support for Trezor hardware wallet ([6edecbb](https://github.com/rango-exchange/rango-client/commit/6edecbb14fd008fc741c892bfa3e025c10160b9b)) +* adding 'shadows' to widget config for theme ([2be1f1a](https://github.com/rango-exchange/rango-client/commit/2be1f1aa508fb642a797610471b63219cd3d2ccf)) +* display all notifications in the notification popover ([c3eda22](https://github.com/rango-exchange/rango-client/commit/c3eda22cf1f06b928fdf0c98512fd444cc46823c)) +* export useWalletList for use in dapp ([e5fb662](https://github.com/rango-exchange/rango-client/commit/e5fb662adc119fb341db2c6c68b3b9e45c0353a2)) +* generate theme color tints and shades using the new method of overriding them separately ([a46b8a9](https://github.com/rango-exchange/rango-client/commit/a46b8a93bff1d8d6766c2fd636091983a8ee1baa)) +* make update settings optional to make it enable in playground ([c13a902](https://github.com/rango-exchange/rango-client/commit/c13a902fba9a03b111bde6fed02a1f3a081ee590)) +* support new widget events ([37a9b6c](https://github.com/rango-exchange/rango-client/commit/37a9b6c023cba660c87af27bcbfceadfb8daa8d0)) +* update explorer icon and add paste to custom destination ([61468a0](https://github.com/rango-exchange/rango-client/commit/61468a0e227517b91def21a85a8f7d72b7411862)) +* update wallets page to add filter by transaction types (category) ([0aa7c73](https://github.com/rango-exchange/rango-client/commit/0aa7c73333bd32912f7b2e90a660f3f43e64f4f7)) + + +### Performance Improvements + +* improve finding tokens from store ([3e890bd](https://github.com/rango-exchange/rango-client/commit/3e890bdcd47971b072f347c368c4370225cb11ff)) + + + +# [0.29.0](https://github.com/rango-exchange/rango-client/compare/widget-embedded@0.28.2...widget-embedded@0.29.0) (2024-06-01) + + +### Bug Fixes + +* exclud ledger on mobile and fix injected wallet bug ([a6d90aa](https://github.com/rango-exchange/rango-client/commit/a6d90aa01b7b1fcea01ab46d1a74583ff6f98ff8)) +* fix init config minor bug ([7d671e3](https://github.com/rango-exchange/rango-client/commit/7d671e336050cd4d4cc0589cfd83e341421fe859)) +* fix the automatic selection of the connected wallets in the confirm wallets modal ([0b85d81](https://github.com/rango-exchange/rango-client/commit/0b85d81bc9ce6ec055e832e37eb6289a1b107d39)) +* resolve custom slippage bug ([54bef0f](https://github.com/rango-exchange/rango-client/commit/54bef0f6d73d1078ab170e8b049a6aa311fff02d)) +* sync notifications with persisted swaps ([2ecaf38](https://github.com/rango-exchange/rango-client/commit/2ecaf38750dacc828ebaee7f8348b502a7645a88)) +* update design for not-selected blockchain or token ([8915101](https://github.com/rango-exchange/rango-client/commit/8915101d4e7a7092fbb5f38bbd95789e124f8ae3)) + + +### Features + +* add an option to wallet connect provider to open a desktop wallet directly ([bee0a1f](https://github.com/rango-exchange/rango-client/commit/bee0a1f57ef5470564f6cdc379d00981e7d34b0a)) +* add custom solana rpc url to config ([8d46ebf](https://github.com/rango-exchange/rango-client/commit/8d46ebf4fcd58c7ecd180ea29c071176c0f863e9)) +* add more predefined fonts list from google fonts ([693f257](https://github.com/rango-exchange/rango-client/commit/693f25790497f6829dd74c800d3d5574d8ee0bed)) +* generate theme color tints and shades using the new method of overriding them separately ([a46b8a9](https://github.com/rango-exchange/rango-client/commit/a46b8a93bff1d8d6766c2fd636091983a8ee1baa)) +* update explorer icon and add paste to custom destination ([61468a0](https://github.com/rango-exchange/rango-client/commit/61468a0e227517b91def21a85a8f7d72b7411862)) +* update wallets page to add filter by transaction types (category) ([0aa7c73](https://github.com/rango-exchange/rango-client/commit/0aa7c73333bd32912f7b2e90a660f3f43e64f4f7)) + + + +## [0.28.2](https://github.com/rango-exchange/rango-client/compare/widget-embedded@0.28.1...widget-embedded@0.28.2) (2024-05-26) + + + +## [0.28.1](https://github.com/rango-exchange/rango-client/compare/widget-embedded@0.28.0...widget-embedded@0.28.1) (2024-05-25) + + + +# [0.28.0](https://github.com/rango-exchange/rango-client/compare/widget-embedded@0.27.3...widget-embedded@0.28.0) (2024-05-14) + + +### Bug Fixes + +* display the swapper's title instead of the swapper's group as their displayed name ([1142d94](https://github.com/rango-exchange/rango-client/commit/1142d9417e690bf4b0093ee84e42352dab149793)) +* fix bugs in fetching quotes ([2b533ea](https://github.com/rango-exchange/rango-client/commit/2b533ead6fa90d2d8b3d9b8de2699072cc57d55b)) +* fix multiwallets config initial value check bug ([94dbf07](https://github.com/rango-exchange/rango-client/commit/94dbf074ab51f56bf1267cb668be4e58781554bf)) +* fix space between of routes and swap box in expanded mode ([cbca33e](https://github.com/rango-exchange/rango-client/commit/cbca33ef31d634466b6595ee01fa337952076b89)) +* fix the entrance animation of the confirm wallets modal ([1907ad2](https://github.com/rango-exchange/rango-client/commit/1907ad25cef2a25c303e2c91194dbae2b8e6fd56)) + + +### Features + +* add auto retry for fetching confirm swap ([5945d82](https://github.com/rango-exchange/rango-client/commit/5945d82030b89006f5c62c8f5ce5d492cc2ed220)) +* add solana to ledger ([77b6695](https://github.com/rango-exchange/rango-client/commit/77b6695758165f9258a0ba5bd3b2cf39b0b2aab5)) +* add test to check workflow ([69a4c3e](https://github.com/rango-exchange/rango-client/commit/69a4c3e144a7e9cd1ce24c3a2f7a3d7a4b4a1eab)) +* detect proper error related to wallet connect params ([a0d8d95](https://github.com/rango-exchange/rango-client/commit/a0d8d95ed977fffbd0244f498c81f7ce3550ee71)) +* improve all routes button ([efcb61e](https://github.com/rango-exchange/rango-client/commit/efcb61ee5920b1a05c44dfa8edf23dc8d3d7f035)) + + + +## [0.27.3](https://github.com/rango-exchange/rango-client/compare/widget-embedded@0.27.2...widget-embedded@0.27.3) (2024-05-08) + + +### Bug Fixes + +* disable the confirm wallet button if all required wallets are not selected ([521883f](https://github.com/rango-exchange/rango-client/commit/521883f9e381d311bf0cdad275b234646da2a648)) + + + +## [0.27.2](https://github.com/rango-exchange/rango-client/compare/widget-embedded@0.27.1...widget-embedded@0.27.2) (2024-04-27) + + +### Bug Fixes + +* make sure to correctly pass validation parameters when setting up a new swap ([4f6d37e](https://github.com/rango-exchange/rango-client/commit/4f6d37ea9b59caca4d0064c1b33b05077b0b59a3)) + + + +## [0.27.1](https://github.com/rango-exchange/rango-client/compare/widget-embedded@0.27.0...widget-embedded@0.27.1) (2024-04-24) + + + +# [0.27.0](https://github.com/rango-exchange/rango-client/compare/widget-embedded@0.26.0...widget-embedded@0.27.0) (2024-04-24) + + + +# [0.26.0](https://github.com/rango-exchange/rango-client/compare/widget-embedded@0.25.0...widget-embedded@0.26.0) (2024-04-23) + + +### Bug Fixes + +* address passing wallet-connect project id ([80a6b80](https://github.com/rango-exchange/rango-client/commit/80a6b8046cc93bc8e88b84a201331b2e7adc0c73)) +* fix token selector hover ui for token explorer link ([ede0fac](https://github.com/rango-exchange/rango-client/commit/ede0fac0e987b0cd6983ccd427207d78f65eeb96)) +* fix token selector infinite loader ([1122dd6](https://github.com/rango-exchange/rango-client/commit/1122dd6db1fecadd41d56f22d5dfd95fbaa645a0)) +* remove setting option from confirm swap page ([1f204c1](https://github.com/rango-exchange/rango-client/commit/1f204c1ebf544348a2969aa35c2cf8c9841ea3ff)) + + +### Features + +* add animation for switch swap button ([601af2d](https://github.com/rango-exchange/rango-client/commit/601af2dde7ed87c7aa803cb0b79a13c21ff0386d)) +* add unit test for app store ([9df49a8](https://github.com/rango-exchange/rango-client/commit/9df49a8aaf0d03fea01d9e9790953c7326e8999d)) + + + +# [0.25.0](https://github.com/rango-exchange/rango-client/compare/widget-embedded@0.24.1...widget-embedded@0.25.0) (2024-04-09) + + +### Bug Fixes + +* address tooltips position ([5ee60d1](https://github.com/rango-exchange/rango-client/commit/5ee60d1622dab29091d97578d417a2187f2ca6cf)) +* correct showing wallets on mobile screens ([89ead7f](https://github.com/rango-exchange/rango-client/commit/89ead7f68e88352dfd69c2a3d1c6cb0b8cf2e5d5)) +* fix export refresh modal ([0c0ec6c](https://github.com/rango-exchange/rango-client/commit/0c0ec6c7f22116a9b5d5c8d2b6a74ebf421fc015)) +* fix widget event hook ([c8547b6](https://github.com/rango-exchange/rango-client/commit/c8547b6a31354afe13aa32c0b72be5b62b3f0d67)) + + +### Features + +* attach config object to window for debugging purposes ([70597b7](https://github.com/rango-exchange/rango-client/commit/70597b78e31ef2da1ef2d20ed398e5bdf0b59a63)) +* implement hover state for full-expanded-route ([1c851d7](https://github.com/rango-exchange/rango-client/commit/1c851d7c62b71fe8f4aa6c05edbc0d6cc78d5437)) +* show a modal with page reload when meta hasn't loaded ([0d3842f](https://github.com/rango-exchange/rango-client/commit/0d3842f9c2d7210cfd5a967d1f0e663ef3125421)) + + + +## [0.24.1](https://github.com/rango-exchange/rango-client/compare/widget-embedded@0.24.0...widget-embedded@0.24.1) (2024-03-12) + + + +# [0.24.0](https://github.com/rango-exchange/rango-client/compare/widget-embedded@0.23.0...widget-embedded@0.24.0) (2024-03-12) + + +### Bug Fixes + +* add a default variant to widget config store ([5f7c18e](https://github.com/rango-exchange/rango-client/commit/5f7c18e54d88ca44eb86de6fff6c252599d3adb9)) +* apply minor improvements to the widget ([c4454e5](https://github.com/rango-exchange/rango-client/commit/c4454e5c3dd1257b48d18a975cb3d1ac19ce3f26)) +* close completeModal when requestId is changed ([f00bee8](https://github.com/rango-exchange/rango-client/commit/f00bee8f9852f66157517c9a4d0bebf38b9a961d)) +* correct default values of hidden features ([10ac5cf](https://github.com/rango-exchange/rango-client/commit/10ac5cf6db419567cc439db785615b00565461d7)) +* correct height of widget & address full-expanded hover & spacing ([6390316](https://github.com/rango-exchange/rango-client/commit/639031622644ee99d3e708f1a783c16e7268fa20)) +* correct set-as-read behavior in swap-details ([b0b5310](https://github.com/rango-exchange/rango-client/commit/b0b53103aef10083c2887f61bf68356eb26698e6)) +* correct sharp styles in swap inputs in different variants ([8fd3232](https://github.com/rango-exchange/rango-client/commit/8fd3232f9353537da2dfdefd201d7f15b17b2434)) +* default theme shouldn't be override on what user has set ([6e64239](https://github.com/rango-exchange/rango-client/commit/6e64239873bd673279bd163f5b54e49744b8abc2)) +* fix bugs in displaying quote error modals ([c72a21e](https://github.com/rango-exchange/rango-client/commit/c72a21e233e48b20a9af0cf44d334fb752b1988b)) +* fix console warning in widget ([d2353f2](https://github.com/rango-exchange/rango-client/commit/d2353f21945d38cfef4051d80b9577b7ab4da620)) +* fix default injected wallet display logic and catch unhandled errors ([6654fcc](https://github.com/rango-exchange/rango-client/commit/6654fcc73481ac8e572da92be4346e059613febe)) +* fix full expanded design issues ([d1aaaa3](https://github.com/rango-exchange/rango-client/commit/d1aaaa30404da6ef8c1ff264a52e718db74f438f)) +* fix queue manager context in widget embedded ([312fe8c](https://github.com/rango-exchange/rango-client/commit/312fe8cfef6b5adb245c81f303694142cb99641b)) +* fix unmounting router on changing language ([80e96dd](https://github.com/rango-exchange/rango-client/commit/80e96ddabd863a65f5e94d6631aecd23f9d12126)) +* fix widget icon size issue and add connected wallet tooltip ([476267f](https://github.com/rango-exchange/rango-client/commit/476267feea9e176829a6df4bf0dbe6eef5ad4366)) +* get theme from config when singleTheme is true ([8fa3caa](https://github.com/rango-exchange/rango-client/commit/8fa3caa2cf2965923c6427187283ecf53737c792)) +* improve search token ([2f7bacc](https://github.com/rango-exchange/rango-client/commit/2f7bacc5358d4fc6da21c0883e46d49293f98a33)) +* remove redundant punctuation from settings page ([51f3825](https://github.com/rango-exchange/rango-client/commit/51f3825fb4a1073de5baef7b9fa988990e2a7d36)) + + +### Features + +* add an expand mode for our compact widget ([eb90daa](https://github.com/rango-exchange/rango-client/commit/eb90daa540592c81efdca6e33032f6dbef371180)) +* add enabling centralized swappers to config ([55f6f7d](https://github.com/rango-exchange/rango-client/commit/55f6f7d746aeab4dc65421c641c920c8687712d3)) +* add full expanded variant to widget ([a3907a0](https://github.com/rango-exchange/rango-client/commit/a3907a0be9f0716c366a2c482253191eebd66301)) +* add more languages to widget ([04f7855](https://github.com/rango-exchange/rango-client/commit/04f78551784b52e286f7f6206337d97bf8401063)) +* add sort filter for multi routing (compact mode) ([d90ddc6](https://github.com/rango-exchange/rango-client/commit/d90ddc6959c63a1ec2ef5908c09fc6ab8c3da23c)) +* implement expanded-mode route ([e75fcad](https://github.com/rango-exchange/rango-client/commit/e75fcad751dfdce0c4d84d08f2c9b41935584a75)) +* improve header buttons and notifications ([5f2188d](https://github.com/rango-exchange/rango-client/commit/5f2188d5cae62576bf13a5cefdc83625b9910c11)) +* improve playground mobile view and widget variants and liquidity sources ([3c2a4a6](https://github.com/rango-exchange/rango-client/commit/3c2a4a6375818d01a4c6682e03a60aa6972a8a02)) +* redesign switching theme in settings ([7fe0bc5](https://github.com/rango-exchange/rango-client/commit/7fe0bc510a56b717bed1bb20d7889d549c7144a1)) +* update active tab warning position ([9420667](https://github.com/rango-exchange/rango-client/commit/9420667d36ac508245fdf05901c1cb3074a3508b)) +* update colours for quote variant for rango/default theme ([897683f](https://github.com/rango-exchange/rango-client/commit/897683f5aa550af9a74e011e4ab3d734d7c595f7)) + + + +# [0.23.0](https://github.com/rango-exchange/rango-client/compare/widget-embedded@0.22.3...widget-embedded@0.23.0) (2024-02-20) + + +### Bug Fixes + +* fix some swap messages in widget-embedded ([f859190](https://github.com/rango-exchange/rango-client/commit/f85919050b0c8f3bb0f91d4f3b87a58cca29601b)) +* fix widget ui minor bugs ([b881755](https://github.com/rango-exchange/rango-client/commit/b881755d59af22b41d8314f9925ecc4de04169db)) +* reset connecting state on close wallet modal ([5d2fa8d](https://github.com/rango-exchange/rango-client/commit/5d2fa8dfffa9542824f6c2a4543c7dea48f5a6ae)) + + +### Features + +* add portuguese language to widget ([a7d40e2](https://github.com/rango-exchange/rango-client/commit/a7d40e2604eede900901865fc5ff1707819929a6)) +* change modal & toast interface ([009612e](https://github.com/rango-exchange/rango-client/commit/009612e09c2f269872b1e639fbcf7df8cce76f74)) +* implement multi routing in widget ([5003446](https://github.com/rango-exchange/rango-client/commit/50034463d25c552584201d0bd0d6a970fdda1d78)) +* passing enabled swappers/bridges to widget through the url for campaigns ([06a42a3](https://github.com/rango-exchange/rango-client/commit/06a42a3b1e3986a2735189d2e9f2d6b3725edd64)) + + + +## [0.22.3](https://github.com/rango-exchange/rango-client/compare/widget-embedded@0.22.2...widget-embedded@0.22.3) (2024-02-08) + + +### Bug Fixes + +* add ethers dependency to embedded ([5bce05d](https://github.com/rango-exchange/rango-client/commit/5bce05df42c96efa9bdffb09985d5de34cbe647e)) + + + +## [0.22.2](https://github.com/rango-exchange/rango-client/compare/widget-embedded@0.22.1...widget-embedded@0.22.2) (2024-02-07) + + + +## [0.22.1](https://github.com/rango-exchange/rango-client/compare/widget-embedded@0.22.0...widget-embedded@0.22.1) (2024-02-06) + + +### Bug Fixes + +* fix tab manager error in Next.js ([ce312b8](https://github.com/rango-exchange/rango-client/commit/ce312b833ef92cf30fe8bd52b2d415a2d73ceb8b)) + + + +# [0.22.0](https://github.com/rango-exchange/rango-client/compare/widget-embedded@0.21.0...widget-embedded@0.22.0) (2024-02-05) + + +### Bug Fixes + +* fix a bug in searching history items and add a skeleton for history list labels ([458a316](https://github.com/rango-exchange/rango-client/commit/458a316b4097cc3586be08b9a1e049b50f29648b)) +* remove auto scroll behavior from collapsible components ([5a4db2a](https://github.com/rango-exchange/rango-client/commit/5a4db2adf9dbf2fbb005933f293d5faedc25fc15)) +* reset wallet state that remains in the connecting ([dbf8bb9](https://github.com/rango-exchange/rango-client/commit/dbf8bb949c1ac308af338de1b8a672928bf98963)) +* widget ui bugs ([7d97336](https://github.com/rango-exchange/rango-client/commit/7d97336f2bc78a0c2f466124eccfe87772e760ad)) + + +### Features + +* add dynamicHeight to iframe ([08d68b6](https://github.com/rango-exchange/rango-client/commit/08d68b64bb6a3aeb24a9abe83f3dd972d9a09969)) +* add right anchor prop to modal component ([f3f2dac](https://github.com/rango-exchange/rango-client/commit/f3f2dacc1c96173dbf5455cf631aae4207c6a27b)) +* Adding title to config and export IDs for accessing blockchain image and swap input ([c3cdd97](https://github.com/rango-exchange/rango-client/commit/c3cdd979068a44a8d45ced7066a7e514a898325d)) +* feature management from server ([2075ac8](https://github.com/rango-exchange/rango-client/commit/2075ac8514e98df6ac3514fe541eb047ba2e196a)) + + +### Reverts + +* reset wallet state that remains in the connecting ([d48544d](https://github.com/rango-exchange/rango-client/commit/d48544d2a6a12916ccf879c1d8e50b313d75be1b)) + + + +# [0.21.0](https://github.com/rango-exchange/rango-client/compare/widget-embedded@0.20.0...widget-embedded@0.21.0) (2024-01-22) + + +### Bug Fixes + +* address apikey config bug in iframe ([9078657](https://github.com/rango-exchange/rango-client/commit/90786576ffc347f6d3f340b34782d0ed721850a6)) +* address some minor bugs in swapHistory & wallet page loading ([1d4488e](https://github.com/rango-exchange/rango-client/commit/1d4488eee5926c2368bb9ba281ebf9fbc5c433e5)) +* cleanup wallets' subscriber when setProvider get null ([88d6a42](https://github.com/rango-exchange/rango-client/commit/88d6a423c49b34b3d9ff567e22df36c3b009bb76)) +* complete and check missing translations ([c661b81](https://github.com/rango-exchange/rango-client/commit/c661b81301f87193578b8a08ce3cbf65dc060487)) +* fix swap detail styles issue ([e74bb0c](https://github.com/rango-exchange/rango-client/commit/e74bb0cbbdd714f07a3128e1487200eeff25d8ba)) +* fix widget-iframe styles ([403009e](https://github.com/rango-exchange/rango-client/commit/403009ed0946d8a185af53f5004dc6160a5f23f8)) +* persist language in store ([0a33b0f](https://github.com/rango-exchange/rango-client/commit/0a33b0ffe596b704e16328277737595b79a72f89)) +* reset the quote when the source token matches the destination token ([938d30a](https://github.com/rango-exchange/rango-client/commit/938d30a9e93c00e7b9e21afa16683368ea612043)) +* resolve issues for prices and dates, and add tooltips for prices ([7515215](https://github.com/rango-exchange/rango-client/commit/751521513aab2c108cecb150b81e0f921d1b603a)) +* styling issues on layout ([7f0e1bd](https://github.com/rango-exchange/rango-client/commit/7f0e1bd883045d6f0a398eeb353cf5280ac09455)) + + +### Features + +* add default injected wallet ([238977c](https://github.com/rango-exchange/rango-client/commit/238977c0e3cd09feba9f2557f1b099b9af3afb0d)) +* adding a modal for fee on quote component ([d314516](https://github.com/rango-exchange/rango-client/commit/d314516b0af26ca71abf071462f19c9efef407e7)) +* export notifications from useWidget ([fc50baf](https://github.com/rango-exchange/rango-client/commit/fc50baf1b4043755162a54bcdd07f10fab94da39)) +* for long routes, we should show a shorter version and hide the rest in a button. ([378b3e4](https://github.com/rango-exchange/rango-client/commit/378b3e4508c8d9a32c0b7ba0b4c5f2a5ba32e193)) +* handle active tab in widget-embedded ([427a3bb](https://github.com/rango-exchange/rango-client/commit/427a3bb42dcaf899c4241aa5bd60c15a3475882a)) +* implement auto-refresh for routes ([9dfe80c](https://github.com/rango-exchange/rango-client/commit/9dfe80c00d01078bfd3f693c6a98ceb4038e58fb)) +* update filter tokens interface in widget ([455d70b](https://github.com/rango-exchange/rango-client/commit/455d70b95ca0c03eb3a738451f760ba4e4d6a04e)) + + + +# [0.20.0](https://github.com/rango-exchange/rango-client/compare/widget-embedded@0.19.0...widget-embedded@0.20.0) (2023-12-24) + + +### Bug Fixes + +* add initial state with props in app store and fix bug of passing liquidity sources via config ([5d50d0f](https://github.com/rango-exchange/rango-client/commit/5d50d0fa18c0519a9464bb205684ecdaf881d936)) +* comments ([79e5c8a](https://github.com/rango-exchange/rango-client/commit/79e5c8a5e204f0a3c006e0aa6174ed440c424dcd)) +* fix emitting failed event in swap execution ([cedc535](https://github.com/rango-exchange/rango-client/commit/cedc53523dc8ddc5f339b4da6afa822058bd760d)) +* fix HMR for widget and playground ([8524820](https://github.com/rango-exchange/rango-client/commit/8524820f10cf0b8921f3db0c4f620ff98daa4103)) +* fix performance issues on token selector ([ea0b1be](https://github.com/rango-exchange/rango-client/commit/ea0b1be71c90befc0b8ad2f19e56122b145227d6)) +* fix quote info bugs ([3668d84](https://github.com/rango-exchange/rango-client/commit/3668d84a43e3d6055b8ff133f546aabce6fcf616)) +* fix wallet button state in swap details page ([ad57603](https://github.com/rango-exchange/rango-client/commit/ad57603885968b2792ed382dc80a3862dc0eebde)) +* handle safe wallet in widget ([52fcca4](https://github.com/rango-exchange/rango-client/commit/52fcca49315f7e2edb4655ae7b9cd0792c2800d7)) +* improve widget for smaller screens ([75a3107](https://github.com/rango-exchange/rango-client/commit/75a310770ece2969833dda2789bee5b8ccda166e)) +* quote summary width ([8728c05](https://github.com/rango-exchange/rango-client/commit/8728c0543f916763cc7a868bce3af835c4ddf572)) +* update blockchain category icons ([5ffd1ac](https://github.com/rango-exchange/rango-client/commit/5ffd1ac9bbe4cee26500c010718f4f530b1349f6)) +* update classNames to new pattern for conflict prevention ([3c89278](https://github.com/rango-exchange/rango-client/commit/3c8927893381774f8bc8dc5b049ffdfccea1ffe4)) +* **widget:** Showing history for selected blockchain if a blockchain selected from main list ([7b77dec](https://github.com/rango-exchange/rango-client/commit/7b77dec2c0417948bbdd4844006ce2d4ea811811)) +* zustand store in context ([a31c34d](https://github.com/rango-exchange/rango-client/commit/a31c34d379173ab2b4a14beb4fddd7ac0402b236)) + + +### Features + +* add dark/light theme to playground ([01c4c45](https://github.com/rango-exchange/rango-client/commit/01c4c45cf42a5b9a945e687fbaf3cb141ca19d13)) +* add langugage section to Playground ([c2deaec](https://github.com/rango-exchange/rango-client/commit/c2deaec91813f7e5cc4bccc2be78f5c297cc1a2d)) +* add state of wallets' details to useWidget ([2a59055](https://github.com/rango-exchange/rango-client/commit/2a590551cc0a3d663fd9901e125890ff1386c0aa)) +* export meta and additional logics from useWidget ([5c8fbc5](https://github.com/rango-exchange/rango-client/commit/5c8fbc5f25979409895b4592b62416f6bd7b82b8)) +* handle wallet referrer in widget ([1073cd2](https://github.com/rango-exchange/rango-client/commit/1073cd2051f6819713a38f0c1e5c3f47ab0a7d53)) +* implement feature disabling in widget config ([c9b5705](https://github.com/rango-exchange/rango-client/commit/c9b5705077ad900c8cbb2b76f5642ca79f54fd86)) +* implement pin tokens in From and To ([c849db2](https://github.com/rango-exchange/rango-client/commit/c849db2083022587960a5d1a4dc64c5f696e07a5)) +* implement WidgetProvider & useWidget for accessing specific widget data ([65f1824](https://github.com/rango-exchange/rango-client/commit/65f1824720d5d7d07c3d42c14285a704bd1da364)) +* support experimental features ([4261610](https://github.com/rango-exchange/rango-client/commit/426161044adc583c3339a53ab58405b8f96dfee3)) + + + +# [0.11.0](https://github.com/rango-exchange/rango-client/compare/widget-embedded@0.10.0...widget-embedded@0.11.0) (2023-08-03) + + + +# [0.10.0](https://github.com/rango-exchange/rango-client/compare/widget-embedded@0.8.0...widget-embedded@0.10.0) (2023-08-01) + + +### Features + +* add project id as a external value ([0c80404](https://github.com/rango-exchange/rango-client/commit/0c80404a8cacb6c5b0338dea1e416b0b11db254b)) +* Get Wallet Connect project id from config ([9fb30b4](https://github.com/rango-exchange/rango-client/commit/9fb30b4b1a83e2005bbf42553298f24b1e278e1c)) + + + +# [0.9.0](https://github.com/rango-exchange/rango-client/compare/widget-embedded@0.8.0...widget-embedded@0.9.0) (2023-07-31) + + +### Features + +* add project id as a external value ([0c80404](https://github.com/rango-exchange/rango-client/commit/0c80404a8cacb6c5b0338dea1e416b0b11db254b)) +* Get Wallet Connect project id from config ([9fb30b4](https://github.com/rango-exchange/rango-client/commit/9fb30b4b1a83e2005bbf42553298f24b1e278e1c)) + + + +# [0.8.0](https://github.com/rango-exchange/rango-client/compare/widget-embedded@0.7.0...widget-embedded@0.8.0) (2023-07-11) + + +### Bug Fixes + +* adding lingui to ui and embedded packages ([efed0d6](https://github.com/rango-exchange/rango-client/commit/efed0d6da437bfd472f26a280adc55da1151966a)) +* fix lingui version ([b7de08b](https://github.com/rango-exchange/rango-client/commit/b7de08b457314192665b9d3afa809e63ecd311a8)) + + + +# [0.7.0](https://github.com/rango-exchange/rango-client/compare/widget-embedded@0.6.0...widget-embedded@0.7.0) (2023-07-11) + + + +# [0.6.0](https://github.com/rango-exchange/rango-client/compare/widget-embedded@0.5.0...widget-embedded@0.6.0) (2023-07-11) + + +### Bug Fixes + +* fix bug in routing when usd value is unknown ([df23685](https://github.com/rango-exchange/rango-client/commit/df23685d63de6dbe5a3e591ef619d845573e0657)) +* update widget affiliate config ([0655dc1](https://github.com/rango-exchange/rango-client/commit/0655dc1949e6e8a9b1efacb71e3f66ac3d1e30fb)) + + +### Features + +* add widget events and refactor swap execution events ([0d76806](https://github.com/rango-exchange/rango-client/commit/0d7680693dd77439de38cd0b20f263f6ae8cceb0)) +* consider internalswaps in second bestRoute & select wallets ([a2d9510](https://github.com/rango-exchange/rango-client/commit/a2d9510288b534e03d6cf2ee3ed60b895607323f)) +* setup lingui for multi-language in widget ([a3f1331](https://github.com/rango-exchange/rango-client/commit/a3f1331def487989a5717335b062dd9ef45876ad)) +* support for external wallets ([0db170d](https://github.com/rango-exchange/rango-client/commit/0db170d28b7052e5a750d270549d9550c52789de)) + + +### Reverts + +* Revert "support for rango-types cjs format" ([4f5f55f](https://github.com/rango-exchange/rango-client/commit/4f5f55f96e8daa329588b932b19c291c30f339c4)) + + + +# [0.5.0](https://github.com/rango-exchange/rango-client/compare/widget-embedded@0.4.0...widget-embedded@0.5.0) (2023-05-31) + + + +# [0.4.0](https://github.com/rango-exchange/rango-client/compare/widget-embedded@0.3.0...widget-embedded@0.4.0) (2023-05-31) + + + +# [0.3.0](https://github.com/rango-exchange/rango-client/compare/widget-embedded@0.2.0...widget-embedded@0.3.0) (2023-05-30) + + + +# [0.2.0](https://github.com/rango-exchange/rango-client/compare/widget-embedded@0.1.19...widget-embedded@0.2.0) (2023-05-30) + + +### Bug Fixes + +* fix bug of duplicate modals for wallet connect ([efb5482](https://github.com/rango-exchange/rango-client/commit/efb54827fd51e6c6c8f42c6abf33c3d7610755e8)) +* Some functions were transferred to helper ([7d5756f](https://github.com/rango-exchange/rango-client/commit/7d5756fc476728e84b16300102918542520983a7)) + + + +## [0.1.19](https://github.com/rango-exchange/rango-client/compare/widget-embedded@0.1.18...widget-embedded@0.1.19) (2023-05-15) + + + +## [0.1.16](https://github.com/rango-exchange/rango-client/compare/widget-embedded@0.1.15...widget-embedded@0.1.16) (2023-05-15) + + +### Bug Fixes + +* Fixed colorpicker ([d821340](https://github.com/rango-exchange/rango-client/commit/d821340fc3f5df07ccbfc3555ae4d7dba0cad49b)) +* some polishment on playground ([cf17f9e](https://github.com/rango-exchange/rango-client/commit/cf17f9e2ac2efc9467c4f550e09eaf19170bbbf0)) +* update rango-types and fix notification bugs ([993f185](https://github.com/rango-exchange/rango-client/commit/993f185e0b8c5e5e15a2c65ba2d85d1f9c8daa90)) + + + diff --git a/widget/embedded/global-env.d.ts b/widget/embedded/global-env.d.ts new file mode 100644 index 0000000000..bd2916415b --- /dev/null +++ b/widget/embedded/global-env.d.ts @@ -0,0 +1,12 @@ +import type { WidgetConfig } from './src'; + +export {}; + +declare global { + interface Window { + __rango: { + config: WidgetConfig; + dappConfig: WidgetConfig; + }; + } +} diff --git a/widget/embedded/package.json b/widget/embedded/package.json index 6c04d3c713..50673d4ed5 100644 --- a/widget/embedded/package.json +++ b/widget/embedded/package.json @@ -1,7 +1,9 @@ { "name": "@rango-dev/widget-embedded", - "version": "0.1.13-next.0", + "version": "0.36.1-next.16", "license": "MIT", + "type": "module", + "source": "./src/index.ts", "main": "dist/index.js", "typings": "dist/index.d.ts", "files": [ @@ -10,49 +12,46 @@ ], "browserslist": "> 0.5%, last 2 versions, not dead", "scripts": { - "watch-tsc": "tsc --watch --noEmit", - "dev": "parcel public/index.html -p 3001 --no-cache", - "dev-tsc": "npm-run-all --parallel watch-tsc dev", - "build:app": "parcel build --cache-dir=.parcel-cache", - "build": "tsdx build --entry ./src/lib.tsx" - }, - "husky": { - "hooks": { - "pre-commit": "tsdx lint" - } - }, - "prettier": { - "printWidth": 80, - "semi": true, - "singleQuote": true, - "trailingComma": "es5" + "build": "node ../../scripts/build/command.mjs --path widget/embedded", + "ts-check": "tsc --declaration --emitDeclarationOnly -p ./tsconfig.json", + "clean": "rimraf dist", + "format": "prettier --write '{.,src}/**/*.{ts,tsx}'", + "lint": "eslint \"**/*.{ts,tsx}\" --ignore-path ../../.eslintignore", + "test": "vitest", + "test:watch": "vitest --watch", + "test:coverage": "vitest run --coverage" }, "dependencies": { - "@rango-dev/provider-all": "^0.1.12", - "@rango-dev/queue-manager-core": "^0.1.12-next.0", - "@rango-dev/queue-manager-rango-preset": "^0.1.11", - "@rango-dev/queue-manager-react": "^0.1.11-next.0", - "@rango-dev/ui": "^0.1.12", - "@rango-dev/wallets-core": "^0.1.12", - "@rango-dev/wallets-shared": "^0.1.11", + "@lingui/core": "4.2.1", + "@lingui/react": "4.2.1", + "@rango-dev/logging-core": "^0.6.0", + "@rango-dev/provider-all": "^0.40.1-next.8", + "@rango-dev/queue-manager-core": "^0.27.0", + "@rango-dev/queue-manager-rango-preset": "^0.40.1-next.6", + "@rango-dev/queue-manager-react": "^0.27.0", + "@rango-dev/signer-solana": "^0.35.1-next.0", + "@rango-dev/ui": "^0.42.1-next.11", + "@rango-dev/wallets-core": "^0.40.1-next.8", + "@rango-dev/wallets-react": "^0.26.1-next.9", + "@rango-dev/wallets-shared": "^0.40.1-next.6", "bignumber.js": "^9.1.1", "copy-to-clipboard": "^3.3.3", "dayjs": "^1.11.7", - "i18next": "^22.4.11", - "i18next-browser-languagedetector": "^7.0.1", - "i18next-http-backend": "^2.1.1", + "ethers": "^6.13.2", "immer": "^9.0.19", "mitt": "^3.0.0", - "parcel": "^2.8.0", - "rango-sdk": "^0.1.23", - "rango-types": "^0.1.28", - "react": "^18.2.0", - "react-dom": "^18.2.0", + "rango-sdk": "^0.1.57", + "rango-types": "^0.1.74", "react-i18next": "^12.2.0", "react-router-dom": "^6.8.0", + "values.js": "2.1.1", "zustand": "^4.3.2" }, + "peerDependencies": { + "react": ">=16", + "react-dom": ">=16" + }, "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/widget/embedded/public/index.css b/widget/embedded/public/index.css deleted file mode 100644 index 0566d3b5f5..0000000000 --- a/widget/embedded/public/index.css +++ /dev/null @@ -1,15 +0,0 @@ -html { - box-sizing: border-box; -} - -*, -*::before, -*::after { - box-sizing: inherit; - list-style-type: none; -} - -body { - padding: 0; - margin: 0; -} diff --git a/widget/embedded/public/index.html b/widget/embedded/public/index.html deleted file mode 100644 index 4d70f97e5d..0000000000 --- a/widget/embedded/public/index.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - Rango Widget - - - -
- - - diff --git a/widget/embedded/readme.md b/widget/embedded/readme.md index 9cfdb1cc97..f5747d4175 100644 --- a/widget/embedded/readme.md +++ b/widget/embedded/readme.md @@ -1 +1,4 @@ # @rango-dev/widget-embedded + +Rango Embedded Widget + diff --git a/widget/embedded/src/App.tsx b/widget/embedded/src/App.tsx deleted file mode 100644 index 5ae807d4b5..0000000000 --- a/widget/embedded/src/App.tsx +++ /dev/null @@ -1,124 +0,0 @@ -import { SwapContainer } from '@rango-dev/ui'; -import React, { useEffect, useMemo, useState } from 'react'; -import { AppRouter } from './components/AppRouter'; -import { useMetaStore } from './store/meta'; -import './app.css'; -import { Events, Provider } from '@rango-dev/wallets-core'; -import { allProviders } from '@rango-dev/provider-all'; -import { EventHandler } from '@rango-dev/wallets-core/dist/wallet'; -import { Network, WalletType } from '@rango-dev/wallets-shared'; -import { - prepareAccountsForWalletStore, - walletAndSupportedChainsNames, -} from './utils/wallets'; -import { useWalletsStore } from './store/wallets'; -import { Layout } from './components/Layout'; -import { globalFont, globalStyles } from './globalStyles'; -import { useTheme } from './hooks/useTheme'; -import QueueManager from './QueueManager'; -import { isEvmBlockchain } from 'rango-sdk'; -import { WidgetConfig } from './types'; -import './i18n'; -import { useUiStore } from './store/ui'; -import { navigationRoutes } from './constants/navigationRoutes'; -import { initConfig } from './utils/configs'; - -const providers = allProviders(); - -export type WidgetProps = { - config?: WidgetConfig; -}; - -export function App({ config }: WidgetProps) { - globalStyles(); - globalFont(config?.theme?.fontFamily || 'Roboto'); - const { activeTheme } = useTheme({ ...config?.theme }); - useMemo(() => { - if (config?.apiKey) { - initConfig({ - API_KEY: config?.apiKey, - }); - } - }, [config]); - - const { blockchains } = useMetaStore.use.meta(); - const disconnectWallet = useWalletsStore.use.disconnectWallet(); - const connectWallet = useWalletsStore.use.connectWallet(); - const currentPage = useUiStore.use.currentPage(); - - const [lastConnectedWalletWithNetwork, setLastConnectedWalletWithNetwork] = - useState(''); - const [disconnectedWallet, setDisconnectedWallet] = useState(); - - const evmBasedChainNames = blockchains - .filter(isEvmBlockchain) - .map((chain) => chain.name); - - const themeBackground = activeTheme?.colors?.background?.value; - - useEffect(() => { - document.body.style.background = themeBackground; - }, [themeBackground]); - - const onUpdateState: EventHandler = ( - type, - event, - value, - state, - supportedChains - ) => { - if (event === Events.ACCOUNTS) { - if (value) { - const supportedChainNames: Network[] | null = - walletAndSupportedChainsNames(supportedChains); - const data = prepareAccountsForWalletStore( - type, - value, - evmBasedChainNames, - supportedChainNames - ); - connectWallet(data); - } else { - disconnectWallet(type); - setDisconnectedWallet(type); - } - } - - if (event === Events.ACCOUNTS && state.connected) { - const key = `${type}-${state.network}-${value}`; - - if (state.connected) { - setLastConnectedWalletWithNetwork(key); - } - } - - if (event === Events.NETWORK && state.network) { - const key = `${type}-${state.network}`; - setLastConnectedWalletWithNetwork(key); - } - }; - - return ( - -
- - - { - setDisconnectedWallet(undefined); - }} - > - - - - -
-
- ); -} diff --git a/widget/embedded/src/QueueManager.tsx b/widget/embedded/src/QueueManager.tsx index 3643b4853b..20f1a2d8ab 100644 --- a/widget/embedded/src/QueueManager.tsx +++ b/widget/embedded/src/QueueManager.tsx @@ -1,23 +1,27 @@ -import React, { PropsWithChildren, useMemo } from 'react'; -import { Provider as ManagerProvider } from '@rango-dev/queue-manager-react'; -import { - makeQueueDefinition, +import type { SwapQueueContext, - checkWaitingForNetworkChange, + TargetNamespace, } from '@rango-dev/queue-manager-rango-preset'; -import { useWallets } from '@rango-dev/wallets-core'; +import type { WalletType } from '@rango-dev/wallets-shared'; +import type { PropsWithChildren } from 'react'; + import { - convertEvmBlockchainMetaToEvmChainInfo, - Network, - WalletType, -} from '@rango-dev/wallets-shared'; -import { useMetaStore } from './store/meta'; -import { useWalletsStore } from './store/wallets'; -import { walletAndSupportedChainsNames } from './utils/wallets'; -import { isEvmBlockchain } from 'rango-sdk'; + checkWaitingForNetworkChange, + makeQueueDefinition, +} from '@rango-dev/queue-manager-rango-preset'; +import { Provider as ManagerProvider } from '@rango-dev/queue-manager-react'; +import { useWallets } from '@rango-dev/wallets-react'; +import { convertEvmBlockchainMetaToEvmChainInfo } from '@rango-dev/wallets-shared'; +import { isEvmBlockchain } from 'rango-types'; +import React, { useMemo } from 'react'; + +import { eventEmitter } from './services/eventEmitter'; +import { useAppStore } from './store/AppStore'; +import { useUiStore } from './store/ui'; import { getConfig } from './utils/configs'; +import { walletAndSupportedChainsNames } from './utils/wallets'; -function QueueManager(props: PropsWithChildren<{}>) { +function QueueManager(props: PropsWithChildren<{ apiKey?: string }>) { const { providers, getSigners, @@ -29,41 +33,55 @@ function QueueManager(props: PropsWithChildren<{}>) { const swapQueueDef = useMemo(() => { return makeQueueDefinition({ - API_KEY: getConfig('API_KEY'), + API_KEY: props.apiKey || getConfig('API_KEY'), + BASE_URL: getConfig('BASE_URL'), + emitter: { + emit: eventEmitter.emit, + }, }); - }, []); - const { blockchains } = useMetaStore.use.meta(); - const balances = useWalletsStore.use.balances(); + }, [props.apiKey]); + + const { blockchains, connectedWallets } = useAppStore(); + const blockchainsList = blockchains(); const wallets = { - blockchains: balances.map((wallet) => ({ + blockchains: connectedWallets.map((wallet) => ({ accounts: [wallet], name: wallet.chain, })), }; - const switchNetwork = (wallet: WalletType, network: Network) => { - if (!canSwitchNetworkTo(wallet, network)) { + const switchNetwork = async ( + wallet: WalletType, + namespace: TargetNamespace + ) => { + if (!canSwitchNetworkTo(wallet, namespace.network)) { return undefined; } - return connect(wallet, network); + const result = await connect(wallet, [namespace]); + + return result; }; + const isMobileWallet = (walletType: WalletType): boolean => + !!getWalletInfo(walletType).mobileWallet; + // TODO: this code copy & pasted from rango, should be refactored. - const allBlockchains = blockchains + const allBlockchains = blockchainsList .filter((blockchain) => blockchain.enabled) .reduce( - (blockchainsObj, blockchain) => ( + (blockchainsObj: any, blockchain) => ( (blockchainsObj[blockchain.name] = blockchain), blockchainsObj ), {} ); - const evmBasedChains = blockchains.filter(isEvmBlockchain); + const evmBasedChains = blockchainsList.filter(isEvmBlockchain); const getSupportedChainNames = (type: WalletType) => { const { supportedChains } = getWalletInfo(type); return walletAndSupportedChainsNames(supportedChains); }; const allProviders = providers(); + const context: SwapQueueContext = { meta: { blockchains: allBlockchains, @@ -73,28 +91,24 @@ function QueueManager(props: PropsWithChildren<{}>) { getSupportedChainNames, }, getSigners, - //todo: remove Network type - //@ts-ignore wallets, providers: allProviders, switchNetwork, - connect, + canSwitchNetworkTo, state, - notifier: (message) => { - console.log('[notifier]', message); - }, + isMobileWallet, }; + const isActiveTab = useUiStore.use.isActiveTab(); + return ( { checkWaitingForNetworkChange(manager); }} - isPaused={false} - > + isPaused={!isActiveTab}> {props.children} ); diff --git a/widget/embedded/src/app.css b/widget/embedded/src/app.css deleted file mode 100644 index 9c16546c2c..0000000000 --- a/widget/embedded/src/app.css +++ /dev/null @@ -1,12 +0,0 @@ -@import url('https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap'); - -#app { - height: 100vh; -} -#pageContainer { - display: flex; - align-items: center; - justify-content: center; - height: 100%; - width: 100%; -} diff --git a/widget/embedded/src/components/AppRouter.tsx b/widget/embedded/src/components/AppRouter.tsx index f1b9b3c7cc..7b90b84aeb 100644 --- a/widget/embedded/src/components/AppRouter.tsx +++ b/widget/embedded/src/components/AppRouter.tsx @@ -1,62 +1,11 @@ -import React, { PropsWithChildren, useEffect, useRef } from 'react'; -import { - MemoryRouter, - useInRouterContext, - useLocation, - useNavigate, -} from 'react-router'; -import { useQueueManager } from '@rango-dev/queue-manager-rango-preset'; -import { navigationRoutes } from '../constants/navigationRoutes'; -import { WalletType } from '@rango-dev/wallets-shared'; -import { isEvmBlockchain } from 'rango-types'; -import { UpdateUrl } from './UpdateUrl'; -import { Home } from '../pages/Home'; -import { useMetaStore } from '../store/meta'; +import type { PropsWithChildren } from 'react'; -const Route: React.FC = ({ children }: PropsWithChildren) => { - const location = useLocation(); - const navigate = useNavigate(); - const ref = useRef(true); +import React, { Fragment } from 'react'; +import { MemoryRouter, useInRouterContext } from 'react-router'; - useEffect(() => { - if (location.pathname === navigationRoutes.confirmSwap && ref.current) - navigate(navigationRoutes.home + location.search, { state: 'redirect' }); - - ref.current = false; - }, []); - - if (location.pathname === navigationRoutes.confirmSwap && ref.current) - return ; - - return <> {children}; -}; - -export function AppRouter({ - children, - ...props -}: PropsWithChildren & { - lastConnectedWallet: string; - disconnectedWallet: WalletType | undefined; - clearDisconnectedWallet: () => void; -}) { +export function AppRouter({ children }: PropsWithChildren) { const isRouterInContext = useInRouterContext(); - const Router = isRouterInContext ? Route : MemoryRouter; - const { blockchains } = useMetaStore.use.meta(); - - const evmChains = blockchains.filter(isEvmBlockchain); - - useQueueManager({ - lastConnectedWallet: props.lastConnectedWallet, - clearDisconnectedWallet: props.clearDisconnectedWallet, - disconnectedWallet: props.disconnectedWallet, - evmChains, - notifier: () => {}, - }); + const Router = isRouterInContext ? Fragment : MemoryRouter; - return ( - <> - {children} - {isRouterInContext && } - - ); + return {children}; } diff --git a/widget/embedded/src/components/AppRoutes.tsx b/widget/embedded/src/components/AppRoutes.tsx index 35a8e81255..9d9c92356b 100644 --- a/widget/embedded/src/components/AppRoutes.tsx +++ b/widget/embedded/src/components/AppRoutes.tsx @@ -1,88 +1,136 @@ import React from 'react'; import { useRoutes } from 'react-router-dom'; + import { navigationRoutes } from '../constants/navigationRoutes'; +import { useSyncStoresWithConfig } from '../hooks/useSyncStoresWithConfig'; +import { useSyncUrlAndStore } from '../hooks/useSyncUrlAndStore'; +import { AddCustomTokenPage } from '../pages/AddCustomTokenPage'; import { ConfirmSwapPage } from '../pages/ConfirmSwapPage'; +import { CustomTokensPage } from '../pages/CustomTokensPage'; import { HistoryPage } from '../pages/HistoryPage'; import { Home } from '../pages/Home'; -import { LiquiditySourcePage } from '../pages/LiquiditySourcesPage'; -import { SelectChainPage } from '../pages/SelectChainPage'; -import { SelectTokenPage } from '../pages/SelectTokenPage'; +import { LanguagePage } from '../pages/LanguagePage'; +import { LiquiditySourcePage } from '../pages/LiquiditySourcePage'; +import { RoutesPage } from '../pages/Routes'; +import { SelectBlockchainPage } from '../pages/SelectBlockchainPage'; +import { SelectSwapItemsPage } from '../pages/SelectSwapItemsPage'; import { SettingsPage } from '../pages/SettingsPage'; -import { WalletsPage } from '../pages/WalletsPage'; import { SwapDetailsPage } from '../pages/SwapDetailsPage'; -import { WidgetConfig } from '../types'; - -const getAbsolutePath = (path: string) => path.replace('/', ''); - -interface PropTypes { - config?: WidgetConfig; -} +import { WalletsPage } from '../pages/WalletsPage'; -export function AppRoutes(props: PropTypes) { - const { config } = props; +export function AppRoutes() { + /** + * The configuration of the widget should initially be applied to the widget state. + * If search parameters exist in the URL, + * they should be applied later and take precedence over the widget configuration. + * To achieve this, it is crucial to execute these hooks in the correct sequence. + */ + useSyncStoresWithConfig(); + useSyncUrlAndStore(); return useRoutes([ { - path: getAbsolutePath(navigationRoutes.home), + path: navigationRoutes.home, element: , }, { - path: getAbsolutePath(navigationRoutes.fromChain), - element: ( - - ), + path: navigationRoutes.routes, + element: , }, { - path: getAbsolutePath(navigationRoutes.toChain), - element: ( - - ), + path: navigationRoutes.fromSwap, + children: [ + { + index: true, + element: , + }, + { + path: navigationRoutes.blockchains, + element: , + }, + ], }, { - path: getAbsolutePath(navigationRoutes.fromToken), - element: ( - - ), + path: navigationRoutes.toSwap, + children: [ + { + index: true, + element: , + }, + { + path: navigationRoutes.blockchains, + element: , + }, + ], }, { - path: getAbsolutePath(navigationRoutes.toToken), - element: ( - - ), + path: navigationRoutes.settings, + children: [ + { + index: true, + element: , + }, + { + path: navigationRoutes.languages, + element: , + }, + { + path: navigationRoutes.exchanges, + element: , + }, + { + path: navigationRoutes.bridges, + element: , + }, + { + path: navigationRoutes.customTokens, + children: [ + { + index: true, + element: , + }, + { + path: navigationRoutes.addCustomTokens, + children: [ + { + index: true, + element: , + }, + { + path: navigationRoutes.blockchains, + element: ( + + ), + }, + ], + }, + ], + }, + ], }, + { - path: getAbsolutePath(navigationRoutes.settings), - element: , - }, - { - path: getAbsolutePath(navigationRoutes.liquiditySources), - element: ( - - ), - }, - { path: getAbsolutePath(navigationRoutes.swaps), element: }, - { - path: navigationRoutes.swapDetails, - element: , + path: navigationRoutes.swaps, + children: [ + { + index: true, + element: , + }, + { + path: navigationRoutes.swapDetails, + element: , + }, + ], }, { - path: getAbsolutePath(navigationRoutes.wallets), - element: ( - - ), + path: navigationRoutes.wallets, + element: , }, { - path: getAbsolutePath(navigationRoutes.confirmSwap), + path: navigationRoutes.confirmSwap, element: , }, ]); diff --git a/widget/embedded/src/components/BlockchainList/BlockchainList.helpers.ts b/widget/embedded/src/components/BlockchainList/BlockchainList.helpers.ts new file mode 100644 index 0000000000..d200e2870b --- /dev/null +++ b/widget/embedded/src/components/BlockchainList/BlockchainList.helpers.ts @@ -0,0 +1,18 @@ +import { type BlockchainMeta } from 'rango-sdk'; + +import { containsText, isBlockchainTypeInCategory } from '../../utils/common'; + +export const filterBlockchains = ( + list: BlockchainMeta[], + searchedFor: string, + blockchainCategory: string +) => + list + .filter((blockchain) => + isBlockchainTypeInCategory(blockchain.type, blockchainCategory) + ) + .filter( + (blockchain) => + containsText(blockchain.name, searchedFor) || + containsText(blockchain.displayName, searchedFor) + ); diff --git a/widget/embedded/src/components/BlockchainList/BlockchainList.styles.ts b/widget/embedded/src/components/BlockchainList/BlockchainList.styles.ts new file mode 100644 index 0000000000..de825faa8e --- /dev/null +++ b/widget/embedded/src/components/BlockchainList/BlockchainList.styles.ts @@ -0,0 +1,22 @@ +import { ImageContainer, styled } from '@rango-dev/ui'; + +import { ScrollableArea } from '../Layout'; + +export const BlockchainListContainer = styled('div', { + display: 'flex', + flexDirection: 'column', + overflow: 'hidden', + height: '100%', + justifyContent: 'center', +}); + +export const List = styled(ScrollableArea, { + padding: 0, + margin: 0, + listStyle: 'none', + + [`& ${ImageContainer}`]: { + borderRadius: '$xm', + overflow: 'hidden', + }, +}); diff --git a/widget/embedded/src/components/BlockchainList/BlockchainList.tsx b/widget/embedded/src/components/BlockchainList/BlockchainList.tsx new file mode 100644 index 0000000000..958ec91658 --- /dev/null +++ b/widget/embedded/src/components/BlockchainList/BlockchainList.tsx @@ -0,0 +1,83 @@ +import type { PropTypes } from './BlockchainList.types'; +import type { BlockchainMeta } from 'rango-sdk'; + +import { i18n } from '@lingui/core'; +import { + Divider, + Image, + ListItemButton, + NotFound, + Typography, +} from '@rango-dev/ui'; +import React, { useEffect, useState } from 'react'; + +import { useAppStore } from '../../store/AppStore'; + +import { filterBlockchains } from './BlockchainList.helpers'; +import { BlockchainListContainer, List } from './BlockchainList.styles'; +import { LoadingBlockchainList } from './LoadingBlockchainList'; + +export function BlockchainList(props: PropTypes) { + const { + list, + searchedFor, + onChange, + blockchainCategory, + showTitle = true, + } = props; + const [blockchains, setBlockchains] = useState(list); + const { fetchStatus } = useAppStore(); + + useEffect(() => { + setBlockchains([ + ...filterBlockchains(list, searchedFor, blockchainCategory), + ]); + }, [list, searchedFor, blockchainCategory]); + + const renderList = () => { + if (!blockchains.length && !!searchedFor) { + return ( + + ); + } + return ( + + {blockchains.map((item) => ( + onChange(item)} + start={} + title={ + + {item.displayName} + + } + id={item.name} + /> + ))} + + ); + }; + + return ( + <> + {showTitle && ( + <> + + {i18n.t('Select Chain')} + + + + )} + + {fetchStatus === 'loading' && } + {fetchStatus === 'success' && renderList()} + + + ); +} diff --git a/widget/embedded/src/components/BlockchainList/BlockchainList.types.ts b/widget/embedded/src/components/BlockchainList/BlockchainList.types.ts new file mode 100644 index 0000000000..e5cb8562e8 --- /dev/null +++ b/widget/embedded/src/components/BlockchainList/BlockchainList.types.ts @@ -0,0 +1,9 @@ +import type { BlockchainMeta } from 'rango-sdk'; + +export interface PropTypes { + list: BlockchainMeta[]; + searchedFor: string; + blockchainCategory: string; + onChange: (blockchain: BlockchainMeta) => void; + showTitle?: boolean; +} diff --git a/widget/embedded/src/components/BlockchainList/LoadingBlockchainList.tsx b/widget/embedded/src/components/BlockchainList/LoadingBlockchainList.tsx new file mode 100644 index 0000000000..aadef491cf --- /dev/null +++ b/widget/embedded/src/components/BlockchainList/LoadingBlockchainList.tsx @@ -0,0 +1,20 @@ +import { ListItem, Skeleton } from '@rango-dev/ui'; +import React from 'react'; + +import { List } from './BlockchainList.styles'; + +const ITEM_SKELETON_COUNT = 20; +export function LoadingBlockchainList() { + return ( + + {Array.from(Array(ITEM_SKELETON_COUNT), (e) => ( + } + title={} + /> + ))} + + ); +} diff --git a/widget/embedded/src/components/BlockchainList/index.ts b/widget/embedded/src/components/BlockchainList/index.ts new file mode 100644 index 0000000000..19f7bb8bef --- /dev/null +++ b/widget/embedded/src/components/BlockchainList/index.ts @@ -0,0 +1 @@ +export { BlockchainList } from './BlockchainList'; diff --git a/widget/embedded/src/components/BlockchainSelectorButton/BlockchainSelectorButton.styles.ts b/widget/embedded/src/components/BlockchainSelectorButton/BlockchainSelectorButton.styles.ts new file mode 100644 index 0000000000..132b871aec --- /dev/null +++ b/widget/embedded/src/components/BlockchainSelectorButton/BlockchainSelectorButton.styles.ts @@ -0,0 +1,49 @@ +import { darkTheme, styled } from '@rango-dev/ui'; + +export const InputContainer = styled('div', { + display: 'flex', + justifyContent: 'space-between', + width: '100%', + height: '$40', + padding: '$4 $10', + borderRadius: '$sm', + cursor: 'pointer', + alignItems: 'center', + backgroundColor: '$neutral300', + [`.${darkTheme} &`]: { + backgroundColor: '$neutral400', + }, + + '&:hover': { + backgroundColor: '$secondary100', + [`.${darkTheme} &`]: { + backgroundColor: '$neutral500', + }, + }, + variants: { + disabled: { + true: { + cursor: 'default', + '&:hover': { + borderColor: '$neutral300', + '& svg': { + color: '$neutral700', + }, + }, + }, + }, + }, +}); + +export const Container = styled('div', { + display: 'flex', + flexDirection: 'column', + width: '100%', + '.title_typography': { + textTransform: 'capitalize', + }, +}); + +export const FlexContainer = styled('div', { + display: 'flex', +}); diff --git a/widget/embedded/src/components/BlockchainSelectorButton/BlockchainSelectorButton.tsx b/widget/embedded/src/components/BlockchainSelectorButton/BlockchainSelectorButton.tsx new file mode 100644 index 0000000000..ddd68e056b --- /dev/null +++ b/widget/embedded/src/components/BlockchainSelectorButton/BlockchainSelectorButton.tsx @@ -0,0 +1,47 @@ +import type { PropTypes } from './BlockchainSelectorButton.types'; + +import { ChevronRightIcon, Divider, Image, Typography } from '@rango-dev/ui'; +import React from 'react'; + +import { + Container, + FlexContainer, + InputContainer, +} from './BlockchainSelectorButton.styles'; + +export function BlockchainSelectorButton(props: PropTypes) { + const { onClick, value, title, hasLogo, placeholder, disabled } = props; + + return ( + + + {title} + + + + + {hasLogo && ( + <> + + + + )} + + {value?.name || placeholder} + + + + + + ); +} diff --git a/widget/embedded/src/components/BlockchainSelectorButton/BlockchainSelectorButton.types.ts b/widget/embedded/src/components/BlockchainSelectorButton/BlockchainSelectorButton.types.ts new file mode 100644 index 0000000000..380802a4dc --- /dev/null +++ b/widget/embedded/src/components/BlockchainSelectorButton/BlockchainSelectorButton.types.ts @@ -0,0 +1,11 @@ +export interface PropTypes { + onClick: () => void; + value?: { + name: string; + logo: string; + }; + title: string; + placeholder: string; + hasLogo?: boolean; + disabled?: boolean; +} diff --git a/widget/embedded/src/components/BlockchainSelectorButton/index.ts b/widget/embedded/src/components/BlockchainSelectorButton/index.ts new file mode 100644 index 0000000000..4e3c4b7013 --- /dev/null +++ b/widget/embedded/src/components/BlockchainSelectorButton/index.ts @@ -0,0 +1 @@ +export { BlockchainSelectorButton } from './BlockchainSelectorButton'; diff --git a/widget/embedded/src/components/BlockchainsSection/BlockchainsSection.styles.ts b/widget/embedded/src/components/BlockchainsSection/BlockchainsSection.styles.ts new file mode 100644 index 0000000000..2a3d61e3dc --- /dev/null +++ b/widget/embedded/src/components/BlockchainsSection/BlockchainsSection.styles.ts @@ -0,0 +1,7 @@ +import { styled } from '@rango-dev/ui'; + +export const Blockchains = styled('div', { + display: 'grid', + gap: '$10', + gridTemplateColumns: 'repeat(6, minmax(0, 1fr))', +}); diff --git a/widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx b/widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx new file mode 100644 index 0000000000..b01fddb3f4 --- /dev/null +++ b/widget/embedded/src/components/BlockchainsSection/BlockchainsSection.tsx @@ -0,0 +1,111 @@ +/* eslint-disable @typescript-eslint/no-magic-numbers */ +import type { PropTypes } from './BlockchainsSection.types'; + +import { i18n } from '@lingui/core'; +import { + BlockchainsChip, + Divider, + Image, + Skeleton, + Tooltip, + Typography, +} from '@rango-dev/ui'; +import React from 'react'; + +import { BLOCKCHAIN_LIST_SIZE } from '../../constants/configs'; +import { usePrepareBlockchainList } from '../../hooks/usePrepareBlockchainList'; +import { useAppStore } from '../../store/AppStore'; +import { useQuoteStore } from '../../store/quote'; +import { getContainer } from '../../utils/common'; + +import { Blockchains } from './BlockchainsSection.styles'; + +const NUMBER_OF_LOADING = 12; + +export function BlockchainsSection(props: PropTypes) { + const { blockchains, type, blockchain, onChange, onMoreClick } = props; + const blockchainsList = usePrepareBlockchainList(blockchains, { + limit: BLOCKCHAIN_LIST_SIZE, + selected: blockchain?.name, + }); + + const { fetchStatus } = useAppStore(); + const resetToBlockchain = useQuoteStore.use.resetToBlockchain(); + const resetFromBlockchain = useQuoteStore.use.resetFromBlockchain(); + const hasMoreItemsInList = blockchainsList.more.length > 0; + /** + * When only one item is left on list, we will not show the `More` button and will show the item itself instead. + */ + const onlyOneItemInList = blockchainsList.more.length === 1; + const showMoreButton = !onlyOneItemInList && hasMoreItemsInList; + + return ( + <> + + + {i18n.t('Select Chain')} + + + + {fetchStatus === 'loading' && + Array.from(Array(NUMBER_OF_LOADING), (e) => ( + + ))} + {fetchStatus === 'success' && ( + <> + { + if (type === 'from') { + resetFromBlockchain(); + } else { + resetToBlockchain(); + } + }}> + + {i18n.t('All')} + + + {blockchainsList.list.map((item) => ( + + onChange(item)}> + + + + ))} + + {onlyOneItemInList ? ( + onChange(blockchainsList.more[0])}> + + + ) : null} + + {showMoreButton ? ( + + + {i18n._('More +{count}', { + count: blockchainsList.more.length, + })} + + + ) : null} + + )} + + + ); +} diff --git a/widget/embedded/src/components/BlockchainsSection/BlockchainsSection.types.ts b/widget/embedded/src/components/BlockchainsSection/BlockchainsSection.types.ts new file mode 100644 index 0000000000..7f6ba0c5c6 --- /dev/null +++ b/widget/embedded/src/components/BlockchainsSection/BlockchainsSection.types.ts @@ -0,0 +1,9 @@ +import type { BlockchainMeta } from 'rango-sdk'; + +export interface PropTypes { + blockchains: BlockchainMeta[]; + type: 'from' | 'to'; + blockchain: BlockchainMeta | null; + onChange: (blockchain: BlockchainMeta) => void; + onMoreClick: () => void; +} diff --git a/widget/embedded/src/components/BlockchainsSection/index.ts b/widget/embedded/src/components/BlockchainsSection/index.ts new file mode 100644 index 0000000000..6d58014897 --- /dev/null +++ b/widget/embedded/src/components/BlockchainsSection/index.ts @@ -0,0 +1 @@ +export { BlockchainsSection } from './BlockchainsSection'; diff --git a/widget/embedded/src/components/BottomLogo.tsx b/widget/embedded/src/components/BottomLogo.tsx deleted file mode 100644 index 866eeabba8..0000000000 --- a/widget/embedded/src/components/BottomLogo.tsx +++ /dev/null @@ -1,47 +0,0 @@ -import React from 'react'; -import { styled } from '@rango-dev/ui/src/theme'; -import { Typography } from '@rango-dev/ui'; -import { useTranslation } from 'react-i18next'; - -const Container = styled('div', { - display: 'flex', - width: '100%', - justifyContent: 'end', - alignItems: 'center', - paddingTop: '$16', -}); - -const Logo = styled('svg', { - fill: '$foreground', - width: '$24', - margin: '0 $8 0 $16', -}); - -const StyledAnchor = styled('a', { - display: 'flex', - justifyContent: 'center', - alignItems: 'center', - textDecoration: 'none', -}); - -export function BottomLogo() { - const { t } = useTranslation(); - - return ( - - {t('Powered By')} - - - - - - - - - - - RANGO - - - ); -} diff --git a/widget/embedded/src/components/ChangeSlippageButton.tsx b/widget/embedded/src/components/ChangeSlippageButton.tsx deleted file mode 100644 index 5aeda79270..0000000000 --- a/widget/embedded/src/components/ChangeSlippageButton.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import React from 'react'; -import { Button } from '@rango-dev/ui'; -import { useNavigate } from 'react-router-dom'; -import { navigationRoutes } from '../constants/navigationRoutes'; - -export function ChangeSlippageButton() { - const navigate = useNavigate(); - - return ( - - ); -} diff --git a/widget/embedded/src/components/ConfirmSwapErrors.tsx b/widget/embedded/src/components/ConfirmSwapErrors.tsx deleted file mode 100644 index 9ffa728fb0..0000000000 --- a/widget/embedded/src/components/ConfirmSwapErrors.tsx +++ /dev/null @@ -1,30 +0,0 @@ -import React from 'react'; -import { ConfirmSwapError, ConfirmSwapErrorTypes } from '../types'; -import { MinRequiredSlippage } from './warnings/MinRequiredSlippage'; -import { BalanceErrors } from './warnings/BalanceErrors'; - -export function ConfirmSwapErrors(errors: ConfirmSwapError[]) { - return errors.flatMap((error) => { - switch (error.type) { - case ConfirmSwapErrorTypes.NO_ROUTE: - return 'No routes found. Please try again later.'; - case ConfirmSwapErrorTypes.REQUEST_FAILED: - return `Failed to confirm swap ${ - error.status ? `'status': ${error.status})` : '' - }, please try again.`; - - case ConfirmSwapErrorTypes.ROUTE_UPDATED_WITH_HIGH_VALUE_LOSS: - return 'Route updated and price impact is too high, try again later!'; - case ConfirmSwapErrorTypes.INSUFFICIENT_SLIPPAGE: - return ( - - ); - case ConfirmSwapErrorTypes.INSUFFICIENT_BALANCE: - return ; - default: - return []; - } - }); -} diff --git a/widget/embedded/src/components/ConfirmSwapWarnings.tsx b/widget/embedded/src/components/ConfirmSwapWarnings.tsx deleted file mode 100644 index 0f4a36c46f..0000000000 --- a/widget/embedded/src/components/ConfirmSwapWarnings.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import { ConfirmSwapWarningTypes, ConfirmSwapWarnings } from '../types'; - -export function ConfirmSwapWarnings(warnings: ConfirmSwapWarnings[]) { - return warnings.flatMap((warning) => { - switch (warning.type) { - case ConfirmSwapWarningTypes.ROUTE_UPDATED: - return "Route has been updated."; - case ConfirmSwapWarningTypes.ROUTE_AND_OUTPUT_AMOUNT_UPDATED: - return ( - `Output amount changed to ${warning.newOutputAmount} (${warning.percentageChange}% change).` - ); - - case ConfirmSwapWarningTypes.ROUTE_SWAPPERS_UPDATED: - return ( - "Route swappers has been updated." - ); - case ConfirmSwapWarningTypes.ROUTE_COINS_UPDATED: - return ( - "Route internal coins has been updated." - ); - default: - return []; - } - }); -} \ No newline at end of file diff --git a/widget/embedded/src/components/ConfirmWalletsModal/ConfirmWallets.styles.ts b/widget/embedded/src/components/ConfirmWalletsModal/ConfirmWallets.styles.ts new file mode 100644 index 0000000000..187cb4a45a --- /dev/null +++ b/widget/embedded/src/components/ConfirmWalletsModal/ConfirmWallets.styles.ts @@ -0,0 +1,100 @@ +import { css, darkTheme, IconButton, styled } from '@rango-dev/ui'; + +export const Title = styled('div', { + display: 'flex', + flexDirection: 'column', + justifyContent: 'center', + alignItems: 'center', +}); + +export const ListContainer = styled('div', { + display: 'flex', + justifyContent: 'space-evenly', + alignItems: 'center', + gap: '$10', + flexWrap: 'wrap', + paddingTop: '$5', + height: '100%', +}); + +export const WalletButton = styled('button', { + borderRadius: '$xm', + padding: '$10', + border: '0', + display: 'flex', + justifyContent: 'center', + $$color: '$colors$neutral100', + [`.${darkTheme} &`]: { + $$color: '$colors$neutral300', + }, + backgroundColor: '$$color', + alignItems: 'center', + cursor: 'pointer', + width: 110, + position: 'relative', + + '&:hover': { + $$color: '$colors$secondary100', + [`.${darkTheme} &`]: { + $$color: '$colors$neutral100', + }, + backgroundColor: '$$color', + }, + + '&:focus-visible': { + $$color: '$colors$secondary100', + [`.${darkTheme} &`]: { + $$color: '$colors$info700', + }, + backgroundColor: '$$color', + outline: 0, + }, + variants: { + selected: { + true: { + outlineWidth: 1, + outlineColor: '$secondary', + outlineStyle: 'solid', + }, + }, + }, +}); + +export const ShowMoreWallets = styled(WalletButton, { + alignSelf: 'stretch', + minHeight: '93px', +}); +export const ShowMoreHeader = styled('div', { + padding: '$20 $20 $15 $20', + display: 'flex', + justifyContent: 'center', + alignItems: 'center', + backgroundColor: '$neutral200', + position: 'relative', + width: '100%', +}); + +export const NavigateBack = styled(IconButton, { + position: 'absolute', + left: '$20', +}); + +export const WalletsContainer = styled('div', { + paddingTop: '$20', +}); + +export const walletsListStyles = css({ + display: 'flex', + justifyContent: 'space-evenly', + alignItems: 'center', + gap: '$10', + flexWrap: 'wrap', + paddingTop: '$5', + height: '100%', +}); + +export const ConfirmButton = styled('div', { + display: 'flex', +}); + +export const Wallets = styled('div', { overflow: 'visible', width: '100%' }); diff --git a/widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx b/widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx new file mode 100644 index 0000000000..f82c72f58e --- /dev/null +++ b/widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.tsx @@ -0,0 +1,476 @@ +import type { PropTypes } from './ConfirmWalletsModal.types'; +import type { ConnectedWallet } from '../../store/slices/wallets'; +import type { Wallet } from '../../types'; + +import { i18n } from '@lingui/core'; +import { + Alert, + BalanceErrors, + Button, + ChevronLeftIcon, + Divider, + MessageBox, + Typography, +} from '@rango-dev/ui'; +import React, { useCallback, useEffect, useMemo, useState } from 'react'; +import { useNavigate } from 'react-router-dom'; + +import { WIDGET_UI_ID } from '../../constants'; +import { getQuoteErrorMessage } from '../../constants/errors'; +import { useAppStore } from '../../store/AppStore'; +import { useQuoteStore } from '../../store/quote'; +import { getBlockchainShortNameFor } from '../../utils/meta'; +import { isConfirmSwapDisabled } from '../../utils/swap'; +import { getQuoteWallets } from '../../utils/wallets'; +import { WatermarkedModal } from '../common/WatermarkedModal'; +import { CustomDestination } from '../CustomDestination/CustomDestination'; + +import { + ConfirmButton, + ListContainer, + NavigateBack, + ShowMoreHeader, + Title, + Wallets, + WalletsContainer, + walletsListStyles, +} from './ConfirmWallets.styles'; +import { WalletList } from './WalletList'; + +const NUMBER_OF_WALLETS_TO_DISPLAY = 2; + +export function ConfirmWalletsModal(props: PropTypes) { + //TODO: move component's logics to a custom hook + const { open, onClose, onCancel, onCheckBalance, loading } = props; + const navigate = useNavigate(); + const blockchains = useAppStore().blockchains(); + const { + selectedQuote, + setSelectedWallets: selectQuoteWallets, + quoteWalletsConfirmed: quoteWalletsConfirmed, + setQuoteWalletConfirmed: setQuoteWalletConfirmed, + customDestination, + setCustomDestination, + } = useQuoteStore(); + const { config, connectedWallets, setWalletsAsSelected } = useAppStore(); + + const [showMoreWalletFor, setShowMoreWalletFor] = useState(''); + const [balanceWarnings, setBalanceWarnings] = useState([]); + const [error, setError] = useState(''); + + const [isCustomDestinationOpen, setCustomDestinationOpen] = useState( + !!customDestination + ); + + const quoteWallets = useMemo( + () => + getQuoteWallets({ + filter: 'all', + quote: selectedQuote, + }), + [selectedQuote] + ); + + const requiredWallets = getQuoteWallets({ + filter: 'required', + quote: selectedQuote, + }); + + const lastStepToBlockchain = blockchains.find( + (blockchain) => + blockchain.name === + selectedQuote?.swaps[selectedQuote?.swaps.length - 1].to.blockchain + ); + const isWalletRequiredFor = (blockchain: string) => + requiredWallets.includes(blockchain); + + const getInitialSelectableWallets = useCallback( + () => + connectedWallets.filter((connectedWallet) => { + return ( + connectedWallet.selected && + quoteWallets.includes(connectedWallet.chain) + ); + }), + [connectedWallets, quoteWallets] + ); + + const [selectableWallets, setSelectableWallets] = useState( + getInitialSelectableWallets() + ); + const [nextSelectedWallets, setNextSelectedWallets] = useState< + { + blockchain: string; + walletType: string; + }[] + >([]); + + const addNextSelectedWallets = (blockchain: string, walletType: string) => + setNextSelectedWallets((prevState) => + prevState.concat({ + blockchain, + walletType, + }) + ); + + const isInsufficientBalanceModalOpen = balanceWarnings.length > 0; + + const isSelected = (walletType: string, chain: string) => + !!selectableWallets.find( + (selectableWallet) => + selectableWallet.walletType === walletType && + selectableWallet.chain === chain && + selectableWallet.selected && + (isWalletRequiredFor(chain) || + (!isWalletRequiredFor(chain) && !customDestination)) + ); + + const updateSelectableWallets = ( + wallets: ConnectedWallet[], + chainName: string, + shouldSelect: boolean + ) => { + let isAnyWalletSelected = false; + return wallets.map((wallet) => { + if (wallet.chain === chainName) { + let selected = wallet.selected; + if (!isAnyWalletSelected && shouldSelect) { + isAnyWalletSelected = true; + selected = true; + } else if (!shouldSelect) { + selected = false; + } + return { + ...wallet, + selected, + }; + } + return wallet; + }); + }; + + const handleCustomDestinationCollapsibleOpenChange = (open: boolean) => { + setCustomDestinationOpen(open); + if (!open) { + setCustomDestination(''); + setSelectableWallets((selectableWallets) => { + return updateSelectableWallets( + selectableWallets, + lastStepToBlockchain?.name || '', + true + ); + }); + } else { + if (!isWalletRequiredFor(lastStepToBlockchain?.name ?? '')) { + setSelectableWallets((selectableWallets) => { + return updateSelectableWallets( + selectableWallets, + lastStepToBlockchain?.name || '', + false + ); + }); + } + } + }; + + const onChange = (wallet: Wallet) => { + if (showMoreWalletFor) { + setShowMoreWalletFor(''); + } + const selected = isSelected(wallet.walletType, wallet.chain); + if (selected) { + return; + } + const connectedWallet = connectedWallets.find( + (connectedWallet) => + connectedWallet.walletType === wallet.walletType && + connectedWallet.chain === wallet.chain + ); + + if (!connectedWallet) { + return; + } + + onCancel(); + if ( + wallet.chain === lastStepToBlockchain?.name && + isCustomDestinationOpen && + !isWalletRequiredFor(lastStepToBlockchain.name) + ) { + setCustomDestinationOpen(false); + setCustomDestination(null); + } + setSelectableWallets((selectableWallets) => + selectableWallets + .filter((selectableWallet) => selectableWallet.chain !== wallet.chain) + .concat({ ...connectedWallet, selected: true }) + ); + }; + + const onConfirmBalance = () => { + const lastSelectedWallets = selectableWallets.filter( + (wallet) => wallet.selected + ); + setWalletsAsSelected(lastSelectedWallets); + selectQuoteWallets(lastSelectedWallets); + setQuoteWalletConfirmed(true); + onClose(); + }; + + const onConfirmWallets = async () => { + setBalanceWarnings([]); + setError(''); + + const result = await onCheckBalance?.({ + selectedWallets: selectableWallets.filter((wallet) => wallet.selected), + customDestination, + }); + const warnings = result.warnings; + if (warnings?.balance?.messages) { + setBalanceWarnings(warnings.balance.messages); + } + + if (result.error) { + setError(getQuoteErrorMessage(result.error)); + } + + if (!result.error && (!warnings?.balance?.messages.length || 0 > 0)) { + onConfirmBalance(); + } else { + setBalanceWarnings(warnings?.balance?.messages ?? []); + } + }; + + useEffect(() => { + setSelectableWallets((selectableWallets) => { + let nextState: typeof selectableWallets = []; + + //if wallet disconnected we should unselect the wallet from the list + selectableWallets.forEach((selectableWallet) => { + const walletDisconnected = !connectedWallets.some( + (connectedWallet) => + connectedWallet.chain === selectableWallet.chain && + connectedWallet.walletType === selectableWallet.walletType && + connectedWallet.address === selectableWallet.address + ); + if (!walletDisconnected) { + nextState.push(selectableWallet); + } + }); + + /** + * We confirm if a newly connected wallet for a blockchain is marked as selected in the store, + * but there are no selected wallets for that blockchain in our list. + * If this condition is met, we include the wallet in our list as selected. + */ + nextState = nextState.concat( + connectedWallets.filter((connectedWallet) => { + const anyWalletSelected = !!nextState.find( + (selectableWallet) => + selectableWallet.chain === connectedWallet.chain + ); + + return ( + !anyWalletSelected && + connectedWallet.selected && + quoteWallets.includes(connectedWallet.chain) + ); + }) + ); + return nextState; + }); + }, [connectedWallets, quoteWallets]); + + useEffect(() => { + const nextState: typeof nextSelectedWallets = []; + + if (nextSelectedWallets.length > 0) { + nextSelectedWallets.forEach((selectedWallet) => { + const wallet = connectedWallets.find( + (wallet) => + wallet.chain === selectedWallet.blockchain && + wallet.walletType === selectedWallet.walletType + ); + if (wallet) { + onChange(wallet); + } else { + nextState.push(selectedWallet); + } + }); + setNextSelectedWallets(nextState); + } + }, [connectedWallets, nextSelectedWallets]); + + const modalContainer = document.getElementById( + WIDGET_UI_ID.SWAP_BOX_ID + ) as HTMLDivElement; + + return ( + { + if (!quoteWalletsConfirmed) { + const home = '../'; + navigate(home, { replace: true }); + } + onClose(); + }} + dismissible={!showMoreWalletFor} + container={modalContainer} + {...(!showMoreWalletFor && { + styles: { container: { height: '100%' } }, + footer: ( + + + + ), + })} + {...(showMoreWalletFor && { + styles: { container: { height: '100%', padding: '$0' } }, + header: ( + + + + + + {i18n.t({ + id: 'Your {blockchainName} wallets', + values: { + blockchainName: getBlockchainShortNameFor( + showMoreWalletFor, + blockchains + ), + }, + })} + + + ), + })} + anchor="center"> + + }> + + + + {showMoreWalletFor && ( + +
+ setShowMoreWalletFor(showMoreWalletFor)} + onConnect={(walletType) => { + addNextSelectedWallets(showMoreWalletFor, walletType); + }} + /> +
+
+ )} + {!showMoreWalletFor && ( + <> + {error && ( + <> + + + + )} + + {quoteWallets.map((requiredWallet, index) => { + const blockchain = blockchains.find( + (blockchain) => blockchain.name === requiredWallet + ); + + const key = `wallet-${index}`; + const isLastWallet = index === quoteWallets.length - 1; + const showCustomDestination = + isLastWallet && + lastStepToBlockchain && + config?.customDestination !== false; + return ( +
+ + <Typography variant="title" size="xmedium"> + {i18n.t({ + id: 'Your {blockchainName} wallets', + values: { blockchainName: blockchain?.shortName }, + })} + </Typography> + <Typography + variant="label" + color="$neutral700" + size="medium"> + {i18n.t({ + id: 'You need to connect a {blockchainName} wallet.', + values: { blockchainName: blockchain?.shortName }, + })} + </Typography> + + + + + setShowMoreWalletFor(blockchain?.name ?? '') + } + onConnect={(walletType) => { + addNextSelectedWallets(requiredWallet, walletType); + }} + /> + + {!isLastWallet && } + {showCustomDestination && ( + + )} +
+ ); + })} +
+ + )} +
+ ); +} diff --git a/widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.types.ts b/widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.types.ts new file mode 100644 index 0000000000..09f5022d10 --- /dev/null +++ b/widget/embedded/src/components/ConfirmWalletsModal/ConfirmWalletsModal.types.ts @@ -0,0 +1,9 @@ +import type { ConfirmSwap } from '../../hooks/useConfirmSwap/useConfirmSwap.types'; + +export type PropTypes = { + open: boolean; + onClose: () => void; + onCancel: () => void; + onCheckBalance: ConfirmSwap['fetch']; + loading: boolean; +}; diff --git a/widget/embedded/src/components/ConfirmWalletsModal/WalletList.styles.ts b/widget/embedded/src/components/ConfirmWalletsModal/WalletList.styles.ts new file mode 100644 index 0000000000..f6a3cbf9c6 --- /dev/null +++ b/widget/embedded/src/components/ConfirmWalletsModal/WalletList.styles.ts @@ -0,0 +1,34 @@ +import { keyframes, styled } from '@rango-dev/ui'; + +export const LogoContainer = styled('div', { + position: 'relative', +}); + +const SpinAnimation = keyframes({ + '0%': { + transform: 'rotate(0deg)', + }, + '100%': { + transform: 'rotate(360deg)', + }, +}); + +export const Spinner = styled('div', { + position: 'absolute', + border: '2px solid rgba(0, 0, 0, 0.1)', + borderTop: '2px solid $info500', + borderRadius: '$lg', + width: '$45', + height: '$45', + animation: `${SpinAnimation} 1s linear infinite`, + top: 0, + bottom: 0, + right: 0, + left: 0, +}); + +export const WalletImageContainer = styled('div', { + '& img': { + borderRadius: '50%', + }, +}); diff --git a/widget/embedded/src/components/ConfirmWalletsModal/WalletList.tsx b/widget/embedded/src/components/ConfirmWalletsModal/WalletList.tsx new file mode 100644 index 0000000000..bad8a10b05 --- /dev/null +++ b/widget/embedded/src/components/ConfirmWalletsModal/WalletList.tsx @@ -0,0 +1,256 @@ +import type { PropTypes } from './WalletList.type'; +import type { Wallet } from '../../types'; +import type { ExtendedModalWalletInfo } from '../../utils/wallets'; + +import { i18n } from '@lingui/core'; +import { warn } from '@rango-dev/logging-core'; +import { + Divider, + SelectableWallet, + Typography, + WalletState, +} from '@rango-dev/ui'; +import React, { useEffect, useState } from 'react'; + +import { useWallets } from '../..'; +import { WIDGET_UI_ID } from '../../constants'; +import { + ResultStatus, + useStatefulConnect, +} from '../../hooks/useStatefulConnect'; +import { useWalletList } from '../../hooks/useWalletList'; +import { useAppStore } from '../../store/AppStore'; +import { useUiStore } from '../../store/ui'; +import { getBlockchainDisplayNameFor } from '../../utils/meta'; +import { + getAddress, + getConciseAddress, + isExperimentalChain, +} from '../../utils/wallets'; +import { WatermarkedModal } from '../common/WatermarkedModal'; +import { StatefulConnectModal } from '../StatefulConnectModal'; +import { ExperimentalChain } from '../WalletStatefulConnect'; +import { ExperimentalChainStatus } from '../WalletStatefulConnect/ExperimentalChainStatus'; + +import { ShowMoreWallets } from './ConfirmWallets.styles'; + +const ACCOUNT_ADDRESS_MAX_CHARACTERS = 7; +const TIME_TO_CLOSE_MODAL = 3_000; + +export function WalletList(props: PropTypes) { + const { chain, isSelected, selectWallet, limit, onShowMore } = props; + const isActiveTab = useUiStore.use.isActiveTab(); + + const { blockchains, connectedWallets } = useAppStore(); + const [selectedWalletToConnect, setSelectedWalletToConnect] = + useState(); + const [experimentalChainWallet, setExperimentalChainWallet] = + useState(null); + const [showExperimentalChainModal, setShowExperimentalChainModal] = + useState(false); + const [addingExperimentalChainStatus, setAddingExperimentalChainStatus] = + useState<'in-progress' | 'completed' | 'rejected' | null>(null); + const { suggestAndConnect } = useWallets(); + const { handleDisconnect } = useStatefulConnect(); + const { list } = useWalletList({ + chain, + }); + + const [sortedList, setSortedList] = useState(list); + const numberOfSupportedWallets = list.length; + const shouldShowMoreWallets = limit && numberOfSupportedWallets - limit > 0; + + const addExperimentalChain = async (wallet: Wallet) => { + setShowExperimentalChainModal(false); + setAddingExperimentalChainStatus('in-progress'); + try { + await suggestAndConnect(wallet.walletType, wallet.chain); + setAddingExperimentalChainStatus('completed'); + } catch (e) { + setAddingExperimentalChainStatus('rejected'); + } + }; + + useEffect(() => { + setSortedList((sortedList) => { + const selectedWalletIndex = list.findIndex((wallet) => + isSelected(wallet.type, chain) + ); + + if (shouldShowMoreWallets && selectedWalletIndex > 1) { + return [list[selectedWalletIndex]].concat( + list.filter((_, index) => index !== selectedWalletIndex) + ); + } + return sortedList.map( + (sortedItem) => + list.find((listItem) => listItem.type === sortedItem.type) ?? + sortedItem + ); + }); + }, [JSON.stringify(list)]); + + const modalContainer = document.getElementById( + WIDGET_UI_ID.SWAP_BOX_ID + ) as HTMLDivElement; + + useEffect(() => { + let timeout: ReturnType | null = null; + if ( + addingExperimentalChainStatus === 'completed' || + addingExperimentalChainStatus === 'rejected' + ) { + timeout = setTimeout( + () => setAddingExperimentalChainStatus(null), + TIME_TO_CLOSE_MODAL + ); + } + + return () => { + if (timeout) { + clearTimeout(timeout); + } + }; + }, [addingExperimentalChainStatus]); + + return ( + <> + {sortedList.slice(0, limit).map((wallet) => { + const address = getAddress({ + connectedWallets, + walletType: wallet.type, + chain, + }); + const conciseAddress = address + ? getConciseAddress(address, ACCOUNT_ADDRESS_MAX_CHARACTERS) + : ''; + + const experimentalChain = isExperimentalChain(blockchains(), chain); + + const experimentalChainNotAdded = !connectedWallets.find( + (connectedWallet) => + connectedWallet.walletType === wallet.type && + connectedWallet.chain === chain + ); + + const couldAddExperimentalChain = + experimentalChain && + experimentalChainNotAdded && + wallet.state === WalletState.CONNECTED; + + const connectedWalletDescription = couldAddExperimentalChain + ? i18n.t({ + id: 'Add {chain} chain', + values: { chain }, + }) + : conciseAddress; + + const onSelectableWalletClick = async () => { + const isDisconnected = wallet.state === WalletState.DISCONNECTED; + const isConnectedButDifferentThanTargetNamespace = wallet.isHub + ? !conciseAddress + : !!wallet.needsNamespace && !conciseAddress; + + if (isDisconnected) { + setSelectedWalletToConnect(wallet); + } else if (isConnectedButDifferentThanTargetNamespace) { + // wallet is connected on a different namespace + await handleDisconnect(wallet.type); + + setSelectedWalletToConnect(wallet); + } else if (couldAddExperimentalChain) { + setExperimentalChainWallet({ + walletType: wallet.type, + chain, + address: address ?? '', + }); + setShowExperimentalChainModal(true); + } else { + selectWallet({ + walletType: wallet.type, + chain, + address: address ?? '', + }); + } + }; + + const blockchainDisplayName: string | undefined = + experimentalChainWallet?.chain + ? getBlockchainDisplayNameFor( + experimentalChainWallet.chain, + blockchains() + ) + : undefined; + return ( + + {!!experimentalChainWallet && ( + { + setExperimentalChainWallet(null); + }}> + { + void addExperimentalChain(experimentalChainWallet); + }} + /> + + )} + {addingExperimentalChainStatus && ( + + + + + )} + + + ); + })} + { + setSelectedWalletToConnect(undefined); + }} + onConnect={(result) => { + if (props.onConnect && result.status === ResultStatus.Connected) { + if (selectedWalletToConnect?.type) { + props.onConnect(selectedWalletToConnect.type); + } else { + warn( + new Error( + "The selected wallet hasn't been detected after the connection process finished. It usually shouldn't happen." + ) + ); + } + } + }} + /> + {shouldShowMoreWallets && ( + + + {i18n.t('Show more wallets')} + +  +{numberOfSupportedWallets - (limit ?? 0)} + + + + )} + + ); +} diff --git a/widget/embedded/src/components/ConfirmWalletsModal/WalletList.type.ts b/widget/embedded/src/components/ConfirmWalletsModal/WalletList.type.ts new file mode 100644 index 0000000000..a3966c71be --- /dev/null +++ b/widget/embedded/src/components/ConfirmWalletsModal/WalletList.type.ts @@ -0,0 +1,10 @@ +import type { Wallet } from '../../types'; + +export type PropTypes = { + chain: string; + isSelected: (walletType: string, chain: string) => boolean; + selectWallet: (wallet: Wallet) => void; + limit?: number; + onShowMore: () => void; + onConnect?: (walletType: string) => void; +}; diff --git a/widget/embedded/src/components/CustomCollapsible/CustomCollapsible.styles.ts b/widget/embedded/src/components/CustomCollapsible/CustomCollapsible.styles.ts new file mode 100644 index 0000000000..b87449de13 --- /dev/null +++ b/widget/embedded/src/components/CustomCollapsible/CustomCollapsible.styles.ts @@ -0,0 +1,76 @@ +import * as Collapsible from '@radix-ui/react-collapsible'; +import { keyframes, styled } from '@rango-dev/ui'; + +export const EXPANDABLE_TRANSITION_DURATION = 300; + +const slideDown = keyframes({ + from: { + height: 0, + }, + to: { + height: 'var(--radix-collapsible-content-height)', + }, +}); + +const slideUp = keyframes({ + from: { + height: 'var(--radix-collapsible-content-height)', + }, + to: { + height: 0, + }, +}); + +export const CollapsibleRoot = styled(Collapsible.Root, { + borderRadius: '$sm', + overflow: 'hidden', + variants: { + selected: { + true: { + outlineWidth: 1, + outlineColor: '$secondary500', + outlineStyle: 'solid', + }, + }, + }, +}); + +export const Trigger = styled(Collapsible.Trigger, { + padding: '$0', + border: 'none', + outline: 'none', + width: '100%', + backgroundColor: 'transparent', + fontFamily: 'inherit', + cursor: 'pointer', +}); + +export const CollapsibleContent = styled(Collapsible.Content, { + overflow: 'hidden', + variants: { + open: { + true: { + animation: `${slideDown} ${EXPANDABLE_TRANSITION_DURATION}ms ease-out`, + }, + false: { + animation: `${slideUp} ${EXPANDABLE_TRANSITION_DURATION}ms ease-out`, + }, + }, + }, +}); + +export const ExpandedIcon = styled('div', { + transition: `all ${EXPANDABLE_TRANSITION_DURATION}ms ease`, + display: 'flex', + alignItems: 'center', + variants: { + orientation: { + down: { + transform: 'rotate(0)', + }, + up: { + transform: 'rotate(180deg)', + }, + }, + }, +}); diff --git a/widget/embedded/src/components/CustomCollapsible/CustomCollapsible.tsx b/widget/embedded/src/components/CustomCollapsible/CustomCollapsible.tsx new file mode 100644 index 0000000000..5202ca63b9 --- /dev/null +++ b/widget/embedded/src/components/CustomCollapsible/CustomCollapsible.tsx @@ -0,0 +1,46 @@ +import type { PropTypes } from './CustomCollapsible.types'; +import type { PropsWithChildren } from 'react'; + +import React, { useRef } from 'react'; + +import { + CollapsibleContent, + CollapsibleRoot, + Trigger, +} from './CustomCollapsible.styles'; + +export function CustomCollapsible(props: PropsWithChildren) { + const { + open, + hasSelected, + onOpenChange, + children, + onClickTrigger, + trigger, + triggerAnchor, + } = props; + const ref = useRef(null); + + return ( + + {triggerAnchor === 'top' && ( + + {trigger} + + )} + + {children} + + {triggerAnchor === 'bottom' && ( + + {trigger} + + )} + + ); +} diff --git a/widget/embedded/src/components/CustomCollapsible/CustomCollapsible.types.ts b/widget/embedded/src/components/CustomCollapsible/CustomCollapsible.types.ts new file mode 100644 index 0000000000..57e6d9741e --- /dev/null +++ b/widget/embedded/src/components/CustomCollapsible/CustomCollapsible.types.ts @@ -0,0 +1,10 @@ +import type { ReactNode } from 'react'; + +export type PropTypes = { + open: boolean; + hasSelected?: boolean; + onOpenChange?: (checked: boolean) => void; + onClickTrigger: () => void; + trigger: ReactNode; + triggerAnchor: 'top' | 'bottom'; +}; diff --git a/widget/embedded/src/components/CustomDestination/CustomDestination.styles.ts b/widget/embedded/src/components/CustomDestination/CustomDestination.styles.ts new file mode 100644 index 0000000000..21481a2ee3 --- /dev/null +++ b/widget/embedded/src/components/CustomDestination/CustomDestination.styles.ts @@ -0,0 +1,45 @@ +import { darkTheme, styled, TextField } from '@rango-dev/ui'; + +export const Container = styled('div', { + padding: '$10 $0', + '& .button__content': { + display: 'flex', + alignItems: 'center', + }, + '& .alarms': { paddingTop: '$5' }, + '& .collapsible_content': { + backgroundColor: '$neutral100', + }, + '& .collapsible_root': { + backgroundColor: '$neutral100', + }, +}); + +export const StyledTextField = styled(TextField, { + backgroundColor: '$neutral100', + padding: '$15', +}); + +export const CustomDestinationButton = styled('div', { + width: '100%', + borderRadius: '$sm', + display: 'flex', + padding: '$15', + justifyContent: 'space-between', + alignItems: 'center', + $$color: '$colors$neutral100', + [`.${darkTheme} &`]: { + $$color: '$colors$neutral300', + }, + backgroundColor: '$$color', + borderBottomRightRadius: '0', + borderBottomLeftRadius: '0', + '&:focus-visible': { + $$background: '$colors$secondary100', + [`.${darkTheme} &`]: { + $$background: '$colors$info700', + }, + backgroundColor: '$$background', + outline: 0, + }, +}); diff --git a/widget/embedded/src/components/CustomDestination/CustomDestination.tsx b/widget/embedded/src/components/CustomDestination/CustomDestination.tsx new file mode 100644 index 0000000000..f84e3e7a9a --- /dev/null +++ b/widget/embedded/src/components/CustomDestination/CustomDestination.tsx @@ -0,0 +1,156 @@ +import type { PropTypes } from './CustomDestination.types'; +import type { MouseEvent } from 'react'; + +import { i18n } from '@lingui/core'; +import { + Alert, + ChevronDownIcon, + CloseIcon, + Divider, + IconButton, + PasteIcon, + Typography, + WalletIcon, +} from '@rango-dev/ui'; +import React, { useEffect, useRef } from 'react'; + +import { useAppStore } from '../../store/AppStore'; +import { useQuoteStore } from '../../store/quote'; +import { + getBlockchainDisplayNameFor, + isValidTokenAddress, +} from '../../utils/meta'; +import { CustomCollapsible } from '../CustomCollapsible/CustomCollapsible'; +import { ExpandedIcon } from '../CustomCollapsible/CustomCollapsible.styles'; + +import { + Container, + CustomDestinationButton, + StyledTextField, +} from './CustomDestination.styles'; + +export function CustomDestination(props: PropTypes) { + const { blockchain, handleOpenChange, open } = props; + + const { customDestination, setCustomDestination } = useQuoteStore(); + const { config } = useAppStore(); + const blockchains = useAppStore().blockchains(); + const blockchainName = getBlockchainDisplayNameFor( + blockchain.name, + blockchains + ); + const inputRef = useRef(null); + const configDestination = + config?.defaultCustomDestinations?.[blockchain.name]; + + const isFirefox = navigator?.userAgent.includes('Firefox'); + const isAddressChecked = open && !!customDestination && blockchain; + const isAddressInvalid = + isAddressChecked && !isValidTokenAddress(blockchain, customDestination); + const handleClear = () => { + setCustomDestination(''); + }; + + const handlePaste = async (event: MouseEvent) => { + event.preventDefault(); + if (navigator.clipboard !== undefined) { + const pastedText = await navigator.clipboard.readText(); + setCustomDestination(pastedText); + inputRef?.current?.focus(); + } + }; + + const renderSuffix = () => { + if (customDestination) { + return ( + + + + ); + } else if (!isFirefox) { + return ( + + + + ); + } + + return null; + }; + + useEffect(() => { + const shouldUseConfigDestination = + !!configDestination && customDestination === null; + + if (shouldUseConfigDestination) { + setCustomDestination(configDestination); + handleOpenChange(true); + } + }, [configDestination]); + + return ( + + +
+ + + + {i18n.t('Send to a different address')} + +
+ + + + + } + onClickTrigger={() => handleOpenChange(!open)}> + { + const customDestination = e.target.value; + setCustomDestination(customDestination); + }} + /> +
+ + {isAddressInvalid && ( + <> + + + + )} +
+ ); +} diff --git a/widget/embedded/src/components/CustomDestination/CustomDestination.types.ts b/widget/embedded/src/components/CustomDestination/CustomDestination.types.ts new file mode 100644 index 0000000000..457397157b --- /dev/null +++ b/widget/embedded/src/components/CustomDestination/CustomDestination.types.ts @@ -0,0 +1,7 @@ +import type { BlockchainMeta } from 'rango-types'; + +export type PropTypes = { + blockchain: BlockchainMeta; + handleOpenChange: (open: boolean) => void; + open: boolean; +}; diff --git a/widget/embedded/src/components/CustomTokenModal/CustomTokenModal.helpers.ts b/widget/embedded/src/components/CustomTokenModal/CustomTokenModal.helpers.ts new file mode 100644 index 0000000000..1d7a4cba3e --- /dev/null +++ b/widget/embedded/src/components/CustomTokenModal/CustomTokenModal.helpers.ts @@ -0,0 +1,19 @@ +import type { BlockchainMeta } from 'rango-types'; + +export function generateExplorerLink( + address: string | null, + blockchain: BlockchainMeta +): string { + // We don't have Cosmos explorer url in API. + if (blockchain.type === 'COSMOS') { + return ''; + } + + const explorerLinkPattern = blockchain.info?.addressUrl; + + if (!explorerLinkPattern || !address) { + return ''; + } + + return explorerLinkPattern.replace('{wallet}', address); +} diff --git a/widget/embedded/src/components/CustomTokenModal/CustomTokenModal.styles.ts b/widget/embedded/src/components/CustomTokenModal/CustomTokenModal.styles.ts new file mode 100644 index 0000000000..d8bc040646 --- /dev/null +++ b/widget/embedded/src/components/CustomTokenModal/CustomTokenModal.styles.ts @@ -0,0 +1,57 @@ +import { darkTheme, styled } from '@rango-dev/ui'; + +export const StyledLink = styled('a', { + textDecoration: 'none', + color: '$colors$neutral700', + [`.${darkTheme} &`]: { + color: '$colors$neutral900', + }, + + '& svg': { + marginLeft: '$4', + color: '$colors$neutral700', + [`.${darkTheme} &`]: { + color: '$colors$neutral900', + }, + }, + + variants: { + hasHover: { + true: { + '&:hover': { + color: '$colors$secondary550', + [`.${darkTheme} &`]: { + color: '$colors$secondary500', + }, + '& svg': { + color: '$colors$secondary550', + [`.${darkTheme} &`]: { + color: '$colors$secondary500', + }, + }, + }, + }, + false: {}, + }, + }, +}); + +export const Container = styled('div', { + display: 'flex', + justifyContent: 'center', + flexDirection: 'column', + alignItems: 'center', + textAlign: 'center', + '& ._blockchain-name, & ._coin-source': { + color: '$colors$neutral600', + [`.${darkTheme} &`]: { + color: '$colors$neutral800', + }, + }, + '& ._coin-source-name, & ._custom-token-description': { + color: '$colors$neutral700', + [`.${darkTheme} &`]: { + color: '$colors$neutral900', + }, + }, +}); diff --git a/widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx b/widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx new file mode 100644 index 0000000000..8b3e330bde --- /dev/null +++ b/widget/embedded/src/components/CustomTokenModal/CustomTokenModal.tsx @@ -0,0 +1,93 @@ +import type { PropTypes } from './CustomTokenModal.types'; + +import { i18n } from '@lingui/core'; +import { + Button, + Divider, + ExternalLinkIcon, + Image, + Typography, +} from '@rango-dev/ui'; +import React from 'react'; + +import { getContainer } from '../../utils/common'; +import { WatermarkedModal } from '../common/WatermarkedModal'; + +import { generateExplorerLink } from './CustomTokenModal.helpers'; +import { Container, StyledLink } from './CustomTokenModal.styles'; + +export function CustomTokenModal(props: PropTypes) { + const { open, onClose, token, onSubmitClick, blockchain } = props; + + const explorerLink = generateExplorerLink(token.address, blockchain); + + return ( + + + + + {token.name} + + + {blockchain.displayName} + + + + + {!!explorerLink ? ( + + {token.address} + + + ) : ( + {token.address} + )} + + + + + {token.coinSource && ( + + {i18n.t('via')}{' '} + + {token.coinSource} + + + )} + + + + {i18n.t( + `This token doesn't appear on the active token list(s). Make sure this is the token that you want to trade.` + )} + + + + + + + + ); +} diff --git a/widget/embedded/src/components/CustomTokenModal/CustomTokenModal.types.ts b/widget/embedded/src/components/CustomTokenModal/CustomTokenModal.types.ts new file mode 100644 index 0000000000..a7f58d9666 --- /dev/null +++ b/widget/embedded/src/components/CustomTokenModal/CustomTokenModal.types.ts @@ -0,0 +1,9 @@ +import type { BlockchainMeta, Token } from 'rango-sdk'; + +export type PropTypes = { + open: boolean; + onClose: () => void; + onSubmitClick: () => void; + token: Token; + blockchain: BlockchainMeta; +}; diff --git a/widget/embedded/src/components/CustomTokenModal/index.ts b/widget/embedded/src/components/CustomTokenModal/index.ts new file mode 100644 index 0000000000..742d179c15 --- /dev/null +++ b/widget/embedded/src/components/CustomTokenModal/index.ts @@ -0,0 +1 @@ +export { CustomTokenModal } from './CustomTokenModal'; diff --git a/widget/embedded/src/components/FilterSelector/FilterSelector.style.ts b/widget/embedded/src/components/FilterSelector/FilterSelector.style.ts new file mode 100644 index 0000000000..7816502c1d --- /dev/null +++ b/widget/embedded/src/components/FilterSelector/FilterSelector.style.ts @@ -0,0 +1,95 @@ +import { css, darkTheme, IconButton, styled } from '@rango-dev/ui'; + +export const IconContainer = styled('div', { + position: 'relative', + '&::before': { + position: 'absolute', + right: '1px', + top: '-1px', + width: '$8', + height: '$8', + borderRadius: '100%', + backgroundColor: '$neutral300', + [`.${darkTheme} &`]: { + backgroundColor: '$neutral400', + }, + padding: '$2', + }, + variants: { + isSelect: { + true: { + '&::before': { + content: '', + }, + }, + }, + }, +}); + +export const FilterButton = styled(IconButton, { + width: '$36', + height: '$36', + position: 'relative', + padding: '0', + overflow: 'unset', + backgroundColor: '$neutral300', + [`.${darkTheme} &`]: { + backgroundColor: '$neutral400', + }, + '&:hover': { + backgroundColor: '$secondary100', + [`.${darkTheme} &`]: { + backgroundColor: '$neutral', + }, + [`& ${IconContainer}::before`]: { + backgroundColor: '$secondary100', + [`.${darkTheme} &`]: { + backgroundColor: '$neutral', + }, + }, + }, + variants: { + isSelect: { + true: { + border: '1px solid $secondary', + }, + }, + }, +}); + +export const Badge = styled('div', { + position: 'absolute', + width: '$6', + height: '$6', + display: 'flex', + justifyContent: 'center', + alignItems: 'center', + borderRadius: '3px', + top: '$0', + right: '1px', + backgroundColor: '$secondary500', +}); + +export const FilterContainer = styled('div', { + padding: '$15', + borderRadius: '$sm', + width: '248px', + backgroundColor: '$background', + zIndex: 10, +}); + +export const centeredFlexContainer = css({ + display: 'flex', + justifyContent: 'space-between', + alignItems: 'center', +}); + +export const FilterList = styled('ul', { + margin: 0, + listStyle: 'none', + height: '100%', + padding: 0, + '.item-start-container': { + paddingRight: '0 !important', + }, +}); diff --git a/widget/embedded/src/components/FilterSelector/FilterSelector.tsx b/widget/embedded/src/components/FilterSelector/FilterSelector.tsx new file mode 100644 index 0000000000..5571a98ffe --- /dev/null +++ b/widget/embedded/src/components/FilterSelector/FilterSelector.tsx @@ -0,0 +1,43 @@ +import type { FilterSelectorPropTypes } from './FilterSelector.type'; + +import { FilterIcon, Popover } from '@rango-dev/ui'; +import React from 'react'; + +import { getContainer } from '../../utils/common'; + +import { Badge, FilterButton, IconContainer } from './FilterSelector.style'; +import { FilterSelectorContent } from './FilterSelectorContent'; + +export function FilterSelector(props: FilterSelectorPropTypes) { + const { onClickItem, onOpenChange, filterBy, list, open } = props; + return ( +
+ { + onClickItem(id); + onOpenChange(false); + }} + /> + }> + onOpenChange(!props.open)}> + + + {!!filterBy && } + + + +
+ ); +} diff --git a/widget/embedded/src/components/FilterSelector/FilterSelector.type.ts b/widget/embedded/src/components/FilterSelector/FilterSelector.type.ts new file mode 100644 index 0000000000..a1a8595616 --- /dev/null +++ b/widget/embedded/src/components/FilterSelector/FilterSelector.type.ts @@ -0,0 +1,15 @@ +export type PropTypes = { + filterBy: string; + onClickItem: (id: string) => void; + list: Array; +}; + +export type FilterItem = { + id: string; + title: string; +}; + +export type FilterSelectorPropTypes = PropTypes & { + open: boolean; + onOpenChange: (open: boolean) => void; +}; diff --git a/widget/embedded/src/components/FilterSelector/FilterSelectorContent.tsx b/widget/embedded/src/components/FilterSelector/FilterSelectorContent.tsx new file mode 100644 index 0000000000..9aaf7574c9 --- /dev/null +++ b/widget/embedded/src/components/FilterSelector/FilterSelectorContent.tsx @@ -0,0 +1,64 @@ +import type { PropTypes } from './FilterSelector.type'; + +import { i18n } from '@lingui/core'; +import { + Button, + Divider, + ListItemButton, + Radio, + RadioRoot, + Typography, +} from '@rango-dev/ui'; +import React from 'react'; + +import { + centeredFlexContainer, + FilterContainer, + FilterList, +} from './FilterSelector.style'; + +export function FilterSelectorContent(props: PropTypes) { + const { filterBy: value, onClickItem } = props; + return ( + +
+ + {i18n.t('Status')} + + +
+ + + + {props.list.map((item, index) => { + return ( + + + + {item.title} + + + } + start={} + onClick={onClickItem} + /> + ); + })} + + +
+ ); +} diff --git a/widget/embedded/src/components/FilterSelector/index.ts b/widget/embedded/src/components/FilterSelector/index.ts new file mode 100644 index 0000000000..ef5657e33c --- /dev/null +++ b/widget/embedded/src/components/FilterSelector/index.ts @@ -0,0 +1 @@ +export { FilterSelector } from './FilterSelector'; diff --git a/widget/embedded/src/components/Footer.tsx b/widget/embedded/src/components/Footer.tsx deleted file mode 100644 index 09472aa4ea..0000000000 --- a/widget/embedded/src/components/Footer.tsx +++ /dev/null @@ -1,8 +0,0 @@ -import { styled } from '@rango-dev/ui'; - -export const Footer = styled('div', { - display: 'flex', - flexDirection: 'column', - width: '100%', - paddingTop: '$16', -}); diff --git a/widget/embedded/src/components/HeaderButtons.tsx b/widget/embedded/src/components/HeaderButtons.tsx deleted file mode 100644 index d6df331555..0000000000 --- a/widget/embedded/src/components/HeaderButtons.tsx +++ /dev/null @@ -1,54 +0,0 @@ -import React from 'react'; -import { - SettingsIcon, - Tooltip, - styled, - Button, - HistoryIcon, - RetryIcon, -} from '@rango-dev/ui'; -import { useNavigate } from 'react-router-dom'; -import { navigationRoutes } from '../constants/navigationRoutes'; - -const ButtonsContainer = styled('div', { - display: 'flex', -}); - -interface PropTypes { - onClickRefresh?: () => void; -} - -export function HeaderButtons(props: PropTypes) { - const { onClickRefresh } = props; - const navigate = useNavigate(); - - return ( - - - - - - - - - - - - ); -} diff --git a/widget/embedded/src/components/HeaderButtons/BackButton.tsx b/widget/embedded/src/components/HeaderButtons/BackButton.tsx new file mode 100644 index 0000000000..e7e8f007c4 --- /dev/null +++ b/widget/embedded/src/components/HeaderButtons/BackButton.tsx @@ -0,0 +1,20 @@ +import type { PropTypes } from './HeaderButtons.types'; + +import { ChevronLeftIcon } from '@rango-dev/ui'; +import React from 'react'; + +import { HeaderButton } from './HeaderButtons.styles'; + +function BackButton(props: PropTypes) { + return ( + + + + ); +} + +export { BackButton }; diff --git a/widget/embedded/src/components/HeaderButtons/CancelButton.tsx b/widget/embedded/src/components/HeaderButtons/CancelButton.tsx new file mode 100644 index 0000000000..13baf1df16 --- /dev/null +++ b/widget/embedded/src/components/HeaderButtons/CancelButton.tsx @@ -0,0 +1,25 @@ +import type { PropTypes } from './HeaderButtons.types'; + +import { i18n } from '@lingui/core'; +import { Button, Typography } from '@rango-dev/ui'; +import React from 'react'; + +import { SuffixContainer } from './HeaderButtons.styles'; + +function CancelButton(props: PropTypes) { + return ( + + + + ); +} + +export { CancelButton }; diff --git a/widget/embedded/src/components/HeaderButtons/HeaderButtons.styles.ts b/widget/embedded/src/components/HeaderButtons/HeaderButtons.styles.ts new file mode 100644 index 0000000000..8bb9bb1873 --- /dev/null +++ b/widget/embedded/src/components/HeaderButtons/HeaderButtons.styles.ts @@ -0,0 +1,96 @@ +import { css, darkTheme, IconButton, styled } from '@rango-dev/ui'; + +export const HeaderButton = styled(IconButton, { + width: '$24', + position: 'relative', + padding: '0', + overflow: 'unset', + '&:hover': { + backgroundColor: '$secondary100', + [`.${darkTheme} &`]: { + backgroundColor: '$neutral', + }, + }, +}); + +export const ConnectedIcon = styled('div', { + position: 'absolute', + background: '$secondary500', + [`.${darkTheme} &`]: { + $$color: '$colors$secondary250', + }, + width: '$6', + height: '$6', + borderRadius: '$lg', + right: '$4', + border: '1px solid $surface100', +}); + +export const SuffixContainer = styled('div', { + display: 'flex', + justifyContent: 'flex-end', + minWidth: '$40', + button: { + padding: 0, + }, +}); + +export const NotificationsBadgeContainer = styled('div', { + position: 'absolute', + width: '14px', + height: '14px', + display: 'flex', + justifyContent: 'center', + alignItems: 'center', + borderRadius: '7px', + top: '$0', + right: '$0', + variants: { + isSever: { + true: { + backgroundColor: '$error500', + }, + false: { + backgroundColor: '$secondary500', + }, + }, + }, +}); + +export const ProgressIcon = styled('div', { + padding: '$2', + variants: { + isRefetched: { + true: { + transform: `rotate(360deg)`, + transition: 'transform 1s ease-in-out', + }, + }, + }, +}); + +export const InProgressTransactionBadgeContainer = styled('div', { + position: 'absolute', + right: '$4', + top: '$4', + backgroundColor: '$background', + borderRadius: '100%', +}); + +export const rowStyles = css({ + display: 'flex', + flexDirection: 'row', + justifyContent: 'center', + alignItems: 'center', +}); + +export const WalletImageContainer = styled('div', { + borderRadius: '100%', + border: '1.5px transparent solid', + '&:not(:first-child)': { + marginLeft: '-$6', + }, + img: { + borderRadius: '100%', + }, +}); diff --git a/widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx b/widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx new file mode 100644 index 0000000000..dd0405c8ba --- /dev/null +++ b/widget/embedded/src/components/HeaderButtons/HeaderButtons.tsx @@ -0,0 +1,106 @@ +import type { HeaderButtonsPropTypes } from './HeaderButtons.types'; + +import { i18n } from '@lingui/core'; +import { + NotificationsIcon, + Popover, + SettingsIcon, + Tooltip, + TransactionIcon, +} from '@rango-dev/ui'; +import React from 'react'; + +import { useAppStore } from '../../store/AppStore'; +import { getContainer } from '../../utils/common'; +import { isFeatureHidden } from '../../utils/settings'; +import { NotificationContent } from '../NotificationContent'; + +import { HeaderButton } from './HeaderButtons.styles'; +import InProgressTransactionBadge from './InProgressTransactionBadge'; +import { NotificationsBadge } from './NotificationsBadge'; +import { RefreshButton } from './RefreshButton'; + +export function HeaderButtons(props: HeaderButtonsPropTypes) { + const { + onClickRefresh, + onClickHistory, + onClickSettings, + hidden = [], + container, + } = props; + + const { + config: { features }, + } = useAppStore(); + + const isNotificationsHidden = + isFeatureHidden('notification', features) || + hidden.includes('notifications'); + + return ( + <> + {!hidden.includes('refresh') && ( + + + + )} + + {!isNotificationsHidden && ( + }> +
+ + + + + + +
+
+ )} + {!hidden.includes('settings') && ( + + + + + + )} + {!hidden.includes('history') && ( + + + + + + + )} + + ); +} diff --git a/widget/embedded/src/components/HeaderButtons/HeaderButtons.types.ts b/widget/embedded/src/components/HeaderButtons/HeaderButtons.types.ts new file mode 100644 index 0000000000..f079d6d2ac --- /dev/null +++ b/widget/embedded/src/components/HeaderButtons/HeaderButtons.types.ts @@ -0,0 +1,12 @@ +export interface PropTypes { + onClick: () => void; + isConnected?: boolean; + container?: HTMLElement; +} +export interface HeaderButtonsPropTypes { + onClickSettings?: () => void; + onClickRefresh?: () => void; + onClickHistory?: () => void; + hidden?: ('settings' | 'refresh' | 'history' | 'notifications')[]; + container?: HTMLElement; +} diff --git a/widget/embedded/src/components/HeaderButtons/InProgressTransactionBadge.tsx b/widget/embedded/src/components/HeaderButtons/InProgressTransactionBadge.tsx new file mode 100644 index 0000000000..3375734aed --- /dev/null +++ b/widget/embedded/src/components/HeaderButtons/InProgressTransactionBadge.tsx @@ -0,0 +1,26 @@ +import type { PendingSwap } from 'rango-types'; + +import { useManager } from '@rango-dev/queue-manager-react'; +import { InProgressIcon } from '@rango-dev/ui'; +import React from 'react'; + +import { getPendingSwaps } from '../../utils/queue'; + +import { InProgressTransactionBadgeContainer } from './HeaderButtons.styles'; + +const InProgressTransactionBadge = () => { + const { manager } = useManager(); + const list: PendingSwap[] = getPendingSwaps(manager).map(({ swap }) => swap); + + if (!list.find((swap) => swap.status === 'running')) { + return null; + } + + return ( + + + + ); +}; + +export default InProgressTransactionBadge; diff --git a/widget/embedded/src/components/HeaderButtons/NotificationsBadge.tsx b/widget/embedded/src/components/HeaderButtons/NotificationsBadge.tsx new file mode 100644 index 0000000000..279593fa09 --- /dev/null +++ b/widget/embedded/src/components/HeaderButtons/NotificationsBadge.tsx @@ -0,0 +1,28 @@ +import { EventSeverity } from '@rango-dev/queue-manager-rango-preset'; +import { Typography } from '@rango-dev/ui'; +import React from 'react'; + +import { useNotificationStore } from '../../store/notification'; + +import { NotificationsBadgeContainer } from './HeaderButtons.styles'; + +export function NotificationsBadge() { + const { getNotifications } = useNotificationStore(); + + const notificationsList = getNotifications(); + + const notificationsCount = notificationsList.length; + + const hasSeverNotification = !!notificationsList.find( + (notificationItem) => + notificationItem.event.messageSeverity === EventSeverity.WARNING + ); + + return notificationsCount ? ( + + + {notificationsCount} + + + ) : null; +} diff --git a/widget/embedded/src/components/HeaderButtons/RefreshButton.tsx b/widget/embedded/src/components/HeaderButtons/RefreshButton.tsx new file mode 100644 index 0000000000..0fcdf8b3ac --- /dev/null +++ b/widget/embedded/src/components/HeaderButtons/RefreshButton.tsx @@ -0,0 +1,83 @@ +import { RefreshProgressButton } from '@rango-dev/ui'; +import React, { useEffect, useState } from 'react'; + +import { HeaderButton, ProgressIcon } from './HeaderButtons.styles'; + +const REFRESH_INTERVAL = 1000; +const MAX_ELAPSED_TIME = 60; +const MAX_PERCENTAGE = 100; + +function RefreshButton({ onClick }: { onClick: (() => void) | undefined }) { + const [elapsedTime, setElapsedTime] = useState(0); + const [isRefetched, setIsRefetched] = useState(false); + + const handleVisibilityChange = (interval?: number) => { + if (document.hidden && interval) { + // Tab is inactive, clear the interval + clearTimeout(interval); + } + }; + + useEffect(() => { + let interval: number | undefined; + if (onClick) { + interval = window.setInterval(() => { + setElapsedTime((prevTime) => prevTime + 1); + + if (elapsedTime === MAX_ELAPSED_TIME) { + handleRefreshClick(); + } + }, REFRESH_INTERVAL); + } else { + clearTimeout(interval); + } + + document.addEventListener('visibilitychange', () => + handleVisibilityChange(interval) + ); + + return () => { + document.removeEventListener('visibilitychange', () => + handleVisibilityChange(interval) + ); + if (interval) { + clearInterval(interval); + } + }; + }, [elapsedTime, onClick]); + + const clearTimeout = (interval?: number) => { + if (interval) { + clearInterval(interval); + } + setElapsedTime(0); + }; + + const handleRefreshClick = () => { + onClick?.(); + setElapsedTime(0); + setIsRefetched(true); + }; + + return ( + + setIsRefetched(false)} + isRefetched={isRefetched}> + + + + ); +} + +export { RefreshButton }; diff --git a/widget/embedded/src/components/HeaderButtons/WalletButton.tsx b/widget/embedded/src/components/HeaderButtons/WalletButton.tsx new file mode 100644 index 0000000000..0bbdacc500 --- /dev/null +++ b/widget/embedded/src/components/HeaderButtons/WalletButton.tsx @@ -0,0 +1,47 @@ +import type { PropTypes } from './HeaderButtons.types'; + +import { i18n } from '@lingui/core'; +import { Image, Tooltip, WalletIcon } from '@rango-dev/ui'; +import React from 'react'; + +import { useWalletList } from '../../hooks/useWalletList'; + +import { + ConnectedIcon, + HeaderButton, + rowStyles, + WalletImageContainer, +} from './HeaderButtons.styles'; + +function WalletButton(props: PropTypes) { + const { list } = useWalletList(); + const connectedWallets = list.filter( + (wallet) => wallet.state === 'connected' + ); + const content = !connectedWallets.length ? ( + i18n.t('Connect Wallet') + ) : ( +
+ {connectedWallets.map((wallet) => ( + + + + ))} +
+ ); + + return ( + + + {props.isConnected && } + + + + ); +} + +export { WalletButton }; diff --git a/widget/embedded/src/components/HeaderButtons/index.ts b/widget/embedded/src/components/HeaderButtons/index.ts new file mode 100644 index 0000000000..2f703aedef --- /dev/null +++ b/widget/embedded/src/components/HeaderButtons/index.ts @@ -0,0 +1,4 @@ +export { BackButton } from './BackButton'; +export { CancelButton } from './CancelButton'; +export { WalletButton } from './WalletButton'; +export { HeaderButtons } from './HeaderButtons'; diff --git a/widget/embedded/src/components/HistoryGroupedList/HistoryGroupedList.helpers.ts b/widget/embedded/src/components/HistoryGroupedList/HistoryGroupedList.helpers.ts new file mode 100644 index 0000000000..7b8c375326 --- /dev/null +++ b/widget/embedded/src/components/HistoryGroupedList/HistoryGroupedList.helpers.ts @@ -0,0 +1,17 @@ +/* + * The calculateGroupsSoFar Slices the total groups into the groups which contain the items so far. + * For example, if you have [10, 10, 10, 10] groups in total, + * slicing them to 23 will result in [10, 10, 3] : + * https://virtuoso.dev/grouped-with-load-on-demand/ + */ +export function calculateGroupsSoFar(totalGroups: number[], count: number) { + const groups: number[] = []; + let index = 0; + do { + const group = totalGroups[index]; + groups.push(Math.min(group, count)); + count -= group; + index++; + } while (count > 0 && index <= totalGroups.length); + return groups; +} diff --git a/widget/embedded/src/components/HistoryGroupedList/HistoryGroupedList.styles.ts b/widget/embedded/src/components/HistoryGroupedList/HistoryGroupedList.styles.ts new file mode 100644 index 0000000000..146c917958 --- /dev/null +++ b/widget/embedded/src/components/HistoryGroupedList/HistoryGroupedList.styles.ts @@ -0,0 +1,44 @@ +import { css, darkTheme, styled } from '@rango-dev/ui'; + +export const groupStyles = css(); + +export const SwapItemContainer = styled('div', { + display: 'flex', + justifyContent: 'center', + alignItems: 'center', + padding: '$5', +}); + +export const Group = styled('div', { + width: '100%', + display: 'flex', + flexDirection: 'column', + backgroundColor: '$background', + padding: '$10 $5 0 $5', + [`& .${groupStyles}`]: { + $$color: '$colors$neutral600', + [`.${darkTheme} &`]: { + $$color: '$colors$neutral700', + }, + color: '$$color', + }, +}); + +export const Time = styled('div', { + display: 'flex', + justifyContent: 'flex-start', + padding: '$2', +}); + +export const SwapList = styled('div', { + gap: '$10', + display: 'flex', + flexDirection: 'column', +}); + +export const NotFoundContainer = styled('div', { + height: '100%', + display: 'flex', + justifyContent: 'center', + alignItems: 'center', +}); diff --git a/widget/embedded/src/components/HistoryGroupedList/HistoryGroupedList.tsx b/widget/embedded/src/components/HistoryGroupedList/HistoryGroupedList.tsx new file mode 100644 index 0000000000..2ca56f45f0 --- /dev/null +++ b/widget/embedded/src/components/HistoryGroupedList/HistoryGroupedList.tsx @@ -0,0 +1,162 @@ +import type { PropTypes } from './HistoryGroupedList.types'; + +import { i18n } from '@lingui/core'; +import { + Divider, + GroupedVirtualizedList, + Skeleton, + SwapListItem, + Typography, +} from '@rango-dev/ui'; +import React, { useCallback, useEffect, useRef, useState } from 'react'; + +import { + TOKEN_AMOUNT_MAX_DECIMALS, + TOKEN_AMOUNT_MIN_DECIMALS, +} from '../../constants/routing'; +import { getContainer } from '../../utils/common'; +import { numberToString } from '../../utils/numbers'; + +import { calculateGroupsSoFar } from './HistoryGroupedList.helpers'; +import { + Group, + groupStyles, + SwapItemContainer, + SwapList, + Time, +} from './HistoryGroupedList.styles'; + +const ITEMS_PER_PAGE = 10; + +export function HistoryGroupedList(props: PropTypes) { + const { list, onSwapClick, groupBy, isLoading } = props; + const [currentGroupCounts, setCurrentGroupCounts] = useState([]); + const loadedItems = useRef(0); + const { swaps, groupCounts, groups } = groupBy(list); + + const calculateGroups = useCallback(calculateGroupsSoFar, []); + + const loadMore = useCallback(() => { + const remainedItems = list.length - loadedItems.current; + if (remainedItems) { + loadedItems.current += Math.min(remainedItems, ITEMS_PER_PAGE); + setCurrentGroupCounts(calculateGroups(groupCounts, loadedItems.current)); + } + }, [list.length]); + + useEffect(() => { + if (!isLoading) { + loadMore(); + } + }, [isLoading, loadMore]); + + if (isLoading) { + // The number of items presented in each group. + const swaps = [1, 2]; + const loadingGroups = [swaps, swaps]; + return ( + <> + {loadingGroups.map((group, index) => { + const key = index; + return ( + + + + + {group.map((_, index) => { + const key = index; + return ; + })} + + + ); + })} + + ); + } + + return ( + { + if (loadedItems.current < list.length) { + loadMore(); + } + }} + groupCounts={currentGroupCounts} + groupContent={(index) => { + return ( + + + + ); + }} + itemContent={(index, groupIndex) => { + const swap = swaps[index]; + if (!swap) { + return null; + } + const firstStep = swap.steps[0]; + const lastStep = swap.steps[swap.steps.length - 1]; + return ( + + + + ); + }} + /> + ); +} diff --git a/widget/embedded/src/components/HistoryGroupedList/HistoryGroupedList.types.ts b/widget/embedded/src/components/HistoryGroupedList/HistoryGroupedList.types.ts new file mode 100644 index 0000000000..80314ba150 --- /dev/null +++ b/widget/embedded/src/components/HistoryGroupedList/HistoryGroupedList.types.ts @@ -0,0 +1,14 @@ +import type { PendingSwap } from 'rango-types'; + +export type GroupBy = (list: PendingSwap[]) => { + swaps: PendingSwap[]; + groups: string[]; + groupCounts: number[]; +}; + +export interface PropTypes { + list: PendingSwap[]; + onSwapClick: (requestId: string) => void; + groupBy: GroupBy; + isLoading: boolean; +} diff --git a/widget/embedded/src/components/HistoryGroupedList/index.ts b/widget/embedded/src/components/HistoryGroupedList/index.ts new file mode 100644 index 0000000000..28510d8266 --- /dev/null +++ b/widget/embedded/src/components/HistoryGroupedList/index.ts @@ -0,0 +1 @@ +export { HistoryGroupedList } from './HistoryGroupedList'; diff --git a/widget/embedded/src/components/Layout.tsx b/widget/embedded/src/components/Layout.tsx deleted file mode 100644 index 0af10e788a..0000000000 --- a/widget/embedded/src/components/Layout.tsx +++ /dev/null @@ -1,138 +0,0 @@ -import { - Button, - AddWalletIcon, - Typography, - styled, - Spinner, -} from '@rango-dev/ui'; -import React, { useEffect } from 'react'; -import { useNavigate } from 'react-router-dom'; -import { useWallets } from '@rango-dev/wallets-core'; -import { navigationRoutes } from '../constants/navigationRoutes'; -import { useUiStore } from '../store/ui'; -import { AppRoutes } from './AppRoutes'; -import { fetchingBalanceSelector, useWalletsStore } from '../store/wallets'; -import { - calculateWalletUsdValue, - getSelectableWallets, - tokensAreEqual, -} from '../utils/wallets'; -import { removeDuplicateFrom } from '../utils/common'; -import { WidgetConfig } from '../types'; -import { useTranslation } from 'react-i18next'; -import { useBestRouteStore } from '../store/bestRoute'; -import { useMetaStore } from '../store/meta'; -import { useSettingsStore } from '../store/settings'; -import { Image } from '@rango-dev/ui'; - -const Header = styled('div', { - display: 'flex', - width: '100%', - justifyContent: 'end', - '.balance': { - display: 'flex', - }, -}); - -const WalletImageContainer = styled('div', { - marginLeft: -15, - marginRight: '$6', - borderRadius: '99999px', -}); - -export type LayoutProps = { - config?: WidgetConfig; -}; - -export function Layout({ config }: LayoutProps) { - const navigate = useNavigate(); - const { balances, accounts, selectedWallets } = useWalletsStore(); - const { getWalletInfo } = useWallets(); - const connectedWalletsImages = removeDuplicateFrom( - getSelectableWallets(accounts, selectedWallets, getWalletInfo).map( - (w) => w.image - ) - ); - const { blockchains, tokens } = useMetaStore.use.meta(); - const setFromChain = useBestRouteStore.use.setFromChain(); - const setFromToken = useBestRouteStore.use.setFromToken(); - const setToChain = useBestRouteStore.use.setToChain(); - const setToToken = useBestRouteStore.use.setToToken(); - const setInputAmount = useBestRouteStore.use.setInputAmount(); - const setAffiliateRef = useSettingsStore.use.setAffiliateRef(); - - const totalBalance = calculateWalletUsdValue(balances); - const connectWalletsButtonDisabled = - useUiStore.use.connectWalletsButtonDisabled(); - const loadingMetaStatus = useMetaStore.use.loadingStatus(); - const fetchingBalance = useWalletsStore(fetchingBalanceSelector); - - const { t } = useTranslation(); - useEffect(() => { - const chain = blockchains.find( - (chain) => chain.name === config?.to?.blockchain - ); - const token = tokens.find((t) => - tokensAreEqual(t, config?.to?.token || null) - ); - setToChain(chain || null); - setToToken(token || null); - }, [config?.to?.token, config?.to?.blockchain]); - - useEffect(() => { - setInputAmount(config?.amount?.toString() || ''); - }, [config?.amount]); - - useEffect(() => { - const chain = blockchains.find( - (chain) => chain.name === config?.from?.blockchain - ); - const token = tokens.find((t) => - tokensAreEqual(t, config?.from?.token || null) - ); - - setFromChain(chain || null); - setFromToken(token || null); - }, [config?.from?.token, config?.from?.blockchain]); - - useEffect(() => { - setAffiliateRef(config?.affiliateRef || null); - }, [config?.affiliateRef]); - return ( - <> -
- -
- - - ); -} diff --git a/widget/embedded/src/components/Layout/Layout.helpers.ts b/widget/embedded/src/components/Layout/Layout.helpers.ts new file mode 100644 index 0000000000..af2501710b --- /dev/null +++ b/widget/embedded/src/components/Layout/Layout.helpers.ts @@ -0,0 +1,16 @@ +import { getContainer } from '../../utils/common'; + +export function onScrollContentAttachStatusToContainer(e: Event) { + const contentElement = e.target as HTMLElement | null; + + if (contentElement) { + const fromTop = contentElement.scrollTop; + const container = getContainer(); + + if (fromTop > 1) { + container.classList.add('rng-scrolled'); + } else { + container.classList.remove('rng-scrolled'); + } + } +} diff --git a/widget/embedded/src/components/Layout/Layout.styles.ts b/widget/embedded/src/components/Layout/Layout.styles.ts new file mode 100644 index 0000000000..33df3ef782 --- /dev/null +++ b/widget/embedded/src/components/Layout/Layout.styles.ts @@ -0,0 +1,57 @@ +import { css, styled } from '@rango-dev/ui'; + +const WIDGET_HEIGHT = '700px'; + +export const LayoutContainer = css({ + borderRadius: '$primary', + display: 'flex', + flexDirection: 'column', + overflow: 'hidden', + boxShadow: '$mainContainer', +}); + +export const Container = styled('div', { + position: 'relative', + width: '100vw', + minWidth: '300px', + maxWidth: '390px', + backgroundColor: '$background', + variants: { + height: { + auto: { + height: 'auto', + maxHeight: WIDGET_HEIGHT, + }, + fixed: { + height: WIDGET_HEIGHT, + }, + }, + }, +}); + +export const Content = styled('div', { + position: 'relative', + overflow: 'hidden', + flexGrow: 1, + display: 'flex', + flexDirection: 'column', + padding: 0, + overflowY: 'auto', +}); + +export const Footer = styled('div', { + padding: '0 $20 $10', + '& .footer__alert': { + paddingTop: '$10', + }, + '& .footer__logo': { + opacity: 0, + transition: 'opacity 1s ease-in-out', + '&.logo__show': { + opacity: 1, + }, + '&.logo__hidden': { + visibility: 'hidden', + }, + }, +}); diff --git a/widget/embedded/src/components/Layout/Layout.tsx b/widget/embedded/src/components/Layout/Layout.tsx new file mode 100644 index 0000000000..1843ee1fe5 --- /dev/null +++ b/widget/embedded/src/components/Layout/Layout.tsx @@ -0,0 +1,169 @@ +import type { PropTypes } from './Layout.types'; +import type { PendingSwap } from 'rango-types'; +import type { PropsWithChildren } from 'react'; + +import { useManager } from '@rango-dev/queue-manager-react'; +import { BottomLogo, Divider, Header } from '@rango-dev/ui'; +import React, { useEffect, useRef, useState } from 'react'; + +import { WIDGET_UI_ID } from '../../constants'; +import { useIframe } from '../../hooks/useIframe'; +import { isAppLoadedIntoIframe } from '../../hooks/useIframe/useIframe.helpers'; +import { useNavigateBack } from '../../hooks/useNavigateBack'; +import { useTheme } from '../../hooks/useTheme'; +import { useAppStore } from '../../store/AppStore'; +import { tabManager, useUiStore } from '../../store/ui'; +import { getContainer } from '../../utils/common'; +import { getPendingSwaps } from '../../utils/queue'; +import { isFeatureHidden } from '../../utils/settings'; +import { ActivateTabAlert } from '../common/ActivateTabAlert'; +import { ActivateTabModal } from '../common/ActivateTabModal'; +import { BackButton, CancelButton, WalletButton } from '../HeaderButtons'; +import { RefreshModal } from '../RefreshModal'; + +import { onScrollContentAttachStatusToContainer } from './Layout.helpers'; +import { Container, Content, Footer, LayoutContainer } from './Layout.styles'; + +function Layout(props: PropsWithChildren) { + const { connectHeightObserver, disconnectHeightObserver } = useIframe(); + const { children, header, footer, height = 'fixed' } = props; + const { fetchStatus, connectedWallets } = useAppStore(); + const [openRefreshModal, setOpenRefreshModal] = useState(false); + const { + config: { features, theme }, + } = useAppStore(); + const { watermark } = useUiStore(); + + const hasWatermark = watermark === 'FULL'; + const { activeTheme } = useTheme(theme || {}); + + const isConnectWalletHidden = isFeatureHidden( + 'connectWalletButton', + features + ); + + const { + isActiveTab, + tabManagerInitiated, + showActivateTabModal, + setShowActivateTabModal, + activateCurrentTab, + } = useUiStore(); + const navigateBack = useNavigateBack(); + const { manager } = useManager(); + const pendingSwaps: PendingSwap[] = getPendingSwaps(manager).map( + ({ swap }) => swap + ); + const hasRunningSwap = pendingSwaps.some((swap) => swap.status === 'running'); + + const onActivateTab = () => + activateCurrentTab(tabManager.forceClaim, hasRunningSwap); + + const onConnectWallet = () => { + header.onWallet?.(); + }; + + const showBackButton = + typeof header.hasBackButton === 'undefined' || header.hasBackButton; + + const scrollViewRef = useRef(null); + const containerRef = useRef(null); + + useEffect(() => { + const isIframe = isAppLoadedIntoIframe(); + + // This feature only will be available in an iframe context. + if (isIframe && containerRef.current) { + connectHeightObserver(containerRef.current); + } + + return () => { + disconnectHeightObserver(); + }; + }, []); + + useEffect(() => { + scrollViewRef.current?.addEventListener( + 'scroll', + onScrollContentAttachStatusToContainer + ); + return () => { + scrollViewRef.current?.removeEventListener( + 'scroll', + onScrollContentAttachStatusToContainer + ); + }; + }, []); + + useEffect(() => { + setOpenRefreshModal(fetchStatus === 'failed'); + }, [fetchStatus]); + + return ( + +
{ + navigateBack(); + // As an example, used in routes page to add a custom logic when navigating back to the home page. + header.onBack && header.onBack(); + }} + /> + ) : null + } + title={header.title} + suffix={ + <> + {header.suffix} + {header.onWallet && !isConnectWalletHidden && ( + + )} + {header.onCancel && } + + } + /> + {children} + setShowActivateTabModal(false)} + onConfirm={onActivateTab} + /> + +
+
+ {tabManagerInitiated && !isActiveTab && ( +
+ + +
+ )} + {footer} +
+ + + +
+ +
+
+ setOpenRefreshModal(false)} + /> + + ); +} +export { Layout }; diff --git a/widget/embedded/src/components/Layout/Layout.types.ts b/widget/embedded/src/components/Layout/Layout.types.ts new file mode 100644 index 0000000000..8e09adb030 --- /dev/null +++ b/widget/embedded/src/components/Layout/Layout.types.ts @@ -0,0 +1,21 @@ +import type { Container } from './Layout.styles'; +import type * as Stitches from '@stitches/react'; + +type ContainerProps = Stitches.VariantProps; +type ContainerHeightProp = NonNullable< + Exclude +>; + +export interface PropTypes { + header: { + title: string; + onWallet?: () => void; + hasSettings?: boolean; + suffix?: React.ReactNode; + hasBackButton?: boolean; + onCancel?: () => void; + onBack?: () => void; + }; + footer?: React.ReactNode; + height?: ContainerHeightProp; +} diff --git a/widget/embedded/src/components/Layout/PageContainer.tsx b/widget/embedded/src/components/Layout/PageContainer.tsx new file mode 100644 index 0000000000..54f462799a --- /dev/null +++ b/widget/embedded/src/components/Layout/PageContainer.tsx @@ -0,0 +1,24 @@ +import { styled } from '@rango-dev/ui'; + +const PageContainer = styled('div', { + display: 'flex', + flexDirection: 'column', + padding: '20px 20px 10px', + flexGrow: 1, + + variants: { + view: { + true: { + flexGrow: 1, + overflow: 'hidden', + }, + }, + compact: { + true: { + padding: 0, + }, + }, + }, +}); + +export { PageContainer }; diff --git a/widget/embedded/src/components/Layout/ScrollableArea.tsx b/widget/embedded/src/components/Layout/ScrollableArea.tsx new file mode 100644 index 0000000000..e9936af4bb --- /dev/null +++ b/widget/embedded/src/components/Layout/ScrollableArea.tsx @@ -0,0 +1,11 @@ +import { styled } from '@rango-dev/ui'; + +const CONTENT_PADDING = '$20 $20 $10 $20'; + +const ScrollableArea = styled('div', { + padding: CONTENT_PADDING, + overflowY: 'auto', + flexGrow: 1, +}); + +export { ScrollableArea, CONTENT_PADDING }; diff --git a/widget/embedded/src/components/Layout/index.ts b/widget/embedded/src/components/Layout/index.ts new file mode 100644 index 0000000000..c6e4267a12 --- /dev/null +++ b/widget/embedded/src/components/Layout/index.ts @@ -0,0 +1,3 @@ +export { Layout } from './Layout'; +export { ScrollableArea, CONTENT_PADDING } from './ScrollableArea'; +export { PageContainer } from './PageContainer'; diff --git a/widget/embedded/src/components/LoadingLiquiditySourceList/LoadingLiquiditySourceList.styles.ts b/widget/embedded/src/components/LoadingLiquiditySourceList/LoadingLiquiditySourceList.styles.ts new file mode 100644 index 0000000000..95cff721b5 --- /dev/null +++ b/widget/embedded/src/components/LoadingLiquiditySourceList/LoadingLiquiditySourceList.styles.ts @@ -0,0 +1,5 @@ +import { ListItem, styled } from '@rango-dev/ui'; + +export const CustomListItem = styled(ListItem, { + height: 61, +}); diff --git a/widget/embedded/src/components/LoadingLiquiditySourceList/LoadingLiquiditySourceList.tsx b/widget/embedded/src/components/LoadingLiquiditySourceList/LoadingLiquiditySourceList.tsx new file mode 100644 index 0000000000..0569a79119 --- /dev/null +++ b/widget/embedded/src/components/LoadingLiquiditySourceList/LoadingLiquiditySourceList.tsx @@ -0,0 +1,23 @@ +import { Checkbox, Skeleton } from '@rango-dev/ui'; +import React from 'react'; + +import { LiquiditySourceList } from '../SettingsContainer'; + +import { CustomListItem } from './LoadingLiquiditySourceList.styles'; + +const ITEM_SKELETON_COUNT = 30; +export function LoadingLiquiditySourceList() { + return ( + + {Array.from(Array(ITEM_SKELETON_COUNT), (_, index) => ( + } + title={} + end={} + /> + ))} + + ); +} diff --git a/widget/embedded/src/components/LoadingLiquiditySourceList/index.ts b/widget/embedded/src/components/LoadingLiquiditySourceList/index.ts new file mode 100644 index 0000000000..3b9b624af0 --- /dev/null +++ b/widget/embedded/src/components/LoadingLiquiditySourceList/index.ts @@ -0,0 +1 @@ +export { LoadingLiquiditySourceList } from './LoadingLiquiditySourceList'; diff --git a/widget/embedded/src/components/LoadingSwapDetails/LoadingSwapDetails.styles.ts b/widget/embedded/src/components/LoadingSwapDetails/LoadingSwapDetails.styles.ts new file mode 100644 index 0000000000..7815b3fc0a --- /dev/null +++ b/widget/embedded/src/components/LoadingSwapDetails/LoadingSwapDetails.styles.ts @@ -0,0 +1,82 @@ +import { css, styled } from '@rango-dev/ui'; + +export const Container = styled('div', { + width: '100%', + height: '100%', + padding: '$10 $20', +}); + +export const StepContainer = styled('div', { + backgroundColor: '$neutral100', + borderRadius: '$xm', + padding: '$10 $15', +}); + +export const StepSeparator = styled('div', { + width: '0px', + height: '$20', + borderLeft: '1px dashed $neutral700', + marginLeft: '25px', +}); + +export const quoteSummaryItemStyles = css({ + display: 'flex', + justifyContent: 'space-between', + alignItems: 'center', +}); + +export const tokenAmountStyles = css({ + display: 'flex', + justifyContent: 'space-between', + alignItems: 'center', +}); + +export const costStyles = css({ + paddingTop: '$15', + display: 'flex', +}); + +export const quoteSummaryStyles = css({ + padding: '$15 $0', +}); + +export const quoteSummarySeparatorStyles = css({ + width: '0px', + height: '$16', + borderLeft: '1px solid $neutral400', + marginLeft: '13px', +}); + +export const swapsStepsStyles = css({ + paddingBottom: '$10', +}); + +export const stepTitleStyles = css({ + display: 'flex', + justifyContent: 'start', + alignItems: 'center', +}); + +export const stepTokensStyles = css({ + paddingTop: '$5', + display: 'flex', + alignItems: 'center', +}); + +export const stepInfoStyles = css({ + display: 'flex', + alignItems: 'center', +}); + +export const stepIconStyles = css({ + padding: '$4 $6', + display: 'flex', + justifyContent: 'center', + alignItems: 'center', +}); + +export const extraInfoStyles = css({ + display: 'flex', + paddingTop: '$10', + paddingBottom: '$5', +}); diff --git a/widget/embedded/src/components/LoadingSwapDetails/LoadingSwapDetails.tsx b/widget/embedded/src/components/LoadingSwapDetails/LoadingSwapDetails.tsx new file mode 100644 index 0000000000..477c62e0a1 --- /dev/null +++ b/widget/embedded/src/components/LoadingSwapDetails/LoadingSwapDetails.tsx @@ -0,0 +1,47 @@ +import { i18n } from '@lingui/core'; +import { Divider, Skeleton, Typography } from '@rango-dev/ui'; +import React from 'react'; + +import { QuoteSummarySkeleton, StepSkeleton } from '../QuoteSkeleton'; + +import { + Container, + extraInfoStyles, + StepContainer, + StepSeparator, +} from './LoadingSwapDetails.styles'; + +export function LoadingSwapDetails() { + return ( + + +
+ + {i18n.t('Swaps steps')} + +
+ + <> + + +
+ + +
+
+ + + + + + + + + + + + + +
+ ); +} diff --git a/widget/embedded/src/components/LoadingSwapDetails/index.ts b/widget/embedded/src/components/LoadingSwapDetails/index.ts new file mode 100644 index 0000000000..c994645df4 --- /dev/null +++ b/widget/embedded/src/components/LoadingSwapDetails/index.ts @@ -0,0 +1 @@ +export { LoadingSwapDetails } from './LoadingSwapDetails'; diff --git a/widget/embedded/src/components/NoResult/NoResult.helpers.ts b/widget/embedded/src/components/NoResult/NoResult.helpers.ts new file mode 100644 index 0000000000..f0bfb1cce0 --- /dev/null +++ b/widget/embedded/src/components/NoResult/NoResult.helpers.ts @@ -0,0 +1,69 @@ +import type { Info } from './NoResult.types'; +import type { NoResultError, QuoteRequestFailed } from '../../types'; + +import { i18n } from '@lingui/core'; + +import { errorMessages } from '../../constants/errors'; +import { QuoteErrorType } from '../../types'; + +const SMALL_NO_ROUTE__ICON_SIZE = 24; +const LARGE_NO_ROUTE_ICON_SIZE = 60; + +export function makeInfo( + error: NoResultError | QuoteRequestFailed | null, + disabledLiquiditySources: string[], + toggleAllLiquiditySources: (shouldReset: boolean) => void, + refetchQuote: () => void +): Info { + if (error?.type === QuoteErrorType.REQUEST_FAILED) { + return { + alert: { + type: 'warning', + text: errorMessages().genericServerError, + action: { + onClick: refetchQuote, + title: i18n.t('Retry'), + }, + }, + description: '', + }; + } else if (disabledLiquiditySources.length) { + return { + alert: { + type: 'warning', + text: errorMessages().liquiditySourcesError.title, + action: { + onClick: () => toggleAllLiquiditySources(true), + title: i18n.t('Reset'), + }, + }, + description: errorMessages().liquiditySourcesError.description, + }; + } else if ( + error?.type === QuoteErrorType.NO_RESULT && + error.diagnosisMessage + ) { + return { + alert: { + type: 'error', + text: error.diagnosisMessage, + action: null, + }, + description: '', + }; + } + return { + alert: null, + description: errorMessages().noResultError.description, + }; +} + +export enum NoRouteIconSize { + small = SMALL_NO_ROUTE__ICON_SIZE, + large = LARGE_NO_ROUTE_ICON_SIZE, +} + +export enum NoRouteTitleSize { + small = 'small', + large = 'medium', +} diff --git a/widget/embedded/src/components/NoResult/NoResult.styles.ts b/widget/embedded/src/components/NoResult/NoResult.styles.ts new file mode 100644 index 0000000000..bec7003aa2 --- /dev/null +++ b/widget/embedded/src/components/NoResult/NoResult.styles.ts @@ -0,0 +1,33 @@ +import { styled } from '@rango-dev/ui'; + +export const Container = styled('div', { + display: 'flex', + flexDirection: 'column', + alignItems: 'center', +}); + +export const ErrorDescription = styled('div', { + variants: { + size: { + small: {}, + large: { + maxWidth: '316px', + }, + }, + }, +}); + +export const Footer = styled('div', { + variants: { + size: { + small: { + width: '100%', + }, + large: {}, + }, + }, +}); + +export const PrefixIcon = styled('div', { + padding: '$6 $0', +}); diff --git a/widget/embedded/src/components/NoResult/NoResult.tsx b/widget/embedded/src/components/NoResult/NoResult.tsx new file mode 100644 index 0000000000..941b1cd3b8 --- /dev/null +++ b/widget/embedded/src/components/NoResult/NoResult.tsx @@ -0,0 +1,89 @@ +import type { PropTypes } from './NoResult.types'; + +import { + Alert, + Button, + Divider, + NoRouteIcon, + RefreshIcon, + Typography, +} from '@rango-dev/ui'; +import React from 'react'; + +import { errorMessages } from '../../constants/errors'; +import { useAppStore } from '../../store/AppStore'; + +import { + makeInfo, + NoRouteIconSize, + NoRouteTitleSize, +} from './NoResult.helpers'; +import { + Container, + ErrorDescription, + Footer, + PrefixIcon, +} from './NoResult.styles'; + +export function NoResult(props: PropTypes) { + const { fetch, error, size = 'small' } = props; + const disabledLiquiditySources = useAppStore().getDisabledLiquiditySources(); + const toggleAllLiquiditySources = useAppStore().toggleAllLiquiditySources; + + const swappers = useAppStore().swappers(); + const info = makeInfo( + error, + disabledLiquiditySources, + () => toggleAllLiquiditySources(swappers, true), + fetch + ); + + return ( + + + + + {errorMessages().noResultError.title} + + {size === 'large' && } + {!!info.description && ( + + + {info.description} + + + )} + + {!!info.alert && ( +
+ + + + } + onClick={info.alert.action.onClick}> + {info.alert.action.title} + + ) + } + variant="alarm" + /> +
+ )} +
+ ); +} diff --git a/widget/embedded/src/components/NoResult/NoResult.types.ts b/widget/embedded/src/components/NoResult/NoResult.types.ts new file mode 100644 index 0000000000..8821114652 --- /dev/null +++ b/widget/embedded/src/components/NoResult/NoResult.types.ts @@ -0,0 +1,23 @@ +import type { NoResultError, QuoteRequestFailed } from '../../types'; + +export interface PropTypes { + fetch: () => void; + error: NoResultError | QuoteRequestFailed | null; + size?: 'small' | 'large'; +} + +type AlertAction = { + title: string; + onClick: () => void; +}; + +type NotFoundAlert = { + type: 'error' | 'warning'; + text: string; + action: AlertAction | null; +}; + +export interface Info { + alert: NotFoundAlert | null; + description: string; +} diff --git a/widget/embedded/src/components/NoResult/index.ts b/widget/embedded/src/components/NoResult/index.ts new file mode 100644 index 0000000000..ce206dbb83 --- /dev/null +++ b/widget/embedded/src/components/NoResult/index.ts @@ -0,0 +1 @@ +export { NoResult } from './NoResult'; diff --git a/widget/embedded/src/components/NotificationContent/NotificationContent.tsx b/widget/embedded/src/components/NotificationContent/NotificationContent.tsx new file mode 100644 index 0000000000..88ed2c3031 --- /dev/null +++ b/widget/embedded/src/components/NotificationContent/NotificationContent.tsx @@ -0,0 +1,36 @@ +import type { Notification } from '../../types/notification'; + +import { Notifications } from '@rango-dev/ui'; +import React from 'react'; +import { useNavigate } from 'react-router-dom'; + +import { navigationRoutes } from '../../constants/navigationRoutes'; +import { useAppStore } from '../../store/AppStore'; +import { useNotificationStore } from '../../store/notification'; +import { getBlockchainImage } from '../../utils/meta'; + +export function NotificationContent() { + const navigate = useNavigate(); + + const { getNotifications, clearNotifications } = useNotificationStore(); + + const notifications: Notification[] = getNotifications(); + const blockchains = useAppStore().blockchains(); + const { findToken } = useAppStore(); + + const onClickItem = (requestId: Notification['requestId']) => { + navigate(`${navigationRoutes.swaps}/${requestId}`); + }; + + return ( + + getBlockchainImage(blockchain, blockchains) ?? '' + } + getTokenImage={(token) => findToken(token)?.image ?? ''} + onClickItem={onClickItem} + onClearAll={clearNotifications} + /> + ); +} diff --git a/widget/embedded/src/components/NotificationContent/index.ts b/widget/embedded/src/components/NotificationContent/index.ts new file mode 100644 index 0000000000..1de19c4c66 --- /dev/null +++ b/widget/embedded/src/components/NotificationContent/index.ts @@ -0,0 +1 @@ +export { NotificationContent } from './NotificationContent'; diff --git a/widget/embedded/src/components/PercentageChange.tsx b/widget/embedded/src/components/PercentageChange.tsx deleted file mode 100644 index 94cd4e470f..0000000000 --- a/widget/embedded/src/components/PercentageChange.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import BigNumber from 'bignumber.js'; -import React from 'react'; -import { getPercentageChange } from '../utils/swap'; -import { Typography } from '@rango-dev/ui'; -import { numberToString } from '../utils/numbers'; - -interface PropTypes { - inputUsdValue: BigNumber | null; - outputUsdValue: BigNumber | null; -} - -export function PercentageChange(props: PropTypes) { - const { inputUsdValue, outputUsdValue } = props; - - if (!inputUsdValue || !outputUsdValue || !outputUsdValue.gt(0)) return null; - - const percentageChange = getPercentageChange( - inputUsdValue.toNumber(), - outputUsdValue.toNumber() - ); - - const showPercentageChange = percentageChange?.lt(0); - - return ( - <> - {showPercentageChange && ( - - {`(${numberToString(percentageChange, 0, 2)}%)`} - - )} - - ); -} diff --git a/widget/embedded/src/components/Quote/Quote.styles.ts b/widget/embedded/src/components/Quote/Quote.styles.ts new file mode 100644 index 0000000000..61e855ec29 --- /dev/null +++ b/widget/embedded/src/components/Quote/Quote.styles.ts @@ -0,0 +1,398 @@ +import * as Collapsible from '@radix-ui/react-collapsible'; +import { + Button, + css, + darkTheme, + Image, + styled, + Typography, +} from '@rango-dev/ui'; + +import { CollapsibleContent } from '../CustomCollapsible/CustomCollapsible.styles'; + +export const EXPANDABLE_QUOTE_TRANSITION_DURATION = 300; + +export const QuoteContainer = styled(Collapsible.Root, { + display: 'flex', + flexDirection: 'column', + alignItems: 'start', + overflowX: 'auto', + overflowY: 'hidden', + width: '100%', + borderRadius: '$xm', + variants: { + selected: { + true: {}, + false: { + $$color: '$colors$neutral400', + [`.${darkTheme} &`]: { + $$color: '$colors$neutral200', + }, + backgroundColor: '$$color', + }, + }, + listItem: { + true: { + $$color: '$colors$neutral400', + [`.${darkTheme} &`]: { + $$color: '$colors$neutral200', + }, + backgroundColor: '$$color', + }, + false: {}, + }, + }, + + compoundVariants: [ + { + listItem: false, + selected: true, + css: { + $$color: '$colors$secondary200', + [`.${darkTheme} &`]: { + $$color: '$colors$secondary800', + }, + backgroundColor: '$$color', + }, + }, + ], +}); + +export const stepsDetailsStyles = css({ + padding: '$10 $15', +}); +export const AllRoutesButton = styled(Button, { + backgroundColor: 'transparent', + border: '1px solid $secondary550', + [`.${darkTheme} &`]: { + border: '1px solid $secondary', + }, + transition: 'background-color 0.3s ease', + '&:hover': { + backgroundColor: '$secondary550', + [`.${darkTheme} &`]: { + backgroundColor: '$secondary', + }, + '.allRoutesLabel': { + $$color: '$colors$background', + [`.${darkTheme} &`]: { + $$color: '$colors$foreground', + }, + color: '$$color', + transition: 'color 0.3s ease', + }, + }, +}); +export const SummaryContainer = styled('div', { + borderRadius: '$xm', + display: 'flex', + flexDirection: 'column', + alignItems: 'start', + justifyContent: 'space-between', + color: '$foreground', + boxSizing: 'border-box', + position: 'relative', + variants: { + selected: { + true: {}, + false: { + $$color: '$colors$neutral200', + [`.${darkTheme} &`]: { + $$color: '$colors$neutral500', + }, + backgroundColor: '$$color', + }, + }, + basic: { true: { borderTopRightRadius: '0', borderTopLeftRadius: '0' } }, + listItem: { + true: { + $$color: '$colors$neutral200', + [`.${darkTheme} &`]: { + $$color: '$colors$neutral500', + }, + backgroundColor: '$$color', + '&:hover': { + '& .quote_container': { + '& button': { + backgroundColor: '$neutral500', + [`.${darkTheme} &`]: { + backgroundColor: '$neutral200', + }, + }, + backgroundColor: '$neutral500', + [`.${darkTheme} &`]: { + backgroundColor: '$neutral200', + }, + }, + backgroundColor: '$neutral300', + [`.${darkTheme} &`]: { + backgroundColor: '$neutral400', + }, + }, + cursor: 'pointer', + }, + false: {}, + }, + }, + + compoundVariants: [ + { + listItem: true, + selected: true, + css: { + outline: '1px solid $secondary', + }, + }, + { + listItem: false, + selected: true, + css: { + $$color: '$colors$secondary100', + [`.${darkTheme} &`]: { + $$color: '$colors$secondary550', + }, + backgroundColor: '$$color', + '&:hover': { + backgroundColor: '$$color', + }, + }, + }, + { + listItem: true, + selected: false, + css: { + cursor: 'pointer', + '&:hover': { + backgroundColor: '$neutral300', + [`.${darkTheme} &`]: { + backgroundColor: '$neutral400', + }, + }, + }, + }, + ], +}); + +export const summaryStyles = css({ + width: '100%', + padding: '$15 $15 $10 $15', +}); + +export const summaryHeaderStyles = css({ + display: 'flex', + flexDirection: 'row', + justifyContent: 'space-between', + alignItems: 'center', + paddingBottom: '$10', + position: 'relative', +}); + +export const rowStyles = css({ + display: 'flex', + flexDirection: 'row', + justifyContent: 'center', + alignItems: 'center', + '.blockchainImage': { + marginLeft: '-$8', + }, +}); +export const basicInfoStyles = css({ + display: 'flex', + alignItems: 'center', + '.usd-value': { + $$color: '$colors$neutral600', + [`.${darkTheme} &`]: { + $$color: '$colors$neutral700', + }, + color: '$$color', + }, +}); + +export const Trigger = styled(Collapsible.Trigger, { + display: 'flex', + width: '100%', + justifyContent: 'space-between', + alignItems: 'center', + height: '$36', + padding: '$10 $15', + boxSizing: 'border-box', + cursor: 'pointer', + border: 'none', + outline: 'none', + backgroundColor: 'transparent', + variants: { + error: { + true: { + [`& ${Image}`]: { + border: '1px $warning500 solid', + borderRadius: '100%', + }, + }, + false: { + [`& ${Image}`]: { + border: '1px transparent solid', + borderRadius: '100%', + }, + }, + }, + selected: { + true: {}, + false: { + $$color: '$colors$neutral400', + [`.${darkTheme} &`]: { + $$color: '$colors$neutral200', + }, + backgroundColor: '$$color', + }, + }, + listItem: { + true: { + $$color: '$colors$neutral400', + [`.${darkTheme} &`]: { + $$color: '$colors$neutral200', + }, + backgroundColor: '$$color', + }, + false: {}, + }, + }, + + compoundVariants: [ + { + listItem: false, + selected: true, + css: { + $$color: '$colors$secondary200', + [`.${darkTheme} &`]: { + $$color: '$colors$secondary800', + }, + backgroundColor: '$$color', + }, + }, + ], + '.blockchains_section': { + display: 'none', + }, + '@xs': { + '.blockchains_section': { + display: 'block', + }, + }, +}); + +export const ImageContainer = styled('div', { + width: '18px', + height: '18px', + borderRadius: '100%', + display: 'flex', + justifyContent: 'center', + alignItems: 'center', + border: '1.5px transparent solid', + img: { + borderRadius: '100%', + }, + variants: { + state: { + error: { + borderColor: '$error500', + }, + warning: { borderColor: '$warning500' }, + }, + }, +}); + +export const Content = styled(CollapsibleContent, { + width: '100%', + background: 'inherit', +}); + +export const IconContainer = styled('div', { + display: 'flex', + justifyContent: 'center', + alignItems: 'center', + padding: '$2', + transition: `all ${EXPANDABLE_QUOTE_TRANSITION_DURATION}ms ease`, + variants: { + orientation: { + down: { + transform: 'rotate(0)', + }, + up: { + transform: 'rotate(180deg)', + }, + }, + }, +}); + +export const Separator = styled('div', { + height: '$12', + marginLeft: '$10', + marginRight: '$10', + borderLeft: '1px solid $foreground', +}); + +export const HorizontalSeparator = styled('div', { + display: 'flex', + justifyContent: 'center', + margin: '0 $15', + borderTop: '1px solid', + $$color: '$colors$neutral300', + [`.${darkTheme} &`]: { + $$color: '$colors$neutral400', + }, + borderColor: '$$color', +}); + +export const FrameIcon = styled('div', { + width: '$16', + height: '$16', + justifyContent: 'center', + alignItems: 'center', + display: 'flex', +}); + +export const BasicInfoOutput = styled(Typography, { + overflow: 'hidden', + textOverflow: 'ellipsis', + letterSpacing: 0.4, +}); + +export const ContainerInfoOutput = styled('div', { + display: 'flex', + flexWrap: 'wrap', +}); + +export const MoreStep = styled('div', { + width: '18px', + height: '18px', + borderRadius: '100%', + backgroundColor: '$background', + cursor: 'default', + display: 'flex', + justifyContent: 'center', + alignItems: 'center', + border: '1.5px transparent solid', + variants: { + state: { + error: { + borderColor: '$error500', + }, + warning: { borderColor: '$warning500' }, + }, + }, +}); + +export const TagContainer = styled('div', { + display: 'flex', +}); + +export const Line = styled('div', { + width: '100%', + borderTopWidth: '1px', + borderTopStyle: 'solid', + borderTopColor: '$neutral', + margin: '$5 0', + [`.${darkTheme} &`]: { + borderTopColor: '$neutral800', + }, +}); diff --git a/widget/embedded/src/components/Quote/Quote.tsx b/widget/embedded/src/components/Quote/Quote.tsx new file mode 100644 index 0000000000..a83a86a0a2 --- /dev/null +++ b/widget/embedded/src/components/Quote/Quote.tsx @@ -0,0 +1,516 @@ +import type { QuoteProps } from './Quote.types'; +import type { Step } from '@rango-dev/ui'; +import type { SwapResult } from 'rango-sdk'; + +import { i18n } from '@lingui/core'; +import { + Alert, + Divider, + FullExpandedQuote, + InfoIcon, + NumericTooltip, + QuoteTag, + StepDetails, + TokenAmount, + Typography, +} from '@rango-dev/ui'; +import BigNumber from 'bignumber.js'; +import React, { useRef, useState } from 'react'; + +import { + GAS_FEE_MAX, + ROUTE_TIME_MAX, + SECONDS_IN_MINUTE, +} from '../../constants/quote'; +import { + GAS_FEE_MAX_DECIMALS, + GAS_FEE_MIN_DECIMALS, + PERCENTAGE_CHANGE_MAX_DECIMALS, + PERCENTAGE_CHANGE_MIN_DECIMALS, + TOKEN_AMOUNT_MAX_DECIMALS, + TOKEN_AMOUNT_MIN_DECIMALS, + USD_VALUE_MAX_DECIMALS, + USD_VALUE_MIN_DECIMALS, +} from '../../constants/routing'; +import { + FooterAlert, + FooterStepAlarm, +} from '../../containers/QuoteInfo/QuoteInfo.styles'; +import { useAppStore } from '../../store/AppStore'; +import { QuoteErrorType, QuoteWarningType } from '../../types'; +import { getContainer, getExpanded } from '../../utils/common'; +import { + getBlockchainShortNameFor, + getSwapperDisplayName, +} from '../../utils/meta'; +import { + numberToString, + roundedSecondsToString, + totalArrivalTime, +} from '../../utils/numbers'; +import { + getPriceImpact, + getPriceImpactLevel, + sortTags, +} from '../../utils/quote'; +import { getTotalFeeInUsd, getUsdFeeOfStep } from '../../utils/swap'; + +import { + AllRoutesButton, + BasicInfoOutput, + basicInfoStyles, + ContainerInfoOutput, + Content, + FrameIcon, + HorizontalSeparator, + Line, + QuoteContainer, + stepsDetailsStyles, + SummaryContainer, + summaryHeaderStyles, + summaryStyles, + TagContainer, +} from './Quote.styles'; +import { QuoteCostDetails } from './QuoteCostDetails'; +import { QuoteSummary } from './QuoteSummary'; +import { QuoteTrigger } from './QuoteTrigger'; + +export function Quote(props: QuoteProps) { + const { + quote, + input, + output, + error, + warning, + type, + selected = false, + tagHidden = true, + showModalFee = true, + onClickAllRoutes, + fullExpandedMode = false, + container: propContainer, + } = props; + const blockchains = useAppStore().blockchains(); + const { findToken } = useAppStore(); + const swappers = useAppStore().swappers(); + const { customSlippage, slippage } = useAppStore(); + const userSlippage = customSlippage || slippage; + const [expanded, setExpanded] = useState(props.expanded); + const quoteRef = useRef(null); + const roundedInput = numberToString( + input.value, + TOKEN_AMOUNT_MIN_DECIMALS, + TOKEN_AMOUNT_MAX_DECIMALS + ); + const roundedOutput = numberToString( + output.value, + TOKEN_AMOUNT_MIN_DECIMALS, + TOKEN_AMOUNT_MAX_DECIMALS + ); + const roundedOutputUsdValue = output.usdValue + ? numberToString( + output.usdValue, + USD_VALUE_MIN_DECIMALS, + USD_VALUE_MAX_DECIMALS + ) + : ''; + const priceImpact = getPriceImpact(input.usdValue, output.usdValue ?? null); + const percentageChange = numberToString( + priceImpact, + PERCENTAGE_CHANGE_MIN_DECIMALS, + PERCENTAGE_CHANGE_MAX_DECIMALS + ); + const priceImpactWarningLevel = getPriceImpactLevel(priceImpact ?? 0); + + const getQuoteSteps = ( + swaps: SwapResult[], + internalSwap?: boolean + ): Step[] => { + return swaps.map((swap, index) => { + let stepState: 'error' | 'warning' | undefined = undefined; + const hasBridgeLimitError = + error?.type === QuoteErrorType.BRIDGE_LIMIT && + error.swap.swapperId === swap.swapperId; + + const hasSlippageError = + error?.type === QuoteErrorType.INSUFFICIENT_SLIPPAGE && + error.recommendedSlippages?.has(index); + + const hasSlippageWarning = + warning?.type === QuoteWarningType.INSUFFICIENT_SLIPPAGE && + warning.recommendedSlippages?.has(index); + + const stepHasError = hasBridgeLimitError || hasSlippageError; + const stepHasWarning = hasSlippageWarning; + + if (stepHasError) { + stepState = 'error'; + } else if (stepHasWarning) { + stepState = 'warning'; + } + + let alertTitle = stepHasError + ? i18n.t('Slippage Error') + : i18n.t('Slippage Warning'); + + if (hasBridgeLimitError) { + alertTitle = i18n.t('Bridge Limit Error'); + } + + return { + swapper: { + displayName: getSwapperDisplayName(swap.swapperId, swappers) ?? '', + image: swap.swapperLogo, + }, + from: { + token: { displayName: swap.from.symbol, image: swap.from.logo }, + chain: { + displayName: + getBlockchainShortNameFor(swap.from.blockchain, blockchains) ?? + '', + image: swap.from.blockchainLogo, + }, + price: { + value: + index === 0 && !internalSwap + ? numberToString( + input.value, + TOKEN_AMOUNT_MIN_DECIMALS, + TOKEN_AMOUNT_MAX_DECIMALS + ) + : numberToString( + swap.fromAmount, + TOKEN_AMOUNT_MIN_DECIMALS, + TOKEN_AMOUNT_MAX_DECIMALS + ), + usdValue: numberToString( + (swap.from.usdPrice ?? 0) * parseFloat(swap.fromAmount), + USD_VALUE_MIN_DECIMALS, + USD_VALUE_MAX_DECIMALS + ), + realValue: index === 0 ? input.value : swap.fromAmount, + realUsdValue: new BigNumber(swap.from.usdPrice ?? 0) + .multipliedBy(swap.fromAmount) + .toString(), + }, + }, + to: { + token: { displayName: swap.to.symbol, image: swap.to.logo }, + chain: { + displayName: + getBlockchainShortNameFor(swap.to.blockchain, blockchains) || '', + image: swap.to.blockchainLogo, + }, + price: { + value: numberToString( + swap.toAmount, + TOKEN_AMOUNT_MIN_DECIMALS, + TOKEN_AMOUNT_MAX_DECIMALS + ), + usdValue: numberToString( + (swap.to.usdPrice ?? 0) * parseFloat(swap.toAmount), + USD_VALUE_MIN_DECIMALS, + USD_VALUE_MAX_DECIMALS + ), + realValue: swap.toAmount, + realUsdValue: new BigNumber(swap.to.usdPrice ?? 0) + .multipliedBy(swap.toAmount) + .toString(), + }, + }, + state: stepState, + alerts: + stepHasError || stepHasWarning ? ( + + + {hasBridgeLimitError && ( +
+ + {error.fromAmountRangeError} + + + + {i18n.t({ + id: 'Yours: {amount} {symbol}', + values: { + amount: numberToString( + swap.fromAmount, + TOKEN_AMOUNT_MIN_DECIMALS, + TOKEN_AMOUNT_MAX_DECIMALS + ), + symbol: swap?.from.symbol, + }, + })} + +
+ )} + {(hasSlippageError || hasSlippageWarning) && + !hasBridgeLimitError && ( +
+ + {i18n.t({ + id: 'Minimum required slippage: {minRequiredSlippage}', + values: { + ...(error?.type === + QuoteErrorType.INSUFFICIENT_SLIPPAGE && { + minRequiredSlippage: + error.recommendedSlippages?.get(index), + }), + ...(warning?.type === + QuoteWarningType.INSUFFICIENT_SLIPPAGE && { + minRequiredSlippage: + warning.recommendedSlippages?.get(index), + }), + }, + })} + + + + {i18n.t({ + id: 'Yours: {userSlippage}', + values: { + userSlippage, + }, + })} + +
+ )} + + } + /> +
+ ) : undefined, + time: roundedSecondsToString(swap.estimatedTimeInSeconds), + fee: numberToString( + getUsdFeeOfStep(swap, findToken), + GAS_FEE_MIN_DECIMALS, + GAS_FEE_MAX_DECIMALS + ), + internalSwaps: swap.internalSwaps + ? getQuoteSteps(swap.internalSwaps) + : undefined, + }; + }); + }; + const steps = getQuoteSteps(quote?.swaps ?? []); + + const numberOfSteps = steps.length; + const container = propContainer || getContainer(); + const sortedQuoteTags = sortTags(props.quote.tags || []); + const showAllRoutesButton = !!onClickAllRoutes; + const totalDurationSeconds = totalArrivalTime(quote?.swaps); + const totalTime = roundedSecondsToString(totalDurationSeconds); + const totalFee = getTotalFeeInUsd(quote?.swaps ?? [], findToken); + const fee = numberToString( + totalFee, + GAS_FEE_MIN_DECIMALS, + GAS_FEE_MAX_DECIMALS + ); + + const feeWarning = totalFee.gte(new BigNumber(GAS_FEE_MAX)); + const timeWarning = + totalDurationSeconds / SECONDS_IN_MINUTE >= ROUTE_TIME_MAX; + + return fullExpandedMode ? ( + + } + percentageChange={percentageChange} + warningLevel={priceImpactWarningLevel} + outputPrice={{ + value: roundedOutput, + usdValue: roundedOutputUsdValue, + realValue: output.value, + realUsdValue: output.usdValue, + }} + /> + ) : ( + +
+ {!tagHidden && sortedQuoteTags.length ? ( + <> + + {sortedQuoteTags.map((tag, index) => { + const key = `${tag.value}_${index}`; + return ( + + + + + ); + })} + + + {!showAllRoutesButton && } + + ) : null} +
+ + + {showAllRoutesButton && ( + { + e.stopPropagation(); + onClickAllRoutes(); + }} + size="xxsmall" + type="secondary" + variant="default" + css={{ + paddingLeft: '$10', + paddingRight: '$10', + paddingTop: '$5', + paddingBottom: '$5', + }}> + + {i18n.t('See All Routes')} + + + )} +
+ {type === 'basic' && ( +
+ + + + + + {`${roundedInput} ${steps[0].from.token.displayName} = `} + + + +   + {`${roundedOutput} ${ + steps[steps.length - 1].to.token.displayName + }`} + + + + + + + {`($${roundedOutputUsdValue})`} + + +
+ )} + {type === 'list-item' && ( + + )} + {type === 'swap-preview' && ( + <> + + + + )} +
+ + + + +
+ {steps.map((step, index) => { + const key = `item-${index}`; + return ( + + ); + })} +
+
+
+
+ ); +} diff --git a/widget/embedded/src/components/Quote/Quote.types.ts b/widget/embedded/src/components/Quote/Quote.types.ts new file mode 100644 index 0000000000..1514f69618 --- /dev/null +++ b/widget/embedded/src/components/Quote/Quote.types.ts @@ -0,0 +1,54 @@ +import type { QuoteError, QuoteWarning, SelectedQuote } from '../../types'; +import type { Step } from '@rango-dev/ui'; +import type { ReactNode } from 'react'; + +export type QuoteProps = { + type: 'basic' | 'list-item' | 'swap-preview'; + error: QuoteError | null; + warning: QuoteWarning | null; + quote: SelectedQuote; + input: { value: string; usdValue: string }; + output: { value: string; usdValue?: string }; + expanded?: boolean; + tagHidden?: boolean; + selected?: boolean; + showModalFee?: boolean; + onClickAllRoutes?: () => void; + fullExpandedMode?: boolean; + container?: HTMLElement; +}; + +export type optionProps = { + value: string; + label: string; +}; + +export type QuoteTriggerProps = { + type: QuoteProps['type']; + quoteRef: React.MutableRefObject; + selected: boolean; + setExpanded: React.Dispatch>; + steps: Step[]; + expanded?: boolean; + container?: HTMLElement; +}; + +export type QuoteTriggerImagesProps = { + content: ReactNode; + state?: 'error' | 'warning' | undefined; + src: string; + open?: boolean; + className?: string; + container?: HTMLElement; +}; + +export type QuoteCostDetailsProps = { + quote: SelectedQuote | null; + steps: number; + fee: string; + time: string; + feeWarning?: boolean; + timeWarning?: boolean; + showModalFee: boolean; + fullExpandedMode?: boolean; +}; diff --git a/widget/embedded/src/components/Quote/QuoteCostDetails.styles.ts b/widget/embedded/src/components/Quote/QuoteCostDetails.styles.ts new file mode 100644 index 0000000000..135fc87616 --- /dev/null +++ b/widget/embedded/src/components/Quote/QuoteCostDetails.styles.ts @@ -0,0 +1,49 @@ +import { css, styled } from '@rango-dev/ui'; + +export const FeeSection = styled('div', { + display: 'flex', + justifyContent: 'space-between', + alignItems: 'center', + padding: '$5 0', + '&.total_payable_fee': { + padding: '$12 0', + }, +}); + +export const Line = styled('div', { + width: '100%', + borderTop: '1px solid $neutral300', + margin: '$10 0', +}); + +export const ModalContainer = styled('div', { + padding: '$20 0', + display: 'flex', + flexDirection: 'column', + '& .collapsible_trigger': { + display: 'flex', + alignItems: 'center', + }, +}); + +export const ModalHeader = styled('div', { + padding: '$20 $20 $10', + position: 'relative', + '._icon-button': { + position: 'absolute', + zIndex: 10, + top: '$16', + right: '$16', + }, +}); +export const trigger = css({ + display: 'flex', + flexDirection: 'row', + alignItems: 'center', + padding: '$5', + '&:hover': { + '& ._typography, & svg': { + color: '$secondary', + }, + }, +}); diff --git a/widget/embedded/src/components/Quote/QuoteCostDetails.tsx b/widget/embedded/src/components/Quote/QuoteCostDetails.tsx new file mode 100644 index 0000000000..fb6207107c --- /dev/null +++ b/widget/embedded/src/components/Quote/QuoteCostDetails.tsx @@ -0,0 +1,229 @@ +import type { QuoteCostDetailsProps } from './Quote.types'; +import type { NameOfFees } from '../../constants/quote'; +import type BigNumber from 'bignumber.js'; + +import { i18n } from '@lingui/core'; +import { + ChevronDownIcon, + CloseIcon, + Divider, + IconButton, + NumericTooltip, + QuoteCost, + Typography, +} from '@rango-dev/ui'; +import React, { useState } from 'react'; + +import { getFeeLabel } from '../../constants/quote'; +import { + GAS_FEE_MAX_DECIMALS, + GAS_FEE_MIN_DECIMALS, + USD_VALUE_MAX_DECIMALS, + USD_VALUE_MIN_DECIMALS, +} from '../../constants/routing'; +import { getContainer, getExpanded } from '../../utils/common'; +import { numberToString } from '../../utils/numbers'; +import { getFeesGroup, getTotalFeesInUsd, getUsdFee } from '../../utils/swap'; +import { WatermarkedModal } from '../common/WatermarkedModal'; +import { CustomCollapsible } from '../CustomCollapsible/CustomCollapsible'; +import { ExpandedIcon } from '../CustomCollapsible/CustomCollapsible.styles'; + +import { + FeeSection, + Line, + ModalContainer, + ModalHeader, + trigger, +} from './QuoteCostDetails.styles'; + +const NonPayableFee = (props: { fee: BigNumber; label: string }) => { + return !props.fee.isZero() ? ( + + + {props.label} + + + $ + {numberToString( + props.fee, + USD_VALUE_MIN_DECIMALS, + USD_VALUE_MAX_DECIMALS + )} + + + ) : null; +}; + +export function QuoteCostDetails(props: QuoteCostDetailsProps) { + const [open, setOpen] = useState(false); + const [openCollapse, setOpenCollapse] = useState(false); + const { + steps, + quote, + fee, + time, + feeWarning, + timeWarning, + showModalFee, + fullExpandedMode = false, + } = props; + const swaps = quote?.swaps ?? []; + const container = fullExpandedMode ? getExpanded() : getContainer(); + + const feesGroup = getFeesGroup(swaps); + + return ( + <> + { + e.stopPropagation(); + setOpen(!open); + } + : undefined + } + fee={fee} + feeWarning={feeWarning} + timeWarning={timeWarning} + time={time} + steps={steps} + tooltipGas={showModalFee ? i18n.t('View more info') : undefined} + tooltipContainer={container} + /> + + + + {i18n.t('Gas & Fee Explanation')} + + + setOpen(false)} + variant="ghost"> + + + + } + onClose={() => { + setOpen(false); + }}> + + + {i18n.t('Details')} + + + {Object.entries(feesGroup.payable).flatMap( + ([payableFeesKey, feeArray]) => + feeArray.map((fee, index) => { + const key = `payable-fee-${index}`; + const usdValue = getUsdFee(fee); + return ( + + + {getFeeLabel(payableFeesKey as NameOfFees, i18n.t)} + + + + {numberToString( + fee.amount, + GAS_FEE_MIN_DECIMALS, + GAS_FEE_MAX_DECIMALS + )}{' '} + {fee.asset.symbol} ($ + {numberToString( + usdValue, + USD_VALUE_MIN_DECIMALS, + USD_VALUE_MAX_DECIMALS + )} + ) + + + + ); + }) + )} + + + + {i18n.t('Total Payable Fee')} + + + $ + {numberToString( + fee, + USD_VALUE_MIN_DECIMALS, + USD_VALUE_MAX_DECIMALS + )} + + + + {Object.keys(feesGroup.nonePayable).length && ( + setOpenCollapse((prev) => !prev)} + trigger={ +
+ + {openCollapse + ? i18n.t('Hide non-payable fees') + : i18n.t('Show non-payable fees')} + + + + + +
+ } + open={openCollapse}> + + {i18n.t('Description')} + + + + {i18n.t(`The following fees are considered in the transaction output and + you won’t need to pay extra gas for them.`)} + + + {Object.entries(feesGroup.nonePayable).map( + ([nonPayableFeesKey, fees], index) => { + const totalFeeInUsd = getTotalFeesInUsd(fees); + const label = getFeeLabel( + nonPayableFeesKey as NameOfFees, + i18n.t + ); + const key = `non-payable-fee-${index}`; + return ( + + ); + } + )} + + +
+ )} +
+
+ + ); +} diff --git a/widget/embedded/src/components/Quote/QuoteSummary.styles.ts b/widget/embedded/src/components/Quote/QuoteSummary.styles.ts new file mode 100644 index 0000000000..eb6fea95d3 --- /dev/null +++ b/widget/embedded/src/components/Quote/QuoteSummary.styles.ts @@ -0,0 +1,16 @@ +import { css, styled } from '@rango-dev/ui'; + +export const Container = styled('div', { + position: 'relative', + display: 'flex', + flexDirection: 'column', + width: '100%', +}); + +export const separatorStyles = css({ + height: '14px', + marginLeft: '14px', + position: 'absolute', + borderLeft: '1px solid $foreground', + top: '42%', +}); diff --git a/widget/embedded/src/components/Quote/QuoteSummary.tsx b/widget/embedded/src/components/Quote/QuoteSummary.tsx new file mode 100644 index 0000000000..b5ee6fc441 --- /dev/null +++ b/widget/embedded/src/components/Quote/QuoteSummary.tsx @@ -0,0 +1,62 @@ +import type { PriceImpactWarningLevel, Step } from '@rango-dev/ui'; + +import { i18n } from '@lingui/core'; +import { TokenAmount } from '@rango-dev/ui'; +import React from 'react'; + +import { getContainer } from '../../utils/common'; + +import { Container, separatorStyles } from './QuoteSummary.styles'; + +type PropTypes = { + from: Step['from']; + to: Step['to']; + percentageChange?: string | null; + warningLevel: PriceImpactWarningLevel; +}; + +export function QuoteSummary(props: PropTypes) { + const { from, to, percentageChange, warningLevel } = props; + + return ( + + +
+ + + ); +} diff --git a/widget/embedded/src/components/Quote/QuoteTrigger.tsx b/widget/embedded/src/components/Quote/QuoteTrigger.tsx new file mode 100644 index 0000000000..d4c38d3c0a --- /dev/null +++ b/widget/embedded/src/components/Quote/QuoteTrigger.tsx @@ -0,0 +1,215 @@ +import type { QuoteTriggerImagesProps, QuoteTriggerProps } from './Quote.types'; + +import { i18n } from '@lingui/core'; +import { + ChevronDownIcon, + ChevronRightIcon, + Divider, + Image, + Tooltip, + Typography, +} from '@rango-dev/ui'; +import React from 'react'; + +import useScreenDetect from '../../hooks/useScreenDetect'; +import { getContainer } from '../../utils/common'; +import { getUniqueBlockchains } from '../../utils/quote'; + +import { + IconContainer, + ImageContainer, + MoreStep, + rowStyles, + Trigger, +} from './Quote.styles'; + +const MAX_STEPS = 4; +const MAX_BLOCKCHAINS = 6; + +const ImageComponent = (props: QuoteTriggerImagesProps) => { + const { content, src, className, open, state, container } = props; + const tooltipContainer = container || getContainer(); + return ( + + + + + + ); +}; + +export function QuoteTrigger(props: QuoteTriggerProps) { + const { quoteRef, selected, setExpanded, steps, expanded, type, container } = + props; + const tooltipContainer = container || getContainer(); + const numberOfSteps = steps.length; + const blockchains = getUniqueBlockchains(steps); + const { isTablet, isMobile } = useScreenDetect(); + + return ( + (quoteRef.current = ref)} + selected={selected} + onClick={(e) => { + e.stopPropagation(); + setExpanded((prevState) => !prevState); + }}> +
+ + {i18n.t('Via:')} + + + {steps.map((step, index) => { + const key = `item-${index}`; + const arrow = ( + + + + ); + + return isMobile || isTablet ? ( + + + {index !== numberOfSteps - 1 && <>{arrow}} + + ) : ( + + {numberOfSteps <= MAX_STEPS || + (numberOfSteps > MAX_STEPS && index < MAX_STEPS - 1) ? ( + <> + + {index !== numberOfSteps - 1 && <>{arrow}} + + ) : ( + index === MAX_STEPS - 1 && ( + + {arrow} + {steps.map((step, i) => { + const key = `image-${i}`; + return ( + i >= index && ( + + + {i !== numberOfSteps - 1 && <>{arrow}} + + ) + ); + })} +
+ }> + + i >= index && + (step.state === 'error' || step.state === 'warning') + )?.state + }> + + +{numberOfSteps - index} + + + + ) + )} + + ); + })} +
+
+
+
+ + {i18n.t('Chains:')} + + + {blockchains.map((blockchain, index) => ( + + {blockchains.length <= MAX_BLOCKCHAINS || + (blockchains.length > MAX_BLOCKCHAINS && + index < MAX_BLOCKCHAINS - 1) ? ( + + + + ) : ( + index === MAX_BLOCKCHAINS - 1 && ( + + {blockchains.map( + (chain, i) => + i >= index && ( + index ? 'blockchainImage' : ''} + container={container} + /> + ) + )} +
+ }> + + + +{blockchains.length - index} + + + + ) + )} + + ))} + + +
+
+ + + + +
+ + ); +} diff --git a/widget/embedded/src/components/Quote/index.ts b/widget/embedded/src/components/Quote/index.ts new file mode 100644 index 0000000000..42c3af0e0a --- /dev/null +++ b/widget/embedded/src/components/Quote/index.ts @@ -0,0 +1,2 @@ +export { Quote } from './Quote'; +export { QuoteSummary } from './QuoteSummary'; diff --git a/widget/embedded/src/components/QuoteSkeleton/QuoteSkeleton.styles.ts b/widget/embedded/src/components/QuoteSkeleton/QuoteSkeleton.styles.ts new file mode 100644 index 0000000000..cd11a563e3 --- /dev/null +++ b/widget/embedded/src/components/QuoteSkeleton/QuoteSkeleton.styles.ts @@ -0,0 +1,50 @@ +import { darkTheme, styled } from '@rango-dev/ui'; + +export const Container = styled('div', { + $$color: '$colors$neutral100', + [`.${darkTheme} &`]: { + $$color: '$colors$neutral300', + }, + backgroundColor: '$$color', + borderBottomLeftRadius: '$xm', + borderBottomRightRadius: '$xm', + padding: '$15', + variants: { + rounded: { + true: { + borderRadius: '$xm', + }, + }, + expanded: { + true: { + paddingBottom: '3px', + }, + false: { + paddingBottom: '$12', + }, + }, + }, +}); + +export const Chains = styled('div', { + paddingTop: '$2', +}); + +export const Steps = styled('div', { + paddingLeft: '$8', +}); + +export const StepSeparator = styled('div', { + borderLeft: '1px dashed $foreground', + minHeight: ' 0', + margin: '0px 11.5px', + alignSelf: 'stretch', + variants: { + hideSeparator: { + true: { + minHeight: 'unset', + height: '0', + }, + }, + }, +}); diff --git a/widget/embedded/src/components/QuoteSkeleton/QuoteSkeleton.tsx b/widget/embedded/src/components/QuoteSkeleton/QuoteSkeleton.tsx new file mode 100644 index 0000000000..d072420005 --- /dev/null +++ b/widget/embedded/src/components/QuoteSkeleton/QuoteSkeleton.tsx @@ -0,0 +1,30 @@ +import type { PropTypes } from './QuoteSkeleton.types'; + +import { Divider, Skeleton } from '@rango-dev/ui'; +import React from 'react'; + +import { Chains, Container, Steps } from './QuoteSkeleton.styles'; +import { QuoteSummarySkeleton } from './QuoteSummarySkeleton'; +import { StepSkeleton } from './StepSkeleton'; + +export function QuoteSkeleton(props: PropTypes) { + const { type, expanded, tagHidden = false } = props; + + return ( + + + + + + + {expanded && ( + + + + + + + )} + + ); +} diff --git a/widget/embedded/src/components/QuoteSkeleton/QuoteSkeleton.types.ts b/widget/embedded/src/components/QuoteSkeleton/QuoteSkeleton.types.ts new file mode 100644 index 0000000000..c8169bb499 --- /dev/null +++ b/widget/embedded/src/components/QuoteSkeleton/QuoteSkeleton.types.ts @@ -0,0 +1,7 @@ +import type { QuoteProps } from '../Quote/Quote.types'; + +export type PropTypes = { + type: QuoteProps['type']; + expanded?: boolean; + tagHidden?: boolean; +}; diff --git a/widget/embedded/src/components/QuoteSkeleton/QuoteSummarySkeleton.styles.ts b/widget/embedded/src/components/QuoteSkeleton/QuoteSummarySkeleton.styles.ts new file mode 100644 index 0000000000..66a654b45e --- /dev/null +++ b/widget/embedded/src/components/QuoteSkeleton/QuoteSummarySkeleton.styles.ts @@ -0,0 +1,55 @@ +import { css, styled } from '@rango-dev/ui'; + +export const FlexContent = styled('div', { + display: 'flex', +}); + +export const BasicSummary = styled('div', { + padding: '$10 $0 $20', +}); + +export const Output = styled('div', { + padding: '14px $0 $20 $0', + display: 'flex', + flexDirection: 'column', +}); + +export const OutputTokenInfo = styled('div', { + display: 'flex', + justifyContent: 'start', + alignItems: 'center', +}); + +export const QuoteSummary = styled('div', { + display: 'flex', + justifyContent: 'space-between', + alignItems: 'end', +}); + +export const QuoteSummarySeparator = styled('div', { + height: '$24', + marginLeft: '13px', + borderLeft: '1px solid $neutral700', +}); + +export const TokenAmount = styled('div', { + width: '65%', + display: 'flex', + justifyContent: 'start', +}); + +export const TokenAmountLabel = styled('div', { + display: 'flex', + flexDirection: 'column', + alignItems: 'start', + flexGrow: 1, + maxWidth: '148px', +}); + +export const SwapPreview = styled('div', { padding: '$15 $0 $15 $0' }); + +export const RowStyle = css({ + display: 'flex', + justifyContent: 'space-between', + alignItems: 'center', +}); diff --git a/widget/embedded/src/components/QuoteSkeleton/QuoteSummarySkeleton.tsx b/widget/embedded/src/components/QuoteSkeleton/QuoteSummarySkeleton.tsx new file mode 100644 index 0000000000..cfbb696148 --- /dev/null +++ b/widget/embedded/src/components/QuoteSkeleton/QuoteSummarySkeleton.tsx @@ -0,0 +1,96 @@ +import type { PropTypes } from './QuoteSummarySkeleton.types'; + +import { ChainToken, Divider, Skeleton } from '@rango-dev/ui'; +import React from 'react'; + +import { Line } from '../Quote/Quote.styles'; + +import { + BasicSummary, + FlexContent, + Output, + OutputTokenInfo, + QuoteSummary, + QuoteSummarySeparator, + RowStyle, + SwapPreview, + TokenAmount, + TokenAmountLabel, +} from './QuoteSummarySkeleton.styles'; + +export function QuoteSummarySkeleton(props: PropTypes) { + const { type, tagHidden = true } = props; + const quotePreview = ( + + + + + + + + + + + + + ); + const showAllRoutesSkeleton = type === 'basic' && !tagHidden; + + return ( +
+ {!tagHidden && ( + <> + + + + + + + + + {!showAllRoutesSkeleton && } + + )} +
+ + + + + + + + {showAllRoutesSkeleton && ( + + )} +
+ + {type === 'basic' && ( + + + + )} + {type === 'list-item' && ( + + + + + + + + + + )} + {type === 'swap-preview' && ( + <> + + + {quotePreview} + + {quotePreview} + + + + )} +
+ ); +} diff --git a/widget/embedded/src/components/QuoteSkeleton/QuoteSummarySkeleton.types.ts b/widget/embedded/src/components/QuoteSkeleton/QuoteSummarySkeleton.types.ts new file mode 100644 index 0000000000..f6e8e1e798 --- /dev/null +++ b/widget/embedded/src/components/QuoteSkeleton/QuoteSummarySkeleton.types.ts @@ -0,0 +1,6 @@ +import type { QuoteProps } from '../Quote/Quote.types'; + +export type PropTypes = { + type: QuoteProps['type']; + tagHidden?: boolean; +}; diff --git a/widget/embedded/src/components/QuoteSkeleton/StepSkeleton.styles.ts b/widget/embedded/src/components/QuoteSkeleton/StepSkeleton.styles.ts new file mode 100644 index 0000000000..7d362a8785 --- /dev/null +++ b/widget/embedded/src/components/QuoteSkeleton/StepSkeleton.styles.ts @@ -0,0 +1,40 @@ +import { styled } from '@rango-dev/ui'; + +export const StepContent = styled('div', { + display: 'flex', + alignItems: 'start', +}); + +export const StepTokens = styled('div', { + flexGrow: 1, + paddingTop: '$5', + paddingBottom: '$10', + display: 'flex', + alignItems: 'center', + variants: { + extraSpace: { + true: { + paddingBottom: '$40', + }, + }, + }, +}); + +export const StepTokenInfo = styled('div', { + display: 'flex', + alignItems: 'center', + flexGrow: 1, +}); + +export const StepIconContainer = styled('div', { + margin: '$0 $2', + padding: '$4', + display: 'flex', + justifyContent: 'center', + alignItems: 'center', +}); + +export const StepTitle = styled('div', { + display: 'flex', + alignItems: 'center', +}); diff --git a/widget/embedded/src/components/QuoteSkeleton/StepSkeleton.tsx b/widget/embedded/src/components/QuoteSkeleton/StepSkeleton.tsx new file mode 100644 index 0000000000..a385f9f6fa --- /dev/null +++ b/widget/embedded/src/components/QuoteSkeleton/StepSkeleton.tsx @@ -0,0 +1,44 @@ +import type { PropTypes } from './StepSkeleton.types'; + +import { ChainToken, Divider, NextIcon, Skeleton } from '@rango-dev/ui'; +import React from 'react'; + +import { StepSeparator } from './QuoteSkeleton.styles'; +import { + StepContent, + StepIconContainer, + StepTitle, + StepTokenInfo, + StepTokens, +} from './StepSkeleton.styles'; + +export function StepSkeleton(props: PropTypes) { + const { separator = true } = props; + return ( + <> + + + + + + + + + + + + + + + + + + + + + + + + + ); +} diff --git a/widget/embedded/src/components/QuoteSkeleton/StepSkeleton.types.ts b/widget/embedded/src/components/QuoteSkeleton/StepSkeleton.types.ts new file mode 100644 index 0000000000..ea57cbd71c --- /dev/null +++ b/widget/embedded/src/components/QuoteSkeleton/StepSkeleton.types.ts @@ -0,0 +1 @@ +export type PropTypes = { separator?: boolean }; diff --git a/widget/embedded/src/components/QuoteSkeleton/index.ts b/widget/embedded/src/components/QuoteSkeleton/index.ts new file mode 100644 index 0000000000..a6e738d358 --- /dev/null +++ b/widget/embedded/src/components/QuoteSkeleton/index.ts @@ -0,0 +1,3 @@ +export { QuoteSkeleton } from './QuoteSkeleton'; +export { StepSkeleton } from './StepSkeleton'; +export { QuoteSummarySkeleton } from './QuoteSummarySkeleton'; diff --git a/widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx b/widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx new file mode 100644 index 0000000000..2440e622d7 --- /dev/null +++ b/widget/embedded/src/components/QuoteWarningsAndErrors/HighValueLossWarningModal.tsx @@ -0,0 +1,114 @@ +import type { HighValueLossWarning } from '../../types'; + +import { i18n } from '@lingui/core'; +import { + Button, + Divider, + MessageBox, + Typography, + WarningIcon, +} from '@rango-dev/ui'; +import React from 'react'; + +import { errorMessages } from '../../constants/errors'; +import { + GAS_FEE_MAX_DECIMALS, + GAS_FEE_MIN_DECIMALS, + PERCENTAGE_CHANGE_MAX_DECIMALS, + PERCENTAGE_CHANGE_MIN_DECIMALS, + USD_VALUE_MAX_DECIMALS, + USD_VALUE_MIN_DECIMALS, +} from '../../constants/routing'; +import { getContainer } from '../../utils/common'; +import { numberToString } from '../../utils/numbers'; +import { WatermarkedModal } from '../common/WatermarkedModal'; + +import { QuoteErrorsModalItem } from './QuoteErrorsModalItem'; +import { Flex } from './QuoteWarningsAndErrors.styles'; + +type Props = { + open: boolean; + confirmationDisabled: boolean; + onClose: () => void; + onConfirm: () => void; + warning: HighValueLossWarning; +}; + +export function HighValueLossWarningModal(props: Props) { + const { open, onClose, onConfirm, warning, confirmationDisabled } = props; + const type = warning.warningLevel === 'high' ? 'error' : 'warning'; + + const highValueLossData = [ + { + title: i18n.t('Swapping'), + value: numberToString( + warning.inputUsdValue, + USD_VALUE_MIN_DECIMALS, + USD_VALUE_MAX_DECIMALS + ), + }, + { + title: i18n.t('Gas cost'), + value: numberToString( + warning.totalFee, + GAS_FEE_MIN_DECIMALS, + GAS_FEE_MAX_DECIMALS + ), + }, + { + title: i18n.t('Receiving'), + value: numberToString( + warning.outputUsdValue, + USD_VALUE_MIN_DECIMALS, + USD_VALUE_MAX_DECIMALS + ), + }, + { + title: i18n.t('Price impact'), + value: numberToString( + warning.priceImpact, + PERCENTAGE_CHANGE_MIN_DECIMALS, + PERCENTAGE_CHANGE_MAX_DECIMALS + ), + valueColor: `${type}500`, + }, + ]; + + return ( + } + fullWidth + disabled={confirmationDisabled} + onClick={onConfirm}> + {errorMessages().highValueLossError.confirmMessage} + + } + open={open} + onClose={onClose} + container={getContainer()}> + + + + + + {i18n.t('Details')} + + + {highValueLossData.map((item, index) => { + const key = index; + return ; + })} + + + + ); +} diff --git a/widget/embedded/src/components/QuoteWarningsAndErrors/QuoteErrorsModalItem.tsx b/widget/embedded/src/components/QuoteWarningsAndErrors/QuoteErrorsModalItem.tsx new file mode 100644 index 0000000000..cdfb0c154c --- /dev/null +++ b/widget/embedded/src/components/QuoteWarningsAndErrors/QuoteErrorsModalItem.tsx @@ -0,0 +1,24 @@ +import type { ModalContentData } from './QuoteWarningsAndErrors.types'; + +import { Typography } from '@rango-dev/ui'; +import React from 'react'; + +import { Item } from './QuoteWarningsAndErrors.styles'; + +export function QuoteErrorsModalItem(props: ModalContentData) { + const { title, value, valueColor } = props; + + return ( + + + {title} + + + {`${valueColor ? '%' : '$'}${value}`} + + + ); +} diff --git a/widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts b/widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts new file mode 100644 index 0000000000..40481b7c32 --- /dev/null +++ b/widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.helpers.ts @@ -0,0 +1,94 @@ +import type { + BridgeLimitError, + InsufficientSlippageError, + QuoteWarning, +} from '../../types'; + +import { i18n } from '@lingui/core'; + +import { errorMessages } from '../../constants/errors'; +import { QuoteErrorType, QuoteWarningType } from '../../types'; +import { getPriceImpactLevel } from '../../utils/quote'; + +type AlertInfo = { + alertType: 'error' | 'warning'; + title: string; + action: 'show-info' | 'change-settings' | null; +}; + +export function makeAlerts( + warning: QuoteWarning | null, + error: BridgeLimitError | InsufficientSlippageError | null +): AlertInfo | null { + const alertInfo: AlertInfo = { + alertType: 'warning', + title: '', + action: null, + }; + if (error) { + alertInfo.alertType = 'error'; + if (error.type === QuoteErrorType.BRIDGE_LIMIT) { + alertInfo.title = error.recommendation; + } + + if (error.type === QuoteErrorType.INSUFFICIENT_SLIPPAGE) { + alertInfo.title = i18n.t({ + id: 'You need to increase slippage to at least {minRequiredSlippage} for this route.', + values: { + minRequiredSlippage: error.minRequiredSlippage, + }, + }); + alertInfo.action = 'change-settings'; + } + + return alertInfo; + } + if (warning) { + switch (warning.type) { + case QuoteWarningType.HIGH_VALUE_LOSS: { + const warningLevel = getPriceImpactLevel(warning.priceImpact); + if (warningLevel === 'high') { + alertInfo.alertType = 'error'; + } + alertInfo.action = 'show-info'; + alertInfo.title = errorMessages().highValueLossError.title; + break; + } + case QuoteWarningType.EXCESSIVE_OUTPUT_AMOUNT_CHANGE: { + alertInfo.title = i18n.t({ + id: 'Output amount changed by {percentageChange}% (${usdValueChange}).', + values: { + percentageChange: warning.percentageChange, + usdValueChange: warning.usdValueChange, + }, + }); + break; + } + case QuoteWarningType.UNKNOWN_PRICE: { + alertInfo.title = errorMessages().unknownPriceError.title; + break; + } + case QuoteWarningType.INSUFFICIENT_SLIPPAGE: { + alertInfo.title = i18n.t({ + id: 'We recommend you to increase slippage to at least {minRequiredSlippage} for this route.', + values: { + minRequiredSlippage: warning.minRequiredSlippage, + }, + }); + alertInfo.action = 'change-settings'; + break; + } + case QuoteWarningType.HIGH_SLIPPAGE: { + alertInfo.title = i18n.t('Caution, your slippage is high.'); + alertInfo.action = 'change-settings'; + break; + } + + default: + break; + } + + return alertInfo; + } + return null; +} diff --git a/widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.styles.ts b/widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.styles.ts new file mode 100644 index 0000000000..328ea7306c --- /dev/null +++ b/widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.styles.ts @@ -0,0 +1,34 @@ +import { darkTheme, styled } from '@rango-dev/ui'; + +export const Alerts = styled('div', { + width: '100%', +}); + +export const Flex = styled('div', { + display: 'flex', + flexDirection: 'column', + alignItems: 'flex-start', + gap: '$5', + width: '100%', +}); + +export const Item = styled('div', { + display: 'flex', + padding: '$5 0', + justifyContent: 'space-between', + alignItems: 'center', + width: '100%', + '._title': { + $$color: '$colors$neutral600', + [`.${darkTheme} &`]: { + $$color: '$colors$neutral700', + }, + color: '$$color', + }, +}); + +export const Action = styled('div', { + padding: '$2', + alignSelf: 'flex-start', + cursor: 'pointer', +}); diff --git a/widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.tsx b/widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.tsx new file mode 100644 index 0000000000..b1874144c7 --- /dev/null +++ b/widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.tsx @@ -0,0 +1,110 @@ +import type { PropTypes } from './QuoteWarningsAndErrors.types'; + +import { i18n } from '@lingui/core'; +import { Alert, Button, InfoIcon } from '@rango-dev/ui'; +import React from 'react'; + +import { QuoteErrorType, QuoteWarningType } from '../../types'; +import { NoResult } from '../NoResult'; + +import { HighValueLossWarningModal } from './HighValueLossWarningModal'; +import { makeAlerts } from './QuoteWarningsAndErrors.helpers'; +import { Action, Alerts } from './QuoteWarningsAndErrors.styles'; +import { SlippageWarningModal } from './SlippageWariningModal'; +import { UnknownPriceWarningModal } from './UnknownPriceWarningModal'; + +export function QuoteWarningsAndErrors(props: PropTypes) { + const { + warning, + error, + couldChangeSettings, + showWarningModal, + confirmationDisabled, + refetchQuote, + onOpenWarningModal, + onCloseWarningModal, + onConfirmWarningModal, + onChangeSettings, + } = props; + + const warningModalHandlers = { + confirmationDisabled, + open: showWarningModal, + onClose: onCloseWarningModal, + onConfirm: onConfirmWarningModal, + }; + + const showNoResultMessage = + error?.type === QuoteErrorType.NO_RESULT || + error?.type === QuoteErrorType.REQUEST_FAILED; + + const alertInfo = makeAlerts( + warning, + error?.type === QuoteErrorType.BRIDGE_LIMIT || + error?.type === QuoteErrorType.INSUFFICIENT_SLIPPAGE + ? error + : null + ); + if (alertInfo && !couldChangeSettings) { + alertInfo.action = null; + } + + const showAlerts = !!alertInfo; + + return ( + <> + {showNoResultMessage && } + + {showAlerts && ( + + + + + ), + })} + {...(alertInfo.action === 'change-settings' && { + action: ( + + ), + })} + /> + + )} + + {warning && ( + <> + {warning.type === QuoteWarningType.HIGH_VALUE_LOSS && ( + + )} + + {(warning.type === QuoteWarningType.HIGH_SLIPPAGE || + warning.type === QuoteWarningType.INSUFFICIENT_SLIPPAGE) && ( + + )} + + {warning.type === QuoteWarningType.UNKNOWN_PRICE && ( + + )} + + )} + + ); +} diff --git a/widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.types.ts b/widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.types.ts new file mode 100644 index 0000000000..ba1b75d5b7 --- /dev/null +++ b/widget/embedded/src/components/QuoteWarningsAndErrors/QuoteWarningsAndErrors.types.ts @@ -0,0 +1,26 @@ +import type { QuoteError, QuoteWarning } from '../../types'; + +export interface PropTypes { + error: QuoteError | null; + warning: QuoteWarning | null; + showWarningModal: boolean; + confirmationDisabled: boolean; + couldChangeSettings: boolean; + refetchQuote: () => void; + onOpenWarningModal: () => void; + onCloseWarningModal: () => void; + onConfirmWarningModal: () => void; + onChangeSettings: () => void; +} + +type ModalPropTypesKeys = keyof Omit; + +export type ModalPropTypes = Pick & { + open: boolean; +}; + +export interface ModalContentData { + title: string; + value: string; + valueColor?: string; +} diff --git a/widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx b/widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx new file mode 100644 index 0000000000..9778c143f9 --- /dev/null +++ b/widget/embedded/src/components/QuoteWarningsAndErrors/SlippageWariningModal.tsx @@ -0,0 +1,83 @@ +import type { + HighSlippageWarning, + InsufficientSlippageWarning, +} from '../../types'; + +import { i18n } from '@lingui/core'; +import { Button, Divider, MessageBox, Typography } from '@rango-dev/ui'; +import React from 'react'; +import { useNavigate } from 'react-router-dom'; + +import { navigationRoutes } from '../../constants/navigationRoutes'; +import { useAppStore } from '../../store/AppStore'; +import { QuoteWarningType } from '../../types'; +import { getContainer } from '../../utils/common'; +import { WatermarkedModal } from '../common/WatermarkedModal'; + +type PropsTypes = { + open: boolean; + confirmationDisabled: boolean; + onClose: () => void; + onConfirm: () => void; + warning: InsufficientSlippageWarning | HighSlippageWarning; +}; + +export function SlippageWarningModal(props: PropsTypes) { + const { customSlippage, slippage } = useAppStore(); + const { open, onClose, onConfirm, warning, confirmationDisabled } = props; + const navigate = useNavigate(); + const userSlippage = customSlippage ?? slippage; + + return ( + navigate('../' + navigationRoutes.settings)}> + + {i18n.t('Change settings')} + + + } + container={getContainer()} + onClose={onClose}> + + + + + + + ); +} diff --git a/widget/embedded/src/components/QuoteWarningsAndErrors/UnknownPriceWarningModal.tsx b/widget/embedded/src/components/QuoteWarningsAndErrors/UnknownPriceWarningModal.tsx new file mode 100644 index 0000000000..97040dba37 --- /dev/null +++ b/widget/embedded/src/components/QuoteWarningsAndErrors/UnknownPriceWarningModal.tsx @@ -0,0 +1,44 @@ +import type { UnknownPriceWarning } from '../../types'; + +import { Button, MessageBox, WarningIcon } from '@rango-dev/ui'; +import React from 'react'; + +import { errorMessages } from '../../constants/errors'; +import { getContainer } from '../../utils/common'; +import { WatermarkedModal } from '../common/WatermarkedModal'; + +type Props = { + open: boolean; + confirmationDisabled: boolean; + onClose: () => void; + onConfirm: () => void; + warning: UnknownPriceWarning; +}; + +export function UnknownPriceWarningModal(props: Props) { + const { open, onClose, onConfirm, confirmationDisabled } = props; + return ( + } + fullWidth + disabled={confirmationDisabled} + onClick={onConfirm}> + {errorMessages().unknownPriceError.confirmMessage} + + } + open={open} + onClose={onClose} + container={getContainer()}> + + + ); +} diff --git a/widget/embedded/src/components/QuoteWarningsAndErrors/index.ts b/widget/embedded/src/components/QuoteWarningsAndErrors/index.ts new file mode 100644 index 0000000000..56b5106748 --- /dev/null +++ b/widget/embedded/src/components/QuoteWarningsAndErrors/index.ts @@ -0,0 +1 @@ +export { QuoteWarningsAndErrors } from './QuoteWarningsAndErrors'; diff --git a/widget/embedded/src/components/Quotes/Quotes.styles.ts b/widget/embedded/src/components/Quotes/Quotes.styles.ts new file mode 100644 index 0000000000..3a11075022 --- /dev/null +++ b/widget/embedded/src/components/Quotes/Quotes.styles.ts @@ -0,0 +1,18 @@ +import { styled } from '@rango-dev/ui'; + +export const ErrorsContainer = styled('div', { + display: 'flex', + justifyContent: 'center', + flexDirection: 'column', + height: '100%', +}); + +export const StrategyContent = styled('div', { + display: 'flex', + justifyContent: 'space-between', + alignItems: 'center', +}); + +export const SelectContainer = styled('div', { + width: '146px', +}); diff --git a/widget/embedded/src/components/Quotes/Quotes.tsx b/widget/embedded/src/components/Quotes/Quotes.tsx new file mode 100644 index 0000000000..78bed22983 --- /dev/null +++ b/widget/embedded/src/components/Quotes/Quotes.tsx @@ -0,0 +1,153 @@ +import type { PropTypes } from './Quotes.types'; +import type { MultiRouteSimulationResult } from 'rango-sdk'; + +import { i18n } from '@lingui/core'; +import { Divider, FullExpandedQuote, Typography } from '@rango-dev/ui'; +import React from 'react'; + +import { QuoteInfo } from '../../containers/QuoteInfo'; +import { getQuoteError } from '../../hooks/useConfirmSwap/useConfirmSwap.helpers'; +import { useAppStore } from '../../store/AppStore'; +import { useQuoteStore } from '../../store/quote'; +import { QuoteErrorType, type SelectedQuote } from '../../types'; +import { getContainer } from '../../utils/common'; +import { generateQuoteWarnings, sortQuotesBy } from '../../utils/quote'; +import { NoResult } from '../NoResult'; +import { QuoteSkeleton } from '../QuoteSkeleton'; + +import { ErrorsContainer, StrategyContent } from './Quotes.styles'; +import { SelectStrategy } from './SelectStrategy'; + +const ITEM_SKELETON_COUNT = 3; +export function Quotes(props: PropTypes) { + const { + loading, + onClickOnQuote, + fetch, + showModalFee, + hasSort = true, + fullExpandedMode = false, + container: propContainer, + } = props; + const { + selectedQuote, + quotes, + updateQuotePartialState, + fromToken, + toToken, + sortStrategy, + error, + } = useQuoteStore(); + const { slippage, customSlippage } = useAppStore(); + const { findToken } = useAppStore(); + const container = propContainer || getContainer(); + const hasQuotes = !!quotes && quotes.results.length; + const userSlippage = customSlippage ?? slippage; + const getQuoteWarning = (quote: MultiRouteSimulationResult) => { + if (!fromToken || !toToken || !quotes) { + return null; + } + const mergedQuote: SelectedQuote = { + requestAmount: quotes.requestAmount, // Assuming quotes is an array + validationStatus: null, + ...quote, + }; + + return generateQuoteWarnings({ + currentQuote: mergedQuote, + userSlippage, + findToken, + }); + }; + const showNoResultMessage = + error?.type === QuoteErrorType.NO_RESULT || + error?.type === QuoteErrorType.REQUEST_FAILED; + + const sortQuotes = quotes?.results + ? sortQuotesBy(sortStrategy, quotes?.results) + : []; + + return ( + <> + {hasSort && ( + <> + + + {i18n.t('Sort by')} + + + + + + )} + + {loading && + Array.from({ length: ITEM_SKELETON_COUNT }, (_, index) => ( + + {fullExpandedMode ? ( + + ) : ( + + )} + {index !== ITEM_SKELETON_COUNT - 1 && } + + ))} + + {!loading && ( + <> + {hasQuotes + ? sortQuotes.map((quote, index) => { + const quoteWarning = getQuoteWarning(quote); + const quoteError = getQuoteError(quote.swaps); + const lastIndex = sortQuotes.length - 1 === index; + + return ( + + { + if (!quoteError) { + updateQuotePartialState('warning', quoteWarning); + } + updateQuotePartialState( + 'error', + quoteError?.options || null + ); + onClickOnQuote(quote); + }} + type="list-item" + /> + {!lastIndex && } + + ); + }) + : showNoResultMessage && ( + + + + )} + + )} + + ); +} diff --git a/widget/embedded/src/components/Quotes/Quotes.types.ts b/widget/embedded/src/components/Quotes/Quotes.types.ts new file mode 100644 index 0000000000..1c2e1ee904 --- /dev/null +++ b/widget/embedded/src/components/Quotes/Quotes.types.ts @@ -0,0 +1,11 @@ +import type { SelectedQuote } from '../../types'; + +export type PropTypes = { + loading: boolean; + onClickOnQuote: (quote: SelectedQuote) => void; + fetch: (shouldChangeSelectedQuote?: boolean) => void; + showModalFee?: boolean; + hasSort?: boolean; + fullExpandedMode?: boolean; + container?: HTMLElement; +}; diff --git a/widget/embedded/src/components/Quotes/SelectStrategy.tsx b/widget/embedded/src/components/Quotes/SelectStrategy.tsx new file mode 100644 index 0000000000..4725e36f8f --- /dev/null +++ b/widget/embedded/src/components/Quotes/SelectStrategy.tsx @@ -0,0 +1,50 @@ +import type { PreferenceType } from 'rango-sdk'; + +import { i18n } from '@lingui/core'; +import { Select } from '@rango-dev/ui'; +import React from 'react'; + +import { useQuoteStore } from '../../store/quote'; + +import { SelectContainer } from './Quotes.styles'; + +export function SelectStrategy(props: { container: HTMLElement }) { + const { updateQuotePartialState, sortStrategy } = useQuoteStore(); + + const ROUTE_STRATEGY: { value: PreferenceType; label: string }[] = [ + { + value: 'SMART', + label: i18n.t('Smart Routing'), + }, + { + value: 'FEE', + label: i18n.t('Lowest Fee'), + }, + { + value: 'SPEED', + label: i18n.t('Fastest Transfer'), + }, + { + value: 'NET_OUTPUT', + label: i18n.t('Maximum Return'), + }, + { + value: 'PRICE', + label: i18n.t('Maximum Output'), + }, + ]; + + return ( + + ({ + value: derivationPath.id, + label: derivationPath.label, + }))} + variant="filled" + handleItemClick={handleDerivationPathItemClick} + styles={{ trigger: derivationPathInputStyles }} + /> + + + {isCustomOptionSelected + ? i18n.t('Enter Path') + : i18n.t('Enter Index')} + + setDerivationPathIndex(event.target.value)} + style={derivationPathInputStyles} + /> + + + + + ); +} diff --git a/widget/embedded/src/components/WalletStatefulConnect/DerivationPath.types.ts b/widget/embedded/src/components/WalletStatefulConnect/DerivationPath.types.ts new file mode 100644 index 0000000000..e00bd7ba17 --- /dev/null +++ b/widget/embedded/src/components/WalletStatefulConnect/DerivationPath.types.ts @@ -0,0 +1,6 @@ +import type { NeedsDerivationPathState } from '../../hooks/useStatefulConnect'; + +export interface PropTypes { + value: NeedsDerivationPathState; + onConfirm: (path: string) => void; +} diff --git a/widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx b/widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx new file mode 100644 index 0000000000..dd717ec432 --- /dev/null +++ b/widget/embedded/src/components/WalletStatefulConnect/ExperimentalChain.tsx @@ -0,0 +1,37 @@ +import { i18n } from '@lingui/core'; +import { Button, Divider, MessageBox } from '@rango-dev/ui'; +import React from 'react'; + +interface PropTypes { + displayName?: string; + onConfirm: () => void; +} + +export function ExperimentalChain(props: PropTypes) { + const { displayName, onConfirm } = props; + + return ( + + + + + + ); +} diff --git a/widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts b/widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts new file mode 100644 index 0000000000..0094d4ebee --- /dev/null +++ b/widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.helpers.ts @@ -0,0 +1,53 @@ +import type { PropTypes } from './ExperimentalChainStatus.types'; +import type { MessageType } from '@rango-dev/ui'; + +import { i18n } from '@lingui/core'; + +export function generateMessageByStatus( + status: PropTypes['status'], + blockchainDisplayName: string | undefined +): { + type: MessageType; + title: string; + description: string; +} { + switch (status) { + case 'in-progress': + return { + type: 'loading', + title: i18n.t({ + id: 'Add {blockchainDisplayName} Chain', + values: { blockchainDisplayName }, + }), + description: i18n.t({ + id: 'Please approve the experimental chain pop-up in your wallet.', + values: { blockchainDisplayName }, + }), + }; + case 'completed': + return { + type: 'success', + title: i18n.t({ + id: '{blockchainDisplayName} Chain Added', + values: { blockchainDisplayName }, + }), + description: i18n.t({ + id: 'The {blockchainDisplayName} chain has been successfully added to your wallet.', + values: { blockchainDisplayName }, + }), + }; + case 'rejected': + return { + type: 'error', + title: i18n.t('Request Rejected'), + description: i18n.t({ + id: "You've rejected adding {blockchainDisplayName} chain to your wallet.", + values: { blockchainDisplayName }, + }), + }; + default: + throw new Error( + `Showing information about an experimentation chain status needs to be defined first. status: ${status}` + ); + } +} diff --git a/widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.tsx b/widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.tsx new file mode 100644 index 0000000000..f3628d10f3 --- /dev/null +++ b/widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.tsx @@ -0,0 +1,36 @@ +import type { PropTypes } from './ExperimentalChainStatus.types'; + +import { Image, MessageBox } from '@rango-dev/ui'; +import React from 'react'; + +import { + LogoContainer, + Spinner, + WalletImageContainer, +} from '../ConfirmWalletsModal/WalletList.styles'; + +import { generateMessageByStatus } from './ExperimentalChainStatus.helpers'; + +export function ExperimentalChainStatus(props: PropTypes) { + const { status, displayName, image } = props; + const data = generateMessageByStatus(status, displayName); + const hasImage = status == 'in-progress'; + + return ( + + + + + + + ) : undefined + } + /> + ); +} diff --git a/widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.types.ts b/widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.types.ts new file mode 100644 index 0000000000..ad414ccbc7 --- /dev/null +++ b/widget/embedded/src/components/WalletStatefulConnect/ExperimentalChainStatus.types.ts @@ -0,0 +1,5 @@ +export interface PropTypes { + displayName?: string; + status: 'in-progress' | 'completed' | 'rejected'; + image: string; +} diff --git a/widget/embedded/src/components/WalletStatefulConnect/Namespaces.helpers.ts b/widget/embedded/src/components/WalletStatefulConnect/Namespaces.helpers.ts new file mode 100644 index 0000000000..cfbfbc1055 --- /dev/null +++ b/widget/embedded/src/components/WalletStatefulConnect/Namespaces.helpers.ts @@ -0,0 +1,9 @@ +import type { BlockchainMeta } from 'rango-types'; + +export function getBlockchainLogo( + blockchains: BlockchainMeta[], + blockchainName: string +) { + return blockchains.find((blockchain) => blockchain.name === blockchainName) + ?.logo; +} diff --git a/widget/embedded/src/components/WalletStatefulConnect/Namespaces.styles.ts b/widget/embedded/src/components/WalletStatefulConnect/Namespaces.styles.ts new file mode 100644 index 0000000000..e09567c8eb --- /dev/null +++ b/widget/embedded/src/components/WalletStatefulConnect/Namespaces.styles.ts @@ -0,0 +1,7 @@ +import { styled } from '@rango-dev/ui'; + +export const NamespaceList = styled('ul', { + padding: 0, + paddingTop: '$4', + paddingBottom: '$4', +}); diff --git a/widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx b/widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx new file mode 100644 index 0000000000..4d9193a06d --- /dev/null +++ b/widget/embedded/src/components/WalletStatefulConnect/Namespaces.tsx @@ -0,0 +1,113 @@ +import type { PropTypes } from './Namespaces.types'; +import type { Namespace } from '@rango-dev/wallets-core/namespaces/common'; + +import { i18n } from '@lingui/core'; +import { + Button, + Checkbox, + Divider, + Image, + ListItemButton, + MessageBox, + Radio, + RadioRoot, +} from '@rango-dev/ui'; +import React, { useState } from 'react'; + +import { useAppStore } from '../../store/AppStore'; +import { WalletImageContainer } from '../HeaderButtons/HeaderButtons.styles'; + +import { LogoContainer, Spinner } from './ConnectStatus.styles'; +import { getBlockchainLogo } from './Namespaces.helpers'; +import { NamespaceList } from './Namespaces.styles'; + +export function Namespaces(props: PropTypes) { + const { targetWallet } = props.value; + const singleNamespace = targetWallet.needsNamespace?.selection === 'single'; + const providerImage = targetWallet.image; + + const [selectedNamespaces, setSelectedNamespaces] = useState([]); + + const blockchains = useAppStore().blockchains(); + + const onSelect = (namespace: Namespace) => { + if (singleNamespace) { + setSelectedNamespaces([namespace]); + } else { + setSelectedNamespaces((selectedNamespaces) => + selectedNamespaces.includes(namespace) + ? selectedNamespaces.filter((item) => item !== namespace) + : selectedNamespaces.concat(namespace) + ); + } + }; + + const wrapRadioRoot = (children: React.ReactNode) => { + if (singleNamespace) { + return {children}; + } + + return <>{children}; + }; + + return ( + <> + + + + + + + + } + /> + + {wrapRadioRoot( + <> + {targetWallet.needsNamespace?.data.map((ns) => { + return ( + onSelect(ns.value)} + start={ + + } + end={ + singleNamespace ? ( + + ) : ( + + ) + } + /> + ); + })} + + )} + + + + ); +} diff --git a/widget/embedded/src/components/WalletStatefulConnect/Namespaces.types.tsx b/widget/embedded/src/components/WalletStatefulConnect/Namespaces.types.tsx new file mode 100644 index 0000000000..4d9656f6ba --- /dev/null +++ b/widget/embedded/src/components/WalletStatefulConnect/Namespaces.types.tsx @@ -0,0 +1,7 @@ +import type { NeedsNamespacesState } from '../../hooks/useStatefulConnect'; +import type { Namespace } from '@rango-dev/wallets-core/namespaces/common'; + +export interface PropTypes { + onConfirm: (namespaces: Namespace[]) => void; + value: NeedsNamespacesState; +} diff --git a/widget/embedded/src/components/WalletStatefulConnect/index.ts b/widget/embedded/src/components/WalletStatefulConnect/index.ts new file mode 100644 index 0000000000..d15b964819 --- /dev/null +++ b/widget/embedded/src/components/WalletStatefulConnect/index.ts @@ -0,0 +1,4 @@ +export { Namespaces } from './Namespaces'; +export { DerivationPath } from './DerivationPath'; +export { ConnectStatus } from './ConnectStatus'; +export { ExperimentalChain } from './ExperimentalChain'; diff --git a/widget/embedded/src/components/common/ActivateTabAlert/ActivateTabAlert.tsx b/widget/embedded/src/components/common/ActivateTabAlert/ActivateTabAlert.tsx new file mode 100644 index 0000000000..3512e6d255 --- /dev/null +++ b/widget/embedded/src/components/common/ActivateTabAlert/ActivateTabAlert.tsx @@ -0,0 +1,25 @@ +import type { PropTypes } from './ActivateTabAlert.types'; + +import { i18n } from '@lingui/core'; +import { Alert, Button } from '@rango-dev/ui'; +import React from 'react'; + +export function ActivateTabAlert(props: PropTypes) { + return ( + + {i18n.t('Activate this tab')} + + } + type="warning" + variant="alarm" + title={i18n.t('Another tab is open and handles transactions.')} + /> + ); +} diff --git a/widget/embedded/src/components/common/ActivateTabAlert/ActivateTabAlert.types.ts b/widget/embedded/src/components/common/ActivateTabAlert/ActivateTabAlert.types.ts new file mode 100644 index 0000000000..c2f8eef149 --- /dev/null +++ b/widget/embedded/src/components/common/ActivateTabAlert/ActivateTabAlert.types.ts @@ -0,0 +1,3 @@ +export type PropTypes = { + onActivateTab: () => void; +}; diff --git a/widget/embedded/src/components/common/ActivateTabAlert/index.ts b/widget/embedded/src/components/common/ActivateTabAlert/index.ts new file mode 100644 index 0000000000..f9a75a04c8 --- /dev/null +++ b/widget/embedded/src/components/common/ActivateTabAlert/index.ts @@ -0,0 +1 @@ +export { ActivateTabAlert } from './ActivateTabAlert'; diff --git a/widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx b/widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx new file mode 100644 index 0000000000..bfc527ee76 --- /dev/null +++ b/widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.tsx @@ -0,0 +1,38 @@ +import type { PropTypes } from './ActivateTabModal.types'; + +import { i18n } from '@lingui/core'; +import { Button, Divider, MessageBox } from '@rango-dev/ui'; +import React from 'react'; + +import { getContainer } from '../../../utils/common'; +import { WatermarkedModal } from '../WatermarkedModal'; + +export function ActivateTabModal(props: PropTypes) { + const { open, onClose, onConfirm } = props; + + return ( + + + + + + + ); +} diff --git a/widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.types.ts b/widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.types.ts new file mode 100644 index 0000000000..890b8ff8fd --- /dev/null +++ b/widget/embedded/src/components/common/ActivateTabModal/ActivateTabModal.types.ts @@ -0,0 +1,5 @@ +export type PropTypes = { + open: boolean; + onClose: () => void; + onConfirm: () => void; +}; diff --git a/widget/embedded/src/components/common/ActivateTabModal/index.ts b/widget/embedded/src/components/common/ActivateTabModal/index.ts new file mode 100644 index 0000000000..995595a755 --- /dev/null +++ b/widget/embedded/src/components/common/ActivateTabModal/index.ts @@ -0,0 +1 @@ +export { ActivateTabModal } from './ActivateTabModal'; diff --git a/widget/embedded/src/components/common/WatermarkedModal/WatermarkedModal.tsx b/widget/embedded/src/components/common/WatermarkedModal/WatermarkedModal.tsx new file mode 100644 index 0000000000..c3643a0f71 --- /dev/null +++ b/widget/embedded/src/components/common/WatermarkedModal/WatermarkedModal.tsx @@ -0,0 +1,18 @@ +import type { ModalPropTypes } from '@rango-dev/ui'; +import type { PropsWithChildren } from 'react'; + +import { Modal } from '@rango-dev/ui'; +import React from 'react'; + +import { useUiStore } from '../../../store/ui'; + +export function WatermarkedModal(props: PropsWithChildren) { + const { watermark } = useUiStore(); + + const hasWatermark = watermark === 'FULL'; + return ( + + {props.children} + + ); +} diff --git a/widget/embedded/src/components/common/WatermarkedModal/index.ts b/widget/embedded/src/components/common/WatermarkedModal/index.ts new file mode 100644 index 0000000000..62faeb4b53 --- /dev/null +++ b/widget/embedded/src/components/common/WatermarkedModal/index.ts @@ -0,0 +1 @@ +export { WatermarkedModal } from './WatermarkedModal'; diff --git a/widget/embedded/src/components/warnings/BalanceErrors.tsx b/widget/embedded/src/components/warnings/BalanceErrors.tsx deleted file mode 100644 index bb47d55f35..0000000000 --- a/widget/embedded/src/components/warnings/BalanceErrors.tsx +++ /dev/null @@ -1,45 +0,0 @@ -import { Spacer, styled, Typography } from '@rango-dev/ui'; -import React from 'react'; - -interface PropTypes { - messages: string[]; -} - -const List = styled('ul', { - variants: { - showListStyle: { - true: { paddingLeft: '$24' }, - }, - }, -}); - -const ListItem = styled('li', { - variants: { - showListStyle: { - true: { listStyleType: 'disc', listStylePosition: 'outside' }, - }, - }, -}); - -const Message = styled(Typography, { - display: 'block', -}); - -export function BalanceErrors({ messages }: PropTypes) { - const showListStyle = messages.length > 1; - return ( - <> - - Insufficent Balance: - - - - {messages.map((warning) => ( - - {warning} - - ))} - - - ); -} \ No newline at end of file diff --git a/widget/embedded/src/components/warnings/ConfirmSwapExtraMessages.tsx b/widget/embedded/src/components/warnings/ConfirmSwapExtraMessages.tsx deleted file mode 100644 index 75b1b1361d..0000000000 --- a/widget/embedded/src/components/warnings/ConfirmSwapExtraMessages.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import React from 'react'; -import { HIGH_SLIPPAGE } from '../../constants/swapSettings'; -import { HighSlippageWarning } from './HighSlippageWarning'; - -interface PropTypes { - selectedSlippage: number; -} - -export function ConfirmSwapExtraMessages(props: PropTypes) { - const { selectedSlippage } = props; - const highSlippage = selectedSlippage >= HIGH_SLIPPAGE; - - return ( - <> - {highSlippage && ( - - )} - - ); -} diff --git a/widget/embedded/src/components/warnings/HighSlippageWarning.tsx b/widget/embedded/src/components/warnings/HighSlippageWarning.tsx deleted file mode 100644 index abf2a9e266..0000000000 --- a/widget/embedded/src/components/warnings/HighSlippageWarning.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import { Alert } from '@rango-dev/ui'; -import React from 'react'; -import { ChangeSlippageButton } from '../ChangeSlippageButton'; - -interface PropTypes { - selectedSlippage: number; -} - -export function HighSlippageWarning(props: PropTypes) { - const { selectedSlippage } = props; - - return ( - }> - Caution, your slippage is high (= - {selectedSlippage}). Your trade may be front run. - - ); -} diff --git a/widget/embedded/src/components/warnings/MinRequiredSlippage.tsx b/widget/embedded/src/components/warnings/MinRequiredSlippage.tsx deleted file mode 100644 index 882c0445a0..0000000000 --- a/widget/embedded/src/components/warnings/MinRequiredSlippage.tsx +++ /dev/null @@ -1,23 +0,0 @@ -import { Spacer, Typography, styled } from '@rango-dev/ui'; -import React from 'react'; -import { ChangeSlippageButton } from '../ChangeSlippageButton'; - -interface PropTypes { - minRequiredSlippage: string | null; -} - -const StyledMessage = styled(Typography, { - color: '$error500 !important', -}); - -export function MinRequiredSlippage({ minRequiredSlippage }: PropTypes) { - return ( - - We recommend you to increase slippage to at least   - {minRequiredSlippage} -   for this route. - - - - ); -} diff --git a/widget/embedded/src/constants/configs.ts b/widget/embedded/src/constants/configs.ts new file mode 100644 index 0000000000..7abaa89a39 --- /dev/null +++ b/widget/embedded/src/constants/configs.ts @@ -0,0 +1 @@ +export const BLOCKCHAIN_LIST_SIZE = 10; diff --git a/widget/embedded/src/constants/customTokens.ts b/widget/embedded/src/constants/customTokens.ts new file mode 100644 index 0000000000..d560a8af38 --- /dev/null +++ b/widget/embedded/src/constants/customTokens.ts @@ -0,0 +1,6 @@ +import { TransactionType } from 'rango-types'; + +export const ACTIVE_BLOCKCHAINS_FOR_CUSTOM_TOKENS: string[] = [ + TransactionType.EVM, + TransactionType.SOLANA, +]; diff --git a/widget/embedded/src/constants/errors.ts b/widget/embedded/src/constants/errors.ts index edf680daa0..021d51f146 100644 --- a/widget/embedded/src/constants/errors.ts +++ b/widget/embedded/src/constants/errors.ts @@ -1,3 +1,63 @@ -export const errorMessages = { - genericServerError: 'Error connecting server, please reload the app and try again', +import type { QuoteError } from '../types'; + +import { i18n } from '@lingui/core'; + +import { QuoteErrorType } from '../types'; + +export const errorMessages = () => { + return { + genericServerError: i18n.t('Failed Network, Please retry your swap.'), + liquiditySourcesError: { + title: i18n.t('Please reset your liquidity sources.'), + description: i18n.t( + 'You have limited the liquidity sources and this might result in Rango finding no routes. Please consider resetting your liquidity sources.' + ), + }, + noResultError: { + title: i18n.t('No Routes Found.'), + description: i18n.t( + "Reasons why Rango couldn't find a route: low liquidity on token, very low input amount or no routes available for the selected input/output token combination." + ), + }, + bridgeLimitErrors: { + increaseAmount: i18n.t( + 'Bridge Limit Error: Please increase your amount.' + ), + decreaseAmount: i18n.t( + 'Bridge Limit Error: Please decrease your amount.' + ), + }, + highValueLossError: { + impactTitle: i18n.t('High Price Impact'), + title: i18n.t('Price impact is too high!'), + description: i18n.t( + 'The price impact is significantly higher than the allowed amount.' + ), + confirmMessage: i18n.t('Confirm high price impact'), + }, + quoteUpdatedWithHighValueLoss: { + title: i18n.t( + 'Route updated and price impact is too high, try again later!' + ), + }, + unknownPriceError: { + impactTitle: i18n.t('USD Price Unknown'), + title: i18n.t('USD Price Unknown, Cannot calculate Price Impact.'), + description: i18n.t( + 'USD Price Unknown, Cannot calculate Price Impact. The price impact may be higher than usual. Are you sure to continue the Swap?' + ), + confirmMessage: i18n.t('Confirm USD Price Unknown'), + }, + }; }; + +export function getQuoteErrorMessage(error: QuoteError) { + switch (error.type) { + case QuoteErrorType.NO_RESULT: + return error.diagnosisMessage ?? errorMessages().noResultError.title; + case QuoteErrorType.REQUEST_FAILED: + return errorMessages().genericServerError; + default: + return ''; + } +} diff --git a/widget/embedded/src/constants/fonts.ts b/widget/embedded/src/constants/fonts.ts new file mode 100644 index 0000000000..ef8a11f7cc --- /dev/null +++ b/widget/embedded/src/constants/fonts.ts @@ -0,0 +1,85 @@ +export const DEFAULT_FONT_FAMILY = 'Roboto'; + +export const SUPPORTED_FONTS = [ + { + name: 'Roboto', + value: 'Roboto', + url: '', + }, + { + name: 'Times New Roman', + value: 'Times New Roman', + url: 'https://fonts.cdnfonts.com/css/times-new-roman', + }, + { + name: 'Arial', + value: 'Arial', + url: '', + }, + { + name: 'Open Sans', + value: 'Open Sans', + url: 'https://fonts.googleapis.com/css2?family=Open+Sans:ital,wght@0,300..800;1,300..800&display=swap', + }, + { + name: 'Noto Sans', + value: 'Noto Sans', + url: 'https://fonts.googleapis.com/css2?family=Noto+Sans:ital,wght@0,100..900;1,100..900&display=swap', + }, + { + name: 'Montserrat', + value: 'Montserrat', + url: 'https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100..900;1,100..900&display=swap', + }, + { + name: 'Poppins', + value: 'Poppins', + url: 'https://fonts.googleapis.com/css2?family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap', + }, + { + name: 'Roboto Condensed', + value: 'Roboto Condensed', + url: 'https://fonts.googleapis.com/css2?family=Roboto+Condensed:ital,wght@0,100..900;1,100..900&display=swap', + }, + + { + name: 'Roboto Mono', + value: 'Roboto Mono', + url: 'https://fonts.googleapis.com/css2?family=Roboto+Mono:ital,wght@0,100..700;1,100..700&display=swap', + }, + { + name: 'Oswald', + value: 'Oswald', + url: 'https://fonts.googleapis.com/css2?family=Oswald:wght@200..700&display=swap', + }, + { + name: 'Raleway', + value: 'Raleway', + url: 'https://fonts.googleapis.com/css2?family=Raleway:ital,wght@0,100..900;1,100..900&display=swap', + }, + { + name: 'Sedan', + value: 'Sedan', + url: 'https://fonts.googleapis.com/css2?family=Sedan:ital@0;1&display=swap', + }, + { + name: 'Inter', + value: 'Inter', + url: 'https://fonts.googleapis.com/css2?family=Inter:wght@100..900&display=swap', + }, + { + name: 'Rubik', + value: 'Rubik', + url: 'https://fonts.googleapis.com/css2?family=Rubik:ital,wght@0,300..900;1,300..900&display=swap', + }, + { + name: 'Lora', + value: 'Lora', + url: 'https://fonts.googleapis.com/css2?family=Lora:ital,wght@0,400..700;1,400..700&display=swap', + }, + { + name: 'Barlow Condensed', + value: 'Barlow Condensed', + url: 'https://fonts.googleapis.com/css2?family=Barlow+Condensed:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap', + }, +]; diff --git a/widget/embedded/src/constants/index.ts b/widget/embedded/src/constants/index.ts new file mode 100644 index 0000000000..0d9df1e1eb --- /dev/null +++ b/widget/embedded/src/constants/index.ts @@ -0,0 +1,11 @@ +import { UI_ID } from '@rango-dev/ui'; + +export const RANGO_PUBLIC_API_KEY = 'c6381a79-2817-4602-83bf-6a641a409e32'; +export const DEFAULT_BASE_URL = 'https://api.rango.exchange'; +export const SCANNER_BASE_URL = 'https://explorer.rango.exchange'; + +export const WIDGET_UI_ID = { + SWAP_BOX_ID: 'rango-swap-box', + EXPANDED_BOX_ID: 'rango-expanded-box', + ...UI_ID, +}; diff --git a/widget/embedded/src/constants/languages.ts b/widget/embedded/src/constants/languages.ts new file mode 100644 index 0000000000..1be1ab5a0a --- /dev/null +++ b/widget/embedded/src/constants/languages.ts @@ -0,0 +1,100 @@ +import type { FlagPropTypes, Language } from '@rango-dev/ui'; + +import { + Bengali, + Catalonia, + Chinese, + Denmark, + English, + Finland, + French, + German, + Greece, + Hungary, + India, + Indonesian, + Italian, + Japanese, + Korea, + Lithuania, + Malay, + Netherlands, + Pakistan, + Philippines, + Poland, + Portuguese, + Russian, + SaudiArabia, + Serbia, + Slovakia, + SouthAfrica, + Spanish, + Swahili, + Swedish, + Thai, + Turkish, + Ukrainian, + Vietnamese, +} from '@rango-dev/ui'; + +export type LanguageItem = { + title: string; + label: string; + local: Language; + SVGFlag: React.ComponentType; +}; + +export const LANGUAGES: LanguageItem[] = [ + { title: 'Afrikaans', label: 'Afrikaans', local: 'af', SVGFlag: SouthAfrica }, + { title: 'Arabic', label: 'عربي', local: 'ar', SVGFlag: SaudiArabia }, + { title: 'Bengali', label: 'বাংলা', local: 'bn', SVGFlag: Bengali }, + { title: 'Catalan', label: 'Català', local: 'ca', SVGFlag: Catalonia }, + { + title: 'Chinese (Simplified)', + label: '简体中文', + local: 'zh-CN', + SVGFlag: Chinese, + }, + { + title: 'Chinese (Traditional)', + label: '中文(繁體)', + local: 'zh-TW', + SVGFlag: Chinese, + }, + { title: 'Danish', label: 'Dansk', local: 'da', SVGFlag: Denmark }, + { title: 'Dutch', label: 'Nederlands', local: 'nl', SVGFlag: Netherlands }, + { title: 'English', label: 'English', local: 'en', SVGFlag: English }, + { title: 'Filipino', label: 'Filipino', local: 'fil', SVGFlag: Philippines }, + { title: 'Finnish', label: 'Suomalainen', local: 'fi', SVGFlag: Finland }, + { title: 'French', label: 'Français', local: 'fr', SVGFlag: French }, + { title: 'German', label: 'Deutsch', local: 'de', SVGFlag: German }, + { title: 'Greek', label: 'ελληνικά', local: 'el', SVGFlag: Greece }, + { title: 'Hindi', label: 'हिंदी', local: 'hi', SVGFlag: India }, + { title: 'Hungarian', label: 'Magyar', local: 'hu', SVGFlag: Hungary }, + { title: 'Indonesian', label: 'Indonesia', local: 'id', SVGFlag: Indonesian }, + { title: 'Italian', label: 'Italiana', local: 'it', SVGFlag: Italian }, + { title: 'Japanese', label: '日本語', local: 'ja', SVGFlag: Japanese }, + { title: 'Korean', label: '한국인', local: 'ko', SVGFlag: Korea }, + { title: 'Lithuanian', label: 'Lietuvių', local: 'lt', SVGFlag: Lithuania }, + { title: 'Malay', label: 'Melayu', local: 'ms', SVGFlag: Malay }, + { title: 'Polish', label: 'Polski', local: 'pl', SVGFlag: Poland }, + { title: 'Portuguese', label: 'Português', local: 'pt', SVGFlag: Portuguese }, + { title: 'Russian', label: 'Русский', local: 'ru', SVGFlag: Russian }, + { title: 'Serbian', label: 'Cрпски', local: 'sr', SVGFlag: Serbia }, + { title: 'Slovak', label: 'Slovenský', local: 'sk', SVGFlag: Slovakia }, + { title: 'Spanish', label: 'Español', local: 'es', SVGFlag: Spanish }, + { title: 'Swahili', label: 'Kiswahili', local: 'sw', SVGFlag: Swahili }, + { title: 'Swedish', label: 'Svenska', local: 'sv', SVGFlag: Swedish }, + { title: 'Thai', label: 'แบบไทย', local: 'th', SVGFlag: Thai }, + { title: 'Turkish', label: 'Türkçe', local: 'tr', SVGFlag: Turkish }, + { title: 'Ukrainian', label: 'Yкраїні', local: 'uk', SVGFlag: Ukrainian }, + { title: 'Urdu', label: 'اردو', local: 'ur', SVGFlag: Pakistan }, + { + title: 'Vietnamese', + label: 'Tiếng Việt', + local: 'vi', + SVGFlag: Vietnamese, + }, +]; + +export const DEFAULT_LANGUAGE = 'en'; diff --git a/widget/embedded/src/constants/messages.ts b/widget/embedded/src/constants/messages.ts new file mode 100644 index 0000000000..e75d1a287e --- /dev/null +++ b/widget/embedded/src/constants/messages.ts @@ -0,0 +1,10 @@ +import { i18n } from '@lingui/core'; + +export const swapButtonTitles = () => { + return { + connectWallet: i18n.t('Connect Wallet'), + swap: i18n.t('Swap'), + swapAnyway: i18n.t('Swap anyway'), + ethWarning: i18n.t('The route goes through Ethereum. Continue?'), + }; +}; diff --git a/widget/embedded/src/constants/navigationRoutes.ts b/widget/embedded/src/constants/navigationRoutes.ts index cdfd48f246..8ae33b60d9 100644 --- a/widget/embedded/src/constants/navigationRoutes.ts +++ b/widget/embedded/src/constants/navigationRoutes.ts @@ -1,13 +1,18 @@ export const navigationRoutes = { home: '/', - fromChain: '/from-chain', - fromToken: '/from-token', - toChain: '/to-chain', - toToken: '/to-token', - settings: '/settings', - liquiditySources: '/settings/liquidity-sources', - swaps: '/swaps', - wallets: '/wallets', - confirmSwap: '/confirm-swap', - swapDetails: '/swaps/:requestId', + fromSwap: 'from-swap', + toSwap: 'to-swap', + blockchains: 'blockchains', + settings: 'settings', + customTokens: 'custom-tokens', + addCustomTokens: 'add-custom-tokens', + liquiditySources: 'liquidity-sources', + bridges: 'bridges', + exchanges: 'exchanges', + languages: 'languages', + swaps: 'swaps', + wallets: 'wallets', + confirmSwap: 'confirm-swap', + swapDetails: ':requestId', + routes: 'routes', }; diff --git a/widget/embedded/src/constants/quote.ts b/widget/embedded/src/constants/quote.ts new file mode 100644 index 0000000000..c6c52bd2fe --- /dev/null +++ b/widget/embedded/src/constants/quote.ts @@ -0,0 +1,60 @@ +import type { I18n } from '@lingui/core'; +import type { SwapFee, TagValue } from 'rango-sdk'; + +export type NameOfFees = + | 'Swapper Fee' + | 'Affiliate Fee' + | 'Outbound network fee' + | 'Rango Fee' + | 'Network Fee'; + +export function getFeeLabel(fee: NameOfFees, t: I18n['t']): string { + const data: Record = { + 'Network Fee': t('Network Fee'), + 'Swapper Fee': t('Protocol Fee'), + 'Affiliate Fee': t('Affiliate Fee'), + 'Outbound network fee': t('Outbound Fee'), + 'Rango Fee': t('Rango Fee'), + }; + return data[fee]; +} + +export type FeesGroup = { + payable: { [key in NameOfFees]?: SwapFee[] }; + nonePayable: { [key in NameOfFees]?: SwapFee[] }; +}; + +export const HIGH_PRIORITY_TAGS: TagValue[] = [ + 'RECOMMENDED', + 'CENTRALIZED', + 'LOWEST_FEE', + 'FASTEST', + 'HIGH_IMPACT', +]; + +export type Criteria = { + threshold: number; + minInput: number; +}; + +export const PERCENT_MULTIPLIER = 100; +export const GAS_FEE_MAX = 30; +export const ROUTE_TIME_MAX = 15; +export const SECONDS_IN_MINUTE = 60; +export const HIGH_FEE_THRESHOLD_USD = 30; + +export const HIGH_VALUE_LOSS_CRITERIA: Criteria[] = [ + { threshold: -10, minInput: 400 }, + { threshold: -5, minInput: 1000 }, +]; + +export const OUTPUT_CHANGE_WARNING_CRITERIA: Criteria[] = [ + { + threshold: -1, + minInput: 1000, + }, + { + threshold: -2, + minInput: 500, + }, +]; diff --git a/widget/embedded/src/constants/routing.ts b/widget/embedded/src/constants/routing.ts new file mode 100644 index 0000000000..4dbca934cb --- /dev/null +++ b/widget/embedded/src/constants/routing.ts @@ -0,0 +1,17 @@ +export const LOW_PRICE_IMPACT = -3; +export const HIGHT_PRICE_IMPACT = -10; + +export const TOKEN_AMOUNT_MIN_DECIMALS = 6; +export const TOKEN_AMOUNT_MAX_DECIMALS = 6; + +export const USD_VALUE_MIN_DECIMALS = 4; +export const USD_VALUE_MAX_DECIMALS = 4; + +export const GAS_FEE_MIN_DECIMALS = 2; +export const GAS_FEE_MAX_DECIMALS = 2; + +export const PERCENTAGE_CHANGE_MIN_DECIMALS = 2; +export const PERCENTAGE_CHANGE_MAX_DECIMALS = 2; + +export const BALANCE_MIN_DECIMALS = 8; +export const BALANCE_MAX_DECIMALS = 8; diff --git a/widget/embedded/src/constants/searchFor.ts b/widget/embedded/src/constants/searchFor.ts new file mode 100644 index 0000000000..8c48bf3c90 --- /dev/null +++ b/widget/embedded/src/constants/searchFor.ts @@ -0,0 +1,6 @@ +export const MIN_LENGTH_SYMBOL_EXACT_MATCH = 1; +export const MIN_LENGTH_SYMBOL_START_WITH = 2; +export const MIN_LENGTH_SYMBOL_CONTAINS = 3; +export const MIN_LENGTH_TOKEN_NAME_EXACT_MATCH = 3; +export const MIN_LENGTH_TOKEN_NAME_CONTAINS = 3; +export const MIN_LENGTH_TOKEN_ADDRESS_CONTAINS = 4; diff --git a/widget/embedded/src/constants/searchParams.ts b/widget/embedded/src/constants/searchParams.ts index e73129bd3c..ae8328fe7c 100644 --- a/widget/embedded/src/constants/searchParams.ts +++ b/widget/embedded/src/constants/searchParams.ts @@ -1,7 +1,18 @@ export enum SearchParams { - 'FROM_CHAIN' = 'fromChain', - 'FROM_TOKEN' = 'fromToken', - 'TO_CHAIN' = 'toChain', - 'TO_TOKEN' = 'toToken', - 'FROM_AMOUNT' = 'fromAmount', + FROM_BLOCKCHAIN = 'fromBlockchain', + FROM_TOKEN = 'fromToken', + TO_BLOCKCHAIN = 'toBlockchain', + TO_TOKEN = 'toToken', + FROM_AMOUNT = 'fromAmount', + AUTO_CONNECT = 'autoConnect', + + // This is for custom tokens + BLOCKCHAIN = 'blockchain', + /* + * dApps can transmit liquidity sources as a search parameter, + * and these take precedence over widget configurations + */ + LIQUIDITY_SOURCES = 'liquiditySources', + // iframe environments + CLIENT_URL = 'clientUrl', } diff --git a/widget/embedded/src/constants/settings.ts b/widget/embedded/src/constants/settings.ts new file mode 100644 index 0000000000..94de1f54e5 --- /dev/null +++ b/widget/embedded/src/constants/settings.ts @@ -0,0 +1,5 @@ +export enum ThemeModeEnum { + DARK = 'dark', + LIGHT = 'light', + AUTO = 'auto', +} diff --git a/widget/embedded/src/constants/swapSettings.ts b/widget/embedded/src/constants/swapSettings.ts index 0435c4d925..f9301a08de 100644 --- a/widget/embedded/src/constants/swapSettings.ts +++ b/widget/embedded/src/constants/swapSettings.ts @@ -1,4 +1,8 @@ -export const SLIPPAGES = [0.5, 1, 3, 5, 8, 13, 20]; +const LOW = 0.5; +const MEDIUM = 1; +const HIGH = 3; + +export const SLIPPAGES = [LOW, MEDIUM, HIGH]; export const DEFAULT_SLIPPAGE = 1; diff --git a/widget/embedded/src/constants/wallets.ts b/widget/embedded/src/constants/wallets.ts new file mode 100644 index 0000000000..3287b0d31b --- /dev/null +++ b/widget/embedded/src/constants/wallets.ts @@ -0,0 +1,3 @@ +import { WalletTypes } from '@rango-dev/wallets-shared'; + +export const EXCLUDED_WALLETS = [WalletTypes.LEAP]; diff --git a/widget/embedded/src/containers/App/App.styles.ts b/widget/embedded/src/containers/App/App.styles.ts new file mode 100644 index 0000000000..6241a2faa0 --- /dev/null +++ b/widget/embedded/src/containers/App/App.styles.ts @@ -0,0 +1,15 @@ +import { styled } from '@rango-dev/ui'; + +export const MainContainer = styled('div', { + fontFamily: '$widget', + boxSizing: 'border-box', + textAlign: 'left', + '& *, *::before, *::after': { + boxSizing: 'inherit', + }, + '& *:focus-visible': { + outlineColor: '$info500', + transition: 'none', + }, + '& ul, ol, li': { listStyleType: 'none' }, +}); diff --git a/widget/embedded/src/containers/App/App.tsx b/widget/embedded/src/containers/App/App.tsx new file mode 100644 index 0000000000..bcf3985b87 --- /dev/null +++ b/widget/embedded/src/containers/App/App.tsx @@ -0,0 +1,25 @@ +import { I18nManager } from '@rango-dev/ui'; +import React from 'react'; + +import { AppRoutes } from '../../components/AppRoutes'; +import { useBootstrap } from '../../hooks/useBootstrap'; +import { useLanguage } from '../../hooks/useLanguage'; +import { useTheme } from '../../hooks/useTheme'; +import { useAppStore } from '../../store/AppStore'; + +import { MainContainer } from './App.styles'; + +export function Main() { + useBootstrap(); + const { config } = useAppStore(); + const { activeTheme } = useTheme(config?.theme || {}); + const { activeLanguage } = useLanguage(); + + return ( + + + + + + ); +} diff --git a/widget/embedded/src/containers/App/index.ts b/widget/embedded/src/containers/App/index.ts new file mode 100644 index 0000000000..bad96edcbb --- /dev/null +++ b/widget/embedded/src/containers/App/index.ts @@ -0,0 +1 @@ +export { Main } from './App'; diff --git a/widget/embedded/src/containers/ExpandedQuotes/ExpandedQuotes.styles.ts b/widget/embedded/src/containers/ExpandedQuotes/ExpandedQuotes.styles.ts new file mode 100644 index 0000000000..6752b2148c --- /dev/null +++ b/widget/embedded/src/containers/ExpandedQuotes/ExpandedQuotes.styles.ts @@ -0,0 +1,44 @@ +import { darkTheme, styled } from '@rango-dev/ui'; + +export const Container = styled('div', { + transition: 'width 0.2s, opacity 0.2s, margin-left 0.2s', + height: '700px', + width: '390px', + position: 'relative', + opacity: 1, + marginLeft: '$16', + backgroundColor: '$neutral100', + [`.${darkTheme} &`]: { + backgroundColor: '$neutral300', + }, + + variants: { + expandMode: { + default: { + width: '390px', + }, + full: { + width: '719px', + }, + }, + }, + + '&.is-hidden': { + width: 0, + height: 0, + opacity: 0, + marginLeft: 0, + }, +}); + +export const Content = styled('div', { + position: 'relative', + overflow: 'hidden', + padding: '$20', + flexGrow: 1, + display: 'flex', + flexDirection: 'column', + overflowY: 'auto', + borderRadius: '$primary', + backgroundColor: '$background', +}); diff --git a/widget/embedded/src/containers/ExpandedQuotes/ExpandedQuotes.tsx b/widget/embedded/src/containers/ExpandedQuotes/ExpandedQuotes.tsx new file mode 100644 index 0000000000..108a4e2a9b --- /dev/null +++ b/widget/embedded/src/containers/ExpandedQuotes/ExpandedQuotes.tsx @@ -0,0 +1,78 @@ +import type { PropTypes } from './ExpandedQuotes.types'; + +import { i18n } from '@lingui/core'; +import { Header } from '@rango-dev/ui'; +import React, { useEffect, useState } from 'react'; + +import { HeaderButtons } from '../../components/HeaderButtons'; +import { LayoutContainer } from '../../components/Layout/Layout.styles'; +import { Quotes } from '../../components/Quotes'; +import { SelectStrategy } from '../../components/Quotes/SelectStrategy'; +import { WIDGET_UI_ID } from '../../constants'; +import { useAppStore } from '../../store/AppStore'; +import { getExpanded } from '../../utils/common'; + +import { Container, Content } from './ExpandedQuotes.styles'; + +export const TIME_TO_CLOSE_OPEN_EXPANDED = 100; + +export function ExpandedQuotes(props: PropTypes) { + const { fetch, loading, onClickOnQuote, onClickRefresh, isVisible } = props; + const [isDelayedVisible, setIsDelayedVisible] = useState(false); + const containerClass = isDelayedVisible ? '' : 'is-hidden'; + const { config } = useAppStore(); + const fullExpandedMode = config?.variant === 'full-expanded'; + const container = getExpanded(); + useEffect(() => { + let timeout: ReturnType | null = null; + + if (isVisible) { + timeout = setTimeout(() => { + setIsDelayedVisible(true); + }, TIME_TO_CLOSE_OPEN_EXPANDED); + } else { + setIsDelayedVisible(false); + if (timeout) { + clearTimeout(timeout); + } + } + + return () => { + if (timeout) { + clearTimeout(timeout); + } + }; + }, [isVisible]); + + return ( + +
+ +
+ + ); +} diff --git a/widget/embedded/src/containers/Wallets/Wallets.types.ts b/widget/embedded/src/containers/Wallets/Wallets.types.ts new file mode 100644 index 0000000000..e349ecf9e7 --- /dev/null +++ b/widget/embedded/src/containers/Wallets/Wallets.types.ts @@ -0,0 +1,23 @@ +import type { WidgetConfig } from '../../types'; +import type { LegacyEventHandler as EventHandler } from '@rango-dev/wallets-core/legacy'; + +export type OnWalletConnectionChange = (key: string) => void; +export interface WidgetContextInterface { + /** + * A wallet connection handler, utilized within the wallet provider, + * is linked to the useBootstrap hook for synchronizing the state of the last connected wallet. + * It's important not to override this handler in other locations. + */ + onConnectWallet(handler: OnWalletConnectionChange): void; + /** + * A wallet disconnection handler, utilized within the wallet provider, + * is linked to the useBootstrap hook for synchronizing the state of the last disconnected wallet. + * It's important not to override this handler in other locations. + */ + onDisconnectWallet(handler: OnWalletConnectionChange): void; +} + +export interface PropTypes { + onUpdateState?: EventHandler; + config: WidgetConfig; +} diff --git a/widget/embedded/src/containers/Wallets/index.ts b/widget/embedded/src/containers/Wallets/index.ts new file mode 100644 index 0000000000..06d0a0b2f0 --- /dev/null +++ b/widget/embedded/src/containers/Wallets/index.ts @@ -0,0 +1 @@ +export { WidgetWallets, WidgetContext } from './Wallets'; diff --git a/widget/embedded/src/containers/Widget/Widget.tsx b/widget/embedded/src/containers/Widget/Widget.tsx new file mode 100644 index 0000000000..95c4726e25 --- /dev/null +++ b/widget/embedded/src/containers/Widget/Widget.tsx @@ -0,0 +1,25 @@ +import type { WidgetProps } from './Widget.types'; +import type { PropsWithChildren } from 'react'; + +import React from 'react'; + +import { AppRouter } from '../../components/AppRouter'; +import { DEFAULT_CONFIG } from '../../store/slices/config'; +import { Main } from '../App'; +import { WidgetProvider } from '../WidgetProvider'; + +export function Widget(props: PropsWithChildren) { + const isExternalWalletsEnabled = props.config?.externalWallets; + + return ( + + {isExternalWalletsEnabled ? ( +
+ ) : ( + +
+ + )} + + ); +} diff --git a/widget/embedded/src/containers/Widget/Widget.types.ts b/widget/embedded/src/containers/Widget/Widget.types.ts new file mode 100644 index 0000000000..034d2c54fb --- /dev/null +++ b/widget/embedded/src/containers/Widget/Widget.types.ts @@ -0,0 +1,5 @@ +import type { WidgetConfig } from '../../types'; + +export type WidgetProps = { + config?: WidgetConfig; +}; diff --git a/widget/embedded/src/containers/Widget/index.ts b/widget/embedded/src/containers/Widget/index.ts new file mode 100644 index 0000000000..c5d5dcb55f --- /dev/null +++ b/widget/embedded/src/containers/Widget/index.ts @@ -0,0 +1,2 @@ +export { Widget } from './Widget'; +export type { WidgetProps } from './Widget.types'; diff --git a/widget/embedded/src/containers/WidgetInfo/WidgetInfo.helpers.ts b/widget/embedded/src/containers/WidgetInfo/WidgetInfo.helpers.ts new file mode 100644 index 0000000000..4ee9b6ac02 --- /dev/null +++ b/widget/embedded/src/containers/WidgetInfo/WidgetInfo.helpers.ts @@ -0,0 +1,73 @@ +import type { Meta, RetryQuote } from '../../store/quote'; +import type { FindToken } from '../../store/slices/data'; +import type { Manager } from '@rango-dev/queue-manager-core'; +import type { PendingSwap } from 'rango-types/lib'; + +import { + cancelSwap, + getCurrentNamespaceOfOrNull, + getCurrentStep, + getRelatedWalletOrNull, +} from '@rango-dev/queue-manager-rango-preset'; + +import { getPendingSwaps } from '../../utils/queue'; +import { createRetryQuote } from '../../utils/quote'; + +interface WidgetHistoryActions { + retrySwap: (retryQuote: RetryQuote) => void; + findToken: FindToken; +} + +export class WidgetHistory { + private manager: Manager | undefined; + private actions: WidgetHistoryActions; + + constructor(manager: Manager | undefined, actions: WidgetHistoryActions) { + this.manager = manager; + this.actions = actions; + } + + public getAllSwaps() { + return getPendingSwaps(this.manager); + } + + public getCurrentStep(swap: PendingSwap) { + return this.getCurrentStepInfo(swap).step; + } + + public getCurrentStepWallet(swap: PendingSwap) { + return this.getCurrentStepInfo(swap).wallet; + } + + public getCurrentStepNetwork(swap: PendingSwap) { + return this.getCurrentStepInfo(swap).network; + } + + public retry(swap: PendingSwap, meta: Meta) { + const retryQuote = createRetryQuote( + swap, + meta.blockchains, + this.actions.findToken + ); + + return this.actions.retrySwap(retryQuote); + } + + public cancel(id: string) { + const queue = this.manager?.get(id); + if (queue) { + cancelSwap(queue); + } + } + + private getCurrentStepInfo(swap: PendingSwap) { + const currentStep = getCurrentStep(swap); + return { + step: currentStep, + wallet: currentStep ? getRelatedWalletOrNull(swap, currentStep) : null, + network: currentStep + ? getCurrentNamespaceOfOrNull(swap, currentStep)?.network + : null, + }; + } +} diff --git a/widget/embedded/src/containers/WidgetInfo/WidgetInfo.tsx b/widget/embedded/src/containers/WidgetInfo/WidgetInfo.tsx new file mode 100644 index 0000000000..38984a3f3f --- /dev/null +++ b/widget/embedded/src/containers/WidgetInfo/WidgetInfo.tsx @@ -0,0 +1,107 @@ +import type { WidgetInfoContextInterface } from './WidgetInfo.types'; + +import { useManager } from '@rango-dev/queue-manager-react'; +import React, { createContext, useContext } from 'react'; + +import { useLanguage } from '../../hooks/useLanguage'; +import { useUpdateQuoteInputs } from '../../hooks/useUpdateQuoteInputs/useUpdateQuoteInputs'; +import { useAppStore } from '../../store/AppStore'; +import { useNotificationStore } from '../../store/notification'; +import { useQuoteStore } from '../../store/quote'; +import { tabManager, useUiStore } from '../../store/ui'; +import { calculateWalletUsdValue } from '../../utils/wallets'; + +import { WidgetHistory } from './WidgetInfo.helpers'; + +export const WidgetInfoContext = createContext< + WidgetInfoContextInterface | undefined +>(undefined); + +export function WidgetInfo(props: React.PropsWithChildren) { + const { manager } = useManager(); + const isActiveTab = useUiStore.use.isActiveTab(); + const retrySwap = useQuoteStore.use.retry(); + const { + findToken, + connectedWallets, + getBalances, + fetchBalances: refetch, + } = useAppStore(); + + const history = new WidgetHistory(manager, { retrySwap, findToken }); + const { fetchingWallets: isLoading } = useAppStore(); + const totalBalance = calculateWalletUsdValue(getBalances()); + const blockchains = useAppStore().blockchains(); + const tokens = useAppStore().tokens(); + const swappers = useAppStore().swappers(); + const loadingStatus = useAppStore().fetchStatus; + const resetLanguage = useLanguage().resetLanguage; + const notifications = useNotificationStore().getNotifications(); + const clearNotifications = useNotificationStore().clearNotifications; + const updateQuoteInputs = useUpdateQuoteInputs(); + const { fromBlockchain, toBlockchain, fromToken, toToken, inputAmount } = + useQuoteStore(); + + // eslint-disable-next-line react/jsx-no-constructed-context-values + const value: WidgetInfoContextInterface = { + isActiveTab, + setCurrentTabAsActive: tabManager.forceClaim, + history, + wallets: { + isLoading, + details: connectedWallets, + totalBalance, + refetch: async (accounts) => refetch(accounts), + }, + meta: { + blockchains, + tokens, + swappers, + loadingStatus, + findToken, + }, + resetLanguage, + notifications: { + list: notifications, + clearAll: clearNotifications, + }, + quote: { + quoteInputs: { + fromBlockchain: fromBlockchain?.name ?? null, + fromToken: fromToken + ? { + symbol: fromToken.symbol, + blockchain: fromToken.blockchain, + address: fromToken.address, + } + : null, + toBlockchain: toBlockchain?.name ?? null, + toToken: toToken + ? { + symbol: toToken.symbol, + blockchain: toToken.blockchain, + address: toToken.address, + } + : null, + requestAmount: inputAmount, + }, + updateQuoteInputs, + }, + }; + + return ( + + {props.children} + + ); +} + +export function useWidget(): WidgetInfoContextInterface { + const context = useContext(WidgetInfoContext); + if (!context) { + throw new Error( + 'useWidget can only be used within the WidgetProvider component' + ); + } + return context; +} diff --git a/widget/embedded/src/containers/WidgetInfo/WidgetInfo.types.ts b/widget/embedded/src/containers/WidgetInfo/WidgetInfo.types.ts new file mode 100644 index 0000000000..33593df1aa --- /dev/null +++ b/widget/embedded/src/containers/WidgetInfo/WidgetInfo.types.ts @@ -0,0 +1,34 @@ +import type { WidgetHistory } from './WidgetInfo.helpers'; +import type { FetchStatus, FindToken } from '../../store/slices/data'; +import type { ConnectedWallet } from '../../store/slices/wallets'; +import type { QuoteInputs, UpdateQuoteInputs, Wallet } from '../../types'; +import type { Notification } from '../../types/notification'; +import type { BlockchainMeta, SwapperMeta, Token } from 'rango-sdk'; + +export interface WidgetInfoContextInterface { + isActiveTab: boolean; + setCurrentTabAsActive: () => void; + history: WidgetHistory; + wallets: { + details: ConnectedWallet[]; + totalBalance: string; + isLoading: boolean; + refetch: (accounts: Wallet[]) => void; + }; + meta: { + blockchains: BlockchainMeta[]; + tokens: Token[]; + swappers: SwapperMeta[]; + loadingStatus: FetchStatus; + findToken: FindToken; + }; + resetLanguage: () => void; + notifications: { + list: Notification[]; + clearAll: () => void; + }; + quote: { + quoteInputs: QuoteInputs; + updateQuoteInputs: UpdateQuoteInputs; + }; +} diff --git a/widget/embedded/src/containers/WidgetInfo/index.ts b/widget/embedded/src/containers/WidgetInfo/index.ts new file mode 100644 index 0000000000..dcc6f77647 --- /dev/null +++ b/widget/embedded/src/containers/WidgetInfo/index.ts @@ -0,0 +1 @@ +export { WidgetInfo, useWidget } from './WidgetInfo'; diff --git a/widget/embedded/src/containers/WidgetProvider/WidgetProvider.tsx b/widget/embedded/src/containers/WidgetProvider/WidgetProvider.tsx new file mode 100644 index 0000000000..e51c17cea8 --- /dev/null +++ b/widget/embedded/src/containers/WidgetProvider/WidgetProvider.tsx @@ -0,0 +1,47 @@ +import type { PropTypes } from './WidgetProvider.types'; +import type { PropsWithChildren } from 'react'; + +import { setSolanaSignerConfig } from '@rango-dev/signer-solana'; +import React, { useEffect, useMemo } from 'react'; + +import { DEFAULT_BASE_URL, RANGO_PUBLIC_API_KEY } from '../../constants'; +import useFontLoader from '../../hooks/useFontLoader'; +import QueueManager from '../../QueueManager'; +import { initConfig } from '../../utils/configs'; +import { WidgetWallets } from '../Wallets'; +import { WidgetInfo } from '../WidgetInfo'; + +export function WidgetProvider(props: PropsWithChildren) { + const { onUpdateState, config } = props; + + const fontFamily = props.config?.theme?.fontFamily; + + const { handleLoadCustomFont } = useFontLoader(); + + useEffect(() => { + if (fontFamily) { + handleLoadCustomFont(fontFamily); + } + }, [fontFamily]); + + useMemo(() => { + initConfig({ + API_KEY: config?.apiKey || RANGO_PUBLIC_API_KEY, + BASE_URL: config?.apiUrl || DEFAULT_BASE_URL, + }); + }, [config.apiKey, config.apiUrl]); + + useEffect(() => { + if (props.config?.signers?.customSolanaRPC) { + setSolanaSignerConfig('customRPC', props.config.signers.customSolanaRPC); + } + }, [props.config?.signers?.customSolanaRPC]); + + return ( + + + {props.children} + + + ); +} diff --git a/widget/embedded/src/containers/WidgetProvider/WidgetProvider.types.ts b/widget/embedded/src/containers/WidgetProvider/WidgetProvider.types.ts new file mode 100644 index 0000000000..4110f9b972 --- /dev/null +++ b/widget/embedded/src/containers/WidgetProvider/WidgetProvider.types.ts @@ -0,0 +1,7 @@ +import type { WidgetConfig } from '../../types'; +import type { LegacyEventHandler as EventHandler } from '@rango-dev/wallets-core/legacy'; + +export type PropTypes = { + onUpdateState?: EventHandler; + config: WidgetConfig; +}; diff --git a/widget/embedded/src/containers/WidgetProvider/index.ts b/widget/embedded/src/containers/WidgetProvider/index.ts new file mode 100644 index 0000000000..dd39a3943b --- /dev/null +++ b/widget/embedded/src/containers/WidgetProvider/index.ts @@ -0,0 +1 @@ +export { WidgetProvider } from './WidgetProvider'; diff --git a/widget/embedded/src/globalStyles.ts b/widget/embedded/src/globalStyles.ts index 910930ffd5..a9e7c41e78 100644 --- a/widget/embedded/src/globalStyles.ts +++ b/widget/embedded/src/globalStyles.ts @@ -1,31 +1,7 @@ import { globalCss } from '@rango-dev/ui'; -export const globalStyles = globalCss({ - '*': { - boxSizing: 'border-box', - margin: 0, - padding: 0, - listStyleType: 'none', - '&::-webkit-scrollbar': { width: '$8', height: '$8' }, - '&::-webkit-scrollbar-thumb': { - backgroundColor: '$neutrals400', - borderRadius: '$10', - }, - '&::-webkit-scrollbar-thumb:hover': { - backgroundColor: '$neutrals500', - }, - '&::-webkit-scrollbar-track': { - backgroundColor: '$neutrals300', - }, - }, -}); -export const globalFont = (fontFamily: string) => +export const globalFont = () => globalCss({ - '@import': [ + '@import': "url('https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap')", - "url('https://fonts.cdnfonts.com/css/times-new-roman')", - ], - body: { - fontFamily, - }, })(); diff --git a/widget/embedded/src/hooks/useBootstrap/index.ts b/widget/embedded/src/hooks/useBootstrap/index.ts new file mode 100644 index 0000000000..c84a443be2 --- /dev/null +++ b/widget/embedded/src/hooks/useBootstrap/index.ts @@ -0,0 +1 @@ +export { useBootstrap } from './useBootstrap'; diff --git a/widget/embedded/src/hooks/useBootstrap/useBootstrap.ts b/widget/embedded/src/hooks/useBootstrap/useBootstrap.ts new file mode 100644 index 0000000000..1f0cc5a138 --- /dev/null +++ b/widget/embedded/src/hooks/useBootstrap/useBootstrap.ts @@ -0,0 +1,80 @@ +import type { WalletType } from '../..'; + +import { useQueueManager } from '@rango-dev/queue-manager-rango-preset'; +import { splitWalletNetwork } from '@rango-dev/wallets-shared'; +import { isEvmBlockchain } from 'rango-sdk'; +import { useContext, useEffect, useState } from 'react'; + +import { useWallets } from '../..'; +import { WidgetContext } from '../../containers/Wallets'; +import { globalFont } from '../../globalStyles'; +import { useAppStore } from '../../store/AppStore'; +import { useNotificationStore } from '../../store/notification'; +import { unsubscribeQuoteStore } from '../../store/quote'; +import { tabManager } from '../../store/ui'; +import { useFetchApiConfig } from '../useFetchApiConfig'; +import { useForceAutoConnect } from '../useForceAutoConnect'; +import { useSubscribeToWidgetEvents } from '../useSubscribeToWidgetEvents'; +import { useSyncNotifications } from '../useSyncNotifications'; + +export function useBootstrap() { + useForceAutoConnect(); + globalFont(); + useSubscribeToWidgetEvents(); + useSyncNotifications(); + const blockchains = useAppStore().blockchains(); + const { canSwitchNetworkTo } = useWallets(); + const [lastConnectedWalletWithNetwork, setLastConnectedWalletWithNetwork] = + useState(''); + const [disconnectedWallet, setDisconnectedWallet] = useState(); + const widgetContext = useContext(WidgetContext); + + const evmChains = blockchains.filter(isEvmBlockchain); + + const { fetchApiConfig } = useFetchApiConfig(); + + // Unsubscribe QuoteStore listeners + useEffect(() => () => unsubscribeQuoteStore(), []); + + // At the moment, we only detect the disconnection of EVM wallets. + useQueueManager({ + lastConnectedWallet: lastConnectedWalletWithNetwork, + clearDisconnectedWallet: () => { + setDisconnectedWallet(undefined); + }, + disconnectedWallet: disconnectedWallet, + evmChains, + canSwitchNetworkTo, + }); + + useEffect(() => { + tabManager.init(); + + if (!useNotificationStore.persist.hasHydrated()) { + void useNotificationStore.persist.rehydrate(); + } + + /** + * Add handlers to the widget context for connecting and disconnecting wallets. + * We pass these handlers to the wallet provider to keep track of the last connected and last disconnected wallets. + * The 'queue-manager' uses these details to spot any changes in the connection status of the required wallet during the swap process. + * + * with this approch anyone who use the widget context can override these handlers and causes some bugs happens. + * it the future we should add a safer soloution like considering array of handlers . + * https://github.com/rango-exchange/rango-client/pull/630/files#r1518846728 + */ + widgetContext.onConnectWallet(setLastConnectedWalletWithNetwork); + widgetContext.onDisconnectWallet((walletType) => { + setDisconnectedWallet(walletType); + if ( + walletType === splitWalletNetwork(lastConnectedWalletWithNetwork)?.[0] + ) { + setLastConnectedWalletWithNetwork(''); + } + }); + + void fetchApiConfig().catch(console.log); + + return tabManager.destroy; + }, []); +} diff --git a/widget/embedded/src/hooks/useConfirmSwap.ts b/widget/embedded/src/hooks/useConfirmSwap.ts deleted file mode 100644 index a35925aa3c..0000000000 --- a/widget/embedded/src/hooks/useConfirmSwap.ts +++ /dev/null @@ -1,262 +0,0 @@ -import { useEffect, useRef, useState } from 'react'; -import { useBestRouteStore } from '../store/bestRoute'; -import { useMetaStore } from '../store/meta'; -import { useSettingsStore } from '../store/settings'; -import { useWalletsStore } from '../store/wallets'; -import { - ConfirmSwapError, - ConfirmSwapErrorTypes, - ConfirmSwapWarningTypes, - ConfirmSwapWarnings, - PendingSwapSettings, -} from '../types'; -import { PendingSwap } from '@rango-dev/ui/dist/containers/History/types'; -import { - createBestRouteRequestBody, - getBalanceWarnings, - getMinRequiredSlippage, - getOutputRatio, - getPercentageChange, - getRouteOutputAmount, - getWalletsForNewSwap, - hasProperSlippage, - isOutputAmountChangedALot, - outputRatioHasWarning, -} from '../utils/swap'; -import { httpService } from '../services/httpService'; -import BigNumber from 'bignumber.js'; -import { - isNumberOfSwapsChanged, - isRouteChanged, - isRouteInternalCoinsUpdated, - isRouteSwappersUpdated, -} from '../utils/routing'; -import { numberToString } from '../utils/numbers'; -import { BestRouteResponse } from 'rango-sdk'; -import { calculatePendingSwap } from '@rango-dev/queue-manager-rango-preset'; - -type ConfirmSwap = { - loading: boolean; - errors: ConfirmSwapError[]; - warnings: ConfirmSwapWarnings[]; - confirmSwap: (() => Promise) | null; -}; - -export function useConfirmSwap(): ConfirmSwap { - const fromToken = useBestRouteStore.use.fromToken(); - const toToken = useBestRouteStore.use.toToken(); - const inputAmount = useBestRouteStore.use.inputAmount(); - const initialRoute = useBestRouteStore.use.bestRoute(); - const setBestRoute = useBestRouteStore.use.setBestRoute(); - const inputUsdValue = useBestRouteStore.use.inputUsdValue(); - const affiliateRef = useSettingsStore.use.affiliateRef(); - - const accounts = useWalletsStore.use.accounts(); - const selectedWallets = useWalletsStore.use.selectedWallets(); - const meta = useMetaStore.use.meta(); - const customSlippage = useSettingsStore.use.customSlippage(); - const slippage = useSettingsStore.use.slippage(); - const disabledLiquiditySources = - useSettingsStore.use.disabledLiquiditySources(); - const userSlippage = customSlippage || slippage; - const proceedAnywayRef = useRef(false); - const confiremedRouteRef = useRef(null); - let abortControllerRef = useRef(null); - - const [loading, setLoading] = useState(false); - const [errors, setErrors] = useState([]); - const [warnings, setWarnings] = useState([]); - - useEffect(() => { - return () => abortControllerRef.current?.abort(); - }, []); - - if (!fromToken || !toToken || !inputAmount || !initialRoute) - return { loading: false, warnings: [], errors: [], confirmSwap: null }; - - const confirmSwap = async (): Promise => { - if (proceedAnywayRef.current) { - const swapSettings: PendingSwapSettings = { - slippage: userSlippage.toString(), - disabledSwappersGroups: disabledLiquiditySources, - }; - - if (errors.length > 0) setErrors([]); - if (warnings.length > 0) setWarnings([]); - proceedAnywayRef.current = false; - - if (confiremedRouteRef.current) { - const newSwap = calculatePendingSwap( - inputAmount.toString(), - confiremedRouteRef.current, - getWalletsForNewSwap(selectedWallets), - swapSettings, - false, - meta - ); - - return newSwap; - } - return; - } - - abortControllerRef.current = new AbortController(); - - setLoading(true); - - const requestBody = createBestRouteRequestBody( - fromToken, - toToken, - inputAmount, - accounts, - selectedWallets, - disabledLiquiditySources, - userSlippage, - affiliateRef, - initialRoute - ); - - try { - const confiremedRoute = await httpService().getBestRoute(requestBody, { - signal: abortControllerRef.current?.signal, - }); - - abortControllerRef.current = null; - - setLoading(false); - - if ( - !confiremedRoute.result || - !new BigNumber(confiremedRoute.requestAmount).isEqualTo( - new BigNumber(inputAmount || '-1') - ) - ) { - setErrors((prevState) => - prevState.concat({ - type: ConfirmSwapErrorTypes.NO_ROUTE, - }) - ); - return; - } - - const confirmSwapState: Omit = { - errors: [], - warnings: [], - }; - - const routeChanged = isRouteChanged(initialRoute, confiremedRoute!); - - if (routeChanged) { - setBestRoute(confiremedRoute); - const newRouteOutputUsdValue = new BigNumber( - confiremedRoute.result?.outputAmount || '0' - ).multipliedBy(toToken.usdPrice || 0); - - const outputRatio = getOutputRatio( - inputUsdValue, - newRouteOutputUsdValue - ); - const highValueLoss = outputRatioHasWarning(inputUsdValue, outputRatio); - - if (highValueLoss) - confirmSwapState.errors.push({ - type: ConfirmSwapErrorTypes.ROUTE_UPDATED_WITH_HIGH_VALUE_LOSS, - }); - else if (isOutputAmountChangedALot(initialRoute, confiremedRoute)) - confirmSwapState.warnings.push({ - type: ConfirmSwapWarningTypes.ROUTE_AND_OUTPUT_AMOUNT_UPDATED, - newOutputAmount: numberToString( - getRouteOutputAmount(confiremedRoute) - ), - percentageChange: numberToString( - getPercentageChange( - getRouteOutputAmount(initialRoute), - getRouteOutputAmount(confiremedRoute) - ), - null, - 2 - ), - }); - else if (isRouteInternalCoinsUpdated(initialRoute, confiremedRoute)) - confirmSwapState.warnings.push({ - type: ConfirmSwapWarningTypes.ROUTE_COINS_UPDATED, - }); - else if (isNumberOfSwapsChanged(initialRoute, confiremedRoute)) - confirmSwapState.warnings.push({ - type: ConfirmSwapWarningTypes.ROUTE_UPDATED, - }); - else if (isRouteSwappersUpdated(initialRoute, confiremedRoute)) - confirmSwapState.warnings.push({ - type: ConfirmSwapWarningTypes.ROUTE_SWAPPERS_UPDATED, - }); - } - - const balanceWarnings = getBalanceWarnings( - confiremedRoute, - selectedWallets - ); - const enoughBalance = balanceWarnings.length === 0; - - if (!enoughBalance) - confirmSwapState.errors.push({ - type: ConfirmSwapErrorTypes.INSUFFICIENT_BALANCE, - messages: balanceWarnings, - }); - - const minRequiredSlippage = getMinRequiredSlippage(initialRoute); - - if (!hasProperSlippage(userSlippage.toString(), minRequiredSlippage)) - confirmSwapState.errors.push({ - type: ConfirmSwapErrorTypes.INSUFFICIENT_SLIPPAGE, - minRequiredSlippage, - }); - - const noErrors = confirmSwapState.errors.length === 0; - const noWarnings = confirmSwapState.warnings.length === 0; - - if ( - (noErrors || (!noErrors && proceedAnywayRef.current)) && - (noWarnings || (!noWarnings && proceedAnywayRef.current)) - ) { - const swapSettings: PendingSwapSettings = { - slippage: userSlippage.toString(), - disabledSwappersGroups: disabledLiquiditySources, - }; - - const newSwap = calculatePendingSwap( - inputAmount.toString(), - confiremedRoute, - getWalletsForNewSwap(selectedWallets), - swapSettings, - false, - meta - ); - return newSwap; - } else if (!proceedAnywayRef.current) { - proceedAnywayRef.current = true; - setErrors(confirmSwapState.errors); - setWarnings(confirmSwapState.warnings); - confiremedRouteRef.current = confiremedRoute; - } - return; - } catch (error) { - if ((error as any)?.code === 'ERR_CANCELED') { - return; - } - - const status = (error as any)?.response?.status; - - setLoading(false); - setErrors([ - { - type: ConfirmSwapErrorTypes.REQUEST_FAILED, - status, - }, - ]); - - return; - } - }; - - return { loading, warnings, errors, confirmSwap }; -} diff --git a/widget/embedded/src/hooks/useConfirmSwap/index.ts b/widget/embedded/src/hooks/useConfirmSwap/index.ts new file mode 100644 index 0000000000..5229351fe2 --- /dev/null +++ b/widget/embedded/src/hooks/useConfirmSwap/index.ts @@ -0,0 +1 @@ +export { useConfirmSwap } from './useConfirmSwap'; diff --git a/widget/embedded/src/hooks/useConfirmSwap/useConfirmSwap.helpers.ts b/widget/embedded/src/hooks/useConfirmSwap/useConfirmSwap.helpers.ts new file mode 100644 index 0000000000..567e0a4509 --- /dev/null +++ b/widget/embedded/src/hooks/useConfirmSwap/useConfirmSwap.helpers.ts @@ -0,0 +1,164 @@ +import type { ConfirmSwapFetchResult } from './useConfirmSwap.types'; +import type { FindToken } from '../../store/slices/data'; +import type { + ConfirmSwapWarnings, + QuoteErrorResponse, + QuoteResponse, + SelectedQuote, + Wallet, +} from '../../types'; +import type BigNumber from 'bignumber.js'; +import type { BlockchainMeta, SwapResult } from 'rango-sdk'; + +import { errorMessages } from '../../constants/errors'; +import { QuoteErrorType } from '../../types'; +import { generateQuoteWarnings } from '../../utils/quote'; +import { + checkSlippageErrors, + generateBalanceWarnings, + getLimitErrorMessage, + getMinRequiredSlippage, + hasLimitError, +} from '../../utils/swap'; + +/** + * A request can be successful but in body of the response, it can be some case which is considered as failed. + */ +export function throwErrorIfResponseIsNotValid(response: QuoteResponse) { + if (!response.swaps) { + throw new Error(errorMessages().noResultError.title, { + cause: { + type: QuoteErrorType.NO_RESULT, + diagnosisMessage: response.diagnosisMessages?.[0], + }, + }); + } + const quoteError = getQuoteError(response.swaps); + if (quoteError) { + throw new Error(quoteError.message, { + cause: quoteError.options, + }); + } +} + +export function getQuoteError(swaps: SwapResult[]): QuoteErrorResponse | null { + const limitError = hasLimitError(swaps); + if (limitError) { + const { swap, recommendation, fromAmountRangeError } = + getLimitErrorMessage(swaps); + return { + message: 'bridge limit error', + options: { + type: QuoteErrorType.BRIDGE_LIMIT, + swap, + recommendation, + fromAmountRangeError, + }, + }; + } + + const recommendedSlippages = checkSlippageErrors(swaps); + + if (recommendedSlippages) { + const minRequiredSlippage = getMinRequiredSlippage(swaps); + return { + message: '', + options: { + type: QuoteErrorType.INSUFFICIENT_SLIPPAGE, + recommendedSlippages, + minRequiredSlippage, + }, + }; + } + return null; +} + +export function generateWarnings(params: { + currentQuote: SelectedQuote; + previousQuote?: SelectedQuote; + meta: { blockchains: BlockchainMeta[] }; + selectedWallets: Wallet[]; + userSlippage: number; + inputUsdValue: BigNumber | null; + findToken: FindToken; +}): ConfirmSwapWarnings { + const { + currentQuote, + previousQuote, + meta, + selectedWallets, + userSlippage, + findToken, + } = params; + + const output: ConfirmSwapWarnings = { + quote: null, + balance: null, + }; + + const quoteWarning = generateQuoteWarnings({ + previousQuote, + currentQuote, + findToken, + userSlippage, + }); + + if (quoteWarning) { + output.quote = quoteWarning; + } + + const balanceWarnings = generateBalanceWarnings( + currentQuote, + selectedWallets, + meta.blockchains + ); + + const enoughBalance = balanceWarnings.length === 0; + + if (!enoughBalance) { + output.balance = { + messages: balanceWarnings, + }; + } + + return output; +} + +export function handleQuoteErrors(error: any): ConfirmSwapFetchResult { + if (error?.code === 'ERR_CANCELED') { + return { + swap: null, + error: { + type: QuoteErrorType.REQUEST_CANCELED, + }, + warnings: null, + }; + } + + if (error.cause) { + return { + swap: null, + error: error.cause, + warnings: null, + }; + } + + if (error?.code === 'ERR_BAD_REQUEST') { + return { + swap: null, + error: { + type: QuoteErrorType.NO_RESULT, + diagnosisMessage: error.response.data.error, + }, + warnings: null, + }; + } + + return { + swap: null, + error: { + type: QuoteErrorType.REQUEST_FAILED, + }, + warnings: null, + }; +} diff --git a/widget/embedded/src/hooks/useConfirmSwap/useConfirmSwap.ts b/widget/embedded/src/hooks/useConfirmSwap/useConfirmSwap.ts new file mode 100644 index 0000000000..7f7bf7fe25 --- /dev/null +++ b/widget/embedded/src/hooks/useConfirmSwap/useConfirmSwap.ts @@ -0,0 +1,139 @@ +import type { ConfirmSwap } from './useConfirmSwap.types'; +import type { PendingSwapSettings, SelectedQuote } from '../../types'; +import type { ConfirmRouteRequest } from 'rango-sdk'; + +import { calculatePendingSwap } from '@rango-dev/queue-manager-rango-preset'; +import { useEffect } from 'react'; + +import { useAppStore } from '../../store/AppStore'; +import { useQuoteStore } from '../../store/quote'; +import { getWalletsForNewSwap } from '../../utils/swap'; +import { useFetchConfirmQuote } from '../useFetchConfirmQuote'; + +import { + generateWarnings, + handleQuoteErrors, + throwErrorIfResponseIsNotValid, +} from './useConfirmSwap.helpers'; + +export function useConfirmSwap(): ConfirmSwap { + const { + fromToken, + toToken, + inputAmount, + inputUsdValue, + setSelectedQuote, + selectedQuote: initialQuote, + customDestination: customDestinationFromStore, + resetAlerts, + } = useQuoteStore(); + + const { slippage, customSlippage } = useAppStore(); + const disabledLiquiditySources = useAppStore().getDisabledLiquiditySources(); + const blockchains = useAppStore().blockchains(); + const tokens = useAppStore().tokens(); + const { findToken } = useAppStore(); + + const userSlippage = customSlippage || slippage; + + const { fetch: fetchQuote, cancelFetch, loading } = useFetchConfirmQuote(); + + useEffect(() => cancelFetch, []); + + const fetch: ConfirmSwap['fetch'] = async (params) => { + const selectedWallets = params.selectedWallets; + const customDestination = + params?.customDestination ?? customDestinationFromStore; + + if (!fromToken || !toToken || !inputAmount) { + return { + quote: null, + swap: null, + error: null, + warnings: null, + }; + } + + const wallets = selectedWallets.reduce( + (acc: Record, item) => { + acc[item.chain] = item.address; + return acc; + }, + {} + ); + const requestBody: ConfirmRouteRequest = { + requestId: initialQuote?.requestId || '', + selectedWallets: wallets, + destination: customDestination || undefined, + }; + + try { + return await fetchQuote(requestBody, true).then((response) => { + const { result } = response; + + if (!result) { + throw new Error('Error fetching updated route'); + } + + throwErrorIfResponseIsNotValid({ + diagnosisMessages: result.diagnosisMessages, + requestId: result.requestId, + swaps: result.result?.swaps, + }); + + const currentQuote: SelectedQuote = { + outputAmount: result.result?.outputAmount, + requestId: result.requestId, + resultType: result.result?.resultType, + swaps: result.result?.swaps || [], + validationStatus: result.validationStatus, + requestAmount: result.requestAmount, + }; + setSelectedQuote(currentQuote); + const swapSettings: PendingSwapSettings = { + slippage: userSlippage.toString(), + disabledSwappersGroups: disabledLiquiditySources, + }; + + const confirmSwapWarnings = generateWarnings({ + previousQuote: initialQuote ?? undefined, + currentQuote, + meta: { blockchains }, + selectedWallets, + userSlippage, + inputUsdValue, + findToken, + }); + + resetAlerts(); + + const proceedAnyway = !!confirmSwapWarnings.balance; + + const swap = calculatePendingSwap( + inputAmount.toString(), + result, + getWalletsForNewSwap(selectedWallets), + swapSettings, + proceedAnyway ? false : true, + { blockchains, tokens } + ); + + return { + quote: currentQuote, + swap, + error: null, + warnings: confirmSwapWarnings, + }; + }); + } catch (error: any) { + const confirmSwapResult = handleQuoteErrors(error); + return confirmSwapResult; + } + }; + + return { + loading, + fetch, + cancelFetch, + }; +} diff --git a/widget/embedded/src/hooks/useConfirmSwap/useConfirmSwap.types.ts b/widget/embedded/src/hooks/useConfirmSwap/useConfirmSwap.types.ts new file mode 100644 index 0000000000..cd8bb8a7d2 --- /dev/null +++ b/widget/embedded/src/hooks/useConfirmSwap/useConfirmSwap.types.ts @@ -0,0 +1,19 @@ +import type { ConfirmSwapWarnings, QuoteError, Wallet } from '../../types'; +import type { PendingSwap } from 'rango-types'; + +export type ConfirmSwapFetchResult = { + swap: PendingSwap | null; + error: QuoteError | null; + warnings: ConfirmSwapWarnings | null; +}; + +export type ConfirmSwap = { + loading: boolean; + fetch: (params: Params) => Promise; + cancelFetch: () => void; +}; + +export type Params = { + selectedWallets: Wallet[]; + customDestination: string | null; +}; diff --git a/widget/embedded/src/hooks/useFetch.ts b/widget/embedded/src/hooks/useFetch.ts new file mode 100644 index 0000000000..477a21d0a3 --- /dev/null +++ b/widget/embedded/src/hooks/useFetch.ts @@ -0,0 +1,59 @@ +import type { RequestOptions } from 'rango-sdk'; + +import { useRef, useState } from 'react'; + +type UseFetchOptions = { + request: ( + requestBody: TRequest, + options?: RequestOptions + ) => Promise; +}; +export type UseFetchResult = { + fetch: (requestBody: TRequest, retryOnFail?: boolean) => Promise; + cancelFetch: () => void; + loading: boolean; +}; + +const RETRY_DELAY = 2_000; + +export function useFetch({ + request, +}: UseFetchOptions): UseFetchResult { + const [loading, setLoading] = useState(false); + const abortController = useRef(null); + + const cancelFetch = () => abortController.current?.abort(); + + const retryFetch = async (requestBody: TRequest) => { + await new Promise((resolve) => setTimeout(resolve, RETRY_DELAY)); + return await fetch(requestBody, false); + }; + + const fetch: UseFetchResult['fetch'] = async ( + requestBody, + retryOnFail = false + ) => { + cancelFetch(); + abortController.current = new AbortController(); + + setLoading(true); + try { + const res = await request(requestBody, { + signal: abortController.current.signal, + }); + + abortController.current = null; + return res; + // eslint-disable-next-line no-useless-catch + } catch (error) { + if (retryOnFail) { + return await retryFetch(requestBody); + } + throw error; + } finally { + setLoading(false); + } + }; + + return { fetch, loading, cancelFetch }; +} diff --git a/widget/embedded/src/hooks/useFetchAllQuotes.ts b/widget/embedded/src/hooks/useFetchAllQuotes.ts new file mode 100644 index 0000000000..ba88e5b218 --- /dev/null +++ b/widget/embedded/src/hooks/useFetchAllQuotes.ts @@ -0,0 +1,21 @@ +import type { UseFetchResult } from './useFetch'; +import type { BestRouteRequest, MultiRouteResponse } from 'rango-sdk'; + +import { httpService } from '../services/httpService'; + +import { useFetch } from './useFetch'; + +export function useFetchAllQuotes(): UseFetchResult< + BestRouteRequest, + MultiRouteResponse +> { + const { fetch, loading, cancelFetch } = useFetch< + BestRouteRequest, + MultiRouteResponse + >({ + request: async (requestBody, options) => + await httpService().getAllRoutes(requestBody, options), + }); + + return { fetch, loading, cancelFetch }; +} diff --git a/widget/embedded/src/hooks/useFetchApiConfig.ts b/widget/embedded/src/hooks/useFetchApiConfig.ts new file mode 100644 index 0000000000..f3d406d6c2 --- /dev/null +++ b/widget/embedded/src/hooks/useFetchApiConfig.ts @@ -0,0 +1,37 @@ +import { useUiStore } from '../store/ui'; +import { getConfig } from '../utils/configs'; + +export type Watermark = 'NONE' | 'FULL'; + +type ConfigResponse = { + config: { + watermark: Watermark; + banners: { + profile: boolean; + }; + }; +}; + +interface UseFetchApiConfig { + fetchApiConfig: () => Promise; +} + +export function useFetchApiConfig(): UseFetchApiConfig { + const { setWatermark, setShowProfileBanner } = useUiStore(); + + const fetchApiConfig: UseFetchApiConfig['fetchApiConfig'] = async () => { + const response = await fetch( + `${getConfig('BASE_URL')}/meta/dapp/config?apiKey=${getConfig('API_KEY')}` + ); + + if (!response.ok) { + throw new Error(`Request failed with status: ${response.status} `); + } + + const data: ConfigResponse = await response.json(); + + setWatermark(data.config.watermark); + setShowProfileBanner(data.config.banners.profile); + }; + return { fetchApiConfig }; +} diff --git a/widget/embedded/src/hooks/useFetchConfirmQuote.ts b/widget/embedded/src/hooks/useFetchConfirmQuote.ts new file mode 100644 index 0000000000..c208397a2f --- /dev/null +++ b/widget/embedded/src/hooks/useFetchConfirmQuote.ts @@ -0,0 +1,21 @@ +import type { UseFetchResult } from './useFetch'; +import type { ConfirmRouteRequest, ConfirmRouteResponse } from 'rango-sdk'; + +import { httpService } from '../services/httpService'; + +import { useFetch } from './useFetch'; + +export function useFetchConfirmQuote(): UseFetchResult< + ConfirmRouteRequest, + ConfirmRouteResponse +> { + const { fetch, loading, cancelFetch } = useFetch< + ConfirmRouteRequest, + ConfirmRouteResponse + >({ + request: async (requestBody, options) => + await httpService().confirmRoute(requestBody, options), + }); + + return { fetch, loading, cancelFetch }; +} diff --git a/widget/embedded/src/hooks/useFetchCustomToken.ts b/widget/embedded/src/hooks/useFetchCustomToken.ts new file mode 100644 index 0000000000..8569340247 --- /dev/null +++ b/widget/embedded/src/hooks/useFetchCustomToken.ts @@ -0,0 +1,118 @@ +import type { Token } from 'rango-sdk'; + +import { i18n } from '@lingui/core'; +import { useState } from 'react'; + +import { httpService } from '../services/httpService'; +import { useAppStore } from '../store/AppStore'; + +type ErrorType = { + title: string; + message: string; +}; + +interface UseFetchCustomToken { + fetchCustomToken: ({ + blockchain, + tokenAddress, + }: { + blockchain: string; + tokenAddress: string; + }) => Promise; + loading: boolean; + error?: ErrorType; +} + +export function useFetchCustomToken(): UseFetchCustomToken { + const [loading, setLoading] = useState(false); + const [error, setError] = useState(undefined); + const { findToken } = useAppStore(); + const customTokens = useAppStore().customTokens(); + + function produceErrorMessage( + type: 'duplicated' | 'not-found' | 'token-exist', + blockchain?: string + ) { + switch (type) { + case 'duplicated': + return { + title: i18n.t('Duplicate Token'), + message: i18n.t( + 'The address you entered is duplicate, please enter a new address.' + ), + }; + case 'token-exist': + return { + title: i18n.t('Token Already Exists'), + message: i18n.t( + `There's no need to add this token again because it already exists and is supported by us.` + ), + }; + case 'not-found': + return { + title: i18n.t('Token Not Found'), + message: i18n.t({ + id: 'Sorry, no token was found on {blockchain} chain with the provided address. please make sure you have entered the right token address.', + values: { + blockchain, + }, + }), + }; + } + } + + const fetchCustomToken: UseFetchCustomToken['fetchCustomToken'] = async ({ + blockchain, + tokenAddress, + }) => { + setLoading(true); + try { + // Check for duplicate token in customTokens + const isDuplicate = customTokens.some( + (token) => token.address?.toLowerCase() === tokenAddress.toLowerCase() + ); + if (isDuplicate) { + const errorMessage = produceErrorMessage('duplicated'); + setError(errorMessage); + return undefined; + } + + const response = await httpService().getCustomToken({ + blockchain, + address: tokenAddress, + }); + + if (!response || !response.token || response.error) { + const errorMessage = produceErrorMessage('not-found', blockchain); + setError(errorMessage); + return undefined; + } + + // Check if token is already in the system + const token = response.token; + const isTokenFound = findToken({ + blockchain: token.blockchain, + address: token.address, + symbol: token.symbol, + }); + if (isTokenFound) { + const errorMessage = produceErrorMessage('token-exist'); + setError(errorMessage); + return undefined; + } + + return token; + } catch (error: any) { + if (error?.code === 'ERR_BAD_REQUEST') { + const errorMessage = produceErrorMessage('not-found', blockchain); + setError(errorMessage); + return undefined; + } + setError(undefined); + throw new Error(error.message); + } finally { + setLoading(false); + } + }; + return { fetchCustomToken, loading, error }; +} diff --git a/widget/embedded/src/hooks/useFontLoader.ts b/widget/embedded/src/hooks/useFontLoader.ts new file mode 100644 index 0000000000..d8ceba4318 --- /dev/null +++ b/widget/embedded/src/hooks/useFontLoader.ts @@ -0,0 +1,40 @@ +import { useState } from 'react'; + +import { getFontUrlByName } from '../utils/common'; +/* + *TODO: + * Loading fonts from JS has a downside and it is the bundle needs to be downloaded and executed first which means after sometime font will be added to and it causes a layoutshift each time. + * We've added Roboto into since it's the default font. the downside here is it will load roboto anyway even dApp has set fontFamily other than Roboto which causes an unneccerary downloand (Roboto). + * We decided to go with the second one and it can be solved in future by split these types of configs into a separate js file and let it to be loaded with a more priority than the main bundle. it should be also cached which imrpove user experience after first load. + */ +const useFontLoader = () => { + const [fontLink, setFontLink] = useState(null); + + const loadFont = (fontUrl: string) => { + const link = document.createElement('link'); + link.href = fontUrl; + link.rel = 'stylesheet'; + document.head.appendChild(link); + return link; + }; + + const unloadFont = () => { + if (fontLink) { + document.head.removeChild(fontLink); + setFontLink(null); + } + }; + + const handleLoadCustomFont = (fontName: string) => { + unloadFont(); // Remove previous font + const fontUrl = getFontUrlByName(fontName); + if (fontUrl) { + const newFontLink = loadFont(fontUrl); + setFontLink(newFontLink); + } + }; + + return { handleLoadCustomFont }; +}; + +export default useFontLoader; diff --git a/widget/embedded/src/hooks/useForceAutoConnect.ts b/widget/embedded/src/hooks/useForceAutoConnect.ts new file mode 100644 index 0000000000..c065eb50bd --- /dev/null +++ b/widget/embedded/src/hooks/useForceAutoConnect.ts @@ -0,0 +1,27 @@ +import { useWallets } from '@rango-dev/wallets-react'; +import { useEffect, useRef } from 'react'; + +import { SearchParams } from '../constants/searchParams'; +import { useAppStore } from '../store/AppStore'; + +export function useForceAutoConnect(): void { + const { connect, state } = useWallets(); + const initiated = useRef<{ [key: string]: boolean }>({}); + const { fetchStatus } = useAppStore(); + const walletType = + new URLSearchParams(location.search).get(SearchParams.AUTO_CONNECT) || ''; + const walletState = state(walletType); + + useEffect(() => { + const shouldTryConnect = + fetchStatus === 'success' && + walletType && + walletState.installed && + !walletState.connecting && + !walletState.connected; + if (shouldTryConnect && !initiated.current[walletType]) { + initiated.current[walletType] = true; + void connect(walletType); + } + }, [walletState, fetchStatus]); +} diff --git a/widget/embedded/src/hooks/useIframe/index.ts b/widget/embedded/src/hooks/useIframe/index.ts new file mode 100644 index 0000000000..69b1ed0ca6 --- /dev/null +++ b/widget/embedded/src/hooks/useIframe/index.ts @@ -0,0 +1 @@ +export { useIframe } from './useIframe'; diff --git a/widget/embedded/src/hooks/useIframe/useIframe.helpers.ts b/widget/embedded/src/hooks/useIframe/useIframe.helpers.ts new file mode 100644 index 0000000000..6bf03a8df9 --- /dev/null +++ b/widget/embedded/src/hooks/useIframe/useIframe.helpers.ts @@ -0,0 +1,3 @@ +export function isAppLoadedIntoIframe() { + return window.self !== window.top; +} diff --git a/widget/embedded/src/hooks/useIframe/useIframe.ts b/widget/embedded/src/hooks/useIframe/useIframe.ts new file mode 100644 index 0000000000..c72f039983 --- /dev/null +++ b/widget/embedded/src/hooks/useIframe/useIframe.ts @@ -0,0 +1,55 @@ +import type { Messages } from './useIframe.types'; + +import { useRef } from 'react'; + +import { useAppStore } from '../../store/AppStore'; + +import { isAppLoadedIntoIframe } from './useIframe.helpers'; + +interface UseIframe { + send: (message: Messages) => void; + connectHeightObserver: (element: HTMLElement) => void; + disconnectHeightObserver: () => void; +} + +function useIframe(): UseIframe { + const heightObserver = useRef(null); + const { iframe } = useAppStore(); + const isMessagePassingAvailable = isAppLoadedIntoIframe() && iframe.clientUrl; + + const send = (message: Messages) => { + if (isMessagePassingAvailable) { + window.top?.postMessage(message, iframe.clientUrl!); + } + }; + + const connectHeightObserver = (element: HTMLElement) => { + heightObserver.current = new ResizeObserver((entries) => { + for (const entry of entries) { + send({ + type: 'widget_height', + data: { + height: entry.contentRect.height, + }, + }); + } + }); + + heightObserver.current.observe(element); + }; + + const disconnectHeightObserver = () => { + if (heightObserver.current) { + heightObserver.current.disconnect(); + heightObserver.current = null; + } + }; + + return { + send, + connectHeightObserver, + disconnectHeightObserver, + }; +} + +export { useIframe }; diff --git a/widget/embedded/src/hooks/useIframe/useIframe.types.ts b/widget/embedded/src/hooks/useIframe/useIframe.types.ts new file mode 100644 index 0000000000..66a96a9e9b --- /dev/null +++ b/widget/embedded/src/hooks/useIframe/useIframe.types.ts @@ -0,0 +1,13 @@ +type Message = { + type: T; + data: D; +}; +type WidgetHeightMessage = Message< + 'widget_height', + { + height: number; + } +>; + +// Add new types of messages to this union. +export type Messages = WidgetHeightMessage; diff --git a/widget/embedded/src/hooks/useLanguage.ts b/widget/embedded/src/hooks/useLanguage.ts new file mode 100644 index 0000000000..7ce4c3fd67 --- /dev/null +++ b/widget/embedded/src/hooks/useLanguage.ts @@ -0,0 +1,28 @@ +import type { LanguageItem } from '../constants/languages'; + +import { type Language } from '@rango-dev/ui'; + +import { DEFAULT_LANGUAGE, LANGUAGES } from '../constants/languages'; +import { useAppStore } from '../store/AppStore'; + +interface UseLanguage { + languages: LanguageItem[]; + defaultLanguage: Language; + activeLanguage: Language; + changeLanguage: (language?: Language | null) => void; + resetLanguage: () => void; +} + +export function useLanguage(): UseLanguage { + const { setLanguage, language, config } = useAppStore(); + const languages = LANGUAGES; + const defaultLanguage = config?.language || DEFAULT_LANGUAGE; + + return { + activeLanguage: language || defaultLanguage, + languages, + defaultLanguage, + changeLanguage: (language) => setLanguage(language || DEFAULT_LANGUAGE), + resetLanguage: () => setLanguage(null), + }; +} diff --git a/widget/embedded/src/hooks/useNavigateBack.ts b/widget/embedded/src/hooks/useNavigateBack.ts index bbf7830b99..e01765063e 100644 --- a/widget/embedded/src/hooks/useNavigateBack.ts +++ b/widget/embedded/src/hooks/useNavigateBack.ts @@ -1,40 +1,6 @@ -import { useInRouterContext, useNavigate } from 'react-router-dom'; -import { navigationRoutes } from '../constants/navigationRoutes'; +import { useNavigate } from 'react-router-dom'; -export function useNavigateBack() { - const isRouterInContext = useInRouterContext(); +export function useNavigateBack(): () => void { const navigate = useNavigate(); - - navigationRoutes; - - const navigateBackFrom = (currentRoute: string) => { - if (currentRoute === navigationRoutes.swapDetails) - return navigate(navigationRoutes.swaps, { replace: true }); - if ( - !isRouterInContext || - (window.history.state && window.history.state.idx > 0) - ) - navigate(-1); - else { - if ( - [ - navigationRoutes.fromChain, - navigationRoutes.fromToken, - navigationRoutes.toChain, - navigationRoutes.toToken, - navigationRoutes.settings, - navigationRoutes.wallets, - navigationRoutes.swaps, - navigationRoutes.confirmSwap, - ].includes(currentRoute) - ) - navigate(navigationRoutes.home, { replace: true }); - else if (currentRoute === navigationRoutes.liquiditySources) - navigate(navigationRoutes.settings, { replace: true }); - else if (currentRoute === navigationRoutes.swapDetails) - navigate(navigationRoutes.swaps, { replace: true }); - } - }; - - return { navigateBackFrom }; + return () => navigate(-1); } diff --git a/widget/embedded/src/hooks/usePrepareBlockchainList/index.ts b/widget/embedded/src/hooks/usePrepareBlockchainList/index.ts new file mode 100644 index 0000000000..3fe71300f0 --- /dev/null +++ b/widget/embedded/src/hooks/usePrepareBlockchainList/index.ts @@ -0,0 +1 @@ +export { usePrepareBlockchainList } from './usePrepareBlockchainList'; diff --git a/widget/embedded/src/hooks/usePrepareBlockchainList/usePrepareBlockchainList.constants.ts b/widget/embedded/src/hooks/usePrepareBlockchainList/usePrepareBlockchainList.constants.ts new file mode 100644 index 0000000000..e47e83cc94 --- /dev/null +++ b/widget/embedded/src/hooks/usePrepareBlockchainList/usePrepareBlockchainList.constants.ts @@ -0,0 +1 @@ +export const MOST_USED_BLOCKCHAINS = ['ETH', 'COSMOS', 'OSMOSIS']; diff --git a/widget/embedded/src/hooks/usePrepareBlockchainList/usePrepareBlockchainList.helpers.ts b/widget/embedded/src/hooks/usePrepareBlockchainList/usePrepareBlockchainList.helpers.ts new file mode 100644 index 0000000000..6844414a92 --- /dev/null +++ b/widget/embedded/src/hooks/usePrepareBlockchainList/usePrepareBlockchainList.helpers.ts @@ -0,0 +1,138 @@ +import type { + PrepareListOptions, + PrepareOutput, +} from './usePrepareBlockchainList.types'; +import type { BlockchainMeta } from 'rango-sdk'; + +import { MOST_USED_BLOCKCHAINS } from './usePrepareBlockchainList.constants'; + +export function prepare( + blockchains: BlockchainMeta[], + preferredBlockchains: string[], + options?: PrepareListOptions +): PrepareOutput { + /* + * TODO: + * We copying the `blockchains` which can causes performance penalties but we should because we are mutating the original object. + * A better way to solve the problem maybe is using new JS features like Use toSpliced() but + * we can not use it right now because we need to upgrade our toolings first. + */ + const list: BlockchainMeta[] = JSON.parse(JSON.stringify(blockchains)); + let more: BlockchainMeta[] = []; + + list.sort(sortByMostUsedBlockchains); + + // Checking `limit` has set and it should be more than of the list items. + if (!!options?.limit && blockchains.length > options.limit) { + const start = options.limit; + let preferredBlockchainsWithoutMainList = preferredBlockchains; + + if (preferredBlockchains.length <= options.limit) { + /** + * + * if we want to show 10 items (aka `options.limit`) + * and have these items as our preferred list: [x,y,z] + * and these as our main list: [A, B, C, D, E, F, G, H, I, J] + * the final list will be like this: [...preferred, ...mainList]. + * + * Since we have a limit (e.g. 10) on our list (preferred + mainList), + * we only should check those items from main list that will be in final list. + * + * finalListWithoutLimit = [x,y,z, A, B, C, D, E, F, G, H, I, J] + * finalListWithLimit = [x,y,z, A, B, C, D, E, F, G] + * + * As you can see, [H, I, J] will not be in our list. + * + * The following code only check preffred blockchain + * shouldn't be in first 7 of 10 items in main list. (Since, the last 3 items will not be in the final list and we should check those.) + */ + const howManyItemsShouldBeCheckedFromMainList = + options.limit - preferredBlockchains.length; + + for (let i = 0; i <= howManyItemsShouldBeCheckedFromMainList; i++) { + const blockchain = list[i]; + + preferredBlockchainsWithoutMainList = + preferredBlockchainsWithoutMainList.filter((preferredBlockchain) => { + return blockchain.name !== preferredBlockchain; + }); + } + } + + list.sort( + generateSortByPreferredBlockchainsFor(preferredBlockchainsWithoutMainList) + ); + + /* + * Splice will modify the original list and returns the deleted items + * We use the deleted items as `more` + */ + more = list.splice(start); + } + return { + list, + more, + }; +} + +/** There is a hardcoded list of blockchains that we want to show them first in the list. */ +export function sortByMostUsedBlockchains( + a: BlockchainMeta, + b: BlockchainMeta +) { + const mostUsed = MOST_USED_BLOCKCHAINS; + const aIndexInMostUsed = mostUsed.findIndex((token) => token === a.name); + const bIndexInMostUsed = mostUsed.findIndex((token) => token === b.name); + const aIsMostUsed = aIndexInMostUsed > -1; + const bIsMostUsed = bIndexInMostUsed > -1; + + if (aIsMostUsed && bIsMostUsed) { + return aIndexInMostUsed > bIndexInMostUsed ? 1 : -1; + } + + if (aIsMostUsed) { + return -1; + } + + if (bIsMostUsed) { + return 1; + } + + return 0; +} + +export function generateSortByPreferredBlockchainsFor( + preferredBlockchains: string[] +) { + return function sortByPreferred(a: BlockchainMeta, b: BlockchainMeta) { + const aIndexInPreferred = preferredBlockchains.findIndex( + (blockchain) => blockchain === a.name + ); + const bIndexInPreferred = preferredBlockchains.findIndex( + (blockchain) => blockchain === b.name + ); + + const aIsPreferred = aIndexInPreferred > -1; + const bIsPreferred = bIndexInPreferred > -1; + + if (aIsPreferred && bIsPreferred) { + return aIndexInPreferred > bIndexInPreferred ? 1 : -1; + } + + if (preferredBlockchains.includes(a.name)) { + return -1; + } + if (preferredBlockchains.includes(b.name)) { + return 1; + } + + return 0; + }; +} + +export function isInVisibleList( + blockchain: string, + prepareOutput: PrepareOutput +): boolean { + return !!prepareOutput.list.find((item) => item.name === blockchain); +} diff --git a/widget/embedded/src/hooks/usePrepareBlockchainList/usePrepareBlockchainList.mock.ts b/widget/embedded/src/hooks/usePrepareBlockchainList/usePrepareBlockchainList.mock.ts new file mode 100644 index 0000000000..bc82862912 --- /dev/null +++ b/widget/embedded/src/hooks/usePrepareBlockchainList/usePrepareBlockchainList.mock.ts @@ -0,0 +1,3292 @@ +import type { BlockchainMeta } from 'rango-sdk'; + +import { TransactionType } from 'rango-sdk'; + +export const sampleDefaultBlockchainNames = [ + 'ETH', + 'COSMOS', + 'OSMOSIS', + 'BSC', + 'ARBITRUM', + 'POLYGON', + 'ZKSYNC', + 'STARKNET', + 'OPTIMISM', + 'AVAX_CCHAIN', + 'POLYGONZK', + 'LINEA', + 'TRON', + 'BTC', + 'NEUTRON', + 'NOBLE', + 'SOLANA', + 'CRONOS', + 'BNB', + 'AURORA', + 'MAYA', + 'THOR', + 'BOBA', + 'MOONBEAM', + 'MOONRIVER', + 'OKC', + 'BOBA_AVALANCHE', + 'LTC', + 'BCH', + 'HECO', + 'STARGAZE', + 'CRYPTO_ORG', + 'CHIHUAHUA', + 'BANDCHAIN', + 'COMDEX', + 'REGEN', + 'IRIS', + 'EMONEY', + 'JUNO', + 'STRIDE', + 'MARS', + 'TERRA', + 'BITSONG', + 'AKASH', + 'KI', + 'PERSISTENCE', + 'MEDIBLOC', + 'KUJIRA', + 'SENTINEL', + 'INJECTIVE', + 'SECRET', + 'KONSTELLATION', + 'STARNAME', + 'BITCANNA', + 'UMEE', + 'DESMOS', + 'LUMNETWORK', +]; + +export const sampleBlockchains: BlockchainMeta[] = [ + { + name: 'ETH', + defaultDecimals: 18, + addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], + feeAssets: [ + { + blockchain: 'ETH', + symbol: 'ETH', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/ethereum.svg', + displayName: 'Ethereum', + shortName: 'ETH', + sort: 0, + color: '#ecf0f1', + enabled: true, + type: TransactionType.EVM, + chainId: '0x1', + info: { + infoType: 'EvmMetaInfo', + chainName: 'Ethereum Mainnet', + nativeCurrency: { + name: 'ETH', + symbol: 'ETH', + decimals: 18, + }, + rpcUrls: ['https://rpc.ankr.com/eth'], + blockExplorerUrls: ['https://etherscan.io'], + addressUrl: 'https://etherscan.io/address/{wallet}', + transactionUrl: 'https://etherscan.io/tx/{txHash}', + enableGasV2: true, + }, + }, + { + name: 'BSC', + defaultDecimals: 18, + addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], + feeAssets: [ + { + blockchain: 'BSC', + symbol: 'BNB', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/bsc.svg', + displayName: 'BNB Smart Chain', + shortName: 'BSC', + sort: 1, + color: '#F3BA2F', + enabled: true, + type: TransactionType.EVM, + chainId: '0x38', + info: { + infoType: 'EvmMetaInfo', + chainName: 'Binance Smart Chain Mainnet', + nativeCurrency: { + name: 'BNB', + symbol: 'BNB', + decimals: 18, + }, + rpcUrls: ['https://bsc-dataseed1.ninicoin.io'], + blockExplorerUrls: ['https://bscscan.com'], + addressUrl: 'https://bscscan.com/address/{wallet}', + transactionUrl: 'https://bscscan.com/tx/{txHash}', + enableGasV2: true, + }, + }, + { + name: 'ARBITRUM', + defaultDecimals: 18, + addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], + feeAssets: [ + { + blockchain: 'ARBITRUM', + symbol: 'ETH', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/arbitrum.svg', + displayName: 'Arbitrum', + shortName: 'Arbitrum', + sort: 2, + color: '#28a0f0', + enabled: true, + type: TransactionType.EVM, + chainId: '0xa4b1', + info: { + infoType: 'EvmMetaInfo', + chainName: 'Arbitrum One', + nativeCurrency: { + name: 'ETH', + symbol: 'ETH', + decimals: 18, + }, + rpcUrls: ['https://arb1.arbitrum.io/rpc'], + blockExplorerUrls: ['https://arbiscan.io'], + addressUrl: 'https://arbiscan.io/address/{wallet}', + transactionUrl: 'https://arbiscan.io/tx/{txHash}', + enableGasV2: true, + }, + }, + { + name: 'POLYGON', + defaultDecimals: 18, + addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], + feeAssets: [ + { + blockchain: 'POLYGON', + symbol: 'MATIC', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/polygon.svg', + displayName: 'Polygon', + shortName: 'Polygon', + sort: 3, + color: '#8247E5', + enabled: true, + type: TransactionType.EVM, + chainId: '0x89', + info: { + infoType: 'EvmMetaInfo', + chainName: 'Polygon Mainnet', + nativeCurrency: { + name: 'MATIC', + symbol: 'MATIC', + decimals: 18, + }, + rpcUrls: ['https://polygon-rpc.com'], + blockExplorerUrls: ['https://polygonscan.com'], + addressUrl: 'https://polygonscan.com/address/{wallet}', + transactionUrl: 'https://polygonscan.com/tx/{txHash}', + enableGasV2: true, + }, + }, + { + name: 'ZKSYNC', + defaultDecimals: 18, + addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], + feeAssets: [ + { + blockchain: 'ZKSYNC', + symbol: 'ETH', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/zksync.png', + displayName: 'zkSync era', + shortName: 'zkSync', + sort: 4, + color: '#2D2925', + enabled: true, + type: TransactionType.EVM, + chainId: '0x144', + info: { + infoType: 'EvmMetaInfo', + chainName: 'zkSync', + nativeCurrency: { + name: 'ETH', + symbol: 'ETH', + decimals: 18, + }, + rpcUrls: ['https://mainnet.era.zksync.io'], + blockExplorerUrls: ['https://explorer.zksync.io'], + addressUrl: 'https://explorer.zksync.io/address/{wallet}', + transactionUrl: 'https://explorer.zksync.io/tx/{txHash}', + enableGasV2: true, + }, + }, + { + name: 'STARKNET', + defaultDecimals: 18, + addressPatterns: ['^(0x)[0-9A-Fa-f]{32,64}$'], + feeAssets: [ + { + blockchain: 'STARKNET', + symbol: 'ETH', + address: + '0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7', + }, + ], + logo: 'https://api.rango.exchange/blockchains/starknet.svg', + displayName: 'StarkNet', + shortName: 'StarkNet', + sort: 5, + color: '#708DD2', + enabled: true, + type: TransactionType.STARKNET, + chainId: '0x534e5f4d41494e', + info: { + infoType: 'StarkNetMetaInfo', + chainName: 'StarkNet Mainnet', + nativeCurrency: { + name: 'ETH', + symbol: 'ETH', + decimals: 18, + }, + blockExplorerUrls: ['https://starkscan.co'], + addressUrl: 'https://starkscan.co/contract/{wallet}', + transactionUrl: 'https://starkscan.co/tx/{txHash}', + }, + }, + { + name: 'OPTIMISM', + defaultDecimals: 18, + addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], + feeAssets: [ + { + blockchain: 'OPTIMISM', + symbol: 'ETH', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/optimism.svg', + displayName: 'Optimism', + shortName: 'Optimism', + sort: 6, + color: '#FF0420', + enabled: true, + type: TransactionType.EVM, + chainId: '0xa', + info: { + infoType: 'EvmMetaInfo', + chainName: 'Optimism', + nativeCurrency: { + name: 'ETH', + symbol: 'ETH', + decimals: 18, + }, + rpcUrls: ['https://mainnet.optimism.io'], + blockExplorerUrls: ['https://optimistic.etherscan.io'], + addressUrl: 'https://optimistic.etherscan.io/address/{wallet}', + transactionUrl: 'https://optimistic.etherscan.io/tx/{txHash}', + enableGasV2: true, + }, + }, + { + name: 'AVAX_CCHAIN', + defaultDecimals: 18, + addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], + feeAssets: [ + { + blockchain: 'AVAX_CCHAIN', + symbol: 'AVAX', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/avax_cchain.svg', + displayName: 'Avalanche', + shortName: 'Avax', + sort: 7, + color: '#e84142', + enabled: true, + type: TransactionType.EVM, + chainId: '0xa86a', + info: { + infoType: 'EvmMetaInfo', + chainName: 'Avalanche C-Chain', + nativeCurrency: { + name: 'AVAX', + symbol: 'AVAX', + decimals: 18, + }, + rpcUrls: ['https://api.avax.network/ext/bc/C/rpc'], + blockExplorerUrls: ['https://snowtrace.io'], + addressUrl: 'https://snowtrace.io/address/{wallet}', + transactionUrl: 'https://snowtrace.io/tx/{txHash}', + enableGasV2: true, + }, + }, + { + name: 'POLYGONZK', + defaultDecimals: 18, + addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], + feeAssets: [ + { + blockchain: 'POLYGONZK', + symbol: 'ETH', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/zkevmpolygon.png', + displayName: 'polygon zkEVM', + shortName: 'Polygon zkEVM', + sort: 8, + color: '#8247e5', + enabled: true, + type: TransactionType.EVM, + chainId: '0x44d', + info: { + infoType: 'EvmMetaInfo', + chainName: 'Polygon zkEVM Mainnet', + nativeCurrency: { + name: 'ETH', + symbol: 'ETH', + decimals: 18, + }, + rpcUrls: ['https://zkevm-rpc.com'], + blockExplorerUrls: ['https://zkevm.polygonscan.com'], + addressUrl: 'https://zkevm.polygonscan.com/address/{wallet}', + transactionUrl: 'https://zkevm.polygonscan.com/tx/{txHash}', + enableGasV2: true, + }, + }, + { + name: 'LINEA', + defaultDecimals: 18, + addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], + feeAssets: [ + { + blockchain: 'LINEA', + symbol: 'ETH', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/linea.svg', + displayName: 'Linea', + shortName: 'Linea', + sort: 9, + color: '#121212', + enabled: true, + type: TransactionType.EVM, + chainId: '0xe708', + info: { + infoType: 'EvmMetaInfo', + chainName: 'Linea Mainnet', + nativeCurrency: { + name: 'ETH', + symbol: 'ETH', + decimals: 18, + }, + rpcUrls: ['https://rpc.linea.build'], + blockExplorerUrls: ['https://explorer.linea.build'], + addressUrl: 'https://explorer.linea.build/address/{wallet}', + transactionUrl: 'https://explorer.linea.build/tx/{txHash}', + enableGasV2: true, + }, + }, + { + name: 'TRON', + defaultDecimals: 18, + addressPatterns: ['^T[1-9A-HJ-NP-Za-km-z]{33}$'], + feeAssets: [ + { + blockchain: 'TRON', + symbol: 'TRX', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/tron.svg', + displayName: 'Tron', + shortName: 'Tron', + sort: 10, + color: '#FF060A', + enabled: true, + type: TransactionType.EVM, + chainId: '0x2b6653dc', + info: { + infoType: 'EvmMetaInfo', + chainName: 'TRON Mainnet', + nativeCurrency: { + name: 'TRX', + symbol: 'TRX', + decimals: 6, + }, + rpcUrls: ['https://api.trongrid.io/jsonrpc'], + blockExplorerUrls: ['https://tronscan.org/#'], + addressUrl: 'https://tronscan.org/#/address/{wallet}', + transactionUrl: 'https://tronscan.org/#/tx/{txHash}', + enableGasV2: true, + }, + }, + { + name: 'BTC', + defaultDecimals: 8, + addressPatterns: [ + '^[13][a-km-zA-HJ-NP-Z1-9]{25,34}$|^(bc1)[0-9A-Za-z]{39,59}$', + ], + feeAssets: [ + { + blockchain: 'BTC', + symbol: 'BTC', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/btc.svg', + displayName: 'Bitcoin', + shortName: 'BTC', + sort: 11, + color: '#F7931A', + enabled: true, + type: TransactionType.TRANSFER, + chainId: null, + info: { + infoType: 'TransferMetaInfo', + blockExplorerUrls: ['https://www.blockchain.com/btc/'], + addressUrl: 'https://www.blockchain.com/btc/address/{wallet}', + transactionUrl: 'https://www.blockchain.com/btc/tx/{txHash}', + }, + }, + { + name: 'COSMOS', + defaultDecimals: 6, + addressPatterns: ['^(cosmos1)[0-9a-z]{38}$'], + feeAssets: [ + { + blockchain: 'COSMOS', + symbol: 'ATOM', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/cosmos.svg', + displayName: 'Cosmos', + shortName: 'Cosmos', + sort: 12, + color: '#2E3148', + enabled: true, + type: TransactionType.COSMOS, + chainId: 'cosmoshub-4', + info: { + infoType: 'CosmosMetaInfo', + blockExplorerUrls: ['https://www.mintscan.io/cosmos/'], + addressUrl: 'https://www.mintscan.io/cosmos/account/{wallet}', + transactionUrl: 'https://www.mintscan.io/cosmos/txs/{txHash}', + experimental: false, + rpc: 'https://cosmos-rpc.polkachu.com', + rest: 'https://lcd-cosmoshub.blockapsis.com', + cosmostationLcdUrl: 'https://lcd-cosmoshub.blockapsis.com', + cosmostationApiUrl: 'https://cosmos-rpc.polkachu.com', + cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', + mintScanName: 'cosmos', + chainName: 'Cosmos', + stakeCurrency: { + coinDenom: 'ATOM', + coinMinimalDenom: 'uatom', + coinDecimals: 6, + coinGeckoId: 'cosmos', + coinImageUrl: '/tokens/blockchain/cosmos.svg', + }, + bip44: { + coinType: 118, + }, + bech32Config: { + bech32PrefixAccAddr: 'cosmos', + bech32PrefixAccPub: 'cosmospub', + bech32PrefixValAddr: 'cosmosvaloper', + bech32PrefixValPub: 'cosmosvaloperpub', + bech32PrefixConsAddr: 'cosmosvalcons', + bech32PrefixConsPub: 'cosmosvalconspub', + }, + currencies: [ + { + coinDenom: 'ATOM', + coinMinimalDenom: 'uatom', + coinDecimals: 6, + coinGeckoId: 'cosmos', + coinImageUrl: '/tokens/blockchain/cosmos.svg', + }, + ], + feeCurrencies: [ + { + coinDenom: 'ATOM', + coinMinimalDenom: 'uatom', + coinDecimals: 6, + coinGeckoId: 'cosmos', + coinImageUrl: '/tokens/blockchain/cosmos.svg', + }, + ], + features: ['stargate', 'ibc-transfer'], + explorerUrlToTx: 'https://www.mintscan.io/cosmos/txs/{txHash}', + gasPriceStep: { + low: 0.01, + average: 0.025, + high: 0.04, + }, + }, + }, + { + name: 'OSMOSIS', + defaultDecimals: 6, + addressPatterns: ['^(osmo1)[0-9a-z]{38}$'], + feeAssets: [ + { + blockchain: 'OSMOSIS', + symbol: 'OSMO', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/osmosis.svg', + displayName: 'Osmosis', + shortName: 'Osmosis', + sort: 13, + color: '#7901B4', + enabled: true, + type: TransactionType.COSMOS, + chainId: 'osmosis-1', + info: { + infoType: 'CosmosMetaInfo', + blockExplorerUrls: ['https://www.mintscan.io/cosmos/'], + addressUrl: 'https://www.mintscan.io/cosmos/account/{wallet}', + transactionUrl: 'https://www.mintscan.io/cosmos/txs/{txHash}', + experimental: false, + rpc: 'https://osmosis-rpc.polkachu.com', + rest: 'https://lcd.osmosis.zone', + cosmostationLcdUrl: 'https://lcd.osmosis.zone', + cosmostationApiUrl: 'https://rpc.osmosis.zone', + cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', + mintScanName: 'osmosis', + chainName: 'Osmosis', + stakeCurrency: { + coinDenom: 'OSMO', + coinMinimalDenom: 'uosmo', + coinDecimals: 6, + coinGeckoId: 'pool:uosmo', + coinImageUrl: '/tokens/blockchain/osmosis.svg', + }, + bip44: { + coinType: 118, + }, + bech32Config: { + bech32PrefixAccAddr: 'osmo', + bech32PrefixAccPub: 'osmopub', + bech32PrefixValAddr: 'osmovaloper', + bech32PrefixValPub: 'osmovaloperpub', + bech32PrefixConsAddr: 'osmovalcons', + bech32PrefixConsPub: 'osmovalconspub', + }, + currencies: [ + { + coinDenom: 'OSMO', + coinMinimalDenom: 'uosmo', + coinDecimals: 6, + coinGeckoId: 'pool:uosmo', + coinImageUrl: '/tokens/blockchain/osmosis.svg', + }, + { + coinDenom: 'ION', + coinMinimalDenom: 'uion', + coinDecimals: 6, + coinGeckoId: 'pool:uion', + coinImageUrl: '/tokens/blockchain/ion.png', + }, + ], + feeCurrencies: [ + { + coinDenom: 'OSMO', + coinMinimalDenom: 'uosmo', + coinDecimals: 6, + coinGeckoId: 'pool:uosmo', + coinImageUrl: '/tokens/blockchain/osmosis.svg', + }, + ], + features: ['stargate', 'ibc-transfer'], + explorerUrlToTx: 'https://www.mintscan.io/osmosis/txs/{txHash}', + gasPriceStep: { + low: 0, + average: 0.025, + high: 0.04, + }, + }, + }, + { + name: 'NEUTRON', + defaultDecimals: 6, + addressPatterns: ['^(neutron1)[0-9a-z]{38}$'], + feeAssets: [ + { + blockchain: 'NEUTRON', + symbol: 'NTRN', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/neutron.svg', + displayName: 'Neutron', + shortName: 'Neutron', + sort: 14, + color: '#141414', + enabled: true, + type: TransactionType.COSMOS, + chainId: 'neutron-1', + info: { + infoType: 'CosmosMetaInfo', + blockExplorerUrls: ['https://www.mintscan.io/cosmos/'], + addressUrl: 'https://www.mintscan.io/cosmos/account/{wallet}', + transactionUrl: 'https://www.mintscan.io/cosmos/txs/{txHash}', + experimental: false, + rpc: 'https://rpc-kralum.neutron-1.neutron.org', + rest: 'https://rest-kralum.neutron-1.neutron.org', + cosmostationLcdUrl: 'https://lcd-neutron.whispernode.com', + cosmostationApiUrl: 'https://neutron-rpc.polkachu.com', + cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', + mintScanName: 'neutron', + chainName: 'Neutron', + stakeCurrency: { + coinDenom: 'NTRN', + coinMinimalDenom: 'untrn', + coinDecimals: 6, + coinGeckoId: 'neutron', + coinImageUrl: '/tokens/blockchain/neutron.jpg', + }, + bip44: { + coinType: 118, + }, + bech32Config: { + bech32PrefixAccAddr: 'neutron', + bech32PrefixAccPub: 'neutronpub', + bech32PrefixValAddr: 'neutronvaloper', + bech32PrefixValPub: 'neutronvaloperpub', + bech32PrefixConsAddr: 'neutronvalcons', + bech32PrefixConsPub: 'neutronvalconspub', + }, + currencies: [ + { + coinDenom: 'NTRN', + coinMinimalDenom: 'untrn', + coinDecimals: 6, + coinGeckoId: 'neutron', + coinImageUrl: '/tokens/blockchain/neutron.jpg', + }, + ], + feeCurrencies: [ + { + coinDenom: 'NTRN', + coinMinimalDenom: 'untrn', + coinDecimals: 6, + coinGeckoId: 'neutron', + coinImageUrl: '/tokens/blockchain/neutron.jpg', + }, + ], + features: ['stargate', 'ibc-transfer'], + explorerUrlToTx: 'https://www.mintscan.io/neutron/txs/{txHash}', + gasPriceStep: { + low: 0.01, + average: 0.025, + high: 0.05, + }, + }, + }, + { + name: 'NOBLE', + defaultDecimals: 6, + addressPatterns: ['^(noble1)[0-9a-z]{38}$'], + feeAssets: [ + { + blockchain: 'NOBLE', + symbol: 'STAKE', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/noble.svg', + displayName: 'Noble', + shortName: 'Noble', + sort: 15, + color: '#141414', + enabled: true, + type: TransactionType.COSMOS, + chainId: 'noble-1', + info: { + infoType: 'CosmosMetaInfo', + blockExplorerUrls: ['https://www.mintscan.io/cosmos/'], + addressUrl: 'https://www.mintscan.io/cosmos/account/{wallet}', + transactionUrl: 'https://www.mintscan.io/cosmos/txs/{txHash}', + experimental: false, + rpc: 'https://noble-rpc.polkachu.com', + rest: 'https://noble-api.polkachu.com', + cosmostationLcdUrl: 'https://noble-api.polkachu.com', + cosmostationApiUrl: 'https://noble-rpc.polkachu.com', + cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', + mintScanName: 'noble', + chainName: 'Noble', + stakeCurrency: { + coinDenom: 'STAKE', + coinMinimalDenom: 'ustake', + coinDecimals: 6, + coinGeckoId: 'noble', + coinImageUrl: '/tokens/blockchain/noble.svg', + }, + bip44: { + coinType: 118, + }, + bech32Config: { + bech32PrefixAccAddr: 'noble', + bech32PrefixAccPub: 'noblepub', + bech32PrefixValAddr: 'noblevaloper', + bech32PrefixValPub: 'noblevaloperpub', + bech32PrefixConsAddr: 'noblevalcons', + bech32PrefixConsPub: 'noblevalconspub', + }, + currencies: [ + { + coinDenom: 'STAKE', + coinMinimalDenom: 'ustake', + coinDecimals: 6, + coinGeckoId: 'noble', + coinImageUrl: '/tokens/blockchain/noble.svg', + }, + ], + feeCurrencies: [ + { + coinDenom: 'STAKE', + coinMinimalDenom: 'ustake', + coinDecimals: 6, + coinGeckoId: 'noble', + coinImageUrl: '/tokens/blockchain/noble.svg', + }, + ], + features: ['stargate', 'ibc-transfer'], + explorerUrlToTx: 'https://www.mintscan.io/noble/txs/{txHash}', + gasPriceStep: { + low: 0.01, + average: 0.025, + high: 0.03, + }, + }, + }, + { + name: 'SOLANA', + defaultDecimals: 9, + addressPatterns: ['^[1-9A-HJ-NP-Za-km-z]{32,44}$'], + feeAssets: [ + { + blockchain: 'SOLANA', + symbol: 'SOL', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/solana.svg', + displayName: 'Solana', + shortName: 'Solana', + sort: 16, + color: '#708DD2', + enabled: true, + type: TransactionType.SOLANA, + chainId: 'mainnet-beta', + info: { + infoType: 'SolanaMetaInfo', + blockExplorerUrls: ['https://www.blockchain.com/btc/'], + addressUrl: 'https://www.blockchain.com/btc/address/{wallet}', + transactionUrl: 'https://www.blockchain.com/btc/tx/{txHash}', + }, + }, + { + name: 'CRONOS', + defaultDecimals: 18, + addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], + feeAssets: [ + { + blockchain: 'CRONOS', + symbol: 'CRO', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/cronos.svg', + displayName: 'Cronos', + shortName: 'Cronos', + sort: 17, + color: '#1a90ff', + enabled: true, + type: TransactionType.EVM, + chainId: '0x19', + info: { + infoType: 'EvmMetaInfo', + chainName: 'Cronos Mainnet Beta', + nativeCurrency: { + name: 'CRO', + symbol: 'CRO', + decimals: 18, + }, + rpcUrls: ['https://evm.cronos.org'], + blockExplorerUrls: ['https://cronoscan.com'], + addressUrl: 'https://cronoscan.com/address/{wallet}', + transactionUrl: 'https://cronoscan.com/tx/{txHash}', + enableGasV2: true, + }, + }, + { + name: 'BNB', + defaultDecimals: 8, + addressPatterns: ['^(bnb1)[0-9a-z]{38}$'], + feeAssets: [ + { + blockchain: 'BNB', + symbol: 'BNB', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/bnb.svg', + displayName: 'Binance Chain', + shortName: 'BNB', + sort: 18, + color: '#F3BA2F', + enabled: true, + type: TransactionType.COSMOS, + chainId: null, + info: null, + }, + { + name: 'AURORA', + defaultDecimals: 18, + addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], + feeAssets: [ + { + blockchain: 'AURORA', + symbol: 'ETH', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/aurora.svg', + displayName: 'Aurora', + shortName: 'Aurora', + sort: 20, + color: '#78d64b', + enabled: true, + type: TransactionType.EVM, + chainId: '0x4e454152', + info: { + infoType: 'EvmMetaInfo', + chainName: 'Aurora Mainnet', + nativeCurrency: { + name: 'ETH', + symbol: 'ETH', + decimals: 18, + }, + rpcUrls: ['https://mainnet.aurora.dev'], + blockExplorerUrls: ['https://explorer.mainnet.aurora.dev'], + addressUrl: 'https://explorer.mainnet.aurora.dev/address/{wallet}', + transactionUrl: 'https://explorer.mainnet.aurora.dev/tx/{txHash}', + enableGasV2: true, + }, + }, + { + name: 'MAYA', + defaultDecimals: 8, + addressPatterns: ['^(maya1)[0-9a-z]{38}$'], + feeAssets: [ + { + blockchain: 'MAYA', + symbol: 'CACAO', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/maya.svg', + displayName: 'MayaChain', + shortName: 'MayaChain', + sort: 21, + color: '#1ae6e6', + enabled: true, + type: TransactionType.COSMOS, + chainId: 'mayachain-mainnet-v1', + info: null, + }, + { + name: 'THOR', + defaultDecimals: 8, + addressPatterns: ['^(thor1)[0-9a-z]{38}$'], + feeAssets: [ + { + blockchain: 'THOR', + symbol: 'RUNE', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/thorchain.svg', + displayName: 'Thorchain', + shortName: 'Thorchain', + sort: 22, + color: '#1AE6CB', + enabled: true, + type: TransactionType.COSMOS, + chainId: 'thorchain-mainnet-v1', + info: null, + }, + { + name: 'BOBA', + defaultDecimals: 18, + addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], + feeAssets: [ + { + blockchain: 'BOBA', + symbol: 'ETH', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/boba.png', + displayName: 'Boba', + shortName: 'Boba', + sort: 23, + color: '#ccff00', + enabled: true, + type: TransactionType.EVM, + chainId: '0x120', + info: { + infoType: 'EvmMetaInfo', + chainName: 'Boba Network', + nativeCurrency: { + name: 'ETH', + symbol: 'ETH', + decimals: 18, + }, + rpcUrls: ['https://mainnet.boba.network'], + blockExplorerUrls: ['https://bobascan.com/'], + addressUrl: 'https://bobascan.com//address/{wallet}', + transactionUrl: 'https://bobascan.com//tx/{txHash}', + enableGasV2: true, + }, + }, + { + name: 'MOONBEAM', + defaultDecimals: 18, + addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], + feeAssets: [ + { + blockchain: 'MOONBEAM', + symbol: 'GLMR', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/moonbeam.png', + displayName: 'MoonBeam', + shortName: 'MoonBeam', + sort: 24, + color: '#B3206B', + enabled: true, + type: TransactionType.EVM, + chainId: '0x504', + info: { + infoType: 'EvmMetaInfo', + chainName: 'MoonBeam', + nativeCurrency: { + name: 'GLMR', + symbol: 'GLMR', + decimals: 18, + }, + rpcUrls: ['https://rpc.api.moonbeam.network'], + blockExplorerUrls: ['https://moonbeam.moonscan.io'], + addressUrl: 'https://moonbeam.moonscan.io/address/{wallet}', + transactionUrl: 'https://moonbeam.moonscan.io/tx/{txHash}', + enableGasV2: true, + }, + }, + { + name: 'MOONRIVER', + defaultDecimals: 18, + addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], + feeAssets: [ + { + blockchain: 'MOONRIVER', + symbol: 'MOVR', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/moonriver.svg', + displayName: 'MoonRiver', + shortName: 'MoonRiver', + sort: 25, + color: '#F3B404', + enabled: true, + type: TransactionType.EVM, + chainId: '0x505', + info: { + infoType: 'EvmMetaInfo', + chainName: 'MoonRiver', + nativeCurrency: { + name: 'MOVR', + symbol: 'MOVR', + decimals: 18, + }, + rpcUrls: ['https://rpc.moonriver.moonbeam.network'], + blockExplorerUrls: ['https://moonriver.moonscan.io'], + addressUrl: 'https://moonriver.moonscan.io/address/{wallet}', + transactionUrl: 'https://moonriver.moonscan.io/tx/{txHash}', + enableGasV2: true, + }, + }, + { + name: 'OKC', + defaultDecimals: 18, + addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], + feeAssets: [ + { + blockchain: 'OKC', + symbol: 'OKT', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/okx.png', + displayName: 'OKX Chain (OKC)', + shortName: 'Okx', + sort: 26, + color: '#29a0f0', + enabled: true, + type: TransactionType.EVM, + chainId: '0x42', + info: { + infoType: 'EvmMetaInfo', + chainName: 'OKX Chain', + nativeCurrency: { + name: 'OKT', + symbol: 'OKT', + decimals: 18, + }, + rpcUrls: ['https://exchainrpc.okex.org'], + blockExplorerUrls: ['https://www.oklink.com/en/okc'], + addressUrl: 'https://www.oklink.com/en/okc/address/{wallet}', + transactionUrl: 'https://www.oklink.com/en/okc/tx/{txHash}', + enableGasV2: true, + }, + }, + { + name: 'BOBA_AVALANCHE', + defaultDecimals: 18, + addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], + feeAssets: [ + { + blockchain: 'BOBA_AVALANCHE', + symbol: 'BOBA', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/boba.png', + displayName: 'Boba Avalanche', + shortName: 'Boba Avalanche', + sort: 28, + color: '#ccff00', + enabled: true, + type: TransactionType.EVM, + chainId: '0xa918', + info: { + infoType: 'EvmMetaInfo', + chainName: 'Boba Avalanche Network', + nativeCurrency: { + name: 'BOBA', + symbol: 'BOBA', + decimals: 18, + }, + rpcUrls: ['https://avax.boba.network'], + blockExplorerUrls: ['https://blockexplorer.avax.boba.network'], + addressUrl: 'https://blockexplorer.avax.boba.network/address/{wallet}', + transactionUrl: 'https://blockexplorer.avax.boba.network/tx/{txHash}', + enableGasV2: true, + }, + }, + { + name: 'LTC', + defaultDecimals: 8, + addressPatterns: ['^(L|M|3)[A-Za-z0-9]{33}$|^(ltc1)[0-9A-Za-z]{39}$'], + feeAssets: [ + { + blockchain: 'LTC', + symbol: 'LTC', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/ltc.svg', + displayName: 'LiteCoin', + shortName: 'LTC', + sort: 29, + color: '#345D9D', + enabled: true, + type: TransactionType.TRANSFER, + chainId: null, + info: { + infoType: 'TransferMetaInfo', + blockExplorerUrls: ['https://www.blockchain.com/btc/'], + addressUrl: 'https://www.blockchain.com/btc/address/{wallet}', + transactionUrl: 'https://www.blockchain.com/btc/tx/{txHash}', + }, + }, + { + name: 'BCH', + defaultDecimals: 8, + addressPatterns: ['^[13][a-km-zA-HJ-NP-Z1-9]{25,34}$|^[0-9A-Za-z]{42,42}$'], + feeAssets: [ + { + blockchain: 'BCH', + symbol: 'BCH', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/bch.svg', + displayName: 'Bitcoin Cash', + shortName: 'BCH', + sort: 30, + color: '#0AC18E', + enabled: true, + type: TransactionType.TRANSFER, + chainId: null, + info: { + infoType: 'TransferMetaInfo', + blockExplorerUrls: ['https://www.blockchain.com/btc/'], + addressUrl: 'https://www.blockchain.com/btc/address/{wallet}', + transactionUrl: 'https://www.blockchain.com/btc/tx/{txHash}', + }, + }, + { + name: 'HECO', + defaultDecimals: 18, + addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], + feeAssets: [ + { + blockchain: 'HECO', + symbol: 'HT', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/heco.png', + displayName: 'Heco', + shortName: 'Heco', + sort: 33, + color: '#4CA852', + enabled: true, + type: TransactionType.EVM, + chainId: '0x80', + info: { + infoType: 'EvmMetaInfo', + chainName: 'Huobi ECO Chain Mainnet', + nativeCurrency: { + name: 'HT', + symbol: 'HT', + decimals: 18, + }, + rpcUrls: ['https://http-mainnet.hecochain.com'], + blockExplorerUrls: ['https://hecoinfo.com'], + addressUrl: 'https://hecoinfo.com/address/{wallet}', + transactionUrl: 'https://hecoinfo.com/tx/{txHash}', + enableGasV2: true, + }, + }, + { + name: 'STARGAZE', + defaultDecimals: 6, + addressPatterns: ['^(stars1)[0-9a-z]{38}$'], + feeAssets: [ + { + blockchain: 'STARGAZE', + symbol: 'STARS', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/stargaze.png', + displayName: 'Stargaze', + shortName: 'Stargaze', + sort: 36, + color: '#231B60', + enabled: true, + type: TransactionType.COSMOS, + chainId: 'stargaze-1', + info: { + infoType: 'CosmosMetaInfo', + blockExplorerUrls: ['https://www.mintscan.io/cosmos/'], + addressUrl: 'https://www.mintscan.io/cosmos/account/{wallet}', + transactionUrl: 'https://www.mintscan.io/cosmos/txs/{txHash}', + experimental: false, + rpc: 'https://rpc.stargaze-apis.com', + rest: 'https://rest.stargaze-apis.com', + cosmostationLcdUrl: 'https://rpc.stargaze-apis.com', + cosmostationApiUrl: 'https://rest.stargaze-apis.com', + cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', + mintScanName: 'stargaze', + chainName: 'Stargaze', + stakeCurrency: { + coinDenom: 'STARS', + coinMinimalDenom: 'ustars', + coinDecimals: 6, + coinGeckoId: 'pool:ustars', + coinImageUrl: '/tokens/blockchain/STARS.png', + }, + bip44: { + coinType: 118, + }, + bech32Config: { + bech32PrefixAccAddr: 'stars', + bech32PrefixAccPub: 'starspub', + bech32PrefixValAddr: 'starsvaloper', + bech32PrefixValPub: 'starsvaloperpub', + bech32PrefixConsAddr: 'starsvalcons', + bech32PrefixConsPub: 'starsvalconspub', + }, + currencies: [ + { + coinDenom: 'STARS', + coinMinimalDenom: 'ustars', + coinDecimals: 6, + coinGeckoId: 'pool:ustars', + coinImageUrl: '/tokens/blockchain/STARS.png', + }, + ], + feeCurrencies: [ + { + coinDenom: 'STARS', + coinMinimalDenom: 'ustars', + coinDecimals: 6, + coinGeckoId: 'pool:ustars', + coinImageUrl: '/tokens/blockchain/STARS.png', + }, + ], + features: ['stargate', 'ibc-transfer', 'no-legacy-stdTx'], + explorerUrlToTx: 'https://www.mintscan.io/stargaze/txs/{txHash}', + gasPriceStep: { + low: 1, + average: 1, + high: 1, + }, + }, + }, + { + name: 'CRYPTO_ORG', + defaultDecimals: 8, + addressPatterns: ['^(cro1)[0-9a-z]{38}$'], + feeAssets: [ + { + blockchain: 'CRYPTO_ORG', + symbol: 'CRO', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/crypto_org.png', + displayName: 'Crypto.org', + shortName: 'Crypto.org', + sort: 38, + color: '#103F68', + enabled: true, + type: TransactionType.COSMOS, + chainId: 'crypto-org-chain-mainnet-1', + info: { + infoType: 'CosmosMetaInfo', + blockExplorerUrls: ['https://www.mintscan.io/cosmos/'], + addressUrl: 'https://www.mintscan.io/cosmos/account/{wallet}', + transactionUrl: 'https://www.mintscan.io/cosmos/txs/{txHash}', + experimental: false, + rpc: 'https://rpc.mainnet.crypto.org', + rest: 'https://rest.mainnet.crypto.org', + cosmostationLcdUrl: 'https://rest.mainnet.crypto.org', + cosmostationApiUrl: 'https://rpc.mainnet.crypto.org', + cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', + mintScanName: 'crypto-org', + chainName: 'Crypto.org', + stakeCurrency: { + coinDenom: 'CRO', + coinMinimalDenom: 'basecro', + coinDecimals: 8, + coinGeckoId: 'crypto-com-chain', + coinImageUrl: '/tokens/blockchain/cro.png', + }, + bip44: { + coinType: 394, + }, + bech32Config: { + bech32PrefixAccAddr: 'cro', + bech32PrefixAccPub: 'cropub', + bech32PrefixValAddr: 'crovaloper', + bech32PrefixValPub: 'crovaloperpub', + bech32PrefixConsAddr: 'crovalcons', + bech32PrefixConsPub: 'crovalconspub', + }, + currencies: [ + { + coinDenom: 'CRO', + coinMinimalDenom: 'basecro', + coinDecimals: 8, + coinGeckoId: 'crypto-com-chain', + coinImageUrl: '/tokens/blockchain/cro.png', + }, + ], + feeCurrencies: [ + { + coinDenom: 'CRO', + coinMinimalDenom: 'basecro', + coinDecimals: 8, + coinGeckoId: 'crypto-com-chain', + coinImageUrl: '/tokens/blockchain/cro.png', + }, + ], + features: ['stargate', 'ibc-transfer'], + explorerUrlToTx: 'https://www.mintscan.io/crypto-org/txs/{txHash}', + gasPriceStep: { + low: 0.025, + average: 0.03, + high: 0.04, + }, + }, + }, + { + name: 'CHIHUAHUA', + defaultDecimals: 6, + addressPatterns: ['^(chihuahua1)[0-9a-z]{38}$'], + feeAssets: [ + { + blockchain: 'CHIHUAHUA', + symbol: 'HUAHUA', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/chihuahua.png', + displayName: 'Chihuahua', + shortName: 'Chihuahua', + sort: 39, + color: '#EFC92B', + enabled: true, + type: TransactionType.COSMOS, + chainId: 'chihuahua-1', + info: { + infoType: 'CosmosMetaInfo', + blockExplorerUrls: ['https://www.mintscan.io/cosmos/'], + addressUrl: 'https://www.mintscan.io/cosmos/account/{wallet}', + transactionUrl: 'https://www.mintscan.io/cosmos/txs/{txHash}', + experimental: true, + rpc: 'https://rpc.chihuahua.wtf', + rest: 'https://api.chihuahua.wtf', + cosmostationLcdUrl: 'https://api.chihuahua.wtf', + cosmostationApiUrl: 'https://rpc.chihuahua.wtf', + cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', + mintScanName: 'chihuahua', + chainName: 'Chihuahua', + stakeCurrency: { + coinDenom: 'HUAHUA', + coinMinimalDenom: 'uhuahua', + coinDecimals: 6, + coinGeckoId: 'pool:uhuahua', + coinImageUrl: '/tokens/blockchain/HUAHUA.svg', + }, + bip44: { + coinType: 118, + }, + bech32Config: { + bech32PrefixAccAddr: 'chihuahua', + bech32PrefixAccPub: 'chihuahuapub', + bech32PrefixValAddr: 'chihuahuavaloper', + bech32PrefixValPub: 'chihuahuavaloperpub', + bech32PrefixConsAddr: 'chihuahuavalcons', + bech32PrefixConsPub: 'chihuahuavalconspub', + }, + currencies: [ + { + coinDenom: 'HUAHUA', + coinMinimalDenom: 'uhuahua', + coinDecimals: 6, + coinGeckoId: 'pool:uhuahua', + coinImageUrl: '/tokens/blockchain/HUAHUA.svg', + }, + ], + feeCurrencies: [ + { + coinDenom: 'HUAHUA', + coinMinimalDenom: 'uhuahua', + coinDecimals: 6, + coinGeckoId: 'pool:uhuahua', + coinImageUrl: '/tokens/blockchain/HUAHUA.svg', + }, + ], + features: ['stargate', 'ibc-transfer', 'no-legacy-stdTx'], + explorerUrlToTx: 'https://ping.pub/chihuahua/tx/{txHash}', + gasPriceStep: { + low: 0.025, + average: 0.03, + high: 0.035, + }, + }, + }, + { + name: 'BANDCHAIN', + defaultDecimals: 6, + addressPatterns: ['^(band1)[0-9a-z]{38}$'], + feeAssets: [ + { + blockchain: 'BANDCHAIN', + symbol: 'BAND', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/bandchain.svg', + displayName: 'BandChain', + shortName: 'BandChain', + sort: 40, + color: '#4520E6', + enabled: true, + type: TransactionType.COSMOS, + chainId: 'laozi-mainnet', + info: { + infoType: 'CosmosMetaInfo', + blockExplorerUrls: ['https://www.mintscan.io/cosmos/'], + addressUrl: 'https://www.mintscan.io/cosmos/account/{wallet}', + transactionUrl: 'https://www.mintscan.io/cosmos/txs/{txHash}', + experimental: true, + rpc: 'https://rpc.laozi3.bandchain.org/', + rest: 'https://laozi1.bandchain.org/api', + cosmostationLcdUrl: 'https://laozi1.bandchain.org/api', + cosmostationApiUrl: 'https://rpc.laozi3.bandchain.org', + cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', + mintScanName: 'band', + chainName: 'BandChain', + stakeCurrency: { + coinDenom: 'BAND', + coinMinimalDenom: 'uband', + coinDecimals: 6, + coinGeckoId: 'band-protocol', + coinImageUrl: '/tokens/blockchain/BAND.svg', + }, + bip44: { + coinType: 494, + }, + bech32Config: { + bech32PrefixAccAddr: 'band', + bech32PrefixAccPub: 'bandpub', + bech32PrefixValAddr: 'bandvaloper', + bech32PrefixValPub: 'bandvaloperpub', + bech32PrefixConsAddr: 'bandvalcons', + bech32PrefixConsPub: 'bandvalconspub', + }, + currencies: [ + { + coinDenom: 'BAND', + coinMinimalDenom: 'uband', + coinDecimals: 6, + coinGeckoId: 'band-protocol', + coinImageUrl: '/tokens/blockchain/BAND.svg', + }, + ], + feeCurrencies: [ + { + coinDenom: 'BAND', + coinMinimalDenom: 'uband', + coinDecimals: 6, + coinGeckoId: 'band-protocol', + coinImageUrl: '/tokens/blockchain/BAND.svg', + }, + ], + features: ['stargate', 'ibc-transfer', 'no-legacy-stdTx'], + explorerUrlToTx: 'https://cosmoscan.io/tx/{txHash}', + gasPriceStep: null, + }, + }, + { + name: 'COMDEX', + defaultDecimals: 6, + addressPatterns: ['^(comdex1)[0-9a-z]{38}$'], + feeAssets: [ + { + blockchain: 'COMDEX', + symbol: 'CMDX', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/comdex.svg', + displayName: 'Comdex', + shortName: 'Comdex', + sort: 41, + color: '#FE4350', + enabled: true, + type: TransactionType.COSMOS, + chainId: 'comdex-1', + info: { + infoType: 'CosmosMetaInfo', + blockExplorerUrls: ['https://www.mintscan.io/cosmos/'], + addressUrl: 'https://www.mintscan.io/cosmos/account/{wallet}', + transactionUrl: 'https://www.mintscan.io/cosmos/txs/{txHash}', + experimental: true, + rpc: 'https://rpc.comdex.one', + rest: 'https://rest.comdex.one', + cosmostationLcdUrl: 'https://rest.comdex.one', + cosmostationApiUrl: 'https://rpc.comdex.one', + cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', + mintScanName: 'comdex', + chainName: 'Comdex', + stakeCurrency: { + coinDenom: 'CMDX', + coinMinimalDenom: 'ucmdx', + coinDecimals: 6, + coinGeckoId: 'comdex', + coinImageUrl: '/tokens/blockchain/CMDX.png', + }, + bip44: { + coinType: 118, + }, + bech32Config: { + bech32PrefixAccAddr: 'comdex', + bech32PrefixAccPub: 'comdexpub', + bech32PrefixValAddr: 'comdexvaloper', + bech32PrefixValPub: 'comdexvaloperpub', + bech32PrefixConsAddr: 'comdexvalcons', + bech32PrefixConsPub: 'comdexvalconspub', + }, + currencies: [ + { + coinDenom: 'CMDX', + coinMinimalDenom: 'ucmdx', + coinDecimals: 6, + coinGeckoId: 'comdex', + coinImageUrl: '/tokens/blockchain/CMDX.png', + }, + ], + feeCurrencies: [ + { + coinDenom: 'CMDX', + coinMinimalDenom: 'ucmdx', + coinDecimals: 6, + coinGeckoId: 'comdex', + coinImageUrl: '/tokens/blockchain/CMDX.png', + }, + ], + features: ['stargate', 'ibc-transfer', 'no-legacy-stdTx'], + explorerUrlToTx: 'https://www.mintscan.io/comdex/txs/{txHash}', + gasPriceStep: null, + }, + }, + { + name: 'REGEN', + defaultDecimals: 6, + addressPatterns: ['^(regen1)[0-9a-z]{38}$'], + feeAssets: [ + { + blockchain: 'REGEN', + symbol: 'REGEN', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/regen.png', + displayName: 'Regen Network', + shortName: 'Regen Network', + sort: 42, + color: '#4FB573', + enabled: true, + type: TransactionType.COSMOS, + chainId: 'regen-1', + info: { + infoType: 'CosmosMetaInfo', + blockExplorerUrls: ['https://www.mintscan.io/cosmos/'], + addressUrl: 'https://www.mintscan.io/cosmos/account/{wallet}', + transactionUrl: 'https://www.mintscan.io/cosmos/txs/{txHash}', + experimental: false, + rpc: 'https://rpc-regen.ecostake.com', + rest: 'https://regen.stakesystems.io', + cosmostationLcdUrl: 'https://regen.stakesystems.io', + cosmostationApiUrl: 'https://rpc-regen.ecostake.com', + cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', + mintScanName: 'regen', + chainName: 'Regen Network', + stakeCurrency: { + coinDenom: 'REGEN', + coinMinimalDenom: 'uregen', + coinDecimals: 6, + coinGeckoId: 'pool:uregen', + coinImageUrl: '/tokens/blockchain/regen.png', + }, + bip44: { + coinType: 118, + }, + bech32Config: { + bech32PrefixAccAddr: 'regen', + bech32PrefixAccPub: 'regenpub', + bech32PrefixValAddr: 'regenvaloper', + bech32PrefixValPub: 'regenvaloperpub', + bech32PrefixConsAddr: 'regenvalcons', + bech32PrefixConsPub: 'regenvalconspub', + }, + currencies: [ + { + coinDenom: 'REGEN', + coinMinimalDenom: 'uregen', + coinDecimals: 6, + coinGeckoId: 'pool:uregen', + coinImageUrl: '/tokens/blockchain/regen.png', + }, + ], + feeCurrencies: [ + { + coinDenom: 'REGEN', + coinMinimalDenom: 'uregen', + coinDecimals: 6, + coinGeckoId: 'pool:uregen', + coinImageUrl: '/tokens/blockchain/regen.png', + }, + ], + features: ['stargate', 'ibc-transfer'], + explorerUrlToTx: 'https://regen.aneka.io/txs/{txHash}', + gasPriceStep: { + low: 0.015, + average: 0.025, + high: 0.04, + }, + }, + }, + { + name: 'IRIS', + defaultDecimals: 6, + addressPatterns: ['^(iaa1)[0-9a-z]{38}$'], + feeAssets: [ + { + blockchain: 'IRIS', + symbol: 'IRIS', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/iris.png', + displayName: 'IRISnet', + shortName: 'IRISnet', + sort: 43, + color: '#8A4A8E', + enabled: true, + type: TransactionType.COSMOS, + chainId: 'irishub-1', + info: { + infoType: 'CosmosMetaInfo', + blockExplorerUrls: ['https://www.mintscan.io/cosmos/'], + addressUrl: 'https://www.mintscan.io/cosmos/account/{wallet}', + transactionUrl: 'https://www.mintscan.io/cosmos/txs/{txHash}', + experimental: false, + rpc: 'https://rpc.nyancat.irisnet.org', + rest: 'https://lcd.nyancat.irisnet.org', + cosmostationLcdUrl: 'https://lcd.nyancat.irisnet.org', + cosmostationApiUrl: 'https://rpc.nyancat.irisnet.org', + cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', + mintScanName: 'iris', + chainName: 'IRISnet', + stakeCurrency: { + coinDenom: 'IRIS', + coinMinimalDenom: 'uiris', + coinDecimals: 6, + coinGeckoId: 'iris-network', + coinImageUrl: '/tokens/blockchain/iris.svg', + }, + bip44: { + coinType: 118, + }, + bech32Config: { + bech32PrefixAccAddr: 'iaa', + bech32PrefixAccPub: 'iaapub', + bech32PrefixValAddr: 'iaavaloper', + bech32PrefixValPub: 'iaavaloperpub', + bech32PrefixConsAddr: 'iaavalcons', + bech32PrefixConsPub: 'iaavalconspub', + }, + currencies: [ + { + coinDenom: 'IRIS', + coinMinimalDenom: 'uiris', + coinDecimals: 6, + coinGeckoId: 'iris-network', + coinImageUrl: '/tokens/blockchain/iris.svg', + }, + ], + feeCurrencies: [ + { + coinDenom: 'IRIS', + coinMinimalDenom: 'uiris', + coinDecimals: 6, + coinGeckoId: 'iris-network', + coinImageUrl: '/tokens/blockchain/iris.svg', + }, + ], + features: ['stargate', 'ibc-transfer'], + explorerUrlToTx: 'https://www.mintscan.io/iris/txs/{txHash}', + gasPriceStep: { + low: 0.2, + average: 0.3, + high: 0.4, + }, + }, + }, + { + name: 'EMONEY', + defaultDecimals: 6, + addressPatterns: ['^(emoney1)[0-9a-z]{38}$'], + feeAssets: [ + { + blockchain: 'EMONEY', + symbol: 'NGM', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/emoney.svg', + displayName: 'e-Money', + shortName: 'e-Money', + sort: 44, + color: '#DFF5EF', + enabled: true, + type: TransactionType.COSMOS, + chainId: 'emoney-3', + info: { + infoType: 'CosmosMetaInfo', + blockExplorerUrls: ['https://www.mintscan.io/cosmos/'], + addressUrl: 'https://www.mintscan.io/cosmos/account/{wallet}', + transactionUrl: 'https://www.mintscan.io/cosmos/txs/{txHash}', + experimental: true, + rpc: 'https://emoney.validator.network/', + rest: 'https://emoney.validator.network/api', + cosmostationLcdUrl: 'https://emoney.validator.network/api', + cosmostationApiUrl: 'https://emoney.validator.network', + cosmostationDenomTracePath: + '/ibc/applications/transfer/v1beta1/denom_traces/', + mintScanName: 'emoney', + chainName: 'e-Money', + stakeCurrency: { + coinDenom: 'NGM', + coinMinimalDenom: 'ungm', + coinDecimals: 6, + coinGeckoId: 'e-money', + coinImageUrl: '/tokens/blockchain/NGM.png', + }, + bip44: { + coinType: 118, + }, + bech32Config: { + bech32PrefixAccAddr: 'emoney', + bech32PrefixAccPub: 'emoneypub', + bech32PrefixValAddr: 'emoneyvaloper', + bech32PrefixValPub: 'emoneyvaloperpub', + bech32PrefixConsAddr: 'emoneyvalcons', + bech32PrefixConsPub: 'emoneyvalconspub', + }, + currencies: [ + { + coinDenom: 'NGM', + coinMinimalDenom: 'ungm', + coinDecimals: 6, + coinGeckoId: 'e-money', + coinImageUrl: '/tokens/blockchain/NGM.png', + }, + { + coinDenom: 'EEUR', + coinMinimalDenom: 'eeur', + coinDecimals: 6, + coinGeckoId: 'e-money-eur', + coinImageUrl: '/tokens/blockchain/EEUR.png', + }, + ], + feeCurrencies: [ + { + coinDenom: 'NGM', + coinMinimalDenom: 'ungm', + coinDecimals: 6, + coinGeckoId: 'e-money', + coinImageUrl: '/tokens/blockchain/NGM.png', + }, + ], + features: ['stargate', 'ibc-transfer'], + explorerUrlToTx: 'https://emoney.bigdipper.live/transactions/{txHash}', + gasPriceStep: { + low: 1, + average: 1, + high: 1, + }, + }, + }, + { + name: 'JUNO', + defaultDecimals: 6, + addressPatterns: ['^(juno1)[0-9a-z]{38}$'], + feeAssets: [ + { + blockchain: 'JUNO', + symbol: 'JUNO', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/juno.svg', + displayName: 'Juno', + shortName: 'Juno', + sort: 46, + color: '#f0827d', + enabled: true, + type: TransactionType.COSMOS, + chainId: 'juno-1', + info: { + infoType: 'CosmosMetaInfo', + blockExplorerUrls: ['https://www.mintscan.io/cosmos/'], + addressUrl: 'https://www.mintscan.io/cosmos/account/{wallet}', + transactionUrl: 'https://www.mintscan.io/cosmos/txs/{txHash}', + experimental: false, + rpc: 'https://rpc-juno.itastakers.com:443/', + rest: 'https://lcd-juno.itastakers.com', + cosmostationLcdUrl: 'https://lcd-juno.itastakers.com', + cosmostationApiUrl: 'https://rpc-juno.itastakers.com', + cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', + mintScanName: 'juno', + chainName: 'Juno', + stakeCurrency: { + coinDenom: 'JUNO', + coinMinimalDenom: 'ujuno', + coinDecimals: 6, + coinGeckoId: 'juno-network', + coinImageUrl: '/tokens/blockchain/JUNO.png', + }, + bip44: { + coinType: 118, + }, + bech32Config: { + bech32PrefixAccAddr: 'juno', + bech32PrefixAccPub: 'junopub', + bech32PrefixValAddr: 'junovaloper', + bech32PrefixValPub: 'junovaloperpub', + bech32PrefixConsAddr: 'junovalcons', + bech32PrefixConsPub: 'junovalconspub', + }, + currencies: [ + { + coinDenom: 'JUNO', + coinMinimalDenom: 'ujuno', + coinDecimals: 6, + coinGeckoId: 'juno-network', + coinImageUrl: '/tokens/blockchain/JUNO.png', + }, + ], + feeCurrencies: [ + { + coinDenom: 'JUNO', + coinMinimalDenom: 'ujuno', + coinDecimals: 6, + coinGeckoId: 'juno-network', + coinImageUrl: '/tokens/blockchain/JUNO.png', + }, + ], + features: ['stargate', 'ibc-transfer'], + explorerUrlToTx: 'https://www.mintscan.io/juno/txs/{txHash}', + gasPriceStep: { + low: 0.001, + average: 0.0025, + high: 0.004, + }, + }, + }, + { + name: 'STRIDE', + defaultDecimals: 6, + addressPatterns: ['^(stride1)[0-9a-z]{38}$'], + feeAssets: [ + { + blockchain: 'STRIDE', + symbol: 'STRD', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/stride.svg', + displayName: 'Stride', + shortName: 'Stride', + sort: 48, + color: '#D63178', + enabled: true, + type: TransactionType.COSMOS, + chainId: 'stride-1', + info: { + infoType: 'CosmosMetaInfo', + blockExplorerUrls: ['https://www.mintscan.io/cosmos/'], + addressUrl: 'https://www.mintscan.io/cosmos/account/{wallet}', + transactionUrl: 'https://www.mintscan.io/cosmos/txs/{txHash}', + experimental: false, + rpc: 'https://stride-rpc.polkachu.com', + rest: 'https://stride-api.polkachu.com', + cosmostationLcdUrl: 'https://stride-api.polkachu.com', + cosmostationApiUrl: 'https://stride-rpc.polkachu.com', + cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', + mintScanName: 'stride', + chainName: 'Stride', + stakeCurrency: { + coinDenom: 'STRD', + coinMinimalDenom: 'ustrd', + coinDecimals: 6, + coinGeckoId: 'stride', + coinImageUrl: '', + }, + bip44: { + coinType: 118, + }, + bech32Config: { + bech32PrefixAccAddr: 'stride', + bech32PrefixAccPub: 'stridepub', + bech32PrefixValAddr: 'stridevaloper', + bech32PrefixValPub: 'stridevaloperpub', + bech32PrefixConsAddr: 'stridevalcons', + bech32PrefixConsPub: 'stridevalconspub', + }, + currencies: [ + { + coinDenom: 'STRD', + coinMinimalDenom: 'ustrd', + coinDecimals: 6, + coinGeckoId: 'stride', + coinImageUrl: '', + }, + { + coinDenom: 'stATOM', + coinMinimalDenom: 'stuatom', + coinDecimals: 6, + coinGeckoId: 'stride-staked-atom', + coinImageUrl: '', + }, + { + coinDenom: 'stOSMO', + coinMinimalDenom: 'stuosmo', + coinDecimals: 6, + coinGeckoId: 'stride-staked-osmo', + coinImageUrl: '', + }, + { + coinDenom: 'stJUNO', + coinMinimalDenom: 'stujuno', + coinDecimals: 6, + coinGeckoId: 'stride-staked-juno', + coinImageUrl: '', + }, + { + coinDenom: 'stSTARS', + coinMinimalDenom: 'stustars', + coinDecimals: 6, + coinGeckoId: '', + coinImageUrl: '', + }, + { + coinDenom: 'stEVMOS', + coinMinimalDenom: 'staevmos', + coinDecimals: 18, + coinGeckoId: '', + coinImageUrl: '', + }, + { + coinDenom: 'stLUNA', + coinMinimalDenom: 'stuluna', + coinDecimals: 6, + coinGeckoId: '', + coinImageUrl: '', + }, + ], + feeCurrencies: [ + { + coinDenom: 'STRD', + coinMinimalDenom: 'ustrd', + coinDecimals: 6, + coinGeckoId: 'stride', + coinImageUrl: '', + }, + ], + features: ['ibc-transfer'], + explorerUrlToTx: 'https://www.mintscan.io/stride/txs/{txHash}', + gasPriceStep: { + low: 0.001, + average: 0.0025, + high: 0.04, + }, + }, + }, + { + name: 'MARS', + defaultDecimals: 6, + addressPatterns: ['^(mars1)[0-9a-z]{38}$'], + feeAssets: [ + { + blockchain: 'MARS', + symbol: 'MARS', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/mars.svg', + displayName: 'Mars', + shortName: 'Mars', + sort: 50, + color: '#CB4B3D', + enabled: true, + type: TransactionType.COSMOS, + chainId: 'mars-1', + info: { + infoType: 'CosmosMetaInfo', + blockExplorerUrls: ['https://www.mintscan.io/cosmos/'], + addressUrl: 'https://www.mintscan.io/cosmos/account/{wallet}', + transactionUrl: 'https://www.mintscan.io/cosmos/txs/{txHash}', + experimental: false, + rpc: 'https://rpc.marsprotocol.io', + rest: 'https://rest.marsprotocol.io', + cosmostationLcdUrl: 'https://rest.marsprotocol.io', + cosmostationApiUrl: 'https://rpc.marsprotocol.io', + cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', + mintScanName: 'mars-protocol', + chainName: 'Mars', + stakeCurrency: { + coinDenom: 'MARS', + coinMinimalDenom: 'umars', + coinDecimals: 6, + coinGeckoId: 'mars-protocol-a7fcbcfb-fd61-4017-92f0-7ee9f9cc6da3', + coinImageUrl: '/tokens/blockchain/mars.svg', + }, + bip44: { + coinType: 118, + }, + bech32Config: { + bech32PrefixAccAddr: 'mars', + bech32PrefixAccPub: 'marspub', + bech32PrefixValAddr: 'marsvaloper', + bech32PrefixValPub: 'marsvaloperpub', + bech32PrefixConsAddr: 'marsvalcons', + bech32PrefixConsPub: 'marsvalconspub', + }, + currencies: [ + { + coinDenom: 'MARS', + coinMinimalDenom: 'umars', + coinDecimals: 6, + coinGeckoId: 'mars-protocol-a7fcbcfb-fd61-4017-92f0-7ee9f9cc6da3', + coinImageUrl: '/tokens/blockchain/mars.svg', + }, + ], + feeCurrencies: [ + { + coinDenom: 'MARS', + coinMinimalDenom: 'umars', + coinDecimals: 6, + coinGeckoId: 'mars-protocol-a7fcbcfb-fd61-4017-92f0-7ee9f9cc6da3', + coinImageUrl: '/tokens/blockchain/mars.svg', + }, + ], + features: ['ibc-transfer'], + explorerUrlToTx: 'https://www.mintscan.io/mars-protocol/txs/{txHash}', + gasPriceStep: { + low: 0.001, + average: 0.0025, + high: 0.01, + }, + }, + }, + { + name: 'TERRA', + defaultDecimals: 6, + addressPatterns: ['^(terra1)[0-9a-z]{38}$'], + feeAssets: [ + { + blockchain: 'TERRA', + symbol: 'LUNA', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/terra.png', + displayName: 'Terra 2.0', + shortName: 'Terra 2.0', + sort: 51, + color: '#5493F7', + enabled: true, + type: TransactionType.COSMOS, + chainId: 'phoenix-1', + info: { + infoType: 'CosmosMetaInfo', + blockExplorerUrls: ['https://www.mintscan.io/cosmos/'], + addressUrl: 'https://www.mintscan.io/cosmos/account/{wallet}', + transactionUrl: 'https://www.mintscan.io/cosmos/txs/{txHash}', + experimental: false, + rpc: 'https://phoenix-rpc.terra.dev', + rest: 'https://phoenix-lcd.terra.dev', + cosmostationLcdUrl: 'https://phoenix-lcd.terra.dev', + cosmostationApiUrl: null, + cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', + mintScanName: null, + chainName: 'Terra 2.0', + stakeCurrency: { + coinDenom: 'LUNA', + coinMinimalDenom: 'uluna', + coinDecimals: 6, + coinGeckoId: 'terra-luna-2', + coinImageUrl: '', + }, + bip44: { + coinType: 330, + }, + bech32Config: { + bech32PrefixAccAddr: 'terra', + bech32PrefixAccPub: 'terrapub', + bech32PrefixValAddr: 'terravaloper', + bech32PrefixValPub: 'terravaloperpub', + bech32PrefixConsAddr: 'terravalcons', + bech32PrefixConsPub: 'terravalconspub', + }, + currencies: [ + { + coinDenom: 'LUNA', + coinMinimalDenom: 'uluna', + coinDecimals: 6, + coinGeckoId: 'terra-luna-2', + coinImageUrl: '', + }, + ], + feeCurrencies: [ + { + coinDenom: 'LUNA', + coinMinimalDenom: 'uluna', + coinDecimals: 6, + coinGeckoId: 'terra-luna-2', + coinImageUrl: '', + }, + ], + features: ['cosmwasm', 'ibc-transfer'], + explorerUrlToTx: 'https://finder.terra.money/mainnet/txs/{txHash}', + gasPriceStep: { + low: 0.0125, + average: 0.015, + high: 0.15, + }, + }, + }, + { + name: 'BITSONG', + defaultDecimals: 6, + addressPatterns: ['^(bitsong1)[0-9a-z]{38}$'], + feeAssets: [ + { + blockchain: 'BITSONG', + symbol: 'BTSG', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/bitsong.svg', + displayName: 'BitSong', + shortName: 'BitSong', + sort: 53, + color: '#FF005C', + enabled: true, + type: TransactionType.COSMOS, + chainId: 'bitsong-2b', + info: { + infoType: 'CosmosMetaInfo', + blockExplorerUrls: ['https://www.mintscan.io/cosmos/'], + addressUrl: 'https://www.mintscan.io/cosmos/account/{wallet}', + transactionUrl: 'https://www.mintscan.io/cosmos/txs/{txHash}', + experimental: true, + rpc: 'https://rpc.explorebitsong.com', + rest: 'https://lcd.explorebitsong.com', + cosmostationLcdUrl: 'https://lcd.explorebitsong.com', + cosmostationApiUrl: 'https://rpc.explorebitsong.com', + cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', + mintScanName: 'bitsong', + chainName: 'BitSong', + stakeCurrency: { + coinDenom: 'BTSG', + coinMinimalDenom: 'ubtsg', + coinDecimals: 6, + coinGeckoId: 'pool:ubtsg', + coinImageUrl: '/tokens/blockchain/BTSG.png', + }, + bip44: { + coinType: 639, + }, + bech32Config: { + bech32PrefixAccAddr: 'bitsong', + bech32PrefixAccPub: 'bitsongpub', + bech32PrefixValAddr: 'bitsongvaloper', + bech32PrefixValPub: 'bitsongvaloperpub', + bech32PrefixConsAddr: 'bitsongvalcons', + bech32PrefixConsPub: 'bitsongvalconspub', + }, + currencies: [ + { + coinDenom: 'BTSG', + coinMinimalDenom: 'ubtsg', + coinDecimals: 6, + coinGeckoId: 'pool:ubtsg', + coinImageUrl: '/tokens/blockchain/BTSG.png', + }, + ], + feeCurrencies: [ + { + coinDenom: 'BTSG', + coinMinimalDenom: 'ubtsg', + coinDecimals: 6, + coinGeckoId: 'pool:ubtsg', + coinImageUrl: '/tokens/blockchain/BTSG.png', + }, + ], + features: ['stargate', 'ibc-transfer', 'no-legacy-stdTx', 'ibc-go'], + explorerUrlToTx: 'https://explorebitsong.com/transactions/{txHash}', + gasPriceStep: null, + }, + }, + { + name: 'AKASH', + defaultDecimals: 6, + addressPatterns: ['^(akash1)[0-9a-z]{38}$'], + feeAssets: [ + { + blockchain: 'AKASH', + symbol: 'AKT', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/akash.svg', + displayName: 'Akash', + shortName: 'Akash', + sort: 54, + color: '#ED3524', + enabled: true, + type: TransactionType.COSMOS, + chainId: 'akashnet-2', + info: { + infoType: 'CosmosMetaInfo', + blockExplorerUrls: ['https://www.mintscan.io/cosmos/'], + addressUrl: 'https://www.mintscan.io/cosmos/account/{wallet}', + transactionUrl: 'https://www.mintscan.io/cosmos/txs/{txHash}', + experimental: false, + rpc: 'https://rpc.akashnet.net', + rest: 'https://api.akashnet.net', + cosmostationLcdUrl: 'https://api.akashnet.net', + cosmostationApiUrl: 'https://rpc.akashnet.net', + cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', + mintScanName: 'akash', + chainName: 'Akash', + stakeCurrency: { + coinDenom: 'AKT', + coinMinimalDenom: 'uakt', + coinDecimals: 6, + coinGeckoId: 'akash-network', + coinImageUrl: '/tokens/blockchain/akt.svg', + }, + bip44: { + coinType: 118, + }, + bech32Config: { + bech32PrefixAccAddr: 'akash', + bech32PrefixAccPub: 'akashpub', + bech32PrefixValAddr: 'akashvaloper', + bech32PrefixValPub: 'akashvaloperpub', + bech32PrefixConsAddr: 'akashvalcons', + bech32PrefixConsPub: 'akashvalconspub', + }, + currencies: [ + { + coinDenom: 'AKT', + coinMinimalDenom: 'uakt', + coinDecimals: 6, + coinGeckoId: 'akash-network', + coinImageUrl: '/tokens/blockchain/akt.svg', + }, + ], + feeCurrencies: [ + { + coinDenom: 'AKT', + coinMinimalDenom: 'uakt', + coinDecimals: 6, + coinGeckoId: 'akash-network', + coinImageUrl: '/tokens/blockchain/akt.svg', + }, + ], + features: ['stargate', 'ibc-transfer'], + explorerUrlToTx: 'https://www.mintscan.io/akash/txs/{txHash}', + gasPriceStep: { + low: 0.001, + average: 0.0025, + high: 0.004, + }, + }, + }, + { + name: 'KI', + defaultDecimals: 6, + addressPatterns: ['^(ki1)[0-9a-z]{38}$'], + feeAssets: [ + { + blockchain: 'KI', + symbol: 'XKI', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/ki.png', + displayName: 'Ki', + shortName: 'Ki', + sort: 55, + color: '#0F2B3D', + enabled: true, + type: TransactionType.COSMOS, + chainId: 'kichain-2', + info: { + infoType: 'CosmosMetaInfo', + blockExplorerUrls: ['https://www.mintscan.io/cosmos/'], + addressUrl: 'https://www.mintscan.io/cosmos/account/{wallet}', + transactionUrl: 'https://www.mintscan.io/cosmos/txs/{txHash}', + experimental: true, + rpc: 'https://rpc-mainnet.blockchain.ki', + rest: 'https://api-mainnet.blockchain.ki', + cosmostationLcdUrl: 'https://api-mainnet.blockchain.ki', + cosmostationApiUrl: 'https://rpc-mainnet.blockchain.ki', + cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', + mintScanName: 'ki-chain', + chainName: 'Ki', + stakeCurrency: { + coinDenom: 'XKI', + coinMinimalDenom: 'uxki', + coinDecimals: 6, + coinGeckoId: 'pool:uxki', + coinImageUrl: '/tokens/blockchain/XKI.png', + }, + bip44: { + coinType: 118, + }, + bech32Config: { + bech32PrefixAccAddr: 'ki', + bech32PrefixAccPub: 'kipub', + bech32PrefixValAddr: 'kivaloper', + bech32PrefixValPub: 'kivaloperpub', + bech32PrefixConsAddr: 'kivalcons', + bech32PrefixConsPub: 'kivalconspub', + }, + currencies: [ + { + coinDenom: 'XKI', + coinMinimalDenom: 'uxki', + coinDecimals: 6, + coinGeckoId: 'pool:uxki', + coinImageUrl: '/tokens/blockchain/XKI.png', + }, + ], + feeCurrencies: [ + { + coinDenom: 'XKI', + coinMinimalDenom: 'uxki', + coinDecimals: 6, + coinGeckoId: 'pool:uxki', + coinImageUrl: '/tokens/blockchain/XKI.png', + }, + ], + features: ['stargate', 'ibc-transfer'], + explorerUrlToTx: 'https://www.mintscan.io/ki-chain/txs/{txHash}', + gasPriceStep: null, + }, + }, + { + name: 'PERSISTENCE', + defaultDecimals: 6, + addressPatterns: ['^(persistence1)[0-9a-z]{38}$'], + feeAssets: [ + { + blockchain: 'PERSISTENCE', + symbol: 'XPRT', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/persistence.png', + displayName: 'Persistence', + shortName: 'Persistence', + sort: 56, + color: '#383838', + enabled: true, + type: TransactionType.COSMOS, + chainId: 'core-1', + info: { + infoType: 'CosmosMetaInfo', + blockExplorerUrls: ['https://www.mintscan.io/cosmos/'], + addressUrl: 'https://www.mintscan.io/cosmos/account/{wallet}', + transactionUrl: 'https://www.mintscan.io/cosmos/txs/{txHash}', + experimental: false, + rpc: 'https://rpc.core.persistence.one', + rest: 'https://rest.core.persistence.one', + cosmostationLcdUrl: 'https://rest.core.persistence.one', + cosmostationApiUrl: 'https://rpc.core.persistence.one', + cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', + mintScanName: 'persistence', + chainName: 'Persistence', + stakeCurrency: { + coinDenom: 'XPRT', + coinMinimalDenom: 'uxprt', + coinDecimals: 6, + coinGeckoId: 'persistence', + coinImageUrl: '/tokens/blockchain/xprt.png', + }, + bip44: { + coinType: 750, + }, + bech32Config: { + bech32PrefixAccAddr: 'persistence', + bech32PrefixAccPub: 'persistencepub', + bech32PrefixValAddr: 'persistencevaloper', + bech32PrefixValPub: 'persistencevaloperpub', + bech32PrefixConsAddr: 'persistencevalcons', + bech32PrefixConsPub: 'persistencevalconspub', + }, + currencies: [ + { + coinDenom: 'XPRT', + coinMinimalDenom: 'uxprt', + coinDecimals: 6, + coinGeckoId: 'persistence', + coinImageUrl: '/tokens/blockchain/xprt.png', + }, + ], + feeCurrencies: [ + { + coinDenom: 'XPRT', + coinMinimalDenom: 'uxprt', + coinDecimals: 6, + coinGeckoId: 'persistence', + coinImageUrl: '/tokens/blockchain/xprt.png', + }, + ], + features: ['stargate', 'ibc-transfer'], + explorerUrlToTx: 'https://www.mintscan.io/persistence/txs/{txHash}', + gasPriceStep: { + low: 0, + average: 0.025, + high: 0.04, + }, + }, + }, + { + name: 'MEDIBLOC', + defaultDecimals: 6, + addressPatterns: ['^(panacea1)[0-9a-z]{38}$'], + feeAssets: [ + { + blockchain: 'MEDIBLOC', + symbol: 'MED', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/medibloc.png', + displayName: 'MediBloc', + shortName: 'MediBloc', + sort: 57, + color: '#4B66DC', + enabled: true, + type: TransactionType.COSMOS, + chainId: 'panacea-3', + info: { + infoType: 'CosmosMetaInfo', + blockExplorerUrls: ['https://www.mintscan.io/cosmos/'], + addressUrl: 'https://www.mintscan.io/cosmos/account/{wallet}', + transactionUrl: 'https://www.mintscan.io/cosmos/txs/{txHash}', + experimental: true, + rpc: 'https://rpc.gopanacea.org', + rest: 'https://api.gopanacea.org', + cosmostationLcdUrl: 'https://api.gopanacea.org', + cosmostationApiUrl: 'https://rpc.gopanacea.org', + cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', + mintScanName: 'medibloc', + chainName: 'MediBloc', + stakeCurrency: { + coinDenom: 'MED', + coinMinimalDenom: 'umed', + coinDecimals: 6, + coinGeckoId: 'medibloc', + coinImageUrl: '/tokens/blockchain/MED.png', + }, + bip44: { + coinType: 118, + }, + bech32Config: { + bech32PrefixAccAddr: 'panacea', + bech32PrefixAccPub: 'panaceapub', + bech32PrefixValAddr: 'panaceavaloper', + bech32PrefixValPub: 'panaceavaloperpub', + bech32PrefixConsAddr: 'panaceavalcons', + bech32PrefixConsPub: 'panaceavalconspub', + }, + currencies: [ + { + coinDenom: 'MED', + coinMinimalDenom: 'umed', + coinDecimals: 6, + coinGeckoId: 'medibloc', + coinImageUrl: '/tokens/blockchain/MED.png', + }, + ], + feeCurrencies: [ + { + coinDenom: 'MED', + coinMinimalDenom: 'umed', + coinDecimals: 6, + coinGeckoId: 'medibloc', + coinImageUrl: '/tokens/blockchain/MED.png', + }, + ], + features: ['stargate', 'ibc-transfer'], + explorerUrlToTx: 'https://www.mintscan.io/medibloc/txs/{txHash}', + gasPriceStep: { + low: 5, + average: 7, + high: 9, + }, + }, + }, + { + name: 'KUJIRA', + defaultDecimals: 6, + addressPatterns: ['^(kujira1)[0-9a-z]{38}$'], + feeAssets: [ + { + blockchain: 'KUJIRA', + symbol: 'KUJI', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/kuji.svg', + displayName: 'Kujira', + shortName: 'Kujira', + sort: 58, + color: '#DF3935', + enabled: true, + type: TransactionType.COSMOS, + chainId: 'kaiyo-1', + info: { + infoType: 'CosmosMetaInfo', + blockExplorerUrls: ['https://www.mintscan.io/cosmos/'], + addressUrl: 'https://www.mintscan.io/cosmos/account/{wallet}', + transactionUrl: 'https://www.mintscan.io/cosmos/txs/{txHash}', + experimental: true, + rpc: 'https://kujira-rpc.lavenderfive.com', + rest: 'https://kujira-api.lavenderfive.com', + cosmostationLcdUrl: 'https://lcd.kaiyo.kujira.setten.io', + cosmostationApiUrl: 'https://kujira-rpc.lavenderfive.com', + cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', + mintScanName: 'kujira', + chainName: 'Kujira', + stakeCurrency: { + coinDenom: 'KUJI', + coinMinimalDenom: 'ukuji', + coinDecimals: 6, + coinGeckoId: 'kujira', + coinImageUrl: '/tokens/blockchain/kuji.svg', + }, + bip44: { + coinType: 118, + }, + bech32Config: { + bech32PrefixAccAddr: 'kujira', + bech32PrefixAccPub: 'kujirapub', + bech32PrefixValAddr: 'kujiravaloper', + bech32PrefixValPub: 'kujiravaloperpub', + bech32PrefixConsAddr: 'kujiravalcons', + bech32PrefixConsPub: 'kujiravalconspub', + }, + currencies: [ + { + coinDenom: 'KUJI', + coinMinimalDenom: 'ukuji', + coinDecimals: 6, + coinGeckoId: 'kujira', + coinImageUrl: '/tokens/blockchain/kuji.png', + }, + ], + feeCurrencies: [ + { + coinDenom: 'KUJI', + coinMinimalDenom: 'ukuji', + coinDecimals: 6, + coinGeckoId: 'kujira', + coinImageUrl: '/tokens/blockchain/kuji.png', + }, + ], + features: ['stargate', 'ibc-transfer'], + explorerUrlToTx: 'https://finder.kujira.app/kaiyo-1/tx/{txHash}', + gasPriceStep: { + low: 0.01, + average: 0.025, + high: 0.03, + }, + }, + }, + { + name: 'SENTINEL', + defaultDecimals: 6, + addressPatterns: ['^(sent1)[0-9a-z]{38}$'], + feeAssets: [ + { + blockchain: 'SENTINEL', + symbol: 'DVPN', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/sentinel.png', + displayName: 'Sentinel', + shortName: 'Sentinel', + sort: 59, + color: '#142E51', + enabled: true, + type: TransactionType.COSMOS, + chainId: 'sentinelhub-2', + info: { + infoType: 'CosmosMetaInfo', + blockExplorerUrls: ['https://www.mintscan.io/cosmos/'], + addressUrl: 'https://www.mintscan.io/cosmos/account/{wallet}', + transactionUrl: 'https://www.mintscan.io/cosmos/txs/{txHash}', + experimental: false, + rpc: 'https://sentinel-rpc.publicnode.com', + rest: 'https://sentinel-rest.publicnode.com', + cosmostationLcdUrl: 'https://sentinel-rest.publicnode.com', + cosmostationApiUrl: 'https://sentinel-rpc.publicnode.com', + cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', + mintScanName: 'sentinel', + chainName: 'Sentinel', + stakeCurrency: { + coinDenom: 'DVPN', + coinMinimalDenom: 'udvpn', + coinDecimals: 6, + coinGeckoId: 'sentinel', + coinImageUrl: '/tokens/blockchain/dvpn.png', + }, + bip44: { + coinType: 118, + }, + bech32Config: { + bech32PrefixAccAddr: 'sent', + bech32PrefixAccPub: 'sentpub', + bech32PrefixValAddr: 'sentvaloper', + bech32PrefixValPub: 'sentvaloperpub', + bech32PrefixConsAddr: 'sentvalcons', + bech32PrefixConsPub: 'sentvalconspub', + }, + currencies: [ + { + coinDenom: 'DVPN', + coinMinimalDenom: 'udvpn', + coinDecimals: 6, + coinGeckoId: 'sentinel', + coinImageUrl: '/tokens/blockchain/dvpn.png', + }, + ], + feeCurrencies: [ + { + coinDenom: 'DVPN', + coinMinimalDenom: 'udvpn', + coinDecimals: 6, + coinGeckoId: 'sentinel', + coinImageUrl: '/tokens/blockchain/dvpn.png', + }, + ], + features: ['stargate', 'ibc-transfer'], + explorerUrlToTx: 'https://www.mintscan.io/sentinel/txs/{txHash}', + gasPriceStep: { + low: 0.1, + average: 0.25, + high: 0.4, + }, + }, + }, + { + name: 'INJECTIVE', + defaultDecimals: 6, + addressPatterns: ['^(inj1)[0-9a-z]{38}$'], + feeAssets: [ + { + blockchain: 'INJECTIVE', + symbol: 'INJ', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/injective.svg', + displayName: 'Injective', + shortName: 'Injective', + sort: 60, + color: '#29B2F4', + enabled: true, + type: TransactionType.COSMOS, + chainId: 'injective-1', + info: { + infoType: 'CosmosMetaInfo', + blockExplorerUrls: ['https://www.mintscan.io/cosmos/'], + addressUrl: 'https://www.mintscan.io/cosmos/account/{wallet}', + transactionUrl: 'https://www.mintscan.io/cosmos/txs/{txHash}', + experimental: true, + rpc: 'https://tm.injective.network', + rest: 'https://lcd.injective.network', + cosmostationLcdUrl: 'https://lcd.injective.network', + cosmostationApiUrl: 'https://tm.injective.network', + cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', + mintScanName: 'injective', + chainName: 'Injective', + stakeCurrency: { + coinDenom: 'INJ', + coinMinimalDenom: 'uinj', + coinDecimals: 18, + coinGeckoId: 'injective', + coinImageUrl: '/tokens/INJECTIVE/inj.svg', + }, + bip44: { + coinType: 529, + }, + bech32Config: { + bech32PrefixAccAddr: 'inj', + bech32PrefixAccPub: 'injpub', + bech32PrefixValAddr: 'injvaloper', + bech32PrefixValPub: 'injvaloperpub', + bech32PrefixConsAddr: 'injvalcons', + bech32PrefixConsPub: 'injvalconspub', + }, + currencies: [ + { + coinDenom: 'INJ', + coinMinimalDenom: 'uinj', + coinDecimals: 18, + coinGeckoId: 'injective', + coinImageUrl: '/tokens/INJECTIVE/inj.svg', + }, + ], + feeCurrencies: [ + { + coinDenom: 'INJ', + coinMinimalDenom: 'uinj', + coinDecimals: 18, + coinGeckoId: 'injective', + coinImageUrl: '/tokens/INJECTIVE/inj.svg', + }, + ], + features: ['stargate', 'ibc-transfer'], + explorerUrlToTx: 'https://www.mintscan.io/injective/txs/{txHash}', + gasPriceStep: { + low: 500000000, + average: 500000000, + high: 500000000, + }, + }, + }, + { + name: 'SECRET', + defaultDecimals: 6, + addressPatterns: ['^(secret1)[0-9a-z]{38}$'], + feeAssets: [ + { + blockchain: 'SECRET', + symbol: 'SCRT', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/secret.svg', + displayName: 'Secret', + shortName: 'Secret', + sort: 61, + color: '#1B1B1B', + enabled: true, + type: TransactionType.COSMOS, + chainId: 'secret-4', + info: { + infoType: 'CosmosMetaInfo', + experimental: false, + blockExplorerUrls: ['https://www.mintscan.io/cosmos/'], + addressUrl: 'https://www.mintscan.io/cosmos/account/{wallet}', + transactionUrl: 'https://www.mintscan.io/cosmos/txs/{txHash}', + rpc: 'https://rpc.secret.express', + rest: 'https://lcd.secret.express', + cosmostationLcdUrl: 'https://lcd.secret.express', + cosmostationApiUrl: 'https://rpc.secret.express', + cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', + mintScanName: 'secret', + chainName: 'Secret', + stakeCurrency: { + coinDenom: 'SCRT', + coinMinimalDenom: 'uscrt', + coinDecimals: 6, + coinGeckoId: 'secret', + coinImageUrl: 'https://dhj8dql1kzq2v.cloudfront.net/white/secret.png', + }, + bip44: { + coinType: 529, + }, + bech32Config: { + bech32PrefixAccAddr: 'secret', + bech32PrefixAccPub: 'secretpub', + bech32PrefixValAddr: 'secretvaloper', + bech32PrefixValPub: 'secretvaloperpub', + bech32PrefixConsAddr: 'secretvalcons', + bech32PrefixConsPub: 'secretvalconspub', + }, + currencies: [ + { + coinDenom: 'SCRT', + coinMinimalDenom: 'uscrt', + coinDecimals: 6, + coinGeckoId: 'secret', + coinImageUrl: 'https://dhj8dql1kzq2v.cloudfront.net/white/secret.png', + }, + ], + feeCurrencies: [ + { + coinDenom: 'SCRT', + coinMinimalDenom: 'uscrt', + coinDecimals: 6, + coinGeckoId: 'secret', + coinImageUrl: 'https://dhj8dql1kzq2v.cloudfront.net/white/secret.png', + }, + ], + features: ['secretwasm'], + explorerUrlToTx: 'https://www.mintscan.io/injective/txs/{txHash}', + gasPriceStep: { + low: 0.1, + average: 0.25, + high: 0.3, + }, + }, + }, + { + name: 'KONSTELLATION', + defaultDecimals: 6, + addressPatterns: ['^(darc1)[0-9a-z]{38}$'], + feeAssets: [ + { + blockchain: 'KONSTELLATION', + symbol: 'DARC', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/konstellation.svg', + displayName: 'Konstellation', + shortName: 'Konstellation', + sort: 62, + color: '#3D7BC2', + enabled: true, + type: TransactionType.COSMOS, + chainId: 'darchub', + info: { + infoType: 'CosmosMetaInfo', + blockExplorerUrls: ['https://www.mintscan.io/cosmos/'], + addressUrl: 'https://www.mintscan.io/cosmos/account/{wallet}', + transactionUrl: 'https://www.mintscan.io/cosmos/txs/{txHash}', + experimental: true, + rpc: 'https://node1.konstellation.tech:26657', + rest: 'https://node1.konstellation.tech:1318', + cosmostationLcdUrl: 'https://node1.konstellation.tech:1318', + cosmostationApiUrl: 'https://node1.konstellation.tech:26657', + cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', + mintScanName: 'konstellation', + chainName: 'Konstellation', + stakeCurrency: { + coinDenom: 'DARC', + coinMinimalDenom: 'udarc', + coinDecimals: 6, + coinGeckoId: 'pool:udarc', + coinImageUrl: '/tokens/blockchain/DARC.png', + }, + bip44: { + coinType: 118, + }, + bech32Config: { + bech32PrefixAccAddr: 'darc', + bech32PrefixAccPub: 'darcpub', + bech32PrefixValAddr: 'darcvaloper', + bech32PrefixValPub: 'darcvaloperpub', + bech32PrefixConsAddr: 'darcvalcons', + bech32PrefixConsPub: 'darcvalconspub', + }, + currencies: [ + { + coinDenom: 'DARC', + coinMinimalDenom: 'udarc', + coinDecimals: 6, + coinGeckoId: 'pool:udarc', + coinImageUrl: '/tokens/blockchain/DARC.png', + }, + ], + feeCurrencies: [ + { + coinDenom: 'DARC', + coinMinimalDenom: 'udarc', + coinDecimals: 6, + coinGeckoId: 'pool:udarc', + coinImageUrl: '/tokens/blockchain/DARC.png', + }, + ], + features: ['stargate', 'ibc-transfer', 'no-legacy-stdTx'], + explorerUrlToTx: 'https://www.mintscan.io/konstellation/txs/{txHash}', + gasPriceStep: null, + }, + }, + { + name: 'STARNAME', + defaultDecimals: 6, + addressPatterns: ['^(star1)[0-9a-z]{38}$'], + feeAssets: [ + { + blockchain: 'STARNAME', + symbol: 'IOV', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/starname.png', + displayName: 'Starname', + shortName: 'Starname', + sort: 63, + color: '#BC64BB', + enabled: true, + type: TransactionType.COSMOS, + chainId: 'iov-mainnet-ibc', + info: { + infoType: 'CosmosMetaInfo', + blockExplorerUrls: ['https://www.mintscan.io/cosmos/'], + addressUrl: 'https://www.mintscan.io/cosmos/account/{wallet}', + transactionUrl: 'https://www.mintscan.io/cosmos/txs/{txHash}', + experimental: false, + rpc: 'https://rpc-starname-ia.cosmosia.notional.ventures', + rest: 'https://api-starname-ia.cosmosia.notional.ventures', + cosmostationLcdUrl: 'https://api-starname-ia.cosmosia.notional.ventures', + cosmostationApiUrl: 'https://rpc-starname-ia.cosmosia.notional.ventures', + cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', + mintScanName: 'starname', + chainName: 'Starname', + stakeCurrency: { + coinDenom: 'IOV', + coinMinimalDenom: 'uiov', + coinDecimals: 6, + coinGeckoId: 'starname', + coinImageUrl: '/tokens/blockchain/IOV.png', + }, + bip44: { + coinType: 494, + }, + bech32Config: { + bech32PrefixAccAddr: 'star', + bech32PrefixAccPub: 'starpub', + bech32PrefixValAddr: 'starvaloper', + bech32PrefixValPub: 'starvaloperpub', + bech32PrefixConsAddr: 'starvalcons', + bech32PrefixConsPub: 'starvalconspub', + }, + currencies: [ + { + coinDenom: 'IOV', + coinMinimalDenom: 'uiov', + coinDecimals: 6, + coinGeckoId: 'starname', + coinImageUrl: '/tokens/blockchain/IOV.png', + }, + ], + feeCurrencies: [ + { + coinDenom: 'IOV', + coinMinimalDenom: 'uiov', + coinDecimals: 6, + coinGeckoId: 'starname', + coinImageUrl: '/tokens/blockchain/IOV.png', + }, + ], + features: ['stargate', 'ibc-transfer'], + explorerUrlToTx: 'https://www.mintscan.io/starname/txs/{txHash}', + gasPriceStep: { + low: 1, + average: 2, + high: 3, + }, + }, + }, + { + name: 'BITCANNA', + defaultDecimals: 6, + addressPatterns: ['^(bcna1)[0-9a-z]{38}$'], + feeAssets: [ + { + blockchain: 'BITCANNA', + symbol: 'BCNA', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/bitcanna.svg', + displayName: 'BitCanna', + shortName: 'BitCanna', + sort: 64, + color: '#3CC194', + enabled: true, + type: TransactionType.COSMOS, + chainId: 'bitcanna-1', + info: { + infoType: 'CosmosMetaInfo', + blockExplorerUrls: ['https://www.mintscan.io/cosmos/'], + addressUrl: 'https://www.mintscan.io/cosmos/account/{wallet}', + transactionUrl: 'https://www.mintscan.io/cosmos/txs/{txHash}', + experimental: true, + rpc: 'https://rpc.bitcanna.io', + rest: 'https://lcd.bitcanna.io', + cosmostationLcdUrl: 'https://lcd.bitcanna.io', + cosmostationApiUrl: 'https://rpc.bitcanna.io', + cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', + mintScanName: 'bitcanna', + chainName: 'BitCanna', + stakeCurrency: { + coinDenom: 'BCNA', + coinMinimalDenom: 'ubcna', + coinDecimals: 6, + coinGeckoId: 'bitcanna', + coinImageUrl: '/tokens/blockchain/BCNA.png', + }, + bip44: { + coinType: 118, + }, + bech32Config: { + bech32PrefixAccAddr: 'bcna', + bech32PrefixAccPub: 'bcnapub', + bech32PrefixValAddr: 'bcnavaloper', + bech32PrefixValPub: 'bcnavaloperpub', + bech32PrefixConsAddr: 'bcnavalcons', + bech32PrefixConsPub: 'bcnavalconspub', + }, + currencies: [ + { + coinDenom: 'BCNA', + coinMinimalDenom: 'ubcna', + coinDecimals: 6, + coinGeckoId: 'bitcanna', + coinImageUrl: '/tokens/blockchain/BCNA.png', + }, + ], + feeCurrencies: [ + { + coinDenom: 'BCNA', + coinMinimalDenom: 'ubcna', + coinDecimals: 6, + coinGeckoId: 'bitcanna', + coinImageUrl: '/tokens/blockchain/BCNA.png', + }, + ], + features: ['stargate', 'ibc-transfer', 'no-legacy-stdTx'], + explorerUrlToTx: 'https://www.mintscan.io/bitcanna/txs/{txHash}', + gasPriceStep: null, + }, + }, + { + name: 'UMEE', + defaultDecimals: 6, + addressPatterns: ['^(umee1)[0-9a-z]{38}$'], + feeAssets: [ + { + blockchain: 'UMEE', + symbol: 'UMEE', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/umee.svg', + displayName: 'Umee', + shortName: 'Umee', + sort: 65, + color: '#D2B6FF', + enabled: true, + type: TransactionType.COSMOS, + chainId: 'umee-1', + info: { + infoType: 'CosmosMetaInfo', + blockExplorerUrls: ['https://www.mintscan.io/cosmos/'], + addressUrl: 'https://www.mintscan.io/cosmos/account/{wallet}', + transactionUrl: 'https://www.mintscan.io/cosmos/txs/{txHash}', + experimental: false, + rpc: 'https://umee-rpc.polkachu.com', + rest: 'https://api.mainnet.network.umee.cc', + cosmostationLcdUrl: 'https://api.mainnet.network.umee.cc', + cosmostationApiUrl: 'https://umee-rpc.polkachu.com', + cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', + mintScanName: 'umee', + chainName: 'Umee', + stakeCurrency: { + coinDenom: 'UMEE', + coinMinimalDenom: 'uumee', + coinDecimals: 6, + coinGeckoId: 'pool:uumee', + coinImageUrl: '/tokens/blockchain/UMEE.png', + }, + bip44: { + coinType: 118, + }, + bech32Config: { + bech32PrefixAccAddr: 'umee', + bech32PrefixAccPub: 'umeepub', + bech32PrefixValAddr: 'umeevaloper', + bech32PrefixValPub: 'umeevaloperpub', + bech32PrefixConsAddr: 'umeevalcons', + bech32PrefixConsPub: 'umeevalconspub', + }, + currencies: [ + { + coinDenom: 'UMEE', + coinMinimalDenom: 'uumee', + coinDecimals: 6, + coinGeckoId: 'pool:uumee', + coinImageUrl: '/tokens/blockchain/UMEE.png', + }, + ], + feeCurrencies: [ + { + coinDenom: 'UMEE', + coinMinimalDenom: 'uumee', + coinDecimals: 6, + coinGeckoId: 'pool:uumee', + coinImageUrl: '/tokens/blockchain/UMEE.png', + }, + ], + features: ['stargate', 'ibc-transfer', 'no-legacy-stdTx'], + explorerUrlToTx: 'https://www.mintscan.io/umee/txs/{txHash}', + gasPriceStep: { + low: 0.05, + average: 0.06, + high: 0.1, + }, + }, + }, + { + name: 'DESMOS', + defaultDecimals: 6, + addressPatterns: ['^(desmos1)[0-9a-z]{38}$'], + feeAssets: [ + { + blockchain: 'DESMOS', + symbol: 'DSM', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/desmos.svg', + displayName: 'Desmos', + shortName: 'Desmos', + sort: 66, + color: '#DF6952', + enabled: true, + type: TransactionType.COSMOS, + chainId: 'desmos-mainnet', + info: { + infoType: 'CosmosMetaInfo', + blockExplorerUrls: ['https://www.mintscan.io/cosmos/'], + addressUrl: 'https://www.mintscan.io/cosmos/account/{wallet}', + transactionUrl: 'https://www.mintscan.io/cosmos/txs/{txHash}', + experimental: true, + rpc: 'https://rpc.mainnet.desmos.network', + rest: 'https://api.mainnet.desmos.network', + cosmostationLcdUrl: 'https://api.mainnet.desmos.network', + cosmostationApiUrl: 'https://rpc.mainnet.desmos.network', + cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', + mintScanName: 'desmos', + chainName: 'Desmos', + stakeCurrency: { + coinDenom: 'DSM', + coinMinimalDenom: 'udsm', + coinDecimals: 6, + coinGeckoId: 'pool:udsm', + coinImageUrl: '/tokens/blockchain/DSM.png', + }, + bip44: { + coinType: 852, + }, + bech32Config: { + bech32PrefixAccAddr: 'desmos', + bech32PrefixAccPub: 'desmospub', + bech32PrefixValAddr: 'desmosvaloper', + bech32PrefixValPub: 'desmosvaloperpub', + bech32PrefixConsAddr: 'desmosvalcons', + bech32PrefixConsPub: 'desmosvalconspub', + }, + currencies: [ + { + coinDenom: 'DSM', + coinMinimalDenom: 'udsm', + coinDecimals: 6, + coinGeckoId: 'pool:udsm', + coinImageUrl: '/tokens/blockchain/DSM.png', + }, + ], + feeCurrencies: [ + { + coinDenom: 'DSM', + coinMinimalDenom: 'udsm', + coinDecimals: 6, + coinGeckoId: 'pool:udsm', + coinImageUrl: '/tokens/blockchain/DSM.png', + }, + ], + features: ['stargate', 'ibc-transfer', 'no-legacy-stdTx', 'ibc-go'], + explorerUrlToTx: 'https://explorer.desmos.network/transactions/{txHash}', + gasPriceStep: null, + }, + }, + { + name: 'LUMNETWORK', + defaultDecimals: 6, + addressPatterns: ['^(lum1)[0-9a-z]{38}$'], + feeAssets: [ + { + blockchain: 'LUMNETWORK', + symbol: 'LUM', + address: null, + }, + ], + logo: 'https://api.rango.exchange/blockchains/lumnetwork.png', + displayName: 'Lum Network', + shortName: 'Lum Network', + sort: 67, + color: '#1B42B4', + enabled: true, + type: TransactionType.COSMOS, + chainId: 'lum-network-1', + info: { + infoType: 'CosmosMetaInfo', + blockExplorerUrls: ['https://www.mintscan.io/cosmos/'], + addressUrl: 'https://www.mintscan.io/cosmos/account/{wallet}', + transactionUrl: 'https://www.mintscan.io/cosmos/txs/{txHash}', + experimental: true, + rpc: 'https://node0.mainnet.lum.network/rpc', + rest: 'https://node0.mainnet.lum.network/rest', + cosmostationLcdUrl: 'https://node0.mainnet.lum.network/rest', + cosmostationApiUrl: 'https://node0.mainnet.lum.network/rpc', + cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', + mintScanName: 'lum', + chainName: 'Lum Network', + stakeCurrency: { + coinDenom: 'LUM', + coinMinimalDenom: 'ulum', + coinDecimals: 6, + coinGeckoId: 'pool:ulum', + coinImageUrl: '/tokens/blockchain/LUM.png', + }, + bip44: { + coinType: 118, + }, + bech32Config: { + bech32PrefixAccAddr: 'lum', + bech32PrefixAccPub: 'lumpub', + bech32PrefixValAddr: 'lumvaloper', + bech32PrefixValPub: 'lumvaloperpub', + bech32PrefixConsAddr: 'lumvalcons', + bech32PrefixConsPub: 'lumvalconspub', + }, + currencies: [ + { + coinDenom: 'LUM', + coinMinimalDenom: 'ulum', + coinDecimals: 6, + coinGeckoId: 'pool:ulum', + coinImageUrl: '/tokens/blockchain/LUM.png', + }, + ], + feeCurrencies: [ + { + coinDenom: 'LUM', + coinMinimalDenom: 'ulum', + coinDecimals: 6, + coinGeckoId: 'pool:ulum', + coinImageUrl: '/tokens/blockchain/LUM.png', + }, + ], + features: ['stargate', 'ibc-transfer', 'no-legacy-stdTx', 'ibc-go'], + explorerUrlToTx: 'https://www.mintscan.io/lum/txs/{txHash}', + gasPriceStep: null, + }, + }, +]; diff --git a/widget/embedded/src/hooks/usePrepareBlockchainList/usePrepareBlockchainList.test.ts b/widget/embedded/src/hooks/usePrepareBlockchainList/usePrepareBlockchainList.test.ts new file mode 100644 index 0000000000..106656a905 --- /dev/null +++ b/widget/embedded/src/hooks/usePrepareBlockchainList/usePrepareBlockchainList.test.ts @@ -0,0 +1,348 @@ +import type { BlockchainMeta } from 'rango-sdk'; + +import { beforeEach, describe, expect, it } from 'vitest'; + +import { MOST_USED_BLOCKCHAINS } from './usePrepareBlockchainList.constants'; +import { + generateSortByPreferredBlockchainsFor, + prepare, + sortByMostUsedBlockchains, +} from './usePrepareBlockchainList.helpers'; +import { sampleBlockchains } from './usePrepareBlockchainList.mock'; + +describe('usePrepareBlockchainList', () => { + let sample: BlockchainMeta[] = []; + + beforeEach(() => { + sample = JSON.parse(JSON.stringify(sampleBlockchains)); + }); + + it('should sort blockchains by most used ones.', () => { + const sortedBlockchainsList = sample.sort(sortByMostUsedBlockchains); + + const mostUsedCount = MOST_USED_BLOCKCHAINS.length; + const expected = MOST_USED_BLOCKCHAINS; + const received = sortedBlockchainsList + .map((blockchain) => blockchain.name) + .slice(0, mostUsedCount); + + expect(expected).toEqual(received); + }); + + it('should sort blockchains by user preferences', () => { + const preferredBlockchains = ['UMEE', 'BANDCHAIN', 'LINEA']; + const sortedBlockchainsList = sample.sort( + generateSortByPreferredBlockchainsFor(preferredBlockchains) + ); + + const expected = [ + 'UMEE', + 'BANDCHAIN', + 'LINEA', + 'ETH', + 'BSC', + 'ARBITRUM', + 'POLYGON', + 'ZKSYNC', + 'STARKNET', + 'OPTIMISM', + 'AVAX_CCHAIN', + 'POLYGONZK', + 'TRON', + 'BTC', + 'COSMOS', + 'OSMOSIS', + 'NEUTRON', + 'NOBLE', + 'SOLANA', + 'CRONOS', + 'BNB', + 'AURORA', + 'MAYA', + 'THOR', + 'BOBA', + 'MOONBEAM', + 'MOONRIVER', + 'OKC', + 'BOBA_AVALANCHE', + 'LTC', + 'BCH', + 'HECO', + 'STARGAZE', + 'CRYPTO_ORG', + 'CHIHUAHUA', + 'COMDEX', + 'REGEN', + 'IRIS', + 'EMONEY', + 'JUNO', + 'STRIDE', + 'MARS', + 'TERRA', + 'BITSONG', + 'AKASH', + 'KI', + 'PERSISTENCE', + 'MEDIBLOC', + 'KUJIRA', + 'SENTINEL', + 'INJECTIVE', + 'SECRET', + 'KONSTELLATION', + 'STARNAME', + 'BITCANNA', + 'DESMOS', + 'LUMNETWORK', + ]; + const received = sortedBlockchainsList.map((blockchain) => blockchain.name); + + expect(expected).toEqual(received); + }); + + it('should prepare the list by most used and user preferences', () => { + const listLimit = 10; + const preferredBlockchains = ['BTC', 'SOLANA', 'COSMOS', 'ETH']; + const expected = [ + 'BTC', + 'SOLANA', + 'ETH', + 'COSMOS', + 'OSMOSIS', + 'BSC', + 'ARBITRUM', + 'POLYGON', + 'ZKSYNC', + 'STARKNET', + 'OPTIMISM', + 'AVAX_CCHAIN', + 'POLYGONZK', + 'LINEA', + 'TRON', + 'NEUTRON', + 'NOBLE', + 'CRONOS', + 'BNB', + 'AURORA', + 'MAYA', + 'THOR', + 'BOBA', + 'MOONBEAM', + 'MOONRIVER', + 'OKC', + 'BOBA_AVALANCHE', + 'LTC', + 'BCH', + 'HECO', + 'STARGAZE', + 'CRYPTO_ORG', + 'CHIHUAHUA', + 'BANDCHAIN', + 'COMDEX', + 'REGEN', + 'IRIS', + 'EMONEY', + 'JUNO', + 'STRIDE', + 'MARS', + 'TERRA', + 'BITSONG', + 'AKASH', + 'KI', + 'PERSISTENCE', + 'MEDIBLOC', + 'KUJIRA', + 'SENTINEL', + 'INJECTIVE', + 'SECRET', + 'KONSTELLATION', + 'STARNAME', + 'BITCANNA', + 'UMEE', + 'DESMOS', + 'LUMNETWORK', + ]; + const received = prepare(sample, preferredBlockchains, { + limit: listLimit, + }); + + const receivedListNames = received.list.map( + (blockchain) => blockchain.name + ); + const receivedMoreNames = received.more.map( + (blockchain) => blockchain.name + ); + + expect(received.list).toHaveLength(listLimit); + expect(received.more).toHaveLength(expected.length - listLimit); + expect(expected).toEqual([...receivedListNames, ...receivedMoreNames]); + + // Check duplication + receivedListNames.forEach((listName) => { + expect(receivedMoreNames).not.toContain(listName); + }); + + // Check preferred blockchains to be on the main list + preferredBlockchains.forEach((blockchain) => { + expect(receivedListNames).toContain(blockchain); + }); + }); + + it('should prepare the list correctly if user has a long list of preferences ', () => { + const listLimit = 10; + const preferredBlockchains = [ + 'ETH', + 'BTC', + 'SOLANA', + 'CRYPTO_ORG', + 'TRON', + 'BOBA_AVALANCHE', + 'AKASH', + 'LUMNETWORK', + 'KONSTELLATION', + 'BANDCHAIN', + 'INJECTIVE', + ]; + const expected = [ + 'ETH', + 'BTC', + 'SOLANA', + 'CRYPTO_ORG', + 'TRON', + 'BOBA_AVALANCHE', + 'AKASH', + 'LUMNETWORK', + 'KONSTELLATION', + 'BANDCHAIN', + 'INJECTIVE', + 'COSMOS', + 'OSMOSIS', + 'BSC', + 'ARBITRUM', + 'POLYGON', + 'ZKSYNC', + 'STARKNET', + 'OPTIMISM', + 'AVAX_CCHAIN', + 'POLYGONZK', + 'LINEA', + 'NEUTRON', + 'NOBLE', + 'CRONOS', + 'BNB', + 'AURORA', + 'MAYA', + 'THOR', + 'BOBA', + 'MOONBEAM', + 'MOONRIVER', + 'OKC', + 'LTC', + 'BCH', + 'HECO', + 'STARGAZE', + 'CHIHUAHUA', + 'COMDEX', + 'REGEN', + 'IRIS', + 'EMONEY', + 'JUNO', + 'STRIDE', + 'MARS', + 'TERRA', + 'BITSONG', + 'KI', + 'PERSISTENCE', + 'MEDIBLOC', + 'KUJIRA', + 'SENTINEL', + 'SECRET', + 'STARNAME', + 'BITCANNA', + 'UMEE', + 'DESMOS', + ]; + const received = prepare(sample, preferredBlockchains, { + limit: listLimit, + }); + + expect(expected).toEqual([ + ...received.list.map((blockchain) => blockchain.name), + ...received.more.map((blockchain) => blockchain.name), + ]); + }); + + it('Last item of the main list should be moved to front if it selected again.', () => { + const listLimit = 10; + const preferredBlockchains = ['AVAX_CCHAIN', 'BTC']; + const expected = [ + 'AVAX_CCHAIN', + 'BTC', + 'ETH', + 'COSMOS', + 'OSMOSIS', + 'BSC', + 'ARBITRUM', + 'POLYGON', + 'ZKSYNC', + 'STARKNET', + 'OPTIMISM', + 'POLYGONZK', + 'LINEA', + 'TRON', + 'NEUTRON', + 'NOBLE', + 'SOLANA', + 'CRONOS', + 'BNB', + 'AURORA', + 'MAYA', + 'THOR', + 'BOBA', + 'MOONBEAM', + 'MOONRIVER', + 'OKC', + 'BOBA_AVALANCHE', + 'LTC', + 'BCH', + 'HECO', + 'STARGAZE', + 'CRYPTO_ORG', + 'CHIHUAHUA', + 'BANDCHAIN', + 'COMDEX', + 'REGEN', + 'IRIS', + 'EMONEY', + 'JUNO', + 'STRIDE', + 'MARS', + 'TERRA', + 'BITSONG', + 'AKASH', + 'KI', + 'PERSISTENCE', + 'MEDIBLOC', + 'KUJIRA', + 'SENTINEL', + 'INJECTIVE', + 'SECRET', + 'KONSTELLATION', + 'STARNAME', + 'BITCANNA', + 'UMEE', + 'DESMOS', + 'LUMNETWORK', + ]; + + const output = prepare(sample, preferredBlockchains, { + limit: listLimit, + }); + + const received = [ + ...output.list.map((blockchain) => blockchain.name), + ...output.more.map((blockchain) => blockchain.name), + ]; + + expect(expected).toEqual(received); + }); +}); diff --git a/widget/embedded/src/hooks/usePrepareBlockchainList/usePrepareBlockchainList.ts b/widget/embedded/src/hooks/usePrepareBlockchainList/usePrepareBlockchainList.ts new file mode 100644 index 0000000000..19048d43eb --- /dev/null +++ b/widget/embedded/src/hooks/usePrepareBlockchainList/usePrepareBlockchainList.ts @@ -0,0 +1,47 @@ +import type { + PrepareListOptions, + UsePrepareList, +} from './usePrepareBlockchainList.types'; +import type { BlockchainMeta } from 'rango-sdk'; + +import { useEffect } from 'react'; + +import { useAppStore } from '../../store/AppStore'; + +import { isInVisibleList, prepare } from './usePrepareBlockchainList.helpers'; + +/** + * + * UI needs some specific logics like limiting the list and sorting, + * this function is getting the raw blockchains list and return a list for showing in UI. + * + */ +export function usePrepareBlockchainList( + blockchains: BlockchainMeta[], + options?: PrepareListOptions +): UsePrepareList { + const { preferredBlockchains, addPreferredBlockchain } = useAppStore(); + + useEffect(() => { + if (options?.selected) { + const output = prepare(blockchains, preferredBlockchains, options); + + /** + * We only add a new blockchain to preferred when it's not in the main list + * In this way we can guarantee we will be able to regenerate the same list always. + * And also it helps us to avoid jumping for the last item of the main list (e.g. tenth item of our list). + */ + if (!isInVisibleList(options.selected, output)) { + addPreferredBlockchain(options?.selected); + } + } + }, [options?.selected]); + + const output = prepare(blockchains, preferredBlockchains, options); + + return { + list: output.list, + more: output.more, + history: [], + }; +} diff --git a/widget/embedded/src/hooks/usePrepareBlockchainList/usePrepareBlockchainList.types.ts b/widget/embedded/src/hooks/usePrepareBlockchainList/usePrepareBlockchainList.types.ts new file mode 100644 index 0000000000..c4469ab52b --- /dev/null +++ b/widget/embedded/src/hooks/usePrepareBlockchainList/usePrepareBlockchainList.types.ts @@ -0,0 +1,17 @@ +import type { BlockchainMeta } from 'rango-sdk'; + +export interface PrepareListOptions { + limit?: number; + selected?: string; +} + +export interface PrepareOutput { + list: BlockchainMeta[]; + more: BlockchainMeta[]; +} + +export interface UsePrepareList { + list: PrepareOutput['list']; + more: PrepareOutput['more']; + history: string[]; +} diff --git a/widget/embedded/src/hooks/useScreenDetect.ts b/widget/embedded/src/hooks/useScreenDetect.ts new file mode 100644 index 0000000000..71774bd719 --- /dev/null +++ b/widget/embedded/src/hooks/useScreenDetect.ts @@ -0,0 +1,49 @@ +import { useLayoutEffect, useState } from 'react'; + +/* + * mobile: screen <= 480 + * tablet: screen > 480 and screen <= 768 + * notebook: screen > 768 & screen <= 1024 + * large: screen > 1024 & screen <= 1200 + * extra large: screen > 1200 + */ + +const MIN_TABLET_WIDTH = 480; +const MIN_NOTEBOOK_WIDTH = 768; +const MIN_LARGE_SCREEN_WIDTH = 1024; +const MIN_EXTRA_LARGE_SCREEN_WIDTH = 1200; + +const useScreenDetect = () => { + const [isMobile, setIsMobile] = useState(false); + const [isTablet, setIsTablet] = useState(false); + const [isNotebook, setIsNotebook] = useState(false); + const [isLargeScreen, setIsLargeScreen] = useState(false); + const [isExtraLargeScreen, setIsExtraLargeScreen] = useState(false); + + const handleResize = () => { + setIsMobile(window.innerWidth <= MIN_TABLET_WIDTH); + setIsTablet( + window.innerWidth > MIN_TABLET_WIDTH && + window.innerWidth <= MIN_NOTEBOOK_WIDTH + ); + setIsNotebook( + window.innerWidth > MIN_NOTEBOOK_WIDTH && + window.innerWidth <= MIN_LARGE_SCREEN_WIDTH + ); + setIsLargeScreen( + window.innerWidth > MIN_LARGE_SCREEN_WIDTH && + window.innerWidth <= MIN_EXTRA_LARGE_SCREEN_WIDTH + ); + setIsExtraLargeScreen(window.innerWidth > MIN_EXTRA_LARGE_SCREEN_WIDTH); + }; + + useLayoutEffect(() => { + handleResize(); // Initial check + window.addEventListener('resize', handleResize); + return () => window.removeEventListener('resize', handleResize); + }, []); + + return { isMobile, isTablet, isNotebook, isLargeScreen, isExtraLargeScreen }; +}; + +export default useScreenDetect; diff --git a/widget/embedded/src/hooks/useSelectLanguage.ts b/widget/embedded/src/hooks/useSelectLanguage.ts deleted file mode 100644 index 6a0eff9f3e..0000000000 --- a/widget/embedded/src/hooks/useSelectLanguage.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { useTranslation } from 'react-i18next'; - -export default function useSelectLanguage() { - const { i18n } = useTranslation(); - // @ts-ignore - const currentLanguage = i18n?.language || 'en'; - const changeLanguage = (value: string) => { - if (currentLanguage !== value) { - // @ts-ignore - i18n.changeLanguage(value); - } - }; - - return { changeLanguage, currentLanguage }; -} diff --git a/widget/embedded/src/hooks/useStatefulConnect/index.ts b/widget/embedded/src/hooks/useStatefulConnect/index.ts new file mode 100644 index 0000000000..7e69136e6b --- /dev/null +++ b/widget/embedded/src/hooks/useStatefulConnect/index.ts @@ -0,0 +1,9 @@ +export { useStatefulConnect } from './useStatefulConnect'; +export { ResultStatus } from './useStatefulConnect.types'; +export type { + NeedsNamespacesState, + NeedsDerivationPathState, + Result, +} from './useStatefulConnect.types'; + +export type { State } from './useStatefulConnect.state'; diff --git a/widget/embedded/src/hooks/useStatefulConnect/useStatefulConnect.helpers.ts b/widget/embedded/src/hooks/useStatefulConnect/useStatefulConnect.helpers.ts new file mode 100644 index 0000000000..fe55dd58f4 --- /dev/null +++ b/widget/embedded/src/hooks/useStatefulConnect/useStatefulConnect.helpers.ts @@ -0,0 +1,13 @@ +import type { State } from './useStatefulConnect.state'; + +export function isStateOnDerivationPathStep( + state: State +): state is State & { derivationPath: NonNullable } { + return !!state.derivationPath; +} + +export function isStateOnNamespace( + state: State +): state is State & { namespace: NonNullable } { + return !!state.namespace; +} diff --git a/widget/embedded/src/hooks/useStatefulConnect/useStatefulConnect.state.ts b/widget/embedded/src/hooks/useStatefulConnect/useStatefulConnect.state.ts new file mode 100644 index 0000000000..7ba6d0bdea --- /dev/null +++ b/widget/embedded/src/hooks/useStatefulConnect/useStatefulConnect.state.ts @@ -0,0 +1,48 @@ +import type { + Actions, + NeedsDerivationPathState, + NeedsNamespacesState, +} from './useStatefulConnect.types'; + +export interface State { + status: 'init' | 'namespace' | 'derivationPath'; + namespace: NeedsNamespacesState | null; + derivationPath: NeedsDerivationPathState | null; +} + +export const initState: State = { + status: 'init', + namespace: null, + derivationPath: null, +}; + +export function reducer(state: State, action: Actions): State { + switch (action.type) { + case 'needsNamespace': + return { + ...state, + status: 'namespace', + namespace: action.payload, + derivationPath: null, + }; + case 'needsDerivationPath': + return { + ...state, + status: 'derivationPath', + derivationPath: action.payload, + }; + case 'reset': + return initState; + case 'resetDerivation': + if (state.namespace) { + return { + ...state, + derivationPath: null, + status: 'namespace', + }; + } + return initState; + default: + throw new Error(`Action hasn't been defined.`); + } +} diff --git a/widget/embedded/src/hooks/useStatefulConnect/useStatefulConnect.ts b/widget/embedded/src/hooks/useStatefulConnect/useStatefulConnect.ts new file mode 100644 index 0000000000..0738912f43 --- /dev/null +++ b/widget/embedded/src/hooks/useStatefulConnect/useStatefulConnect.ts @@ -0,0 +1,265 @@ +import type { HandleConnectOptions, Result } from './useStatefulConnect.types'; +import type { WalletInfoWithExtra } from '../../types'; +import type { ExtendedModalWalletInfo } from '../../utils/wallets'; +import type { Namespace } from '@rango-dev/wallets-core/namespaces/common'; +import type { NamespaceData, WalletType } from '@rango-dev/wallets-shared'; + +import { WalletState } from '@rango-dev/ui'; +import { useWallets } from '@rango-dev/wallets-react'; +import { useReducer } from 'react'; + +import { + isStateOnDerivationPathStep, + isStateOnNamespace, +} from './useStatefulConnect.helpers'; +import { initState, reducer, type State } from './useStatefulConnect.state'; +import { ResultStatus } from './useStatefulConnect.types'; + +interface UseStatefulConnect { + handleConnect: ( + wallet: WalletInfoWithExtra, + options?: HandleConnectOptions + ) => Promise; + handleNamespace: ( + wallet: WalletInfoWithExtra, + selectedNamespaces: Namespace[] + ) => Promise; + handleDerivationPath: (path: string) => Promise; + handleDisconnect: (type: WalletType) => Promise; + getState(): State; + resetState(section?: 'derivation'): void; +} + +/** + * + * This hook maintains state of wallet and checks if additional information + * is required to call the `connect` method of `core` package properly. + * + * The final goal is running `runConnect` which calls `wallets/core`'s `connect` method. + * But sometimes it needs to get more information like what namespace it should be connected to, + * or what derivation path should be used for. + * + */ +export function useStatefulConnect(): UseStatefulConnect { + const { state, disconnect, connect } = useWallets(); + + const [connectState, dispatch] = useReducer(reducer, initState); + + const runConnect = async ( + type: WalletType, + namespaces?: NamespaceData[], + _options?: HandleConnectOptions + ): Promise<{ status: ResultStatus }> => { + /* + * When running this function, it means all optional steps (like namespace and derivation path) has passed, or wallet doesn't need them at all. + * By resetting state, we will make sure when user tries to connect other wallets, it doesn't have unexpected states. + */ + dispatch({ + type: 'reset', + }); + + try { + const legacyNamespacesInput = namespaces?.map((namespaceInput) => ({ + ...namespaceInput, + network: undefined, + })); + await connect(type, legacyNamespacesInput); + + return { status: ResultStatus.Connected }; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + } catch (e: any) { + const message = e?.message + ? `Error: ${e.message}` + : 'An unknown error happened during connecting wallet.'; + + throw new Error(message, { cause: e }); + } + }; + + const handleConnect = async ( + wallet: ExtendedModalWalletInfo, + options?: HandleConnectOptions + ): Promise<{ + status: ResultStatus; + }> => { + const isDisconnected = wallet.state === WalletState.DISCONNECTED; + + if (isDisconnected) { + // Legacy and hub have different structure to check wether we need to show namespace or not. + + // Hub + const isHub = !!wallet.isHub; + if (isHub) { + const detachedInstances = wallet.properties?.find( + (item) => item.name === 'detached' + ); + const needsNamespace = + detachedInstances && wallet.state !== 'connected'; + + if (needsNamespace) { + dispatch({ + type: 'needsNamespace', + payload: { + targetWallet: wallet, + }, + }); + return { status: ResultStatus.Namespace }; + } + } + + /* + * Legacy + * + * For legacy there are 3 states: + * 1. a wallet doesn't have any namespace defined, we call the connect. + * 2. a wallet has more than two namespaces, we should show namepsace modal, and in that place user will be checked to needs derivation path or not. + * 3. a wallet has exactly one namespacesape, in this case we check if that needs derivation or not, if it needs we will do it here by dispatching the action accordingly. + */ + if (!wallet.needsNamespace) { + return await runConnect(wallet.type, undefined, options); + } + + const needsNamespace = wallet.needsNamespace.data.length > 1; + const needsDerivationPath = wallet.needsDerivationPath; + + if (needsNamespace) { + dispatch({ + type: 'needsNamespace', + payload: { + targetWallet: wallet, + }, + }); + return { status: ResultStatus.Namespace }; + } else if (needsDerivationPath) { + const namespace = wallet.needsNamespace.data[0]; + + dispatch({ + type: 'needsDerivationPath', + payload: { + providerType: wallet.type, + providerImage: wallet.image, + namespace: namespace.value, + }, + }); + return { status: ResultStatus.DerivationPath }; + } + + return await runConnect( + wallet.type, + wallet.needsNamespace?.data.map((namespace) => ({ + namespace: namespace.value, + })), + options + ); + } + + if (options?.disconnectIfConnected) { + await handleDisconnect(wallet.type); + return { status: ResultStatus.Disconnected }; + } + + return { status: ResultStatus.DisconnectedUnhandled }; + }; + + const handleNamespace = async ( + wallet: WalletInfoWithExtra, + selectedNamespaces: Namespace[] + ): Promise => { + const isSingleNamespace = wallet.needsNamespace?.selection === 'single'; + const needsDerivationPath = wallet.needsDerivationPath; + const firstSelectedNamespace = selectedNamespaces[0]; + + if (!firstSelectedNamespace) { + throw new Error( + 'To confirm a namespace, you should select at least one namespace.' + ); + } + + /* + * Currently we support derivation path only for single namespace wallets. + * + * Basically Single namespace is a list with radio buttons to let the user select one value within the list. + */ + if (isSingleNamespace && needsDerivationPath) { + dispatch({ + type: 'needsDerivationPath', + payload: { + providerType: wallet.type, + providerImage: wallet.image, + namespace: firstSelectedNamespace, + }, + }); + + return { status: ResultStatus.DerivationPath }; + } + + /** + * If execution reaches here, means we don't have any more optional step (like namespace and derivation) + * So we should start connecting wallet. + */ + + if (!isStateOnNamespace(connectState)) { + // Unreachable code. + throw new Error( + 'Something went wrong on handling namespace. Please retry.' + ); + } + + const type = connectState.namespace.targetWallet.type; + const namespaces = selectedNamespaces.map((namespace) => ({ + namespace, + })); + + return await runConnect(type, namespaces); + }; + + const handleDerivationPath = async ( + derivationPath: string + ): Promise => { + if (!derivationPath) { + throw new Error( + "Derivation path is empty. Please make sure you've filled the field correctly." + ); + } + + if (!isStateOnDerivationPathStep(connectState)) { + throw new Error( + 'It seems you are filling derivation path without setting namespace before doing that. Please retry to connect.' + ); + } + const type = connectState.derivationPath.providerType; + const selectedNamespace = connectState.derivationPath.namespace; + const namespaces = [{ namespace: selectedNamespace, derivationPath }]; + + return await runConnect(type, namespaces); + }; + + const handleDisconnect = async (type: WalletType): Promise => { + const wallet = state(type); + if (wallet.connected || wallet.connecting) { + await disconnect(type); + return { status: ResultStatus.Disconnected }; + } + + return { status: ResultStatus.Noop }; + }; + + return { + handleConnect, + handleDisconnect, + handleNamespace, + handleDerivationPath, + getState: () => connectState, + resetState: (section?: 'derivation') => { + if (section === 'derivation') { + dispatch({ + type: 'resetDerivation', + }); + } else { + dispatch({ + type: 'reset', + }); + } + }, + }; +} diff --git a/widget/embedded/src/hooks/useStatefulConnect/useStatefulConnect.types.ts b/widget/embedded/src/hooks/useStatefulConnect/useStatefulConnect.types.ts new file mode 100644 index 0000000000..15febca049 --- /dev/null +++ b/widget/embedded/src/hooks/useStatefulConnect/useStatefulConnect.types.ts @@ -0,0 +1,54 @@ +import type { ExtendedModalWalletInfo } from '../../utils/wallets'; +import type { Namespace } from '@rango-dev/wallets-core/namespaces/common'; + +export interface HandleConnectOptions { + // To have a switch between connect and disconnect when user is clicking on a button, this option can be helpful. + disconnectIfConnected?: boolean; +} + +export interface NeedsNamespacesState { + targetWallet: ExtendedModalWalletInfo; +} + +export interface NeedsDerivationPathState { + providerType: string; + providerImage: string; + namespace: Namespace; +} + +export enum ResultStatus { + Connected = 'connected', + Namespace = 'namespace', + DerivationPath = 'derivation-path', + Disconnected = 'disconnected', + DisconnectedUnhandled = 'disconnected-unhandled', + Noop = 'noop', +} + +export type Result = { status: ResultStatus }; + +// State types + +interface UpdateNamespaceAction { + type: 'needsNamespace'; + payload: NeedsNamespacesState; +} + +interface UpdateDerivationPathAction { + type: 'needsDerivationPath'; + payload: NeedsDerivationPathState; +} + +interface ResetAction { + type: 'reset'; +} + +interface ResetDerivationAction { + type: 'resetDerivation'; +} + +export type Actions = + | ResetAction + | ResetDerivationAction + | UpdateDerivationPathAction + | UpdateNamespaceAction; diff --git a/widget/embedded/src/hooks/useSubscribeToWidgetEvents/index.ts b/widget/embedded/src/hooks/useSubscribeToWidgetEvents/index.ts new file mode 100644 index 0000000000..8318371c73 --- /dev/null +++ b/widget/embedded/src/hooks/useSubscribeToWidgetEvents/index.ts @@ -0,0 +1 @@ +export { useSubscribeToWidgetEvents } from './useSubscribeToWidgetEvents'; diff --git a/widget/embedded/src/hooks/useSubscribeToWidgetEvents/useSubscribeToWidgetEvents.ts b/widget/embedded/src/hooks/useSubscribeToWidgetEvents/useSubscribeToWidgetEvents.ts new file mode 100644 index 0000000000..2c97af2e4f --- /dev/null +++ b/widget/embedded/src/hooks/useSubscribeToWidgetEvents/useSubscribeToWidgetEvents.ts @@ -0,0 +1,68 @@ +import type { RouteEventData, StepEventData } from '../..'; + +import { + isApprovalTX, + RouteEventType, + StepEventType, + StepExecutionEventStatus, + WidgetEvents, +} from '@rango-dev/queue-manager-rango-preset'; +import { useEffect } from 'react'; + +import { eventEmitter } from '../../services/eventEmitter'; +import { useAppStore } from '../../store/AppStore'; +import { useNotificationStore } from '../../store/notification'; + +export function useSubscribeToWidgetEvents() { + const setNotification = useNotificationStore.use.setNotification(); + const { connectedWallets, fetchBalances } = useAppStore(); + + useEffect(() => { + const handleStepEvent = (widgetEvent: StepEventData) => { + const { event, step, route } = widgetEvent; + const shouldRefetchBalance = + (event.type === StepEventType.TX_EXECUTION && + event.status === StepExecutionEventStatus.TX_SENT && + !isApprovalTX(step)) || + event.type === StepEventType.SUCCEEDED; + + if (shouldRefetchBalance) { + const fromAccount = connectedWallets.find( + (account) => account.chain === step?.fromBlockchain + ); + const toAccount = + step?.fromBlockchain !== step?.toBlockchain && + connectedWallets.find( + (wallet) => wallet.chain === step?.toBlockchain + ); + + if (fromAccount) { + void fetchBalances([fromAccount]); + } + if (toAccount) { + void fetchBalances([toAccount]); + } + } + + setNotification(event, route); + }; + eventEmitter.on(WidgetEvents.StepEvent, handleStepEvent); + return () => eventEmitter.off(WidgetEvents.StepEvent, handleStepEvent); + }, [eventEmitter, connectedWallets]); + + useEffect(() => { + const handleRouteEvent = (widgetEvent: RouteEventData) => { + const { event, route } = widgetEvent; + + if ( + event.type === RouteEventType.FAILED || + event.type === RouteEventType.SUCCEEDED + ) { + setNotification(event, route); + } + }; + eventEmitter.on(WidgetEvents.RouteEvent, handleRouteEvent); + + return () => eventEmitter.off(WidgetEvents.RouteEvent, handleRouteEvent); + }, [eventEmitter]); +} diff --git a/widget/embedded/src/hooks/useSwapInput.ts b/widget/embedded/src/hooks/useSwapInput.ts new file mode 100644 index 0000000000..dd6aa935ab --- /dev/null +++ b/widget/embedded/src/hooks/useSwapInput.ts @@ -0,0 +1,267 @@ +import type { Token } from 'rango-sdk'; + +import { useCallback, useEffect, useRef, useState } from 'react'; + +import { useAppStore } from '../store/AppStore'; +import { useQuoteStore } from '../store/quote'; +import { QuoteErrorType } from '../types'; +import { debounce } from '../utils/common'; +import { isPositiveNumber } from '../utils/numbers'; +import { + generateQuoteWarnings, + getDefaultQuote, + sortQuotesBy, +} from '../utils/quote'; +import { isRoutingEnabled } from '../utils/settings'; +import { createQuoteRequestBody } from '../utils/swap'; +import { areTokensEqual } from '../utils/wallets'; + +import { + handleQuoteErrors, + throwErrorIfResponseIsNotValid, +} from './useConfirmSwap/useConfirmSwap.helpers'; +import { useFetchAllQuotes } from './useFetchAllQuotes'; + +const DEBOUNCE_DELAY = 600; +const FIRST_INDEX = 0; + +type FetchQuoteParams = Omit< + Parameters[typeof FIRST_INDEX], + 'fromToken' | 'toToken' +> & { fromToken: Token | null; toToken: Token | null }; + +type UseSwapInput = { + fetch: (shouldChangeSelectedQuote?: boolean) => void; + loading: boolean; +}; +type UseSwapInputProps = { + refetchQuote: boolean; +}; +/** + * a hook for fetching quote based on from and to input values + * we use this hook in home page + */ +export function useSwapInput({ + refetchQuote, +}: UseSwapInputProps): UseSwapInput { + const { fetch: fetchQuote, cancelFetch } = useFetchAllQuotes(); + const { excludeLiquiditySources: configExcludeLiquiditySources, routing } = + useAppStore().config; + const { connectedWallets } = useAppStore(); + + const { + fromToken, + toToken, + inputAmount, + inputUsdValue, + selectedQuote, + sortStrategy, + resetQuote, + error, + warning, + setSelectedQuote, + updateQuotePartialState, + } = useQuoteStore(); + const { + slippage, + customSlippage, + affiliatePercent, + affiliateRef, + affiliateWallets, + fetchStatus, + } = useAppStore(); + const liquiditySources = useAppStore().getLiquiditySources(); + const disabledLiquiditySources = useAppStore().getDisabledLiquiditySources(); + const excludeLiquiditySources = useAppStore().excludeLiquiditySources(); + const { findToken } = useAppStore(); + + const [loading, setLoading] = useState(true); + const prevInputAmount = useRef(inputAmount); + const userSlippage = customSlippage ?? slippage; + const tokensValueInvalid = !fromToken || !toToken; + const shouldSkipRequest = + tokensValueInvalid || + areTokensEqual(fromToken, toToken) || + !isPositiveNumber(inputAmount); + + const resetState = (loading: boolean) => { + setLoading(loading); + }; + + const fetch = (params: FetchQuoteParams) => { + const { + fromToken, + toToken, + inputAmount, + liquiditySources, + excludeLiquiditySources, + disabledLiquiditySources, + slippage, + affiliateRef, + affiliatePercent, + affiliateWallets, + } = params; + + if (!loading) { + resetState(true); + } + if (!shouldSkipRequest && fromToken && toToken) { + resetQuote(); + const requestBody = createQuoteRequestBody({ + fromToken, + toToken, + inputAmount, + liquiditySources: liquiditySources, + excludeLiquiditySources, + disabledLiquiditySources, + wallets: connectedWallets, + slippage, + affiliateRef, + affiliatePercent, + affiliateWallets, + }); + if (isRoutingEnabled('experimental', routing)) { + requestBody.experimental = true; + } + + if (isRoutingEnabled('avoidNativeFee', routing)) { + requestBody.avoidNativeFee = true; + } + + if (isRoutingEnabled('enableCentralizedSwappers', routing)) { + requestBody.enableCentralizedSwappers = true; + } + + if (routing?.maxLength) { + requestBody.maxLength = routing.maxLength; + } + + fetchQuote(requestBody) + .then((res) => { + const sortQuotes = sortQuotesBy(sortStrategy, res.results); + const quote = getDefaultQuote( + selectedQuote, + sortQuotes, + res.requestAmount + ); + + setLoading(false); + updateQuotePartialState('quotes', res); + setSelectedQuote(quote); + + throwErrorIfResponseIsNotValid({ + diagnosisMessages: res.diagnosisMessages, + requestId: quote?.requestId || '', + swaps: quote?.swaps, + }); + const quoteWarning = + quote && + generateQuoteWarnings({ + currentQuote: quote, + userSlippage, + findToken, + }); + updateQuotePartialState('warning', quoteWarning); + }) + .catch((error) => { + const { error: quoteError } = handleQuoteErrors(error); + if ( + quoteError?.type === QuoteErrorType.NO_RESULT || + quoteError?.type === QuoteErrorType.REQUEST_FAILED + ) { + resetQuote(); + } + if (quoteError?.type !== QuoteErrorType.REQUEST_CANCELED) { + updateQuotePartialState('error', quoteError); + setLoading(false); + } + }); + } + }; + + const debouncedFetch = useCallback( + debounce((params: FetchQuoteParams) => { + fetch(params); + }, DEBOUNCE_DELAY), + [shouldSkipRequest] + ); + + useEffect(() => { + if (!refetchQuote) { + setLoading(false); + return; + } + if (fetchStatus !== 'success') { + return; + } + if (shouldSkipRequest) { + setLoading(false); + if (selectedQuote || error || warning) { + resetQuote(); + } + return; + } + if (!isPositiveNumber(inputAmount) || inputUsdValue?.eq(0)) { + resetState(false); + cancelFetch(); + return; + } + + resetQuote(); + resetState(true); + + let fetchQuotes = fetch; + if (prevInputAmount.current && prevInputAmount.current != inputAmount) { + fetchQuotes = debouncedFetch; + } + prevInputAmount.current = inputAmount; + + fetchQuotes({ + inputAmount, + fromToken, + toToken, + liquiditySources, + excludeLiquiditySources, + disabledLiquiditySources, + slippage: userSlippage, + affiliateRef, + affiliatePercent, + affiliateWallets, + }); + return cancelFetch; + }, [ + fetchStatus, + inputAmount, + fromToken?.symbol, + fromToken?.address, + fromToken?.blockchain, + toToken?.symbol, + toToken?.address, + toToken?.blockchain, + shouldSkipRequest, + liquiditySources?.length, + configExcludeLiquiditySources, + disabledLiquiditySources.length, + userSlippage, + affiliateRef, + affiliatePercent, + JSON.stringify(affiliateWallets), + ]); + + return { + fetch: () => + fetch({ + inputAmount, + fromToken, + toToken, + liquiditySources, + excludeLiquiditySources, + disabledLiquiditySources, + slippage: userSlippage, + affiliateRef, + affiliatePercent, + affiliateWallets, + }), + loading, + }; +} diff --git a/widget/embedded/src/hooks/useSyncNotifications/index.ts b/widget/embedded/src/hooks/useSyncNotifications/index.ts new file mode 100644 index 0000000000..45afcc4ff9 --- /dev/null +++ b/widget/embedded/src/hooks/useSyncNotifications/index.ts @@ -0,0 +1 @@ +export { useSyncNotifications } from './useSyncNotifications'; diff --git a/widget/embedded/src/hooks/useSyncNotifications/useSyncNotifications.ts b/widget/embedded/src/hooks/useSyncNotifications/useSyncNotifications.ts new file mode 100644 index 0000000000..efc23c2833 --- /dev/null +++ b/widget/embedded/src/hooks/useSyncNotifications/useSyncNotifications.ts @@ -0,0 +1,25 @@ +import { useManager } from '@rango-dev/queue-manager-react'; +import { useEffect } from 'react'; + +import { useNotificationStore } from '../../store/notification'; +import { getPendingSwaps } from '../../utils/queue'; + +export function useSyncNotifications() { + const { isSynced, syncNotifications } = useNotificationStore(); + const { manager, state } = useManager(); + + useEffect(() => { + const shouldSyncNotifications = + useNotificationStore.persist.hasHydrated() && + state.loadedFromPersistor && + !isSynced; + + if (shouldSyncNotifications) { + syncNotifications(getPendingSwaps(manager)); + } + }, [ + useNotificationStore.persist.hasHydrated(), + state.loadedFromPersistor, + isSynced, + ]); +} diff --git a/widget/embedded/src/hooks/useSyncStoresWithConfig.ts b/widget/embedded/src/hooks/useSyncStoresWithConfig.ts new file mode 100644 index 0000000000..a81087d034 --- /dev/null +++ b/widget/embedded/src/hooks/useSyncStoresWithConfig.ts @@ -0,0 +1,139 @@ +import type { Asset } from 'rango-sdk'; + +import { useEffect, useRef } from 'react'; + +import { useAppStore } from '../store/AppStore'; +import { useQuoteStore } from '../store/quote'; +import { + isBlockchainExcludedInConfig, + isTokenExcludedInConfig, +} from '../utils/configs'; + +export function useSyncStoresWithConfig() { + const { + setInputAmount, + setToToken, + setToBlockchain, + setFromBlockchain, + resetQuote, + setFromToken, + fromToken, + toToken, + fromBlockchain, + toBlockchain, + } = useQuoteStore(); + + const config = useAppStore().config; + const fetchMetaStatus = useAppStore().fetchStatus; + const blockchains = useAppStore().blockchains(); + const tokens = useAppStore().tokens(); + const { findToken } = useAppStore(); + + const { setAffiliateRef, setAffiliatePercent, setAffiliateWallets } = + useAppStore(); + + const fromTokensConfig = config?.from?.tokens; + const fromBlockchainsConfig = config?.from?.blockchains; + const toTokensConfig = config?.to?.tokens; + const toBlockchainsConfig = config?.to?.blockchains; + const prevConfigFromToken = useRef(undefined); + const prevConfigToToken = useRef(undefined); + const prevConfigFromBlockchain = useRef(undefined); + const prevConfigToBlockchain = useRef(undefined); + + useEffect(() => { + if (typeof config.amount !== 'undefined') { + setInputAmount(config.amount.toString()); + } + }, [config?.amount]); + + useEffect(() => { + if (fetchMetaStatus === 'success') { + resetQuote(); + const chain = blockchains.find( + (chain) => chain.name === config?.from?.blockchain + ); + const fromToken = config?.from?.token; + const token = fromToken && findToken(fromToken); + + if (chain || (!chain && prevConfigFromBlockchain.current)) { + setFromBlockchain(chain ?? null); + } + + if (token) { + setFromToken({ token, meta: { blockchains, tokens } }); + } else if (!token && prevConfigFromToken.current) { + setFromToken({ token: null }); + } + + prevConfigFromBlockchain.current = config?.from?.blockchain; + prevConfigFromToken.current = config?.from?.token; + } + }, [ + config?.from?.token?.symbol, + config?.from?.token?.address, + config?.from?.token?.blockchain, + config?.from?.blockchain, + fetchMetaStatus, + ]); + + useEffect(() => { + if (isTokenExcludedInConfig(fromToken, fromTokensConfig)) { + setFromToken({ token: null }); + } + + if (isBlockchainExcludedInConfig(fromBlockchain, fromBlockchainsConfig)) { + setFromBlockchain(null); + } + }, [fromTokensConfig, fromBlockchainsConfig]); + + useEffect(() => { + if (isTokenExcludedInConfig(toToken, toTokensConfig)) { + setFromToken({ token: null }); + } + if (isBlockchainExcludedInConfig(toBlockchain, toBlockchainsConfig)) { + setToBlockchain(null); + } + }, [toTokensConfig, toBlockchainsConfig]); + + useEffect(() => { + if (fetchMetaStatus === 'success') { + resetQuote(); + const chain = blockchains.find( + (chain) => chain.name === config?.to?.blockchain + ); + + const toToken = config?.to?.token; + const token = toToken && findToken(toToken); + + if (chain || (!chain && prevConfigToBlockchain.current)) { + setToBlockchain(chain ?? null); + } + + if (token) { + setToToken({ token, meta: { blockchains, tokens } }); + } else if (!token && prevConfigToToken.current) { + setToToken({ token: null }); + } + + prevConfigToBlockchain.current = config?.to?.blockchain; + prevConfigToToken.current = config?.to?.token; + } + }, [ + config?.to?.token?.symbol, + config?.to?.token?.address, + config?.to?.token?.blockchain, + config?.to?.blockchain, + fetchMetaStatus, + ]); + + useEffect(() => { + setAffiliateRef(config?.affiliate?.ref ?? null); + setAffiliatePercent(config?.affiliate?.percent ?? null); + setAffiliateWallets(config?.affiliate?.wallets ?? null); + }, [ + config?.affiliate?.ref, + config?.affiliate?.percent, + config?.affiliate?.wallets, + ]); +} diff --git a/widget/embedded/src/hooks/useSyncUrlAndStore/index.ts b/widget/embedded/src/hooks/useSyncUrlAndStore/index.ts new file mode 100644 index 0000000000..b93709df91 --- /dev/null +++ b/widget/embedded/src/hooks/useSyncUrlAndStore/index.ts @@ -0,0 +1 @@ +export { useSyncUrlAndStore } from './useSyncUrlAndStore'; diff --git a/widget/embedded/src/hooks/useSyncUrlAndStore/useSyncUrlAndStore.helpers.ts b/widget/embedded/src/hooks/useSyncUrlAndStore/useSyncUrlAndStore.helpers.ts new file mode 100644 index 0000000000..060b99d304 --- /dev/null +++ b/widget/embedded/src/hooks/useSyncUrlAndStore/useSyncUrlAndStore.helpers.ts @@ -0,0 +1,21 @@ +import type { Asset, BlockchainMeta, Token } from 'rango-sdk'; + +export function convertTokenSearchParamToAsset( + searchParam: string, + chain: BlockchainMeta +): Asset { + const symbolAndAddress = searchParam.split('--'); + + return { + blockchain: chain.name, + address: symbolAndAddress?.[1] || null, + symbol: symbolAndAddress[0], + }; +} + +export function tokenToSearchParam(token: Token | null): string | undefined { + if (token) { + return `${token.symbol}${token.address ? `--${token.address}` : ''}`; + } + return undefined; +} diff --git a/widget/embedded/src/hooks/useSyncUrlAndStore/useSyncUrlAndStore.ts b/widget/embedded/src/hooks/useSyncUrlAndStore/useSyncUrlAndStore.ts new file mode 100644 index 0000000000..a41193dd7c --- /dev/null +++ b/widget/embedded/src/hooks/useSyncUrlAndStore/useSyncUrlAndStore.ts @@ -0,0 +1,188 @@ +import { useEffect, useRef } from 'react'; +import { + useInRouterContext, + useLocation, + useSearchParams, +} from 'react-router-dom'; + +import { SearchParams } from '../../constants/searchParams'; +import { useAppStore } from '../../store/AppStore'; +import { useQuoteStore } from '../../store/quote'; + +import { + convertTokenSearchParamToAsset, + tokenToSearchParam, +} from './useSyncUrlAndStore.helpers'; + +export function useSyncUrlAndStore() { + const location = useLocation(); + const [searchParams, setSearchParams] = useSearchParams(); + const { + fromBlockchain, + toBlockchain, + fromToken, + toToken, + inputAmount, + setFromBlockchain, + setToBlockchain, + setFromToken, + setToToken, + setInputAmount, + } = useQuoteStore(); + const fetchMetaStatus = useAppStore().fetchStatus; + const blockchains = useAppStore().blockchains(); + const tokens = useAppStore().tokens(); + const isInRouterContext = useInRouterContext(); + const { updateIframe, updateCampaignMode } = useAppStore(); + const campaignMode = useAppStore().isInCampaignMode(); + const liquiditySourcesParamsRef = useRef(); + const { findToken } = useAppStore(); + const getUrlSearchParams = () => { + const utmQueryParams: Record = {}; + + for (const [key, value] of searchParams.entries()) { + if (key.startsWith('utm_')) { + utmQueryParams[key] = value; + } + } + const fromAmount = searchParams.get(SearchParams.FROM_AMOUNT); + const fromBlockchain = searchParams.get(SearchParams.FROM_BLOCKCHAIN); + const fromToken = searchParams.get(SearchParams.FROM_TOKEN); + const toBlockchain = searchParams.get(SearchParams.TO_BLOCKCHAIN); + const toToken = searchParams.get(SearchParams.TO_TOKEN); + const autoConnect = searchParams.get(SearchParams.AUTO_CONNECT); + const clientUrl = searchParams.get(SearchParams.CLIENT_URL); + const liquiditySources = searchParams.get(SearchParams.LIQUIDITY_SOURCES); + + const blockchain = searchParams.get(SearchParams.BLOCKCHAIN); + + return { + fromAmount, + fromBlockchain, + fromToken, + toBlockchain, + toToken, + autoConnect, + clientUrl, + liquiditySources, + utmQueryParams, + blockchain, + }; + }; + + const updateUrlSearchParams = ( + searchParams: Record + ) => { + for (const property in searchParams) { + if (!searchParams[property]) { + delete searchParams[property]; + } + } + setSearchParams(searchParams as Record, { replace: true }); + }; + + useEffect(() => { + const { autoConnect, clientUrl, utmQueryParams, blockchain } = + getUrlSearchParams(); + if (isInRouterContext && fetchMetaStatus === 'success') { + updateUrlSearchParams({ + [SearchParams.FROM_BLOCKCHAIN]: fromBlockchain?.name, + [SearchParams.FROM_TOKEN]: tokenToSearchParam(fromToken), + [SearchParams.TO_BLOCKCHAIN]: toBlockchain?.name, + [SearchParams.TO_TOKEN]: tokenToSearchParam(toToken), + [SearchParams.FROM_AMOUNT]: inputAmount, + [SearchParams.AUTO_CONNECT]: autoConnect ?? undefined, + [SearchParams.CLIENT_URL]: clientUrl ?? undefined, + [SearchParams.BLOCKCHAIN]: blockchain ?? undefined, + [SearchParams.LIQUIDITY_SOURCES]: campaignMode + ? liquiditySourcesParamsRef.current + : undefined, + ...utmQueryParams, + }); + } + }, [ + location.pathname, + inputAmount, + fromBlockchain, + fromToken, + toBlockchain, + toToken, + campaignMode, + ]); + + useEffect(() => { + if (!isInRouterContext) { + return; + } + + const searchParams = getUrlSearchParams(); + + if (!liquiditySourcesParamsRef.current && searchParams.liquiditySources) { + liquiditySourcesParamsRef.current = searchParams.liquiditySources; + } + + if (searchParams.fromAmount) { + setInputAmount(searchParams.fromAmount); + } + + if (fetchMetaStatus === 'success') { + const fromBlockchain = blockchains.find( + (blockchain) => blockchain.name === searchParams.fromBlockchain + ); + + const fromToken = + searchParams.fromToken && fromBlockchain + ? findToken( + convertTokenSearchParamToAsset( + searchParams.fromToken, + fromBlockchain + ) + ) + : undefined; + const toBlockchain = blockchains.find( + (blockchain) => blockchain.name === searchParams.toBlockchain + ); + + const toToken = + searchParams.toToken && toBlockchain + ? findToken( + convertTokenSearchParamToAsset(searchParams.toToken, toBlockchain) + ) + : undefined; + + if (!!fromBlockchain) { + setFromBlockchain(fromBlockchain); + if (!!fromToken) { + setFromToken({ + token: fromToken, + meta: { + blockchains: blockchains, + tokens: tokens, + }, + }); + } + } + + if (!!toBlockchain) { + setToBlockchain(toBlockchain); + if (!!toToken) { + setToToken({ + token: toToken, + meta: { blockchains: blockchains, tokens: tokens }, + }); + } + } + } + }, [fetchMetaStatus]); + + useEffect(() => { + const { clientUrl, liquiditySources } = getUrlSearchParams(); + // We run this only once, because if the app is embedded into an iframe, the data in url for iframe will not change. + updateIframe('clientUrl', clientUrl || undefined); + + updateCampaignMode( + 'liquiditySources', + liquiditySources?.split(',') ?? undefined + ); + }, []); +} diff --git a/widget/embedded/src/hooks/useTheme.ts b/widget/embedded/src/hooks/useTheme.ts index 51be0a677c..cbe5a73e4d 100644 --- a/widget/embedded/src/hooks/useTheme.ts +++ b/widget/embedded/src/hooks/useTheme.ts @@ -1,139 +1,104 @@ -import { createTheme } from '@rango-dev/ui'; -import { useState, useEffect, useLayoutEffect } from 'react'; -import { useMetaStore } from '../store/meta'; -import { useSettingsStore } from '../store/settings'; -import { WidgetTheme } from '../types'; -import { shadeColor } from '../utils/common'; -import usePrevious from './usePrevious'; +/* eslint-disable @typescript-eslint/no-magic-numbers */ +import { + createTheme, + darkTheme as defaultDarkTheme, + lightTheme as defaultLightTheme, +} from '@rango-dev/ui'; +import { useEffect, useState } from 'react'; -export function useTheme({ - colors: themeColors, - fontFamily = 'Robot', - borderRadius = 8, - mode = 'auto', -}: WidgetTheme) { - const theme = useSettingsStore.use.theme(); - const fetchMeta = useMetaStore.use.fetchMeta(); - const setTheme = useSettingsStore.use.setTheme(); +import { DEFAULT_FONT_FAMILY } from '../constants/fonts'; +import { useAppStore } from '../store/AppStore'; +import { type WidgetTheme } from '../types'; +import { + DEFAULT_PRIMARY_RADIUS, + DEFAULT_SECONDARY_RADIUS, +} from '../utils/configs'; +import { customizedThemeTokens } from '../utils/ui'; - const primary = themeColors?.primary || '#5FA425', - background = themeColors?.background || '#fff', - foreground = themeColors?.foreground || '#000', - error = themeColors?.error || '#FF0000', - warning = themeColors?.warning || '#F5A623', - success = themeColors?.success || '#0070F3'; - const colors = { - neutrals200: '#FAFAFA', - neutrals300: '#f2f2f2', - neutrals400: '#dedede', - neutrals500: '#cccccc', - neutrals600: '#acacac', - neutrals700: '#444444', - neutrals800: '#333333', - neutrals900: '#111111', - primary, - primary100: shadeColor(primary, 15), - primary200: shadeColor(primary, -10), - primary300: shadeColor(primary, -15), - primary400: shadeColor(primary, -20), - primary500: shadeColor(primary, -25), - primary600: shadeColor(primary, -30), - primary700: shadeColor(primary, -35), - primary800: shadeColor(primary, -40), - primary900: shadeColor(primary, -45), - background, - foreground, - error, - error100: shadeColor(error, 50), - error300: shadeColor(error, -10), - error500: shadeColor(error, -20), - error700: shadeColor(error, -30), - warning, - warning100: shadeColor(warning, 50), - warning300: shadeColor(warning, -10), - warning500: shadeColor(warning, -20), - warning700: shadeColor(warning, -30), - success, - success100: shadeColor(success, 50), - success300: shadeColor(success, -10), - success500: shadeColor(success, -20), - success700: shadeColor(success, -30), - }; +function doesWindowPreferDarkColorScheme() { + return ( + window.matchMedia && + window.matchMedia('(prefers-color-scheme: dark)').matches + ); +} - const customeLightTheme = createTheme({ +export function useTheme(props: WidgetTheme) { + const { colors, - radii: { - 5: `${borderRadius}px`, - }, - shadows: { - s: '0px 3px 5px 3px #f0f2f5, 0px 6px 10px 3px #f0f2f5, 0px 1px 18px 3px #f0f2f5', - }, - }); + fontFamily = DEFAULT_FONT_FAMILY, + borderRadius = DEFAULT_PRIMARY_RADIUS, + secondaryBorderRadius = DEFAULT_SECONDARY_RADIUS, + } = props; - const customeDarkTheme = createTheme({ - colors: { - ...colors, - neutrals200: '#111111', - neutrals300: '#333333', - neutrals400: '#444444', - neutrals500: '#acacac', - neutrals600: '#cccccc', - neutrals700: '#dedede', - neutrals800: '#f2f2f2', - neutrals900: '#FAFAFA', - foreground: background, - background: foreground, - }, + const [OSTheme, setOSTheme] = useState( + doesWindowPreferDarkColorScheme() ? 'dark' : 'light' + ); + + const { theme } = useAppStore(); + + const { dark, light } = customizedThemeTokens(colors); + + const baseTheme = createTheme({ + shadows: props.shadows || {}, radii: { - 5: `${borderRadius}px`, + primary: `${borderRadius}px`, + secondary: `${secondaryBorderRadius}px`, }, - shadows: { - s: '0px 3px 5px 3px #222, 0px 6px 10px 3px #222, 0px 1px 18px 3px #222', + fonts: { + widget: fontFamily, }, }); - const [OSTheme, setOSTheme] = useState(customeLightTheme); - useEffect(() => { - (async () => { - await fetchMeta(); - })(); + const lightThemeClasses = [baseTheme.className, defaultLightTheme.className]; + const darkThemeClasses = [baseTheme.className, defaultDarkTheme.className]; + + /* + * If theme has been customized, we will push the customized theme to override the default themes. + * To be overridden, it should be last thing that has been pushed. + */ + if (light) { + const customizedLightTheme = createTheme(light.id, light.tokens); + lightThemeClasses.push(customizedLightTheme.className); + } + if (dark) { + const customizedDarkTheme = createTheme(dark.id, dark.tokens); + darkThemeClasses.push(customizedDarkTheme.className); + } - const switchTheme = (event: MediaQueryListEvent) => { - if (event.matches) setOSTheme(customeDarkTheme); - else setOSTheme(customeLightTheme); + useEffect(() => { + const switchThemeListener = (event: MediaQueryListEvent) => { + if (event.matches) { + setOSTheme('dark'); + } else { + setOSTheme('light'); + } }; - if ( - window.matchMedia && - window.matchMedia('(prefers-color-scheme: dark)').matches - ) { - setOSTheme(customeDarkTheme); + if (doesWindowPreferDarkColorScheme()) { + setOSTheme('dark'); } window .matchMedia('(prefers-color-scheme: dark)') - .addEventListener('change', switchTheme); + .addEventListener('change', switchThemeListener); return () => { window .matchMedia('(prefers-color-scheme: dark)') - .removeEventListener('change', switchTheme); + .removeEventListener('change', switchThemeListener); }; }, []); - useEffect(() => { - if (mode !== 'auto') setTheme(mode); - }, [mode]); - const prevFont = usePrevious(fontFamily); - - useLayoutEffect(() => { - const { classList } = document.body; - - if (prevFont) classList.remove(`font_${prevFont.replace(/ /g, '')}`); - classList.add(`font_${fontFamily.replace(/ /g, '')}`); - }, [fontFamily]); const getActiveTheme = () => { - if (theme === 'auto') return OSTheme; - else return theme === 'dark' ? customeDarkTheme : customeLightTheme; + const lightClassNames = lightThemeClasses.join(' '); + const darkClassNames = darkThemeClasses.join(' '); + if (theme === 'auto') { + return OSTheme === 'dark' ? darkClassNames : lightClassNames; + } + + return theme === 'dark' ? darkClassNames : lightClassNames; }; - return { activeTheme: getActiveTheme() }; + return { + activeTheme: getActiveTheme, + mode: theme === 'auto' ? OSTheme : theme, + }; } diff --git a/widget/embedded/src/hooks/useUpdateQuoteInputs/index.ts b/widget/embedded/src/hooks/useUpdateQuoteInputs/index.ts new file mode 100644 index 0000000000..fad9154d40 --- /dev/null +++ b/widget/embedded/src/hooks/useUpdateQuoteInputs/index.ts @@ -0,0 +1 @@ +export { useUpdateQuoteInputs } from './useUpdateQuoteInputs'; diff --git a/widget/embedded/src/hooks/useUpdateQuoteInputs/useUpdateQuoteInputs.ts b/widget/embedded/src/hooks/useUpdateQuoteInputs/useUpdateQuoteInputs.ts new file mode 100644 index 0000000000..d38fdfa870 --- /dev/null +++ b/widget/embedded/src/hooks/useUpdateQuoteInputs/useUpdateQuoteInputs.ts @@ -0,0 +1,50 @@ +import type { UpdateQuoteInputs } from '../../types'; + +import { useAppStore } from '../../store/AppStore'; +import { useQuoteStore } from '../../store/quote'; + +// This hook provides a function to update quote inputs using fewer and simpler parameters. +export function useUpdateQuoteInputs() { + const { findToken } = useAppStore(); + const blockchains = useAppStore().blockchains(); + const tokens = useAppStore().tokens(); + const { + setFromBlockchain, + setFromToken, + setToBlockchain, + setToToken, + setInputAmount, + } = useQuoteStore(); + + const updateQuoteInputs: UpdateQuoteInputs = (params) => { + const { fromBlockchain, fromToken, toBlockchain, toToken, requestAmount } = + params; + const meta = { blockchains, tokens }; + + if (fromBlockchain !== undefined) { + const blockchainMeta = + blockchains.find((blockchain) => blockchain.name === fromBlockchain) ?? + null; + setFromBlockchain(blockchainMeta); + } + if (fromToken !== undefined) { + const token = fromToken ? findToken(fromToken) ?? null : null; + setFromToken({ meta, token }); + } + if (toBlockchain !== undefined) { + const blockchainMeta = + blockchains.find((blockchain) => blockchain.name === toBlockchain) ?? + null; + setToBlockchain(blockchainMeta); + } + if (toToken !== undefined) { + const token = toToken ? findToken(toToken) ?? null : null; + setToToken({ meta, token }); + } + if (requestAmount !== undefined) { + setInputAmount(requestAmount); + } + }; + + return updateQuoteInputs; +} diff --git a/widget/embedded/src/hooks/useWalletList.ts b/widget/embedded/src/hooks/useWalletList.ts new file mode 100644 index 0000000000..e1f3f2bb41 --- /dev/null +++ b/widget/embedded/src/hooks/useWalletList.ts @@ -0,0 +1,151 @@ +import type { WalletInfoWithExtra } from '../types'; +import type { WalletInfo } from '@rango-dev/ui'; +import type { BlockchainMeta } from 'rango-sdk'; + +import { WalletState } from '@rango-dev/ui'; +import { useWallets } from '@rango-dev/wallets-react'; +import { + detectMobileScreens, + KEPLR_COMPATIBLE_WALLETS, + WalletTypes, +} from '@rango-dev/wallets-shared'; +import { useCallback, useEffect } from 'react'; + +import { useAppStore } from '../store/AppStore'; +import { configWalletsToWalletName } from '../utils/providers'; +import { + hashWalletsState, + isExperimentalChain, + mapWalletTypesToWalletInfo, + sortWalletsBasedOnConnectionState, +} from '../utils/wallets'; + +import { useStatefulConnect } from './useStatefulConnect/useStatefulConnect'; + +interface Params { + chain?: string; +} + +interface API { + list: WalletInfoWithExtra[]; + terminateConnectingWallets: () => void; +} + +/** + * + * Returning list of wallets which has a applied sorting and filtering (some of wallet can be excluded). + * It can have some functionality on list itself, + * now it only has a method to disconnect the wallets that has `connecting` status. This is useful for exiting page and terminating wallet connection. + * + */ +export function useWalletList(params?: Params): API { + const { chain } = params || {}; + const { config, connectedWallets, getAvailableProviders } = useAppStore(); + const { state, getWalletInfo } = useWallets(); + const blockchains = useAppStore().blockchains(); + const { handleDisconnect } = useStatefulConnect(); + + /** It can be what has been set by widget config or as a fallback we use all the supported wallets by our library */ + const listAvailableWalletTypes = configWalletsToWalletName( + getAvailableProviders(), + { + trezorManifest: config?.trezorManifest, + walletConnectProjectId: config?.walletConnectProjectId, + walletConnectListedDesktopWalletLink: + config.__UNSTABLE_OR_INTERNAL__?.walletConnectListedDesktopWalletLink, + tonConnect: config.tonConnect, + } + ); + + let wallets = mapWalletTypesToWalletInfo( + state, + getWalletInfo, + listAvailableWalletTypes, + chain + ); + + wallets = detectMobileScreens() + ? wallets.filter( + (wallet) => + wallet.showOnMobile !== false && state(wallet.type).installed + ) + : wallets; + + const sortedWallets = sortWalletsBasedOnConnectionState(wallets); + + const isExperimentalChainNotAdded = (walletType: string) => + !connectedWallets.find( + (connectedWallet) => + connectedWallet.walletType === walletType && + connectedWallet.chain === chain + ); + + const terminateConnectingWallets = useCallback(() => { + const connectingWallets = + wallets?.filter((wallet) => wallet.state === WalletState.CONNECTING) || + []; + for (const wallet of connectingWallets) { + void handleDisconnect(wallet.type); + } + }, [hashWalletsState(wallets)]); + + useEffect(() => { + return () => { + terminateConnectingWallets(); + }; + }, []); + + /* + * Atm, we only support default injected wallet for the EVM + * so we show default wallet when there is no other evm wallet installed + * but we have ethereum injected + */ + const shouldShowDefaultInjectedWallet = (wallets: WalletInfo[]) => { + // don't show default injected wallet when it's not installed + const defaultWallet = wallets.find( + (wallet) => wallet.type === WalletTypes.DEFAULT + ); + if (!defaultWallet || defaultWallet.state === WalletState.NOT_INSTALLED) { + return false; + } + + /* + * if we have another evm wallet installed (except wallet connect), + * there is no need to show default injected wallet anymore + */ + const isEvmWalletInstalledExceptDefault = wallets.filter( + (wallet) => + wallet.state != WalletState.NOT_INSTALLED && + ![ + WalletTypes.DEFAULT, + WalletTypes.WALLET_CONNECT_2, + WalletTypes.LEDGER, + ].includes(wallet.type as WalletTypes) && + getWalletInfo(wallet.type).supportedChains.filter( + (blockchain) => blockchain.type == 'EVM' + ).length > 0 + ); + return isEvmWalletInstalledExceptDefault.length == 0; + }; + + const shouldExcludeWallet = ( + walletType: string, + chain: string, + blockchains: BlockchainMeta[] + ) => { + return ( + (isExperimentalChain(blockchains, chain) && + isExperimentalChainNotAdded(walletType) && + !KEPLR_COMPATIBLE_WALLETS.includes(walletType)) || + (walletType == WalletTypes.DEFAULT && + !shouldShowDefaultInjectedWallet(wallets)) + ); + }; + + return { + list: sortedWallets.filter( + (wallet) => !shouldExcludeWallet(wallet.type, chain ?? '', blockchains) + ), + terminateConnectingWallets, + }; +} diff --git a/widget/embedded/src/hooks/useWalletProviders/index.ts b/widget/embedded/src/hooks/useWalletProviders/index.ts new file mode 100644 index 0000000000..8ab8268315 --- /dev/null +++ b/widget/embedded/src/hooks/useWalletProviders/index.ts @@ -0,0 +1 @@ +export { useWalletProviders } from './useWalletProviders'; diff --git a/widget/embedded/src/hooks/useWalletProviders/useWalletProviders.helpers.ts b/widget/embedded/src/hooks/useWalletProviders/useWalletProviders.helpers.ts new file mode 100644 index 0000000000..bfb6da6269 --- /dev/null +++ b/widget/embedded/src/hooks/useWalletProviders/useWalletProviders.helpers.ts @@ -0,0 +1,14 @@ +import type { ProviderInterface } from '@rango-dev/wallets-react'; + +export function hashProviders( + providers: (string | ProviderInterface)[] +): string { + return providers + .map((provider) => { + if (typeof provider === 'string') { + return provider; + } + return provider.config.type; + }) + .join('-'); +} diff --git a/widget/embedded/src/hooks/useWalletProviders/useWalletProviders.ts b/widget/embedded/src/hooks/useWalletProviders/useWalletProviders.ts new file mode 100644 index 0000000000..6a6afeff5f --- /dev/null +++ b/widget/embedded/src/hooks/useWalletProviders/useWalletProviders.ts @@ -0,0 +1,30 @@ +import type { WidgetConfig } from '../../types'; +import type { ProvidersOptions } from '../../utils/providers'; + +import { useEffect } from 'react'; + +import { useAppStore } from '../../store/AppStore'; + +import { hashProviders } from './useWalletProviders.helpers'; + +export function useWalletProviders( + configWallets: WidgetConfig['wallets'], + options?: ProvidersOptions +) { + const { clearConnectedWallet, getAvailableProviders, buildAndSetProviders } = + useAppStore(); + const providers = getAvailableProviders(); + + useEffect(() => { + clearConnectedWallet(); + buildAndSetProviders(); + }, [ + hashProviders(configWallets ?? []), + options?.walletConnectProjectId, + options?.walletConnectListedDesktopWalletLink, + ]); + + return { + providers, + }; +} diff --git a/widget/embedded/src/hooks/useWidgetEvents/index.ts b/widget/embedded/src/hooks/useWidgetEvents/index.ts new file mode 100644 index 0000000000..e1f84bf539 --- /dev/null +++ b/widget/embedded/src/hooks/useWidgetEvents/index.ts @@ -0,0 +1 @@ +export { useWidgetEvents } from './useWidgetEvents'; diff --git a/widget/embedded/src/hooks/useWidgetEvents/useWidgetEvents.ts b/widget/embedded/src/hooks/useWidgetEvents/useWidgetEvents.ts new file mode 100644 index 0000000000..106d5f2e0c --- /dev/null +++ b/widget/embedded/src/hooks/useWidgetEvents/useWidgetEvents.ts @@ -0,0 +1,9 @@ +import type { WidgetEventEmitter } from '../../types'; + +import { eventEmitter } from '../../services/eventEmitter'; + +export function useWidgetEvents(): WidgetEventEmitter { + // To be exported for Dapps + const { on, off } = eventEmitter; + return { on, off }; +} diff --git a/widget/embedded/src/i18n.js b/widget/embedded/src/i18n.js deleted file mode 100644 index 8eeeaf3689..0000000000 --- a/widget/embedded/src/i18n.js +++ /dev/null @@ -1,30 +0,0 @@ -import i18n from 'i18next'; -import { initReactI18next } from 'react-i18next'; -import en from './languages/en.json'; -import tr from './languages/tr.json'; -import Backend from 'i18next-http-backend'; -import LanguageDetector from 'i18next-browser-languagedetector'; - -const languages = ['en', 'tr']; - -i18n - .use(Backend) - // detect user language - .use(LanguageDetector) - // pass the i18n instance to react-i18next. - .use(initReactI18next) - .init({ - resources: { - en: { - translation: en, - }, - tr: { - translation: tr, - }, - }, - fallbackLng: 'en', - debug: true, - whitelist: languages, - }); - -export default i18n; \ No newline at end of file diff --git a/widget/embedded/src/index.ts b/widget/embedded/src/index.ts new file mode 100644 index 0000000000..5c64a666d1 --- /dev/null +++ b/widget/embedded/src/index.ts @@ -0,0 +1,177 @@ +import type { WidgetProps } from './containers/Widget'; +import type { ConnectedWallet } from './store/slices/wallets'; +import type { + BlockchainAndTokenConfig, + QuoteEventData, + Tokens, + UiEventData, + WalletEventData, + WalletInfoWithExtra, + WidgetColors, + WidgetColorsKeys, + WidgetConfig, + WidgetTheme, + WidgetVariant, +} from './types'; +import type { + PendingSwapWithQueueID, + Route, + RouteEvent, + RouteEventData, + RouteExecutionEvents, + RouteFailedEvent, + RouteStartedEvent, + RouteSucceededEvent, + Step, + StepApprovalTxSucceededEvent, + StepCheckStatusEvent, + StepEvent, + StepEventData, + StepFailedEvent, + StepOutputRevealedEvent, + StepStartedEvent, + StepSucceededEvent, + StepTxExecutionBlockedEvent, + StepTxExecutionUpdatedEvent, +} from '@rango-dev/queue-manager-rango-preset'; +import type { + LegacyEventHandler as HandleWalletsUpdate, + LegacyProviderInterface as ProviderInterface, +} from '@rango-dev/wallets-core/legacy'; +import type { + WalletInfo, + WalletState, + WalletType, +} from '@rango-dev/wallets-shared'; +import type { PendingSwap, PendingSwapStep } from 'rango-types'; + +import { + EventSeverity, + RouteEventType, + StepEventType, + StepExecutionBlockedEventStatus, + StepExecutionEventStatus, +} from '@rango-dev/queue-manager-rango-preset'; +import { legacyReadAccountAddress as readAccountAddress } from '@rango-dev/wallets-core/legacy'; +import { useWallets, Events as WalletEvents } from '@rango-dev/wallets-react'; +import { Networks, WalletTypes } from '@rango-dev/wallets-shared'; +import { PendingSwapNetworkStatus } from 'rango-types'; + +import { + isOnDerivationPath, + isOnNamespace, +} from './components/StatefulConnectModal'; +import { DerivationPath, Namespaces } from './components/WalletStatefulConnect'; +import { WIDGET_UI_ID as UI_ID } from './constants'; +import { SUPPORTED_FONTS } from './constants/fonts'; +import { WidgetWallets } from './containers/Wallets'; +import { Widget } from './containers/Widget'; +import { useWidget } from './containers/WidgetInfo'; +import { WidgetProvider } from './containers/WidgetProvider'; +import { useStatefulConnect } from './hooks/useStatefulConnect'; +import { useWalletList } from './hooks/useWalletList'; +import { useWidgetEvents } from './hooks/useWidgetEvents'; +import { widgetEventEmitter } from './services/eventEmitter'; +import { + WidgetEvents as MainEvents, + QuoteEventTypes, + UiEventTypes, + WalletEventTypes, + WidgetEvents, +} from './types'; +import { customizedThemeTokens } from './utils/ui'; + +export const StatefulConnect = { + DerivationPath, + Namespaces, + isOnDerivationPath, + isOnNamespace, +}; + +export type { + WidgetConfig, + WalletType, + WidgetTheme, + WidgetColors, + WidgetColorsKeys, + ProviderInterface, + BlockchainAndTokenConfig, + WidgetProps, + RouteEvent, + RouteEventData, + StepEvent, + StepEventData, + Route, + Step, + RouteStartedEvent, + RouteSucceededEvent, + RouteFailedEvent, + StepStartedEvent, + StepSucceededEvent, + StepFailedEvent, + StepTxExecutionUpdatedEvent, + StepTxExecutionBlockedEvent, + StepCheckStatusEvent, + StepApprovalTxSucceededEvent, + StepOutputRevealedEvent, + HandleWalletsUpdate, + ConnectedWallet, + Tokens, + WidgetVariant, + WalletEventData, + QuoteEventData, + UiEventData, + WalletInfoWithExtra, +}; +export { + Widget, + /** + * @deprecated Use `WidgetProvider` instead. This component will be removed in future versions. + */ + WidgetWallets, + WidgetProvider, + useWidget, + useWallets, + useStatefulConnect, + /** + * @deprecated Use `widgetEventEmitter` instead. This hook will be removed in future versions. + */ + useWidgetEvents, + useWalletList, + customizedThemeTokens, + widgetEventEmitter, + WidgetEvents, + /** + * @deprecated Use `WidgetEvents` instead. This enum will be removed in future versions. + */ + MainEvents, + QuoteEventTypes, + WalletEventTypes, + UiEventTypes, + RouteEventType, + StepEventType, + StepExecutionEventStatus, + StepExecutionBlockedEventStatus, + UI_ID, + SUPPORTED_FONTS, +}; + +// Internal type exports for Rango +export type { + WalletState, + WalletInfo, + PendingSwap, + PendingSwapWithQueueID, + PendingSwapStep, + RouteExecutionEvents, +}; + +// Internal function and enum exports for Rango +export { + readAccountAddress, + Networks, + WalletEvents, + WalletTypes, + PendingSwapNetworkStatus, + EventSeverity, +}; diff --git a/widget/embedded/src/index.tsx b/widget/embedded/src/index.tsx deleted file mode 100644 index 001fba290f..0000000000 --- a/widget/embedded/src/index.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import React from 'react'; -import { createRoot } from 'react-dom/client'; -import { BrowserRouter } from 'react-router-dom'; -import { App } from './App'; - -const container = document.getElementById('app')!; -const root = createRoot(container); -root.render( - - , - -); - -export { Widget } from './lib'; diff --git a/widget/embedded/src/languages/en.json b/widget/embedded/src/languages/en.json deleted file mode 100644 index f688661bc1..0000000000 --- a/widget/embedded/src/languages/en.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "swap": "SWAP", - "Connect Wallet": "Connect Wallet", - "Powered By": "Powered By", - "From": "You sell", - "To": "You receive", - "Balance": "Balance", - "Max": "Max", - "Chain": "Chain", - "Token": "Token", - "Source": "Source", - "Destination": "Destination", - "Select Wallet": "Connect Your Wallet" -} diff --git a/widget/embedded/src/languages/tr.json b/widget/embedded/src/languages/tr.json deleted file mode 100644 index 8216ff7af1..0000000000 --- a/widget/embedded/src/languages/tr.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "swap": "TAKAS", - "Select Wallet":"Cüzdan Seç", - "Powered By" :"Tarafından desteklenmektedir", - "Connect Wallet":"Cüzdanı Bağla", - "From":"İtibaren", - "To":"İle", - "Max":"maks.", - "Chain": "Zincir", - "Token": "Jeton" -} \ No newline at end of file diff --git a/widget/embedded/src/lib.tsx b/widget/embedded/src/lib.tsx deleted file mode 100644 index 2522f81109..0000000000 --- a/widget/embedded/src/lib.tsx +++ /dev/null @@ -1,136 +0,0 @@ -import { SwapContainer } from '@rango-dev/ui'; -import React, { useEffect, useMemo, useState } from 'react'; -import { AppRouter } from './components/AppRouter'; -import { useMetaStore } from './store/meta'; -import { Events, Provider } from '@rango-dev/wallets-core'; -import { allProviders } from '@rango-dev/provider-all'; -import { EventHandler } from '@rango-dev/wallets-core/dist/wallet'; -import { Network, WalletType } from '@rango-dev/wallets-shared'; -import { - prepareAccountsForWalletStore, - walletAndSupportedChainsNames, -} from './utils/wallets'; -import { useWalletsStore } from './store/wallets'; -import { Layout } from './components/Layout'; -import { globalFont, globalStyles } from './globalStyles'; -import { useTheme } from './hooks/useTheme'; -import { isEvmBlockchain } from 'rango-sdk'; -import { WidgetTheme, WidgetConfig, WidgetColors, BlockchainAndTokenConfig } from './types'; -import useSelectLanguage from './hooks/useSelectLanguage'; -import './i18n'; -import QueueManager from './QueueManager'; -import { useUiStore } from './store/ui'; -import { navigationRoutes } from './constants/navigationRoutes'; -import { initConfig } from './utils/configs'; - - -export {WidgetConfig, WalletType, WidgetTheme, WidgetColors, BlockchainAndTokenConfig} - -export type WidgetProps = { - config?: WidgetConfig; -}; - -export const Widget: React.FC = ({ config }) => { - globalStyles(); - globalFont(config?.theme?.fontFamily || 'Roboto'); - - const { activeTheme } = useTheme({ ...config?.theme }); - const { blockchains } = useMetaStore.use.meta(); - const disconnectWallet = useWalletsStore.use.disconnectWallet(); - const connectWallet = useWalletsStore.use.connectWallet(); - const { changeLanguage } = useSelectLanguage(); - const clearConnectedWallet = useWalletsStore.use.clearConnectedWallet(); - const [lastConnectedWalletWithNetwork, setLastConnectedWalletWithNetwork] = - useState(''); - const [disconnectedWallet, setDisconnectedWallet] = useState(); - const currentPage = useUiStore.use.currentPage(); - - const evmBasedChainNames = blockchains - .filter(isEvmBlockchain) - .map((chain) => chain.name); - - useMemo(() => { - if (config?.apiKey) { - initConfig({ - API_KEY: config?.apiKey, - }); - } - }, [config]); - - const onUpdateState: EventHandler = ( - type, - event, - value, - state, - supportedChains - ) => { - if (event === Events.ACCOUNTS) { - if (value) { - const supportedChainNames: Network[] | null = - walletAndSupportedChainsNames(supportedChains); - const data = prepareAccountsForWalletStore( - type, - value, - evmBasedChainNames, - supportedChainNames - ); - connectWallet(data); - } else { - disconnectWallet(type); - } - } - if (event === Events.ACCOUNTS && state.connected) { - const key = `${type}-${state.network}-${value}`; - - if (state.connected) { - setLastConnectedWalletWithNetwork(key); - } - } - - if (event === Events.NETWORK && state.network) { - const key = `${type}-${state.network}`; - setLastConnectedWalletWithNetwork(key); - } - }; - let providers = allProviders(); - - useEffect(() => { - const wallets = config?.wallets; - clearConnectedWallet(); - providers = !wallets - ? allProviders() - : allProviders().filter((provider) => { - const type = provider.config.type; - return wallets.find((w) => w === type); - }); - }, [config?.wallets]); - - useEffect(() => { - changeLanguage(config?.language || 'en'); - }, [config?.language]); - - return ( - -
- - - { - setDisconnectedWallet(undefined); - }} - > - - - - -
-
- ); -}; diff --git a/widget/embedded/src/libs/tabManager/index.ts b/widget/embedded/src/libs/tabManager/index.ts new file mode 100644 index 0000000000..908b1d92f7 --- /dev/null +++ b/widget/embedded/src/libs/tabManager/index.ts @@ -0,0 +1,2 @@ +export { TabManager } from './tabManager'; +export type { TabManagerInterface } from './tabManager.types'; diff --git a/widget/embedded/src/libs/tabManager/tabManager.constants.ts b/widget/embedded/src/libs/tabManager/tabManager.constants.ts new file mode 100644 index 0000000000..f247ecd889 --- /dev/null +++ b/widget/embedded/src/libs/tabManager/tabManager.constants.ts @@ -0,0 +1,3 @@ +export const TIMEOUT = 300; +export const MAXIMUM_TAB_ID = 100_000; +export const CHANNEL_NAME = 'rango-widget'; diff --git a/widget/embedded/src/libs/tabManager/tabManager.ts b/widget/embedded/src/libs/tabManager/tabManager.ts new file mode 100644 index 0000000000..c96abe5960 --- /dev/null +++ b/widget/embedded/src/libs/tabManager/tabManager.ts @@ -0,0 +1,225 @@ +import type { + Events, + ID, + Message, + TabManagerInterface, +} from './tabManager.types'; + +import { CHANNEL_NAME, MAXIMUM_TAB_ID, TIMEOUT } from './tabManager.constants'; + +export class TabManager implements TabManagerInterface { + private tabId: ID; + private state: 'not-initiated' | 'not-claimed' | 'claimed' = 'not-initiated'; + private lastTryClaim: number | undefined; + private events: Events = {}; + private channel: BroadcastChannel; + + constructor(events: Events) { + this.channel = new BroadcastChannel(CHANNEL_NAME); + this.tabId = Math.trunc(Math.random() * MAXIMUM_TAB_ID); + this.events = events; + } + + init = () => { + this.initEvents(); + void this.tryClaim(); + }; + + /** + * This is applicable when a user in an inactive tab seeks to activate that tab. + */ + forceClaim = () => { + if (!this.isClaimed()) { + const message: Message = { name: 'force-claim', candidateId: this.tabId }; + this.channel.postMessage(message); + setTimeout(() => { + if (!this.isClaimed()) { + this.claim(); + } + }, TIMEOUT); + } + }; + + isClaimed = () => { + return this.state === 'claimed'; + }; + + /** + * remove event listeners + */ + destroy = () => { + this.channel.removeEventListener('message', this.handleMessageEvent); + document.removeEventListener( + 'visibilitychange', + this.handleVisibilityChange + ); + document.removeEventListener('resume', this.handleResume); + }; + + /** + * Reacting to messages and window events to claim. + */ + private initEvents() { + this.channel.addEventListener('message', this.handleMessageEvent); + + document.addEventListener('visibilitychange', this.handleVisibilityChange); + + /** + * The "resume" event is currently supported only in certain browsers. + * It is triggered when a previously frozen tab is unfrozen and resumes execution. + * To avoid having multiple active tabs, + * if the current tab is active after the "resume" event, + * we send a signal to other tabs to verify if any of them currently claim to be active. + * If this is the case, we deactivate the current tab. + * https://developer.chrome.com/docs/web-platform/page-lifecycle-api + */ + document.addEventListener('resume', this.handleResume); + } + + /** + * Runs after a `ping` message and checks if current tab is claimed the tabs, + * if yes, it responds with `pong`, If not, it doesn't do anything. + * + * Note 1: If we receive a `ping` message, + * it means a tab is trying to claim tabs directly, usually it's the active tab. + * + * Note 2: If multiple tabs are opening at once, all of them are broadcasting `ping` + * and eventually all of them will `claim` the queue after the TIMEOUT. + * For avoiding this, we will accepts the oldest broadcasted ping. (`isPingSentBefore`) + */ + private claimedByCurrentTab(pingAt: number) { + const isPingSentBefore = this.lastTryClaim && this.lastTryClaim < pingAt; + + if (this.isClaimed() || isPingSentBefore) { + const message: Message = { + name: 'pong', + }; + this.channel.postMessage(message); + return; + } + } + + private handleMessageEvent = (event: MessageEvent) => { + const name = event.data.name; + + switch (name) { + case 'ping': + this.claimedByCurrentTab(event.data.pingAt); + break; + + case 'pong': + this.alreadyClaimedByAnotherTab(); + break; + + case 'force-claim': + this.forceRelease(event.data.candidateId); + break; + + case 'force-release': + if (this.tabId === event.data.candidateId) { + this.claim(); + } + break; + + default: + throw new Error(`${name} is not supported.`); + } + }; + + private handleVisibilityChange = async () => { + if (document.visibilityState === 'visible') { + await this.tryClaim(); + } + }; + + private handleResume = async () => { + if (this.isClaimed()) { + await this.tryClaim(); + if (!this.isClaimed()) { + this.events.onRelease?.(); + } + } + }; + /** + * Runs after receiving `pong` message, which means one of tabs already claimed the tabs. + */ + private alreadyClaimedByAnotherTab() { + this.resetLastCheck(); + } + + /** + * Try to send a `ping` message to know if the tabs `claimed` or not. + * On constructing instance, or whenever page is active we will try. + */ + private async tryClaim() { + /** + * Try to ask from possible other running tabs. + */ + this.setLastCheck(); + return new Promise((resolve) => { + setTimeout(() => { + this.check(); + resolve(); + }, TIMEOUT); + }); + } + + /** + * If `lastCheck` is exist, it means there is no other tabs which `claimed` the tabs. + * And we mark the current tab as `claimed` + */ + private check() { + if (this.state === 'not-initiated') { + this.events.onInit?.(); + } + /** + *it means we didn't get any response from other tabs, this tab can claim. + */ + if (this.lastTryClaim) { + this.claim(); + this.resetLastCheck(); + } else { + this.state = 'not-claimed'; + } + } + + private claim() { + this.state = 'claimed'; + this.events.onClaim?.(); + } + + /** + * Setting current time as `lastCheck` and broadcast a `ping` message event. + */ + private setLastCheck() { + this.lastTryClaim = Date.now(); + const message: Message = { + name: 'ping', + pingAt: this.lastTryClaim, + }; + this.channel.postMessage(message); + } + + private resetLastCheck() { + this.lastTryClaim = undefined; + } + + /** + * Upon receipt of a "force-claim" message, + * the presently active tab is expected to deactivate itself and initiate any attached callback associated with this event. + */ + private forceRelease(nextActiveTab: ID) { + if (this.isClaimed()) { + this.state = 'not-claimed'; + + this.events.onRelease?.(); + + const message: Message = { + name: 'force-release', + candidateId: nextActiveTab, + }; + + this.channel.postMessage(message); + } + } +} diff --git a/widget/embedded/src/libs/tabManager/tabManager.types.ts b/widget/embedded/src/libs/tabManager/tabManager.types.ts new file mode 100644 index 0000000000..e9f9dd39ea --- /dev/null +++ b/widget/embedded/src/libs/tabManager/tabManager.types.ts @@ -0,0 +1,29 @@ +export type ID = number; + +type PingMessage = { name: 'ping'; pingAt: number }; +type PongMessage = { name: 'pong' }; +type ForceClaimMessage = { + name: 'force-claim'; + candidateId: ID; +}; +type ForceReleaseMessage = { name: 'force-release'; candidateId: ID }; + +export type Message = + | PingMessage + | PongMessage + | ForceClaimMessage + | ForceReleaseMessage; + +export type Events = { + // Initially attempt to verify if the tab can be activated. + onInit?: () => void; + onClaim?: () => void; + onRelease?: () => void; +}; + +export interface TabManagerInterface { + init: () => void; + forceClaim: () => void; + isClaimed: () => boolean; + destroy: () => void; +} diff --git a/widget/embedded/src/mockData/pendingSwap.ts b/widget/embedded/src/mockData/pendingSwap.ts deleted file mode 100644 index e1daf6e88b..0000000000 --- a/widget/embedded/src/mockData/pendingSwap.ts +++ /dev/null @@ -1,607 +0,0 @@ -//TODO: remove mock data after queue manager integration -export const pendingSwap: any = { - creationTime: '1675837879344', - finishTime: '1675842500799', - requestId: 'c40b81cd-fdac-4dad-bfef-1c7b2cff715f', - inputAmount: '2', - wallets: { - POLYGON: { - walletType: 'metamask', - address: '0x2702d89c1c8658b49c45dd460deebcc45faec03c', - }, - SOLANA: { - walletType: 'phantom', - address: '9QoVnPEHj5HNL4cVicXUF8CVmyhBxTDqUUigVn3UPWwk', - }, - }, - status: 'success', - isPaused: false, - extraMessage: null, - extraMessageSeverity: 'info', - extraMessageDetail: '', - extraMessageErrorCode: null, - networkStatusExtraMessage: '', - networkStatusExtraMessageDetail: '', - lastNotificationTime: null, - settings: { - slippage: '13.0', - disabledSwappersIds: [ - 'PancakeSwapBsc', - 'ThorChain', - 'Horizon Bridge', - 'OneInchOptimism', - 'OneInchGnosis', - 'OneInchBsc', - 'OneInchArbitrum', - 'OpenOceanFantom', - 'SushiHarmony', - 'SushiArbitrum', - 'OkcSwap', - 'CherrySwap', - 'Osmosis', - 'SolanaWrapper', - 'Jupiter', - 'stargate', - 'AnySwap', - 'Satellite', - 'Diffusion', - 'JunoSwap', - 'PangolinSwap', - 'MMFinance', - 'CronaSwap', - 'VVSFinance', - 'MDexHeco', - 'ParaSwap Polygon', - 'ParaSwap Bsc', - 'ParaSwap Avalanche', - 'AuroraSwap', - 'Across', - 'Arbitrum Bridge', - 'TrisolarisSwap', - 'Polygon Bridge', - 'SpookySwap', - 'Rainbow Bridge', - 'Lido', - 'Symbiosis', - 'Avalanche Bridge', - 'VoltageSwap', - 'Stargate Aggregator', - 'Across Aggregator', - 'THORChain Aggregator', - 'CBridge Aggregator', - 'AnySwap Aggregator', - 'Hyphen Aggregator', - 'Optimism Bridge', - 'OolongSwap', - 'QuickSwap', - 'StellaSwap', - 'Hyphen', - 'ViperSwap', - 'cBridge v2.0', - 'FinKujira', - 'Hop', - 'BeamSwap', - 'SolarbeamSwap', - 'Sifchain', - 'Wormhole', - 'EthUniSwapV2', - 'OneInchPolygon', - ], - disabledSwappersGroups: [], - }, - simulationResult: { - outputAmount: '0.084249153', - swaps: [ - { - swapperId: 'QuickSwap', - swapperLogo: 'https://api.rango.exchange/swappers/quick-swap.png', - swapperType: 'DEX', - from: { - symbol: 'USDC', - logo: 'https://api.rango.exchange/i/ns0AMf', - blockchainLogo: 'https://api.rango.exchange/blockchains/polygon.svg', - address: '0x2791bca1f2de4661ed88a30c99a7a9449aa84174', - blockchain: 'POLYGON', - decimals: 6, - usdPrice: 0.999792, - }, - to: { - symbol: 'SOL', - logo: 'https://api.rango.exchange/i/YhJ1nK', - blockchainLogo: 'https://api.rango.exchange/blockchains/polygon.svg', - address: '0xd93f7e271cb87c23aaa73edc008a79646d1f9912', - blockchain: 'POLYGON', - decimals: 9, - usdPrice: 23.700913462284028, - }, - fromAmount: '2.000000', - fromAmountPrecision: null, - fromAmountMinValue: null, - fromAmountMaxValue: null, - fromAmountRestrictionType: null, - toAmount: '0.084249153', - fee: [ - { - asset: { - blockchain: 'POLYGON', - symbol: 'USDC', - address: '0x2791bca1f2de4661ed88a30c99a7a9449aa84174', - }, - expenseType: 'DECREASE_FROM_OUTPUT', - amount: '0.006000000000000000124900090270330110797658562660217285156250000000', - name: 'Swapper Fee', - }, - { - asset: { - blockchain: 'POLYGON', - symbol: 'MATIC', - address: null, - }, - expenseType: 'FROM_SOURCE_WALLET', - amount: '0.032758180196833611', - name: 'Network Fee', - }, - ], - estimatedTimeInSeconds: 60, - swapChainType: 'INTER_CHAIN', - routes: [ - { - nodes: [ - { - nodes: [ - { - marketName: 'QuickSwap', - marketId: 'QuickSwap', - percent: 1, - }, - ], - from: 'USDC', - fromLogo: '', - fromAddress: '0x2791bca1f2de4661ed88a30c99a7a9449aa84174', - fromBlockchain: 'POLYGON', - - to: 'SOL', - toLogo: '', - toAddress: '0xd93f7e271cb87c23aaa73edc008a79646d1f9912', - toBlockchain: 'POLYGON', - }, - ], - }, - ], - recommendedSlippage: null, - warnings: [], - timeStat: { - min: 7, - avg: 59, - max: 736, - }, - includesDestinationTx: false, - internalSwaps: null, - maxRequiredSign: 1, - fromAsset: { - blockchain: 'POLYGON', - symbol: 'USDC', - address: '0x2791bca1f2de4661ed88a30c99a7a9449aa84174', - }, - toAsset: { - blockchain: 'POLYGON', - symbol: 'SOL', - address: '0xd93f7e271cb87c23aaa73edc008a79646d1f9912', - }, - }, - { - swapperId: 'Wormhole', - swapperLogo: 'https://api.rango.exchange/swappers/wormhole.png', - swapperType: 'BRIDGE', - from: { - symbol: 'SOL', - logo: 'https://api.rango.exchange/i/YhJ1nK', - blockchainLogo: 'https://api.rango.exchange/blockchains/polygon.svg', - address: '0xd93f7e271cb87c23aaa73edc008a79646d1f9912', - blockchain: 'POLYGON', - decimals: 9, - usdPrice: 23.700913462284028, - }, - to: { - symbol: 'SOL', - logo: 'https://api.rango.exchange/i/eLHYrb', - blockchainLogo: 'https://api.rango.exchange/blockchains/solana.svg', - address: null, - blockchain: 'SOLANA', - decimals: 9, - usdPrice: 23.97093428787272, - }, - fromAmount: '0.084249153', - fromAmountPrecision: null, - fromAmountMinValue: null, - fromAmountMaxValue: null, - fromAmountRestrictionType: null, - toAmount: '0.084249153', - fee: [ - { - asset: { - blockchain: 'POLYGON', - symbol: 'MATIC', - address: null, - }, - expenseType: 'FROM_SOURCE_WALLET', - amount: '0.042205949048288939', - name: 'Network Fee', - }, - { - asset: { - blockchain: 'SOLANA', - symbol: 'SOL', - address: null, - }, - expenseType: 'FROM_DESTINATION_WALLET', - amount: '0.000070000', - name: 'Swapper Fee', - }, - ], - estimatedTimeInSeconds: 150, - swapChainType: 'INTRA_CHAIN', - routes: null, - recommendedSlippage: null, - warnings: [], - timeStat: { - min: 42, - avg: 146, - max: 5582, - }, - includesDestinationTx: true, - internalSwaps: null, - maxRequiredSign: 6, - fromAsset: { - blockchain: 'POLYGON', - symbol: 'SOL', - address: '0xd93f7e271cb87c23aaa73edc008a79646d1f9912', - }, - toAsset: { - blockchain: 'SOLANA', - symbol: 'SOL', - address: null, - }, - }, - ], - resultType: 'OK', - }, - validateBalanceOrFee: true, - steps: [ - { - id: 1, - fromBlockchain: 'POLYGON', - fromSymbol: 'USDC', - fromSymbolAddress: '0x2791bca1f2de4661ed88a30c99a7a9449aa84174', - fromDecimals: 6, - fromAmountPrecision: null, - fromAmountMinValue: null, - fromAmountMaxValue: null, - toBlockchain: 'POLYGON', - fromLogo: 'https://api.rango.exchange/i/ns0AMf', - fromBlockchainLogo: 'https://api.rango.exchange/blockchains/polygon.svg', - toBlockchainLogo: 'https://api.rango.exchange/blockchains/solana.svg', - toSymbol: 'SOL', - toSymbolAddress: '0xd93f7e271cb87c23aaa73edc008a79646d1f9912', - toDecimals: 9, - toLogo: 'https://api.rango.exchange/i/YhJ1nK', - startTransactionTime: 1675837904769, - swapperId: 'QuickSwap', - swapperLogo: 'https://api.rango.exchange/swappers/quick-swap.png', - expectedOutputAmountHumanReadable: '0.084249153', - outputAmount: '0.084206923', - status: 'success', - networkStatus: 'networkChanged', - executedTransactionId: '0xb2a6b1b497b660bd58d8583d05425ea1b89fa19efc18c9b3baa501abf5f8cee9', - externalTransactionId: null, - explorerUrl: [ - { - url: 'https://polygonscan.com/tx/0xb2a6b1b497b660bd58d8583d05425ea1b89fa19efc18c9b3baa501abf5f8cee9', - description: 'swap', - }, - ], - trackingCode: null, - cosmosTransaction: null, - solanaTransaction: null, - evmTransaction: { - type: 'EVM', - blockChain: 'POLYGON', - isApprovalTx: false, - from: '0x2702d89c1c8658b49c45dd460deebcc45faec03c', - to: '0x38F7Aa5370439E879370E24AdD063a11Bd74610D', - spender: null, - data: '0xa60fdfb60000000000000000000000002791bca1f2de4661ed88a30c99a7a9449aa84174000000000000000000000000d93f7e271cb87c23aaa73edc008a79646d1f991200000000000000000000000000000000000000000000000000000000001e84800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000a5e0829caced8ffdd4de3c43696c57f7d7a678ff0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000010438ed173900000000000000000000000000000000000000000000000000000000001e848000000000000000000000000000000000000000000000000000000000045e6b7b00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000038f7aa5370439e879370e24add063a11bd74610d0000000000000000000000000000000000000000000000000000000063e348d800000000000000000000000000000000000000000000000000000000000000020000000000000000000000002791bca1f2de4661ed88a30c99a7a9449aa84174000000000000000000000000d93f7e271cb87c23aaa73edc008a79646d1f991200000000000000000000000000000000000000000000000000000000', - value: null, - gasLimit: '0x62f20', - gasPrice: '247516799843', - nonce: null, - }, - evmApprovalTransaction: null, - transferTransaction: null, - diagnosisUrl: null, - internalSteps: null, - }, - { - id: 2, - fromBlockchain: 'POLYGON', - fromSymbol: 'SOL', - fromSymbolAddress: '0xd93f7e271cb87c23aaa73edc008a79646d1f9912', - fromDecimals: 9, - fromAmountPrecision: null, - fromAmountMinValue: null, - fromAmountMaxValue: null, - toBlockchain: 'SOLANA', - fromLogo: 'https://api.rango.exchange/i/YhJ1nK', - fromBlockchainLogo: 'https://api.rango.exchange/blockchains/polygon.svg', - toBlockchainLogo: 'https://api.rango.exchange/blockchains/solana.svg', - toSymbol: 'SOL', - toSymbolAddress: null, - toDecimals: 9, - toLogo: 'https://api.rango.exchange/i/eLHYrb', - startTransactionTime: 1675842459076, - swapperId: 'Wormhole', - swapperLogo: 'https://api.rango.exchange/swappers/wormhole.png', - expectedOutputAmountHumanReadable: '0.084249153', - outputAmount: '0.08420692', - status: 'failed', - networkStatus: 'networkChanged', - executedTransactionId: - '5MGhqrNRwRKkHGU11S37mgF7LscXWhAvwBeAWEdxcmV9AD6bNqig6iCCzC4mKBH41JBexKb6kj4axLfcH4XZQsT9', - externalTransactionId: null, - explorerUrl: [ - { - url: 'https://solscan.io/tx/2wvqHEy5hCDfpwZM5sZhBpFxXZL7p6PRqpDdCZGpGF85deGQU9oiBC9Jgoszdo8x9hjkySktGPYzubcXP8pxW3H4', - description: 'Associate Token', - }, - { - url: 'https://polygonscan.com/tx/0xcdd0c684fc203d41a0eaacfba2201ab0a48845bb6d0f0805fb4a70a0f971a599', - description: 'Transfer', - }, - { - url: 'https://solscan.io/tx/5rc5EHfMrChB749RsJew1ze35yQMddafkQqy5JFqcdKPJ6j2NiggGT7UDmFDAXzP2AwHGyFj2XjaYr7RQjjc1KmH', - description: 'Verify vaa 1', - }, - { - url: 'https://solscan.io/tx/5xNgHvdzu63fmF7uojrHuqcHC3NgErpdGiSg38X7KZ7EEjTyPWt8W1QUtuyUFcNcSjGkFGrGzfnkRUbe4Hj6oY2v', - description: 'Verify vaa 2', - }, - { - url: 'https://solscan.io/tx/3FnXLYwwpc93o2TyjKNDfiBcRDZ9W1qJVdmCjTRw3kz4Jrwjr5zQzLSbsbbBzqFNMSxBFcUDaiQ7pP4DL5coUGq', - description: 'Post vaa', - }, - { - url: 'https://solscan.io/tx/5MGhqrNRwRKkHGU11S37mgF7LscXWhAvwBeAWEdxcmV9AD6bNqig6iCCzC4mKBH41JBexKb6kj4axLfcH4XZQsT9', - description: 'Redeem', - }, - ], - trackingCode: null, - cosmosTransaction: null, - solanaTransaction: { - type: 'SOLANA', - blockChain: 'SOLANA', - from: '9QoVnPEHj5HNL4cVicXUF8CVmyhBxTDqUUigVn3UPWwk', - identifier: 'redeem', - instructions: [ - { - keys: [ - { - pubkey: '9QoVnPEHj5HNL4cVicXUF8CVmyhBxTDqUUigVn3UPWwk', - isSigner: true, - isWritable: true, - }, - { - pubkey: 'DapiQYH3BGonhN8cngWcXQ6SrqSm3cwysoznoHr6Sbsx', - isSigner: false, - isWritable: false, - }, - { - pubkey: 'Wf8aqunuZ9y1tprCihMateij299Pa57XL15a6EQz9qt', - isSigner: false, - isWritable: false, - }, - { - pubkey: 'FTWSFuqyc6B5BbarBzuHdBofA2ks12eyRNmUfKmDiUN1', - isSigner: false, - isWritable: true, - }, - { - pubkey: 'J6fNPeeJc1E2zDRUtvD9aaC9kBsEq7JaFr1oa97DAJhj', - isSigner: false, - isWritable: false, - }, - { - pubkey: '8nUPRxuXUJPbWiCbqCPrVLkmXqR8LdifLrRW3VjCQDhZ', - isSigner: false, - isWritable: true, - }, - { - pubkey: '8nUPRxuXUJPbWiCbqCPrVLkmXqR8LdifLrRW3VjCQDhZ', - isSigner: false, - isWritable: true, - }, - { - pubkey: '2nQNF8F9LLWMqdjymiLK2u8HoHMvYa4orCXsp3w65fQ2', - isSigner: false, - isWritable: true, - }, - { - pubkey: 'So11111111111111111111111111111111111111112', - isSigner: false, - isWritable: false, - }, - { - pubkey: 'GugU1tP7doLeTw9hQP51xRJyS8Da1fWxuiy2rVrnMD2m', - isSigner: false, - isWritable: false, - }, - { - pubkey: 'SysvarRent111111111111111111111111111111111', - isSigner: false, - isWritable: false, - }, - { - pubkey: '11111111111111111111111111111111', - isSigner: false, - isWritable: false, - }, - { - pubkey: 'worm2ZoG2kUd4vFXhvjh93UUH596ayRfgQ2MgjNMTth', - isSigner: false, - isWritable: false, - }, - { - pubkey: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA', - isSigner: false, - isWritable: false, - }, - ], - programId: 'wormDTUJ6AWPNvk59vGQbDvGJmqbDTdgWgAqcLBCgUb', - data: [2], - }, - { - keys: [ - { - pubkey: '9QoVnPEHj5HNL4cVicXUF8CVmyhBxTDqUUigVn3UPWwk', - isSigner: true, - isWritable: true, - }, - { - pubkey: '72pK2FqwMYPr9ajAhzLNQq8e5S2Rf33MGpVXxdXwCT6V', - isSigner: true, - isWritable: true, - }, - ], - programId: '11111111111111111111111111111111', - data: [ - 0, 0, 0, 0, -16, 29, 31, 0, 0, 0, 0, 0, -91, 0, 0, 0, 0, 0, 0, 0, 6, -35, -10, -31, - -41, 101, -95, -109, -39, -53, -31, 70, -50, -21, 121, -84, 28, -76, -123, -19, 95, - 91, 55, -111, 58, -116, -11, -123, 126, -1, 0, -87, - ], - }, - { - keys: [ - { - pubkey: '72pK2FqwMYPr9ajAhzLNQq8e5S2Rf33MGpVXxdXwCT6V', - isSigner: false, - isWritable: true, - }, - { - pubkey: 'So11111111111111111111111111111111111111112', - isSigner: false, - isWritable: false, - }, - { - pubkey: '9QoVnPEHj5HNL4cVicXUF8CVmyhBxTDqUUigVn3UPWwk', - isSigner: false, - isWritable: false, - }, - { - pubkey: 'SysvarRent111111111111111111111111111111111', - isSigner: false, - isWritable: false, - }, - ], - programId: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA', - data: [1], - }, - { - keys: [ - { - pubkey: '8nUPRxuXUJPbWiCbqCPrVLkmXqR8LdifLrRW3VjCQDhZ', - isSigner: false, - isWritable: true, - }, - { - pubkey: '72pK2FqwMYPr9ajAhzLNQq8e5S2Rf33MGpVXxdXwCT6V', - isSigner: false, - isWritable: true, - }, - { - pubkey: '9QoVnPEHj5HNL4cVicXUF8CVmyhBxTDqUUigVn3UPWwk', - isSigner: true, - isWritable: false, - }, - ], - programId: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA', - data: [3, 72, -27, 4, 5, 0, 0, 0, 0], - }, - { - keys: [ - { - pubkey: '72pK2FqwMYPr9ajAhzLNQq8e5S2Rf33MGpVXxdXwCT6V', - isSigner: false, - isWritable: true, - }, - { - pubkey: '9QoVnPEHj5HNL4cVicXUF8CVmyhBxTDqUUigVn3UPWwk', - isSigner: false, - isWritable: true, - }, - { - pubkey: '9QoVnPEHj5HNL4cVicXUF8CVmyhBxTDqUUigVn3UPWwk', - isSigner: true, - isWritable: false, - }, - ], - programId: 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA', - data: [9], - }, - ], - recentBlockhash: '2wBCvR3jVNj6wzL8vHSuqTRtxBYiwhtoY6Gkp6WaBxSG', - signatures: [ - { - publicKey: '72pK2FqwMYPr9ajAhzLNQq8e5S2Rf33MGpVXxdXwCT6V', - signature: [ - -116, 17, -5, 86, -122, 120, -7, -53, -29, -15, -70, -100, 16, 48, 113, -42, 8, 126, - 75, -13, 63, -31, -17, 1, 74, 85, 77, 90, 98, -15, 104, 63, 4, -74, 45, -3, -3, -117, - -24, -56, 20, -89, -40, 33, 125, -120, -44, -75, 17, 69, 20, -48, 106, 48, 16, -19, - 83, 123, -77, 93, -20, -27, -77, 7, - ], - }, - ], - serializedMessage: null, - }, - evmTransaction: null, - evmApprovalTransaction: null, - transferTransaction: null, - diagnosisUrl: null, - internalSteps: [ - { - name: 'associate token address', - state: 'SUCCESSED', - current: false, - }, - { - name: 'transfer', - state: 'SUCCESSED', - current: false, - }, - { - name: 'signed vaa', - state: 'SUCCESSED', - current: false, - }, - { - name: 'verify vaa#1', - state: 'SUCCESSED', - current: false, - }, - { - name: 'verify vaa#2', - state: 'SUCCESSED', - current: false, - }, - { - name: 'post vaa', - state: 'SUCCESSED', - current: false, - }, - { - name: 'redeem', - state: 'SUCCESSED', - current: true, - }, - ], - }, - ], -}; diff --git a/widget/embedded/src/pages/AddCustomTokenPage.tsx b/widget/embedded/src/pages/AddCustomTokenPage.tsx new file mode 100644 index 0000000000..c3982b6e05 --- /dev/null +++ b/widget/embedded/src/pages/AddCustomTokenPage.tsx @@ -0,0 +1,214 @@ +import { i18n } from '@lingui/core'; +import { + Alert, + Button, + darkTheme, + Divider, + DoneIcon, + MessageBox, + styled, + TextField, + Typography, +} from '@rango-dev/ui'; +import { type Token } from 'rango-sdk'; +import React, { useEffect, useState } from 'react'; +import { useNavigate, useSearchParams } from 'react-router-dom'; + +import { BlockchainSelectorButton } from '../components/BlockchainSelectorButton'; +import { WatermarkedModal } from '../components/common/WatermarkedModal'; +import { CustomTokenModal } from '../components/CustomTokenModal'; +import { Layout, PageContainer } from '../components/Layout'; +import { navigationRoutes } from '../constants/navigationRoutes'; +import { SearchParams } from '../constants/searchParams'; +import { useFetchCustomToken } from '../hooks/useFetchCustomToken'; +import { useNavigateBack } from '../hooks/useNavigateBack'; +import { useAppStore } from '../store/AppStore'; +import { getContainer } from '../utils/common'; +import { findBlockchain, isValidTokenAddress } from '../utils/meta'; + +const Content = styled('div', { + display: 'flex', + justifyContent: 'space-between', + flexDirection: 'column', + flex: 1, + '& ._text-field': { + padding: '$4 $10', + backgroundColor: '$neutral300', + [`.${darkTheme} &`]: { + backgroundColor: '$neutral400', + }, + borderRadius: '$sm', + height: '$40', + }, +}); +const CUSTOM_TOKEN_REFRESH_DELAY = 1000; + +export function AddCustomTokenPage() { + const navigate = useNavigate(); + const [searchParams] = useSearchParams(); + const navigateBack = useNavigateBack(); + const { setCustomToken } = useAppStore(); + const blockchains = useAppStore().blockchains(); + + const blockchainName = searchParams.get(SearchParams.BLOCKCHAIN) || ''; + const blockchain = findBlockchain(blockchainName, blockchains); + const [address, setAddress] = useState(''); + const [isOpenErrorModal, setIsOpenErrorModal] = useState(false); + const [token, setToken] = useState(); + const { fetchCustomToken, loading, error } = useFetchCustomToken(); + const [networkError, setNetworkError] = useState(''); + const isValidAddress = + !!blockchain && isValidTokenAddress(blockchain, address); + const isImportDisabled = !blockchain || !address || !isValidAddress; + + const getCustomToken = async () => { + if (blockchain) { + try { + const res = await fetchCustomToken({ + blockchain: blockchainName, + tokenAddress: address, + }); + setNetworkError(''); + if (!!res) { + setToken(res); + } + // eslint-disable-next-line @typescript-eslint/no-explicit-any + } catch (error: any) { + if (error.message === 'Failed to fetch') { + setNetworkError(i18n.t('Network Error')); + setIsOpenErrorModal(true); + } + } + } + }; + + const closeErrorModal = () => { + if (!!error) { + setAddress(''); + } + setIsOpenErrorModal(false); + }; + + const handleErrorModalButtonClick = async () => { + if (!!networkError) { + setTimeout(async () => { + await getCustomToken(); + }, CUSTOM_TOKEN_REFRESH_DELAY); + } + closeErrorModal(); + }; + + useEffect(() => { + if (!!error) { + setIsOpenErrorModal(true); + } + }, [error]); + return ( + + + +
+ + navigate(navigationRoutes.blockchains, { replace: true }) + } + hasLogo={!!blockchain?.logo} + value={ + !!blockchain + ? { + name: blockchain.displayName, + logo: blockchain.logo, + } + : undefined + } + title={i18n.t('Select chain')} + placeholder={i18n.t('Select chain')} + /> + + + {i18n.t('Enter Address')} + + + + } + onChange={(e) => setAddress(e.target.value)} + /> + {!isValidAddress && !!address && ( + <> + + + + )} +
+ + +
+ + + + + {/* eslint-disable-next-line jsx-id-attribute-enforcement/missing-ids */} + + + + {blockchain && token && ( + { + if (token) { + setCustomToken(token); + setToken(undefined); + navigateBack(); + } + }} + onClose={() => setToken(undefined)} + open={!!blockchain && !!token} + /> + )} +
+
+ ); +} diff --git a/widget/embedded/src/pages/ConfirmSwapPage.tsx b/widget/embedded/src/pages/ConfirmSwapPage.tsx index ec6a50f6cb..7f26534060 100644 --- a/widget/embedded/src/pages/ConfirmSwapPage.tsx +++ b/widget/embedded/src/pages/ConfirmSwapPage.tsx @@ -1,189 +1,311 @@ -import React, { useEffect } from 'react'; +/* eslint-disable @typescript-eslint/no-magic-numbers */ +import type { + ConfirmSwap, + ConfirmSwapFetchResult, +} from '../hooks/useConfirmSwap/useConfirmSwap.types'; + +import { i18n } from '@lingui/core'; +import { useManager } from '@rango-dev/queue-manager-react'; +import { + Alert, + Button, + css, + Divider, + IconButton, + styled, + Typography, + WalletIcon, +} from '@rango-dev/ui'; +import React, { useEffect, useLayoutEffect, useRef, useState } from 'react'; import { useNavigate } from 'react-router-dom'; -import { useBestRouteStore } from '../store/bestRoute'; -import { useWalletsStore } from '../store/wallets'; -import { useWallets } from '@rango-dev/wallets-core'; + +import { ConfirmWalletsModal } from '../components/ConfirmWalletsModal/ConfirmWalletsModal'; +import { RefreshButton } from '../components/HeaderButtons/RefreshButton'; +import { Layout, PageContainer } from '../components/Layout'; +import { QuoteWarningsAndErrors } from '../components/QuoteWarningsAndErrors'; import { navigationRoutes } from '../constants/navigationRoutes'; -import { - getKeplrCompatibleConnectedWallets, - getRequiredChains, - getSelectableWallets, - isExperimentalChain, -} from '../utils/wallets'; -import { getTotalFeeInUsd, requiredWallets } from '../utils/swap'; -import { decimalNumber, numberToString } from '../utils/numbers'; -import { useMetaStore } from '../store/meta'; -import { Network, WalletType } from '@rango-dev/wallets-shared'; -import { useNavigateBack } from '../hooks/useNavigateBack'; -import { TokenPreview } from '../components/TokenPreview'; -// @ts-ignore // TODO: fix error in tsc build -import { t } from 'i18next'; -import { Spacer, ConfirmSwap } from '@rango-dev/ui'; -import RoutesOverview from '../components/RoutesOverview'; -import { useManager } from '@rango-dev/queue-manager-react'; +import { QuoteInfo } from '../containers/QuoteInfo'; import { useConfirmSwap } from '../hooks/useConfirmSwap'; -import { useSettingsStore } from '../store/settings'; +import { useAppStore } from '../store/AppStore'; +import { useQuoteStore } from '../store/quote'; import { useUiStore } from '../store/ui'; -import { ConfirmSwapErrorTypes } from '../types'; -import { ConfirmSwapErrors } from '../components/ConfirmSwapErrors'; -import { ConfirmSwapWarnings } from '../components/ConfirmSwapWarnings'; -import { ConfirmSwapExtraMessages } from '../components/warnings/ConfirmSwapExtraMessages'; -import { getBestRouteStatus } from '../utils/routing'; -import { PercentageChange } from '../components/PercentageChange'; +import { isQuoteWarningConfirmationRequired } from '../utils/quote'; +import { joinList } from '../utils/ui'; + +const Buttons = styled('div', { + width: '100%', + display: 'flex', + justifyContent: 'space-between', + [`& ${IconButton}`]: { + width: '$48', + height: '$48', + }, +}); + +const confirmBtnStyles = css({ + flexGrow: 1, + paddingRight: '$10', +}); + +const iconStyles = css({ + width: '$24', + height: '$24', + display: 'flex', + justifyContent: 'center', + alignItems: 'center', +}); + +const descriptionStyles = css({ + display: 'flex', + justifyContent: 'space-between', + alignItems: 'center', +}); export function ConfirmSwapPage() { + //TODO: move component's logics to a custom hook + const { + selectedQuote, + setInputAmount, + selectedWallets, + quoteWalletsConfirmed, + customDestination, + quoteWarningsConfirmed, + } = useQuoteStore(); const navigate = useNavigate(); - const { navigateBackFrom } = useNavigateBack(); - const bestRoute = useBestRouteStore.use.bestRoute(); - const fetchingBestRoute = useBestRouteStore.use.loading(); - const fetchingBestRouteError = useBestRouteStore.use.error(); - const setSelectedSwap = useUiStore.use.setSelectedSwap(); - const { blockchains, tokens } = useMetaStore.use.meta(); - const accounts = useWalletsStore.use.accounts(); - const selectedWallets = useWalletsStore.use.selectedWallets(); - const initSelectedWallets = useWalletsStore.use.initSelectedWallets(); - const setSelectedWallet = useWalletsStore.use.setSelectedWallet(); - const slippage = useSettingsStore.use.slippage(); - const customSlippage = useSettingsStore.use.customSlippage(); - const inputUsdValue = useBestRouteStore.use.inputUsdValue(); - const outputUsdValue = useBestRouteStore.use.outputUsdValue(); - const setInputAmount = useBestRouteStore.use.setInputAmount(); - - const bestRouteloadingStatus = getBestRouteStatus( - fetchingBestRoute, - !!fetchingBestRouteError - ); + const [dbErrorMessage, setDbErrorMessage] = useState(''); + const showWalletsOnInit = !quoteWalletsConfirmed; + const [showWallets, setShowWallets] = useState(false); + const [isConfirming, setIsConfirming] = useState(false); + const { isActiveTab } = useUiStore(); + const disabledLiquiditySources = useAppStore().getDisabledLiquiditySources(); + const prevDisabledLiquiditySources = useRef(disabledLiquiditySources); const { manager } = useManager(); - const { loading, errors, warnings, confirmSwap } = useConfirmSwap(); + const { + fetch: confirmSwap, + loading: fetchingConfirmationQuote, + cancelFetch, + } = useConfirmSwap(); + const [confirmSwapResult, setConfirmSwapResult] = + useState({ + swap: null, + error: null, + warnings: null, + }); + const [showQuoteWarningModal, setShowQuoteWarningModal] = useState(false); - const selectedSlippage = customSlippage || slippage; + const onConfirmSwap: ConfirmSwap['fetch'] = async ({ + selectedWallets, + customDestination, + }) => { + const result = await confirmSwap?.({ selectedWallets, customDestination }); - const showHighSlippageWarning = !errors.find( - (error) => error.type === ConfirmSwapErrorTypes.INSUFFICIENT_SLIPPAGE - ); + setConfirmSwapResult(result); + return result; + }; - const { getWalletInfo, connect } = useWallets(); - const confirmDisabled = - fetchingBestRoute || - !requiredWallets(bestRoute).every((chain) => - selectedWallets.map((wallet) => wallet.chain).includes(chain) - ); + const addNewSwap = async () => { + if (confirmSwapResult.swap && quoteWalletsConfirmed) { + try { + await manager?.create( + 'swap', + { swapDetails: confirmSwapResult.swap }, + { id: confirmSwapResult.swap.requestId } + ); + + const swap_url = `../${navigationRoutes.swaps}/${confirmSwapResult.swap.requestId}`; + navigate(swap_url, { + replace: true, + }); + setTimeout(() => { + setInputAmount(''); + }, 0); + } catch (e) { + setDbErrorMessage('Error: ' + (e as any)?.message); + } + } + }; + + const onConfirm = async () => { + setIsConfirming(true); + await addNewSwap(); + setIsConfirming(false); + }; + + const onStartConfirmSwap = async () => { + const shouldShowWarningModal = + confirmSwapResult.warnings?.quote && + isQuoteWarningConfirmationRequired(confirmSwapResult.warnings.quote) && + !quoteWarningsConfirmed; - const firstStep = bestRoute?.result?.swaps[0]; - const lastStep = - bestRoute?.result?.swaps[bestRoute?.result?.swaps.length - 1]; + if (shouldShowWarningModal) { + setShowQuoteWarningModal(true); + } else { + await onConfirm(); + } + }; + + const onRefresh = async () => { + setConfirmSwapResult({ + error: null, + swap: null, + warnings: null, + }); + confirmSwap({ selectedWallets, customDestination }) + .then((res) => { + setConfirmSwapResult(res); + }) + .catch((error) => console.error(error)); + }; + + useEffect(() => { + const disabledLiquiditySourceReset = + !!prevDisabledLiquiditySources.current.length && + !disabledLiquiditySources.length; + if (disabledLiquiditySourceReset) { + void onRefresh(); + } + prevDisabledLiquiditySources.current = disabledLiquiditySources; + }, [disabledLiquiditySources.length]); + + useEffect(() => { + if (showWalletsOnInit) { + cancelFetch(); + } + }, [showWalletsOnInit]); - const fromAmount = decimalNumber(firstStep?.fromAmount, 3); - const toAmount = decimalNumber(lastStep?.toAmount, 3); useEffect(() => { - initSelectedWallets(); + if (showWalletsOnInit) { + setShowWallets(showWalletsOnInit); + } + }, [showWalletsOnInit]); + + useEffect(() => { + if (!showWalletsOnInit) { + confirmSwap({ selectedWallets, customDestination }) + .then((result) => setConfirmSwapResult(result)) + .catch((error) => console.error(error)); + } }, []); - const selectableWallets = getSelectableWallets( - accounts, - selectedWallets, - getWalletInfo - ); + useLayoutEffect(() => { + if (!selectedQuote?.requestId) { + navigate(`../${location.search}`); + } + }, [selectedQuote?.requestId]); - const handleConnectChain = (wallet: string) => { - const network = wallet as Network; - getKeplrCompatibleConnectedWallets(selectableWallets).forEach( - (compatibleWallet: WalletType) => connect?.(compatibleWallet, network) - ); - }; + const quoteWarning = confirmSwapResult.warnings?.quote ?? null; + const quoteError = confirmSwapResult.error; + const alerts = []; + if (dbErrorMessage) { + alerts.push(); + } - const totalFeeInUsd = getTotalFeeInUsd(bestRoute, tokens); + if (quoteWarning || quoteError) { + const settings_url = `../${navigationRoutes.settings}`; + alerts.push( + setShowQuoteWarningModal(true)} + onCloseWarningModal={() => setShowQuoteWarningModal(false)} + onConfirmWarningModal={async () => { + setShowQuoteWarningModal(false); + await addNewSwap(); + }} + onChangeSettings={() => navigate(settings_url)} + /> + ); + } return ( - { - confirmSwap?.().then((swap) => { - if (swap) { - manager?.create( - 'swap', - { swapDetails: swap }, - { id: swap.requestId } - ); - setSelectedSwap(swap.requestId); - navigate(navigationRoutes.swaps + `/${swap.requestId}`, { - replace: true, - }); - setTimeout(() => { - setInputAmount(''); - }, 0); - } - }); + { + const wallets_url = `../${navigationRoutes.wallets}`; + navigate(wallets_url); + }, }} - onChange={(wallet) => setSelectedWallet(wallet)} - confirmDisabled={confirmDisabled} - handleConnectChain={(wallet) => handleConnectChain(wallet)} - isExperimentalChain={(wallet) => - getKeplrCompatibleConnectedWallets(selectableWallets).length > 0 - ? isExperimentalChain(blockchains, wallet) - : false - } - previewInputs={ - <> - - - - } - /> - - } - previewRoutes={ - +
+ +
+ + + + + }> + {showWallets && ( + setShowWallets(false)} + onCancel={cancelFetch} + loading={fetchingConfirmationQuote} + onCheckBalance={onConfirmSwap} /> - } - loading={loading} - errors={ConfirmSwapErrors(errors)} - warnings={ConfirmSwapWarnings(warnings)} - extraMessages={ - showHighSlippageWarning && ( - - ) - } - confirmButtonTitle={ - warnings.length > 0 || errors.length > 0 - ? 'Proceed anyway!' - : 'Confirm swap!' - } - /> + )} + + +
+ + {i18n.t('You get')} + +
+ +
+
+ + + {joinList( + alerts.map((alert, index) => ({ + element: alert, + key: `alert-${index}`, + })), + + )} + {alerts.length > 0 ? : null} + + +
+
); } diff --git a/widget/embedded/src/pages/CustomTokensPage.tsx b/widget/embedded/src/pages/CustomTokensPage.tsx new file mode 100644 index 0000000000..03917764d5 --- /dev/null +++ b/widget/embedded/src/pages/CustomTokensPage.tsx @@ -0,0 +1,188 @@ +import type { Token } from 'rango-sdk'; + +import { i18n } from '@lingui/core'; +import { + Button, + CustomTokensZeroStateDarkIcon, + CustomTokensZeroStateIcon, + DeleteIcon, + Divider, + IconButton, + MessageBox, + NotFound, + styled, +} from '@rango-dev/ui'; +import React, { useState } from 'react'; +import { useNavigate } from 'react-router-dom'; + +import { WatermarkedModal } from '../components/common/WatermarkedModal'; +import { Layout, PageContainer } from '../components/Layout'; +import { SearchInput } from '../components/SearchInput'; +import { TokenList } from '../components/TokenList'; +import { navigationRoutes } from '../constants/navigationRoutes'; +import { useTheme } from '../hooks/useTheme'; +import { useAppStore } from '../store/AppStore'; +import { useQuoteStore } from '../store/quote'; +import { containsText, getContainer } from '../utils/common'; +import { createTokenHash } from '../utils/meta'; + +const Content = styled('div', { + display: 'flex', + justifyContent: 'space-between', + flexDirection: 'column', + flex: 1, +}); +const NotFoundContent = styled('div', { + display: 'flex', + flexDirection: 'column', + alignItems: 'center', + justifyContent: 'center', + flex: '0.75', +}); +const DeleteIconButton = styled(IconButton, { + '&:hover': { + '& svg': { + color: '$secondary550', + }, + }, +}); +export function CustomTokensPage() { + const [searchedFor, setSearchedFor] = useState(''); + const { deleteCustomToken } = useAppStore(); + const customTokens = useAppStore().customTokens(); + const { fromToken, toToken, setFromToken, setToToken } = useQuoteStore(); + const { mode } = useTheme({}); + const navigate = useNavigate(); + const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false); + const [selectedToken, setSelectedToken] = useState(); + const handleSearch = (event: React.ChangeEvent) => { + const value = event.target.value; + setSearchedFor(value); + }; + const isDarkTheme = mode === 'dark'; + + const customTokensResults = customTokens.filter( + (token) => + containsText(token.symbol, searchedFor) || + containsText(token.address || '', searchedFor) || + containsText(token.name || '', searchedFor) + ); + + const handleDeleteCustomToken = () => { + if (selectedToken) { + const toTokenHash = toToken ? createTokenHash(toToken) : null; + const fromTokenHash = fromToken ? createTokenHash(fromToken) : null; + const selectedTokenHash = createTokenHash(selectedToken); + + if (toTokenHash === selectedTokenHash) { + setToToken({ token: null }); + } else if (fromTokenHash === selectedTokenHash) { + setFromToken({ token: null }); + } + deleteCustomToken(selectedToken); + } + setIsDeleteModalOpen(false); + }; + + return ( + + + + {!!customTokens.length ? ( + <> + + + ( + { + setIsDeleteModalOpen(true); + setSelectedToken(token); + }}> + + + )} + /> + + ) : ( + + + ) : ( + + ) + } + title={i18n.t('No custom tokens')} + description={i18n.t( + 'press the button to add your custom token' + )} + /> + + )} + + + + + setIsDeleteModalOpen(false)} + container={getContainer()}> + + + + + + + + + + + + ); +} diff --git a/widget/embedded/src/pages/HistoryPage.tsx b/widget/embedded/src/pages/HistoryPage.tsx index 720e20431a..83c4b018df 100644 --- a/widget/embedded/src/pages/HistoryPage.tsx +++ b/widget/embedded/src/pages/HistoryPage.tsx @@ -1,32 +1,259 @@ -import { History } from '@rango-dev/ui'; +import { i18n } from '@lingui/core'; import { useManager } from '@rango-dev/queue-manager-react'; -import React from 'react'; +import { + Button, + darkTheme, + Divider, + MessageBox, + NotFound, + styled, + Typography, +} from '@rango-dev/ui'; +import { + type PendingSwap, + type PendingSwapStep, + TransactionStatus, +} from 'rango-types'; +import React, { useMemo, useState } from 'react'; import { useNavigate } from 'react-router-dom'; -import { navigationRoutes } from '../constants/navigationRoutes'; -import { useNavigateBack } from '../hooks/useNavigateBack'; -import { getPendingSwaps } from '../utils/queue'; -import { useUiStore } from '../store/ui'; + +import { WatermarkedModal } from '../components/common/WatermarkedModal'; +import { FilterSelector } from '../components/FilterSelector'; +import { SuffixContainer } from '../components/HeaderButtons/HeaderButtons.styles'; +import { HistoryGroupedList } from '../components/HistoryGroupedList'; +import { NotFoundContainer } from '../components/HistoryGroupedList/HistoryGroupedList.styles'; +import { Layout, PageContainer } from '../components/Layout'; +import { SearchInput } from '../components/SearchInput'; +import { getContainer } from '../utils/common'; import { groupSwapsByDate } from '../utils/date'; +import { containsText } from '../utils/numbers'; +import { getPendingSwaps } from '../utils/queue'; + +const HistoryGroupedListContainer = styled('div', { + overflowY: 'visible', + width: '100%', + display: 'flex', + flexDirection: 'column', + gap: 15, + height: '100%', +}); + +const SearchAndFilterBar = styled('div', { + display: 'flex', + justifyContent: 'center', + alignItems: 'center', +}); + +const Description = styled('div', { + '._typography': { + color: '$neutral700', + [`.${darkTheme}&`]: { + color: '$neutral900', + }, + }, +}); + +const transactionStatusFilters = [ + { + id: TransactionStatus.SUCCESS, + title: i18n.t('Complete'), + }, + { + id: TransactionStatus.RUNNING, + title: i18n.t('Running'), + }, + { id: TransactionStatus.FAILED, title: i18n.t('Failed') }, +]; + +const isStepContainsText = (steps: PendingSwapStep[], value: string) => { + if (!steps?.length) { + return false; + } + return steps.filter( + (step) => + containsText(step.fromBlockchain, value) || + containsText(step.toBlockchain, value) || + containsText(step.toSymbol, value) || + containsText(step.fromSymbol, value) + ).length; +}; export function HistoryPage() { - const setSelectedSwap = useUiStore.use.setSelectedSwap(); const navigate = useNavigate(); - const { navigateBackFrom } = useNavigateBack(); const { manager, state } = useManager(); - const pendingSwaps = getPendingSwaps(manager).map(({ swap }) => swap); - + const list: PendingSwap[] = getPendingSwaps(manager).map(({ swap }) => swap); + const [searchedFor, setSearchedFor] = useState(''); + const [openFilterSelector, setOpenFilterSelector] = useState(false); const loading = !state.loadedFromPersistor; + const [filterBy, setFilterBy] = useState(''); + const [openClearModal, setOpenClearModal] = useState(false); + const handleSearch = (event: React.ChangeEvent) => { + const value = event.target.value; + setSearchedFor(value); + }; + + const filteredList = useMemo(() => { + if (!searchedFor && !filterBy) { + return list; + } + + return list.filter((swap) => { + const { inputAmount, status, steps, requestId } = swap; + + const matchesSearch = + !searchedFor || + containsText(inputAmount, searchedFor) || + containsText(status, searchedFor) || + isStepContainsText(steps, searchedFor) || + containsText(requestId, searchedFor); + + const matchesFilter = !filterBy || filterBy === status; + + return matchesSearch && matchesFilter; + }); + }, [list, searchedFor, filterBy]); + + const isEmpty = !filteredList?.length && !loading; + + const onCloseModal = () => setOpenClearModal(false); + const onClear = async () => { + try { + await manager?.clearQueue(); + + setOpenClearModal(false); + } catch (e) { + console.log(e); + } + }; + const isClearButtonDisabled = useMemo(() => { + return !list.some( + (swap) => + swap.status === TransactionStatus.SUCCESS || + swap.status === TransactionStatus.FAILED + ); + }, [list]); return ( - { - setSelectedSwap(requestId); - navigate(navigationRoutes.swaps + `/${requestId}`, { replace: true }); - }} - onBack={navigateBackFrom.bind(null, navigationRoutes.swaps)} - /> + + + + ), + }}> + + + + + + setOpenFilterSelector(open)} + onClickItem={(id) => setFilterBy(id)} + list={transactionStatusFilters} + /> + + + + + {isEmpty && ( + + + + + )} + {!isEmpty && ( + + )} + + + + + + + {i18n.t( + 'Proceeding will remove all successful and failed transactions from the widget. Do you want to continue?' + )} + + + + + {i18n.t( + 'Note: This does not erase your transaction history on the chain; it only removes them here.' + )} + + + } + /> + + + + + + ); } diff --git a/widget/embedded/src/pages/Home.tsx b/widget/embedded/src/pages/Home.tsx index fef1e5fd30..47c185021e 100644 --- a/widget/embedded/src/pages/Home.tsx +++ b/widget/embedded/src/pages/Home.tsx @@ -1,225 +1,247 @@ -import { - Alert, - BestRoute, - Button, - styled, - Typography, - VerticalSwapIcon, - Header, -} from '@rango-dev/ui'; -import React, { useEffect, useState } from 'react'; -import { useInRouterContext, useNavigate } from 'react-router-dom'; -import { TokenInfo } from '../components/TokenInfo'; -import { fetchBestRoute, useBestRouteStore } from '../store/bestRoute'; -import { BottomLogo } from '../components/BottomLogo'; -import { SwithFromAndTo } from '../components/SwitchFromAndTo'; -import { Footer } from '../components/Footer'; -import { navigationRoutes } from '../constants/navigationRoutes'; -import { useMetaStore } from '../store/meta'; -import { useWalletsStore } from '../store/wallets'; -import { errorMessages } from '../constants/errors'; -import { - getSwapButtonState, - getOutputRatio, - hasLimitError, - outputRatioHasWarning, - canComputePriceImpact, - LimitErrorMessage, - getTotalFeeInUsd, - hasHighFee, -} from '../utils/swap'; -import { - numberToString, - secondsToString, - totalArrivalTime, -} from '../utils/numbers'; +import type { SelectedQuote } from '../types'; + +import { i18n } from '@lingui/core'; +import { Button, Divider, styled, WarningIcon } from '@rango-dev/ui'; import BigNumber from 'bignumber.js'; +import React, { useEffect, useState } from 'react'; +import { useNavigate } from 'react-router-dom'; + import { HeaderButtons } from '../components/HeaderButtons'; +import { Layout, PageContainer } from '../components/Layout'; +import { QuoteWarningsAndErrors } from '../components/QuoteWarningsAndErrors'; +import { SameTokensWarning } from '../components/SameTokensWarning'; +import { navigationRoutes } from '../constants/navigationRoutes'; +import { ExpandedQuotes } from '../containers/ExpandedQuotes'; +import { Inputs } from '../containers/Inputs'; +import { QuoteInfo } from '../containers/QuoteInfo'; +import useScreenDetect from '../hooks/useScreenDetect'; +import { useSwapInput } from '../hooks/useSwapInput'; +import { useAppStore } from '../store/AppStore'; +import { useQuoteStore } from '../store/quote'; import { useUiStore } from '../store/ui'; -import { getFormatedBestRoute } from '../utils/routing'; +import { UiEventTypes } from '../types'; +import { isVariantExpandable } from '../utils/configs'; +import { emitPreventableEvent } from '../utils/events'; +import { getSwapButtonState, isTokensIdentical } from '../utils/swap'; -const Container = styled('div', { +const MainContainer = styled('div', { display: 'flex', - flexDirection: 'column', -}); - -const FromContainer = styled('div', { - position: 'relative', - paddingBottom: '$12', -}); - -const SwitchButtonContainer = styled('div', { - position: 'absolute', - bottom: '-12px', - left: '50%', - transform: 'translate(-50%, 10%)', -}); - -const BestRouteContainer = styled('div', { - width: '100%', - paddingTop: '$16', -}); - -const Alerts = styled('div', { - width: '100%', - paddingTop: '$16', + alignItems: 'flex-start', + maxHeight: 700, + '& .footer__alert': { + paddingTop: '0 !important', + }, }); +export const TIME_TO_NAVIGATE_ANOTHER_PAGE = 300; export function Home() { - const isRouterInContext = useInRouterContext(); const navigate = useNavigate(); - const [count, setCount] = useState(0); - const fromChain = useBestRouteStore.use.fromChain(); - const fromToken = useBestRouteStore.use.fromToken(); - const toChain = useBestRouteStore.use.toChain(); - const toToken = useBestRouteStore.use.toToken(); - const setInputAmount = useBestRouteStore.use.setInputAmount(); - const inputUsdValue = useBestRouteStore.use.inputUsdValue(); - const inputAmount = useBestRouteStore.use.inputAmount(); - const outputAmount = useBestRouteStore.use.outputAmount(); - const outputUsdValue = useBestRouteStore.use.outputUsdValue(); - const bestRoute = useBestRouteStore.use.bestRoute(); - const tokens = useMetaStore.use.meta().tokens; - const fetchingBestRoute = useBestRouteStore.use.loading(); - const bestRouteError = useBestRouteStore.use.error(); - const loadingMetaStatus = useMetaStore.use.loadingStatus(); - const accounts = useWalletsStore.use.accounts(); - const setCurrentPage = useUiStore.use.setCurrentPage(); - const switchFromAndTo = useBestRouteStore.use.switchFromAndTo(); - - const errorMessage = - loadingMetaStatus === 'failed' - ? errorMessages.genericServerError - : bestRouteError; + const { + fromToken, + toToken, + inputAmount, + selectedQuote, + refetchQuote, + error: quoteError, + warning: quoteWarning, + quotes, + setSelectedQuote, + resetQuoteWallets, + setQuoteWarningsConfirmed, + updateQuotePartialState, + } = useQuoteStore(); + const [isVisibleExpanded, setIsVisibleExpanded] = useState(false); + const { isLargeScreen, isExtraLargeScreen } = useScreenDetect(); + + const { fetch: fetchQuote, loading } = useSwapInput({ refetchQuote }); + const { + config, + fetchStatus: fetchMetaStatus, + connectedWallets, + } = useAppStore(); + + const { isActiveTab } = useUiStore(); + const [showQuoteWarningModal, setShowQuoteWarningModal] = useState(false); const needsToWarnEthOnPath = false; - const showBestRoute = - inputAmount && (!!bestRoute || fetchingBestRoute || bestRouteError); - - const outToInRatio = getOutputRatio(inputUsdValue, outputUsdValue); - - const highValueLoss = outputRatioHasWarning(inputUsdValue, outToInRatio); - - const { fromAmountRangeError, recommendation, swap } = - LimitErrorMessage(bestRoute); - - const priceImpactCanNotBeComputed = !canComputePriceImpact( - bestRoute, + const swapButtonState = getSwapButtonState({ + fetchMetaStatus, + fetchingQuote: loading, inputAmount, - inputUsdValue, - outputUsdValue - ); - - const swapButtonState = getSwapButtonState( - loadingMetaStatus, - accounts, - fetchingBestRoute, - bestRoute, - hasLimitError(bestRoute), - highValueLoss, - priceImpactCanNotBeComputed, + quote: selectedQuote, + anyWalletConnected: connectedWallets.length > 0, + error: quoteError, + warning: quoteWarning, needsToWarnEthOnPath, - inputAmount + }); + + const isExpandable = isVariantExpandable( + isLargeScreen, + isExtraLargeScreen, + config?.variant ); - const totalFeeInUsd = getTotalFeeInUsd(bestRoute, tokens); + const hasInputs = + !!inputAmount && + !!fromToken && + !!toToken && + new BigNumber(inputAmount).gt(0) && + !isTokensIdentical(fromToken, toToken); - const highFee = hasHighFee(totalFeeInUsd); + const fetchingQuote = hasInputs && fetchMetaStatus === 'success' && loading; - useEffect(() => { - setCurrentPage(navigationRoutes.home); + const hasValidQuotes = + !isExpandable || (isExpandable && quotes?.results.length); + const hasWarningOrError = quoteWarning || quoteError; + const showMessages = hasValidQuotes && hasWarningOrError; - return setCurrentPage.bind(null, ''); + useEffect(() => { + resetQuoteWallets(); + updateQuotePartialState('refetchQuote', true); }, []); + useEffect(() => { + setIsVisibleExpanded(hasInputs); + }, [hasInputs]); + + const onClickRefresh = + (!!selectedQuote || quoteError) && !showQuoteWarningModal + ? fetchQuote + : undefined; + + const onHandleNavigation = (route: string) => { + if (isExpandable && isVisibleExpanded) { + setIsVisibleExpanded(false); + setTimeout(() => { + navigate(route); + }, TIME_TO_NAVIGATE_ANOTHER_PAGE); + } else { + navigate(route); + } + }; + const onClickOnQuote = (quote: SelectedQuote) => { + if (selectedQuote?.requestId !== quote.requestId) { + setShowQuoteWarningModal(false); + setSelectedQuote(quote); + } + }; + return ( - -
- } - /> - - - + + + } + fullWidth onClick={() => { - switchFromAndTo(); - setCount((prev) => prev + 1); - }} - > - - {isRouterInContext && } + if (swapButtonState.action === 'connect-wallet') { + emitPreventableEvent( + { type: UiEventTypes.CLICK_CONNECT_WALLET }, + () => onHandleNavigation(navigationRoutes.wallets) + ); + } else if (swapButtonState.action === 'confirm-warning') { + setShowQuoteWarningModal(true); + } else { + onHandleNavigation(navigationRoutes.confirmSwap); + } + }}> + {swapButtonState.title} - - - - {showBestRoute && ( - - { + onHandleNavigation(navigationRoutes.wallets); + }, + hasBackButton: false, + title: config.title || i18n.t('Swap'), + suffix: ( + - )} - {(errorMessage || hasLimitError(bestRoute)) && ( - - {errorMessage && {errorMessage}} - {hasLimitError(bestRoute) && ( - - <> - - {`${fromAmountRangeError}, Yours: ${numberToString( - swap?.fromAmount || null - )} ${swap?.from.symbol}`} - - {recommendation} - - - )} - - )} -
- - -
- + + {!isExpandable ? ( + 1 + ? () => { + updateQuotePartialState('refetchQuote', false); + onHandleNavigation(navigationRoutes.routes); + } + : undefined + } + /> + ) : null} + + {showMessages ? ( + <> + + setShowQuoteWarningModal(true)} + onCloseWarningModal={() => setShowQuoteWarningModal(false)} + onConfirmWarningModal={() => { + setShowQuoteWarningModal(false); + setQuoteWarningsConfirmed(true); + onHandleNavigation(navigationRoutes.confirmSwap); + }} + onChangeSettings={() => + onHandleNavigation(navigationRoutes.settings) + } + /> + + ) : null} + + + + {isExpandable ? ( + + ) : null} + ); } diff --git a/widget/embedded/src/pages/LanguagePage.tsx b/widget/embedded/src/pages/LanguagePage.tsx new file mode 100644 index 0000000000..1ef1f93ece --- /dev/null +++ b/widget/embedded/src/pages/LanguagePage.tsx @@ -0,0 +1,67 @@ +import { i18n } from '@lingui/core'; +import { + Alert, + Divider, + List, + ListItemButton, + Radio, + RadioRoot, + Typography, +} from '@rango-dev/ui'; +import React from 'react'; + +import { Layout, PageContainer } from '../components/Layout'; +import { useLanguage } from '../hooks/useLanguage'; +import { useNavigateBack } from '../hooks/useNavigateBack'; + +export function LanguagePage() { + const { activeLanguage, changeLanguage, languages } = useLanguage(); + const navigateBack = useNavigateBack(); + + const languageList = languages.map((languageItem) => { + const { local, label, SVGFlag } = languageItem; + return { + id: `widget-setting-languages-${local}-item-btn`, + value: local, + title: ( + + {label} + + ), + onClick: () => { + changeLanguage(languageItem.local); + navigateBack(); + }, + end: , + start: , + }; + }); + + return ( + + + + + + console.log()} + /> + } + items={languageList} + /> + + + + ); +} diff --git a/widget/embedded/src/pages/LiquiditySourcePage.tsx b/widget/embedded/src/pages/LiquiditySourcePage.tsx new file mode 100644 index 0000000000..f9146db25f --- /dev/null +++ b/widget/embedded/src/pages/LiquiditySourcePage.tsx @@ -0,0 +1,170 @@ +import type { UniqueSwappersGroupType } from '../utils/settings'; +import type { SwapperType } from 'rango-sdk'; + +import { i18n } from '@lingui/core'; +import { + Button, + Checkbox, + Image, + ListItemButton, + NotFound, + Typography, +} from '@rango-dev/ui'; +import React, { useState } from 'react'; + +import { Layout, PageContainer } from '../components/Layout'; +import { LoadingLiquiditySourceList } from '../components/LoadingLiquiditySourceList'; +import { SearchInput } from '../components/SearchInput'; +import { + LiquiditySourceList, + LiquiditySourceSuffix, + NotFoundContainer, +} from '../components/SettingsContainer'; +import { useAppStore } from '../store/AppStore'; +import { containsText } from '../utils/numbers'; +import { getUniqueSwappersGroups } from '../utils/settings'; + +interface PropTypes { + sourceType: 'Exchanges' | 'Bridges'; +} + +export function LiquiditySourcePage({ sourceType }: PropTypes) { + const fetchStatus = useAppStore().fetchStatus; + const swappers = useAppStore().swappers(); + const disabledLiquiditySources = useAppStore().getDisabledLiquiditySources(); + const [searchedFor, setSearchedFor] = useState(''); + const toggleLiquiditySource = useAppStore().toggleLiquiditySource; + const campaignMode = useAppStore().isInCampaignMode(); + const supportedUniqueSwappersGroups: Array = + getUniqueSwappersGroups(swappers, disabledLiquiditySources); + + const types = { Exchanges: i18n.t('Exchanges'), Bridges: i18n.t('Bridges') }; + const validTypes: Array = []; + if (sourceType === 'Exchanges') { + validTypes.push('DEX'); + } + if (sourceType === 'Bridges') { + validTypes.push('BRIDGE', 'AGGREGATOR', 'OFF_CHAIN'); + } + + const liquiditySources = supportedUniqueSwappersGroups.filter((uniqueItem) => + validTypes.includes(uniqueItem.type) + ); + + const hasSelectAll = + liquiditySources.length === + liquiditySources.filter((sourceItem) => sourceItem.selected).length; + + const toggleAllSources = () => { + liquiditySources.forEach((sourceItem) => { + if (hasSelectAll) { + toggleLiquiditySource(sourceItem.groupTitle); + } else { + if (!sourceItem.selected) { + toggleLiquiditySource(sourceItem.groupTitle); + } + } + }); + }; + + const list = liquiditySources.map((sourceItem) => { + const { selected, groupTitle, logo, id, ...restSourceItem } = sourceItem; + return { + id: `widget-setting-liquidity-source-${id + .toLowerCase() + .replace(/\s+/g, '-')}-item-btn`, + start: , + onClick: () => { + if (!campaignMode) { + toggleLiquiditySource(groupTitle); + } + }, + end: , + title: ( + + {i18n.t(groupTitle)} + + ), + selected, + groupTitle, + logo, + ...restSourceItem, + }; + }); + + const handleSearch = (event: React.ChangeEvent) => { + const value = event.target.value; + setSearchedFor(value); + }; + + let filteredList = list; + if (searchedFor) { + filteredList = list.filter((sourceItem) => + containsText(sourceItem.groupTitle, searchedFor) + ); + } + + return ( + + {/* eslint-disable-next-line jsx-id-attribute-enforcement/missing-ids */} + + + ), + }}> + + + {fetchStatus === 'loading' && } + + {!filteredList.length && !!searchedFor ? ( + + + + ) : ( + fetchStatus === 'success' && ( + + {filteredList.map((sourceItem) => { + const { groupTitle, ...otherProps } = sourceItem; + + return ( + + + + ); + })} + + ) + )} + + + ); +} diff --git a/widget/embedded/src/pages/LiquiditySourcesPage.tsx b/widget/embedded/src/pages/LiquiditySourcesPage.tsx deleted file mode 100644 index 9bb579a20b..0000000000 --- a/widget/embedded/src/pages/LiquiditySourcesPage.tsx +++ /dev/null @@ -1,63 +0,0 @@ -import { LiquiditySourcesSelector } from '@rango-dev/ui'; -import React from 'react'; -import { navigationRoutes } from '../constants/navigationRoutes'; -import { useNavigateBack } from '../hooks/useNavigateBack'; -import { useMetaStore } from '../store/meta'; -import { useSettingsStore } from '../store/settings'; -import { removeDuplicateFrom } from '../utils/common'; -interface PropTypes { - supportedSwappers?: string[]; -} -export function LiquiditySourcePage({ supportedSwappers }: PropTypes) { - const swappers = useMetaStore.use.meta().swappers; - const loadingMetaStatus = useMetaStore.use.loadingStatus(); - const toggleLiquiditySource = useSettingsStore.use.toggleLiquiditySource(); - const disabledLiquiditySources = - useSettingsStore.use.disabledLiquiditySources(); - const toggleAllLiquiditySources = - useSettingsStore.use.toggleAllLiquiditySources(); - - const { navigateBackFrom } = useNavigateBack(); - - const uniqueSwappersGroups: Array<{ - title: string; - logo: string; - type: 'BRIDGE' | 'AGGREGATOR' | 'DEX'; - selected: boolean; - }> = []; - removeDuplicateFrom(swappers.map((s) => s.swapperGroup)) - .map((swapperGroup) => { - return swappers.find((s) => s.swapperGroup === swapperGroup); - }) - .find((s) => { - if (s) { - for (const type of s.types) { - uniqueSwappersGroups.push({ - title: s.swapperGroup, - logo: s.logo, - type, - selected: !disabledLiquiditySources.includes(s.swapperGroup), - }); - } - } - }); - - return ( - - supportedSwappers.filter((s) => s === item.title).length > 0 - ) - : uniqueSwappersGroups - } - onChange={(liquiditySource) => - toggleLiquiditySource(liquiditySource.title) - } - onBack={navigateBackFrom.bind(null, navigationRoutes.liquiditySources)} - loadingStatus={loadingMetaStatus} - /> - ); -} diff --git a/widget/embedded/src/pages/Routes.tsx b/widget/embedded/src/pages/Routes.tsx new file mode 100644 index 0000000000..c1f3d8fe2e --- /dev/null +++ b/widget/embedded/src/pages/Routes.tsx @@ -0,0 +1,71 @@ +import type { SelectedQuote } from '../types'; + +import { i18n } from '@lingui/core'; +import React from 'react'; +import { useNavigate } from 'react-router-dom'; + +import { HeaderButtons } from '../components/HeaderButtons'; +import { Layout, PageContainer } from '../components/Layout'; +import { Quotes } from '../components/Quotes'; +import { navigationRoutes } from '../constants/navigationRoutes'; +import { useNavigateBack } from '../hooks/useNavigateBack'; +import { useSwapInput } from '../hooks/useSwapInput'; +import { useQuoteStore } from '../store/quote'; + +export function RoutesPage() { + const navigate = useNavigate(); + const navigateBack = useNavigateBack(); + const { + selectedQuote, + refetchQuote, + setSelectedQuote, + updateQuotePartialState, + error: quoteError, + } = useQuoteStore(); + + const { fetch: fetchQuote, loading: fetchingQuote } = useSwapInput({ + refetchQuote, + }); + + const onClickOnQuote = (quote: SelectedQuote) => { + setSelectedQuote(quote); + updateQuotePartialState('refetchQuote', false); + navigateBack(); + }; + + const settings_url = `../${navigationRoutes.settings}`; + const wallets_url = `../${navigationRoutes.wallets}`; + return ( + { + navigate(wallets_url); + updateQuotePartialState('refetchQuote', true); + }, + onBack: () => { + updateQuotePartialState('refetchQuote', false); + }, + title: i18n.t('Routes'), + suffix: ( + + ); +} diff --git a/widget/embedded/src/pages/SelectBlockchainPage.tsx b/widget/embedded/src/pages/SelectBlockchainPage.tsx new file mode 100644 index 0000000000..76faa8fbd4 --- /dev/null +++ b/widget/embedded/src/pages/SelectBlockchainPage.tsx @@ -0,0 +1,90 @@ +import { i18n } from '@lingui/core'; +import { + Divider, + getCategoriesCount, + SelectableCategoryList, +} from '@rango-dev/ui'; +import React, { useState } from 'react'; +import { useNavigate } from 'react-router-dom'; + +import { BlockchainList } from '../components/BlockchainList'; +import { Layout, PageContainer } from '../components/Layout'; +import { SearchInput } from '../components/SearchInput'; +import { useNavigateBack } from '../hooks/useNavigateBack'; +import { useAppStore } from '../store/AppStore'; +import { useQuoteStore } from '../store/quote'; + +interface PropTypes { + type: 'source' | 'destination' | 'custom-token'; + hideCategory?: boolean; +} + +export function SelectBlockchainPage(props: PropTypes) { + const { type } = props; + const navigateBack = useNavigateBack(); + const [searchedFor, setSearchedFor] = useState(''); + const [blockchainCategory, setBlockchainCategory] = useState('ALL'); + const setToBlockchain = useQuoteStore.use.setToBlockchain(); + const setFromBlockchain = useQuoteStore.use.setFromBlockchain(); + const { fetchStatus } = useAppStore(); + const navigate = useNavigate(); + + const blockchains = useAppStore().blockchains({ + type, + }); + const activeCategoriesCount = getCategoriesCount(blockchains); + + const showCategory = !props.hideCategory && activeCategoriesCount !== 1; + + return ( + + + {showCategory && ( + <> + + + + )} + + setSearchedFor('')} + onChange={(event) => setSearchedFor(event.target.value)} + /> + + + { + if (type === 'custom-token') { + navigate(`..?blockchain=${blockchain.name}`, { replace: true }); + } else { + if (type === 'source') { + setFromBlockchain(blockchain); + } else { + setToBlockchain(blockchain); + } + navigateBack(); + } + }} + /> + + + ); +} diff --git a/widget/embedded/src/pages/SelectChainPage.tsx b/widget/embedded/src/pages/SelectChainPage.tsx deleted file mode 100644 index 03934934cc..0000000000 --- a/widget/embedded/src/pages/SelectChainPage.tsx +++ /dev/null @@ -1,42 +0,0 @@ -import React from 'react'; -import { BlockchainSelector } from '@rango-dev/ui'; -import { useBestRouteStore } from '../store/bestRoute'; -import { useMetaStore } from '../store/meta'; -import { useNavigateBack } from '../hooks/useNavigateBack'; -import { navigationRoutes } from '../constants/navigationRoutes'; - -interface PropTypes { - type: 'from' | 'to'; - supportedChains?: string[]; -} - -export function SelectChainPage(props: PropTypes) { - const { type, supportedChains } = props; - const blockchains = supportedChains - ? useMetaStore.use - .meta() - .blockchains.filter((chain) => supportedChains.includes(chain.name)) - : useMetaStore.use.meta().blockchains; - const loadingStatus = useMetaStore.use.loadingStatus(); - const fromChain = useBestRouteStore.use.fromChain(); - const toChain = useBestRouteStore.use.toChain(); - const setFromChain = useBestRouteStore.use.setFromChain(); - const setToChain = useBestRouteStore.use.setToChain(); - - const { navigateBackFrom } = useNavigateBack(); - - return ( - { - if (type === 'from') setFromChain(chain, true); - else setToChain(chain, true); - navigateBackFrom(navigationRoutes.fromChain); - }} - onBack={navigateBackFrom.bind(null, navigationRoutes.fromChain)} - /> - ); -} diff --git a/widget/embedded/src/pages/SelectSwapItemsPage.tsx b/widget/embedded/src/pages/SelectSwapItemsPage.tsx new file mode 100644 index 0000000000..5e1f99a0b8 --- /dev/null +++ b/widget/embedded/src/pages/SelectSwapItemsPage.tsx @@ -0,0 +1,118 @@ +import type { BlockchainMeta, Token } from 'rango-sdk'; + +import { i18n } from '@lingui/core'; +import { Divider } from '@rango-dev/ui'; +import React, { useState } from 'react'; +import { useNavigate } from 'react-router-dom'; + +import { BlockchainsSection } from '../components/BlockchainsSection'; +import { Layout, PageContainer } from '../components/Layout'; +import { SearchInput } from '../components/SearchInput'; +import { TokenList } from '../components/TokenList'; +import { navigationRoutes } from '../constants/navigationRoutes'; +import { useNavigateBack } from '../hooks/useNavigateBack'; +import { useAppStore } from '../store/AppStore'; +import { useQuoteStore } from '../store/quote'; + +interface PropTypes { + type: 'source' | 'destination'; +} + +export function SelectSwapItemsPage(props: PropTypes) { + const { type } = props; + const navigate = useNavigate(); + const navigateBack = useNavigateBack(); + const { + fromBlockchain, + toBlockchain, + setFromToken, + setToToken, + setFromBlockchain, + setToBlockchain, + } = useQuoteStore(); + const { getBalanceFor } = useAppStore(); + const [searchedFor, setSearchedFor] = useState(''); + + const selectedBlockchain = type === 'source' ? fromBlockchain : toBlockchain; + const selectedBlockchainName = selectedBlockchain?.name ?? ''; + + // Tokens & Blockchains list + const blockchains = useAppStore().blockchains({ + type, + }); + const tokens = useAppStore().tokens({ + type, + blockchain: selectedBlockchainName, + searchFor: searchedFor, + getBalanceFor: getBalanceFor, + }); + + const updateBlockchain = (blockchain: BlockchainMeta) => { + if (type === 'source') { + setFromBlockchain(blockchain); + } else { + setToBlockchain(blockchain); + } + }; + + const updateToken = (token: Token) => { + if (type === 'source') { + setFromToken({ token, meta: { blockchains, tokens } }); + } else { + setToToken({ token, meta: { blockchains, tokens } }); + } + }; + const types = { + source: i18n.t('Source'), + destination: i18n.t('Destination'), + }; + + return ( + + + navigate(navigationRoutes.blockchains)} + onChange={(blockchain) => { + updateBlockchain(blockchain); + }} + /> + + setSearchedFor('')} + onChange={(event) => setSearchedFor(event.target.value)} + /> + + { + updateToken(token); + + const tokenBlockchain = blockchains.find( + (chain) => token.blockchain === chain.name + ); + if (tokenBlockchain) { + updateBlockchain(tokenBlockchain); + } + + navigateBack(); + }} + /> + + + ); +} diff --git a/widget/embedded/src/pages/SelectTokenPage.tsx b/widget/embedded/src/pages/SelectTokenPage.tsx deleted file mode 100644 index 37fbef9a9c..0000000000 --- a/widget/embedded/src/pages/SelectTokenPage.tsx +++ /dev/null @@ -1,64 +0,0 @@ -import React from 'react'; -import { TokenSelector } from '@rango-dev/ui'; -import { useBestRouteStore } from '../store/bestRoute'; -import { Asset, Token } from 'rango-sdk'; -import { useNavigateBack } from '../hooks/useNavigateBack'; -import { navigationRoutes } from '../constants/navigationRoutes'; -import { tokensAreEqual } from '../utils/wallets'; -import { useMetaStore } from '../store/meta'; - -interface PropTypes { - type: 'from' | 'to'; - supportedTokens?: Asset[]; -} - -export interface TokenWithBalance extends Token { - balance?: { - amount: string; - usdValue: string; - }; -} - -export function SelectTokenPage(props: PropTypes) { - const { navigateBackFrom } = useNavigateBack(); - - const { type, supportedTokens } = props; - const sourceTokens = useBestRouteStore.use.sourceTokens(); - const destinationTokens = useBestRouteStore.use.destinationTokens(); - const supportedSourceTokens = supportedTokens - ? sourceTokens.filter((token) => - supportedTokens.some((supportedToken) => - tokensAreEqual(supportedToken, token) - ) - ) - : sourceTokens; - - const supportedDestinationTokens = supportedTokens - ? destinationTokens.filter((token) => - supportedTokens.some((supportedToken) => - tokensAreEqual(supportedToken, token) - ) - ) - : destinationTokens; - - const fromToken = useBestRouteStore.use.fromToken(); - const toToken = useBestRouteStore.use.toToken(); - const setFromToken = useBestRouteStore.use.setFromToken(); - const setToToken = useBestRouteStore.use.setToToken(); - const loadingMetaStatus = useMetaStore.use.loadingStatus(); - - return ( - { - if (type === 'from') setFromToken(token); - else setToToken(token); - navigateBackFrom(navigationRoutes.fromToken); - }} - onBack={navigateBackFrom.bind(null, navigationRoutes.fromToken)} - loadingStatus={loadingMetaStatus} - /> - ); -} diff --git a/widget/embedded/src/pages/SettingsPage.tsx b/widget/embedded/src/pages/SettingsPage.tsx index be392c314d..42e726f846 100644 --- a/widget/embedded/src/pages/SettingsPage.tsx +++ b/widget/embedded/src/pages/SettingsPage.tsx @@ -1,91 +1,66 @@ +import { i18n } from '@lingui/core'; +import { Alert, Button, styled } from '@rango-dev/ui'; import React from 'react'; -import { Settings } from '@rango-dev/ui'; -import { useSettingsStore } from '../store/settings'; -import { useMetaStore } from '../store/meta'; -import { useNavigate } from 'react-router-dom'; -import { navigationRoutes } from '../constants/navigationRoutes'; -import { removeDuplicateFrom } from '../utils/common'; -import { - MAX_SLIPPAGE, - MIN_SLIPPGAE, - SLIPPAGES, -} from '../constants/swapSettings'; -import { useNavigateBack } from '../hooks/useNavigateBack'; -interface PropTypes { - supportedSwappers?: string[]; -} -export function SettingsPage({ supportedSwappers }: PropTypes) { - const slippage = useSettingsStore.use.slippage(); - const setSlippage = useSettingsStore.use.setSlippage(); - const disabledLiquiditySources = - useSettingsStore.use.disabledLiquiditySources(); - const customSlippage = useSettingsStore.use.customSlippage(); - const setCustomSlippage = useSettingsStore.use.setCustomSlippage(); - const theme = useSettingsStore.use.theme(); - const setTheme = useSettingsStore.use.setTheme(); - const swappers = useMetaStore.use.meta().swappers; - const navigate = useNavigate(); - const { navigateBackFrom } = useNavigateBack(); +import { useInRouterContext, useSearchParams } from 'react-router-dom'; + +import { Layout, PageContainer } from '../components/Layout'; +import { Slippage } from '../components/Slippage'; +import { SearchParams } from '../constants/searchParams'; +import { SettingsLists } from '../containers/Settings/Lists'; +import { useAppStore } from '../store/AppStore'; - const infiniteApprove = useSettingsStore.use.infiniteApprove(); - const toggleInfiniteApprove = useSettingsStore.use.toggleInfiniteApprove(); - const loadingMetaStatus = useMetaStore.use.loadingStatus(); +const ResetAction = styled('div', { + paddingLeft: '$8', +}); - const uniqueSwappersGroups: Array<{ - title: string; - logo: string; - type: 'BRIDGE' | 'AGGREGATOR' | 'DEX'; - selected: boolean; - }> = []; - removeDuplicateFrom(swappers.map((s) => s.swapperGroup)) - .map((swapperGroup) => { - return swappers.find((s) => s.swapperGroup === swapperGroup); - }) - .find((s) => { - if (s) { - for (const type of s.types) { - uniqueSwappersGroups.push({ - title: s.swapperGroup, - logo: s.logo, - type, - selected: !disabledLiquiditySources.includes(s.swapperGroup), - }); - } - } - }); - supportedSwappers && - uniqueSwappersGroups.filter( - (item) => supportedSwappers.filter((s) => s === item.title).length > 0 - ); +export function SettingsPage() { + const { isInCampaignMode, updateCampaignMode } = useAppStore(); + const campaignMode = isInCampaignMode(); - const supportedUniqueSwappersGroups = supportedSwappers - ? uniqueSwappersGroups.filter( - (item) => supportedSwappers.filter((s) => s === item.title).length > 0 - ) - : uniqueSwappersGroups; + const [, setSearchParams] = useSearchParams(); + const isRouterInContext = useInRouterContext(); + const onClick = () => { + if (isRouterInContext && campaignMode) { + setSearchParams( + (prev) => { + prev.delete(SearchParams.LIQUIDITY_SOURCES); + return prev; + }, + { replace: true } + ); + updateCampaignMode('liquiditySources', undefined); + } + }; return ( - setSlippage(slippage)} - onLiquiditySourcesClick={() => - navigate(navigationRoutes.liquiditySources) - } - onBack={navigateBackFrom.bind(null, navigationRoutes.settings)} - liquiditySources={supportedUniqueSwappersGroups} - selectedLiquiditySources={supportedUniqueSwappersGroups.filter( - (s) => s.selected - )} - customSlippage={customSlippage || NaN} - onCustomSlippageChange={setCustomSlippage} - minSlippage={MIN_SLIPPGAE} - maxSlippage={MAX_SLIPPAGE} - selectedTheme={theme} - onThemeChange={setTheme} - infiniteApprove={infiniteApprove} - toggleInfiniteApprove={toggleInfiniteApprove} - loadingStatus={loadingMetaStatus} - /> + + + {campaignMode && ( + + + + } + /> + )} + + + + ); } diff --git a/widget/embedded/src/pages/SwapDetailsPage.tsx b/widget/embedded/src/pages/SwapDetailsPage.tsx index 191a2b2af4..a067c962f7 100644 --- a/widget/embedded/src/pages/SwapDetailsPage.tsx +++ b/widget/embedded/src/pages/SwapDetailsPage.tsx @@ -1,159 +1,78 @@ -import React from 'react'; -import { navigationRoutes } from '../constants/navigationRoutes'; -import useCopyToClipboard from '../hooks/useCopyToClipboard'; +import { i18n } from '@lingui/core'; +import { cancelSwap } from '@rango-dev/queue-manager-rango-preset'; import { useManager } from '@rango-dev/queue-manager-react'; +import { Alert } from '@rango-dev/ui'; +import React from 'react'; +import { useParams } from 'react-router-dom'; + +import { SwapDetails } from '../components/SwapDetails'; +import { SwapDetailsPlaceholder } from '../components/SwapDetails/SwapDetails.Placeholder'; import { useNavigateBack } from '../hooks/useNavigateBack'; +import { useAppStore } from '../store/AppStore'; import { getPendingSwaps } from '../utils/queue'; -import { SwapHistory } from '@rango-dev/ui'; -import { useUiStore } from '../store/ui'; -import { - cancelSwap, - PendingSwapNetworkStatus, -} from '@rango-dev/queue-manager-rango-preset'; -import { useWallets } from '@rango-dev/wallets-core'; -import { - getCurrentBlockchainOfOrNull, - getCurrentStep, - getRelatedWalletOrNull, -} from '@rango-dev/queue-manager-rango-preset'; -import { getSwapDate } from '../utils/time'; -import { useNavigate } from 'react-router-dom'; -import { useBestRouteStore } from '../store/bestRoute'; -import { - getLastConvertedTokenInFailedSwap, - getSwapMessages, - isNetworkStatusInWarningState, - shouldRetrySwap, -} from '../utils/swap'; -//@ts-ignore -import { t } from 'i18next'; -import { SwapDetailsPlaceholder } from '../components/SwapDetailsPlaceholder'; -import { getFormatedPendingSwap } from '../utils/routing'; export function SwapDetailsPage() { - const selectedSwapRequestId = useUiStore.use.selectedSwapRequestId(); - const { canSwitchNetworkTo, connect } = useWallets(); - const retry = useBestRouteStore.use.retry(); - const navigate = useNavigate(); - const { navigateBackFrom } = useNavigateBack(); - const [isCopied, handleCopy] = useCopyToClipboard(2000); const { manager, state } = useManager(); - - const pendingSwaps = getPendingSwaps(manager); - const selectedSwap = pendingSwaps.find( - ({ swap }) => swap.requestId === selectedSwapRequestId - ); - - const onCancel = () => { - const swap = manager?.get(selectedSwap?.id!); - if (swap) cancelSwap(swap); - }; - const swap = selectedSwap?.swap; const loading = !state.loadedFromPersistor; + const pendingSwaps = getPendingSwaps(manager); + const { requestId } = useParams<{ requestId: string }>(); + const navigateBack = useNavigateBack(); + const { fetchStatus: fetchMetaStatus } = useAppStore(); - if (!swap) + if (!requestId) { return ( - ); + } - const currentStep = getCurrentStep(swap); - - const currentStepBlockchain = currentStep - ? getCurrentBlockchainOfOrNull(swap, currentStep) - : null; - const currentStepWallet = currentStep - ? getRelatedWalletOrNull(swap, currentStep) - : null; - const currentStepNetworkStatus = currentStep?.networkStatus; - - const swapMessages = getSwapMessages(swap, currentStep); + const showSkeleton = loading || fetchMetaStatus === 'loading'; - const networkWarningState = isNetworkStatusInWarningState(currentStep); + const selectedSwap = requestId + ? pendingSwaps.find(({ swap }) => swap.requestId === requestId) + : undefined; - const swapDate = getSwapDate(swap); - - const shouldRetry = shouldRetrySwap(swap); + const onCancel = () => { + if (selectedSwap?.id) { + const swap = manager?.get(selectedSwap.id); + if (swap) { + cancelSwap(swap); + } + } + }; - const switchNetwork = - !!currentStepBlockchain && - !!currentStepWallet?.walletType && - currentStepNetworkStatus === - PendingSwapNetworkStatus.WaitingForNetworkChange && - canSwitchNetworkTo(currentStepWallet?.walletType, currentStepBlockchain) - ? connect.bind(null, currentStepWallet.walletType, currentStepBlockchain) - : undefined; + const onDelete = async () => { + if (selectedSwap?.id) { + try { + manager?.deleteQueue(selectedSwap.id); + navigateBack(); + } catch (e) { + console.log(e); + } + } + }; + const swap = selectedSwap?.swap; - const lastConvertedTokenInFailedSwap = - getLastConvertedTokenInFailedSwap(swap); + if (!swap || showSkeleton) { + return ( + + ); + } return ( - - - - - - } - */ - pendingSwap={getFormatedPendingSwap(swap)} - onCopy={handleCopy} - isCopied={isCopied} + { - retry(swap); - setTimeout(() => { - navigate(navigationRoutes.home); - }, 0); - }, - })} - {...(lastConvertedTokenInFailedSwap && { - lastConvertedTokenInFailedSwap: { - blockchain: lastConvertedTokenInFailedSwap.blockchain, - outputAmount: lastConvertedTokenInFailedSwap.outputAmount || '', - symbol: lastConvertedTokenInFailedSwap.symbol, - }, - })} + onDelete={onDelete} /> ); } diff --git a/widget/embedded/src/pages/WalletsPage.tsx b/widget/embedded/src/pages/WalletsPage.tsx index 7d82a2f329..746ce67667 100644 --- a/widget/embedded/src/pages/WalletsPage.tsx +++ b/widget/embedded/src/pages/WalletsPage.tsx @@ -1,138 +1,108 @@ +import type { WalletInfoWithExtra } from '../types'; + +import { i18n } from '@lingui/core'; import { - Alert, - SecondaryPage, + Divider, + getCategoriesCount, + SelectableCategoryList, styled, + Typography, Wallet, - WalletState, - WalletInfo, } from '@rango-dev/ui'; -import React, { useEffect, useRef, useState } from 'react'; -import { getlistWallet, sortWalletsBasedOnState } from '../utils/wallets'; -import { WalletType, detectMobileScreens } from '@rango-dev/wallets-shared'; -import { useWallets } from '@rango-dev/wallets-core'; +import React, { useState } from 'react'; +import { Layout, PageContainer } from '../components/Layout'; +import { StatefulConnectModal } from '../components/StatefulConnectModal'; +import { useWalletList } from '../hooks/useWalletList'; +import { useAppStore } from '../store/AppStore'; import { useUiStore } from '../store/ui'; -import { useNavigateBack } from '../hooks/useNavigateBack'; -import { navigationRoutes } from '../constants/navigationRoutes'; -import { useTranslation } from 'react-i18next'; -import { useMetaStore } from '../store/meta'; -import { Spinner } from '@rango-dev/ui'; -import { LoadingFailedAlert } from '@rango-dev/ui'; - -interface PropTypes { - supportedWallets?: WalletType[]; - multiWallets: boolean; -} +import { getContainer, isSingleWalletActive } from '../utils/common'; +import { + filterBlockchainsByWalletTypes, + filterWalletsByCategory, +} from '../utils/wallets'; const ListContainer = styled('div', { - display: 'grid', - gap: '.5rem', - gridTemplateColumns: ' repeat(2, minmax(0, 1fr))', - alignContent: 'baseline', - padding: '0.5rem', - overflowY: 'auto', -}); - -const LoaderContainer = styled('div', { display: 'flex', justifyContent: 'center', - width: '100%', - position: 'absolute', - top: '50%', + alignItems: 'center', + gap: '$10', + flexWrap: 'wrap', + paddingTop: '$5', }); -const AlertContainer = styled('div', { - paddingBottom: '$16', +const Container = styled(PageContainer, { + textAlign: 'center', }); -export function WalletsPage({ supportedWallets, multiWallets }: PropTypes) { - const { navigateBackFrom } = useNavigateBack(); - const { state, disconnect, getWalletInfo, connect } = useWallets(); - const wallets = getlistWallet( - state, - getWalletInfo, - supportedWallets || Object.values(WalletType) - ); - const walletsRef = useRef(); - let sortedWallets = detectMobileScreens() - ? wallets.filter((wallet) => wallet.showOnMobile) - : wallets; - sortedWallets = sortWalletsBasedOnState(sortedWallets); - const [walletErrorMessage, setWalletErrorMessage] = useState(''); - const toggleConnectWalletsButton = - useUiStore.use.toggleConnectWalletsButton(); - const loadingMetaStatus = useMetaStore.use.loadingStatus(); - const { t } = useTranslation(); +export function WalletsPage() { + const { fetchStatus: fetchMetaStatus } = useAppStore(); + const [blockchainCategory, setBlockchainCategory] = useState('ALL'); + const blockchains = useAppStore().blockchains(); + const { config } = useAppStore(); - const onSelectWallet = async (type: WalletType) => { - const wallet = state(type); - try { - if (walletErrorMessage) setWalletErrorMessage(''); - if (wallet.connected) { - await disconnect(type); - } else { - if ( - !multiWallets && - !!wallets.find((w) => w.state === WalletState.CONNECTED) - ) { - return; - } - await connect(type); - } - } catch (e) { - setWalletErrorMessage('Error: ' + (e as any)?.message); - } - }; - const disconnectConnectingWallets = () => { - const connectingWallets = - walletsRef.current?.filter( - (wallet) => wallet.state === WalletState.CONNECTING - ) || []; - for (const wallet of connectingWallets) { - disconnect(wallet.type); + const [selectedWalletToConnect, setSelectedWalletToConnect] = + useState(); + const isActiveTab = useUiStore.use.isActiveTab(); + + const { list } = useWalletList(); + + const filteredBlockchains = filterBlockchainsByWalletTypes(list, blockchains); + const activeCategoriesCount = getCategoriesCount(filteredBlockchains); + const showCategory = activeCategoriesCount !== 1; + + const filteredWallets = filterWalletsByCategory(list, blockchainCategory); + + const handleWalletItemClick = (wallet: WalletInfoWithExtra) => { + if (isSingleWalletActive(list, config.multiWallets)) { + return; } - }; - useEffect(() => { - toggleConnectWalletsButton(); - return () => { - disconnectConnectingWallets(); - toggleConnectWalletsButton(); - }; - }, []); - useEffect(() => { - walletsRef.current = wallets; - }, [wallets]); + setSelectedWalletToConnect(wallet); + }; return ( - - <> - {walletErrorMessage && ( - - - - )} - {loadingMetaStatus === 'loading' && ( - - - + + + {showCategory && ( + <> + + + )} - {loadingMetaStatus === 'failed' && } + + {i18n.t('Choose a wallet to connect.')} + - {loadingMetaStatus === 'success' && - sortedWallets.map((wallet, index) => ( + {filteredWallets.map((wallet, index) => { + const key = `wallet-${index}-${wallet.type}`; + return ( handleWalletItemClick(wallet)} + isLoading={fetchMetaStatus === 'loading'} + disabled={!isActiveTab} /> - ))} + ); + })} + { + setSelectedWalletToConnect(undefined); + }} + /> - - + + ); } diff --git a/widget/embedded/src/services/cacheService.ts b/widget/embedded/src/services/cacheService.ts new file mode 100644 index 0000000000..c598b140aa --- /dev/null +++ b/widget/embedded/src/services/cacheService.ts @@ -0,0 +1,35 @@ +import type { Token } from 'rango-sdk'; + +interface CacheServiceInterface { + get(key: K): V[K] | undefined; + set(key: K, value: V[K]): void; + remove(key: K): void; + clear(): void; +} + +class CacheService implements CacheServiceInterface { + #cache: Map = new Map(); + + get(key: K): T[K] | undefined { + return this.#cache.get(key as string) as T[K]; + } + + set(key: K, value: T[K]): void { + this.#cache.set(key as string, value); + } + + remove(key: K): void { + this.#cache.delete(key as string); + } + + clear(): void { + this.#cache.clear(); + } +} + +export type CachedEntries = { + supportedSourceTokens: Token[]; + supportedDestinationTokens: Token[]; +}; + +export const cacheService = new CacheService(); diff --git a/widget/embedded/src/services/eventEmitter.ts b/widget/embedded/src/services/eventEmitter.ts new file mode 100644 index 0000000000..d51fffdf8c --- /dev/null +++ b/widget/embedded/src/services/eventEmitter.ts @@ -0,0 +1,11 @@ +import type { Events, WidgetEventEmitter } from '../types'; + +import mitt from 'mitt'; + +export const eventEmitter = mitt(); + +// To be exported for Dapps +export const widgetEventEmitter: WidgetEventEmitter = { + on: eventEmitter.on, + off: eventEmitter.off, +}; diff --git a/widget/embedded/src/services/httpService.ts b/widget/embedded/src/services/httpService.ts index 7b789ac9d2..20093a64bb 100644 --- a/widget/embedded/src/services/httpService.ts +++ b/widget/embedded/src/services/httpService.ts @@ -1,14 +1,13 @@ import { RangoClient } from 'rango-sdk'; -import { getConfig } from '../utils/configs'; -// this API key is limited and -// it is only for test purpose -export const RANGO_PUBLIC_API_KEY = 'c6381a79-2817-4602-83bf-6a641a409e32'; +import { getConfig } from '../utils/configs'; let rango: RangoClient | undefined = undefined; export const httpService = () => { - if (rango) return rango; - rango = new RangoClient(getConfig('API_KEY')); + if (rango) { + return rango; + } + rango = new RangoClient(getConfig('API_KEY'), getConfig('BASE_URL')); return rango; }; diff --git a/widget/embedded/src/store/AppStore.tsx b/widget/embedded/src/store/AppStore.tsx new file mode 100644 index 0000000000..b7ab00055d --- /dev/null +++ b/widget/embedded/src/store/AppStore.tsx @@ -0,0 +1,41 @@ +import type { WidgetConfig } from '../types'; +import type { PropsWithChildren } from 'react'; + +import React, { createContext, useContext, useEffect, useRef } from 'react'; + +import { createAppStore } from './app'; + +type AppStore = ReturnType; +type AppStoreProviderProps = PropsWithChildren<{ config?: WidgetConfig }>; + +export const AppStoreContext = createContext(null); + +export function useAppStore() { + const store = useContext(AppStoreContext); + + useEffect(() => { + if (store && !store.persist.hasHydrated()) { + void store.persist.rehydrate(); + } + }, []); + + if (!store) { + throw new Error('Missing AppStoreContext.Provider in the tree'); + } + + return store(); +} + +export function AppStoreProvider(props: AppStoreProviderProps) { + const appStoreRef = useRef(); + + if (!appStoreRef.current) { + appStoreRef.current = createAppStore(props.config); + } + + return ( + + {props.children} + + ); +} diff --git a/widget/embedded/src/store/app.ts b/widget/embedded/src/store/app.ts new file mode 100644 index 0000000000..1276cb99e7 --- /dev/null +++ b/widget/embedded/src/store/app.ts @@ -0,0 +1,54 @@ +import type { AppStoreState } from './slices/types'; +import type { WidgetConfig } from '../types'; +import type { StateCreator } from 'zustand'; + +import { create } from 'zustand'; +import { persist } from 'zustand/middleware'; + +import { createConfigSlice } from './slices/config'; +import { createDataSlice } from './slices/data'; +import { createSettingsSlice } from './slices/settings'; +import { createWalletsSlice } from './slices/wallets'; + +export type StateCreatorWithInitialData< + T extends Partial, + R extends Partial, + V extends Partial +> = ( + initialData: T | undefined, + ...rest: Parameters> +) => ReturnType>; + +export type { AppStoreState }; + +export function createAppStore(initialData?: WidgetConfig) { + return create()( + persist( + (...a) => ({ + ...createWalletsSlice(...a), + ...createDataSlice(...a), + ...createSettingsSlice(...a), + ...createConfigSlice(initialData, ...a), + }), + { + name: 'user-settings', + skipHydration: true, + partialize: (state) => { + return { + _customTokens: state._customTokens, + theme: state.theme, + language: state.language, + affiliatePercent: state.affiliatePercent, + affiliateRef: state.affiliateRef, + affiliateWallets: state.affiliateWallets, + slippage: state.slippage, + customSlippage: state.customSlippage, + infiniteApprove: state.infiniteApprove, + preferredBlockchains: state.preferredBlockchains, + disabledLiquiditySources: state.disabledLiquiditySources, + }; + }, + } + ) + ); +} diff --git a/widget/embedded/src/store/bestRoute.ts b/widget/embedded/src/store/bestRoute.ts deleted file mode 100644 index 5ce4506552..0000000000 --- a/widget/embedded/src/store/bestRoute.ts +++ /dev/null @@ -1,375 +0,0 @@ -import { BestRouteResponse, BlockchainMeta } from 'rango-sdk'; -import { Token } from 'rango-sdk'; -import { create } from 'zustand'; -import BigNumber from 'bignumber.js'; -import { ZERO } from '../constants/numbers'; -import { - getBestRouteToTokenUsdPrice, - isRouteParametersChanged, -} from '../utils/routing'; -import createSelectors from './selectors'; -import { subscribeWithSelector } from 'zustand/middleware'; -import { httpService } from '../services/httpService'; -import { useSettingsStore } from './settings'; -import { calcOutputUsdValue, createBestRouteRequestBody } from '../utils/swap'; -import { useMetaStore } from './meta'; -import { - getDefaultToken, - getSortedTokens, - tokensAreEqual, -} from '../utils/wallets'; -import { useWalletsStore } from './wallets'; -import { TokenWithBalance } from '../pages/SelectTokenPage'; -import { PendingSwap } from '@rango-dev/queue-manager-rango-preset/dist/shared'; -import { debounce } from '../utils/common'; -import { isPositiveNumber } from '../utils/numbers'; - -const getUsdValue = (token: Token | null, amount: string) => - new BigNumber(amount || ZERO).multipliedBy(token?.usdPrice || 0); - -export interface RouteState { - fromChain: BlockchainMeta | null; - toChain: BlockchainMeta | null; - inputAmount: string; - inputUsdValue: BigNumber; - outputAmount: BigNumber | null; - outputUsdValue: BigNumber; - fromToken: TokenWithBalance | null; - toToken: TokenWithBalance | null; - loading: boolean; - error: string; - sourceTokens: Token[]; - destinationTokens: Token[]; - setFromChain: ( - chain: BlockchainMeta | null, - setDefaultToken?: boolean - ) => void; - setToChain: (chian: BlockchainMeta | null, setDefaultToken?: boolean) => void; - setFromToken: (token: Token | null) => void; - setToToken: (token: Token | null) => void; - setInputAmount: (amount: string) => void; - bestRoute: BestRouteResponse | null; - setBestRoute: (bestRoute: BestRouteResponse | null) => void; - retry: (pendingSwap: PendingSwap) => void; - switchFromAndTo: () => void; -} - -export const useBestRouteStore = createSelectors( - create()( - subscribeWithSelector((set) => ({ - fromChain: null, - fromToken: null, - inputAmount: '', - outputAmount: null, - inputUsdValue: new BigNumber(0), - outputUsdValue: new BigNumber(0), - toChain: null, - toToken: null, - bestRoute: null, - loading: false, - error: '', - sourceTokens: [], - destinationTokens: [], - setBestRoute: (bestRoute) => - set((state) => { - let outputAmount: BigNumber | null = null; - let outputUsdValue: BigNumber = ZERO; - if (!isPositiveNumber(state.inputAmount)) return {}; - if (!!bestRoute) { - outputAmount = !!bestRoute.result?.outputAmount - ? new BigNumber(bestRoute.result?.outputAmount) - : null; - outputUsdValue = calcOutputUsdValue( - bestRoute.result?.outputAmount, - getBestRouteToTokenUsdPrice(bestRoute) || state.toToken?.usdPrice - ); - } - return { - bestRoute, - ...(!!bestRoute && { - outputAmount, - outputUsdValue, - }), - }; - }), - setFromChain: (chain, setDefaultToken) => { - set((state) => { - if (state.fromChain?.name === chain?.name) return {}; - const tokens = useMetaStore.getState().meta.tokens; - const balances = useWalletsStore.getState().balances; - const sortedTokens = getSortedTokens( - chain, - tokens, - balances, - state.destinationTokens - ); - const fromToken = getDefaultToken(sortedTokens, state.toToken); - return { - fromChain: chain, - sourceTokens: sortedTokens, - ...(setDefaultToken && { - fromToken, - }), - ...(!!state.inputAmount && { - inputUsdValue: getUsdValue(fromToken, state.inputAmount), - }), - }; - }); - }, - setFromToken: (token) => - set((state) => ({ - fromToken: token, - ...(!!state.inputAmount && { - inputUsdValue: getUsdValue(token, state.inputAmount), - }), - })), - setToChain: (chain, setDefaultToken) => { - set((state) => { - if (state.toChain?.name === chain?.name) return {}; - const tokens = useMetaStore.getState().meta.tokens; - const balances = useWalletsStore.getState().balances; - const sortedTokens = getSortedTokens( - chain, - tokens, - balances, - state.destinationTokens - ); - - return { - toChain: chain, - destinationTokens: sortedTokens, - ...(setDefaultToken && { - toToken: getDefaultToken(sortedTokens, state.fromToken), - }), - }; - }); - }, - setToToken: (token) => - set(() => ({ - toToken: token, - })), - setInputAmount: (amount) => { - set((state) => ({ - inputAmount: amount, - ...(!amount && { - outputAmount: new BigNumber(0), - outputUsdValue: new BigNumber(0), - bestRoute: null, - }), - ...(!!state.fromToken && { - inputUsdValue: getUsdValue(state.fromToken, amount), - }), - })); - }, - retry: (pendingSwap) => { - const { tokens, blockchains } = useMetaStore.getState().meta; - const balances = useWalletsStore.getState().balances; - const failedIndex = - pendingSwap.status === 'failed' - ? pendingSwap.steps.findIndex((s) => s.status === 'failed') - : null; - - if (failedIndex === null || failedIndex < 0) return; - - const firstStep = pendingSwap.steps[0]; - const lastStep = pendingSwap.steps[pendingSwap.steps.length - 1]; - const fromChain = - blockchains.find( - (blockchain) => blockchain.name === firstStep.fromBlockchain - ) || null; - const toChain = - blockchains.find( - (blockchain) => blockchain.name === lastStep.toBlockchain - ) || null; - - const fromToken = tokens.find((token) => - tokensAreEqual(token, { - blockchain: firstStep.fromBlockchain, - symbol: firstStep.fromSymbol, - address: firstStep.fromSymbolAddress, - }) - ); - - const toToken = tokens.find((token) => - tokensAreEqual(token, { - blockchain: lastStep.toBlockchain, - symbol: lastStep.toSymbol, - address: lastStep.toSymbolAddress, - }) - ); - const sortedSourceTokens = getSortedTokens( - fromChain, - tokens, - balances, - [] - ); - const sortedDestinationTokens = getSortedTokens( - toChain, - tokens, - balances, - [] - ); - const inputAmount = pendingSwap.inputAmount; - set({ - fromChain, - fromToken, - inputAmount, - outputAmount: null, - inputUsdValue: getUsdValue(fromToken || null, inputAmount), - outputUsdValue: new BigNumber(0), - toChain, - toToken, - bestRoute: null, - loading: false, - error: '', - sourceTokens: sortedSourceTokens, - destinationTokens: sortedDestinationTokens, - }); - }, - switchFromAndTo: () => - set((state) => ({ - fromChain: state.toChain, - fromToken: state.toToken, - toChain: state.fromChain, - toToken: state.fromToken, - sourceTokens: state.destinationTokens, - destinationTokens: state.sourceTokens, - inputAmount: state.outputAmount?.toString() || '', - inputUsdValue: getUsdValue( - state.toToken, - state.outputAmount?.toString() || '' - ), - })), - })) - ) -); - -const bestRoute = ( - bestRouteStore: typeof useBestRouteStore, - settingsStore: typeof useSettingsStore -) => { - let abortController: AbortController | null = null; - const fetchBestRoute = () => { - const { fromToken, toToken, inputAmount } = bestRouteStore.getState(); - const { slippage, customSlippage, disabledLiquiditySources, affiliateRef } = - settingsStore.getState(); - if (!fromToken || !toToken || !isPositiveNumber(inputAmount)) return; - abortController?.abort(); - abortController = new AbortController(); - const userSlippage = !!customSlippage ? customSlippage : slippage; - const requestBody = createBestRouteRequestBody( - fromToken, - toToken, - inputAmount, - [], - [], - disabledLiquiditySources, - userSlippage, - affiliateRef - ); - if (!bestRouteStore.getState().loading) - bestRouteStore.setState({ - loading: true, - bestRoute: null, - outputAmount: null, - outputUsdValue: new BigNumber(0), - }); - httpService() - .getBestRoute(requestBody, { - signal: abortController.signal, - }) - .then((res) => { - const { setBestRoute } = bestRouteStore.getState(); - setBestRoute(res); - bestRouteStore.setState({ loading: false }); - abortController = null; - }) - .catch((error) => { - if (error.code === 'ERR_CANCELED') return; - bestRouteStore.setState({ - error: error.message, - loading: false, - }); - }); - }; - - const debouncedFetchBestRoute = debounce(fetchBestRoute, 600); - - const bestRouteParamsListener = () => { - const { fromToken, toToken, inputAmount, inputUsdValue } = - useBestRouteStore.getState(); - if (!isPositiveNumber(inputAmount) || inputUsdValue.eq(0)) - return bestRouteStore.setState({ loading: false }); - - if (tokensAreEqual(fromToken, toToken)) - return bestRouteStore.setState({ - loading: false, - bestRoute: null, - outputAmount: new BigNumber(inputAmount), - outputUsdValue: inputUsdValue, - }); - - if (!bestRouteStore.getState().loading) - bestRouteStore.setState({ - loading: true, - bestRoute: null, - outputAmount: null, - outputUsdValue: new BigNumber(0), - }); - debouncedFetchBestRoute(); - }; - - useBestRouteStore.subscribe( - (state) => ({ - fromChain: state.fromChain, - fromToken: state.fromToken, - toChain: state.toChain, - toToken: state.toToken, - inputAmount: state.inputAmount, - }), - bestRouteParamsListener, - { - equalityFn: (prevState, currentState) => { - if ( - isRouteParametersChanged({ - store: 'bestRoute', - prevState, - currentState, - }) - ) - return false; - else return true; - }, - } - ); - - useSettingsStore.subscribe( - (state) => ({ - slippage: state.slippage, - customSlippage: state.customSlippage, - disabledLiquiditySources: state.disabledLiquiditySources, - infiniteApprove: state.infiniteApprove, - }), - bestRouteParamsListener, - { - equalityFn: (prevState, currentState) => { - if ( - isRouteParametersChanged({ - store: 'settings', - prevState, - currentState, - }) - ) - return false; - else return true; - }, - } - ); - - return { fetchBestRoute }; -}; - -export const { fetchBestRoute } = bestRoute( - useBestRouteStore, - useSettingsStore -); diff --git a/widget/embedded/src/store/meta.ts b/widget/embedded/src/store/meta.ts deleted file mode 100644 index a0869ad547..0000000000 --- a/widget/embedded/src/store/meta.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { create } from 'zustand'; -import { MetaResponse } from 'rango-sdk'; -import { httpService } from '../services/httpService'; -import createSelectors from './selectors'; -import { removeDuplicateFrom } from '../utils/common'; - -export type LoadingStatus = 'loading' | 'success' | 'failed'; - -export interface MetaState { - meta: MetaResponse; - loadingStatus: LoadingStatus; - fetchMeta: () => Promise; -} - -export const useMetaStore = createSelectors( - create()((set) => ({ - meta: { blockchains: [], popularTokens: [], swappers: [], tokens: [] }, - loadingStatus: 'loading', - fetchMeta: async () => { - try { - const response = await httpService().getAllMetadata(); - const chainThatHasTokenInMetaResponse = removeDuplicateFrom( - response.tokens.map((t) => t.blockchain) - ); - const enabledChains = response.blockchains.filter( - (chain) => - chain.enabled && - chainThatHasTokenInMetaResponse.includes(chain.name) - ); - response.blockchains = enabledChains.sort((a, b) => a.sort - b.sort); - set({ meta: response, loadingStatus: 'success' }); - } catch (error) { - set({ loadingStatus: 'failed' }); - } - }, - })) -); diff --git a/widget/embedded/src/store/notification.ts b/widget/embedded/src/store/notification.ts new file mode 100644 index 0000000000..a0e9764415 --- /dev/null +++ b/widget/embedded/src/store/notification.ts @@ -0,0 +1,136 @@ +import type { Notification } from '../types/notification'; + +import { + type PendingSwapWithQueueID, + type Route, + type RouteEvent, + type StepEvent, +} from '@rango-dev/queue-manager-rango-preset'; +import { create } from 'zustand'; +import { persist, subscribeWithSelector } from 'zustand/middleware'; + +import createSelectors from './selectors'; + +export interface NotificationState { + isSynced: boolean; + notifications: Notification[]; + setNotification: (event: RouteEvent | StepEvent, route: Route) => void; + removeNotification: (requestId: Notification['requestId']) => void; + getNotifications: () => Notification[]; + syncNotifications: (swaps: PendingSwapWithQueueID[]) => void; + clearNotifications: () => void; +} + +export const useNotificationStore = createSelectors( + create()( + persist( + subscribeWithSelector((set, get) => ({ + isSynced: false, + notifications: [], + setNotification: (event, route) => { + const fromStep = route.steps[0]; + const toStep = route.steps[route.steps.length - 1]; + + const notification: Notification = { + event, + creationTime: Date.now(), + requestId: route.requestId, + route: { + creationTime: parseInt(route.creationTime), + from: { + blockchain: fromStep.fromBlockchain, + address: fromStep.fromSymbolAddress, + symbol: fromStep.fromSymbol, + }, + to: { + blockchain: toStep.toBlockchain, + address: toStep.toSymbolAddress, + symbol: toStep.toSymbol, + }, + }, + }; + + const excludedList = get().notifications.filter( + (notificationItem) => notificationItem.requestId !== route.requestId + ); + + set(() => ({ + notifications: [...excludedList, notification], + })); + }, + removeNotification: (requestId) => { + set((state) => ({ + notifications: state.notifications.filter( + (notification) => notification.requestId !== requestId + ), + })); + }, + getNotifications: () => { + const { isSynced, notifications } = get(); + return isSynced + ? notifications.sort((a, b) => { + if (a.route.creationTime && !b.route.creationTime) { + return -1; + } + if (!a.route.creationTime && b.route.creationTime) { + return 1; + } + if (!a.route.creationTime && !b.route.creationTime) { + return b.creationTime - a.creationTime; + } + return b.route.creationTime - a.route.creationTime; + }) + : []; + }, + syncNotifications: (swaps) => { + const { isSynced, notifications } = get(); + + if (!isSynced) { + const nextNotifications: Notification[] = []; + notifications.forEach((notification) => { + const swapExist = swaps.some( + (swap) => swap.swap.requestId === notification.requestId + ); + if (swapExist) { + nextNotifications.push(notification); + } + }); + + set({ isSynced: true, notifications: nextNotifications }); + } + }, + clearNotifications: () => set({ notifications: [] }), + })), + + { + name: 'notification', + skipHydration: true, + partialize: ({ isSynced, ...otherProps }) => otherProps, + version: 1, + migrate: (persistedState, version) => { + if (version === 0) { + /** + * Eliminate the persistence of read notifications, + * and remove the "read" flag from other notifications to align with the current modifications in the notification store structure. + */ + const oldNotifications = ( + persistedState as { + notifications: (Notification & { read: boolean })[]; + } + ).notifications; + + (persistedState as NotificationState).notifications = + oldNotifications + .filter( + (notification: Notification & { read: boolean }) => + !notification.read + ) + .map(({ read, ...otherProps }) => otherProps); + } + + return persistedState as NotificationState; + }, + } + ) + ) +); diff --git a/widget/embedded/src/store/quote.ts b/widget/embedded/src/store/quote.ts new file mode 100644 index 0000000000..81ac910fe5 --- /dev/null +++ b/widget/embedded/src/store/quote.ts @@ -0,0 +1,356 @@ +import type { + BlockchainMeta, + MetaResponse, + MultiRouteResponse, + PreferenceType, + Token, +} from 'rango-sdk'; + +import BigNumber from 'bignumber.js'; +import { create } from 'zustand'; +import { subscribeWithSelector } from 'zustand/middleware'; + +import { ZERO } from '../constants/numbers'; +import { eventEmitter } from '../services/eventEmitter'; +import { + type QuoteError, + QuoteEventTypes, + type QuoteWarning, + type SelectedQuote, + type Wallet, + WidgetEvents, +} from '../types'; +import { isPositiveNumber } from '../utils/numbers'; +import { getUsdInputFrom, getUsdOutputFrom } from '../utils/swap'; + +import createSelectors from './selectors'; + +export const getUsdValue = ( + token: Token | null, + amount: string +): BigNumber | null => + token?.usdPrice + ? new BigNumber(amount || ZERO).multipliedBy(token?.usdPrice || 0) + : null; + +export type Meta = Pick; + +export type SetTokenParams = { token: Token; meta: Meta } | { token: null }; + +type SomeQuoteState = { + quotes: MultiRouteResponse | null; + sortStrategy: PreferenceType; + refetchQuote: boolean; + error: QuoteError | null; + warning: QuoteWarning | null; +}; +export type RetryQuote = { + fromBlockchain: BlockchainMeta | null; + fromToken?: Token; + toBlockchain: BlockchainMeta | null; + toToken?: Token; + inputAmount: string; +}; +export interface QuoteState { + fromBlockchain: BlockchainMeta | null; + toBlockchain: BlockchainMeta | null; + inputAmount: string; + inputUsdValue: BigNumber | null; + outputAmount: BigNumber | null; + outputUsdValue: BigNumber | null; + fromToken: Token | null; + sortStrategy: PreferenceType; + toToken: Token | null; + quoteWalletsConfirmed: boolean; + selectedWallets: Wallet[]; + quoteWarningsConfirmed: boolean; + refetchQuote: boolean; + selectedQuote: SelectedQuote | null; + quotes: MultiRouteResponse | null; + customDestination: string | null; + error: QuoteError | null; + warning: QuoteWarning | null; + resetQuote: () => void; + resetAlerts: () => void; + + resetToBlockchain: () => void; + resetFromBlockchain: () => void; + setFromBlockchain: (chain: BlockchainMeta | null) => void; + setToBlockchain: (chian: BlockchainMeta | null) => void; + setFromToken: (params: SetTokenParams) => void; + setToToken: (params: SetTokenParams) => void; + updateQuotePartialState: ( + key: K, + value: SomeQuoteState[K] + ) => void; + setInputAmount: (amount: string) => void; + setSelectedQuote: (quote: SelectedQuote | null) => void; + retry: (retryQuote: RetryQuote) => void; + switchFromAndTo: () => void; + setQuoteWalletConfirmed: (flag: boolean) => void; + setSelectedWallets: (wallets: Wallet[]) => void; + setCustomDestination: (address: string | null) => void; + resetQuoteWallets: () => void; + setQuoteWarningsConfirmed: (flag: boolean) => void; +} + +export const useQuoteStore = createSelectors( + create()( + subscribeWithSelector((set) => ({ + fromBlockchain: null, + fromToken: null, + inputAmount: '', + outputAmount: null, + inputUsdValue: new BigNumber(0), + outputUsdValue: new BigNumber(0), + toBlockchain: null, + toToken: null, + refetchQuote: true, + sortStrategy: 'SMART', + selectedQuote: null, + quotes: null, + error: null, + warning: null, + quoteWalletsConfirmed: false, + selectedWallets: [], + customDestination: null, + quoteWarningsConfirmed: false, + updateQuotePartialState: (key, value) => + set((state) => ({ + ...state, + [key]: value, + })), + setSelectedQuote: (quote) => + set((state) => { + let outputAmount: BigNumber | null = null; + let outputUsdValue: BigNumber = ZERO; + + let inputUsdValue = state.inputUsdValue; + if (!isPositiveNumber(state.inputAmount)) { + return {}; + } + if (!!quote) { + outputAmount = !!quote?.outputAmount + ? new BigNumber(quote?.outputAmount) + : null; + inputUsdValue = getUsdInputFrom(quote) ?? ZERO; + outputUsdValue = getUsdOutputFrom(quote) ?? ZERO; + } + return { + selectedQuote: quote, + ...(!!quote && { + outputAmount, + outputUsdValue, + inputUsdValue, + }), + }; + }), + resetAlerts: () => + set(() => ({ + error: null, + warning: null, + })), + resetQuote: () => + set(() => ({ + selectedQuote: null, + outputAmount: null, + outputUsdValue: new BigNumber(0), + quotes: null, + refetchQuote: true, + error: null, + warning: null, + })), + setFromBlockchain: (chain) => { + set((state) => { + if (state.fromBlockchain?.name === chain?.name) { + return {}; + } + + return { + fromBlockchain: chain, + inputUsdValue: new BigNumber(0), + ...(state.fromToken && { + selectedQuote: null, + fromToken: null, + outputAmount: null, + outputUsdValue: new BigNumber(0), + }), + }; + }); + }, + setFromToken: (params) => { + return set((state) => ({ + fromToken: params.token, + ...(params.token && { + fromBlockchain: + params.meta.blockchains.find( + (blockchain) => blockchain.name === params.token.blockchain + ) ?? null, + }), + ...(!!state.inputAmount && { + inputUsdValue: getUsdValue(params.token, state.inputAmount), + }), + })); + }, + setToBlockchain: (chain) => { + set((state) => { + if (state.toBlockchain?.name === chain?.name) { + return {}; + } + + return { + toBlockchain: chain, + ...(state.toToken && { + selectedQuote: null, + toToken: null, + outputAmount: null, + outputUsdValue: new BigNumber(0), + }), + }; + }); + }, + setToToken: (params) => { + return set(() => ({ + toToken: params.token, + ...(params.token && { + toBlockchain: + params.meta.blockchains.find( + (blockchain) => blockchain.name === params.token.blockchain + ) ?? null, + }), + })); + }, + setInputAmount: (amount) => { + set((state) => ({ + inputAmount: amount, + ...(!amount && { + outputAmount: null, + outputUsdValue: new BigNumber(0), + selectedQuote: null, + }), + ...(!!state.fromToken && { + inputUsdValue: getUsdValue(state.fromToken, amount), + }), + })); + }, + retry: (retryQuote) => { + const { + fromBlockchain, + fromToken, + toBlockchain, + toToken, + inputAmount, + } = retryQuote; + + set({ + fromBlockchain, + fromToken, + inputAmount, + outputAmount: null, + inputUsdValue: getUsdValue(fromToken ?? null, inputAmount), + outputUsdValue: new BigNumber(0), + toBlockchain, + toToken, + selectedQuote: null, + }); + }, + switchFromAndTo: () => + set((state) => ({ + fromBlockchain: state.toBlockchain, + fromToken: state.toToken, + toBlockchain: state.fromBlockchain, + toToken: state.fromToken, + inputAmount: state.outputAmount?.toString() || '', + inputUsdValue: state.toToken + ? getUsdValue(state.toToken, state.outputAmount?.toString() || '') + : new BigNumber(0), + })), + resetFromBlockchain: () => + set(() => ({ + fromToken: null, + fromBlockchain: null, + outputUsdValue: new BigNumber(0), + inputUsdValue: new BigNumber(0), + inputAmount: '', + outputAmount: null, + selectedQuote: null, + })), + resetToBlockchain: () => + set(() => ({ + toToken: null, + toBlockchain: null, + outputAmount: null, + outputUsdValue: new BigNumber(0), + selectedQuote: null, + })), + setQuoteWalletConfirmed: (flag) => + set({ + quoteWalletsConfirmed: flag, + }), + setSelectedWallets: (wallets) => set({ selectedWallets: wallets }), + setCustomDestination: (address) => set({ customDestination: address }), + resetQuoteWallets: () => + set({ + quoteWalletsConfirmed: false, + selectedWallets: [], + customDestination: null, + }), + setQuoteWarningsConfirmed: (flag) => + set({ quoteWarningsConfirmed: flag }), + })) + ) +); + +export const unsubscribeQuoteStore = useQuoteStore.subscribe( + (selectedState, previousSelectedState) => { + if ( + selectedState.fromBlockchain !== previousSelectedState.fromBlockchain || + selectedState.fromToken !== previousSelectedState.fromToken || + selectedState.toBlockchain !== previousSelectedState.toBlockchain || + selectedState.toToken !== previousSelectedState.toToken || + selectedState.inputAmount !== previousSelectedState.inputAmount + ) { + // useEffect hook can not be used in Zustand subscribe + eventEmitter.emit(WidgetEvents.QuoteEvent, { + type: QuoteEventTypes.QUOTE_INPUT_UPDATE, + payload: { + fromBlockchain: selectedState.fromBlockchain?.name, + toBlockchain: selectedState.toBlockchain?.name, + fromToken: selectedState.fromToken + ? { + symbol: selectedState.fromToken.symbol, + name: selectedState.fromToken.name, + address: selectedState.fromToken.address, + } + : undefined, + toToken: selectedState.toToken + ? { + symbol: selectedState.toToken.symbol, + name: selectedState.toToken.name, + address: selectedState.toToken.address, + } + : undefined, + requestAmount: selectedState.inputAmount, + }, + }); + } + + if ( + selectedState.selectedQuote?.requestId !== + previousSelectedState.selectedQuote?.requestId + ) { + eventEmitter.emit(WidgetEvents.QuoteEvent, { + type: QuoteEventTypes.QUOTE_OUTPUT_UPDATE, + payload: selectedState.selectedQuote + ? { + requestAmount: selectedState.selectedQuote.requestAmount, + swaps: selectedState.selectedQuote.swaps, + outputAmount: selectedState.selectedQuote.outputAmount, + resultType: selectedState.selectedQuote.resultType, + tags: selectedState.selectedQuote.tags, + } + : null, + }); + } + } +); diff --git a/widget/embedded/src/store/selectors.ts b/widget/embedded/src/store/selectors.ts index 6d97e2e995..4b87678b7b 100644 --- a/widget/embedded/src/store/selectors.ts +++ b/widget/embedded/src/store/selectors.ts @@ -1,4 +1,4 @@ -import { StoreApi, UseBoundStore } from 'zustand'; +import type { StoreApi, UseBoundStore } from 'zustand'; type State = object; @@ -6,10 +6,12 @@ type WithSelectors = S extends { getState: () => infer T } ? S & { use: { [K in keyof T]: () => T[K] } } : never; -const createSelectors = >>(_store: S) => { - let store = _store as WithSelectors; +const createSelectors = >>( + _store: S +) => { + const store = _store as WithSelectors; store.use = {}; - for (let k of Object.keys(store.getState())) { + for (const k of Object.keys(store.getState())) { (store.use as any)[k] = () => store((s) => s[k as keyof typeof s]); } diff --git a/widget/embedded/src/store/settings.ts b/widget/embedded/src/store/settings.ts deleted file mode 100644 index 83491a85cf..0000000000 --- a/widget/embedded/src/store/settings.ts +++ /dev/null @@ -1,91 +0,0 @@ -import { create } from 'zustand'; -import { persist, subscribeWithSelector } from 'zustand/middleware'; -import { DEFAULT_SLIPPAGE } from '../constants/swapSettings'; -import { removeDuplicateFrom } from '../utils/common'; -import { useMetaStore } from './meta'; -import createSelectors from './selectors'; - -type Theme = 'auto' | 'dark' | 'light'; - -export interface SettingsState { - slippage: number; - customSlippage: number | null; - infiniteApprove: boolean; - disabledLiquiditySources: string[]; - theme: Theme; - affiliateRef: string | null; - setSlippage: (slippage: number) => void; - setCustomSlippage: (customSlippage: number | null) => void; - toggleInfiniteApprove: () => void; - toggleLiquiditySource: (name: string) => void; - setTheme: (theme: Theme) => void; - toggleAllLiquiditySources: () => void; - setAffiliateRef: (affiliateRef: string | null) => void; -} - -export const useSettingsStore = createSelectors( - create()( - persist( - subscribeWithSelector((set) => ({ - slippage: DEFAULT_SLIPPAGE, - customSlippage: null, - infiniteApprove: false, - affiliateRef: null, - disabledLiquiditySources: [], - theme: 'auto', - setSlippage: (slippage) => - set(() => ({ - slippage: slippage, - })), - setCustomSlippage: (customSlippage) => - set(() => ({ - customSlippage: customSlippage, - })), - setAffiliateRef: (affiliateRef) => - set(() => ({ - affiliateRef, - })), - toggleAllLiquiditySources: () => - set((state) => { - const { swappers } = useMetaStore.getState().meta; - const swappersGroup = removeDuplicateFrom( - swappers.map((swapper) => swapper.swapperGroup) - ); - - if (swappersGroup.length === state.disabledLiquiditySources.length) - return { disabledLiquiditySources: [] }; - else { - return { - disabledLiquiditySources: swappersGroup, - }; - } - }), - toggleInfiniteApprove: () => - set((state) => ({ - infiniteApprove: !state.infiniteApprove, - })), - toggleLiquiditySource: (name) => - set((state) => { - if (state.disabledLiquiditySources.includes(name)) - return { - disabledLiquiditySources: state.disabledLiquiditySources.filter( - (liquiditySource) => liquiditySource != name - ), - }; - else - return { - disabledLiquiditySources: - state.disabledLiquiditySources.concat(name), - }; - }), - setTheme: (theme) => - set(() => ({ - theme, - })), - })), - { - name: 'user-settings', - } - ) - ) -); diff --git a/widget/embedded/src/store/slices/config.ts b/widget/embedded/src/store/slices/config.ts new file mode 100644 index 0000000000..676b5bf053 --- /dev/null +++ b/widget/embedded/src/store/slices/config.ts @@ -0,0 +1,239 @@ +import type { DataSlice } from './data'; +import type { SettingsSlice } from './settings'; +import type { WidgetConfig } from '../../types'; +import type { StateCreatorWithInitialData } from '../app'; + +import { allProviders as getAllProviders } from '@rango-dev/provider-all'; +import { type VersionedProviders } from '@rango-dev/wallets-core'; + +import { cacheService } from '../../services/cacheService'; +import { + matchAndGenerateProviders, + type ProvidersOptions, +} from '../../utils/providers'; +import { matchTokensFromConfigWithMeta } from '../utils'; + +function makeProvidersOptionsFromConfig( + config: WidgetConfig +): ProvidersOptions { + const options: ProvidersOptions = { + walletConnectProjectId: config?.walletConnectProjectId, + trezorManifest: config?.trezorManifest, + tonConnect: config?.tonConnect, + walletConnectListedDesktopWalletLink: + config.__UNSTABLE_OR_INTERNAL__?.walletConnectListedDesktopWalletLink, + experimentalWallet: config.features?.experimentalWallet, + }; + + return options; +} + +export const DEFAULT_CONFIG: WidgetConfig = { + apiKey: '', + title: undefined, + multiWallets: true, + excludeLiquiditySources: true, + customDestination: true, + variant: 'default', + trezorManifest: { + appUrl: 'https://widget.rango.exchange/', + email: 'hi+trezorwidget@rango.exchange', + }, + tonConnect: { + manifestUrl: + 'https://raw.githubusercontent.com/rango-exchange/rango-types/main/assets/manifests/tonconnect-manifest.json', + }, + features: { + experimentalWallet: 'enabled', + }, +}; + +interface IframeConfigs { + clientUrl?: string; +} + +interface CampaignMode { + liquiditySources?: string[]; +} + +const DEFAULT_IFRAME_CONFIGS: IframeConfigs = { + clientUrl: undefined, +}; + +const DEFAULT_CAMPAIGN_MODE: CampaignMode = { + liquiditySources: undefined, +}; + +export interface ConfigSlice { + // What user can set directly. + config: WidgetConfig; + campaignMode: CampaignMode; + isInCampaignMode: () => boolean; + getLiquiditySources: () => string[]; + getDisabledLiquiditySources: () => string[]; + excludeLiquiditySources: () => boolean; + updateConfig: (config: WidgetConfig) => void; + updateCampaignMode: ( + name: K, + value: CampaignMode[K] + ) => void; + // What we are setting based on environments. + iframe: { clientUrl?: string }; + updateIframe: ( + name: K, + value: IframeConfigs[K] + ) => void; + allProviders: VersionedProviders[]; + buildAndSetProviders: () => void; + getAvailableProviders: () => VersionedProviders[]; +} + +function generateProviders(config: WidgetConfig) { + const options = makeProvidersOptionsFromConfig(config); + const envs = { + walletconnect2: { + WC_PROJECT_ID: options?.walletConnectProjectId || '', + DISABLE_MODAL_AND_OPEN_LINK: + options?.walletConnectListedDesktopWalletLink, + }, + selectedProviders: config.wallets, + trezor: options?.trezorManifest + ? { manifest: options.trezorManifest } + : undefined, + tonConnect: options?.tonConnect?.manifestUrl + ? { manifestUrl: options?.tonConnect.manifestUrl } + : undefined, + }; + const allProviders = getAllProviders(envs); + const allBuiltProviders = allProviders.map((build) => build()); + + return allBuiltProviders; +} + +export const createConfigSlice: StateCreatorWithInitialData< + WidgetConfig, + ConfigSlice & SettingsSlice & DataSlice, + ConfigSlice +> = (initialData, set, get) => { + const allBuiltProviders = generateProviders({ + ...DEFAULT_CONFIG, + ...initialData, + }); + return { + config: { ...DEFAULT_CONFIG, ...initialData }, + iframe: DEFAULT_IFRAME_CONFIGS, + campaignMode: DEFAULT_CAMPAIGN_MODE, + allProviders: allBuiltProviders, + getLiquiditySources: () => { + const { config, campaignMode } = get(); + return campaignMode.liquiditySources?.length + ? campaignMode.liquiditySources + : config.liquiditySources ?? []; + }, + getDisabledLiquiditySources: () => { + const { disabledLiquiditySources, campaignMode } = get(); + return campaignMode.liquiditySources?.length + ? [] + : disabledLiquiditySources; + }, + excludeLiquiditySources: () => { + const { config, campaignMode } = get(); + return campaignMode.liquiditySources?.length + ? false + : !!config.excludeLiquiditySources; + }, + isInCampaignMode: () => { + const { campaignMode } = get(); + return !!campaignMode.liquiditySources?.length; + }, + + // Actions + updateConfig: (nextConfig: WidgetConfig) => { + const currentConfig = get().config; + const { + _tokensMapByTokenHash: tokensMapByTokenHash, + _tokensMapByBlockchainName: tokensMapByBlockchainName, + } = get(); + + const supportedSourceTokens = matchTokensFromConfigWithMeta({ + type: 'source', + config: { + blockchains: nextConfig.from?.blockchains, + tokens: nextConfig.from?.tokens, + }, + meta: { + tokensMapByBlockchainName, + tokensMapByTokenHash, + }, + }); + + const supportedDestinationTokens = matchTokensFromConfigWithMeta({ + type: 'destination', + config: { + blockchains: nextConfig.to?.blockchains, + tokens: nextConfig.to?.tokens, + }, + meta: { + tokensMapByBlockchainName, + tokensMapByTokenHash, + }, + }); + + cacheService.set('supportedSourceTokens', supportedSourceTokens); + cacheService.set( + 'supportedDestinationTokens', + supportedDestinationTokens + ); + + set({ + config: { + ...currentConfig, + ...nextConfig, + }, + }); + }, + + updateCampaignMode: (name, value) => { + const currentCampaignMode = get().campaignMode; + + set({ + campaignMode: { + ...currentCampaignMode, + [name]: value, + }, + }); + }, + + updateIframe: (name, value) => { + const currentIframeConfig = get().iframe; + + set({ + iframe: { + ...currentIframeConfig, + [name]: value, + }, + }); + }, + + buildAndSetProviders: () => { + const { config } = get(); + const allBuiltProviders = generateProviders(config); + + set({ + allProviders: allBuiltProviders, + }); + }, + + getAvailableProviders: () => { + const { allProviders, config } = get(); + const options = makeProvidersOptionsFromConfig(config); + + const availableProviders = matchAndGenerateProviders({ + allProviders, + configWallets: config.wallets, + options, + }); + return availableProviders; + }, + }; +}; diff --git a/widget/embedded/src/store/slices/data.test.ts b/widget/embedded/src/store/slices/data.test.ts new file mode 100644 index 0000000000..e76c8fe339 --- /dev/null +++ b/widget/embedded/src/store/slices/data.test.ts @@ -0,0 +1,459 @@ +import type { WidgetConfig } from '../../types'; +import type { AppStoreState } from '../app'; +import type { EvmBlockchainMeta, Token } from 'rango-sdk'; + +import { assert, beforeEach, describe, expect, test } from 'vitest'; + +import { cacheService } from '../../services/cacheService'; +import { + createEvmBlockchain, + createInitialAppStore, + createToken, + updateAppStoreConfig, +} from '../../test-utils/fixtures'; +import { createTokenHash } from '../../utils/meta'; +import { createAppStore } from '../app'; + +let appStoreState: AppStoreState; +let customTokens: [Token, Token, Token]; +let rangoBlockchain: EvmBlockchainMeta; + +const DEFAULT_CONFIG: WidgetConfig = { + apiKey: '', + walletConnectProjectId: 'e24844c5deb5193c1c14840a7af6a40b', + title: undefined, + multiWallets: true, + excludeLiquiditySources: true, + customDestination: true, + variant: 'default', + trezorManifest: { + appUrl: 'https://widget.rango.exchange/', + email: 'hi+trezorwidget@rango.exchange', + }, + tonConnect: { + manifestUrl: + 'https://raw.githubusercontent.com/rango-exchange/rango-types/main/assets/manifests/tonconnect-manifest.json', + }, + features: { + experimentalWallet: 'enabled', + }, +}; + +beforeEach(() => { + cacheService.clear(); + rangoBlockchain = createEvmBlockchain(); + + customTokens = [ + { + ...createToken(), + symbol: 'RNG', + name: 'Rango', + blockchain: rangoBlockchain.name, + address: '0x0000000000000000068701000000000000000000', + isSecondaryCoin: false, + isPopular: false, + }, + { + ...createToken(), + symbol: 'DJG', + name: 'Django', + blockchain: rangoBlockchain.name, + isSecondaryCoin: false, + isPopular: false, + }, + { + ...createToken(), + symbol: 'RABO', + name: 'Rainbow', + blockchain: rangoBlockchain.name, + isSecondaryCoin: false, + isPopular: false, + }, + ]; + + const initData = createInitialAppStore(); + initData._blockchainsMapByName.set(rangoBlockchain.name, rangoBlockchain); + customTokens.forEach((token) => { + const tokenHash = createTokenHash(token); + initData._tokensMapByTokenHash.set(tokenHash, token); + if (!initData._tokensMapByBlockchainName[token.blockchain]) { + initData._tokensMapByBlockchainName[token.blockchain] = []; + } + initData._tokensMapByBlockchainName[token.blockchain].push(tokenHash); + }); + + const appStore = createAppStore(DEFAULT_CONFIG); + appStore.setState(initData); + appStoreState = appStore.getState(); +}); + +describe('check sorting tokens is working correctly in app store', () => { + test('put pinned tokens first', () => { + const rangoToken = customTokens[0]; + + appStoreState = updateAppStoreConfig(appStoreState, { + from: { + pinnedTokens: [ + { + symbol: rangoToken.symbol, + address: rangoToken.address, + blockchain: rangoToken.blockchain, + }, + ], + }, + }); + + const tokens = appStoreState.tokens({ + type: 'source', + }); + + const firstResult = tokens[0].symbol; + expect(firstResult).toBe(rangoToken.symbol); + }); + + test('put tokens with balances first', () => { + const rangoToken = customTokens[0]; + + const tokens = appStoreState.tokens({ + type: 'source', + getBalanceFor: (token: Token) => { + if (token.symbol === rangoToken.symbol) { + return { + amount: '100', + decimals: 12, + usdValue: '5000', + }; + } + return null; + }, + }); + + const firstResult = tokens[0].symbol; + expect(firstResult).toBe(rangoToken.symbol); + }); + + test('put native tokens first', () => { + const rangoToken = customTokens[0]; + appStoreState._blockchainsMapByName.set(rangoToken.blockchain, { + ...rangoBlockchain, + feeAssets: [ + { + address: rangoToken.address, + blockchain: rangoToken.blockchain, + symbol: rangoToken.symbol, + }, + ], + }); + + const tokens = appStoreState.tokens({ + type: 'source', + }); + + const firstResult = tokens[0].symbol; + expect(firstResult).toBe(rangoToken.symbol); + }); + + test('put popular tokens first', () => { + const tokens = appStoreState.tokens({ + type: 'source', + }); + const popularTokensCount = tokens.reduce((previousValue, current) => { + if (current.isPopular) { + return previousValue + 1; + } + return previousValue; + }, 0); + + /* + * Getting an slice of tokens which is equals to how many popular tokens exist + * then we can check all of them should be on top of the list + */ + const result = tokens.slice(0, popularTokensCount); + assert(result.every((token) => token.isPopular === true)); + }); + + test('put secondary tokens at the end of list', () => { + const tokens = appStoreState.tokens({ + type: 'source', + }); + expect(tokens[tokens.length - 1]?.isSecondaryCoin).toBe(true); + }); + + test('put popular token with lowest blockchain sort at first', () => { + const rangoToken = customTokens[0]; + const token = appStoreState.findToken(rangoToken); + if (token) { + token.isPopular = true; + } + appStoreState._blockchainsMapByName.set(rangoToken.blockchain, { + ...rangoBlockchain, + sort: 0, + }); + + const tokens = appStoreState.tokens({ + type: 'source', + }); + + const firstResult = tokens[0].symbol; + expect(firstResult).toBe(rangoToken.symbol); + }); + + test('put pinned token first and tokens with balances second', () => { + const rangoToken = customTokens[0]; + const djangoToken = customTokens[1]; + + appStoreState = updateAppStoreConfig(appStoreState, { + from: { + pinnedTokens: [ + { + symbol: rangoToken.symbol, + address: rangoToken.address, + blockchain: rangoToken.blockchain, + }, + ], + }, + }); + + const tokens = appStoreState.tokens({ + type: 'source', + getBalanceFor: (token: Token) => { + if (token.symbol === djangoToken.symbol) { + return { + amount: '100', + decimals: 12, + usdValue: '5000', + }; + } + return null; + }, + }); + + const firstResult = tokens[0].symbol; + const secondResult = tokens[1].symbol; + expect(firstResult).toBe(rangoToken.symbol); + expect(secondResult).toBe(djangoToken.symbol); + }); + + test('put pinned token first and tokens with balances second and popular tokens followed', () => { + const rangoToken = customTokens[0]; + const djangoToken = customTokens[1]; + + appStoreState = updateAppStoreConfig(appStoreState, { + from: { + pinnedTokens: [ + { + symbol: rangoToken.symbol, + address: rangoToken.address, + blockchain: rangoToken.blockchain, + }, + ], + }, + }); + + const tokens = appStoreState.tokens({ + type: 'source', + getBalanceFor: (token: Token) => { + if (token.symbol === djangoToken.symbol) { + return { + amount: '100', + decimals: 12, + usdValue: '5000', + }; + } + return null; + }, + }); + + const firstResult = tokens[0].symbol; + const secondResult = tokens[1].symbol; + + const popularTokensCount = tokens.reduce((previousValue, current) => { + if (current.isPopular) { + return previousValue + 1; + } + return previousValue; + }, 0); + const popularResult = tokens.slice(2, popularTokensCount); + + expect(firstResult).toBe(rangoToken.symbol); + expect(secondResult).toBe(djangoToken.symbol); + assert(popularResult.every((token) => token.isPopular === true)); + }); +}); + +describe('search in tokens', () => { + test('should be first result when the symbol is exactly equal to the search term', () => { + const tokens = appStoreState.tokens({ + type: 'source', + searchFor: 'rng', + }); + const firstResult = tokens[0]?.symbol; + expect(firstResult).toBe('RNG'); + }); + + test('should be first result when the token name is exactly equal to the search term', () => { + const tokens = appStoreState.tokens({ + type: 'source', + searchFor: 'Rango', + }); + + const firstResult = tokens[0]?.symbol; + expect(firstResult).toBe('RNG'); + }); + + test('should be first result when symbol characters starts with search term ', () => { + const tokens = appStoreState.tokens({ + type: 'source', + searchFor: 'dj', + }); + + const firstResult = tokens[0]?.symbol; + expect(firstResult).toBe('DJG'); + }); + + test('should be first result when symbol characters contains search term', () => { + const tokens = appStoreState.tokens({ + type: 'source', + searchFor: 'abo', + }); + + const firstResult = tokens[0]?.symbol; + expect(firstResult).toBe('RABO'); + }); + + test('should be first result when token name characters starts with search term', () => { + const tokens = appStoreState.tokens({ + type: 'source', + searchFor: 'rang', + }); + + const firstResult = tokens[0]?.symbol; + expect(firstResult).toBe('RNG'); + }); + + test('should be first result when token name characters contains search term', () => { + const tokens = appStoreState.tokens({ + type: 'source', + searchFor: 'ngo', + }); + + // If there is more than one result, priority is given to the string that is shorter + const firstResult = tokens[0]?.symbol; + expect(firstResult).toBe('RNG'); + }); + + test('should be first result when address contains searched term', () => { + const tokens = appStoreState.tokens({ + type: 'source', + searchFor: '68701', + }); + + const firstResult = tokens[0]?.symbol; + expect(firstResult).toBe('RNG'); + }); + + test('put pinned token first and popular tokens followed when token name or symbol contains search term', () => { + const djangoToken = customTokens[1]; + + appStoreState = updateAppStoreConfig(appStoreState, { + from: { + pinnedTokens: [ + { + symbol: djangoToken.symbol, + address: djangoToken.address, + blockchain: djangoToken.blockchain, + }, + ], + }, + }); + + const tokens = appStoreState.tokens({ + type: 'source', + searchFor: 'ngo', + }); + + const firstResult = tokens[0]?.symbol; + const secondResult = tokens[1]?.symbol; + + expect(firstResult).toBe(djangoToken.symbol); + expect(secondResult).toBe('RNG'); + }); +}); + +describe('supported tokens from config', () => { + test('Should ensure tokens include only tokens from the config', () => { + const rangoToken = customTokens[0]; + const djangoToken = customTokens[1]; + + const configTokens = [rangoToken, djangoToken]; + + appStoreState = updateAppStoreConfig(appStoreState, { + from: { + tokens: configTokens, + }, + to: { tokens: configTokens }, + }); + + let sourceTokens = appStoreState.tokens({ + type: 'source', + }); + + let destinationTokens = appStoreState.tokens({ + type: 'destination', + }); + + expect(configTokens).toMatchObject(sourceTokens); + expect(configTokens).toMatchObject(destinationTokens); + + appStoreState = updateAppStoreConfig(appStoreState, { + from: { + blockchains: [rangoBlockchain.name], + tokens: { + [rangoBlockchain.name]: { + tokens: configTokens, + isExcluded: false, + }, + }, + }, + to: { + blockchains: [rangoBlockchain.name], + tokens: { + [rangoBlockchain.name]: { + tokens: configTokens, + isExcluded: false, + }, + }, + }, + }); + + sourceTokens = appStoreState.tokens({ + type: 'source', + }); + + destinationTokens = appStoreState.tokens({ + type: 'destination', + }); + + expect(sourceTokens).toMatchObject(sourceTokens); + expect(configTokens).toMatchObject(destinationTokens); + }); + + test('Check tokens calculation is caching', () => { + const rangoToken = customTokens[0]; + const djangoToken = customTokens[1]; + + appStoreState = updateAppStoreConfig(appStoreState, { + from: { + tokens: [rangoToken, djangoToken], + }, + }); + + expect(cacheService.get('supportedSourceTokens')?.length ?? 0).toBe(0); + + appStoreState.tokens({ + type: 'source', + }); + + expect(cacheService.get('supportedSourceTokens')?.length ?? 0).toBe(2); + }); +}); diff --git a/widget/embedded/src/store/slices/data.ts b/widget/embedded/src/store/slices/data.ts new file mode 100644 index 0000000000..a28610d786 --- /dev/null +++ b/widget/embedded/src/store/slices/data.ts @@ -0,0 +1,396 @@ +// We keep all the received data from server in this slice + +import type { ConfigSlice } from './config'; +import type { SettingsSlice } from './settings'; +import type { CachedEntries } from '../../services/cacheService'; +import type { Balance, Blockchain, TokenHash } from '../../types'; +import type { StateCreator } from 'zustand'; + +import { + type Asset, + type BlockchainMeta, + type SwapperMeta, + type Token, +} from 'rango-sdk'; + +import { ACTIVE_BLOCKCHAINS_FOR_CUSTOM_TOKENS } from '../../constants/customTokens'; +import { cacheService } from '../../services/cacheService'; +import { httpService as sdk } from '../../services/httpService'; +import { compareWithSearchFor, containsText } from '../../utils/common'; +import { createTokenHash, isTokenNative } from '../../utils/meta'; +import { + addCustomTokensToSupportedTokens, + isRoutingEnabled, + sortLiquiditySourcesByGroupTitle, +} from '../../utils/settings'; +import { areTokensEqual, compareTokenBalance } from '../../utils/wallets'; +import { + getSupportedBlockchainsFromConfig, + matchTokensFromConfigWithMeta, +} from '../utils'; + +type BlockchainOptions = { + type?: 'source' | 'destination' | 'custom-token'; +}; + +type TokenOptions = { + type: 'source' | 'destination'; + // filter by an specific blockchain + blockchain?: string; + searchFor?: string; + getBalanceFor?: (token: Token) => Balance | null; +}; + +export type FindToken = (asset: Asset) => Token | undefined; + +export type FetchStatus = 'loading' | 'success' | 'failed'; +export interface DataSlice { + _blockchainsMapByName: Map; + _tokensMapByTokenHash: Map; + _tokensMapByBlockchainName: Record; + _popularTokens: Token[]; + _swappers: SwapperMeta[]; + fetchStatus: FetchStatus; + blockchains: (options?: BlockchainOptions) => BlockchainMeta[]; + tokens: (options?: TokenOptions) => Token[]; + swappers: () => SwapperMeta[]; + isTokenPinned: (token: Token, type: 'source' | 'destination') => boolean; + findToken: FindToken; + fetch: () => Promise; +} + +export const createDataSlice: StateCreator< + DataSlice & ConfigSlice & SettingsSlice, + [], + [], + DataSlice +> = (set, get) => ({ + // State + _blockchainsMapByName: new Map(), + _tokensMapByTokenHash: new Map(), + _tokensMapByBlockchainName: {}, + _popularTokens: [], + _swappers: [], + fetchStatus: 'loading', + // Selectors + blockchains: (options) => { + const blockchainsMapByName = get()._blockchainsMapByName; + const blockchainsFromState = Array.from( + blockchainsMapByName?.values() || [] + ); + + if (!options || !options?.type) { + return blockchainsFromState; + } + const config = get().config; + + if (options.type === 'custom-token') { + const supportedBlockchainsFromConfig = getSupportedBlockchainsFromConfig({ + config, + }); + + let supportedBlockchains: BlockchainMeta[] = blockchainsFromState; + + /* + * Supported blockchains can be configured and be limited. + * In this case, we only keep those active blockchains which exist in config. + */ + if (supportedBlockchainsFromConfig.length > 0) { + supportedBlockchains = supportedBlockchains.filter((blockchain) => + supportedBlockchainsFromConfig.includes(blockchain.name) + ); + } + + return supportedBlockchains.filter((blockchain) => + ACTIVE_BLOCKCHAINS_FOR_CUSTOM_TOKENS.includes(blockchain.type) + ); + } + + const supportedBlockchainsFromConfig = + (options.type === 'source' + ? config.from?.blockchains + : config.to?.blockchains) ?? []; + + const list = blockchainsFromState.filter((blockchain) => { + if ( + supportedBlockchainsFromConfig.length > 0 && + !supportedBlockchainsFromConfig.includes(blockchain.name) + ) { + return false; + } + + return true; + }); + + return list; + }, + tokens: (options) => { + const { + _tokensMapByTokenHash, + _tokensMapByBlockchainName, + config, + _customTokens, + } = get(); + const tokensFromState = Array.from(_tokensMapByTokenHash.values()); + const blockchainsMapByName = get()._blockchainsMapByName; + if (!options || !options.type) { + return tokensFromState; + } + + const configType = options.type === 'source' ? 'from' : 'to'; + const cacheKey: keyof CachedEntries = + options.type === 'source' + ? 'supportedSourceTokens' + : 'supportedDestinationTokens'; + + let supportedTokens = cacheService.get(cacheKey); + if (!supportedTokens?.length) { + supportedTokens = matchTokensFromConfigWithMeta({ + type: options.type, + config: { + blockchains: config[configType]?.blockchains, + tokens: config[configType]?.tokens, + }, + meta: { + tokensMapByTokenHash: _tokensMapByTokenHash, + tokensMapByBlockchainName: _tokensMapByBlockchainName, + }, + }); + cacheService.set(cacheKey, supportedTokens); + } + + supportedTokens = addCustomTokensToSupportedTokens( + supportedTokens, + _customTokens, + config.features + ); + + const blockchains = get().blockchains({ + type: options.type, + }); + + const list = supportedTokens + .filter((token) => { + // If a specific blockchain has passed, we only keep that blockchain's tokens. + if (!!options.blockchain && token.blockchain !== options.blockchain) { + return false; + } + + // Check only available blockchains + if ( + !blockchains.some((blockchain) => { + return blockchain.name === token.blockchain; + }) + ) { + return false; + } + + // Search functionality + if (options.searchFor) { + if ( + containsText(token.symbol, options.searchFor) || + containsText(token.address || '', options.searchFor) || + containsText(token.name || '', options.searchFor) + ) { + return true; + } + + return false; + } + + return true; + }) + .sort((tokenA, tokenB) => { + //1. sort by pinned tokens + const isToken1Pinned = get().isTokenPinned(tokenA, options.type); + const isToken2Pinned = get().isTokenPinned(tokenB, options.type); + if (isToken1Pinned !== isToken2Pinned) { + return isToken1Pinned ? -1 : 1; + } + + //2. sort by balance + if (options.getBalanceFor) { + const token1Balance = options.getBalanceFor(tokenA); + const token2Balance = options.getBalanceFor(tokenB); + const balanceCompare = compareTokenBalance( + token1Balance, + token2Balance + ); + if (balanceCompare !== 0) { + return balanceCompare; + } + } + + const blockChainA = blockchainsMapByName.get(tokenA.blockchain); + const blockChainB = blockchainsMapByName.get(tokenB.blockchain); + + //3. sort by native token + const isNativeTokenA = isTokenNative(tokenA, blockChainA); + const isNativeTokenB = isTokenNative(tokenB, blockChainB); + if (isNativeTokenA !== isNativeTokenB) { + return isNativeTokenA ? -1 : 1; + } + + //4. sort by token popularity + if (tokenA.isPopular !== tokenB.isPopular) { + return tokenA.isPopular ? -1 : 1; + } + + //5. sort by search phrase + if (options.searchFor) { + const symbolSearchForCompare = compareWithSearchFor( + tokenA, + tokenB, + options.searchFor + ); + if (symbolSearchForCompare) { + return symbolSearchForCompare; + } + } + + //6. sort by token isSecondary + if (tokenA.isSecondaryCoin !== tokenB.isSecondaryCoin) { + return tokenA.isSecondaryCoin ? 1 : -1; + } + + //7. sort by blockchain order + if (!!blockChainA && !!blockChainB) { + return blockChainA.sort - blockChainB.sort; + } + + return 0; + }); + + return list; + }, + findToken: (asset) => { + const tokensMapByHashToken = get()._tokensMapByTokenHash; + const customTokens = get().customTokens(); + const tokenHash = createTokenHash(asset); + let token = tokensMapByHashToken.get(tokenHash); + if (!token) { + token = customTokens.find( + (customToken) => createTokenHash(customToken) === tokenHash + ); + } + return token; + }, + isTokenPinned: (token, type) => { + const pinnedTokens = + type === 'source' + ? get().config.from?.pinnedTokens + : get().config.to?.pinnedTokens; + const pinned = !!pinnedTokens?.some((pinnedToken) => + areTokensEqual(pinnedToken, token) + ); + return pinned; + }, + swappers: () => { + const { config, campaignMode } = get(); + + const campaignModeLiquiditySource = campaignMode.liquiditySources?.length + ? campaignMode.liquiditySources + : null; + + const liquiditySources = + campaignModeLiquiditySource ?? config.liquiditySources; + + const excludeLiquiditySources = campaignModeLiquiditySource + ? false + : config.excludeLiquiditySources; + + /* + * If the excludeLiquiditySources flag is set to true, we return all swappers that are not included in the config. + * Otherwise, we return all swappers that are included in the config. + */ + const swappers = get()._swappers.filter((swapper) => { + const swapperGroupIncludedInLiquiditySources = liquiditySources?.includes( + swapper.swapperGroup + ); + + const shouldExcludeLiquiditySources = + excludeLiquiditySources || + !liquiditySources || + liquiditySources.length === 0; + + return shouldExcludeLiquiditySources + ? !swapperGroupIncludedInLiquiditySources + : swapperGroupIncludedInLiquiditySources; + }); + + const sortedSwappers = swappers.sort(sortLiquiditySourcesByGroupTitle); + + return sortedSwappers; + }, + // Actions + fetch: async () => { + try { + const { routing } = get().config; + const enableCentralizedSwappers = isRoutingEnabled( + 'enableCentralizedSwappers', + routing + ); + + const response = await sdk().getAllMetadata({ + enableCentralizedSwappers, + }); + set({ fetchStatus: 'success' }); + const blockchainsMapByName: Map = new Map< + string, + BlockchainMeta + >(); + + const tokensMapByTokenHash: Map = new Map< + TokenHash, + Token + >(); + const tokensMapByBlockchainName: DataSlice['_tokensMapByBlockchainName'] = + {}; + const tokens: Token[] = []; + const popularTokens: Token[] = response.popularTokens; + const swappers: SwapperMeta[] = response.swappers.filter( + (swapper) => swapper.enabled + ); + const blockchainsWithAtLeastOneToken = new Set(); + + response.tokens.forEach((token) => { + blockchainsWithAtLeastOneToken.add(token.blockchain); + + tokens.push(token); + }); + + const sortedBlockchain = response.blockchains.sort( + (a, b) => a.sort - b.sort + ); + + sortedBlockchain.forEach((blockchain) => { + if ( + blockchain.enabled && + blockchainsWithAtLeastOneToken.has(blockchain.name) + ) { + blockchainsMapByName.set(blockchain.name, blockchain); + } + }); + + tokens.forEach((token) => { + const tokenHash = createTokenHash(token); + if (!tokensMapByBlockchainName[token.blockchain]) { + tokensMapByBlockchainName[token.blockchain] = []; + } + tokensMapByTokenHash.set(tokenHash, token); + tokensMapByBlockchainName[token.blockchain].push(tokenHash); + }); + + set({ + _blockchainsMapByName: blockchainsMapByName, + _tokensMapByTokenHash: tokensMapByTokenHash, + _tokensMapByBlockchainName: tokensMapByBlockchainName, + _popularTokens: popularTokens, + _swappers: swappers, + }); + } catch (error) { + set({ fetchStatus: 'failed' }); + throw error; + } + }, +}); diff --git a/widget/embedded/src/store/slices/settings.ts b/widget/embedded/src/store/slices/settings.ts new file mode 100644 index 0000000000..1ca54b3754 --- /dev/null +++ b/widget/embedded/src/store/slices/settings.ts @@ -0,0 +1,213 @@ +import type { ConfigSlice } from './config'; +import type { DataSlice } from './data'; +import type { WidgetConfig } from '../../types'; +import type { SwapperMeta, Token } from 'rango-sdk'; +import type { StateCreator } from 'zustand'; + +import { type Language } from '@rango-dev/ui'; + +import { BLOCKCHAIN_LIST_SIZE } from '../../constants/configs'; +import { DEFAULT_LANGUAGE } from '../../constants/languages'; +import { DEFAULT_SLIPPAGE } from '../../constants/swapSettings'; +import { removeDuplicateFrom } from '../../utils/common'; +import { isFeatureHidden } from '../../utils/settings'; +import { getSupportedBlockchainsFromConfig } from '../utils'; + +export type ThemeMode = 'auto' | 'dark' | 'light'; + +export interface SettingsSlice { + theme: ThemeMode; + language: Language | null; + disabledLiquiditySources: string[]; + /** Keeping a history of blockchains that user has selected (in Swap process) */ + preferredBlockchains: string[]; + slippage: number; + customSlippage: number | null; + infiniteApprove: boolean; + affiliateRef: string | null; + affiliatePercent: number | null; + affiliateWallets: { [key: string]: string } | null; + _customTokens: Token[]; + + setSlippage: (slippage: number) => void; + setCustomSlippage: (customSlippage: number | null) => void; + toggleInfiniteApprove: () => void; + toggleLiquiditySource: (name: string) => void; + setTheme: (theme: ThemeMode) => void; + setLanguage: (language: Language | null) => void; + toggleAllLiquiditySources: ( + swappers: SwapperMeta[], + shouldReset?: boolean + ) => void; + setAffiliateRef: (affiliateRef: string | null) => void; + setAffiliatePercent: (affiliatePercent: number | null) => void; + setAffiliateWallets: ( + affiliateWallets: { [key: string]: string } | null + ) => void; + addPreferredBlockchain: (blockchain: string) => void; + updateSettings: (config: WidgetConfig) => void; + setCustomToken: (token: Token) => void; + deleteCustomToken: (token: Token) => void; + customTokens: () => Token[]; +} + +export const createSettingsSlice: StateCreator< + SettingsSlice & DataSlice & ConfigSlice, + [], + [], + SettingsSlice +> = (set, get) => ({ + disabledLiquiditySources: [], + theme: 'auto', + language: null, + preferredBlockchains: [], + slippage: DEFAULT_SLIPPAGE, + customSlippage: null, + infiniteApprove: false, + affiliateRef: null, + affiliatePercent: null, + affiliateWallets: null, + _customTokens: [], + + addPreferredBlockchain: (blockchain) => { + const currentPreferredBlockchains = get().preferredBlockchains; + + const noNeedToDoAnything = currentPreferredBlockchains.find( + (preferredBlockchain, index) => { + const isSameBlockchain = preferredBlockchain === blockchain; + const isInVisibleList = index <= BLOCKCHAIN_LIST_SIZE - 1; + + return isSameBlockchain && isInVisibleList; + } + ); + + if (noNeedToDoAnything) { + return; + } + + const nextPreferredBlockchains: string[] = + currentPreferredBlockchains.filter((preferredBlockchain) => { + const isSameBlockchain = preferredBlockchain === blockchain; + + return !isSameBlockchain; + }); + + set(() => ({ + preferredBlockchains: [blockchain, ...nextPreferredBlockchains], + })); + }, + setSlippage: (slippage) => + set(() => ({ + slippage: slippage, + })), + + setCustomSlippage: (customSlippage) => + set(() => ({ + customSlippage: customSlippage, + })), + setAffiliateRef: (affiliateRef) => + set(() => ({ + affiliateRef, + })), + setAffiliatePercent: (affiliatePercent) => + set(() => ({ + affiliatePercent, + })), + + setAffiliateWallets: (affiliateWallets) => + set(() => ({ + affiliateWallets, + })), + toggleAllLiquiditySources: (swappers, shouldReset) => + set((state) => { + if (shouldReset) { + return { disabledLiquiditySources: [] }; + } + const swappersGroup = removeDuplicateFrom( + swappers.map((swapper) => swapper.swapperGroup) + ); + + if (swappersGroup.length === state.disabledLiquiditySources.length) { + return { disabledLiquiditySources: [] }; + } + + return { + disabledLiquiditySources: swappersGroup, + }; + }), + toggleInfiniteApprove: () => + set((state) => ({ + infiniteApprove: !state.infiniteApprove, + })), + + toggleLiquiditySource: (name) => + set((state) => { + if (state.disabledLiquiditySources.includes(name)) { + return { + disabledLiquiditySources: state.disabledLiquiditySources.filter( + (liquiditySource) => liquiditySource != name + ), + }; + } + return { + disabledLiquiditySources: state.disabledLiquiditySources.concat(name), + }; + }), + setTheme: (theme) => + set(() => ({ + theme, + })), + setLanguage: (language) => + set(() => ({ + language, + })), + updateSettings: (nextConfig: WidgetConfig) => { + const { features, theme } = nextConfig; + + const isThemeHidden = isFeatureHidden('theme', features); + const isLanguageHidden = isFeatureHidden('language', features); + const isLiquidityHidden = isFeatureHidden('liquiditySource', features); + const singleTheme = theme?.singleTheme; + const autoUpdateSettings = + nextConfig?.__UNSTABLE_OR_INTERNAL__?.autoUpdateSettings; + + set({ + ...(isThemeHidden && { theme: nextConfig.theme?.mode || 'auto' }), + ...(singleTheme && { theme: nextConfig.theme?.mode || 'light' }), + ...(isLanguageHidden && { + language: nextConfig.language || DEFAULT_LANGUAGE, + }), + ...(isLiquidityHidden && { + disabledLiquiditySources: nextConfig.liquiditySources || [], + }), + ...(autoUpdateSettings && { + // For the time being, we have added the language; if more are needed later, we can add other parameters. + language: nextConfig.language || DEFAULT_LANGUAGE, + }), + }); + }, + setCustomToken: (token) => + set((state) => ({ + _customTokens: [token, ...state._customTokens], + })), + deleteCustomToken: (token) => + set((state) => ({ + _customTokens: state._customTokens.filter( + (customToken) => customToken.address !== token.address + ), + })), + customTokens: () => { + const config = get().config; + + const customTokens = get()._customTokens; + const supportedBlockchainsFromConfig = getSupportedBlockchainsFromConfig({ + config, + }); + + return !supportedBlockchainsFromConfig.length + ? customTokens + : customTokens.filter((token) => + supportedBlockchainsFromConfig.includes(token.blockchain) + ); + }, +}); diff --git a/widget/embedded/src/store/slices/types.ts b/widget/embedded/src/store/slices/types.ts new file mode 100644 index 0000000000..99cd924852 --- /dev/null +++ b/widget/embedded/src/store/slices/types.ts @@ -0,0 +1,9 @@ +import type { ConfigSlice } from './config'; +import type { DataSlice } from './data'; +import type { SettingsSlice } from './settings'; +import type { WalletsSlice } from './wallets'; + +export type AppStoreState = DataSlice & + ConfigSlice & + SettingsSlice & + WalletsSlice; diff --git a/widget/embedded/src/store/slices/wallets.ts b/widget/embedded/src/store/slices/wallets.ts new file mode 100644 index 0000000000..bbc977c637 --- /dev/null +++ b/widget/embedded/src/store/slices/wallets.ts @@ -0,0 +1,488 @@ +import type { AppStoreState } from './types'; +import type { Token } from 'rango-sdk'; +import type { StateCreator } from 'zustand'; + +import BigNumber from 'bignumber.js'; + +import { eventEmitter } from '../../services/eventEmitter'; +import { httpService } from '../../services/httpService'; +import { + type Balance, + type Wallet, + WalletEventTypes, + WidgetEvents, +} from '../../types'; +import { isAccountAndWalletMatched } from '../../utils/wallets'; +import { + createAssetKey, + createBalanceKey, + createBalanceStateForNewAccount, + extractAssetFromBalanceKey, + removeBalanceFromAggregatedBalance, + updateAggregatedBalanceStateForNewAccount, +} from '../utils/wallets'; + +type WalletAddress = string; +type TokenAddress = string; +type TokenSymbol = string; +type BlockchainId = string; +/** format: `BlockchainId-TokenAddress-TokenSymbol` */ +export type AssetKey = `${BlockchainId}-${TokenAddress}-${TokenSymbol}`; +/** format: `BlockchainId-TokenAddress-TokenSymbol-WalletAddress` */ +export type BalanceKey = + `${BlockchainId}-${TokenAddress}-${TokenSymbol}-${WalletAddress}`; + +export type BalanceState = { + [key: BalanceKey]: Balance; +}; +export type AggregatedBalanceState = { + [key: AssetKey]: BalanceKey[]; +}; + +export interface ConnectedWallet extends Wallet { + explorerUrl: string | null; + selected: boolean; + loading: boolean; + error: boolean; +} + +export interface WalletsSlice { + _balances: BalanceState; + _aggregatedBalances: AggregatedBalanceState; + connectedWallets: ConnectedWallet[]; + fetchingWallets: boolean; + + setConnectedWalletAsRefetching: (walletType: string) => void; + setConnectedWalletHasError: (walletType: string) => void; + setConnectedWalletRetrievedData: (walletType: string) => void; + removeBalancesForWallet: ( + walletType: string, + options?: { + chains?: string[]; + } + ) => void; + addConnectedWallet: (accounts: Wallet[]) => void; + setWalletsAsSelected: ( + wallets: { walletType: string; chain: string }[] + ) => void; + /** + * Add new accounts to store and fetch balances for them. + */ + newWalletConnected: (accounts: Wallet[]) => Promise; + /** + * Disconnect a wallet and clean up balances after that. + */ + disconnectWallet: (walletType: string) => void; + clearConnectedWallet: () => void; + fetchBalances: ( + accounts: Wallet[], + options?: { retryOnFailedBalances?: boolean } + ) => Promise; + getBalanceFor: (token: Token) => Balance | null; + getBalances: () => BalanceState; +} + +export const createWalletsSlice: StateCreator< + AppStoreState, + [], + [], + WalletsSlice +> = (set, get) => ({ + _balances: {}, + _aggregatedBalances: {}, + connectedWallets: [], + fetchingWallets: false, + + // Actions + setConnectedWalletAsRefetching: (walletType: string) => { + set((state) => { + return { + fetchingWallets: true, + connectedWallets: state.connectedWallets.map((connectedWallet) => { + if (connectedWallet.walletType === walletType) { + return { + ...connectedWallet, + loading: true, + error: false, + }; + } + + return connectedWallet; + }), + }; + }); + }, + setConnectedWalletRetrievedData: (walletType: string) => { + set((state) => { + return { + fetchingWallets: false, + connectedWallets: state.connectedWallets.map((connectedWallet) => { + if (connectedWallet.walletType === walletType) { + return { + ...connectedWallet, + loading: false, + error: false, + }; + } + + return connectedWallet; + }), + }; + }); + }, + setConnectedWalletHasError: (walletType: string) => { + set((state) => { + return { + fetchingWallets: false, + connectedWallets: state.connectedWallets.map((connectedWallet) => { + if (connectedWallet.walletType === walletType) { + return { + ...connectedWallet, + loading: false, + error: true, + }; + } + + return connectedWallet; + }), + }; + }); + }, + addConnectedWallet: (accounts: Wallet[]) => { + /* + * When we are going to add a new account, there are two thing that can be happens: + * 1. Wallet hasn't add yet. + * 2. Wallet has added, and there are some more account that needs to added to connected wallet. consider we've added an ETH and Pol account, then we need to add Arb account later as well. + * + * For handling this, we need to only keep not-added-account, then only add those. + * + * Note: + * The second option would be useful for hub particularly. + */ + const connectedWallets = get().connectedWallets; + const walletsNeedToBeAdded = accounts.filter( + (account) => + !connectedWallets.some((connectedWallet) => + isAccountAndWalletMatched(account, connectedWallet) + ) + ); + + if (walletsNeedToBeAdded.length > 0) { + const newConnectedWallets = walletsNeedToBeAdded.map((account) => { + /* + * When a wallet is connecting, we will check if there is any `selected` wallet before, if not, we will consider this new wallet as connected. + * In this way, when user tries to swap, we selected a wallet by default and don't need to do an extra click in ConfirmWalletModal + */ + const shouldMarkWalletAsSelected = !connectedWallets.some( + (connectedWallet) => + connectedWallet.chain === account.chain && + connectedWallet.selected && + /** + * Sometimes, the connect function can be called multiple times for a particular wallet type when using the auto-connect feature. + * This check is there to make sure the chosen wallet doesn't end up unselected. + */ + connectedWallet.walletType !== account.walletType + ); + + return { + address: account.address, + chain: account.chain, + explorerUrl: null, + walletType: account.walletType, + selected: shouldMarkWalletAsSelected, + + loading: false, + error: false, + }; + }); + + set((state) => { + /* + * If wallet connected before and only need to update the address we should remove the old value and then add new conncted value. + * This scenario happens when user wants to change account inside the wallet. + * So the assumption here is the wallet has only one active address for a blockchain at the moment. + */ + const connectedWalletsWithoutSameWalletAndBlockchain = + state.connectedWallets.filter((currentConnectedWallet) => { + return !newConnectedWallets.some( + (newConnectedWallet) => + newConnectedWallet.walletType === + currentConnectedWallet.walletType && + newConnectedWallet.chain === currentConnectedWallet.chain + ); + }); + + return { + connectedWallets: [ + ...connectedWalletsWithoutSameWalletAndBlockchain, + ...newConnectedWallets, + ], + }; + }); + } + }, + setWalletsAsSelected: (wallets) => { + const nextConnectedWalletsWithUpdatedSelectedStatus = + get().connectedWallets.map((connectedWallet) => { + const walletSelected = !!wallets.find( + (wallet) => + wallet.chain === connectedWallet.chain && + wallet.walletType !== connectedWallet.walletType && + connectedWallet.selected + ); + const walletNotSelected = !!wallets.find( + (wallet) => + wallet.chain === connectedWallet.chain && + wallet.walletType === connectedWallet.walletType && + !connectedWallet.selected + ); + if (walletSelected) { + return { ...connectedWallet, selected: false }; + } else if (walletNotSelected) { + return { ...connectedWallet, selected: true }; + } + + return connectedWallet; + }); + + set({ + connectedWallets: nextConnectedWalletsWithUpdatedSelectedStatus, + }); + }, + newWalletConnected: async (accounts) => { + eventEmitter.emit(WidgetEvents.WalletEvent, { + type: WalletEventTypes.CONNECT, + payload: { walletType: accounts[0].walletType, accounts }, + }); + + get().addConnectedWallet(accounts); + + void get().fetchBalances(accounts); + }, + removeBalancesForWallet: (walletType, options) => { + let walletsNeedsToBeRemoved = get().connectedWallets.filter( + (connectedWallet) => connectedWallet.walletType === walletType + ); + /* + * We only need to delete balances where there is no connected wallets with same chain and address for that balance. + * Consider both Metamask and Solana having support for `0xblahblahblahblah` for Ethereum. + * If Phantom is disconnecting, we should keep the balance since Metamask has access to same address yet. + * So we only delete balance when there is no connected wallet that has access to that specific chain and address. + */ + get().connectedWallets.forEach((connectedWallet) => { + if (connectedWallet.walletType !== walletType) { + walletsNeedsToBeRemoved = walletsNeedsToBeRemoved.filter((wallet) => { + const isAnotherWalletHasSameAddressAndChain = + wallet.chain === connectedWallet.chain && + wallet.address === connectedWallet.address; + return !isAnotherWalletHasSameAddressAndChain; + }); + } + }); + + if (!!options?.chains && options.chains.length > 0) { + walletsNeedsToBeRemoved = walletsNeedsToBeRemoved.filter((wallet) => { + return options.chains?.includes(wallet.chain); + }); + } + + const nextBalancesState: BalanceState = {}; + let nextAggregatedBalanceState: AggregatedBalanceState = + get()._aggregatedBalances; + const currentBalancesState = get()._balances; + const balanceKeys = Object.keys(currentBalancesState) as BalanceKey[]; + + balanceKeys.forEach((key) => { + const asset = extractAssetFromBalanceKey(key); + + const shouldBalanceBeRemoved = !!walletsNeedsToBeRemoved.find( + (wallet) => + createBalanceKey(wallet.address, { + address: asset.address, + blockchain: wallet.chain, + symbol: asset.symbol, + }) === key + ); + + if (!shouldBalanceBeRemoved) { + nextBalancesState[key] = currentBalancesState[key]; + } + + // if a balance should be removed, we need to remove its caches in _aggregatedBalances as wel. + if (shouldBalanceBeRemoved) { + nextAggregatedBalanceState = removeBalanceFromAggregatedBalance( + nextAggregatedBalanceState, + key + ); + } + }); + set({ + _balances: nextBalancesState, + _aggregatedBalances: nextAggregatedBalanceState, + }); + }, + disconnectWallet: (walletType) => { + const isTargetWalletExistsInConnectedWallets = get().connectedWallets.find( + (wallet) => wallet.walletType === walletType + ); + if (isTargetWalletExistsInConnectedWallets) { + eventEmitter.emit(WidgetEvents.WalletEvent, { + type: WalletEventTypes.DISCONNECT, + payload: { walletType }, + }); + + // This should be called before updating connectedWallets since we need the old state to remove balances. + get().removeBalancesForWallet(walletType); + + let targetWalletWasSelectedForBlockchains = get() + .connectedWallets.filter( + (connectedWallet) => + connectedWallet.selected && + connectedWallet.walletType === walletType + ) + .map((connectedWallet) => connectedWallet.chain); + + // Remove target wallet from connectedWallets + let nextConnectedWallets = get().connectedWallets.filter( + (connectedWallet) => connectedWallet.walletType !== walletType + ); + + /* + * If we are disconnecting a wallet that has `selected` for some blockchains, + * For those blockchains we will fallback to first connected wallet + * which means selected wallet will change. + */ + if (targetWalletWasSelectedForBlockchains.length > 0) { + nextConnectedWallets = nextConnectedWallets.map((connectedWallet) => { + if ( + targetWalletWasSelectedForBlockchains.includes( + connectedWallet.chain + ) + ) { + targetWalletWasSelectedForBlockchains = + targetWalletWasSelectedForBlockchains.filter( + (blockchain) => blockchain !== connectedWallet.chain + ); + return { + ...connectedWallet, + selected: true, + }; + } + + return connectedWallet; + }); + } + + set({ + connectedWallets: nextConnectedWallets, + }); + } + }, + clearConnectedWallet: () => set({ connectedWallets: [] }), + fetchBalances: async (accounts, options) => { + // All the `accounts` have same `walletType` so we can pick the first one. + const walletType = accounts[0].walletType; + + get().setConnectedWalletAsRefetching(walletType); + + const addressesToFetch = accounts.map((account) => ({ + address: account.address, + blockchain: account.chain, + })); + const response = await httpService().getWalletsDetails(addressesToFetch); + + const listWalletsWithBalances = response.wallets; + + if (listWalletsWithBalances) { + const { retryOnFailedBalances = true } = options || {}; + if (retryOnFailedBalances) { + const failedWallets: Wallet[] = listWalletsWithBalances + .filter((wallet) => wallet.failed) + .map((wallet) => ({ + chain: wallet.blockChain, + walletType: walletType, + address: wallet.address, + })); + if (failedWallets.length > 0) { + void get().fetchBalances(failedWallets, { + retryOnFailedBalances: false, + }); + } + } + + let nextBalances: BalanceState = {}; + let nextAggregatedBalances: AggregatedBalanceState = + get()._aggregatedBalances; + listWalletsWithBalances.forEach((wallet) => { + if (wallet.failed) { + return; + } + + const balancesForWallet = createBalanceStateForNewAccount(wallet, get); + + nextAggregatedBalances = updateAggregatedBalanceStateForNewAccount( + nextAggregatedBalances, + balancesForWallet + ); + + nextBalances = { + ...nextBalances, + ...balancesForWallet, + }; + }); + + set((state) => ({ + _balances: { + ...state._balances, + ...nextBalances, + }, + _aggregatedBalances: nextAggregatedBalances, + })); + + get().setConnectedWalletRetrievedData(walletType); + } else { + get().setConnectedWalletHasError(walletType); + throw new Error( + `We couldn't fetch your account balances. Seem there is no information on blockchain for them yet.` + ); + } + }, + getBalances: () => { + return get()._balances; + }, + getBalanceFor: (token) => { + const balances = get().getBalances(); + + /* + * The old implementation wasn't considering user's address. + * it can be problematic when two separate address has same token, both of them will override on same key. + * + * For keeping the same behavior, here we pick the most amount and also will not consider user's address in key. + */ + + // Note: balance key is created using asset key + wallet address + const assetKey = createAssetKey(token); + const targetBalanceKeys = get()._aggregatedBalances[assetKey] || []; + + if (targetBalanceKeys.length === 0) { + return null; + } else if (targetBalanceKeys.length === 1) { + const targetKey = targetBalanceKeys[0]; + return balances[targetKey]; + } + + // If there are multiple balances for an specific token, we pick the maximum. + const firstTargetBalance = balances[targetBalanceKeys[0]]; + let maxBalance: Balance = firstTargetBalance; + targetBalanceKeys.forEach((targetBalanceKey) => { + const currentBalance = balances[targetBalanceKey]; + const currentBalanceAmount = new BigNumber(currentBalance.amount); + const prevBalanceAmount = new BigNumber(maxBalance.amount); + + if (currentBalanceAmount.isGreaterThan(prevBalanceAmount)) { + maxBalance = currentBalance; + } + }); + return maxBalance; + }, +}); diff --git a/widget/embedded/src/store/ui.ts b/widget/embedded/src/store/ui.ts index 1cb3b84158..fbae176214 100644 --- a/widget/embedded/src/store/ui.ts +++ b/widget/embedded/src/store/ui.ts @@ -1,25 +1,59 @@ +import type { Watermark } from '../hooks/useFetchApiConfig'; +import type { TabManagerInterface } from '../libs/tabManager'; + import { create } from 'zustand'; + +import { TabManager } from '../libs/tabManager'; + import createSelectors from './selectors'; interface UiState { - connectWalletsButtonDisabled: boolean; - selectedSwapRequestId: string | null; - currentPage: string; - toggleConnectWalletsButton: () => void; - setSelectedSwap: (requestId: string | null) => void; - setCurrentPage: (path: string) => void; + isActiveTab: boolean; + tabManagerInitiated: boolean; + showActivateTabModal: boolean; + watermark: Watermark; + showProfileBanner: boolean; + activateCurrentTab: ( + setCurrentTabAsActive: () => void, + hasRunningSwaps: boolean + ) => void; + setShowActivateTabModal: (flag: boolean) => void; + setWatermark: (watermark: Watermark) => void; + setShowProfileBanner: (showProfileBanner: boolean) => void; } export const useUiStore = createSelectors( - create()((set) => ({ - connectWalletsButtonDisabled: false, - selectedSwapRequestId: null, - currentPage: '', - toggleConnectWalletsButton: () => - set((state) => ({ - connectWalletsButtonDisabled: !state.connectWalletsButtonDisabled, - })), - setSelectedSwap: (requestId) => set({ selectedSwapRequestId: requestId }), - setCurrentPage: (path) => set({ currentPage: path }), + create()((set, get) => ({ + isActiveTab: false, + tabManagerInitiated: false, + showActivateTabModal: false, + watermark: 'NONE', + showProfileBanner: false, + fetchingApiConfig: false, + activateCurrentTab: (setCurrentTabAsActive, hasRunningSwaps) => { + const { showActivateTabModal } = get(); + + if (!showActivateTabModal && hasRunningSwaps) { + set({ showActivateTabModal: true }); + } else if (showActivateTabModal || !hasRunningSwaps) { + setCurrentTabAsActive(); + } + }, + setShowActivateTabModal: (flag) => { + set({ showActivateTabModal: flag }); + }, + setWatermark: (watermark) => { + set({ watermark }); + }, + setShowProfileBanner: (showProfileBanner) => { + set({ showProfileBanner }); + }, })) ); + +export const tabManager: TabManagerInterface = new TabManager({ + onInit: () => useUiStore.setState({ tabManagerInitiated: true }), + onClaim: () => + useUiStore.setState({ isActiveTab: true, showActivateTabModal: false }), + onRelease: () => useUiStore.setState({ isActiveTab: false }), +}); diff --git a/widget/embedded/src/store/utils/data.test.ts b/widget/embedded/src/store/utils/data.test.ts new file mode 100644 index 0000000000..2d04b1ffbf --- /dev/null +++ b/widget/embedded/src/store/utils/data.test.ts @@ -0,0 +1,175 @@ +import type { Token } from 'rango-sdk'; + +import { describe, expect, test } from 'vitest'; + +import { createToken } from '../../test-utils/fixtures'; +import { createTokenHash } from '../../utils/meta'; + +import { matchTokensFromConfigWithMeta } from './data'; // Adjust path as necessary + +type MatchTokensFromConfigWithMetaParam = Parameters< + typeof matchTokensFromConfigWithMeta +>[0]; + +const BLOCKCHAIN_A = 'blockchainA'; +const BLOCKCHAIN_B = 'blockchainB'; +const BLOCKCHAIN_C = 'blockchainC'; + +const tokens: Token[] = [ + { ...createToken(), blockchain: BLOCKCHAIN_A }, + { ...createToken(), blockchain: BLOCKCHAIN_A }, + { ...createToken(), blockchain: BLOCKCHAIN_B }, + { ...createToken(), blockchain: BLOCKCHAIN_C }, +]; + +function createMetaForMockData( + tokens: Token[] +): MatchTokensFromConfigWithMetaParam['meta'] { + const meta: MatchTokensFromConfigWithMetaParam['meta'] = { + tokensMapByTokenHash: new Map(), + tokensMapByBlockchainName: {}, + }; + tokens.forEach((token) => { + const tokenHash = createTokenHash(token); + meta.tokensMapByTokenHash.set(tokenHash, token); + if (!meta.tokensMapByBlockchainName[token.blockchain]) { + meta.tokensMapByBlockchainName[token.blockchain] = []; + } + meta.tokensMapByBlockchainName[token.blockchain].push(tokenHash); + }); + + return meta; +} + +describe('matchTokensFromConfigWithMeta', () => { + test('should include tokens from config.tokens array that exist in meta', () => { + const mockData: MatchTokensFromConfigWithMetaParam = { + type: 'source', + meta: createMetaForMockData(tokens), + config: { + blockchains: undefined, + tokens: [tokens[0], tokens[1]], + }, + }; + + const result = matchTokensFromConfigWithMeta(mockData); + expect(result).toEqual([tokens[0], tokens[1]]); + }); + + test('If config.blockchains is not defined or is empty, we should include all tokens from the meta for every blockchain that does not have tokens specified in the config, as well as tokens specified in the config that exist in the meta.', () => { + const mockData: MatchTokensFromConfigWithMetaParam = { + type: 'source', + meta: createMetaForMockData(tokens), + config: { + blockchains: undefined, + tokens: { + [BLOCKCHAIN_A]: { tokens: [tokens[0]], isExcluded: false }, + }, + }, + }; + + const runTestWithConfig = (config: { + blockchains: MatchTokensFromConfigWithMetaParam['config']['blockchains']; + }) => { + mockData.config.blockchains = config.blockchains; + const result = matchTokensFromConfigWithMeta(mockData); + /** + * In this case, the result might differ from what was expected. + * To pass the test, we reordered the expected result. + * Changing the order of tokens does not impact the overall behavior of our app, + * as we have a comprehensive sorting logic applied to tokens within the data slice. + */ + // eslint-disable-next-line @typescript-eslint/no-magic-numbers + expect(result).toEqual([tokens[2], tokens[3], tokens[0]]); + }; + + runTestWithConfig({ blockchains: undefined }); + runTestWithConfig({ blockchains: [] }); + }); + + test('should include tokens from config.tokens object that exist in meta', () => { + const mockData: MatchTokensFromConfigWithMetaParam = { + type: 'source', + meta: createMetaForMockData(tokens), + config: { + blockchains: [BLOCKCHAIN_A, BLOCKCHAIN_B], + tokens: { + [BLOCKCHAIN_A]: { tokens: [tokens[0]], isExcluded: false }, + [BLOCKCHAIN_B]: { tokens: [tokens[2]], isExcluded: false }, + }, + }, + }; + + const result = matchTokensFromConfigWithMeta(mockData); + expect(result).toEqual([tokens[0], tokens[2]]); + }); + + test('should not include tokens from config.tokens whose blockchain does not exist in config.blockchains', () => { + const mockData: MatchTokensFromConfigWithMetaParam = { + type: 'source', + meta: createMetaForMockData(tokens), + config: { + blockchains: [BLOCKCHAIN_A], + tokens: { + [BLOCKCHAIN_B]: { tokens: [tokens[2]], isExcluded: false }, + }, + }, + }; + + const result = matchTokensFromConfigWithMeta(mockData); + expect(result).toEqual([tokens[0], tokens[1]]); + }); + + test('should include all tokens from a blockchain if that blockchain does not have any tokens in config.tokens', () => { + const mockData: MatchTokensFromConfigWithMetaParam = { + type: 'source', + meta: createMetaForMockData(tokens), + config: { + blockchains: [BLOCKCHAIN_A], + tokens: {}, + }, + }; + + const result = matchTokensFromConfigWithMeta(mockData); + expect(result).toEqual([tokens[0], tokens[1]]); + }); + + test('should include all tokens from config.blockchains that exist in the meta, except tokens excluded in config.token', () => { + const mockData: MatchTokensFromConfigWithMetaParam = { + type: 'source', + meta: createMetaForMockData(tokens), + config: { + blockchains: [BLOCKCHAIN_A], + tokens: { + [BLOCKCHAIN_A]: { tokens: [tokens[0]], isExcluded: true }, + }, + }, + }; + + const result = matchTokensFromConfigWithMeta(mockData); + expect(result).toEqual([tokens[1]]); + }); + + test('should include all tokens from the meta when config parameters are empty values', () => { + const mockData: MatchTokensFromConfigWithMetaParam = { + type: 'source', + meta: createMetaForMockData(tokens), + config: { + blockchains: [], + tokens: {}, + }, + }; + + const runTestWithConfig = ( + config: MatchTokensFromConfigWithMetaParam['config'] + ) => { + mockData.config = config; + const result = matchTokensFromConfigWithMeta(mockData); + expect(result).toEqual(tokens); + }; + + runTestWithConfig({ blockchains: [], tokens: {} }); + runTestWithConfig({ blockchains: undefined, tokens: undefined }); + runTestWithConfig({ blockchains: [], tokens: [] }); + }); +}); diff --git a/widget/embedded/src/store/utils/data.ts b/widget/embedded/src/store/utils/data.ts new file mode 100644 index 0000000000..943f20776f --- /dev/null +++ b/widget/embedded/src/store/utils/data.ts @@ -0,0 +1,142 @@ +import type { + BlockchainAndTokenConfig, + TokenHash, + WidgetConfig, +} from '../../types'; +import type { DataSlice } from '../slices/data'; +import type { Asset, Token } from 'rango-sdk'; + +import { createTokenHash } from '../../utils/meta'; + +/** + * This function retrieves tokens and blockchains from the widget configuration and combines them with token data from the meta response to determine which tokens should be displayed in the widget. + * To optimize performance, the function minimizes unnecessary iterations over the meta tokens. + * The result of this function should be cached and recalculated whenever the widget configuration changes. + */ +export function matchTokensFromConfigWithMeta(params: { + type: 'source' | 'destination'; + config: { + blockchains: BlockchainAndTokenConfig['blockchains']; + tokens: BlockchainAndTokenConfig['tokens']; + }; + meta: { + tokensMapByTokenHash: DataSlice['_tokensMapByTokenHash']; + tokensMapByBlockchainName: DataSlice['_tokensMapByBlockchainName']; + }; +}): Token[] { + const { config, meta } = params; + const result: Record = {}; + const configTokens = config.tokens; + + // Helper function to add tokens to result + const addTokens = (tokens: (Asset | TokenHash)[]) => { + tokens.forEach((item) => { + if (typeof item !== 'string') { + item = createTokenHash(item); + } + const tokenFromMeta = meta.tokensMapByTokenHash.get(item); + if (tokenFromMeta) { + result[item] = tokenFromMeta; + } + }); + }; + + /** + * We support two types of configurations for passing tokens in the widget config. + * We check the type of configuration and calculate the result based on that. + */ + if (Array.isArray(configTokens)) { + /** + * If "config.tokens" is an array, + * we iterate through it and include any token that exists in the meta data in the result. + */ + if (configTokens.length > 0) { + addTokens(configTokens); + return Object.values(result); + } + return Array.from(meta.tokensMapByTokenHash.values()); + } + + /** + * From this point onward, + * the function handles the other type of widget configuration. + */ + if (!configTokens) { + return Array.from(meta.tokensMapByTokenHash.values()); + } + + let configBlockchains: string[]; + + if (config.blockchains?.length) { + configBlockchains = config.blockchains; + } else { + /** + * If config.blockchains does not exist, + * we include all tokens from every blockchain in the meta data that are not specified in the tokens from the config. + */ + configBlockchains = Object.keys(configTokens); + const configBlockchainsSet = new Set(configBlockchains); + + Object.keys(meta.tokensMapByBlockchainName).forEach((blockchain) => { + if (!configBlockchainsSet.has(blockchain)) { + addTokens(meta.tokensMapByBlockchainName[blockchain]); + } + }); + } + //We iterate over each blockchain and retrieve the related tokens for each one from the configuration. + configBlockchains.forEach((blockchain) => { + const targetTokensForBlockchain = configTokens[blockchain]; + /** + * If no tokens exist for a blockchain, + * we include all tokens for that blockchain from the meta response. + */ + if ( + !targetTokensForBlockchain && + meta.tokensMapByBlockchainName?.[blockchain] + ) { + addTokens(meta.tokensMapByBlockchainName[blockchain]); + return; + } + + if (targetTokensForBlockchain) { + if (targetTokensForBlockchain.isExcluded) { + /** + * If tokens are excluded, + * we first include all tokens from the meta for that blockchain, + * then remove the excluded tokens from the result. + */ + addTokens(meta.tokensMapByBlockchainName[blockchain]); + targetTokensForBlockchain.tokens.forEach((token) => { + const tokenHash = createTokenHash(token); + delete result[tokenHash]; + }); + } else { + //We retrieve the corresponding token from the meta and include it in the result. + addTokens(targetTokensForBlockchain.tokens); + } + } + }); + + return Object.values(result); +} + +export function getSupportedBlockchainsFromConfig(params: { + config: WidgetConfig; +}): string[] { + const { config } = params; + const configFromBlockchains = config.from?.blockchains || []; + const configToBlockchains = config.to?.blockchains || []; + + /* + * Empty array means all blockchains. So if any of to or from has an empty array, + * it means all blockchains is available to use and there is no limitation from config. + */ + if (!configFromBlockchains.length || !configToBlockchains.length) { + return []; + } + const blockchains = [...configFromBlockchains, ...configToBlockchains]; + + const supportedBlockchains = new Set(blockchains); + + return Array.from(supportedBlockchains); +} diff --git a/widget/embedded/src/store/utils/index.ts b/widget/embedded/src/store/utils/index.ts new file mode 100644 index 0000000000..3707679222 --- /dev/null +++ b/widget/embedded/src/store/utils/index.ts @@ -0,0 +1 @@ +export * from './data'; diff --git a/widget/embedded/src/store/utils/wallets.ts b/widget/embedded/src/store/utils/wallets.ts new file mode 100644 index 0000000000..ae94345388 --- /dev/null +++ b/widget/embedded/src/store/utils/wallets.ts @@ -0,0 +1,108 @@ +import type { Balance } from '../../types'; +import type { AppStoreState } from '../app'; +import type { + AggregatedBalanceState, + AssetKey, + BalanceKey, + BalanceState, +} from '../slices/wallets'; +import type { Asset, WalletDetail } from 'rango-types'; + +import BigNumber from 'bignumber.js'; + +import { ZERO } from '../../constants/numbers'; + +/** + * Note: We need to use `symbol` as well since native coins and cosmos blockchains don't have `address` + * output format: BlockchainId-TokenAddress-TokenSymbol + */ +export function createAssetKey(asset: Asset): AssetKey { + return `${asset.blockchain}-${asset.address}-${asset.symbol}`; +} + +/** + * output format: BlockchainId-TokenAddress-TokenSymbol-WalletAddress + */ +export function createBalanceKey( + accountAddress: string, + asset: Asset +): BalanceKey { + const assetKey = createAssetKey(asset); + return `${assetKey}-${accountAddress}`; +} + +export function extractAssetFromBalanceKey(key: BalanceKey): Asset { + const [assetChain, assetAddress, assetSymbol] = key.split('-'); + return { + address: assetAddress, + blockchain: assetChain, + symbol: assetSymbol, + }; +} + +export function createBalanceStateForNewAccount( + account: WalletDetail, + store: () => AppStoreState +): BalanceState { + const state: BalanceState = {}; + + account.balances?.forEach((accountBalance) => { + const key = createBalanceKey(account.address, accountBalance.asset); + const amount = accountBalance.amount.amount; + const decimals = accountBalance.amount.decimals; + + const usdPrice = store().findToken(accountBalance.asset)?.usdPrice; + const usdValue = usdPrice + ? new BigNumber(usdPrice ?? ZERO).multipliedBy(amount).toString() + : ''; + + const balance: Balance = { + amount, + decimals, + usdValue, + }; + + state[key] = balance; + }); + + return state; +} + +export function updateAggregatedBalanceStateForNewAccount( + aggregatedBalances: AggregatedBalanceState, + balanceState: BalanceState +) { + for (const balanceKey in balanceState) { + const asset = extractAssetFromBalanceKey(balanceKey as BalanceKey); + const assetKey = createAssetKey(asset); + + if (!aggregatedBalances[assetKey]) { + aggregatedBalances[assetKey] = []; + } + + if (!aggregatedBalances[assetKey].includes(balanceKey as BalanceKey)) { + aggregatedBalances[assetKey] = [ + ...aggregatedBalances[assetKey], + balanceKey as BalanceKey, + ]; + } + } + + return aggregatedBalances; +} + +export function removeBalanceFromAggregatedBalance( + aggregatedBalances: AggregatedBalanceState, + balanceKey: BalanceKey +) { + const asset = extractAssetFromBalanceKey(balanceKey); + const assetKey = createAssetKey(asset); + + if (aggregatedBalances[assetKey]) { + aggregatedBalances[assetKey] = aggregatedBalances[assetKey].filter( + (aggregatedBalance) => aggregatedBalance !== balanceKey + ); + } + + return aggregatedBalances; +} diff --git a/widget/embedded/src/store/wallets.ts b/widget/embedded/src/store/wallets.ts deleted file mode 100644 index 061634136b..0000000000 --- a/widget/embedded/src/store/wallets.ts +++ /dev/null @@ -1,193 +0,0 @@ -import { SelectableWallet } from '@rango-dev/ui'; -import { WalletType } from '@rango-dev/wallets-shared'; -import { create } from 'zustand'; -import { subscribeWithSelector } from 'zustand/middleware'; -import { httpService } from '../services/httpService'; -import { - getRequiredChains, - getTokensWithBalance, - isAccountAndBalanceMatched, - makeBalanceFor, - resetBalanceState, - SelectedWallet, - sortTokens, -} from '../utils/wallets'; -import { useBestRouteStore } from './bestRoute'; -import { useMetaStore } from './meta'; -import createSelectors from './selectors'; -import { shallow } from 'zustand/shallow'; - -export interface Account { - chain: string; - address: string; - walletType: WalletType; -} - -export type TokenBalance = { - chain: string; - symbol: string; - ticker: string; - address: string | null; - rawAmount: string; - decimal: number | null; - amount: string; - logo: string | null; - usdPrice: number | null; -}; - -export interface Balance { - balances: TokenBalance[] | null; - address: string; - chain: string; - loading: boolean; - walletType: WalletType; - error: boolean; - explorerUrl: string | null; -} - -interface WalletsStore { - accounts: Account[]; - balances: Balance[]; - selectedWallets: SelectedWallet[]; - connectWallet: (accounts: Account[]) => void; - disconnectWallet: (walletType: WalletType) => void; - initSelectedWallets: () => void; - setSelectedWallet: (wallet: SelectableWallet) => void; - clearConnectedWallet: () => void; -} - -export const useWalletsStore = createSelectors( - create()( - subscribeWithSelector((set) => ({ - accounts: [], - balances: [], - selectedWallets: [], - connectWallet: (accounts) => { - const tokens = useMetaStore.getState().meta.tokens; - - set((state) => ({ - accounts: state.accounts.concat(accounts), - balances: state.balances.concat( - accounts.map((account) => ({ - balances: [], - address: account.address, - chain: account.chain, - loading: true, - walletType: account.walletType, - error: false, - explorerUrl: null, - })) - ), - })); - accounts.forEach(async (account) => { - try { - const response = await httpService().getWalletsDetails([ - { address: account.address, blockchain: account.chain }, - ]); - const retrivedBalance = response.wallets[0]; - if (retrivedBalance) { - set((state) => ({ - balances: state.balances.map((balance) => { - return isAccountAndBalanceMatched(account, balance) - ? makeBalanceFor(account, retrivedBalance, tokens) - : balance; - }), - })); - } else throw new Error('Wallet not found'); - } catch (error) { - set((state) => ({ - balances: state.balances.map((balance) => { - return isAccountAndBalanceMatched(account, balance) - ? resetBalanceState(balance) - : balance; - }), - })); - } - }); - }, - disconnectWallet: (walletType) => { - set((state) => ({ - accounts: state.accounts.filter( - (account) => account.walletType !== walletType - ), - balances: state.balances.filter( - (balance) => balance.walletType !== walletType - ), - selectedWallets: state.selectedWallets.filter( - (wallet) => wallet.walletType != walletType - ), - })); - }, - initSelectedWallets: () => - set((state) => { - const requiredChains = getRequiredChains( - useBestRouteStore.getState().bestRoute - ); - const connectedWallets = state.accounts; - const selectedWallets: SelectedWallet[] = []; - requiredChains.forEach((chain) => { - const anyWalletSelected = !!state.selectedWallets.find( - (wallet) => wallet.chain === chain - ); - if (!anyWalletSelected) { - const firstWalletWithMatchedChain = connectedWallets.find( - (wallet) => wallet.chain === chain - ); - if (!!firstWalletWithMatchedChain) - selectedWallets.push({ - address: firstWalletWithMatchedChain.address, - chain: firstWalletWithMatchedChain.chain, - walletType: firstWalletWithMatchedChain.walletType, - }); - } - }); - return { - selectedWallets: state.selectedWallets.concat(selectedWallets), - }; - }), - setSelectedWallet: (wallet) => - set((state) => ({ - selectedWallets: state.selectedWallets - .filter((selectedWallet) => selectedWallet.chain !== wallet.chain) - .concat({ - chain: wallet.chain, - address: wallet.address, - walletType: wallet.walletType, - }), - })), - - clearConnectedWallet: () => - set(() => ({ - accounts: [], - balances: [], - selectedWallets: [], - })), - })) - ) -); - -useWalletsStore.subscribe( - (state) => state.balances, - (balances) => { - useBestRouteStore.setState(({ sourceTokens, destinationTokens }) => { - const sourceTokensWithBalance = getTokensWithBalance( - sourceTokens, - balances - ); - const destinationTokensWithBalance = getTokensWithBalance( - destinationTokens, - balances - ); - return { - sourceTokens: sortTokens(sourceTokensWithBalance), - destinationTokens: sortTokens(destinationTokensWithBalance), - }; - }); - }, - { - equalityFn: shallow, - } -); - -export const fetchingBalanceSelector = (state: WalletsStore) => - !!state.balances.find((wallet) => wallet.loading); diff --git a/widget/embedded/src/test-utils/fixtures.ts b/widget/embedded/src/test-utils/fixtures.ts new file mode 100644 index 0000000000..6ecfcef74f --- /dev/null +++ b/widget/embedded/src/test-utils/fixtures.ts @@ -0,0 +1,265 @@ +import type { AppStoreState } from '../store/app'; +import type { Blockchain, TokenHash, WidgetConfig } from '../types'; +import type { BlockchainMeta, EvmBlockchainMeta, Token } from 'rango-sdk'; + +import { faker } from '@faker-js/faker'; +import { TransactionType } from 'rango-sdk'; + +import { createTokenHash } from '../utils/meta'; + +const TOKENS_COUNT = 20; +const BLOCKCHAINS_COUNT = 20; + +const listBlockchains = [ + 'ETH', + 'BSC', + 'ARBITRUM', + 'POLYGON', + 'ZKSYNC', + 'STARKNET', + 'OPTIMISM', + 'AVAX_CCHAIN', + 'POLYGONZK', + 'BASE', + 'LINEA', + 'TRON', + 'BTC', + 'SCROLL', + 'COSMOS', + 'OSMOSIS', + 'METIS', + 'NEUTRON', + 'NOBLE', + 'DYDX', + 'SOLANA', + 'CRONOS', + 'BNB', + 'FANTOM', + 'AURORA', + 'MAYA', + 'THOR', + 'BOBA', + 'MOONBEAM', + 'MOONRIVER', + 'OKC', + 'BOBA_BNB', + 'BOBA_AVALANCHE', + 'LTC', + 'BCH', + 'HARMONY', + 'EVMOS', + 'HECO', + 'SIF', + 'BRISE', + 'STARGAZE', + 'FUSE', + 'CRYPTO_ORG', + 'CHIHUAHUA', + 'BANDCHAIN', + 'COMDEX', + 'REGEN', + 'IRIS', + 'EMONEY', + 'GNOSIS', + 'JUNO', + 'AXELAR', + 'STRIDE', + 'KCC', + 'MARS', + 'TERRA', + 'TELOS', + 'BITSONG', + 'AKASH', + 'KI', + 'PERSISTENCE', + 'MEDIBLOC', + 'KUJIRA', + 'SENTINEL', + 'INJECTIVE', + 'SECRET', + 'KONSTELLATION', + 'STARNAME', + 'BITCANNA', + 'UMEE', + 'DESMOS', + 'LUMNETWORK', + 'TERRA_CLASSIC', + 'DASH', + 'DOGE', +]; + +const listTokens = [ + 'BTC', + 'ETH', + 'USDT', + 'BNB', + 'AVAX', + 'DOT', + 'LINK', + 'MATIC', + 'TRX', + 'BCH', + 'NEAR', + 'LTC', + 'ICP', + 'FIL', + 'ETC', + 'DAI', + 'ATOM', + 'IMX', + 'OP', + 'HBAR', + 'INJ', + 'XLM', + 'CRO', + 'RNDR', + 'GRT', + 'OKB', + 'VET', + 'MNT', + 'KAS', + 'THETA', + 'LDO', + 'FDUSD', + 'XRP', + 'RUNE', + 'UNI', + 'USDC', + 'LEO', + 'ADA', + 'TON', + 'STX', + 'APT', + 'SOL', + 'TIA', + 'FLOKI', + 'DOGE', + 'ARB', + 'PEPE', + 'SHIB', + 'TON', +]; + +const FAKER_SEED = 9595; +faker.seed(FAKER_SEED); + +export function createToken(options?: { blockchains?: string[] }) { + const fromBlockchains = options?.blockchains ?? listBlockchains; + + return { + address: faker.datatype.boolean() ? faker.finance.ethereumAddress() : null, + blockchain: faker.helpers.arrayElement(fromBlockchains), + coinSource: faker.datatype.boolean() ? faker.word.noun() : null, + coinSourceUrl: faker.datatype.boolean() ? faker.internet.url() : null, + decimals: faker.number.int(), + usdPrice: faker.datatype.boolean() ? faker.number.float() : null, + isPopular: faker.datatype.boolean(), + image: faker.internet.url(), + symbol: faker.helpers.arrayElement(listTokens), + name: faker.datatype.boolean() ? faker.hacker.verb() : null, + supportedSwappers: faker.datatype.boolean() + ? faker.helpers.multiple(faker.string.sample) + : undefined, + isSecondaryCoin: faker.datatype.boolean(), + }; +} +export function createTokens( + count: number, + options?: { + blockchains?: string[]; + } +): Token[] { + return Array(count) + .fill(null) + .map(() => createToken({ blockchains: options?.blockchains })); +} + +export function createEvmBlockchain(): EvmBlockchainMeta { + const name = faker.helpers.arrayElement(listBlockchains); + return { + name: name, + shortName: faker.string.alpha({ + length: 3, + }), + displayName: faker.string.alpha(), + defaultDecimals: faker.number.int(), + addressPatterns: faker.helpers.multiple(faker.string.sample), + logo: faker.internet.url(), + color: faker.helpers.fake('#{{number.hex()}}'), + sort: faker.number.int({ min: 1, max: BLOCKCHAINS_COUNT }), + enabled: faker.datatype.boolean(), + feeAssets: [ + { + blockchain: faker.helpers.arrayElement( + listBlockchains.filter((item) => item !== name) + ), + symbol: faker.helpers.arrayElement(listTokens), + address: faker.datatype.boolean() + ? faker.finance.ethereumAddress() + : null, + }, + ], + type: TransactionType.EVM, + chainId: faker.string.hexadecimal({ + length: 2, + }), + info: { + infoType: 'EvmMetaInfo', + chainName: faker.hacker.adjective(), + nativeCurrency: { + name: faker.hacker.noun(), + symbol: faker.helpers.arrayElement(listTokens), + decimals: faker.number.int(), + }, + rpcUrls: faker.helpers.multiple(faker.internet.url), + blockExplorerUrls: faker.helpers.multiple(faker.internet.url), + addressUrl: faker.internet.url(), + transactionUrl: faker.internet.url(), + enableGasV2: faker.datatype.boolean(), + }, + }; +} + +export function createEvmBlockchains(count: number): EvmBlockchainMeta[] { + return Array(count) + .fill(null) + .map(() => createEvmBlockchain()); +} + +export function createInitialAppStore() { + const blockchains = createEvmBlockchains(BLOCKCHAINS_COUNT); + const tokens = createTokens(TOKENS_COUNT, { + blockchains: blockchains.map((b) => b.name), + }); + + const tokensMapByTokenHash: Map = new Map(); + const tokensMapByBlockchainName: Record = {}; + tokens.forEach((token) => { + const tokenHash = createTokenHash(token); + if (!tokensMapByBlockchainName[token.blockchain]) { + tokensMapByBlockchainName[token.blockchain] = []; + } + tokensMapByTokenHash.set(tokenHash, token); + tokensMapByBlockchainName[token.blockchain].push(tokenHash); + }); + + return { + _tokensMapByTokenHash: tokensMapByTokenHash, + _tokensMapByBlockchainName: tokensMapByBlockchainName, + _blockchainsMapByName: new Map( + blockchains.map((meta) => [meta.name, meta]) + ), + }; +} + +export function updateAppStoreConfig( + appStoreState: AppStoreState, + config: Partial +): AppStoreState { + appStoreState.config = { + ...appStoreState.config, + ...config, + }; + + return appStoreState; +} diff --git a/widget/embedded/src/types/config.ts b/widget/embedded/src/types/config.ts index d875ded54c..fd716fe77d 100644 --- a/widget/embedded/src/types/config.ts +++ b/widget/embedded/src/types/config.ts @@ -1,46 +1,90 @@ -import { Asset } from 'rango-sdk'; -import { WalletType } from '@rango-dev/wallets-shared'; +import type { Language, theme } from '@rango-dev/ui'; +import type { LegacyProviderInterface } from '@rango-dev/wallets-core/dist/legacy/mod'; +import type { WalletType } from '@rango-dev/wallets-shared'; +import type { Asset } from 'rango-sdk'; + +export type WidgetVariant = 'default' | 'expanded' | 'full-expanded'; /** * The above type defines a set of optional color properties for a widget. * @property {string} background * @property {string} foreground * @property {string} primary - * @property {string} success - * @property {string} error - * @property {string} warning + * @property {string} secondary + * */ -export type WidgetColors = { +export type WidgetColorsKeys = keyof WidgetColors; + +export type ThemeColors = { + [key in string]?: string; +}; + +export interface WidgetColors extends ThemeColors { background?: string; foreground?: string; + neutral?: string; primary?: string; - success?: string; - error?: string; - warning?: string; -}; + secondary?: string; +} /** * The `WidgetTheme` defines the properties of a widget theme, including mode, font family, colors, border * radius, width, and height. * @property {'auto' | 'light' | 'dark'} mode - The mode property is used to specify the default theme for * the widget. - * @property {string} fontFamily - The font family to be used in the widget. - * @property {Colors} colors - The `colors` property is a sub-property of the `WidgetTheme` object that + * @property {string} fontFamily - The font family to be used in the widget. If you want to do this, include the font of your choice in your HTML file. + * @property {{ light?: WidgetColors; dark?: WidgetColors }} colors - The `colors` property is a sub-property of the `WidgetTheme` object that * defines the color scheme for the widget. It is of type `Colors`, which is likely another object that * contains specific color values for various parts of the widget (e.g. background color, text color, * border color * @property {number} borderRadius - `borderRadius` is a property of the `WidgetTheme` type that * specifies the radius of the corners of a widget. + * @property {number} secondaryBorderRadius - `secondaryBorderRadius` is a property of the `WidgetTheme` type that + * specifies the radius of the buttons of a widget. * @property {number} width - The `width` property is a number that represents the width of the widget. * @property {number} height - The `height` property is a number that specifies the height of the widget. + * @property {boolean} singleTheme - The `singleTheme` property is a boolean that specifies the theme is support dark and light or only light. */ export type WidgetTheme = { mode?: 'auto' | 'light' | 'dark'; fontFamily?: string; - colors?: WidgetColors; + colors?: { light?: WidgetColors; dark?: WidgetColors }; + shadows?: typeof theme.shadows; borderRadius?: number; + secondaryBorderRadius?: number; width?: number; height?: number; + singleTheme?: boolean; +}; + +/** + * If you want to charge users fee per transaction, you should + * pass `WidgetAffiliate` including affiliateRef, affiliatePercent, and affiliateWallets. + * @property {string | null} ref - To enable dApps to charge affiliate fees and generate income from + * users' transactions, the affiliate referral code should be provided. You can create this code by + * visiting the following link: https://app.rango.exchange/affiliate. + * @property {number | null} percent - If you want to change the default affiliate fee percentage, + * you can provide a new value here. + * @property {{ [key: string]: string }} wallets - If you want to change the default affiliate wallet + * addresses, you can provide new values here. (Map of route blockchains to affiliate address) + */ +export type WidgetAffiliate = { + ref?: string; + percent?: number; + wallets?: { [key: string]: string }; +}; + +/** + * `Tokens` + * + * @property {boolean} isExcluded - This is a boolean property capable of removing tokens from all or a blockchain. + * @property {Asset[]} tokens - The `tokens` property is an array of `Asset` objects that + * you could use that to limit tokens to some limited ones. + */ + +export type Tokens = { + isExcluded: boolean; + tokens: Asset[]; }; /** @@ -51,14 +95,92 @@ export type WidgetTheme = { * which is selected. e.g. {blockchain: 'BSC', symbol: 'BNB', address: null} * @property {string[]} blockchains - An optional array of strings representing the supported * blockchains. e.g. ['BSC','ETHEREUM'] - * @property {Asset[]} tokens - The `tokens` property is an optional array of `Asset` objects that - * you could use that to limit tokens to some limited ones. + * @property {Asset[] |{ [blockchain: string]: Tokens }} tokens - The `tokens` property is an optional object of `blockchain` objects or array of `Asset` objects + * that you could use that to limit tokens to some limited ones. + * @property {Asset} pinnedTokens - The `pinnedTokens` property is an optional array of `Asset` objects that + * you could use to pin tokens of your choice to the top of the token list. */ export type BlockchainAndTokenConfig = { blockchain?: string; token?: Asset; blockchains?: string[]; - tokens?: Asset[]; + pinnedTokens?: Asset[]; + tokens?: Asset[] | { [blockchain: string]: Tokens }; +}; + +export type SignersConfig = { + customSolanaRPC?: string; +}; + +/** + * `Features` + * + * @property {'visible' | 'hidden'} [theme] + * - The visibility state for the theme feature. Optional property. + * + * @property {'visible' | 'hidden'} [language] + * - The visibility state for the language feature. Optional property. + * + * @property {'visible' | 'hidden'} [connectWalletButton] + * - The visibility state for the connect wallet button feature. Optional property. + * + * @property {'visible' | 'hidden'} [notification] + * - The visibility state for the notification feature. Optional property. + * + * @property {'visible' | 'hidden'} [liquiditySource] + * - The visibility state for the liquiditySource feature. Optional property. + * + * @property {'disabled' | 'enabled'} [experimentalWallet] + * - Enable our experimental version of wallets. Default: disable on production, enabled on dev. + */ +export type Features = Partial< + Record< + | 'theme' + | 'language' + | 'connectWalletButton' + | 'notification' + | 'liquiditySource' + | 'customTokens', + 'visible' | 'hidden' + > +> & + Partial>; + +/** + * `Routing` + * + * @property {'disabled' | 'enabled'} [avoidNativeFee] + * - If you want to exclude swappers that have native tokens as fee, for example when you are using an AA account, you could set this parameter. + * + * @property {number} [maxLength] + * - If you want to limit the maximum acceptable length of a route, you could set this parameter. + * + * @property {'disabled' | 'enabled'} [experimental] + * - Use this parameter to enable experimental routes. This settings shouldn't be used in your production environment. + * + * @property {'disabled' | 'enabled'} [enableCentralizedSwappers] + * - If you want to enable routing from the centralized protocols like XO Swap, you could set this parameter. + */ +export type Routing = Partial< + Record< + 'experimental' | 'avoidNativeFee' | 'enableCentralizedSwappers', + 'disabled' | 'enabled' + > +> & + Partial>; + +export type TrezorManifest = { + appUrl: string; + email: string; +}; + +/** + * + * @property {string} manifestUrl - The URL of the TON Connect [manifest]{@link https://github.com/ton-connect/docs/blob/main/requests-responses.md#app-manifest}, containing the Dapp metadata to be displayed in the user’s wallet. + * + */ +export type TonConnectConfig = { + manifestUrl?: string; }; /** @@ -67,12 +189,16 @@ export type BlockchainAndTokenConfig = { * and theme. * * @property {string} apiKey - The API key used to communicate with Rango API - * @property {string} affiliateRef - The affiliate reference is an optional string property in the - * WidgetConfig type. It is used to set and track referrals or affiliations for the dApps. + * @property {string} apiUrl - The API url used to set custom API url + * @property {WidgetAffiliate} affiliate - If you want to charge users fee per transaction, you should + * pass `WidgetAffiliate` including affiliateRef, affiliatePercent, and affiliateWallets. * @property {number} amount - The default input amount. * @property {BlockchainAndTokenConfig} from - The `from` property is an optional property of type * `BlockchainAndTokenConfig` that specifies the default blockchain and token from which the user wants to * exchange.It can also used to limit source swap blockchains/tokens to some limited ones. + * @property {TrezorManifest} trezorManifest - Trezor Connect Manifest requires that you, + * as a Trezor Connect integrator,share your e-mail and application url. + * @property {TonConnectConfig} tonConnect - Configuration for TON Connect compatible providers like MyTonWallet. * @property {BlockchainAndTokenConfig} to - The "to" property is an optional property of type * "BlockchainAndTokenConfig" that specifies the default blockchain and token to which the user wants to * exchange.It can also used to limit destination swap blockchains/tokens to some limited ones. @@ -84,26 +210,68 @@ export type BlockchainAndTokenConfig = { * include values like `"metamask"`, `"kepler"`, or `"phantom"`. * @property {boolean} multiWallets - The `multiWallets` property is a boolean value that indicates * whether the widget should allow the user to select multiple wallets for the transaction. - * @property {boolean} customAddress - A boolean value indicating whether the user can input a custom + * @property {boolean} customDestination - A boolean value indicating whether the user can input a custom * address for the transaction. If set to true, the widget will allow the user to input a custom * address for the destination. + * @property {{[blockchain: string]: string }} defaultCustomDestinations - The `defaultCustomDestinations` property is a map of supported `blockchain` names to an arbitrary blockchain address. + * You could use it to set a default custom destination for some blockchains. e.g. {'BSC': '0x2be.....c1','ETH': '0x2be.....c1'} * @property {string} language - The language property is an optional string that specifies the * default language in which the widget should be displayed. If not provided, the widget will default to the * language of the user's browser. * @property {WidgetTheme} theme - The `theme` property is a part of the `WidgetConfig` type and is * used to specify the visual theme of the widget. It is of type `WidgetTheme`, which is an interface * that defines the various properties of the theme, such as colors, fonts, and others. + * @property {boolean} externalWallets + * If `externalWallets` is `true`, you should add `WidgetWallets` to your app. + * @property {boolean} excludeLiquiditySources - The `excludeLiquiditySources` property is a boolean value that when you + * set it to true, the list of liquidity sources provided in `liquiditySources` will be excluded; otherwise, they will be included. + * @property {Features} features - An optional object for configuring the visibility of various features. + * Keys include: + * - 'notification': Visibility state for the notification icon. + * - 'theme': Visibility state for the theme. + * - 'liquiditySource': Visibility state for liquidity source. + * - 'connectWalletButton': Visibility state for the wallet connect icon. + * - 'language': Visibility state for the language. + * - 'customTokens': Visibility state for the custom tokens. + * @property {Routing} routing - An optional object for configuring the enablement or numeric of various features. + * Keys include: + * - 'maxLength': If you want to limit the maximum acceptable length of a route, you could set this parameter. + * - 'avoidNativeFee': If you want to exclude swappers that have native tokens as fee, for example when you are using an AA account, you could set this parameter. + * - 'experimental': Use this parameter to enable experimental routes. This settings shouldn't be used in your production environment. + * - 'enableCentralizedSwappers': If you want to enable routing from the centralized protocols like XO Swap, you could set this parameter. + * @property {WidgetVariant} variant + * If it is expanded, multiple routes will show up on the home page; + * If it is full-expanded, multiple routes will show up on the home page with full routes; + * if not, you will need to go to a different page to see the suggested routes. */ + export type WidgetConfig = { apiKey: string; - affiliateRef?: string; + apiUrl?: string; + title?: string; + walletConnectProjectId?: string; + trezorManifest?: TrezorManifest; + tonConnect?: TonConnectConfig; + affiliate?: WidgetAffiliate; amount?: number; from?: BlockchainAndTokenConfig; to?: BlockchainAndTokenConfig; liquiditySources?: string[]; - wallets?: WalletType[]; + wallets?: (WalletType | LegacyProviderInterface)[]; multiWallets?: boolean; - customAddress?: boolean; - language?: string; + customDestination?: boolean; + defaultCustomDestinations?: { [blockchain: string]: string }; + language?: Language; theme?: WidgetTheme; + externalWallets?: boolean; + excludeLiquiditySources?: boolean; + features?: Features; + variant?: WidgetVariant; + signers?: SignersConfig; + // These are likely to change or remove at anytime. Please use with a caution. + __UNSTABLE_OR_INTERNAL__?: { + walletConnectListedDesktopWalletLink?: string; + autoUpdateSettings?: boolean; // If true, settings will be updated automatically based on the configuration. + }; + routing?: Routing; }; diff --git a/widget/embedded/src/types/event.ts b/widget/embedded/src/types/event.ts new file mode 100644 index 0000000000..249fdbc9fc --- /dev/null +++ b/widget/embedded/src/types/event.ts @@ -0,0 +1,105 @@ +import type { SelectedQuote } from './quote'; +import type { Wallet } from './wallets'; +import type { + RouteEventData, + StepEventData, +} from '@rango-dev/queue-manager-rango-preset'; + +import { WidgetEvents as QueueManagerEvents } from '@rango-dev/queue-manager-rango-preset'; + +type EventData< + T extends QuoteEventTypes | WalletEventTypes | UiEventTypes, + U extends Record | null +> = { type: T; payload: U }; + +export type PreventableEventPayload< + T extends Record = Record +> = { + preventDefault: () => void; +} & T; + +type Account = Wallet; + +export enum QuoteEventTypes { + QUOTE_INPUT_UPDATE = 'quoteInputUpdate', + QUOTE_OUTPUT_UPDATE = 'quoteOutputUpdate', +} + +export enum WalletEventTypes { + CONNECT = 'connect', + DISCONNECT = 'disconnect', +} + +/** + * We use a prefix for interaction type and a name for defining the event name: INTERACTION_EVENT_NAME + * e.g. CLICK_X_BUTTON or NAVIGATE_WALLET_PAGE + */ +export enum UiEventTypes { + CLICK_CONNECT_WALLET = 'clickConnectWallet', +} + +export type QuoteInputUpdateEventPayload = { + fromBlockchain?: string; + toBlockchain?: string; + fromToken?: { symbol: string; name: string | null; address: string | null }; + toToken?: { symbol: string; name: string | null; address: string | null }; + requestAmount?: string; +}; + +export type QuoteUpdateEventPayload = Pick< + SelectedQuote, + 'requestAmount' | 'swaps' | 'outputAmount' | 'resultType' | 'tags' +> | null; + +export type ConnectWalletEventPayload = { + walletType: string; + accounts: Account[]; +}; + +export type DisconnectWalletEventPayload = { + walletType: string; +}; + +export type ClickConnectWalletPayload = PreventableEventPayload; + +export type QuoteEventData = + | EventData + | EventData; + +export type WalletEventData = + | EventData + | EventData; + +export type UiEventData = EventData< + UiEventTypes.CLICK_CONNECT_WALLET, + ClickConnectWalletPayload +>; + +export enum WidgetEvents { + RouteEvent = QueueManagerEvents.RouteEvent, + StepEvent = QueueManagerEvents.StepEvent, + QuoteEvent = 'quoteEvent', + WalletEvent = 'walletEvent', + UiEvent = 'uiEvent', +} + +export type Events = { + [WidgetEvents.RouteEvent]: RouteEventData; + [WidgetEvents.StepEvent]: StepEventData; + [WidgetEvents.QuoteEvent]: QuoteEventData; + [WidgetEvents.WalletEvent]: WalletEventData; + [WidgetEvents.UiEvent]: UiEventData; +}; + +declare type EventHandler = (event: T) => void; + +export type WidgetEventEmitter = { + on( + type: Key, + handler: EventHandler + ): void; + off( + type: Key, + handler?: EventHandler + ): void; +}; diff --git a/widget/embedded/src/types/index.ts b/widget/embedded/src/types/index.ts index a8e7d70997..24f15b01b0 100644 --- a/widget/embedded/src/types/index.ts +++ b/widget/embedded/src/types/index.ts @@ -1,3 +1,5 @@ export * from './swap'; export * from './config'; -export * from './routing'; +export * from './quote'; +export * from './wallets'; +export * from './event'; diff --git a/widget/embedded/src/types/notification.ts b/widget/embedded/src/types/notification.ts new file mode 100644 index 0000000000..b79e69c7b3 --- /dev/null +++ b/widget/embedded/src/types/notification.ts @@ -0,0 +1,26 @@ +import { + type Route, + type RouteEvent, + type Step, + type StepEvent, +} from '@rango-dev/queue-manager-rango-preset'; + +type NotificationRoute = { + creationTime: number; + from: { + blockchain: Step['fromBlockchain']; + symbol: Step['fromSymbol']; + address: Step['fromSymbolAddress']; + }; + to: { + blockchain: Step['toBlockchain']; + symbol: Step['toSymbol']; + address: Step['toSymbolAddress']; + }; +}; + +export type Notification = Pick & { + event: RouteEvent | StepEvent; + creationTime: number; + route: NotificationRoute; +}; diff --git a/widget/embedded/src/types/quote.ts b/widget/embedded/src/types/quote.ts new file mode 100644 index 0000000000..a452da119e --- /dev/null +++ b/widget/embedded/src/types/quote.ts @@ -0,0 +1,130 @@ +/* eslint-disable @typescript-eslint/prefer-enum-initializers */ + +import type { PriceImpactWarningLevel } from '@rango-dev/ui'; +import type BigNumber from 'bignumber.js'; +import type { + Asset, + BlockchainValidationStatus, + RouteTag, + RoutingResultType, + SwapResult, +} from 'rango-sdk'; + +export enum QuoteErrorType { + NO_RESULT, + REQUEST_FAILED, + REQUEST_CANCELED, + BRIDGE_LIMIT, + INSUFFICIENT_SLIPPAGE, +} + +export type NoResultError = { + type: QuoteErrorType.NO_RESULT; + diagnosisMessage?: string; +}; + +export type BridgeLimitError = { + type: QuoteErrorType.BRIDGE_LIMIT; + swap: SwapResult; + recommendation: string; + fromAmountRangeError: string; +}; + +export type InsufficientSlippageError = { + type: QuoteErrorType.INSUFFICIENT_SLIPPAGE; + recommendedSlippages: RecommendedSlippages | null; + minRequiredSlippage: string | null; +}; + +export type QuoteRequestFailed = { type: QuoteErrorType.REQUEST_FAILED }; +export type QuoteRequestCanceled = { type: QuoteErrorType.REQUEST_CANCELED }; + +export type QuoteError = + | NoResultError + | BridgeLimitError + | InsufficientSlippageError + | QuoteRequestFailed + | QuoteRequestCanceled; + +export enum QuoteWarningType { + HIGH_VALUE_LOSS, + UNKNOWN_PRICE, + INSUFFICIENT_SLIPPAGE, + HIGH_SLIPPAGE, + EXCESSIVE_OUTPUT_AMOUNT_CHANGE, +} + +export type RecommendedSlippages = Map; + +export type InsufficientSlippageWarning = { + type: QuoteWarningType.INSUFFICIENT_SLIPPAGE; + recommendedSlippages: RecommendedSlippages | null; + minRequiredSlippage: string | null; +}; + +export type HighSlippageWarning = { + type: QuoteWarningType.HIGH_SLIPPAGE; + slippage: string | null; +}; + +export type HighValueLossWarning = { + type: QuoteWarningType.HIGH_VALUE_LOSS; + warningLevel: PriceImpactWarningLevel; + inputUsdValue: BigNumber; + outputUsdValue: BigNumber; + totalFee: BigNumber; + priceImpact: number; +}; + +export type UnknownPriceWarning = { + type: QuoteWarningType.UNKNOWN_PRICE; +}; + +export type ExcessiveOutputAmountChange = { + type: QuoteWarningType.EXCESSIVE_OUTPUT_AMOUNT_CHANGE; + usdValueChange: string; + percentageChange: string; +}; + +export type QuoteWarning = + | HighValueLossWarning + | ExcessiveOutputAmountChange + | UnknownPriceWarning + | InsufficientSlippageWarning + | HighSlippageWarning; + +export type ConfirmSwapWarnings = { + quote: QuoteWarning | null; + balance: { messages: string[] } | null; +}; + +export type QuoteResponse = { + requestId: string; + swaps?: SwapResult[]; + diagnosisMessages: string[] | null; +}; + +export type SelectedQuote = { + swaps: SwapResult[]; + requestId: string; + outputAmount?: string; + resultType?: RoutingResultType; + tags?: RouteTag[]; + validationStatus: BlockchainValidationStatus[] | null; + requestAmount: string; +}; + +export type QuoteErrorResponse = { + message: string; + options: QuoteError; +}; + +export type QuoteInputs = { + fromBlockchain: string | null; + toBlockchain: string | null; + fromToken: Asset | null; + toToken: Asset | null; + requestAmount: string; +}; + +export type UpdateQuoteInputs = (params: Partial) => void; diff --git a/widget/embedded/src/types/routing.ts b/widget/embedded/src/types/routing.ts deleted file mode 100644 index b06e9eceac..0000000000 --- a/widget/embedded/src/types/routing.ts +++ /dev/null @@ -1,76 +0,0 @@ -import { RouteState } from '../store/bestRoute'; -import { SettingsState } from '../store/settings'; - -interface BestRouteStoreParams { - fromChain?: RouteState['fromChain']; - toChain?: RouteState['toChain']; - fromToken?: RouteState['fromToken']; - toToken?: RouteState['toToken']; - inputAmount?: RouteState['inputAmount']; -} - -interface SettingsStoreParams { - slippage?: SettingsState['slippage']; - customSlippage?: SettingsState['customSlippage']; - disabledLiquiditySources?: SettingsState['disabledLiquiditySources']; - infiniteApprove?: SettingsState['infiniteApprove']; -} - -export type BestRouteEqualityParams = - | { - store: 'bestRoute'; - prevState: BestRouteStoreParams; - currentState: BestRouteStoreParams; - } - | { - store: 'settings'; - prevState: SettingsStoreParams; - currentState: SettingsStoreParams; - }; - -export enum ConfirmSwapErrorTypes { - NO_ROUTE, - ROUTE_UPDATED_WITH_HIGH_VALUE_LOSS, - REQUEST_FAILED, - INSUFFICIENT_SLIPPAGE, - INSUFFICIENT_BALANCE, -} - -export type ConfirmSwapError = - | { - type: ConfirmSwapErrorTypes.REQUEST_FAILED; - status?: number; - } - | { - type: ConfirmSwapErrorTypes.INSUFFICIENT_SLIPPAGE; - minRequiredSlippage: string | null; - } - | { type: ConfirmSwapErrorTypes.INSUFFICIENT_BALANCE; messages: string[] } - | { - type: Exclude< - ConfirmSwapErrorTypes, - | ConfirmSwapErrorTypes.REQUEST_FAILED - | ConfirmSwapErrorTypes.INSUFFICIENT_SLIPPAGE - | ConfirmSwapErrorTypes.INSUFFICIENT_BALANCE - >; - }; - -export type ConfirmSwapWarnings = - | { - type: ConfirmSwapWarningTypes.ROUTE_AND_OUTPUT_AMOUNT_UPDATED; - newOutputAmount: string; - percentageChange: string; - } - | { - type: Exclude< - ConfirmSwapWarningTypes, - ConfirmSwapWarningTypes.ROUTE_AND_OUTPUT_AMOUNT_UPDATED - >; - }; - -export enum ConfirmSwapWarningTypes { - ROUTE_UPDATED, - ROUTE_SWAPPERS_UPDATED, - ROUTE_COINS_UPDATED, - ROUTE_AND_OUTPUT_AMOUNT_UPDATED, -} diff --git a/widget/embedded/src/types/swap.ts b/widget/embedded/src/types/swap.ts index 70cee49075..074d9ea63d 100644 --- a/widget/embedded/src/types/swap.ts +++ b/widget/embedded/src/types/swap.ts @@ -1,15 +1,14 @@ -import { SwapSavedSettings } from '@rango-dev/ui/dist/types/swaps'; +import type { SwapSavedSettings } from 'rango-types'; export type PendingSwapSettings = Omit< SwapSavedSettings, 'disabledSwappersIds' >; -export type SwapButtonState = ( - | { disabled: true } - | { disabled: false; hasWarning?: boolean } -) & { +export type SwapButtonState = { + disabled: boolean; title: string; + action: 'connect-wallet' | 'confirm-warning' | 'confirm-swap'; }; export type ConvertedToken = { diff --git a/widget/embedded/src/types/wallets.ts b/widget/embedded/src/types/wallets.ts new file mode 100644 index 0000000000..2da19b01d6 --- /dev/null +++ b/widget/embedded/src/types/wallets.ts @@ -0,0 +1,27 @@ +import type { WalletInfo } from '@rango-dev/ui'; +import type { WalletType } from '@rango-dev/wallets-shared'; + +export interface Wallet { + chain: string; + address: string; + walletType: WalletType; +} + +export type Balance = { + amount: string; + decimals: number; + usdValue: string | null; +}; + +export type Blockchain = string; +type TokenSymbol = string; +type Address = string; + +/** `blockchain-symbol-Address` */ +export type TokenHash = `${Blockchain}-${TokenSymbol}-${Address}`; + +export type TokensBalance = { + [key: TokenHash]: Balance; +}; + +export type WalletInfoWithExtra = WalletInfo; diff --git a/widget/embedded/src/utils/colors.ts b/widget/embedded/src/utils/colors.ts new file mode 100644 index 0000000000..b58c4620bc --- /dev/null +++ b/widget/embedded/src/utils/colors.ts @@ -0,0 +1,184 @@ +/* eslint-disable @typescript-eslint/no-magic-numbers */ +// Types +import type { ThemeColors, WidgetColors, WidgetColorsKeys } from '../types'; + +type RGB = { + red: number; + green: number; + blue: number; +}; + +type ShadeOrTintFunction = (rgb: RGB, step: number) => RGB; + +const HEX_BASE = 16; +const MAX_COLOR_VALUE = 255; +const PERCENT = 0.11; + +// Utility Functions + +function expandShortHexColor(hexColor: string) { + // Remove '#' if it exists + if (hexColor.startsWith('#')) { + hexColor = hexColor.slice(1); + } + + // Check if the hexColor has a length of 3 + if (hexColor.length === 3) { + // Convert the string to an array of characters + const characters = hexColor.split(''); + + // Duplicate each character and combine them into a single string + const expandedHex = characters.reduce(function (acc, char) { + return acc + char + char; + }, ''); + + // Return the resulting 6-character hex color + return `#${expandedHex}`; + } + + // Return the original hexColor if it's not 3 characters + return `#${hexColor}`; +} + +/* + * We letting users to override some specific colors (e.g. `primary550`, `secondary100`). + * So we are generating a range of colors if `primary` (or other keys) has passed but if user is passing a specific color, + * we will override the user color to generated range. + */ +function isOverridingColor(colorKey: string): boolean { + return /[0-9]+$/.test(colorKey); +} + +// pad a hexadecimal string with zeros if it needs it +function pad(number: string, length: number) { + return number.padStart(length, '0'); +} + +// Convert an integer to a 2-character hex string +function intToHex(value: number) { + const clampedValue = Math.min( + Math.max(Math.round(value), 0), + MAX_COLOR_VALUE + ); + return pad(clampedValue.toString(HEX_BASE), 2); +} + +// convert one of our rgb color objects to a full hex color string +function rgbToHex(rgb: RGB) { + return `#${intToHex(rgb.red)}${intToHex(rgb.green)}${intToHex(rgb.blue)}`; +} + +// Convert a hex color string to an RGB object +function hexToRGB(hex: string): RGB { + const red = parseInt(hex.slice(1, 3), HEX_BASE); + const green = parseInt(hex.slice(3, 5), HEX_BASE); + const blue = parseInt(hex.slice(5, 7), HEX_BASE); + + return { red, green, blue }; +} + +// Generate a shade of a given RGB color +function generateShade(rgb: RGB, step: number): RGB { + const factor = 1 - PERCENT * step; + return { + red: rgb.red * factor, + green: rgb.green * factor, + blue: rgb.blue * factor, + }; +} + +// Generate a tint of a given RGB color +function generateTint(rgb: RGB, step: number): RGB { + const factor = PERCENT * step; + return { + red: rgb.red + (MAX_COLOR_VALUE - rgb.red) * factor, + green: rgb.green + (MAX_COLOR_VALUE - rgb.green) * factor, + blue: rgb.blue + (MAX_COLOR_VALUE - rgb.blue) * factor, + }; +} + +// Main Functions + +// Calculate an array of shades from a hex color string +export function calculateShades(hex: string): string[] { + return calculateColors(hex, generateShade); +} + +// Calculate an array of tints from a hex color string +export function calculateTints(hex: string): string[] { + return calculateColors(hex, generateTint); +} + +// General function to calculate shades or tints +function calculateColors( + hex: string, + generateColor: ShadeOrTintFunction +): string[] { + const rgb = hexToRGB(hex); + const colors: string[] = []; + for (let i = 1; i < 9; i++) { + colors.push(rgbToHex(generateColor(rgb, i))); + } + return colors; +} + +// Create tints and shades for a given color +export function createTintsAndShades( + hex: string, + colorKey: string, + isReversed?: boolean +): { [key: string]: string } { + const BASE_INDEX = 100; + const STEP = 50; + + const tints = calculateTints(hex).reverse().concat(hex); + const shades = calculateShades(hex); + const combinedColors = tints.concat(shades); + + const colorMap: { [key: string]: string } = {}; + const length = combinedColors.length; + + for (let i = 0; i < length; i++) { + const index = BASE_INDEX + (isReversed ? length - 1 - i : i) * STEP; + colorMap[`${colorKey}${index}`] = combinedColors[i]; + } + + return colorMap; +} + +// Generate a color palette based on base colors and "Expand Colors" +export function expandToGenerateThemeColors( + baseColors: ThemeColors, + expandColors: WidgetColors, + options?: { reverseNeutralRange?: boolean } +): ThemeColors { + const output = { ...baseColors }; + + for (const colorKey in expandColors) { + const expandColor = expandColors[colorKey as WidgetColorsKeys] as string; + const isNeutralReversed = + colorKey === 'neutral' && !!options?.reverseNeutralRange; + /* + *Most of the colors are range but there are some colors that should be a single value e.g. + *{ + * // single value + * background: "#fff", + * // range + * primary: '#1C3CF1', + * primary500: '#1C3CF1', + * primary550: '#0B27C4', + *} + */ + const isSingleColor = ['background', 'foreground'].includes(colorKey); + + if (!isSingleColor && !isOverridingColor(colorKey)) { + const expandedHexColor = expandShortHexColor(expandColor); + Object.assign( + output, + createTintsAndShades(expandedHexColor, colorKey, isNeutralReversed) + ); + } + } + + return { ...output, ...expandColors }; +} diff --git a/widget/embedded/src/utils/common.ts b/widget/embedded/src/utils/common.ts index 7ee04d3d24..b3c26b3c47 100644 --- a/widget/embedded/src/utils/common.ts +++ b/widget/embedded/src/utils/common.ts @@ -1,3 +1,19 @@ +import type { WalletInfoWithExtra } from '../types'; +import type { Token } from 'rango-sdk'; + +import { BlockchainCategories, WalletState } from '@rango-dev/ui'; +import { TransactionType } from 'rango-sdk'; + +import { WIDGET_UI_ID } from '../constants'; +import { SUPPORTED_FONTS } from '../constants/fonts'; +import { + MIN_LENGTH_SYMBOL_CONTAINS, + MIN_LENGTH_SYMBOL_START_WITH, + MIN_LENGTH_TOKEN_ADDRESS_CONTAINS, + MIN_LENGTH_TOKEN_NAME_CONTAINS, + MIN_LENGTH_TOKEN_NAME_EXACT_MATCH, +} from '../constants/searchFor'; + export function removeDuplicateFrom(array: T[]): T[] { return Array.from(new Set(array)); } @@ -10,30 +26,7 @@ export function areEqual( array1.length === array2.length && array1.every((v, i) => v === array2[i]) ); } -export function shadeColor(color: string, percent: number) { - var R = parseInt(color.substring(1, 3), 16); - var G = parseInt(color.substring(3, 5), 16); - var B = parseInt(color.substring(5, 7), 16); - - R = (R * (100 + percent)) / 100; - G = (G * (100 + percent)) / 100; - B = (B * (100 + percent)) / 100; - - R = R < 255 ? R : 255; - G = G < 255 ? G : 255; - B = B < 255 ? B : 255; - - R = Math.round(R); - G = Math.round(G); - B = Math.round(B); - - var RR = R.toString(16).length == 1 ? '0' + R.toString(16) : R.toString(16); - var GG = G.toString(16).length == 1 ? '0' + G.toString(16) : G.toString(16); - var BB = B.toString(16).length == 1 ? '0' + B.toString(16) : B.toString(16); - - return '#' + RR + GG + BB; -} - +// eslint-disable-next-line @typescript-eslint/ban-types export function debounce(fn: Function, time: number) { let timeoutId: ReturnType | null; return wrapper; @@ -47,3 +40,221 @@ export function debounce(fn: Function, time: number) { }, time); } } + +export function containsText(text: string, searchText: string): boolean { + // eslint-disable-next-line @typescript-eslint/no-magic-numbers + return text.toLowerCase().indexOf(searchText.toLowerCase()) > -1; +} + +export function exactText(text: string, searchText: string): boolean { + return text.toLowerCase() === searchText.toLowerCase(); +} + +export function startWithText(text: string, searchText: string): boolean { + return text.toLowerCase().startsWith(searchText.toLowerCase()); +} + +export const getContainer = () => + document.getElementById(WIDGET_UI_ID.SWAP_BOX_ID) as HTMLElement; + +export const getExpanded = () => + document.getElementById(WIDGET_UI_ID.EXPANDED_BOX_ID) as HTMLElement; + +function compareExactMatchText( + searchFor: string, + textA: string | null, + textB: string | null +) { + const exactMatchA = !!textA && exactText(textA, searchFor); + const exactMatchB = !!textB && exactText(textB, searchFor); + if (exactMatchA !== exactMatchB) { + return exactMatchA ? -1 : 1; + } + + return 0; +} + +function compareContainsText( + searchFor: string, + textA: string | null, + textB: string | null +) { + const textContainsA = !!textA && containsText(textA, searchFor); + const textContainsB = !!textB && containsText(textB, searchFor); + if (textContainsA !== textContainsB) { + return textContainsA ? -1 : 1; + } + + // If both texts contains the searched term, The shorter one has priority + if (textContainsA && textContainsB && textA?.length !== textB?.length) { + return textA?.length - textB?.length; + } + + return 0; +} + +function compareStartWithText( + searchFor: string, + textA: string | null, + textB: string | null +) { + const textStartWithA = !!textA && startWithText(textA, searchFor); + const textStartWithB = !!textB && startWithText(textB, searchFor); + if (textStartWithA !== textStartWithB) { + return textStartWithA ? -1 : 1; + } + + // If both texts start with the searched term, The shorter one has priority + if (textStartWithA && textStartWithB && textA?.length !== textB?.length) { + return textA?.length - textB?.length; + } + + return 0; +} + +export function compareWithSearchFor( + tokenA: Token, + tokenB: Token, + searchFor?: string +): number { + if (!searchFor) { + return 0; + } + + // 1: Check the order to exact match the symbol + const symbolExactMatchCompare = compareExactMatchText( + searchFor, + tokenA.symbol, + tokenB.symbol + ); + if (symbolExactMatchCompare) { + return symbolExactMatchCompare; + } + + // 2: Check the order to exact match the token name + if (searchFor.length >= MIN_LENGTH_TOKEN_NAME_EXACT_MATCH) { + const tokenNameExactMatchCompare = compareExactMatchText( + searchFor, + tokenA.name, + tokenB.name + ); + if (tokenNameExactMatchCompare) { + return tokenNameExactMatchCompare; + } + } + + // 3: Check symbol start with searchFor + if (searchFor.length >= MIN_LENGTH_SYMBOL_START_WITH) { + const symbolStartWithCompare = compareStartWithText( + searchFor, + tokenA.symbol, + tokenB.symbol + ); + + if (symbolStartWithCompare) { + return symbolStartWithCompare; + } + } + + // 4: Check symbol Contains searchFor + if (searchFor.length >= MIN_LENGTH_SYMBOL_CONTAINS) { + const symbolContainsCompare = compareContainsText( + searchFor, + tokenA.symbol, + tokenB.symbol + ); + + if (symbolContainsCompare) { + return symbolContainsCompare; + } + } + + // 5: Check token name start with searchFor + if (searchFor.length >= MIN_LENGTH_TOKEN_NAME_CONTAINS) { + const tokenNameStartWithCompare = compareStartWithText( + searchFor, + tokenA.name, + tokenB.name + ); + + if (tokenNameStartWithCompare) { + return tokenNameStartWithCompare; + } + } + + // 6: Check token name Contains searchFor + if (searchFor.length >= MIN_LENGTH_TOKEN_NAME_CONTAINS) { + const tokenNameContainsCompare = compareContainsText( + searchFor, + tokenA.name, + tokenB.name + ); + + if (tokenNameContainsCompare !== 0) { + return tokenNameContainsCompare; + } + } + + // 7: Check address start with searchFor + if (searchFor.length >= MIN_LENGTH_TOKEN_ADDRESS_CONTAINS) { + const addressStartWithCompare = compareStartWithText( + searchFor, + tokenA.address, + tokenB.address + ); + + if (addressStartWithCompare) { + return addressStartWithCompare; + } + } + + // 8: Check address Contains searchFor + if (searchFor.length >= MIN_LENGTH_TOKEN_ADDRESS_CONTAINS) { + const addressContainCompare = compareContainsText( + searchFor, + tokenA.address, + tokenB.address + ); + + if (addressContainCompare !== 0) { + return addressContainCompare; + } + } + + return 0; +} + +export const isBlockchainTypeInCategory = ( + blockchainType: TransactionType, + category: string +): boolean => { + switch (category) { + case BlockchainCategories.ALL: + return true; + case BlockchainCategories.UTXO: + return blockchainType === TransactionType.TRANSFER; + case BlockchainCategories.OTHER: + return ( + blockchainType !== TransactionType.TRANSFER && + blockchainType !== TransactionType.COSMOS && + blockchainType !== TransactionType.EVM + ); + default: + return blockchainType === category; + } +}; + +export const getFontUrlByName = (fontName: string) => { + const font = SUPPORTED_FONTS.find((font) => font.value === fontName); + return font?.url; +}; + +export function isSingleWalletActive( + wallets: WalletInfoWithExtra[], + multiWallets?: boolean +) { + const atLeastOneWalletIsConnected = !!wallets.find( + (w) => w.state === WalletState.CONNECTED + ); + return multiWallets === false && atLeastOneWalletIsConnected; +} diff --git a/widget/embedded/src/utils/configs.ts b/widget/embedded/src/utils/configs.ts index 26406f8138..3dfb3275d7 100644 --- a/widget/embedded/src/utils/configs.ts +++ b/widget/embedded/src/utils/configs.ts @@ -1,15 +1,27 @@ +import type { Tokens, WidgetVariant } from '../types'; +import type { Asset, BlockchainMeta, Token } from 'rango-sdk'; + +import { RANGO_PUBLIC_API_KEY } from '../constants'; + +import { areTokensEqual } from './wallets'; + export interface Configs { API_KEY: string; + BASE_URL?: string; } -const RANGO_PUBLIC_API_KEY = 'c6381a79-2817-4602-83bf-6a641a409e32'; +type TokensConfig = + | Asset[] + | { + [blockchain: string]: Tokens; + }; let configs: Configs = { API_KEY: RANGO_PUBLIC_API_KEY, }; export function getConfig(name: keyof Configs) { - return configs[name]; + return configs[name] || ''; } export function setConfig(name: keyof Configs, value: any) { @@ -18,6 +30,9 @@ export function setConfig(name: keyof Configs, value: any) { return value; } +/** + * Getting new configs from params and reset the value of global `configs` with provided param. + */ export function initConfig(nextConfigs: Configs) { let clonedConfigs; if (typeof structuredClone === 'function') { @@ -28,3 +43,49 @@ export function initConfig(nextConfigs: Configs) { configs = clonedConfigs; return configs; } + +export const DEFAULT_PRIMARY_RADIUS = 20; +export const DEFAULT_SECONDARY_RADIUS = 25; + +export const THEME_CLASS_NAME_PREFIX = `theme-widget`; + +export const isTokenExcludedInConfig = ( + token: Token | null, + tokensConfig?: TokensConfig +) => { + let result = false; + if (tokensConfig && token) { + if (Array.isArray(tokensConfig)) { + result = !tokensConfig.some((asset) => areTokensEqual(asset, token)); + } else if (!Array.isArray(tokensConfig) && tokensConfig[token.blockchain]) { + result = tokensConfig[token.blockchain].tokens.some((asset) => + areTokensEqual(asset, token) + ); + const isExcluded = tokensConfig[token.blockchain].isExcluded; + return (!isExcluded && !result) || (isExcluded && result); + } + } + return result; +}; + +export const isBlockchainExcludedInConfig = ( + blockchain: BlockchainMeta | null, + blockchainsConfig?: string[] +) => { + return ( + blockchain && + blockchainsConfig && + !blockchainsConfig.includes(blockchain.name) + ); +}; + +export const isVariantExpandable = ( + isLargeScreen: boolean, + isExtraLargeScreen: boolean, + variant?: WidgetVariant +) => { + return ( + (variant === 'expanded' && (isLargeScreen || isExtraLargeScreen)) || + (variant === 'full-expanded' && isExtraLargeScreen) + ); +}; diff --git a/widget/embedded/src/utils/date.ts b/widget/embedded/src/utils/date.ts index 7aade52b48..aefa4dbf5a 100644 --- a/widget/embedded/src/utils/date.ts +++ b/widget/embedded/src/utils/date.ts @@ -1,8 +1,10 @@ -import { PendingSwap } from '@rango-dev/queue-manager-rango-preset'; +import type { GroupBy } from '../components/HistoryGroupedList/HistoryGroupedList.types'; +import type { PendingSwap } from 'rango-types'; + +import { i18n } from '@lingui/core'; import dayjs from 'dayjs'; -import { GroupBy } from '@rango-dev/ui'; -export const groupSwapsByDate: GroupBy = swaps => { +export const groupSwapsByDate: GroupBy = (swaps) => { const output: Map< string, { @@ -13,50 +15,67 @@ export const groupSwapsByDate: GroupBy = swaps => { [ 'today', { - title: 'Today', + title: i18n.t('Today'), swaps: [], }, ], [ 'week', { - title: 'This week', + title: i18n.t('This week'), swaps: [], }, ], [ 'month', { - title: 'This month', + title: i18n.t('This month'), swaps: [], }, ], [ 'year', { - title: 'This year', - swaps: [], - }, - ], - [ - 'history', - { - title: 'History', + title: i18n.t('This year'), swaps: [], }, ], ]); + function addYearsToOutput(key: string, swap: PendingSwap) { + if (!output.has(key)) { + output.set(key, { + title: key, + swaps: [], + }); + } + output.get(key)?.swaps.push(swap); + } + const now = dayjs(); - swaps.forEach(swap => { - const swapDate = dayjs(Number(swap.creationTime)); - if (now.isSame(swapDate, 'day')) output.get('today')?.swaps.push(swap); - else if (now.isSame(swapDate, 'week')) output.get('week')?.swaps.push(swap); - else if (now.isSame(swapDate, 'month')) + swaps.forEach((swap) => { + const time = Number(swap.creationTime); + const swapDate = dayjs(time); + if (now.isSame(swapDate, 'day')) { + output.get('today')?.swaps.push(swap); + } else if (now.isSame(swapDate, 'week')) { + output.get('week')?.swaps.push(swap); + } else if (now.isSame(swapDate, 'month')) { output.get('month')?.swaps.push(swap); - else if (now.isSame(swapDate, 'year')) output.get('year')?.swaps.push(swap); - else output.get('history')?.swaps.push(swap); + } else if (now.isSame(swapDate, 'year')) { + output.get('year')?.swaps.push(swap); + } else { + const year = new Date(time).getFullYear().toString(); + addYearsToOutput(year, swap); + } }); - return Array.from(output.values()); + const groupedSwaps = Array.from(output.values()).filter( + (item) => item.swaps.length > 0 + ); + const items = groupedSwaps.flatMap((group) => group.swaps); + const groupCounts = groupedSwaps.map((group) => group.swaps.length); + const groups = groupedSwaps.map((group) => group.title); + + return { swaps: items, groupCounts, groups }; }; diff --git a/widget/embedded/src/utils/events.ts b/widget/embedded/src/utils/events.ts new file mode 100644 index 0000000000..a792a697de --- /dev/null +++ b/widget/embedded/src/utils/events.ts @@ -0,0 +1,27 @@ +import { eventEmitter } from '../services/eventEmitter'; +import { type UiEventData, WidgetEvents } from '../types'; + +type UiEvent = { + type: UiEventData['type']; + payload?: Omit; +}; + +export function emitPreventableEvent(event: UiEvent, action: () => void): void { + let defaultPrevented = false; + + const extendedPayload = { + preventDefault() { + defaultPrevented = true; + }, + ...(event.payload === undefined && { payload: event.payload }), + }; + + eventEmitter.emit(WidgetEvents.UiEvent, { + type: event.type, + payload: extendedPayload, + }); + + if (!defaultPrevented) { + action(); + } +} diff --git a/widget/embedded/src/utils/hash.ts b/widget/embedded/src/utils/hash.ts new file mode 100644 index 0000000000..29d2fb3f28 --- /dev/null +++ b/widget/embedded/src/utils/hash.ts @@ -0,0 +1,27 @@ +/* eslint-disable @typescript-eslint/no-magic-numbers */ +// Original Code: https://github.com/stitchesjs/stitches/blob/canary/packages/core/src/convert/toHash.js + +const toAlphabeticChar = (code: number) => + String.fromCharCode(code + (code > 25 ? 39 : 97)); + +const toAlphabeticName = (code: number) => { + let name = ''; + let x; + + for (x = Math.abs(code); x > 52; x = (x / 52) | 0) { + name = toAlphabeticChar(x % 52) + name; + } + + return toAlphabeticChar(x % 52) + name; +}; + +const toPhash = (h: number, x: string) => { + let i = x.length; + while (i) { + h = (h * 33) ^ x.charCodeAt(--i); + } + return h; +}; + +export const toHash = (value: object) => + toAlphabeticName(toPhash(5381, JSON.stringify(value)) >>> 0); diff --git a/widget/embedded/src/utils/meta.ts b/widget/embedded/src/utils/meta.ts new file mode 100644 index 0000000000..170b06114d --- /dev/null +++ b/widget/embedded/src/utils/meta.ts @@ -0,0 +1,72 @@ +import type { TokenHash } from '../types'; +import type { Asset, BlockchainMeta, SwapperMeta, Token } from 'rango-sdk'; + +export function getBlockchainDisplayNameFor( + blockchainName: string, + blockchains: BlockchainMeta[] +): string | undefined { + return blockchains.find((blockchain) => blockchain.name === blockchainName) + ?.displayName; +} +export function getBlockchainShortNameFor( + blockchainName: string, + blockchains: BlockchainMeta[] +): string | undefined { + return blockchains.find((blockchain) => blockchain.name === blockchainName) + ?.shortName; +} + +export function getBlockchainImage( + blockchainName: string, + blockchains: BlockchainMeta[] +): string | undefined { + return blockchains.find((blockchain) => blockchain.name === blockchainName) + ?.logo; +} + +export function getSwapperDisplayName( + swapperId: string, + swappers: SwapperMeta[] +) { + return swappers.find((swapper) => swapper.id === swapperId)?.title; +} + +export function findBlockchain(name: string, blockchains: BlockchainMeta[]) { + return blockchains.find((blockchain) => blockchain.name === name) ?? null; +} + +export function isTokenNative( + token: Token, + blockchain: BlockchainMeta | undefined +) { + if (!blockchain || !token) { + return false; + } + + for (const feeAsset of blockchain.feeAssets) { + if ( + token?.blockchain === feeAsset?.blockchain && + token?.symbol === feeAsset?.symbol && + token?.address === feeAsset?.address + ) { + return true; + } + } + + return false; +} + +export function createTokenHash(asset: Asset): TokenHash { + return `${asset.blockchain.toLowerCase()}-${asset.symbol.toLowerCase()}-${( + asset.address ?? '' + ).toLowerCase()}`; +} + +export function isValidTokenAddress( + chain: BlockchainMeta, + address: string +): boolean { + const regex = chain.addressPatterns; + const valid = regex.filter((r) => new RegExp(r).test(address)).length > 0; + return valid; +} diff --git a/widget/embedded/src/utils/numbers.ts b/widget/embedded/src/utils/numbers.ts index e48f56b681..27d3dbdeb2 100644 --- a/widget/embedded/src/utils/numbers.ts +++ b/widget/embedded/src/utils/numbers.ts @@ -1,23 +1,35 @@ +/* eslint-disable @typescript-eslint/no-magic-numbers */ + +import type { BestRouteResponse } from 'rango-sdk'; + import { BigNumber } from 'bignumber.js'; -import { BestRouteResponse } from 'rango-sdk'; -export const percentToString = (p: number, fractions = 0): string => - (p * 100).toFixed(fractions); -export const secondsToString = (s: number): string => { - const seconds = (s % 60).toString().padStart(2, '0'); - const minutes = parseInt((s / 60).toString()) +/* + * if time > 1h -> rounded with 5 minutes precision + * if time < 1h -> rounded with 15 seconds precision + */ +export const roundedSecondsToString = (s: number): string => { + const seconds = Math.floor((s % 60) / 15) * 15; + const minutes = parseInt((s / 60).toString()); + if (minutes >= 60) { + return `${Math.floor(minutes / 5) * 5}:00`; + } + return `${minutes.toString().padStart(2, '0')}:${seconds .toString() - .padStart(2, '0'); - return `${minutes}:${seconds}`; + .padStart(2, '0')}`; }; export const numberToString = ( - number: BigNumber | string | null, + number: BigNumber | string | number | null | undefined, minDecimals: number | null = null, maxDecimals: number | null = null ): string => { - if (number === null) return ''; - if (number === '') return ''; + if (number === null || number === undefined) { + return ''; + } + if (number === '') { + return ''; + } const n = new BigNumber(number); const roundingMode = 1; let maxI = 1000; @@ -28,8 +40,10 @@ export const numberToString = ( } } - if (n.gte(10000)) return n.toFormat(0, roundingMode); - if (n.gte(1000)) + if (n.gte(10000)) { + return n.toFormat(0, roundingMode); + } + if (n.gte(1000)) { return n.toFormat( Math.min( maxI, @@ -37,7 +51,8 @@ export const numberToString = ( ), roundingMode ); - if (n.gte(100)) + } + if (n.gte(100)) { return n.toFormat( Math.min( maxI, @@ -45,7 +60,8 @@ export const numberToString = ( ), roundingMode ); - if (n.gte(1)) + } + if (n.gte(1)) { return n.toFormat( Math.min( maxI, @@ -53,7 +69,8 @@ export const numberToString = ( ), roundingMode ); - if (n.gte(0.01)) + } + if (n.gte(0.01)) { return n.toFormat( Math.min( maxI, @@ -61,8 +78,9 @@ export const numberToString = ( ), roundingMode ); - for (let i = minDecimals || 4; i < 17; i++) - if (n.gte(Math.pow(10, -i))) + } + for (let i = minDecimals || 4; i < 17; i++) { + if (n.gte(Math.pow(10, -i))) { return n.toFormat( Math.min( maxI, @@ -70,7 +88,11 @@ export const numberToString = ( ), roundingMode ); - if (n.isEqualTo(0)) return '0'; + } + } + if (n.isEqualTo(0)) { + return '0'; + } return n.toFormat( Math.min(maxI, Math.min(maxDecimals || 100, Math.max(minDecimals || 0, 8))), @@ -78,44 +100,16 @@ export const numberToString = ( ); }; -export const convertBigNumberToHex = ( - value: BigNumber, - decimals: number -): string => { - return '0x' + value.shiftedBy(decimals).toString(16); -}; - export const uint8ArrayToHex = (buffer: Uint8Array): string => { // buffer is an ArrayBuffer + // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore return [...buffer].map((x) => x.toString(16).padStart(2, '0')).join(''); }; -export function dollarToConciseString(num: number | undefined): string { - if (!num) return '-'; - if (num < 1) return ' < 1$'; - if (num < 1000) return numberToString(new BigNumber(num)) + '$'; - if (num < 10_000) return parseInt((num / 100).toString()) / 10 + 'K'; - if (num < 1_000_000) return parseInt((num / 1000).toString()) + 'K'; - if (num < 100_000_000) return parseInt((num / 100000).toString()) / 10 + 'M'; - return parseInt((num / 1000000).toString()) + 'M'; -} - -export function removeExtraDecimals(num: string, maxDecimals: number): string { - try { - if (!num.includes('.')) return num; - const [b, f] = num.split('.'); - if (f && f.length > maxDecimals) { - return `${b}.${f.substring(0, maxDecimals)}`; - } - return num; - } catch (e) { - return num; - } -} - -export const totalArrivalTime = (data: BestRouteResponse | null) => - data?.result?.swaps?.reduce((a, b) => a + b.estimatedTimeInSeconds, 0) || 0; +export const totalArrivalTime = ( + data: { estimatedTimeInSeconds: number | null }[] | undefined +) => data?.reduce((a, b) => a + (b.estimatedTimeInSeconds ?? 0), 0) || 0; export const rawFees = (data: BestRouteResponse): string => ( @@ -126,12 +120,8 @@ export const rawFees = (data: BestRouteResponse): string => .reduce((partialSum, a) => partialSum + parseFloat(a.fee.amount), 0) .toFixed(3); -export const decimalNumber = (number = '0', toFixed: number) => - parseFloat(number).toFixed(toFixed); - export const containsText = (text: string, searchText: string) => text.toLowerCase().indexOf(searchText.toLowerCase()) > -1; export const isPositiveNumber = (text?: string) => !!text && parseFloat(text) > 0; -10; diff --git a/widget/embedded/src/utils/providers.ts b/widget/embedded/src/utils/providers.ts new file mode 100644 index 0000000000..2c68e74df9 --- /dev/null +++ b/widget/embedded/src/utils/providers.ts @@ -0,0 +1,132 @@ +import type { WidgetConfig } from '../types'; +import type { LegacyProviderInterface } from '@rango-dev/wallets-core/legacy'; + +import { + defineVersions, + pickVersion, + Provider, + type VersionedProviders, +} from '@rango-dev/wallets-core'; + +export interface ProvidersOptions { + walletConnectProjectId?: WidgetConfig['walletConnectProjectId']; + walletConnectListedDesktopWalletLink?: NonNullable< + WidgetConfig['__UNSTABLE_OR_INTERNAL__'] + >['walletConnectListedDesktopWalletLink']; + trezorManifest: WidgetConfig['trezorManifest']; + tonConnect: WidgetConfig['tonConnect']; + experimentalWallet?: 'enabled' | 'disabled'; +} + +/** + * + * Generate a list of providers by passing a provider name (e.g. metamask) or a custom provider which implemented ProviderInterface. + * @returns BothProvidersInterface[] a list of BothProvidersInterface + * + */ +type BothProvidersInterface = LegacyProviderInterface | Provider; +export function matchAndGenerateProviders({ + allProviders, + configWallets, + options, +}: { + allProviders: VersionedProviders[]; + configWallets: WidgetConfig['wallets']; + options?: ProvidersOptions; +}): VersionedProviders[] { + if (configWallets) { + /* + * If `wallets` is included in widget config, + * allProviders should be filtered based on wallets list + */ + const selectedProviders: VersionedProviders[] = []; + + configWallets.forEach((requestedWallet) => { + /* + * There are two types of provider we get, the first one is only passing the wallet name + * then we will match the wallet name with our providers (@rango-dev/provider-*). + * The second way is passing a custom provider which implemented ProviderInterface. + */ + if (typeof requestedWallet === 'string') { + const result = allProviders.find((provider) => { + /* + * To find a provider in allProviders, + * a version of each provider should be picked + * and validated based on that version scheme. + * If the corresponding provider to a wallet was found in allProvider, + * it will be add to selected providers. + */ + const versionedProvider = pickProviderVersionWithFallbackToLegacy( + provider, + options + ); + if (versionedProvider instanceof Provider) { + return versionedProvider.id === requestedWallet; + } + return versionedProvider.config.type === requestedWallet; + }); + + /* + * A provider may have multiple versions + * (e.g., 0.0, also known as legacy, and 1.0, also known as hub). + * We should ensure that all existing versions of a provider are added to selectedProviders. + */ + if (result) { + selectedProviders.push(result); + } else { + console.warn( + // A provider name is included in config but was not found in allProviders + `Couldn't find ${requestedWallet} provider. Please make sure you are passing the correct name.` + ); + } + } else { + // It's a custom provider so we directly push it to the list. + if (requestedWallet instanceof Provider) { + selectedProviders.push( + defineVersions().version('1.0.0', requestedWallet).build() + ); + } else { + selectedProviders.push( + defineVersions().version('0.0.0', requestedWallet).build() + ); + } + } + }); + + return selectedProviders; + } + + return allProviders; +} + +function pickProviderVersionWithFallbackToLegacy( + provider: VersionedProviders, + options?: ProvidersOptions +): BothProvidersInterface { + const { experimentalWallet = 'enabled' } = options || {}; + const version = experimentalWallet == 'disabled' ? '0.0.0' : '1.0.0'; + + try { + return pickVersion(provider, version)[1]; + } catch { + // Fallback to legacy version, if target version doesn't exists. + return pickVersion(provider, '0.0.0')[1]; + } +} + +export function configWalletsToWalletName( + providers: VersionedProviders[], + options?: ProvidersOptions +): string[] { + const names = providers + .map((provider) => + pickProviderVersionWithFallbackToLegacy(provider, options) + ) + .map((provider) => { + if (provider instanceof Provider) { + return provider.id; + } + return provider.config.type; + }); + return names; +} diff --git a/widget/embedded/src/utils/queue.ts b/widget/embedded/src/utils/queue.ts index ce360e9f94..477a72cf6d 100644 --- a/widget/embedded/src/utils/queue.ts +++ b/widget/embedded/src/utils/queue.ts @@ -1,5 +1,5 @@ -import { Manager } from '@rango-dev/queue-manager-core'; -import { +import type { Manager } from '@rango-dev/queue-manager-core'; +import type { PendingSwapWithQueueID, SwapStorage, } from '@rango-dev/queue-manager-rango-preset'; diff --git a/widget/embedded/src/utils/quote.ts b/widget/embedded/src/utils/quote.ts new file mode 100644 index 0000000000..05f54b6c7f --- /dev/null +++ b/widget/embedded/src/utils/quote.ts @@ -0,0 +1,393 @@ +/* eslint-disable @typescript-eslint/no-magic-numbers */ +import type { RetryQuote } from '../store/quote'; +import type { FindToken } from '../store/slices/data'; +import type { QuoteWarning, SelectedQuote, Wallet } from '../types'; +import type { + PriceImpactWarningLevel, + SimulationAssetAndAmount, + SimulationValidationStatus, + Step, +} from '@rango-dev/ui'; +import type { + Asset, + BlockchainMeta, + MultiRouteResponse, + MultiRouteSimulationResult, + PreferenceType, + RouteTag, +} from 'rango-sdk'; +import type { PendingSwap } from 'rango-types'; + +import { getLastSuccessfulStep } from '@rango-dev/queue-manager-rango-preset'; +import BigNumber from 'bignumber.js'; + +import { HIGH_PRIORITY_TAGS } from '../constants/quote'; +import { HIGHT_PRICE_IMPACT, LOW_PRICE_IMPACT } from '../constants/routing'; +import { HIGH_SLIPPAGE } from '../constants/swapSettings'; +import { QuoteWarningType } from '../types'; + +import { areEqual } from './common'; +import { createTokenHash, findBlockchain } from './meta'; +import { numberToString } from './numbers'; +import { + checkSlippageWarnings, + getMinRequiredSlippage, + getPercentageChange, + getTotalFeeInUsd, + getUsdInputFrom, + getUsdOutputFrom, + hasHighValueLoss, + hasProperSlippage, + isOutputAmountChangedExcessively, +} from './swap'; + +export function isNumberOfSwapsChanged( + quoteA: SelectedQuote, + quoteB: SelectedQuote +) { + const quoteASwaps = quoteA?.swaps || []; + const quoteBSwaps = quoteB?.swaps || []; + return quoteASwaps.length !== quoteBSwaps.length; +} + +export function isQuoteSwappersUpdated( + quoteA: SelectedQuote, + quoteB: SelectedQuote +) { + const quoteASwappers = quoteA?.swaps.map((swap) => swap.swapperId) || []; + const quoteBSwappers = quoteB?.swaps.map((swap) => swap.swapperId) || []; + return !areEqual(quoteASwappers, quoteBSwappers); +} + +export function isQuoteInternalCoinsUpdated( + quoteA: SelectedQuote, + quoteB: SelectedQuote +) { + const quoteAInternalCoins = quoteA?.swaps.map((swap) => swap.to.symbol) || []; + const quoteBInternalCoins = quoteB?.swaps.map((swap) => swap.to.symbol) || []; + return !areEqual(quoteAInternalCoins, quoteBInternalCoins); +} + +export function isQuoteChanged( + quoteA: SelectedQuote, + quoteB: SelectedQuote +): boolean { + return ( + isNumberOfSwapsChanged(quoteA, quoteB) || + isQuoteSwappersUpdated(quoteA, quoteB) || + isQuoteInternalCoinsUpdated(quoteA, quoteB) + ); +} + +export function outToRatioHasWarning( + fromUsdValue: BigNumber | null, + outToInRatio: BigNumber | 0 +) { + return ( + (parseInt(outToInRatio?.toFixed(2) || '0') <= -10 && + (fromUsdValue === null || fromUsdValue.gte(new BigNumber(200)))) || + (parseInt(outToInRatio?.toFixed(2) || '0') <= -5 && + (fromUsdValue === null || fromUsdValue.gte(new BigNumber(1000)))) + ); +} + +export function getRequiredBalanceOfWallet( + selectedWallet: Wallet, + fee: SimulationValidationStatus[] | null +): SimulationAssetAndAmount[] | null { + if (fee === null) { + return null; + } + const relatedFeeStatus = fee + ?.find((item) => item.blockchain === selectedWallet.chain) + ?.wallets.find( + (wallet) => + wallet.address?.toLowerCase() === selectedWallet.address.toLowerCase() + ); + if (!relatedFeeStatus) { + return null; + } + return relatedFeeStatus.requiredAssets; +} + +export function getPriceImpactLevel( + priceImpact: number +): PriceImpactWarningLevel { + let warningLevel: PriceImpactWarningLevel = undefined; + if (priceImpact <= LOW_PRICE_IMPACT && priceImpact > HIGHT_PRICE_IMPACT) { + warningLevel = 'low'; + } else if (priceImpact <= HIGHT_PRICE_IMPACT) { + warningLevel = 'high'; + } + + return warningLevel; +} + +export function findCommonTokens( + listA: T, + listB: R +) { + const set = new Set(); + + listA.forEach((token) => set.add(createTokenHash(token))); + + return listB.filter((token) => set.has(createTokenHash(token))) as R; +} + +export function createRetryQuote( + pendingSwap: PendingSwap, + blockchains: BlockchainMeta[], + findToken: FindToken +): RetryQuote { + const firstStep = pendingSwap.steps[0]; + const lastStep = pendingSwap.steps[pendingSwap.steps.length - 1]; + const lastSuccessfulStep = getLastSuccessfulStep(pendingSwap.steps); + + const toToken = { + blockchain: lastStep.toBlockchain, + symbol: lastStep.toSymbol, + address: lastStep.toSymbolAddress, + }; + + const fromBlockchainMeta = findBlockchain( + lastSuccessfulStep + ? lastSuccessfulStep.toBlockchain + : firstStep.fromBlockchain, + blockchains + ); + const toBlockchainMeta = findBlockchain(lastStep.toBlockchain, blockchains); + const fromTokenMeta = findToken( + lastSuccessfulStep + ? { + blockchain: fromBlockchainMeta?.name ?? '', + symbol: lastSuccessfulStep.toSymbol, + address: lastSuccessfulStep.toSymbolAddress, + } + : { + blockchain: fromBlockchainMeta?.name ?? '', + symbol: firstStep.fromSymbol, + address: firstStep.fromSymbolAddress, + } + ); + const toTokenMeta = findToken(toToken); + const inputAmount = lastSuccessfulStep + ? lastSuccessfulStep.outputAmount ?? '' + : pendingSwap.inputAmount; + + return { + fromBlockchain: fromBlockchainMeta, + fromToken: fromTokenMeta, + toBlockchain: toBlockchainMeta, + toToken: toTokenMeta, + inputAmount, + }; +} + +export function generateQuoteWarnings(params: { + previousQuote?: SelectedQuote; + currentQuote: SelectedQuote; + findToken: FindToken; + userSlippage: number; +}): QuoteWarning | null { + const { previousQuote, currentQuote, findToken, userSlippage } = params; + const usdInput = getUsdInputFrom(currentQuote); + const usdOutput = getUsdOutputFrom(currentQuote); + + if (!!currentQuote && usdInput && usdOutput) { + const priceImpact = getPriceImpact( + usdInput.toString(), + usdOutput.toString() + ); + const highValueLoss = + !!priceImpact && hasHighValueLoss(usdInput, priceImpact); + + if (highValueLoss) { + const totalFee = getTotalFeeInUsd(currentQuote?.swaps, findToken); + const warningLevel = getPriceImpactLevel(priceImpact); + return { + type: QuoteWarningType.HIGH_VALUE_LOSS, + inputUsdValue: usdInput, + outputUsdValue: usdOutput, + priceImpact, + totalFee, + warningLevel, + }; + } + } + + if ( + previousQuote && + isOutputAmountChangedExcessively(previousQuote, currentQuote) + ) { + return { + type: QuoteWarningType.EXCESSIVE_OUTPUT_AMOUNT_CHANGE, + usdValueChange: numberToString( + getUsdOutputFrom(currentQuote) + ?.minus(getUsdOutputFrom(previousQuote) ?? 0) + .toString() ?? '0', + null, + 2 + ), + percentageChange: numberToString( + getPriceImpact( + getUsdOutputFrom(previousQuote) ?? '1', + getUsdOutputFrom(currentQuote) ?? '1' + ), + null, + 2 + ), + }; + } + + if (currentQuote && (!usdInput || !usdOutput)) { + return { type: QuoteWarningType.UNKNOWN_PRICE }; + } + + const minRequiredSlippage = getMinRequiredSlippage(currentQuote.swaps); + const highSlippage = userSlippage > HIGH_SLIPPAGE; + + if (!hasProperSlippage(params.userSlippage.toString(), minRequiredSlippage)) { + return { + type: QuoteWarningType.INSUFFICIENT_SLIPPAGE, + recommendedSlippages: checkSlippageWarnings(currentQuote, userSlippage), + minRequiredSlippage: minRequiredSlippage, + }; + } else if ( + highSlippage && + parseFloat(minRequiredSlippage ?? '0') < userSlippage + ) { + return { + type: QuoteWarningType.HIGH_SLIPPAGE, + slippage: userSlippage.toString(), + }; + } + + return null; +} + +export function isQuoteWarningConfirmationRequired(warning: QuoteWarning) { + const WARNINGS_NOT_REQUIRING_CONFIRMATION = [ + QuoteWarningType.EXCESSIVE_OUTPUT_AMOUNT_CHANGE, + ]; + return !WARNINGS_NOT_REQUIRING_CONFIRMATION.includes(warning.type); +} + +export function getPriceImpact( + inputUsdValue: BigNumber | string | null, + outputUsdValue: BigNumber | string | null +): number | null { + const outputUsdValueIsInvalid = + typeof outputUsdValue === 'string' + ? parseFloat(outputUsdValue) <= 0 + : !outputUsdValue?.gt(0); + const percentageChange = + !inputUsdValue || !outputUsdValue || outputUsdValueIsInvalid + ? null + : getPercentageChange( + inputUsdValue.toString(), + outputUsdValue.toString() + ); + + return percentageChange && percentageChange < 0 ? percentageChange : null; +} + +export const getUniqueBlockchains = (steps: Step[]) => { + const set = new Set(); + const result: { displayName: string; image: string }[] = []; + steps.forEach((step) => { + if (!set.has(step.from.chain.displayName)) { + set.add(step.from.chain.displayName); + result.push(step.from.chain); + } + if (!set.has(step.to.chain.displayName)) { + set.add(step.to.chain.displayName); + result.push(step.to.chain); + } + }); + + return result; +}; + +export const sortQuotesBy = ( + strategy: PreferenceType, + quotes: MultiRouteResponse['results'] +): MultiRouteResponse['results'] => { + return quotes.sort((quote1, quote2) => { + const getScore = (route: MultiRouteSimulationResult) => + route.scores?.find((score) => score.preferenceType === strategy)?.score ?? + 0; + + const quote1Score = getScore(quote1); + const quote2Score = getScore(quote2); + + if (quote1Score !== quote2Score) { + return quote2Score - quote1Score; + } + + const lowerQuoteId1 = quote1.requestId.toLowerCase(); + const lowerQuoteId2 = quote2.requestId.toLowerCase(); + + return lowerQuoteId1.localeCompare(lowerQuoteId2); + }); +}; + +export const getDefaultQuote = ( + currentQuote: SelectedQuote | null, + quotes: MultiRouteSimulationResult[], + requestAmount: string +): SelectedQuote | null => { + if (!quotes.length) { + return null; + } + if (!currentQuote) { + // Handle the case where currentQuote is null + return { + requestAmount: requestAmount, + validationStatus: null, + ...quotes[0], // Return the first quote from the quotes array + }; + } + // Create a set of swapperIds from the currentQuote swaps + const currentQuoteSwapperIds = new Set( + currentQuote.swaps.map((swap) => swap.swapperId) + ); + + // Find a quote that matches the currentQuote's swapperIds + const matchedQuote = quotes.find((quote) => { + // Create a set of swapperIds from the quote swaps + const quoteSwapperIds = new Set(quote.swaps.map((swap) => swap.swapperId)); + + // Check if all swapperIds from the currentQuote are present in the quoteSwapperIds + return Array.from(currentQuoteSwapperIds).every((swapperId) => + quoteSwapperIds.has(swapperId) + ); + }); + + // Return the matchedQuote if found, otherwise return the first quote from the quotes array + return { + requestAmount: requestAmount, + validationStatus: null, + ...(matchedQuote || quotes[0]), + }; +}; + +export const sortTags = (tags: RouteTag[]): RouteTag[] => { + const customSort = (a: RouteTag, b: RouteTag) => { + const indexA = HIGH_PRIORITY_TAGS.indexOf(a.value); + const indexB = HIGH_PRIORITY_TAGS.indexOf(b.value); + + if (indexA !== -1 && indexB !== -1) { + return indexA - indexB; + } + + if (indexA !== -1) { + return -1; + } else if (indexB !== -1) { + return 1; + } + + return 0; + }; + + return tags.sort(customSort); +}; diff --git a/widget/embedded/src/utils/routing.ts b/widget/embedded/src/utils/routing.ts deleted file mode 100644 index 83192b4424..0000000000 --- a/widget/embedded/src/utils/routing.ts +++ /dev/null @@ -1,186 +0,0 @@ -import { - SimulationAssetAndAmount, - SimulationValidationStatus, -} from '@rango-dev/ui/dist/types/swaps'; -import BigNumber from 'bignumber.js'; -import { BestRouteResponse, BlockchainMeta, Token } from 'rango-sdk'; -import { areEqual } from './common'; -import { SelectedWallet } from './wallets'; -import { BestRouteEqualityParams } from '../types'; -import { numberToString } from './numbers'; -import { PendingSwap } from '@rango-dev/queue-manager-rango-preset'; - -export function searchParamsToToken( - tokens: Token[], - searchParams: string | null, - chain: BlockchainMeta | null -): Token | null { - if (!chain) return null; - return ( - tokens.find((token) => { - const symbolAndAddress = searchParams?.split('--'); - if (symbolAndAddress?.length === 1) - return ( - token.symbol === symbolAndAddress[0] && - token.address === null && - token.blockchain === chain.name - ); - return ( - token.symbol === symbolAndAddress?.[0] && - token.address === symbolAndAddress?.[1] && - token.blockchain === chain.name - ); - }) || null - ); -} - -export function getBestRouteToTokenUsdPrice( - bestRoute: BestRouteResponse | null -): number | null | undefined { - return bestRoute?.result?.swaps[bestRoute?.result?.swaps.length - 1].to - .usdPrice; -} - -export function isNumberOfSwapsChanged( - route1: BestRouteResponse, - route2: BestRouteResponse -) { - const route1Swaps = route1.result?.swaps || []; - const route2Swaps = route2.result?.swaps || []; - return route1Swaps.length !== route2Swaps.length; -} - -export function isRouteSwappersUpdated( - route1: BestRouteResponse, - route2: BestRouteResponse -) { - const route1Swappers = - route1.result?.swaps.map((swap) => swap.swapperId) || []; - const route2Swappers = - route2.result?.swaps.map((swap) => swap.swapperId) || []; - return !areEqual(route1Swappers, route2Swappers); -} - -export function isRouteInternalCoinsUpdated( - route1: BestRouteResponse, - route2: BestRouteResponse -) { - const route1InternalCoins = - route1.result?.swaps.map((swap) => swap.to.symbol) || []; - const route2InternalCoins = - route2.result?.swaps.map((swap) => swap.to.symbol) || []; - return !areEqual(route1InternalCoins, route2InternalCoins); -} - -export function isRouteChanged( - route1: BestRouteResponse, - route2: BestRouteResponse -): boolean { - return ( - isNumberOfSwapsChanged(route1, route2) || - isRouteSwappersUpdated(route1, route2) || - isRouteInternalCoinsUpdated(route1, route2) - ); -} - -export function outToRatioHasWarning( - fromUsdValue: BigNumber | null, - outToInRatio: BigNumber | 0 -) { - return ( - (parseInt(outToInRatio?.toFixed(2) || '0') <= -10 && - (fromUsdValue === null || fromUsdValue.gte(new BigNumber(200)))) || - (parseInt(outToInRatio?.toFixed(2) || '0') <= -5 && - (fromUsdValue === null || fromUsdValue.gte(new BigNumber(1000)))) - ); -} - -export function getRequiredBalanceOfWallet( - selectedWallet: SelectedWallet, - fee: SimulationValidationStatus[] | null -): SimulationAssetAndAmount[] | null { - if (fee === null) return null; - const relatedFeeStatus = fee - ?.find((item) => item.blockchain === selectedWallet.chain) - ?.wallets.find( - (wallet) => - wallet.address?.toLowerCase() === selectedWallet.address.toLowerCase() - ); - if (!relatedFeeStatus) return null; - return relatedFeeStatus.requiredAssets; -} - -export function isRouteParametersChanged(params: BestRouteEqualityParams) { - if (params.store === 'bestRoute') { - const { prevState, currentState } = params; - return ( - !!currentState.fromToken && - !!currentState.toToken && - (prevState.fromChain?.name !== currentState.fromChain?.name || - prevState.toChain?.name !== currentState.toChain?.name || - prevState.fromToken?.symbol !== currentState.fromToken?.symbol || - prevState.toToken?.symbol !== currentState.toToken?.symbol || - prevState.fromToken?.blockchain !== prevState.fromToken?.blockchain || - prevState.toToken?.blockchain !== currentState.toToken?.blockchain || - prevState.fromToken?.address !== currentState.fromToken?.address || - prevState.toToken?.address !== currentState.toToken?.address || - prevState.inputAmount !== currentState.inputAmount) - ); - } else if (params.store === 'settings') { - const { prevState, currentState } = params; - return ( - prevState.slippage !== currentState.slippage || - prevState.customSlippage !== currentState.customSlippage || - prevState.disabledLiquiditySources?.length !== - currentState.disabledLiquiditySources?.length || - prevState.infiniteApprove || - currentState.infiniteApprove - ); - } - return false; -} - -export function getFormatedBestRoute( - bestRoute: BestRouteResponse | null -): BestRouteResponse | null { - if (!bestRoute) return null; - - const formatedSwaps = (bestRoute.result?.swaps || []).map((swap) => ({ - ...swap, - fromAmount: numberToString(swap.fromAmount, 6, 6), - toAmount: numberToString(swap.toAmount, 6, 6), - })); - - return { - ...bestRoute, - ...(bestRoute.result && { - result: { ...bestRoute.result, swaps: formatedSwaps }, - }), - }; -} - -export function getFormatedPendingSwap(pendingSwap: PendingSwap): PendingSwap { - const formatedSteps = pendingSwap.steps.map((step) => ({ - ...step, - feeInUsd: numberToString(step.feeInUsd, 4, 4), - outputAmount: numberToString(step.outputAmount, 6, 6), - expectedOutputAmountHumanReadable: numberToString( - step.expectedOutputAmountHumanReadable, - 6, - 6 - ), - })); - - return { - ...pendingSwap, - inputAmount: numberToString(pendingSwap.inputAmount, 6, 6), - steps: formatedSteps, - }; -} - -//todo: refactor bestRoute store and add loadingStatus -export const getBestRouteStatus = (loading: boolean, error: boolean) => { - if (loading) return 'loading'; - if (error) return 'failed'; - else return 'success'; -}; diff --git a/widget/embedded/src/utils/settings.ts b/widget/embedded/src/utils/settings.ts new file mode 100644 index 0000000000..c8e180ddba --- /dev/null +++ b/widget/embedded/src/utils/settings.ts @@ -0,0 +1,93 @@ +import type { Features, Routing } from '../types'; +import type { SwapperMeta, SwapperType, Token } from 'rango-sdk'; + +import { removeDuplicateFrom } from './common'; + +export type UniqueSwappersGroupType = { + id: string; + groupTitle: string; + logo: string; + type: SwapperType; + selected: boolean; +}; + +export function getUniqueSwappersGroups( + swappers: SwapperMeta[], + disabledLiquiditySources: string[] +): UniqueSwappersGroupType[] { + const supportedSwappers = swappers.map((swapper) => swapper.swapperGroup); + + const uniqueSupportedSwappersGroups: Array = []; + + const uniqueGroup = removeDuplicateFrom(swappers.map((s) => s.swapperGroup)); + + uniqueGroup.map((uniqueGroupItem) => { + const swapperItem = swappers.find( + (swapper) => swapper.swapperGroup === uniqueGroupItem + ); + + if (swapperItem) { + let isSupportedSwapper = true; + if (supportedSwappers) { + isSupportedSwapper = supportedSwappers.some( + (supportedItem) => supportedItem === swapperItem.swapperGroup + ); + } + + if (isSupportedSwapper) { + swapperItem.types.map((swapperTypeItem) => { + uniqueSupportedSwappersGroups.push({ + id: swapperItem.swapperGroup, + groupTitle: swapperItem.swapperGroup, + logo: swapperItem.logo, + type: swapperTypeItem, + selected: !disabledLiquiditySources.includes( + swapperItem.swapperGroup + ), + }); + }); + } + } + }); + + return uniqueSupportedSwappersGroups; +} + +export function sortLiquiditySourcesByGroupTitle( + a: SwapperMeta, + b: SwapperMeta +) { + if (a.swapperGroup < b.swapperGroup) { + return -1; + } + + if (a.swapperGroup > b.swapperGroup) { + return 1; + } + + return 0; +} + +export function isFeatureHidden(feature: keyof Features, features?: Features) { + return features?.[feature] === 'hidden'; +} + +export function isFeatureEnabled(feature: keyof Features, features?: Features) { + return features?.[feature] === 'enabled'; +} + +export function isRoutingEnabled(item: keyof Routing, routing?: Routing) { + return routing?.[item] === 'enabled'; +} + +export const addCustomTokensToSupportedTokens = ( + supportedTokens: Token[], + customTokens: Token[], + features?: Features +) => { + const isCustomTokensHidden = isFeatureHidden('customTokens', features); + + return isCustomTokensHidden + ? supportedTokens + : supportedTokens.concat(customTokens); +}; diff --git a/widget/embedded/src/utils/swap.ts b/widget/embedded/src/utils/swap.ts index c065776092..5eae398820 100644 --- a/widget/embedded/src/utils/swap.ts +++ b/widget/embedded/src/utils/swap.ts @@ -1,49 +1,96 @@ -import BigNumber from 'bignumber.js'; -import { +import type { FetchStatus, FindToken } from '../store/slices/data'; +import type { ConnectedWallet } from '../store/slices/wallets'; +import type { + ConvertedToken, + QuoteError, + QuoteWarning, + RecommendedSlippages, + SelectedQuote, + SwapButtonState, + Wallet, +} from '../types'; +import type { WalletType } from '@rango-dev/wallets-shared'; +import type { BestRouteRequest, - BestRouteResponse, + BlockchainMeta, RecommendedSlippage, + SwapFee, SwapResult, Token, } from 'rango-sdk'; -import { Account } from '../store/wallets'; -import { ZERO } from '../constants/numbers'; -import { numberToString } from './numbers'; -import { WalletType } from '@rango-dev/wallets-shared'; -import { getRequiredBalanceOfWallet } from './routing'; -import { getRequiredChains, SelectedWallet } from './wallets'; -import { LoadingStatus } from '../store/meta'; -import { ConvertedToken, SwapButtonState } from '../types'; +import type { PendingSwap, PendingSwapStep } from 'rango-types'; + +import { i18n } from '@lingui/core'; import { - PendingSwapNetworkStatus, - PendingSwapStep, + type RouteEvent, + RouteEventType, + type StepEvent, } from '@rango-dev/queue-manager-rango-preset'; -import { PendingSwap } from '@rango-dev/queue-manager-rango-preset'; -import { removeDuplicateFrom } from './common'; +import BigNumber from 'bignumber.js'; +import { PendingSwapNetworkStatus } from 'rango-types'; + +import { errorMessages } from '../constants/errors'; +import { swapButtonTitles } from '../constants/messages'; +import { ZERO } from '../constants/numbers'; +import { + type FeesGroup, + HIGH_FEE_THRESHOLD_USD, + HIGH_VALUE_LOSS_CRITERIA, + type NameOfFees, + OUTPUT_CHANGE_WARNING_CRITERIA, + PERCENT_MULTIPLIER, +} from '../constants/quote'; +import { + BALANCE_MAX_DECIMALS, + BALANCE_MIN_DECIMALS, + TOKEN_AMOUNT_MAX_DECIMALS, + TOKEN_AMOUNT_MIN_DECIMALS, +} from '../constants/routing'; + +import { getBlockchainShortNameFor, isValidTokenAddress } from './meta'; +import { numberToString } from './numbers'; +import { getRequiredBalanceOfWallet } from './quote'; +import { getQuoteWallets } from './wallets'; export function getOutputRatio( - inputUsdValue: BigNumber, - outputUsdValue: BigNumber + inputUsdValue: BigNumber | null, + outputUsdValue: BigNumber | null ) { - if (inputUsdValue.lte(ZERO) || outputUsdValue.lte(ZERO)) return 0; - return outputUsdValue.div(inputUsdValue).minus(1).multipliedBy(100); + if ( + !inputUsdValue || + !outputUsdValue || + inputUsdValue.lte(ZERO) || + outputUsdValue.lte(ZERO) + ) { + return 0; + } + return outputUsdValue + .div(inputUsdValue) + .minus(1) + .multipliedBy(PERCENT_MULTIPLIER) + .toNumber(); } -export function outputRatioHasWarning( - inputUsdValue: BigNumber, - outputRatio: BigNumber | 0 -) { - return ( - (parseInt(outputRatio.toFixed(2) || '0') <= -10 && - inputUsdValue.gte(new BigNumber(400))) || - (parseInt(outputRatio.toFixed(2) || '0') <= -5 && - inputUsdValue.gte(new BigNumber(1000))) +export function hasHighValueLoss( + inputUsdValue: BigNumber | null, + priceImpact: number +): boolean { + if (!inputUsdValue) { + return false; + } + + const formattedPriceImpact = parseInt(priceImpact.toFixed(2) || '0'); + + return HIGH_VALUE_LOSS_CRITERIA.some( + ({ threshold, minInput }) => + formattedPriceImpact <= threshold && + inputUsdValue.gte(new BigNumber(minInput)) ); } -export function hasLimitError(bestRoute: BestRouteResponse | null): boolean { +export function hasLimitError(swaps: SwapResult[]): boolean { return ( - (bestRoute?.result?.swaps || []).filter((swap) => { + (swaps || []).filter((swap) => { const minimum = !!swap.fromAmountMinValue ? new BigNumber(swap.fromAmountMinValue) : null; @@ -53,21 +100,18 @@ export function hasLimitError(bestRoute: BestRouteResponse | null): boolean { const isExclusive = swap.fromAmountRestrictionType === 'EXCLUSIVE'; if (isExclusive) { return minimum?.gte(swap.fromAmount) || maximum?.lte(swap.fromAmount); - } else { - return minimum?.gt(swap.fromAmount) || maximum?.lt(swap.fromAmount); } + return minimum?.gt(swap.fromAmount) || maximum?.lt(swap.fromAmount); }).length > 0 ); } -export function LimitErrorMessage(bestRoute: BestRouteResponse | null): { - swap: SwapResult | null; +export function getLimitErrorMessage(swaps: SwapResult[]): { + swap: SwapResult; fromAmountRangeError: string; recommendation: string; } { - if (!bestRoute) - return { swap: null, fromAmountRangeError: '', recommendation: '' }; - const swap = (bestRoute?.result?.swaps || []).filter((swap) => { + const swap = (swaps || []).filter((swap) => { const minimum = !!swap.fromAmountMinValue ? new BigNumber(swap.fromAmountMinValue) : null; @@ -77,12 +121,10 @@ export function LimitErrorMessage(bestRoute: BestRouteResponse | null): { const isExclusive = swap.fromAmountRestrictionType === 'EXCLUSIVE'; if (isExclusive) { return minimum?.gte(swap.fromAmount) || maximum?.lte(swap.fromAmount); - } else { - return minimum?.gt(swap.fromAmount) || maximum?.lt(swap.fromAmount); } + return minimum?.gt(swap.fromAmount) || maximum?.lt(swap.fromAmount); })[0]; - if (!swap) - return { swap: null, fromAmountRangeError: '', recommendation: '' }; + const minimum = !!swap.fromAmountMinValue ? new BigNumber(swap.fromAmountMinValue) : null; @@ -94,131 +136,152 @@ export function LimitErrorMessage(bestRoute: BestRouteResponse | null): { let fromAmountRangeError = ''; let recommendation = ''; if (!isExclusive && !!minimum && minimum.gt(swap.fromAmount)) { - fromAmountRangeError = `Required: >= ${numberToString(minimum)} ${ - swap.from.symbol - }`; - recommendation = 'Increase your swap amount'; + fromAmountRangeError = i18n.t({ + id: 'Required: >= {min} {symbol}', + values: { + min: numberToString( + minimum, + TOKEN_AMOUNT_MIN_DECIMALS, + TOKEN_AMOUNT_MAX_DECIMALS + ), + symbol: swap.from.symbol, + }, + }); + recommendation = errorMessages().bridgeLimitErrors.increaseAmount; } else if (isExclusive && !!minimum && minimum.gte(swap.fromAmount)) { - fromAmountRangeError = `Required: > ${numberToString(minimum)} ${ - swap.from.symbol - }`; - recommendation = 'Increase your swap amount'; + fromAmountRangeError = i18n.t({ + id: 'Required: > {min} {symbol}', + values: { + min: numberToString( + minimum, + TOKEN_AMOUNT_MIN_DECIMALS, + TOKEN_AMOUNT_MAX_DECIMALS + ), + symbol: swap.from.symbol, + }, + }); + recommendation = errorMessages().bridgeLimitErrors.increaseAmount; } if (!isExclusive && !!maximum && maximum.lt(swap.fromAmount)) { - fromAmountRangeError = `Required: <= ${numberToString(maximum)} ${ - swap.from.symbol - }`; - recommendation = 'Decrease your swap amount'; + fromAmountRangeError = i18n.t({ + id: 'Required: <= {max} {symbol}', + values: { + max: numberToString( + maximum, + TOKEN_AMOUNT_MIN_DECIMALS, + TOKEN_AMOUNT_MAX_DECIMALS + ), + symbol: swap.from.symbol, + }, + }); + recommendation = errorMessages().bridgeLimitErrors.decreaseAmount; } else if (isExclusive && !!maximum && maximum.lte(swap.fromAmount)) { - fromAmountRangeError = `Required: < ${numberToString(maximum)} ${ - swap.from.symbol - }`; - recommendation = 'Decrease your swap amount'; + fromAmountRangeError = i18n.t({ + id: 'Required: < {max} {symbol}', + values: { + max: numberToString( + maximum, + TOKEN_AMOUNT_MIN_DECIMALS, + TOKEN_AMOUNT_MAX_DECIMALS + ), + symbol: swap.from.symbol, + }, + }); + recommendation = errorMessages().bridgeLimitErrors.decreaseAmount; } return { swap, fromAmountRangeError, recommendation }; } -export function getSwapButtonState( - loadingMetaStatus: LoadingStatus, - accounts: Account[], - loading: boolean, - bestRoute: BestRouteResponse | null, - hasLimitError: boolean, - highValueLoss: boolean, - priceImpactCanNotBeComputed: boolean, - needsToWarnEthOnPath: boolean, - inputAmount: string -): SwapButtonState { - if (loadingMetaStatus !== 'success') - return { title: 'Connect Wallet', disabled: true }; - if (accounts.length == 0) return { title: 'Connect Wallet', disabled: false }; - if (loading) return { title: 'Finding Best Route...', disabled: true }; - else if (!inputAmount || inputAmount === '0') - return { title: 'Enter an amount', disabled: true }; - else if (!bestRoute || !bestRoute.result) - return { title: 'Swap', disabled: true }; - else if (hasLimitError) return { title: 'Limit Error', disabled: true }; - else if (highValueLoss) - return { title: 'Price impact is too high!', disabled: true }; - else if (priceImpactCanNotBeComputed) +export function getSwapButtonState(params: { + fetchMetaStatus: FetchStatus; + anyWalletConnected: boolean; + fetchingQuote: boolean; + inputAmount: string; + quote: SelectedQuote | null; + warning: QuoteWarning | null; + error: QuoteError | null; + needsToWarnEthOnPath: boolean; +}): SwapButtonState { + const { + fetchMetaStatus, + anyWalletConnected, + fetchingQuote, + inputAmount, + quote, + warning, + error, + needsToWarnEthOnPath, + } = params; + if (fetchMetaStatus !== 'success') { return { - title: 'USD price is unknown, price impact might be high!', + title: swapButtonTitles().connectWallet, + action: 'connect-wallet', + disabled: true, + }; + } + if (!anyWalletConnected) { + return { + title: swapButtonTitles().connectWallet, + action: 'connect-wallet', + disabled: false, + }; + } + if (fetchingQuote || !quote || error || !inputAmount || inputAmount === '0') { + return { + title: swapButtonTitles().swap, + action: 'confirm-swap', + disabled: true, + }; + } else if (warning) { + return { + title: swapButtonTitles().swapAnyway, + action: 'confirm-warning', disabled: false, - hasWarning: true, }; - else if (needsToWarnEthOnPath) + } else if (needsToWarnEthOnPath) { return { - title: 'The route goes through Ethereum. Continue?', + title: swapButtonTitles().ethWarning, + action: 'confirm-warning', disabled: false, - hasWarning: true, }; - else return { title: 'Swap', disabled: false }; + } + return { + title: swapButtonTitles().swap, + action: 'confirm-swap', + disabled: false, + }; } export function canComputePriceImpact( - bestRoute: BestRouteResponse | null, + quote: SelectedQuote | null, inputAmount: string, - inputUsdValue: BigNumber, - outputUsdValue: BigNumber + usdValue: BigNumber | null ) { + const inputAmountNumber = parseFloat(inputAmount || '0'); + return !( - (inputUsdValue.lte(ZERO) || outputUsdValue.lte(ZERO)) && - !!bestRoute?.result && - !!inputAmount && + quote && + (!usdValue || usdValue.lte(ZERO)) && + inputAmount && inputAmount !== '0' && - parseFloat(inputAmount || '0') !== 0 && - !!bestRoute.result + inputAmountNumber !== 0 ); } -export function requiredWallets(route: BestRouteResponse | null) { - const wallets: string[] = []; - - route?.result?.swaps.forEach((swap) => { - const currentStepFromBlockchain = swap.from.blockchain; - const currentStepToBlockchain = swap.to.blockchain; - let lastAddedWallet = wallets[wallets.length - 1]; - if (currentStepFromBlockchain != lastAddedWallet) - wallets.push(currentStepFromBlockchain); - lastAddedWallet = wallets[wallets.length - 1]; - if (currentStepToBlockchain != lastAddedWallet) - wallets.push(currentStepToBlockchain); - }); - return wallets; -} - -export const getUsdPrice = ( - blockchain: string, - symbol: string, - address: string | null, - allTokens: Token[] -): number | null => { - const token = allTokens?.find( - (t) => - t.blockchain === blockchain && - t.symbol?.toUpperCase() === symbol?.toUpperCase() && - t.address === address - ); - return token?.usdPrice || null; -}; - export function getUsdFeeOfStep( step: SwapResult, - allTokens: Token[] + findToken: FindToken ): BigNumber { let totalFeeInUsd = ZERO; for (let i = 0; i < step.fee.length; i++) { const fee = step.fee[i]; - if (fee.expenseType === 'DECREASE_FROM_OUTPUT') continue; + if (fee.expenseType === 'DECREASE_FROM_OUTPUT') { + continue; + } - const unitPrice = getUsdPrice( - fee.asset.blockchain, - fee.asset.symbol, - fee.asset.address, - allTokens - ); + const unitPrice = findToken(fee.asset)?.usdPrice || null; totalFeeInUsd = totalFeeInUsd.plus( new BigNumber(fee.amount).multipliedBy(unitPrice || 0) ); @@ -228,21 +291,54 @@ export function getUsdFeeOfStep( } export function getTotalFeeInUsd( - bestRoute: BestRouteResponse | null, - allTokens: Token[] -): BigNumber | null { - return ( - bestRoute?.result?.swaps.reduce( - (totalFee: BigNumber, step) => - totalFee.plus(getUsdFeeOfStep(step, allTokens)), - ZERO - ) || null + swaps: SwapResult[], + findToken: FindToken +): BigNumber { + return swaps.reduce( + (totalFee: BigNumber, step) => + totalFee.plus(getUsdFeeOfStep(step, findToken)), + ZERO + ); +} + +export function getUsdFee(fee: SwapFee): BigNumber { + let totalFeeInUsd = ZERO; + totalFeeInUsd = totalFeeInUsd.plus( + new BigNumber(fee.amount).multipliedBy(fee.price || 0) + ); + + return totalFeeInUsd; +} + +export function getTotalFeesInUsd(fees: SwapFee[]): BigNumber { + return fees.reduce( + (totalFee: BigNumber, fee) => totalFee.plus(getUsdFee(fee)), + ZERO + ); +} +export function getFeesGroup(swaps: SwapResult[]): FeesGroup { + return swaps.reduce( + (result, swap) => { + for (const fee of swap.fee) { + const name = fee.name as NameOfFees; + const feeGroup = + fee.expenseType !== 'DECREASE_FROM_OUTPUT' + ? result.payable + : result.nonePayable; + + feeGroup[name] = [...(feeGroup[name] || []), fee]; + } + return result; + }, + { payable: {}, nonePayable: {} } as FeesGroup ); } export function hasHighFee(totalFeeInUsd: BigNumber | null) { - if (!totalFeeInUsd) return false; - return !totalFeeInUsd.lt(new BigNumber(30)); + if (!totalFeeInUsd) { + return false; + } + return !totalFeeInUsd.lt(new BigNumber(HIGH_FEE_THRESHOLD_USD)); } export function hasSlippageError( @@ -251,12 +347,42 @@ export function hasSlippageError( return (slippages?.filter((s) => !!s?.error)?.length || 0) > 0; } -export function getMinRequiredSlippage( - route: BestRouteResponse -): string | null { - const slippages = route.result?.swaps.map( - (slippage) => slippage.recommendedSlippage - ); +export function checkSlippageErrors( + swaps: SwapResult[] +): RecommendedSlippages | null { + const recommendedSlippages: RecommendedSlippages = new Map(); + swaps.forEach((swap, index) => { + if (swap.recommendedSlippage?.error) { + recommendedSlippages.set(index, swap.recommendedSlippage.slippage); + } + }); + if (recommendedSlippages.size > 0) { + return recommendedSlippages; + } + return null; +} + +export function checkSlippageWarnings( + quote: SelectedQuote, + userSlippage: number +): RecommendedSlippages | null { + const recommendedSlippages: RecommendedSlippages = new Map(); + quote?.swaps.forEach((swap, index) => { + if ( + swap.recommendedSlippage?.slippage && + parseFloat(swap.recommendedSlippage.slippage) > userSlippage + ) { + recommendedSlippages.set(index, swap.recommendedSlippage.slippage); + } + }); + if (recommendedSlippages.size > 0) { + return recommendedSlippages; + } + return null; +} + +export function getMinRequiredSlippage(swaps: SwapResult[]): string | null { + const slippages = swaps.map((slippage) => slippage.recommendedSlippage); return ( slippages ?.map((s) => s?.slippage || '0') @@ -270,55 +396,82 @@ export function hasProperSlippage( userSlippage: string, minRequiredSlippage: string | null ) { - if (!minRequiredSlippage) return true; + if (!minRequiredSlippage) { + return true; + } return parseFloat(userSlippage) >= parseFloat(minRequiredSlippage); } export function hasEnoughBalance( - route: BestRouteResponse, - selectedWallets: SelectedWallet[] + quote: SelectedQuote, + selectedWallets: Wallet[] ) { - const fee = route.validationStatus; + const fee = quote.validationStatus; - if (fee === null || fee.length === 0) return true; + if (fee === null || fee.length === 0) { + return true; + } for (const wallet of selectedWallets) { const requiredAssets = getRequiredBalanceOfWallet(wallet, fee); - if (!requiredAssets) continue; + if (!requiredAssets) { + continue; + } const enoughBalanceInWallet = requiredAssets .map((asset) => asset.ok) .reduce((previous, current) => previous && current); - if (!enoughBalanceInWallet) return false; + if (!enoughBalanceInWallet) { + return false; + } } return true; } export function hasEnoughBalanceAndProperSlippage( - route: BestRouteResponse, - selectedWallets: SelectedWallet[], + quote: SelectedQuote, + selectedWallets: Wallet[], userSlippage: string, minRequiredSlippage: string | null ): boolean { return ( - hasEnoughBalance(route, selectedWallets) && + hasEnoughBalance(quote, selectedWallets) && hasProperSlippage(userSlippage, minRequiredSlippage) ); } -export function createBestRouteRequestBody( - fromToken: Token, - toToken: Token, - inputAmount: string, - wallets: Account[], - selectedWallets: SelectedWallet[], - disabledLiquiditySources: string[], - slippage: number, - affiliateRef: string | null, - initialRoute?: BestRouteResponse -): BestRouteRequest { - const selectedWalletsMap = selectedWallets.reduce( +export function createQuoteRequestBody(params: { + fromToken: Token; + toToken: Token; + inputAmount: string; + wallets?: ConnectedWallet[]; + selectedWallets?: Wallet[]; + liquiditySources?: string[]; + excludeLiquiditySources?: boolean; + disabledLiquiditySources: string[]; + slippage: number; + affiliateRef: string | null; + affiliatePercent: number | null; + affiliateWallets: { [key: string]: string } | null; + destination?: string; +}): BestRouteRequest { + const { + fromToken, + toToken, + inputAmount, + wallets, + selectedWallets, + disabledLiquiditySources, + liquiditySources, + excludeLiquiditySources, + slippage, + affiliateRef, + affiliatePercent, + affiliateWallets, + destination, + } = params; + const selectedWalletsMap = selectedWallets?.reduce( ( selectedWalletsMap: BestRouteRequest['selectedWallets'], selectedWallet @@ -331,33 +484,18 @@ export function createBestRouteRequestBody( const connectedWallets: BestRouteRequest['connectedWallets'] = []; - wallets.forEach((wallet) => { - const chainAndAccounts = connectedWallets.find( - (connectedWallet) => connectedWallet.blockchain === wallet.chain - ); - if (!!chainAndAccounts) chainAndAccounts.addresses.push(wallet.address); - else - connectedWallets.push({ - blockchain: wallet.chain, - addresses: [wallet.address], - }); + wallets?.forEach((wallet) => { + connectedWallets.push({ + blockchain: wallet.chain, + addresses: [wallet.address], + }); }); - const checkPrerequisites = !!initialRoute; - - const filteredBlockchains = removeDuplicateFrom( - (initialRoute?.result?.swaps || []).reduce( - (blockchains: string[], swap) => ( - blockchains.push(swap.from.blockchain, swap.to.blockchain), blockchains - ), - [] - ) - ); - const requestBody: BestRouteRequest = { amount: inputAmount.toString(), - affiliateRef, - checkPrerequisites, + affiliateRef: affiliateRef ?? undefined, + affiliatePercent: affiliatePercent ?? undefined, + affiliateWallets: affiliateWallets ?? undefined, from: { address: fromToken.address, blockchain: fromToken.blockchain, @@ -369,17 +507,24 @@ export function createBestRouteRequestBody( symbol: toToken.symbol, }, connectedWallets, - selectedWallets: selectedWalletsMap, - swapperGroups: disabledLiquiditySources, - swappersGroupsExclude: true, + selectedWallets: selectedWalletsMap ?? {}, slippage: slippage.toString(), - ...(checkPrerequisites && { blockchains: filteredBlockchains }), + ...(destination && { destination: destination }), + ...(excludeLiquiditySources && { + swapperGroups: disabledLiquiditySources.concat(liquiditySources ?? []), + swappersGroupsExclude: true, + }), + ...(!excludeLiquiditySources && { + swapperGroups: liquiditySources?.filter( + (liquiditySource) => !disabledLiquiditySources.includes(liquiditySource) + ), + swappersGroupsExclude: false, + }), }; - return requestBody; } -export function getWalletsForNewSwap(selectedWallets: SelectedWallet[]) { +export function getWalletsForNewSwap(selectedWallets: Wallet[]) { const wallets = selectedWallets.reduce( ( selectedWalletsMap: { @@ -399,48 +544,67 @@ export function getWalletsForNewSwap(selectedWallets: SelectedWallet[]) { return wallets; } -export function getRouteOutputAmount(route: BestRouteResponse | null) { - return route?.result?.outputAmount || null; +export function getUsdInputFrom(quote: SelectedQuote): BigNumber | undefined { + const inputAmount = quote.requestAmount; + const inputTokenUsdPrice = quote.swaps[0].from.usdPrice; + if (!inputAmount || !inputTokenUsdPrice) { + return; + } + return new BigNumber(inputAmount).multipliedBy(inputTokenUsdPrice); } -export function getPercentageChange( - oldValue: string | number | null, - newValue: string | number | null -) { - if (!oldValue || !newValue) return null; - return new BigNumber(newValue) - .div(new BigNumber(oldValue)) +export function getUsdOutputFrom(quote: SelectedQuote): BigNumber | undefined { + const outputAmount = quote?.outputAmount || null; + const outputTokenUsdPrice = quote.swaps[quote.swaps.length - 1].to.usdPrice; + if (!outputAmount || !outputTokenUsdPrice) { + return; + } + return new BigNumber(outputAmount).multipliedBy(outputTokenUsdPrice); +} + +export function getPercentageChange(input: string, output: string) { + return new BigNumber(output) + .div(new BigNumber(input)) .minus(1) - .multipliedBy(100); + .multipliedBy(PERCENT_MULTIPLIER) + .toNumber(); } -export function isOutputAmountChangedALot( - oldRoute: BestRouteResponse, - newRoute: BestRouteResponse +export function isOutputAmountChangedExcessively( + previousQuote: SelectedQuote, + currentQuote: SelectedQuote ) { - const oldOutputAmount = getRouteOutputAmount(oldRoute); - const newOutputAmount = getRouteOutputAmount(newRoute); - if (!oldOutputAmount || !newOutputAmount) return false; + const usdInput = getUsdInputFrom(previousQuote); + const previousUsdOutput = getUsdOutputFrom(previousQuote); + const currentUsdOutput = getUsdOutputFrom(currentQuote); + if (!usdInput || !previousUsdOutput || !currentUsdOutput) { + return false; + } + const percentageChange = getPercentageChange( - oldOutputAmount, - newOutputAmount + previousUsdOutput.toString(), + currentUsdOutput.toString() ); - if (!percentageChange) return true; - return percentageChange.toNumber() <= -1; + return OUTPUT_CHANGE_WARNING_CRITERIA.some( + ({ threshold, minInput }) => + percentageChange <= threshold && usdInput.isGreaterThanOrEqualTo(minInput) + ); } -export function getBalanceWarnings( - route: BestRouteResponse, - selectedWallets: SelectedWallet[] +export function generateBalanceWarnings( + quote: SelectedQuote, + selectedWallets: Wallet[], + blockchains: BlockchainMeta[] ) { - const fee = route.validationStatus; - const requiredWallets = getRequiredChains(route); + const fee = quote.validationStatus; + const requiredWallets = getQuoteWallets({ filter: 'required', quote }); const walletsSortedByRequiredWallets = selectedWallets.sort( (selectedWallet1, selectedWallet2) => requiredWallets.indexOf(selectedWallet1.chain) - requiredWallets.indexOf(selectedWallet2.chain) ); + return walletsSortedByRequiredWallets .flatMap((wallet) => getRequiredBalanceOfWallet(wallet, fee) || []) .filter((asset) => !asset.ok) @@ -450,33 +614,43 @@ export function getBalanceWarnings( new BigNumber(asset.currentAmount.amount).shiftedBy( -asset.currentAmount.decimals ), - 8 + BALANCE_MIN_DECIMALS, + BALANCE_MAX_DECIMALS ); const requiredAmount = numberToString( new BigNumber(asset.requiredAmount.amount).shiftedBy( -asset.requiredAmount.decimals ), - 8 + BALANCE_MIN_DECIMALS, + BALANCE_MAX_DECIMALS ); let reason = ''; - if (asset.reason === 'FEE') reason = ' for network fee'; - if (asset.reason === 'INPUT_ASSET') reason = ' for swap'; - if (asset.reason === 'FEE_AND_INPUT_ASSET') - reason = ' for input and network fee'; - const warningMessage = `Needs ≈ ${requiredAmount} ${symbol}${reason}, but you have ${currentAmount} ${symbol} in your ${asset.asset.blockchain} wallet.`; + if (asset.reason === 'FEE') { + reason = i18n.t(' for network fee'); + } + if (asset.reason === 'INPUT_ASSET') { + reason = i18n.t(' for swap'); + } + if (asset.reason === 'FEE_AND_INPUT_ASSET') { + reason = i18n.t(' for input and network fee'); + } + const warningMessage = i18n.t({ + id: `Needs ≈ {requiredAmount} {symbol}{reason}, but you have {currentAmount} {symbol} in your {blockchain} wallet.`, + values: { + requiredAmount, + symbol, + reason, + currentAmount, + blockchain: getBlockchainShortNameFor( + asset.asset.blockchain, + blockchains + ), + }, + }); return warningMessage; }); } -export function calcOutputUsdValue( - outputAmount?: string, - tokenPrice?: number | null -) { - const amount = !!outputAmount ? new BigNumber(outputAmount) : ZERO; - - return amount.multipliedBy(tokenPrice || 0); -} - export function isNetworkStatusInWarningState( pendingSwapStep: PendingSwapStep | null ): boolean { @@ -508,15 +682,20 @@ export function getSwapMessages( if (networkWarningState) { message = pendingSwap.networkStatusExtraMessage || ''; detailedMessage = pendingSwap.networkStatusExtraMessageDetail || ''; + // eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check switch (currentStep?.networkStatus) { case PendingSwapNetworkStatus.WaitingForConnectingWallet: - message = message || 'Waiting for connecting wallet'; + message = message || i18n.t('Waiting for connecting wallet'); break; case PendingSwapNetworkStatus.WaitingForQueue: - message = message || 'Waiting for other running tasks to be finished'; + message = + message || i18n.t('Waiting for other running tasks to be finished'); break; case PendingSwapNetworkStatus.WaitingForNetworkChange: - message = message || 'Waiting for changing wallet network'; + message = message || i18n.t('Waiting for changing wallet network'); + break; + default: + message = message || ''; break; } } @@ -554,9 +733,60 @@ export function getLastConvertedTokenInFailedSwap( } export function shouldRetrySwap(pendingSwap: PendingSwap) { + return pendingSwap.status === 'failed'; +} + +export function isConfirmSwapDisabled( + fetching: boolean, + isCustomDestinationOpen: boolean, + customDestination: string | null, + quote: SelectedQuote | null, + selectedWallets: { walletType: string; chain: string }[], + lastStepToBlockchain: BlockchainMeta | undefined +): boolean { + if (!quote || fetching) { + return true; + } + + const allWallets = getQuoteWallets({ filter: 'all', quote }); + + const requiredWallets = getQuoteWallets({ filter: 'required', quote }); + + const everyWalletSelected = allWallets.every((blockchain) => + selectedWallets.some( + (selectedWallet) => selectedWallet.chain === blockchain + ) + ); + + const everyRequiredWalletSelected = requiredWallets.every((wallet) => + selectedWallets.some((selectedWallet) => selectedWallet.chain === wallet) + ); + + const customDestinationIsValid = + customDestination && lastStepToBlockchain + ? isValidTokenAddress(lastStepToBlockchain, customDestination) + : false; + + return ( + (!isCustomDestinationOpen && !everyWalletSelected) || + (isCustomDestinationOpen && !customDestination) || + (isCustomDestinationOpen && + !!customDestination && + (!customDestinationIsValid || !everyRequiredWalletSelected)) + ); +} + +export function isTokensIdentical(tokenA: Token, tokenB: Token) { + return ( + tokenA.blockchain === tokenB.blockchain && + tokenA.symbol === tokenB.symbol && + tokenA.address === tokenB.address + ); +} + +export function isSwapFinished(event: RouteEvent | StepEvent) { return ( - pendingSwap.status === 'failed' && - !!pendingSwap.finishTime && - new Date().getTime() - parseInt(pendingSwap.finishTime) < 4 * 3600 * 1000 + event.type === RouteEventType.FAILED || + event.type === RouteEventType.SUCCEEDED ); } diff --git a/widget/embedded/src/utils/time.ts b/widget/embedded/src/utils/time.ts index cde274e295..2eefe63330 100644 --- a/widget/embedded/src/utils/time.ts +++ b/widget/embedded/src/utils/time.ts @@ -1,46 +1,33 @@ -import { PendingSwap } from '@rango-dev/queue-manager-rango-preset'; +import type { PendingSwap } from 'rango-types'; -export function timeSince(timeMillis: number): string { - const seconds = Math.floor((new Date().getTime() - timeMillis) / 1000); - let intervalType: string; +import { i18n } from '@lingui/core'; - let interval = Math.floor(seconds / 31536000); - if (interval >= 1) { - intervalType = 'year'; - } else { - interval = Math.floor(seconds / 2592000); - if (interval >= 1) { - intervalType = 'month'; - } else { - interval = Math.floor(seconds / 86400); - if (interval >= 1) { - intervalType = 'day'; - } else { - interval = Math.floor(seconds / 3600); - if (interval >= 1) { - intervalType = 'hour'; - } else { - interval = Math.floor(seconds / 60); - if (interval >= 1) { - intervalType = 'minute'; - } else { - interval = seconds; - intervalType = 'second'; - } - } - } - } - } +const daysOfWeek = [ + i18n.t('Sunday'), + i18n.t('Monday'), + i18n.t('Tuesday'), + i18n.t('Wednesday'), + i18n.t('Thursday'), + i18n.t('Friday'), + i18n.t('Saturday'), +]; - if (interval > 1 || interval === 0) { - intervalType += 's'; - } +export function timeSince(millisecond: number) { + const date = new Date(millisecond); + const day = date.getDate(); + const month = date.toLocaleString('default', { month: 'long' }); + const year = date.getFullYear(); + const isToday = date.getDay() === new Date().getDay(); + const formattedDate = isToday + ? i18n.t('Today') + : `${daysOfWeek[date.getDay()]} ${day} ${month} ${year}`; - return interval + ' ' + intervalType; + return `${formattedDate}, ${new Date(millisecond).toLocaleTimeString()}`; } export function getSwapDate(pendingSwap: PendingSwap) { - return pendingSwap.finishTime - ? `${timeSince(parseInt(pendingSwap.finishTime))} ago` - : `${timeSince(parseInt(pendingSwap.creationTime))} ago`; + const time = pendingSwap.finishTime + ? timeSince(parseInt(pendingSwap.finishTime)) + : timeSince(parseInt(pendingSwap.creationTime)); + return time; } diff --git a/widget/embedded/src/utils/ui.ts b/widget/embedded/src/utils/ui.ts new file mode 100644 index 0000000000..fa0651ac48 --- /dev/null +++ b/widget/embedded/src/utils/ui.ts @@ -0,0 +1,89 @@ +/* eslint-disable @typescript-eslint/no-magic-numbers */ +import type { WidgetTheme } from '../types'; +import type { createTheme } from '@rango-dev/ui'; + +import { + theme as baseThemeTokens, + darkColors as defaultDarkColors, +} from '@rango-dev/ui'; +import React from 'react'; + +import { expandToGenerateThemeColors } from '../utils/colors'; +import { toHash } from '../utils/hash'; + +import { THEME_CLASS_NAME_PREFIX } from './configs'; + +type Tokens = Parameters[0]; +interface CustomizedThemeValues { + id: string; + tokens: Tokens; +} + +interface CustomizedTheme { + light: undefined | CustomizedThemeValues; + dark: undefined | CustomizedThemeValues; +} + +export function customizedThemeTokens( + colors: WidgetTheme['colors'] +): CustomizedTheme { + const baseColors = baseThemeTokens.colors; + const baseDarkColors = { + ...baseColors, + ...defaultDarkColors, + }; + let lightTheme: CustomizedTheme['light'] = undefined; + let darkTheme: CustomizedTheme['dark'] = undefined; + + if (colors?.light) { + const lightColors = expandToGenerateThemeColors(baseColors, colors.light); + const tokens = { colors: lightColors }; + const id = `${THEME_CLASS_NAME_PREFIX}-light-${toHash(tokens)}`; + lightTheme = { + id, + tokens: tokens as Tokens, + }; + } + + if (colors?.dark) { + const darkColors = expandToGenerateThemeColors( + baseDarkColors, + colors.dark, + { + reverseNeutralRange: true, + } + ); + const tokens = { colors: darkColors }; + const id = `${THEME_CLASS_NAME_PREFIX}-dark-${toHash(tokens)}`; + darkTheme = { + id, + tokens: tokens as Tokens, + }; + } + + return { + light: lightTheme, + dark: darkTheme, + }; +} + +export function joinList( + list: { element: React.JSX.Element; key: string }[], + divider: React.JSX.Element +) { + if (list.length <= 1) { + return list.map(({ element, key }) => React.cloneElement(element, { key })); + } + + const output: React.JSX.Element[] = []; + list.forEach((item, index) => { + const { element, key } = item; + output.push(React.cloneElement(element, { key })); + if (index < list.length - 1) { + const key = `divider-${index}`; + output.push(React.cloneElement(divider, { key })); + } + }); + + return output; +} diff --git a/widget/embedded/src/utils/wallets.ts b/widget/embedded/src/utils/wallets.ts index 82a4427af3..826e1d4f87 100644 --- a/widget/embedded/src/utils/wallets.ts +++ b/widget/embedded/src/utils/wallets.ts @@ -1,34 +1,50 @@ -import { - getCosmosExperimentalChainInfo, - isEvmAddress, - KEPLR_COMPATIBLE_WALLETS, +import type { BalanceState, ConnectedWallet } from '../store/slices/wallets'; +import type { + Balance, + SelectedQuote, + Wallet, + WalletInfoWithExtra, +} from '../types'; +import type { ExtendedWalletInfo } from '@rango-dev/wallets-react'; +import type { Network, WalletState, WalletType, - detectInstallLink, - WalletInfo, + WalletTypes, } from '@rango-dev/wallets-shared'; +import type { BlockchainMeta, Token, TransactionType } from 'rango-sdk'; import { - WalletInfo as ModalWalletInfo, + BlockchainCategories, WalletState as WalletStatus, - SelectableWallet, } from '@rango-dev/ui'; +import { legacyReadAccountAddress as readAccountAddress } from '@rango-dev/wallets-core/legacy'; import { - BestRouteResponse, - BlockchainMeta, - Token, - WalletDetail, -} from 'rango-sdk'; -import { isCosmosBlockchain } from 'rango-types'; -import { readAccountAddress } from '@rango-dev/wallets-core'; -import { Account, Balance, TokenBalance } from '../store/wallets'; -import { numberToString } from './numbers'; + detectInstallLink, + getCosmosExperimentalChainInfo, + isEvmAddress, + KEPLR_COMPATIBLE_WALLETS, + Networks, +} from '@rango-dev/wallets-shared'; import BigNumber from 'bignumber.js'; -import { TokenWithBalance } from '../pages/SelectTokenPage'; +import { isCosmosBlockchain } from 'rango-types'; + import { ZERO } from '../constants/numbers'; +import { + BALANCE_MAX_DECIMALS, + BALANCE_MIN_DECIMALS, + USD_VALUE_MAX_DECIMALS, + USD_VALUE_MIN_DECIMALS, +} from '../constants/routing'; +import { EXCLUDED_WALLETS } from '../constants/wallets'; + +import { isBlockchainTypeInCategory, removeDuplicateFrom } from './common'; +import { numberToString } from './numbers'; -export function getStateWallet(state: WalletState): WalletStatus { +export type ExtendedModalWalletInfo = WalletInfoWithExtra & + Pick; + +export function mapStatusToWalletState(state: WalletState): WalletStatus { switch (true) { case state.connected: return WalletStatus.CONNECTED; @@ -41,51 +57,72 @@ export function getStateWallet(state: WalletState): WalletStatus { } } -export const excludedWallets = [ - WalletType.UNKNOWN, - WalletType.TERRA_STATION, - WalletType.LEAP, -]; - -export function getlistWallet( +export function mapWalletTypesToWalletInfo( getState: (type: WalletType) => WalletState, - getWalletInfo: (type: WalletType) => WalletInfo, - list: WalletType[] -): ModalWalletInfo[] { - const excludedWallets = [ - WalletType.UNKNOWN, - WalletType.TERRA_STATION, - WalletType.LEAP, - ]; - + getWalletInfo: (type: WalletType) => ExtendedWalletInfo, + list: WalletType[], + chain?: string +): ExtendedModalWalletInfo[] { return list - .filter((wallet) => !excludedWallets.includes(wallet)) + .filter((wallet) => !EXCLUDED_WALLETS.includes(wallet as WalletTypes)) + .filter((wallet) => { + const { supportedChains, isContractWallet } = getWalletInfo(wallet); + + const { installed, network } = getState(wallet); + const filterContractWallets = + isContractWallet && (!installed || (!!chain && network !== chain)); + if (filterContractWallets) { + return false; + } + if (chain) { + return !!supportedChains.find( + (supportedChain) => supportedChain.name === chain + ); + } + return true; + }) .map((type) => { const { name, img: image, installLink, showOnMobile, + needsNamespace, + supportedChains, + needsDerivationPath, + properties, + isHub, } = getWalletInfo(type); - const state = getStateWallet(getState(type)); + const blockchainTypes = removeDuplicateFrom( + supportedChains.map((item) => item.type) + ); + + const state = mapStatusToWalletState(getState(type)); return { - name, + title: name, image, - installLink: detectInstallLink(installLink), + link: detectInstallLink(installLink), state, type, - showOnMobile: typeof showOnMobile === 'undefined' ? false : true, + showOnMobile, + needsNamespace, + blockchainTypes, + needsDerivationPath, + properties, + isHub, }; }); } export function walletAndSupportedChainsNames( - supportedChains: BlockchainMeta[] + supportedBlockchains: BlockchainMeta[] ): Network[] | null { - if (!supportedChains) return null; + if (!supportedBlockchains) { + return null; + } let walletAndSupportedChainsNames: Network[] = []; - walletAndSupportedChainsNames = supportedChains.map( - (blockchainMeta) => blockchainMeta.name as Network + walletAndSupportedChainsNames = supportedBlockchains.map( + (blockchainMeta) => blockchainMeta.name ); return walletAndSupportedChainsNames; @@ -95,58 +132,84 @@ export function prepareAccountsForWalletStore( wallet: WalletType, accounts: string[], evmBasedChains: string[], - supportedChainNames: Network[] | null -): Account[] { - const result: Account[] = []; + supportedChainNames: Network[] | null, + isContractWallet: boolean +): Wallet[] { + const result: Wallet[] = []; function addAccount(network: Network, address: string) { - const newAccount: Account = { - address, - chain: network, - walletType: wallet, - }; + const accountForChainAlreadyExists = !!result.find( + (account) => account.chain === network + ); + if (!accountForChainAlreadyExists) { + const newAccount: Wallet = { + address, + chain: network, + walletType: wallet, + }; - result.push(newAccount); + result.push(newAccount); + } } - const supportedChains = supportedChainNames || []; + const supportedBlockchains = supportedChainNames || []; accounts.forEach((account) => { const { address, network } = readAccountAddress(account); - const hasLimitation = supportedChains.length > 0; - const isSupported = supportedChains.includes(network); - const isUnknown = network === Network.Unknown; + const hasLimitation = supportedBlockchains.length > 0; + const isSupported = supportedBlockchains.includes(network); + const isUnknown = network === Networks.Unknown; const notSupportedNetworkByWallet = hasLimitation && !isSupported && !isUnknown; - // Here we check given `network` is not supported by wallet - // And also the network is known. - if (notSupportedNetworkByWallet) return; + /* + * Here we check given `network` is not supported by wallet + * And also the network is known. + */ + if (notSupportedNetworkByWallet) { + return; + } - // In some cases we can handle unknown network by checking its address - // pattern and act on it. - // Example: showing our evm compatible netwrok when the uknown network is evem. - // Otherwise, we stop executing this function. - const isUknownAndEvmBased = - network === Network.Unknown && isEvmAddress(address); - if (isUnknown && !isUknownAndEvmBased) return; + /* + * In some cases we can handle unknown network by checking its address + * pattern and act on it. + * Example: showing our evm compatible network when the unknown network is evm. + * Otherwise, we stop executing this function. + */ + const isUnknownAndEvmBased = + network === Networks.Unknown && isEvmAddress(address); + if (isUnknown && !isUnknownAndEvmBased) { + return; + } const isEvmBasedChain = evmBasedChains.includes(network); // If it's an evm network, we will add the address to all the evm chains. - if (isEvmBasedChain || isUknownAndEvmBased) { - // all evm chains are not supported in wallets, so we are adding - // only to those that are supported by wallet. - const evmChainsSupportedByWallet = supportedChains.filter((chain) => - evmBasedChains.includes(chain) - ); - - evmChainsSupportedByWallet.forEach((network) => { - // EVM addresses are not case sensetive. - // Some wallets like Binance-chain return some letters in uppercase which produces bugs in our wallet state. + if (isEvmBasedChain || isUnknownAndEvmBased) { + if (isContractWallet) { + /* + * for contract wallets like Safe wallet, we should add only account for the + * current connected blockchain not all of the supported blockchains + */ addAccount(network, address.toLowerCase()); - }); + } else { + /* + * all evm chains are not supported in wallets, so we are adding + * only to those that are supported by wallet. + */ + const evmChainsSupportedByWallet = supportedBlockchains.filter( + (chain) => evmBasedChains.includes(chain) + ); + + evmChainsSupportedByWallet.forEach((network) => { + /* + * EVM addresses are not case sensitive. + * Some wallets like Binance-chain return some letters in uppercase which produces bugs in our wallet state. + */ + addAccount(network, address.toLowerCase()); + }); + } } else { addAccount(network, address); } @@ -155,216 +218,80 @@ export function prepareAccountsForWalletStore( return result; } -export function getRequiredChains(route: BestRouteResponse | null) { - const wallets: string[] = []; +export function getQuoteWallets(params: { + filter: 'all' | 'required'; + quote: SelectedQuote | null; +}): string[] { + const { filter, quote } = params; + const wallets = new Set(); - route?.result?.swaps.forEach((swap) => { + quote?.swaps.forEach((swap, swapIndex) => { const currentStepFromBlockchain = swap.from.blockchain; const currentStepToBlockchain = swap.to.blockchain; - let lastAddedWallet = wallets[wallets.length - 1]; - if (currentStepFromBlockchain != lastAddedWallet) - wallets.push(currentStepFromBlockchain); - lastAddedWallet = wallets[wallets.length - 1]; - if (currentStepToBlockchain != lastAddedWallet) - wallets.push(currentStepToBlockchain); - }); - return wallets; -} - -export interface SelectedWallet extends Account {} -type Blockchain = { name: string; accounts: Balance[] }; - -export function getSelectableWallets( - accounts: Account[], - selectedWallets: SelectedWallet[], - getWalletInfo: (type: WalletType) => WalletInfo -): SelectableWallet[] { - const connectedWallets: SelectableWallet[] = accounts.map((account) => ({ - address: account.address, - walletType: account.walletType, - chain: account.chain, - image: getWalletInfo(account.walletType).img, - name: getWalletInfo(account.walletType).name, - selected: !!selectedWallets.find( - (wallet) => - wallet.chain === account.chain && - wallet.walletType === account.walletType - ), - })); - - return connectedWallets; -} - -export function getBalanceFromWallet( - balances: Balance[], - chain: string, - symbol: string, - address: string | null -): TokenBalance | null { - if (balances.length === 0) return null; - - const selectedChainBalances = balances.filter( - (balance) => balance.chain === chain - ); - if (selectedChainBalances.length === 0) return null; + wallets.add(currentStepFromBlockchain); + + // Check if internalSwaps array exists + if (swap.internalSwaps) { + const { internalSwaps } = swap; + internalSwaps.forEach((internalSwap, internalSwapIndex) => { + const internalStepFromBlockchain = internalSwap.from.blockchain; + const internalStepToBlockchain = internalSwap.to.blockchain; + const isLastStep = swapIndex === quote.swaps.length - 1; + const isLastInternalStep = + internalSwapIndex === internalSwaps.length - 1; + + if ( + (!isLastStep && !isLastInternalStep) || + (isLastStep && + currentStepToBlockchain !== internalStepFromBlockchain) || + filter === 'all' + ) { + wallets.add(internalStepFromBlockchain); + } + if (filter === 'all') { + wallets.add(internalStepToBlockchain); + } + }); + } - return ( - selectedChainBalances - .map( - (a) => - a.balances?.find( - (bl) => - (address !== null && bl.address === address) || - (address === null && - bl.address === address && - bl.symbol === symbol) - ) || null - ) - .filter((b) => b !== null) - .sort( - (a, b) => parseFloat(b?.amount || '0') - parseFloat(a?.amount || '1') - ) - .find(() => true) || null - ); + if (filter === 'all') { + wallets.add(currentStepToBlockchain); + } + }); + return Array.from(wallets); } -export function isAccountAndBalanceMatched(account: Account, balance: Balance) { +export function isAccountAndWalletMatched( + account: Wallet, + connectedWallet: ConnectedWallet +) { return ( - account.address === balance.address && - account.chain === balance.chain && - account.walletType === balance.walletType + account.address === connectedWallet.address && + account.chain === connectedWallet.chain && + account.walletType === connectedWallet.walletType ); } -export function makeBalanceFor( - account: Account, - retrivedBalance: WalletDetail, - tokens: Token[] -): Balance { - const { - address, - blockChain: chain, - explorerUrl, - balances = [], - } = retrivedBalance; - return { - address, - chain, - loading: false, - error: false, - explorerUrl, - walletType: account.walletType, - balances: - balances?.map((tokenBalance) => ({ - chain, - symbol: tokenBalance.asset.symbol, - ticker: tokenBalance.asset.symbol, - address: tokenBalance.asset.address || null, - rawAmount: tokenBalance.amount.amount, - decimal: tokenBalance.amount.decimals, - amount: new BigNumber(tokenBalance.amount.amount) - .shiftedBy(-tokenBalance.amount.decimals) - .toFixed(), - logo: '', - usdPrice: - getUsdPrice( - chain, - tokenBalance.asset.symbol, - tokenBalance.asset.address, - tokens - ) || null, - })) || [], - }; -} - -export function resetBalanceState(balance: Balance): Balance { - return { ...balance, loading: false, error: true }; +export function resetConnectedWalletState( + connectedWallet: ConnectedWallet +): ConnectedWallet { + return { ...connectedWallet, loading: false, error: true }; } -export const calculateWalletUsdValue = (balance: Balance[]) => { - const uniqueAccountAddresses = new Set(); - const uniqueBalane: Balance[] = balance?.reduce( - (acc: Balance[], current: Balance) => { - return acc.findIndex( - (i) => i.address === current.address && i.chain === current.chain - ) === -1 - ? [...acc, current] - : acc; - }, - [] - ); +export const calculateWalletUsdValue = (balances: BalanceState) => { + const total = Object.values(balances).reduce((prev, balance) => { + return balance.usdValue ? prev.plus(balance.usdValue) : prev; + }, new BigNumber(ZERO)); - const modifiedWalletBlockchains = uniqueBalane?.map((chain) => { - const modifiedWalletBlockchain: Blockchain = { - name: chain.chain, - accounts: [], - }; - if (!uniqueAccountAddresses.has(chain.address)) { - uniqueAccountAddresses.add(chain.address); - } - uniqueAccountAddresses.forEach((accountAddress) => { - if (chain.address === accountAddress) - modifiedWalletBlockchain.accounts.push(chain); - }); - return modifiedWalletBlockchain; - }); - const total = numberToString( - modifiedWalletBlockchains - ?.flatMap((b) => b.accounts) - ?.flatMap((a) => a?.balances) - ?.map((b) => - new BigNumber(b?.amount || ZERO).multipliedBy(b?.usdPrice || 0) - ) - ?.reduce((a, b) => a.plus(b), ZERO) || ZERO - ).toString(); - - return numberWithThousandSeperator(total); + return numberWithThousandSeparator(total.toString()); }; -function numberWithThousandSeperator(number: string | number): string { - var parts = number.toString().split('.'); +function numberWithThousandSeparator(number: string | number): string { + const parts = number.toString().split('.'); parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ','); return parts.join('.'); } -export const sortTokens = (tokens: TokenWithBalance[]): TokenWithBalance[] => { - let walletConnected = !!tokens.some((token) => token.balance); - if (!walletConnected) { - return tokens - .filter((token) => !token.address) - .concat( - tokens.filter((token) => token.address && !token.isSecondaryCoin), - tokens.filter((token) => token.isSecondaryCoin) - ); - } - - return tokens - .filter((token) => !!token.balance) - .sort( - (tokenA, tokenB) => - parseFloat(tokenB.balance?.usdValue || '0') - - parseFloat(tokenA.balance?.usdValue || '0') - ) - .concat( - tokens.filter((token) => !token.balance && !token.isSecondaryCoin), - tokens.filter((token) => !token.balance && token.isSecondaryCoin) - ); -}; - -export const getUsdPrice = ( - blockchain: string, - symbol: string, - address: string | null, - allTokens: Token[] -): number | null => { - const token = allTokens?.find( - (t) => - t.blockchain === blockchain && - t.symbol?.toUpperCase() === symbol?.toUpperCase() && - t.address === address - ); - return token?.usdPrice || null; -}; export const isExperimentalChain = ( blockchains: BlockchainMeta[], wallet: string @@ -374,14 +301,19 @@ export const isExperimentalChain = ( .map(([, blockchainMeta]) => blockchainMeta) .filter(isCosmosBlockchain) ); - return cosmosExperimentalChainInfo && !!cosmosExperimentalChainInfo[wallet]; + return ( + cosmosExperimentalChainInfo && + cosmosExperimentalChainInfo[wallet]?.experimental + ); }; export const getKeplrCompatibleConnectedWallets = ( - selectableWallets: SelectableWallet[] + selectableWallets: Wallet[] ): WalletType[] => { const connectedWalletTypes = new Set( - selectableWallets.map((a: any) => a.walletType.toString()) + selectableWallets.map((wallet) => { + return wallet.walletType; + }) ); return KEPLR_COMPATIBLE_WALLETS.filter((compatibleWallet) => @@ -389,85 +321,95 @@ export const getKeplrCompatibleConnectedWallets = ( ); }; -export function getTokensWithBalance( - tokens: TokenWithBalance[], - balances: Balance[] -): TokenWithBalance[] { - return tokens.map(({ balance, ...otherProps }) => { - const tokenAmount = numberToString( - new BigNumber( - getBalanceFromWallet( - balances, - otherProps.blockchain, - otherProps.symbol, - otherProps.address - )?.amount || ZERO - ) - ); - - let tokenUsdValue = ''; - if (otherProps.usdPrice) - tokenUsdValue = numberToString( - new BigNumber( - getBalanceFromWallet( - balances, - otherProps.blockchain, - otherProps.symbol, - otherProps.address - )?.amount || ZERO - ).multipliedBy(otherProps.usdPrice) - ); +export function formatBalance(balance: Balance | null): Balance | null { + if (!balance) { + return null; + } - return { - ...otherProps, - ...(tokenAmount !== '0' && { - balance: { amount: tokenAmount, usdValue: tokenUsdValue }, - }), - }; - }); + const amount = new BigNumber(balance.amount) + .shiftedBy(-balance.decimals) + .toFixed(); + const usdValue = balance.usdValue + ? new BigNumber(balance.usdValue).shiftedBy(-balance.decimals).toFixed() + : null; + const formattedAmount = numberToString( + amount, + BALANCE_MIN_DECIMALS, + BALANCE_MAX_DECIMALS + ); + // null is using for detecing uknown prices + const formattedUsdValue = usdValue + ? numberToString(usdValue, USD_VALUE_MIN_DECIMALS, USD_VALUE_MAX_DECIMALS) + : null; + + const formattedBalance: Balance | null = balance + ? { + ...balance, + amount: formattedAmount, + usdValue: formattedUsdValue, + } + : null; + + return formattedBalance; } -export function getSortedTokens( - chain: BlockchainMeta | null, - tokens: Token[], - balances: Balance[], - otherChainTokens: TokenWithBalance[] -): TokenWithBalance[] { - const fromChainEqueulsToToChain = chain?.name === otherChainTokens[0]?.name; - if (fromChainEqueulsToToChain) return otherChainTokens; - const filteredTokens = tokens.filter( - (token) => token.blockchain === chain?.name - ); - return sortTokens(getTokensWithBalance(filteredTokens, balances)); +export function compareTokenBalance( + token1Balance: Balance | null, + token2Balance: Balance | null +): number { + if (token1Balance?.usdValue || token2Balance?.usdValue) { + const token1UsdValue = + !!token1Balance && !!token1Balance.usdValue + ? new BigNumber(token1Balance.usdValue).shiftedBy( + -token1Balance.decimals + ) + : ZERO; + const token2UsdValue = + !!token2Balance && !!token2Balance.usdValue + ? new BigNumber(token2Balance.usdValue).shiftedBy( + -token2Balance.decimals + ) + : ZERO; + + if (token1UsdValue.isEqualTo(token2UsdValue)) { + return 0; + } + return token1UsdValue.isGreaterThan(token2UsdValue) ? -1 : 1; + } + + if (token1Balance?.amount || token2Balance?.amount) { + const token1Amount = + !!token1Balance && !!token1Balance.amount + ? new BigNumber(token1Balance.amount).shiftedBy(-token1Balance.decimals) + : ZERO; + const token2Amount = + !!token2Balance && !!token2Balance.amount + ? new BigNumber(token2Balance.amount).shiftedBy(-token2Balance.decimals) + : ZERO; + + if (token1Amount.isEqualTo(token2Amount)) { + return 0; + } + return token1Amount.isGreaterThan(token2Amount) ? -1 : 1; + } + + return 0; } -export function tokensAreEqual( +export function areTokensEqual( tokenA: Pick | null, tokenB: Pick | null ) { return ( tokenA?.blockchain === tokenB?.blockchain && - tokenA?.symbol === tokenB?.symbol && - tokenA?.address === tokenB?.address + tokenA?.symbol.toLowerCase() === tokenB?.symbol.toLowerCase() && + tokenA?.address?.toLowerCase() === tokenB?.address?.toLowerCase() ); } -export function getDefaultToken( - sortedTokens: TokenWithBalance[], - otherToken: TokenWithBalance | null -): TokenWithBalance { - let selectedToken: TokenWithBalance; - const firstToken = sortedTokens[0]; - const secondToken = sortedTokens[1]; - if (sortedTokens.length === 1) selectedToken = firstToken; - else if (tokensAreEqual(firstToken, otherToken)) selectedToken = secondToken; - else selectedToken = firstToken; - return selectedToken; -} - -export function sortWalletsBasedOnState( - wallets: ModalWalletInfo[] -): ModalWalletInfo[] { +export function sortWalletsBasedOnConnectionState( + wallets: ExtendedModalWalletInfo[] +): ExtendedModalWalletInfo[] { return wallets.sort( (a, b) => Number(b.state === WalletStatus.CONNECTED) - @@ -482,3 +424,81 @@ export function sortWalletsBasedOnState( ) ); } + +export function getConciseAddress( + address: string, + // eslint-disable-next-line @typescript-eslint/no-magic-numbers + maxChars = 8, + // eslint-disable-next-line @typescript-eslint/no-magic-numbers + ellipsisLength = 3 +): string { + if (address.length < 2 * maxChars + ellipsisLength) { + return address; + } + const start = address.slice(0, maxChars); + const end = address.slice(-maxChars); + return `${start}${'.'.repeat(ellipsisLength)}${end}`; +} + +export function getAddress({ + chain, + connectedWallets, + walletType, +}: { + connectedWallets: ConnectedWallet[]; + walletType: string; + chain: string; +}): string | undefined { + return connectedWallets.find( + (connectedWallet) => + connectedWallet.walletType === walletType && + connectedWallet.chain === chain + )?.address; +} + +export const isFetchingBalance = ( + connectedWallets: ConnectedWallet[], + blockchain: string +) => + !!connectedWallets.find( + (wallet) => wallet.chain === blockchain && wallet.loading + ); + +export function hashWalletsState(walletsInfo: WalletInfoWithExtra[]) { + return walletsInfo.map((w) => w.state).join('-'); +} + +export function filterBlockchainsByWalletTypes( + wallets: WalletInfoWithExtra[], + blockchains: BlockchainMeta[] +) { + const uniqueBlockchainTypes = new Set(); + wallets.forEach((wallet) => { + wallet.blockchainTypes.forEach((type) => { + uniqueBlockchainTypes.add(type); + }); + }); + const filteredBlockchains = blockchains.filter((blockchain) => + uniqueBlockchainTypes.has(blockchain.type) + ); + + return filteredBlockchains; +} + +export function filterWalletsByCategory( + wallets: ExtendedModalWalletInfo[], + category: string +) { + if (category === BlockchainCategories.ALL) { + return wallets; + } + + return wallets.filter((wallet) => { + for (const type of wallet.blockchainTypes) { + if (isBlockchainTypeInCategory(type, category)) { + return true; + } + } + return false; + }); +} diff --git a/widget/embedded/tsconfig.build.json b/widget/embedded/tsconfig.build.json new file mode 100644 index 0000000000..89a371f77c --- /dev/null +++ b/widget/embedded/tsconfig.build.json @@ -0,0 +1,19 @@ +{ + // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs + "extends": "../../tsconfig.lib.json", + "include": [ + "src", + "types", + "../../global-wallets-env.d.ts", + "./global-env.d.ts" + ], + "compilerOptions": { + "outDir": "dist", + "downlevelIteration": true, + "lib": ["dom", "esnext"], + // match output dir to input dir. e.g. dist/index instead of dist/src/index + "rootDir": "./src", + // transpile JSX to React.createElement + "jsx": "react" + } +} diff --git a/widget/embedded/tsconfig.json b/widget/embedded/tsconfig.json index 3ee10b9503..4103700fab 100644 --- a/widget/embedded/tsconfig.json +++ b/widget/embedded/tsconfig.json @@ -1,38 +1,4 @@ { - // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs - "extends": "../../tsconfig.base.json", - "include": ["src", "types"], - "compilerOptions": { - "module": "esnext", - "lib": ["dom", "esnext"], - "importHelpers": true, - // output .d.ts declaration files for consumers - "declaration": true, - // output .js.map sourcemap files for consumers - "sourceMap": true, - // match output dir to input dir. e.g. dist/index instead of dist/src/index - "rootDir": "./src", - // stricter type-checking for stronger correctness. Recommended by TS - "strict": true, - // linter checks for common issues - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true, - "noImplicitAny": false, - // noUnused* overlap with @typescript-eslint/no-unused-vars, can disable if duplicative - "noUnusedLocals": true, - "noUnusedParameters": true, - // use Node's module resolution algorithm, instead of the legacy TS one - "moduleResolution": "node", - // transpile JSX to React.createElement - "jsx": "react", - // interop between ESM and CJS modules. Recommended by TS - "esModuleInterop": true, - // significant perf increase by skipping checking .d.ts files, particularly those in node_modules. Recommended by TS - "skipLibCheck": true, - // error out if import and file system have a casing mismatch. Recommended by TS - "forceConsistentCasingInFileNames": true, - // `tsdx build` ignores this option, but it is commonly used when type-checking separately with `tsc` - "noEmit": true, - "allowJs": true - } + "extends": "./tsconfig.build.json", + "include": ["src", "tests"] } diff --git a/widget/iframe/CHANGELOG.md b/widget/iframe/CHANGELOG.md new file mode 100644 index 0000000000..fc5ea46517 --- /dev/null +++ b/widget/iframe/CHANGELOG.md @@ -0,0 +1,45 @@ +# [0.12.0](https://github.com/rango-exchange/rango-client/compare/widget-iframe@0.11.0...widget-iframe@0.12.0) (2023-08-03) + + + +# [0.11.0](https://github.com/rango-exchange/rango-client/compare/widget-iframe@0.8.0...widget-iframe@0.11.0) (2023-08-01) + + + +# [0.9.0](https://github.com/rango-exchange/rango-client/compare/widget-iframe@0.8.0...widget-iframe@0.9.0) (2023-07-31) + + + +# [0.8.0](https://github.com/rango-exchange/rango-client/compare/widget-iframe@0.7.0...widget-iframe@0.8.0) (2023-07-11) + + + +# [0.7.0](https://github.com/rango-exchange/rango-client/compare/widget-iframe@0.6.0...widget-iframe@0.7.0) (2023-07-11) + + + +# [0.6.0](https://github.com/rango-exchange/rango-client/compare/widget-iframe@0.5.0...widget-iframe@0.6.0) (2023-07-11) + + + +# [0.5.0](https://github.com/rango-exchange/rango-client/compare/widget-iframe@0.4.0...widget-iframe@0.5.0) (2023-05-31) + + + +# [0.4.0](https://github.com/rango-exchange/rango-client/compare/widget-iframe@0.3.0...widget-iframe@0.4.0) (2023-05-31) + + + +# [0.3.0](https://github.com/rango-exchange/rango-client/compare/widget-iframe@0.2.0...widget-iframe@0.3.0) (2023-05-30) + + + +# 0.2.0 (2023-05-30) + + +### Features + +* add a script for initializing iframe version of rango-widget ([a84f7e9](https://github.com/rango-exchange/rango-client/commit/a84f7e98d7a5c813d97b1f8a1322790f4b18c313)) + + + diff --git a/widget/iframe/package.json b/widget/iframe/package.json new file mode 100644 index 0000000000..e9e1862ec6 --- /dev/null +++ b/widget/iframe/package.json @@ -0,0 +1,18 @@ +{ + "name": "@rango-dev/widget-iframe", + "version": "0.13.1-next.33", + "license": "MIT", + "private": true, + "source": "src/index.ts", + "browserslist": "> 0.5%, last 2 versions, not dead", + "scripts": { + "build": "parcel build --no-source-maps --cache-dir=.parcel-cache", + "clean": "rimraf .parcel-cache && rimraf dist", + "format": "prettier --write '{.,src}/**/*.{ts,tsx}'", + "lint": "eslint \"**/*.{ts,tsx}\" --ignore-path ../../.eslintignore" + }, + "devDependencies": {}, + "dependencies": { + "@rango-dev/widget-embedded": "^0.36.1-next.16" + } +} \ No newline at end of file diff --git a/widget/iframe/readme.md b/widget/iframe/readme.md new file mode 100644 index 0000000000..4f00a6e9e7 --- /dev/null +++ b/widget/iframe/readme.md @@ -0,0 +1,69 @@ +# @rango-dev/widget-iframe + +It's a javascript code to create an `iframe` for loading Rango's widget to your page. + +Example: + +Put the script in ``: +```html + +``` + +then you need to specify your container tag: + +```html +
+``` + +and finally, + +```javascript + +``` + +## Build + +You need to pass an enviroment variable which is the widget app that we are going to embedd. + +``` +WIDGET_URL=http://... yarn build +``` + + +## Development + +```shell +# 1. Create a test html page and put the example code there. +# 2. It will serve the `widget-app` on 3002 +yarn dev:widget +# 3. Build the script +WIDGET_URL=http://localhost:3002 yarn build +``` \ No newline at end of file diff --git a/widget/iframe/src/index.ts b/widget/iframe/src/index.ts new file mode 100644 index 0000000000..19ab1e897b --- /dev/null +++ b/widget/iframe/src/index.ts @@ -0,0 +1,5 @@ +import { RangoWidget } from './main'; + +const rangoWidget = new RangoWidget(); + +(window as any).rangoWidget = rangoWidget; diff --git a/widget/iframe/src/main.ts b/widget/iframe/src/main.ts new file mode 100644 index 0000000000..9011f93e4f --- /dev/null +++ b/widget/iframe/src/main.ts @@ -0,0 +1,204 @@ +import type { WidgetConfig } from '@rango-dev/widget-embedded'; + +import { + applyCommonStyles, + applyDefaultStyles, + applyDynamicHeightStyles, +} from './styles'; +import { canParse } from './utils'; + +// Actual app that will be loaded inside the iframe. +const WIDGET_URL = 'https://widget.rango.exchange/'; +const DEFAULT_CONTAINER_ID = 'rango-widget-container'; +const RANGO_WIDGET_IFRAME_ID = 'rango-widget-iframe'; + +interface Options { + rootId?: string; + clientUrl?: string; + widgetUrl?: string; +} + +interface Features { + dynamicHeight: boolean; +} + +/** + * TODO: we should add a new path to our build process to be able to use some internal types. + * esm supports for `exports` in package json which will be useful for this use case. + * The bellow type should come from `widget/embedded/src/hooks/useIframe/useIframe.types.ts`. + */ +type Messages = any; + +export class RangoWidget { + private widget: HTMLIFrameElement | null = null; + private features: Features = { + dynamicHeight: false, + }; + private options?: Options; + + public init(configuration?: WidgetConfig, options?: string | Options) { + /** + * It was only an string for setting rootId previously, so for backward compatibility we should keep the string yet. + * Here, we are parsing the value and convert it to an object. + */ + this.parseOptions(options); + + if (!!this.options?.widgetUrl && !canParse(this.options.widgetUrl)) { + throw new Error('You need to pass a valid `widgetUrl`.'); + } + + if (!!this.options?.clientUrl && !canParse(this.options.clientUrl)) { + throw new Error('You need to pass a valid `clientUrl`.'); + } + + // Create widget + this.createWidget(configuration); + if (!this.widget) { + throw new Error("Widget element hasn't been created yet."); + } + + // Append the widget to target container + const rootId = this.options?.rootId || DEFAULT_CONTAINER_ID; + const container = this.getContainer(rootId); + container.appendChild(this.widget); + + // Listening to events + this.widget.onload = () => { + this.widget!.style.display = 'block'; + }; + + if (!!this.options?.clientUrl) { + this.listenToMessages(); + } + + return this.builder(); + } + + /** + * + * Activating feature + * This script can have different features that needs to be activated by user explicitly. + * + * @param feature + * @returns + */ + public activate(feature: keyof Features) { + if (!this.widget) { + throw new Error( + "It seems you didn't call `init`. Please first setup iframe using `init` then try to activate a feature." + ); + } + if (!this.options?.clientUrl) { + throw new Error( + "You need to pass `clientUrl` in your init's options to be able to use iframe features." + ); + } + if (!(feature in this.features)) { + throw new Error(`${feature} is not a valid feature.`); + } + + this.features[feature] = true; + + return this.builder(); + } + + /** + * We can call some specific methods like a chain by using this pattern. + * It will be like: rango().activate('a').activate('b') + */ + private builder(): { + activate: RangoWidget['activate']; + } { + return { + activate: this.activate.bind(this), + }; + } + + /** + * Encode configuration object into a string that can be passed as url param. + */ + private encode(configuration: WidgetConfig): string { + const configParams = JSON.stringify(configuration, (key, value) => { + // Take # out of the url parameters + if (typeof value === 'string' && value[0] === '#') { + return value.replace('#', '$'); + } + return value; + }); + return configParams; + } + + /** + * We need a container to load our iframe into it. This method will get the container or raise an error. + */ + private getContainer(containerId: string): HTMLElement { + const container = window.document.getElementById(containerId); + + if (!container) { + throw new Error( + `Couldn't find root element for initializing widget. Please make sure you have an HTML element with this is: ${container} ` + ); + } + + return container; + } + + /** + * Creating an iframe node with desired attributes to load the widget. + */ + private createWidget(configuration?: WidgetConfig) { + if (!configuration) { + throw new Error('Make sure you are passing configurations.'); + } + + const configs = this.encode(configuration); + const baseUrl = this.options?.widgetUrl || WIDGET_URL; + let url = `${baseUrl}?config=${configs}`; + const widget = document.createElement('iframe'); + widget.setAttribute('id', RANGO_WIDGET_IFRAME_ID); + + if (this.options?.clientUrl) { + url += `&clientUrl=${encodeURI(this.options.clientUrl)}`; + applyDynamicHeightStyles(widget); + } else { + applyCommonStyles(widget); + applyDefaultStyles(widget); + } + widget.src = url; + this.widget = widget; + } + + /** + * Listening to messages and react to events sent by widget. + */ + private listenToMessages() { + window.addEventListener('message', (e) => { + if (this.features.dynamicHeight && e.data.type === 'widget_height') { + this.onWidgetHeightChange(e.data); + } + }); + } + + private onWidgetHeightChange(message: Messages) { + if (!this.widget) { + return; + } + this.widget.style.height = message.data.height; + } + + /** + * This is for backward compatibility. Previously we only got `rootId` as option and second parameter of `init`. + */ + private parseOptions(options?: string | Options) { + let opts: Options | undefined = undefined; + if (typeof options === 'string') { + opts = { + rootId: options, + }; + } else if (typeof options !== 'undefined') { + opts = options; + } + + this.options = opts; + } +} diff --git a/widget/iframe/src/styles.ts b/widget/iframe/src/styles.ts new file mode 100644 index 0000000000..aff639fd24 --- /dev/null +++ b/widget/iframe/src/styles.ts @@ -0,0 +1,18 @@ +export function applyCommonStyles(element: HTMLIFrameElement) { + element.style.width = '100vw'; + element.style.maxWidth = '390px'; + element.style.overflow = 'hidden'; + element.style.backgroundColor = 'transparent'; + element.style.border = 'none'; +} + +export function applyDefaultStyles(element: HTMLIFrameElement) { + applyCommonStyles(element); + element.style.height = '100vh'; + element.style.maxHeight = '700px'; +} +export function applyDynamicHeightStyles(element: HTMLIFrameElement) { + applyCommonStyles(element); + // This is an initial value when widget hasn't been loaded completely. + element.style.height = '390px'; +} diff --git a/widget/iframe/src/utils.ts b/widget/iframe/src/utils.ts new file mode 100644 index 0000000000..719c4b82c8 --- /dev/null +++ b/widget/iframe/src/utils.ts @@ -0,0 +1,11 @@ +// URL.canParse hasn't good support yet, so using a polyfill if it's not available. +export function canParse(url: string) { + if ('canParse' in window.URL) { + return URL.canParse(url); + } + try { + return !!new URL(url); + } catch (error) { + return false; + } +} diff --git a/widget/iframe/tsconfig.build.json b/widget/iframe/tsconfig.build.json new file mode 100644 index 0000000000..1ca5619ee0 --- /dev/null +++ b/widget/iframe/tsconfig.build.json @@ -0,0 +1,12 @@ +{ + // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs + "extends": "../../tsconfig.lib.json", + "include": ["src"], + "compilerOptions": { + "module": "esnext", + "outDir": "dist", + "lib": ["dom", "esnext"], + // match output dir to input dir. e.g. dist/index instead of dist/src/index + "rootDir": "./src" + } +} diff --git a/widget/iframe/tsconfig.json b/widget/iframe/tsconfig.json new file mode 100644 index 0000000000..a3a0b0f59d --- /dev/null +++ b/widget/iframe/tsconfig.json @@ -0,0 +1 @@ +{ "extends": "./tsconfig.build.json", "include": ["src", "tests"] } diff --git a/widget/playground/package.json b/widget/playground/package.json index c173a4c360..bb72bdd7b8 100644 --- a/widget/playground/package.json +++ b/widget/playground/package.json @@ -1,27 +1,41 @@ { "name": "@rango-dev/widget-playground", - "version": "0.1.15", + "version": "0.24.0", "license": "MIT", "private": true, "source": "public/index.html", + "main": "dist/index.html", + "targets": { + "main": false + }, "browserslist": "> 0.5%, last 2 versions, not dead", "scripts": { - "dev": "parcel -p 3005 --cache-dir=.parcel-cache", - "build": "parcel build --cache-dir=.parcel-cache" + "dev": "parcel -p 3005 --cache-dir=.parcel-cache --no-cache", + "build": "parcel build --cache-dir=.parcel-cache", + "ts-check": "tsc --declaration --emitDeclarationOnly -p ./tsconfig.json", + "clean": "rimraf .parcel-cache && rimraf dist", + "format": "prettier --write '{.,src}/**/*.{ts,tsx}'", + "lint": "eslint \"**/*.{ts,tsx}\" --ignore-path ../../.eslintignore" }, "devDependencies": { - "parcel": "^2.7.0" + "@types/react-color": "^3.0.6", + "@types/stringify-object": "^4.0.2" }, "dependencies": { - "@rango-dev/provider-all": "^0.1.12", - "@rango-dev/ui": "^0.1.12", - "@rango-dev/wallets-core": "^0.1.12", - "@rango-dev/wallets-shared": "^0.1.11", - "@rango-dev/widget-embedded": "^0.1.12", - "rango-sdk": "^0.1.20", + "@rango-dev/provider-all": "^0.40.1-next.8", + "@rango-dev/ui": "^0.42.1-next.11", + "@rango-dev/wallets-react": "^0.26.1-next.9", + "@rango-dev/wallets-shared": "^0.40.1-next.6", + "@rango-dev/widget-embedded": "^0.36.1-next.16", + "rango-sdk": "^0.1.57", "react": "^18.2.0", + "react-color": "^2.19.3", "react-dom": "^18.2.0", + "react-router-dom": "^6.10.0", + "react-syntax-highlighter": "^15.5.0", + "stringify-object": "^5.0.0", + "subtract-object": "^1.1.0", "zustand": "^4.3.2" }, "gitHead": "a4584c2a3341fe23e033a9ff2db0f201b0a6278c" -} +} \ No newline at end of file diff --git a/widget/playground/public/favicon.png b/widget/playground/public/favicon.png new file mode 100644 index 0000000000..3c23bc6466 Binary files /dev/null and b/widget/playground/public/favicon.png differ diff --git a/widget/playground/public/index.html b/widget/playground/public/index.html index cee7e0a7e7..63421762b0 100644 --- a/widget/playground/public/index.html +++ b/widget/playground/public/index.html @@ -1,16 +1,20 @@ - + - + + + Rango Widget Playground - - - + + + -
- \ No newline at end of file + diff --git a/widget/playground/readme.md b/widget/playground/readme.md index d3f18c54d8..83fb057798 100644 --- a/widget/playground/readme.md +++ b/widget/playground/readme.md @@ -1,3 +1,4 @@ # Widget Playground +Create your cross-chain widget in 2 minutes! diff --git a/widget/playground/src/App.tsx b/widget/playground/src/App.tsx index 32367a71e6..bba50e713b 100644 --- a/widget/playground/src/App.tsx +++ b/widget/playground/src/App.tsx @@ -1,18 +1,58 @@ -import React from 'react'; -import { Config } from './containers/Config'; -import { Widget } from '@rango-dev/widget-embedded'; -import { useConfigStore } from './store/config'; -import { useTheme } from './hook/useTheme'; +import type { WidgetConfig } from '@rango-dev/widget-embedded'; + +import { ToastProvider } from '@rango-dev/ui'; +import { Widget, WidgetProvider } from '@rango-dev/widget-embedded'; +import React, { useEffect } from 'react'; +import { Route, Routes } from 'react-router-dom'; + +import { PLAYGROUND_CONTAINER_ID } from './constants'; +import { ConfigContainer } from './containers/configContainer'; +import { useTheme } from './hooks/useTheme'; +import { initialConfig, useConfigStore } from './store/config'; +import { useMetaStore } from './store/meta'; +import { RANGO_PUBLIC_API_KEY } from './utils/configs'; +import { filterConfig } from './utils/export'; export function App() { - const { activeTheme } = useTheme(); + const { activeStyle } = useTheme(); + const fetchMeta = useMetaStore.use.fetchMeta(); const config = useConfigStore.use.config(); + const { filteredConfigForExport } = filterConfig(config, initialConfig); + + const overridedConfig: WidgetConfig = { + theme: {}, + ...config, + ...filteredConfigForExport, + /* + * externalWallets should be always true to avoid mounting WidgetProvider twice. + * mounting multiple WidgetProviders may result in conflicts and unexpected behaviour. + */ + externalWallets: true, + apiKey: RANGO_PUBLIC_API_KEY, + features: { + theme: 'hidden', + experimentalWallet: 'enabled', + }, + __UNSTABLE_OR_INTERNAL__: { + autoUpdateSettings: true, + }, + }; + + useEffect(() => { + void fetchMeta(); + }, []); return ( -
- - - -
+ +
+ + + + } /> + + + +
+
); } diff --git a/widget/playground/src/components/ChainsConfig.tsx b/widget/playground/src/components/ChainsConfig.tsx deleted file mode 100644 index 399247e3f8..0000000000 --- a/widget/playground/src/components/ChainsConfig.tsx +++ /dev/null @@ -1,97 +0,0 @@ -import { Checkbox, Spacer, styled, Typography } from '@rango-dev/ui'; -import React from 'react'; -import { onChangeMultiSelects } from '../helpers'; -import { useConfigStore } from '../store/config'; -import { useMetaStore } from '../store/meta'; -import { Type } from '../types'; -import { MultiSelect } from './MultiSelect'; -import { MultiTokenSelect } from './MultiSelect/MultiTokenSelect'; -import { TokenInfo } from './TokenInfo'; -import { Asset } from 'rango-sdk'; - -interface PropTypes { - type: Type; -} -export const ConfigurationContainer = styled('div', { - borderRadius: '$10', - maxWidth: '732px', - boxShadow: '$s', - padding: '$16', - backgroundColor: '$background', -}); - -export function ChainsConfig({ type }: PropTypes) { - const blockchains = useMetaStore.use.meta().blockchains; - const tokens = useMetaStore.use.meta().tokens; - const from = useConfigStore.use.config().from; - const to = useConfigStore.use.config().to; - - const customAddress = useConfigStore.use.config().customAddress; - const onChangeBlockChains = useConfigStore.use.onChangeBlockChains(); - const onChangeTokens = useConfigStore.use.onChangeTokens(); - - const onChangeBooleansConfig = useConfigStore.use.onChangeBooleansConfig(); - - const chains = type === 'Source' ? from?.blockchains : to?.blockchains; - - const onChangeChains = (blockchain: string) => { - const tokens = type === 'Source' ? from?.tokens : to?.tokens; - const ChainsList = blockchains.map((chain) => chain.name); - const values = onChangeMultiSelects( - blockchain, - chains, - ChainsList, - (item) => item === blockchain, - ); - onChangeBlockChains(values, type); - - let tokensList: Asset[] = []; - if (tokens && values) { - for (const chain of values) { - tokensList = [...tokensList, ...tokens.filter((token) => token.blockchain === chain)]; - } - } - onChangeTokens(tokensList && tokensList.length ? tokensList : undefined, type); - }; - - return ( -
- {type} Form - - - - - chains.includes(chain.name)) - } - /> - {type === 'Destination' ? ( - <> - - onChangeBooleansConfig('customAddress', checked)} - id="custom_address" - label="Enable Transfer To Custom Address" - checked={customAddress} - /> - - ) : null} - - - - -
- ); -} diff --git a/widget/playground/src/components/Collapse/Collapse.styles.ts b/widget/playground/src/components/Collapse/Collapse.styles.ts new file mode 100644 index 0000000000..d692f1e977 --- /dev/null +++ b/widget/playground/src/components/Collapse/Collapse.styles.ts @@ -0,0 +1,27 @@ +import { Collapsible, styled } from '@rango-dev/ui'; + +export const CollapseContainer = styled(Collapsible, { + borderRadius: '$xm', + backgroundColor: '$neutral100', + border: '1px solid $neutral100', + '&:hover': { + borderColor: '$secondary200', + '& .collapse_header > svg': { + color: '$secondary500', + }, + }, +}); + +export const CollapseHeader = styled('div', { + display: 'flex', + justifyContent: 'space-between', + alignItems: 'center', + width: '100%', + cursor: 'pointer', + padding: '$20 $25', + textTransform: 'capitalize', +}); + +export const CollapseContent = styled('div', { + padding: '0 $15 $20', +}); diff --git a/widget/playground/src/components/Collapse/Collapse.tsx b/widget/playground/src/components/Collapse/Collapse.tsx new file mode 100644 index 0000000000..83d7222752 --- /dev/null +++ b/widget/playground/src/components/Collapse/Collapse.tsx @@ -0,0 +1,34 @@ +import type { PropTypes } from './Collapse.types'; +import type { PropsWithChildren } from 'react'; + +import { ChevronDownIcon, ChevronUpIcon, Typography } from '@rango-dev/ui'; +import React from 'react'; + +import { + CollapseContainer, + CollapseContent, + CollapseHeader, +} from './Collapse.styles'; + +export function Collapse(props: PropsWithChildren) { + const { title, children, open, toggle } = props; + return ( + + + {title} + + {open ? ( + + ) : ( + + )} + + }> + {children} + + ); +} diff --git a/widget/playground/src/components/Collapse/Collapse.types.ts b/widget/playground/src/components/Collapse/Collapse.types.ts new file mode 100644 index 0000000000..229322c3ca --- /dev/null +++ b/widget/playground/src/components/Collapse/Collapse.types.ts @@ -0,0 +1,5 @@ +export interface PropTypes { + title: string; + open: boolean; + toggle: () => void; +} diff --git a/widget/playground/src/components/Collapse/index.ts b/widget/playground/src/components/Collapse/index.ts new file mode 100644 index 0000000000..f87b98b456 --- /dev/null +++ b/widget/playground/src/components/Collapse/index.ts @@ -0,0 +1 @@ +export { Collapse } from './Collapse'; diff --git a/widget/playground/src/components/ColorPicker/ColorPicker.styles.ts b/widget/playground/src/components/ColorPicker/ColorPicker.styles.ts new file mode 100644 index 0000000000..52472aeb38 --- /dev/null +++ b/widget/playground/src/components/ColorPicker/ColorPicker.styles.ts @@ -0,0 +1,23 @@ +import { Button, styled } from '@rango-dev/ui'; + +export const Container = styled('div', { + display: 'flex', + justifyContent: 'space-around', + alignItems: 'center', + position: 'relative', +}); + +export const ColorContainer = styled('div', { + border: '1px solid $neutral300', + borderRadius: '$xs', + width: '$20', + height: '$20', +}); + +export const ColorButton = styled(Button, { + border: '1px solid $neutral300', + backgroundColor: 'transparent', + borderRadius: '$xs', + width: 93, + justifyContent: 'normal', +}); diff --git a/widget/playground/src/components/ColorPicker/ColorPicker.tsx b/widget/playground/src/components/ColorPicker/ColorPicker.tsx new file mode 100644 index 0000000000..428c740913 --- /dev/null +++ b/widget/playground/src/components/ColorPicker/ColorPicker.tsx @@ -0,0 +1,46 @@ +import type { PropTypes } from './ColorPicker.types'; +import type { ColorResult } from 'react-color'; + +import { Button, Popover, Typography } from '@rango-dev/ui'; +import React from 'react'; +import { ChromePicker } from 'react-color'; + +import { ColorButton, ColorContainer, Container } from './ColorPicker.styles'; + +function ColorPicker(props: PropTypes) { + const { label, placeholder, color, onChangeColor, onReset, resetDisable } = + props; + const onChange = (c: ColorResult) => { + onChangeColor(c.hex); + }; + return ( + + + {label} + + }> + }> + + {color || placeholder} + + + + + + ); +} + +export default React.memo(ColorPicker); diff --git a/widget/playground/src/components/ColorPicker/ColorPicker.types.ts b/widget/playground/src/components/ColorPicker/ColorPicker.types.ts new file mode 100644 index 0000000000..835a39db52 --- /dev/null +++ b/widget/playground/src/components/ColorPicker/ColorPicker.types.ts @@ -0,0 +1,8 @@ +export interface PropTypes { + onReset: () => void; + label: string; + placeholder?: string; + color?: string; + onChangeColor: (color?: string) => void; + resetDisable?: boolean; +} diff --git a/widget/playground/src/components/ColorPicker/index.ts b/widget/playground/src/components/ColorPicker/index.ts new file mode 100644 index 0000000000..8cc1bd3c1c --- /dev/null +++ b/widget/playground/src/components/ColorPicker/index.ts @@ -0,0 +1 @@ +export { default as ColorPicker } from './ColorPicker'; diff --git a/widget/playground/src/components/ExportConfigModal/CodeBlock.styles.tsx b/widget/playground/src/components/ExportConfigModal/CodeBlock.styles.tsx new file mode 100644 index 0000000000..22181198dc --- /dev/null +++ b/widget/playground/src/components/ExportConfigModal/CodeBlock.styles.tsx @@ -0,0 +1,113 @@ +import { Button, keyframes, styled } from '@rango-dev/ui'; + +export const CopyCodeBlock = styled('div', { + position: 'absolute', + right: '$16', + bottom: '$12', +}); + +export const CopyCodeBlockButton = styled(Button, { + width: '$48', + height: '$48', + lineHeight: '$12 !important', +}); + +export const CodeBlockContainer = styled('div', { + position: 'relative', + borderRadius: '$sm', + height: '507px', + width: '100%', +}); + +const copyIconFadeIn = keyframes({ + '0%': { + opacity: 0, + }, + '100%': { + opacity: 1, + }, +}); + +const copyIconFadeOut = keyframes({ + '0%': { + opacity: 1, + }, + '100%': { + opacity: 0, + }, +}); + +export const CopyCodeBlockButtonIcon = styled('span', { + variants: { + visible: { + true: { + animation: `${copyIconFadeIn} .5s ease-in-out`, + opacity: 1, + }, + false: { + animation: `${copyIconFadeOut} .5s ease-in-out`, + opacity: 0, + }, + }, + }, +}); + +const doneIconFadeIn = keyframes({ + '0%': { + transform: 'translateY(12px)', + opacity: 0, + }, + '100%': { + transform: 'translateY(0)', + opacity: 1, + }, +}); + +export const CopyCodeBlockButtonDoneIcon = styled('span', { + position: 'absolute', + top: '12px', + left: '12px', + transform: 'translateY(0)', + variants: { + visible: { + true: { + animation: `${doneIconFadeIn} .5s ease-in-out`, + transform: 'translateY(0)', + opacity: 1, + }, + false: { + opacity: 0, + }, + }, + }, +}); + +const SuccessfulAlertContainerTransform = keyframes({ + '0%': { + transform: 'translateY(24px) translateX(-50%)', + opacity: 0, + }, + '100%': { + transform: 'translateY(0) translateX(-50%)', + opacity: 1, + }, +}); + +export const SuccessfulAlertContainer = styled('div', { + display: 'inline', + position: 'fixed', + bottom: '$12', + left: '50%', + variants: { + visible: { + true: { + animation: `${SuccessfulAlertContainerTransform} .5s ease-in-out`, + transform: 'translateY(0) translateX(-50%)', + opacity: 1, + }, + false: { + opacity: 0, + }, + }, + }, +}); diff --git a/widget/playground/src/components/ExportConfigModal/CodeBlock.tsx b/widget/playground/src/components/ExportConfigModal/CodeBlock.tsx new file mode 100644 index 0000000000..d2a76c23b9 --- /dev/null +++ b/widget/playground/src/components/ExportConfigModal/CodeBlock.tsx @@ -0,0 +1,70 @@ +import type { CodeBlockProps } from './CodeBlock.types'; + +import { + Alert, + CopyIcon, + DoneIcon, + Tooltip, + useCopyToClipboard, +} from '@rango-dev/ui'; +import React from 'react'; +import { PrismLight as SyntaxHighlighter } from 'react-syntax-highlighter'; +import { + javascript, + jsx, +} from 'react-syntax-highlighter/dist/esm/languages/prism'; + +import { + CodeBlockContainer, + CopyCodeBlock, + CopyCodeBlockButton, + CopyCodeBlockButtonDoneIcon, + CopyCodeBlockButtonIcon, + SuccessfulAlertContainer, +} from './CodeBlock.styles'; + +const RESET_INTERVAL = 2_000; + +SyntaxHighlighter.registerLanguage('javascript', javascript); +SyntaxHighlighter.registerLanguage('jsx', jsx); + +export function CodeBlock(props: CodeBlockProps) { + const { language, theme, children, selectedType } = props; + + const [isCopied, handleCopy] = useCopyToClipboard(RESET_INTERVAL); + + return ( + + + + { + handleCopy(children); + }}> + + + + + + + + + + + {children} + + + + + + + ); +} diff --git a/widget/playground/src/components/ExportConfigModal/CodeBlock.types.tsx b/widget/playground/src/components/ExportConfigModal/CodeBlock.types.tsx new file mode 100644 index 0000000000..03325ac994 --- /dev/null +++ b/widget/playground/src/components/ExportConfigModal/CodeBlock.types.tsx @@ -0,0 +1,8 @@ +import type { ExportType, Language } from './ExportConfigModal.types'; + +export interface CodeBlockProps { + selectedType: ExportType; + language: Language; + theme: any; + children: string; +} diff --git a/widget/playground/src/components/ExportConfigModal/ExportConfigModal.styles.tsx b/widget/playground/src/components/ExportConfigModal/ExportConfigModal.styles.tsx new file mode 100644 index 0000000000..ca85614dc2 --- /dev/null +++ b/widget/playground/src/components/ExportConfigModal/ExportConfigModal.styles.tsx @@ -0,0 +1,65 @@ +import { IconButton, styled } from '@rango-dev/ui'; + +export const Link = styled('a', { + color: '$neutral700', + padding: 4, + textDecoration: 'none', + '&:hover': { + color: '$secondary500', + '& .icon_container > svg': { + color: '$secondary500', + }, + }, +}); + +export const TabsContainer = styled('div', { + height: '$40', +}); + +export const ModalFlex = styled('div', { + display: 'flex', + alignItems: 'center', + justifyContent: 'end', + [`& ${IconButton}`]: { + padding: '$5', + }, +}); + +export const LinkContainer = styled('div', { + padding: '$5', +}); + +export const Head = styled('div', { + display: 'flex', + padding: '$10 0', + borderBottom: '1px solid $neutral300', + borderTop: '1px solid $neutral300', +}); + +export const APIKeyInputContainer = styled('div', { + width: '350px', + backgroundColor: '$neutral100', + padding: '$5 $10', + borderRadius: '$sm', +}); + +export const HelpLinksContainer = styled('div', { + margin: 'auto', + marginBottom: 'inherit', + marginRight: 'inherit', + display: 'flex', +}); + +export const ExternalLinkIconContainer = styled('span', { + position: 'relative', + display: 'inline-block', + top: '1px', +}); + +export const StyledIconButton = styled(IconButton, { + width: '48px', + height: '48px', +}); +export const Label = styled('span', { + display: 'flex', +}); diff --git a/widget/playground/src/components/ExportConfigModal/ExportConfigModal.tsx b/widget/playground/src/components/ExportConfigModal/ExportConfigModal.tsx new file mode 100644 index 0000000000..31edc2ecc5 --- /dev/null +++ b/widget/playground/src/components/ExportConfigModal/ExportConfigModal.tsx @@ -0,0 +1,161 @@ +import type { + ExportConfigModalProps, + ExportType, +} from './ExportConfigModal.types'; + +import { + CloseIcon, + Divider, + ExternalLinkIcon, + KeyIcon, + Modal, + ModalHeader, + Tabs, + TextField, + Typography, +} from '@rango-dev/ui'; +import React, { useState } from 'react'; +import { + atomDark as dark, + prism, +} from 'react-syntax-highlighter/dist/esm/styles/prism'; + +import { PLAYGROUND_CONTAINER_ID } from '../../constants'; +import { useTheme } from '../../hooks/useTheme'; +import { initialConfig, useConfigStore } from '../../store/config'; +import { filterConfig, formatConfig } from '../../utils/export'; + +import { CodeBlock } from './CodeBlock'; +import { + APIKeyInputContainer, + ExternalLinkIconContainer, + Head, + HelpLinksContainer, + Label, + Link, + LinkContainer, + ModalFlex, + StyledIconButton, + TabsContainer, +} from './ExportConfigModal.styles'; +import { + typesOfCodeBlocks, + typesOfCodeBlocksTabs, +} from './ExportConfigModal.types'; + +export function ExportConfigModal(props: ExportConfigModalProps) { + const { open, onClose, config } = props; + + const { activeTheme } = useTheme(); + const [selected, setSelected] = useState('embedded'); + const syntaxHighlighterTheme = activeTheme === 'dark' ? dark : prism; + const { filteredConfigForExport } = filterConfig(config, initialConfig); + const formatedConfig = formatConfig(filteredConfigForExport); + const apiKey = useConfigStore.use.config().apiKey; + const onChangeApiKey = useConfigStore.use.onChangeApiKey(); + + return ( + + + Export Code + + + + + + + + } + open={open} + onClose={onClose} + title="Export Code" + anchor="center"> + + + + { + onChangeApiKey(e.target.value); + }} + name="apiKey" + value={apiKey} + label={ + + } + labelProps={{ + color: '$neutral600', + size: 'medium', + variant: 'label', + }} + type="string" + placeholder="Enter API Key" + /> + + + + + + + + +  Full Instructions + + + + + + + + + +  More Examples + + + + + + + + setSelected(item.id as ExportType)} + value={selected} + type="secondary" + borderRadius="medium" + /> + + + + {typesOfCodeBlocks[selected].generateCode(formatedConfig)} + + + ); +} diff --git a/widget/playground/src/components/ExportConfigModal/ExportConfigModal.types.tsx b/widget/playground/src/components/ExportConfigModal/ExportConfigModal.types.tsx new file mode 100644 index 0000000000..dff5174dc8 --- /dev/null +++ b/widget/playground/src/components/ExportConfigModal/ExportConfigModal.types.tsx @@ -0,0 +1,47 @@ +import type { WidgetConfig } from '@rango-dev/widget-embedded'; + +import { getEmbeddedCode, getIframeCode } from '../../utils/export'; + +export type ExportType = 'embedded' | 'iframe' | 'config'; +export type Language = 'jsx' | 'javascript'; + +export const typesOfCodeBlocksTabs = [ + { + id: 'embedded', + title: 'Embedded', + }, + { + id: 'iframe', + title: 'Iframe', + }, + { + id: 'config', + title: 'Config', + }, +]; + +export const typesOfCodeBlocks: { + [key in ExportType]: { + language: Language; + generateCode: (config: string) => string; + }; +} = { + embedded: { + language: 'jsx', + generateCode: (config) => getEmbeddedCode(config), + }, + iframe: { + language: 'javascript', + generateCode: (config) => getIframeCode(config), + }, + config: { + language: 'javascript', + generateCode: (config) => config, + }, +}; + +export interface ExportConfigModalProps { + open: boolean; + onClose: () => void; + config: WidgetConfig; +} diff --git a/widget/playground/src/components/ExportConfigModal/index.ts b/widget/playground/src/components/ExportConfigModal/index.ts new file mode 100644 index 0000000000..6c05d12976 --- /dev/null +++ b/widget/playground/src/components/ExportConfigModal/index.ts @@ -0,0 +1 @@ +export { ExportConfigModal } from './ExportConfigModal'; diff --git a/widget/playground/src/components/ItemPicker/ItemPicker.styles.ts b/widget/playground/src/components/ItemPicker/ItemPicker.styles.ts new file mode 100644 index 0000000000..eb74958a2d --- /dev/null +++ b/widget/playground/src/components/ItemPicker/ItemPicker.styles.ts @@ -0,0 +1,44 @@ +import { styled } from '@rango-dev/ui'; + +export const InputContainer = styled('div', { + border: '1px solid $neutral300', + display: 'flex', + justifyContent: 'space-between', + padding: '$10', + width: '100%', + borderRadius: '$xm', + cursor: 'pointer', + alignItems: 'center', + '&:hover': { + borderColor: '$secondary200', + '& svg': { + color: '$secondary500', + }, + }, + variants: { + disabled: { + true: { + cursor: 'default', + '&:hover': { + borderColor: '$neutral300', + '& svg': { + color: '$neutral700', + }, + }, + }, + }, + }, +}); + +export const Container = styled('div', { + display: 'flex', + flexDirection: 'column', + width: '100%', + '.title_typography': { + textTransform: 'capitalize', + }, +}); + +export const Title = styled('div', { + display: 'flex', +}); diff --git a/widget/playground/src/components/ItemPicker/ItemPicker.tsx b/widget/playground/src/components/ItemPicker/ItemPicker.tsx new file mode 100644 index 0000000000..9c070cf993 --- /dev/null +++ b/widget/playground/src/components/ItemPicker/ItemPicker.tsx @@ -0,0 +1,78 @@ +import type { PropTypes } from './ItemPicker.types'; + +import { + ChevronRightIcon, + Divider, + Image, + InfoIcon, + Tooltip, + Typography, +} from '@rango-dev/ui'; +import React from 'react'; + +import { Container, InputContainer, Title } from './ItemPicker.styles'; + +function ItemPicker(props: PropTypes) { + const { + onClick, + value: { label = '', logo }, + title, + iconTitle, + hasLogo, + placeholder, + tooltip, + disabled, + } = props; + + const LogoComponent = logo; + return ( + + + {iconTitle} + {iconTitle && <Divider direction="horizontal" size={4} />} + <Typography size="medium" variant="body"> + {title} + </Typography> + <Divider size={4} direction="horizontal" /> + + {tooltip && ( + <Tooltip content={tooltip} side="top"> + <InfoIcon size={14} color="gray" /> + </Tooltip> + )} + + + + + {hasLogo && ( + <> + {typeof logo === 'string' || logo === undefined ? ( + <Image + src={logo} + size={16} + useAsPlaceholder={!logo} + type="circular" + /> + ) : ( + LogoComponent && <LogoComponent size={16} /> + )} + <Divider size={4} direction="horizontal" /> + </> + )} + <Typography + className="title_typography" + size="medium" + variant="label" + color="neutral700"> + {label || placeholder} + </Typography> + + + + + ); +} + +export default React.memo(ItemPicker); diff --git a/widget/playground/src/components/ItemPicker/ItemPicker.types.ts b/widget/playground/src/components/ItemPicker/ItemPicker.types.ts new file mode 100644 index 0000000000..22341ac9a8 --- /dev/null +++ b/widget/playground/src/components/ItemPicker/ItemPicker.types.ts @@ -0,0 +1,13 @@ +export interface PropTypes { + onClick: () => void; + value: { + label?: string; + logo?: string | React.ComponentType<{ size?: number }>; + }; + title: string; + iconTitle?: React.ReactNode; + placeholder?: string; + hasLogo?: boolean; + disabled?: boolean; + tooltip?: React.ReactNode; +} diff --git a/widget/playground/src/components/ItemPicker/index.ts b/widget/playground/src/components/ItemPicker/index.ts new file mode 100644 index 0000000000..29eff37e1c --- /dev/null +++ b/widget/playground/src/components/ItemPicker/index.ts @@ -0,0 +1 @@ +export { default as ItemPicker } from './ItemPicker'; diff --git a/widget/playground/src/components/MultiList/MultiList.helper.ts b/widget/playground/src/components/MultiList/MultiList.helper.ts new file mode 100644 index 0000000000..2ab530c11f --- /dev/null +++ b/widget/playground/src/components/MultiList/MultiList.helper.ts @@ -0,0 +1,8 @@ +import type { MapSupportedList } from '../MultiSelect/MultiSelect.types'; + +// Determines if all items in the category list are selected. +export const selectDeselectHandler = ( + selectedItems: string[], + categoryList: MapSupportedList[] +): boolean => + categoryList.every((category) => selectedItems.includes(category.name)); diff --git a/widget/playground/src/components/MultiList/MultiList.styles.ts b/widget/playground/src/components/MultiList/MultiList.styles.ts new file mode 100644 index 0000000000..38991b97e0 --- /dev/null +++ b/widget/playground/src/components/MultiList/MultiList.styles.ts @@ -0,0 +1,59 @@ +import { ListItemButton, styled, Typography } from '@rango-dev/ui'; + +export const HeaderContainer = styled('div', { + display: 'flex', + justifyContent: 'space-between', + alignItems: 'center', + paddingTop: '$10', + '& .header': { + display: 'flex', + alignItems: 'center', + }, +}); + +export const SelectButton = styled('div', { + padding: '$4', + display: 'flex', + justifyContent: 'flex-end', + cursor: 'pointer', + textTransform: 'capitalize', +}); + +export const SelectDeselectText = styled(Typography, { + variants: { + disabled: { + true: {}, + false: { + '&:hover': { + color: '$secondary500', + }, + }, + }, + }, +}); + +export const CheckList = styled('div', { + overflow: 'auto', + height: '90%', + paddingRight: '$5', + marginBottom: '$32', +}); + +export const ItemDivider = styled('li', { + margin: '0 auto', + width: '100%', + height: '1px', + backgroundColor: '$neutral300', +}); + +export const IconWrapper = styled('div', { + width: '$24', + height: '$24', + display: 'flex', + alignItems: 'center', + justifyContent: 'center', +}); + +export const StyledListItemButton = styled(ListItemButton, { + height: '$46', +}); diff --git a/widget/playground/src/components/MultiList/MultiList.tsx b/widget/playground/src/components/MultiList/MultiList.tsx new file mode 100644 index 0000000000..906ab9f544 --- /dev/null +++ b/widget/playground/src/components/MultiList/MultiList.tsx @@ -0,0 +1,192 @@ +import type { MultiListPropTypes } from './MultiList.types'; + +import { + Checkbox, + Divider, + Image, + NotFound, + SelectableCategoryList, + Typography, +} from '@rango-dev/ui'; +import React, { useState } from 'react'; + +import { useMetaStore } from '../../store/meta'; +import { SearchInput } from '../SearchInput'; +import { EmptyContainer, StyledButton } from '../SingleList/SingleList.styles'; + +import { selectDeselectHandler } from './MultiList.helper'; +import { + CheckList, + HeaderContainer, + ItemDivider, + SelectButton, + SelectDeselectText, + StyledListItemButton, +} from './MultiList.styles'; + +export function MultiList(props: MultiListPropTypes) { + const { + defaultSelectedItems, + list, + icon, + label, + type, + onChange, + showCategory, + } = props; + const [category, setCategory] = useState('ALL'); + const [searchValue, setSearchValue] = useState(''); + const [selectedItems, setSelectedItems] = useState( + defaultSelectedItems || [] + ); + const { blockchains } = useMetaStore.use.meta(); + + // Filter the list based on search input + const filteredList = searchValue + ? list.filter((item) => + item.title.toLowerCase().includes(searchValue.toLowerCase()) + ) + : list; + + // Filter the list based on selected category + const categoryList = + category === 'ALL' || !showCategory + ? filteredList + : filteredList.filter((item) => + item.supportedNetworks?.includes(category) + ); + + // Handle item selection/unselection + const handleChangeList = (item: string) => { + const list = [...selectedItems]; + const updatedList = list.includes(item) + ? list.filter((i) => i !== item) + : [...list, item]; + setSelectedItems(updatedList); + }; + + // Select or deselect all items in the category list + const handleAllSelectedClick = (type: 'select' | 'deselect') => () => { + const categoryListTypes = categoryList.map((c) => c.name); + if (type === 'select') { + const newSelectedItems = Array.from( + new Set([...selectedItems, ...categoryListTypes]) + ); + setSelectedItems(newSelectedItems); + } else { + const filteredCategories = selectedItems.filter( + (item) => !categoryListTypes.includes(item) + ); + setSelectedItems(filteredCategories); + } + }; + + const handleConfirm = () => { + onChange(selectedItems.length === list.length ? undefined : selectedItems); + }; + + // Mapping the items to their respective components + const items = categoryList.map((item, index) => { + const { logo, title, name } = item; + const id = title + index; + return { + start: , + onClick: () => handleChangeList(name), + end: , + title: ( + + {title} + + ), + id, + }; + }); + + const resultsNotFound = !items.length && !!searchValue; + const isAllCategorySelected = React.useMemo( + () => selectDeselectHandler(selectedItems, categoryList), + [selectedItems, categoryList] + ); + return ( + <> + +
+ {icon} + + + {label} + +
+ + {`${selectedItems.length}/${list.length}`} + +
+ + {showCategory && ( + <> + + + + )} + setSearchValue(value)} + /> + + {resultsNotFound ? ( + + + + ) : ( + <> + + + {isAllCategorySelected ? 'Deselect all' : 'Select all'} + + + + + {items.map((item) => { + return ( + + + + + ); + })} + + + )} + + {!resultsNotFound && ( + + Confirm + + )} + + ); +} diff --git a/widget/playground/src/components/MultiList/MultiList.types.ts b/widget/playground/src/components/MultiList/MultiList.types.ts new file mode 100644 index 0000000000..b0f7aac1ad --- /dev/null +++ b/widget/playground/src/components/MultiList/MultiList.types.ts @@ -0,0 +1,7 @@ +import type { CommonListProps } from '../MultiSelect/MultiSelect.types'; + +export type MultiListPropTypes = { + label: string; + icon: React.ReactNode; + showCategory?: boolean; +} & CommonListProps; diff --git a/widget/playground/src/components/MultiList/index.ts b/widget/playground/src/components/MultiList/index.ts new file mode 100644 index 0000000000..4de9e3ea87 --- /dev/null +++ b/widget/playground/src/components/MultiList/index.ts @@ -0,0 +1 @@ +export { MultiList } from './MultiList'; diff --git a/widget/playground/src/components/MultiSelect/Container.tsx b/widget/playground/src/components/MultiSelect/Container.tsx deleted file mode 100644 index 917b798d1c..0000000000 --- a/widget/playground/src/components/MultiSelect/Container.tsx +++ /dev/null @@ -1,52 +0,0 @@ -import React, { PropsWithChildren } from 'react'; -import { Button, InfoCircleIcon, Spacer, styled, Typography } from '@rango-dev/ui'; -import { useMetaStore } from '../../store/meta'; -type PropTypes = { - label: string; - onOpenModal: () => void; -}; - -const Head = styled('div', { - display: 'flex', - justifyContent: 'space-between', - alignItems: 'center', -}); - -const Body = styled('div', { - maxHeight: 150, - overflow: 'hidden auto', -}); - -const Row = styled('div', { - display: 'flex', - flexWrap: 'wrap', - maxHeight: 120, - overflow: 'auto', -}); - -export function Container({ label, onOpenModal, children }: PropsWithChildren) { - const loadingStatus = useMetaStore.use.loadingStatus(); - - return ( -
- - - {label} - - - - - - {children} -
- ); -} diff --git a/widget/playground/src/components/MultiSelect/ModalContent.tsx b/widget/playground/src/components/MultiSelect/ModalContent.tsx deleted file mode 100644 index cdd61b33fc..0000000000 --- a/widget/playground/src/components/MultiSelect/ModalContent.tsx +++ /dev/null @@ -1,77 +0,0 @@ -import React from 'react'; -import { Button, FilledCircle, SecondaryPage, styled, Typography } from '@rango-dev/ui'; -import { WalletType } from '@rango-dev/wallets-shared'; -import { Source, Wallets } from '../../types'; -import { LiquiditySource } from '@rango-dev/ui/dist/types/meta'; -const ListContainer = styled('div', { - display: 'grid', - gap: '.5rem', - gridTemplateColumns: ' repeat(2, minmax(0, 1fr))', - maxHeight: 480, - overflow: 'auto', -}); - -const Image = styled('img', { - width: '1.5rem', - maxHeight: '1.5rem', - marginRight: '$4', -}); - -type PropTypes = - | { - type: 'Wallets'; - selectedList?: WalletType[]; - list: Wallets; - onChange: (wallet: { title: string; logo: string; type: WalletType }) => void; - } - | { - type: 'Sources'; - selectedList?: string[]; - list: LiquiditySource[]; - onChange: (sources: Source) => void; - }; - -const filterList = (list, searchedFor: string) => - list.filter((item) => item.title.toLowerCase().includes(searchedFor.toLowerCase())); - -const getIndex = (list, v, type) => { - switch (type) { - case 'Wallets': - return list.findIndex((item) => item === v); - case 'Sources': - return list.findIndex((item) => item === v); - } -}; - -export default function ModalContent({ type, list, selectedList, onChange }: PropTypes) { - const isSelect = (name: string) => { - return !selectedList || getIndex(selectedList, name, type) > -1; - }; - - return ( - - {(searchedFor) => ( - - {filterList(list, searchedFor).map((item, index) => ( - - ))} - - )} - - ); -} diff --git a/widget/playground/src/components/MultiSelect/MultiSelect.styles.ts b/widget/playground/src/components/MultiSelect/MultiSelect.styles.ts new file mode 100644 index 0000000000..d3c4739274 --- /dev/null +++ b/widget/playground/src/components/MultiSelect/MultiSelect.styles.ts @@ -0,0 +1,69 @@ +import { styled } from '@rango-dev/ui'; + +export const Label = styled('div', { + display: 'flex', + alignItems: 'center', +}); + +export const Select = styled('div', { + padding: '$10', + borderRadius: '$xm', + border: '1px solid $neutral300', + backgroundColor: '$background', + + '& .field': { + display: 'flex', + justifyContent: 'space-between', + alignItems: 'center', + }, + '& .chips': { + display: 'flex', + flexWrap: 'wrap', + gap: '$5', + }, + + variants: { + disabled: { + false: { + '&:hover': { + borderColor: '$secondary200', + '& svg': { + color: '$secondary500', + }, + }, + '& .field': { + cursor: 'pointer', + }, + }, + true: { + '& .chips': { + '& div': { + backgroundColor: '$neutral500', + '& span': { + color: '$neutral600', + }, + }, + }, + }, + }, + }, +}); + +export const WalletChip = styled('div', { + borderRadius: '$md', + padding: '1px $10', + display: 'flex', + justifyContent: 'center', + alignItems: 'center', + variants: { + variant: { + contained: { + backgroundColor: '$secondary100', + }, + outlined: { + backgroundColor: 'transparent', + border: '1px solid $secondary500', + }, + }, + }, +}); diff --git a/widget/playground/src/components/MultiSelect/MultiSelect.tsx b/widget/playground/src/components/MultiSelect/MultiSelect.tsx new file mode 100644 index 0000000000..b0d8e44234 --- /dev/null +++ b/widget/playground/src/components/MultiSelect/MultiSelect.tsx @@ -0,0 +1,107 @@ +import type { + MuliSelectPropTypes, + MultiSelectChipProps, +} from './MultiSelect.types'; + +import { + ChainsIcon, + ChevronRightIcon, + Divider, + Typography, + WalletIcon, +} from '@rango-dev/ui'; +import React, { useState } from 'react'; + +import { MultiList } from '../MultiList'; +import { OverlayPanel } from '../OverlayPanel'; +import { TokensPanel } from '../TokensPanel'; + +import { Label, Select, WalletChip } from './MultiSelect.styles'; + +const MAX_CHIPS = 4; +const Chip = (props: MultiSelectChipProps) => { + const { label, variant = 'contained' } = props; + return ( + + + {label} + + + ); +}; + +export function MultiSelect(props: MuliSelectPropTypes) { + const [showNextModal, setShowNextModal] = useState(false); + const { label, type, value, list, disabled } = props; + const valueAll = !value; + const noneSelected = !valueAll && !value.length; + const hasValue = !valueAll; + const showMore = hasValue && value.length > MAX_CHIPS; + const onBack = () => setShowNextModal(false); + const onOpenNextModal = () => { + if (!disabled) { + setShowNextModal(true); + } + }; + + return ( + <> + + + + {showNextModal && ( + + {type !== 'Tokens' ? ( + + ) : ( + + ) + } + onChange={(items) => { + props.onChange(items); + onBack(); + }} + label={label} + /> + ) : ( + { + props.onChange(selectedTokens, pinnedTokens); + onBack(); + }} + selectedBlockchains={props.selectedBlockchains} + /> + )} + + )} + + ); +} diff --git a/widget/playground/src/components/MultiSelect/MultiSelect.types.ts b/widget/playground/src/components/MultiSelect/MultiSelect.types.ts new file mode 100644 index 0000000000..03008e4342 --- /dev/null +++ b/widget/playground/src/components/MultiSelect/MultiSelect.types.ts @@ -0,0 +1,38 @@ +import type { TokenType } from '../TokensPanel/TokensPanel.types'; +import type { Tokens } from '@rango-dev/widget-embedded'; + +export interface CommonListProps { + type: 'Chains' | 'Bridges' | 'DEXs' | 'Wallets'; + defaultSelectedItems: string[]; + list: MapSupportedList[]; + onChange: (items?: string[]) => void; +} + +interface TokensListProps { + type: 'Tokens'; + list: TokenType[]; + selectedBlockchains: string[]; + onChange: ( + selectedTokens?: { [blockchain: string]: Tokens }, + pinnedTokens?: TokenType[] + ) => void; + tokensConfig: { [blockchain: string]: Tokens }; +} +export type MuliSelectPropTypes = (TokensListProps | CommonListProps) & { + value?: string[]; + label: string; + icon: React.ReactNode; + disabled?: boolean; +}; + +export interface MultiSelectChipProps { + label: string; + variant?: 'contained' | 'outlined'; +} + +export type MapSupportedList = { + title: string; + logo: string; + name: string; + supportedNetworks?: string[]; +}; diff --git a/widget/playground/src/components/MultiSelect/MultiTokenSelect.tsx b/widget/playground/src/components/MultiSelect/MultiTokenSelect.tsx deleted file mode 100644 index 88effede9a..0000000000 --- a/widget/playground/src/components/MultiSelect/MultiTokenSelect.tsx +++ /dev/null @@ -1,229 +0,0 @@ -import React, { useState } from 'react'; -import { - Button, - Checkbox, - Chip, - Modal, - SecondaryPage, - Spacer, - styled, - TokenList, - Typography, -} from '@rango-dev/ui'; -import { Asset, BlockchainMeta, Token } from 'rango-sdk'; -import { Type } from '../../types'; -import { useConfigStore } from '../../store/config'; -import { Container } from './Container'; -import { filterTokens, tokensAreEqual } from '../../helpers'; - -type PropTypes = { - list: Token[]; - blockchains: BlockchainMeta[]; - label: string; - modalTitle: string; - type: Type; -}; -const Row = styled('div', { - display: 'flex', - flexWrap: 'wrap', - maxHeight: 120, - overflow: 'auto', -}); - -const EmptyContent = styled('div', { - textAlign: 'center', - marginTop: '20%', -}); -const Content = styled('div', { - display: 'flex', - flexDirection: 'column', -}); - - -export function MultiTokenSelect({ label, modalTitle, list, blockchains, type }: PropTypes) { - const [open, setOpen] = useState(false); - const [chain, setChain] = useState(''); - const [selectTokens, setSelectTokens] = useState({}); - const fromTokens = useConfigStore.use.config().from.tokens; - const toTokens = useConfigStore.use.config().to.tokens; - const onChangeTokens = useConfigStore.use.onChangeTokens(); - const tokens = type === 'Source' ? fromTokens : toTokens; - - const onChangeSelectList = (token: Asset) => { - const select = { ...selectTokens }; - if (select[chain]) { - const index = select[chain].findIndex((item) => tokensAreEqual(item, token)); - if (index === -1) { - select[chain].push(token); - } else { - select[chain].splice(index, 1); - } - } else { - select[chain] = [ - { - blockchain: token.blockchain, - address: token.address, - symbol: token.symbol, - }, - ]; - } - - let values = !!tokens ? [...tokens] : []; - const index = values.findIndex( - (item) => item.symbol === token.symbol && item.address === token.address, - ); - if (index === -1) { - values.push(token); - } else { - values.splice(index, 1); - } - setSelectTokens(select); - onChangeTokens(values, type); - }; - - const onClickSelectAll = (listOfToken) => { - let values = !!tokens ? [...tokens] : []; - const select = selectTokens; - if (selectTokens[chain] && selectTokens[chain].length === listOfToken.length) { - select[chain] = []; - for (const item of listOfToken) { - const index = values.findIndex( - (v) => v.symbol === item.symbol && v.address === item.address, - ); - if (index !== -1) values.splice(index, 1); - } - } else { - for (const item of listOfToken) { - select[chain] = listOfToken; - const index = values.findIndex( - (v) => v.symbol === item.symbol && v.address === item.address, - ); - if (index === -1) values.push(item); - } - } - setSelectTokens(select); - onChangeTokens(values, type); - }; - - const onClose = () => { - if (!!tokens && (!tokens.length || tokens.length === list.length)) { - onChangeTokens(undefined, type); - } - setOpen(false); - }; - return ( -
- setOpen(true)}> - {!!tokens && tokens.length ? ( - <> - {[...tokens].splice(0, 10).map((v) => ( - - ))} - setOpen(true)} - /> - - ) : ( - - )} - - - { - if (checked) { - setChain(''); - onChangeTokens(undefined, type); - } else { - onChangeTokens([], type); - setChain(blockchains[0].name); - } - }} - id="all_Tokens" - label="Select All Tokens" - checked={!tokens} - /> - } - open={open} - onClose={onClose} - content={ - - {(searchedFor) => { - const filterList = list.filter((token) => token.blockchain === chain); - - return ( - <> - - {blockchains.map((blockchain) => ( - <> - - - ))} - - - - {!tokens ? ( - - All tokens are selected - - ) : ( - <> - - - onChangeSelectList({ - blockchain: token.blockchain, - address: token.address, - symbol: token.symbol, - }) - } - /> - - )} - - ); - }} - - } - title={modalTitle} - containerStyle={{ width: '560px', maxHeight: '775px', minHeight: '665px' }} - /> -
- ); -} diff --git a/widget/playground/src/components/MultiSelect/index.ts b/widget/playground/src/components/MultiSelect/index.ts new file mode 100644 index 0000000000..7140f36c68 --- /dev/null +++ b/widget/playground/src/components/MultiSelect/index.ts @@ -0,0 +1 @@ +export { MultiSelect } from './MultiSelect'; diff --git a/widget/playground/src/components/MultiSelect/index.tsx b/widget/playground/src/components/MultiSelect/index.tsx deleted file mode 100644 index f544a09e5f..0000000000 --- a/widget/playground/src/components/MultiSelect/index.tsx +++ /dev/null @@ -1,128 +0,0 @@ -import React, { useState } from 'react'; -import { BlockchainSelector, Button, Chip, CloseIcon, Modal } from '@rango-dev/ui'; -import { LiquiditySource } from '@rango-dev/ui/dist/types/meta'; -import { Source, Wallets } from '../../types'; -import { WalletType } from '@rango-dev/wallets-shared'; -import { BlockchainMeta } from 'rango-sdk'; -import { useMetaStore } from '../../store/meta'; -import { Container } from './Container'; -import ModalContent from './ModalContent'; - -type PropTypes = ( - | { - type: 'Blockchains'; - value?: string[]; - list: BlockchainMeta[]; - onChange: (chain: string | 'all' | 'empty') => void; - } - | { - type: 'Wallets'; - value?: WalletType[]; - list: Wallets; - onChange: (wallet: WalletType | 'all' | 'empty') => void; - } - | { - type: 'Sources'; - value?: string[]; - list: LiquiditySource[]; - onChange: (source: string | 'all' | 'empty') => void; - } -) & { - label: string; - modalTitle: string; -}; - -export function MultiSelect({ label, type, modalTitle, list, value, onChange }: PropTypes) { - const [open, setOpen] = useState(false); - const loadingStatus = useMetaStore.use.loadingStatus(); - const { blockchains } = useMetaStore.use.meta(); - - const onClickAction = () => { - if (!value) onChange('empty'); - else onChange('all'); - }; - - const onClose = () => { - if (!value || !value.length) onChange('all'); - setOpen(false); - }; - const renderModalContent = () => { - switch (type) { - case 'Blockchains': - return ( - value.includes(chain.name)) - } - onChange={(blockchain) => onChange(blockchain.name)} - loadingStatus={loadingStatus} - /> - ); - case 'Sources': - return ( - onChange(item.title)} - selectedList={value} - type={type} - /> - ); - case 'Wallets': - return ( - onChange(item.type)} - selectedList={value} - type={type} - /> - ); - } - }; - - const getLabel = (value) => { - switch (type) { - case 'Blockchains': - return value; - case 'Wallets': - case 'Sources': - return value; - } - }; - return ( -
- setOpen(true)}> - {!value ? ( - - ) : !value.length ? ( - - ) : ( - value.map((v) => ( - } - onClick={() => onChange(v)} - /> - )) - )} - - - - {!value ? 'Deselect All' : 'Select All'} - - } - open={open} - onClose={onClose} - content={renderModalContent()} - title={modalTitle} - containerStyle={{ width: '560px', height: '655px' }} - /> -
- ); -} diff --git a/widget/playground/src/components/OverlayPanel/OverlayPanel.styles.ts b/widget/playground/src/components/OverlayPanel/OverlayPanel.styles.ts new file mode 100644 index 0000000000..a9949f6e1a --- /dev/null +++ b/widget/playground/src/components/OverlayPanel/OverlayPanel.styles.ts @@ -0,0 +1,35 @@ +import { styled } from '@rango-dev/ui'; + +export const Container = styled('div', { + display: 'flex', + flexDirection: 'column', + position: 'relative', + height: '100%', +}); +export const Header = styled('div', { + display: 'flex', + padding: '$5', + alignItems: 'center', + width: '70px', + cursor: 'pointer', + '&:hover': { + '& ._text, svg': { + color: '$secondary500', + }, + }, +}); + +export const Layout = styled('div', { + borderRadius: '20px', + display: 'flex', + padding: '$15', + backgroundColor: '$background', + width: '338px', + height: '100%', + flexDirection: 'column', + position: 'absolute', + zIndex: 1, + top: 0, + left: 0, + zIndex: '1', +}); diff --git a/widget/playground/src/components/OverlayPanel/OverlayPanel.tsx b/widget/playground/src/components/OverlayPanel/OverlayPanel.tsx new file mode 100644 index 0000000000..f7895dcab9 --- /dev/null +++ b/widget/playground/src/components/OverlayPanel/OverlayPanel.tsx @@ -0,0 +1,26 @@ +import type { PropTypes } from './OverlayPanel.types'; +import type { PropsWithChildren } from 'react'; + +import { ChevronLeftIcon, Divider, Typography } from '@rango-dev/ui'; +import React from 'react'; + +import { Container, Header, Layout } from './OverlayPanel.styles'; + +export function OverlayPanel(props: PropsWithChildren) { + const { onBack, children } = props; + return ( + + +
+ + + + back + +
+ + {children} +
+
+ ); +} diff --git a/widget/playground/src/components/OverlayPanel/OverlayPanel.types.ts b/widget/playground/src/components/OverlayPanel/OverlayPanel.types.ts new file mode 100644 index 0000000000..212059b219 --- /dev/null +++ b/widget/playground/src/components/OverlayPanel/OverlayPanel.types.ts @@ -0,0 +1,3 @@ +export interface PropTypes { + onBack: () => void; +} diff --git a/widget/playground/src/components/OverlayPanel/index.ts b/widget/playground/src/components/OverlayPanel/index.ts new file mode 100644 index 0000000000..5ffcb46a34 --- /dev/null +++ b/widget/playground/src/components/OverlayPanel/index.ts @@ -0,0 +1 @@ +export { OverlayPanel } from './OverlayPanel'; diff --git a/widget/playground/src/components/SearchInput/SearchInput.styles.ts b/widget/playground/src/components/SearchInput/SearchInput.styles.ts new file mode 100644 index 0000000000..ed9a301228 --- /dev/null +++ b/widget/playground/src/components/SearchInput/SearchInput.styles.ts @@ -0,0 +1,30 @@ +import { darkTheme, styled } from '@rango-dev/ui'; + +export const IconWrapper = styled('div', { + width: '$24', + height: '$24', + display: 'flex', + alignItems: 'center', + justifyContent: 'center', +}); + +export const InputContainer = styled('div', { + '._text-field': { + padding: 10, + borderRadius: 25, + alignItems: 'center', + '._icon-button': { + display: 'none', + }, + '&:hover': { + $$color: '$colors$neutral100', + [`.${darkTheme} &`]: { + $$color: '$colors$neutral300', + }, + backgroundColor: '$$color', + '._icon-button': { + display: 'unset', + }, + }, + }, +}); diff --git a/widget/playground/src/components/SearchInput/SearchInput.tsx b/widget/playground/src/components/SearchInput/SearchInput.tsx new file mode 100644 index 0000000000..9aee5e482b --- /dev/null +++ b/widget/playground/src/components/SearchInput/SearchInput.tsx @@ -0,0 +1,35 @@ +import type { PropTypes } from './SearchInput.types'; + +import { CloseIcon, IconButton, SearchIcon, TextField } from '@rango-dev/ui'; +import React from 'react'; + +import { IconWrapper, InputContainer } from './SearchInput.styles'; + +export function SearchInput(props: PropTypes) { + const { fullWidth, color, size, value, setValue, ...inputAttributes } = props; + + return ( + + setValue(e.target.value)} + value={value} + variant="contained" + prefix={ + + + + } + suffix={ + setValue('')} + size="small"> + + + } + {...inputAttributes} + /> + + ); +} diff --git a/widget/playground/src/components/SearchInput/SearchInput.types.ts b/widget/playground/src/components/SearchInput/SearchInput.types.ts new file mode 100644 index 0000000000..cc71cdd01b --- /dev/null +++ b/widget/playground/src/components/SearchInput/SearchInput.types.ts @@ -0,0 +1,12 @@ +import type React from 'react'; + +export type PropTypes = { + fullWidth?: boolean; + color?: 'dark' | 'light'; + size?: 'small' | 'large'; + value: string; + setValue: (value: string) => void; +} & Omit< + React.InputHTMLAttributes, + 'size' | 'value' | 'onChange' +>; diff --git a/widget/playground/src/components/SearchInput/index.ts b/widget/playground/src/components/SearchInput/index.ts new file mode 100644 index 0000000000..98d12ff5f1 --- /dev/null +++ b/widget/playground/src/components/SearchInput/index.ts @@ -0,0 +1 @@ +export { SearchInput } from './SearchInput'; diff --git a/widget/playground/src/components/Select.tsx b/widget/playground/src/components/Select.tsx deleted file mode 100644 index 9851237ecc..0000000000 --- a/widget/playground/src/components/Select.tsx +++ /dev/null @@ -1,91 +0,0 @@ -import { - AngleDownIcon, - Button, - CheckIcon, - Modal, - SecondaryPage, - styled, - Typography, -} from '@rango-dev/ui'; -import React, { useState } from 'react'; - -interface PropTypes { - onChange: (name: string, value: string) => void; - label: string; - value: string; - modalTitle: string; - name: string; - list: Array<{ - name: string; - logo?: string; - value: string; - }>; -} -const filterList = (list, searchedFor: string) => - list.filter((item) => item.name.toLowerCase().includes(searchedFor.toLowerCase())); -const Image = styled('img', { - width: '24px', - height: '24px', - marginRight: '$4', - borderRadius: '12px', -}); - -const Label = styled('label', { - display: 'inline-block', - fontSize: '$14', - marginBottom: '$4', - color: '$foreground', -}); - -export function Select({ label, value, onChange, modalTitle, list, name }: PropTypes) { - const [open, setOpen] = useState(false); - const search = list.find((item) => item.value === value); - - return ( -
- - - - - setOpen((prev) => !prev)} - content={ - - {(searchedFor) => - filterList(list, searchedFor).map((item, index) => ( - <> - -
- - )) - } -
- } - title={modalTitle} - containerStyle={{ width: '560px', height: '655px' }} - /> -
- ); -} diff --git a/widget/playground/src/components/SideNavigation/SideNavigation.Icon.tsx b/widget/playground/src/components/SideNavigation/SideNavigation.Icon.tsx new file mode 100644 index 0000000000..e53f38b334 --- /dev/null +++ b/widget/playground/src/components/SideNavigation/SideNavigation.Icon.tsx @@ -0,0 +1,23 @@ +import type { IconLinkPropTypes } from './SideNavigation.types'; + +import { Divider, Typography } from '@rango-dev/ui'; +import React from 'react'; + +import { IconLabelContaienr, IconWrapper } from './SideNavigation.styles'; + +export function IconLink(props: IconLinkPropTypes) { + const { icon, label, disabled } = props; + return ( + + {icon} + + + {label} + + + ); +} diff --git a/widget/playground/src/components/SideNavigation/SideNavigation.Tabs.tsx b/widget/playground/src/components/SideNavigation/SideNavigation.Tabs.tsx new file mode 100644 index 0000000000..236039f21f --- /dev/null +++ b/widget/playground/src/components/SideNavigation/SideNavigation.Tabs.tsx @@ -0,0 +1,51 @@ +import type { TabPropTypes } from './SideNavigation.types'; +import type { SIDE_TABS_IDS } from '../../constants'; + +import React, { useState } from 'react'; + +import { Indicator, Tab, TabsContainer } from './SideNavigation.styles'; + +const TAB_HEIGHT = 105; +const Tabs = (props: TabPropTypes) => { + const { variant = 'vertical', tabs, onChange, activeLayout } = props; + const [activeIndex, setActiveIndex] = useState(0); + + const handleTabClick = (tabId: SIDE_TABS_IDS, index: number) => { + onChange(tabId); + setActiveIndex(index); + }; + + return ( + + {variant === 'vertical' && + tabs.map((tab, index) => { + const isActive = activeLayout === tab.id; + const disabled = tab.disabled; + return ( + handleTabClick(tab.id, index) + : undefined + } + css={{ + height: TAB_HEIGHT, + }}> + {tab.content} + + ); + })} + + + // TODO: check horizontal tab + ); +}; + +export default Tabs; diff --git a/widget/playground/src/components/SideNavigation/SideNavigation.styles.ts b/widget/playground/src/components/SideNavigation/SideNavigation.styles.ts new file mode 100644 index 0000000000..dc7a60e738 --- /dev/null +++ b/widget/playground/src/components/SideNavigation/SideNavigation.styles.ts @@ -0,0 +1,71 @@ +import { styled } from '@rango-dev/ui'; + +const Flex = styled('div', { + display: 'flex', + justifyContent: 'center', + alignItems: 'center', +}); + +export const Container = styled('div', { + borderRadius: '20px', + display: 'flex', + justifyContent: 'space-between', + padding: '$46 0 $30', + backgroundColor: '$background', + width: '96px', + height: '100%', + flexDirection: 'column', +}); + +export const IconLabelContaienr = styled(Flex, { + flexDirection: 'column', + padding: '1px 0', +}); + +export const IconWrapper = styled(Flex, { + width: '$32', + height: '$32', +}); + +export const Tab = styled(Flex, { + flexDirection: 'column', + padding: '$15 0', + cursor: 'pointer', + width: '100%', + variants: { + disabled: { + true: { + cursor: 'not-allowed', + '&:hover': { + backgroundColor: 'unset', + }, + }, + }, + }, + '&:hover': { + backgroundColor: '$neutral200', + }, +}); + +export const Indicator = styled('div', { + width: '2px', + backgroundColor: '$secondary500', + position: 'absolute', + transition: 'transform 0.4s ease-in-out', + left: 0, + top: 0, +}); + +export const TabsContainer = styled(Flex, { + flexDirection: 'column', + position: 'relative', + width: '100%', +}); + +export const StyledAnchor = styled('a', { + textDecoration: 'none', + padding: '$15 0', + '&:hover': { + backgroundColor: '$neutral200', + }, +}); diff --git a/widget/playground/src/components/SideNavigation/SideNavigation.tsx b/widget/playground/src/components/SideNavigation/SideNavigation.tsx new file mode 100644 index 0000000000..fd05431dce --- /dev/null +++ b/widget/playground/src/components/SideNavigation/SideNavigation.tsx @@ -0,0 +1,52 @@ +import type { PropTypes } from './SideNavigation.types'; + +import { InfoIcon, SettingsIcon, StyleIcon } from '@rango-dev/ui'; +import React from 'react'; + +import { SIDE_TABS_IDS } from '../../constants'; + +import { IconLink } from './SideNavigation.Icon'; +import { Container, StyledAnchor } from './SideNavigation.styles'; +import Tabs from './SideNavigation.Tabs'; + +const SIDE_NAVIGATION_TABS = [ + { + title: 'Functional Setting', + id: SIDE_TABS_IDS.FUNCTIONAL, + icon: , + }, + { + title: 'Style', + id: SIDE_TABS_IDS.STYLE, + icon: , + }, +]; + +export function SideNavigation(props: PropTypes) { + const { onChange, activeLayout } = props; + + return ( + + { + return { + title: tab.title, + id: tab.id, + content: , + }; + })} + /> + + } + label="Help" + /> + + + ); +} diff --git a/widget/playground/src/components/SideNavigation/SideNavigation.types.ts b/widget/playground/src/components/SideNavigation/SideNavigation.types.ts new file mode 100644 index 0000000000..f5d6a91a77 --- /dev/null +++ b/widget/playground/src/components/SideNavigation/SideNavigation.types.ts @@ -0,0 +1,22 @@ +import type { SIDE_TABS_IDS } from '../../constants'; + +export interface PropTypes { + activeLayout: SIDE_TABS_IDS; + onChange: (id: SIDE_TABS_IDS) => void; +} + +export interface TabPropTypes extends PropTypes { + variant: 'vertical' | 'horizontal'; + tabs: { + content: React.ReactNode; + disabled?: boolean; + title?: string; + id: SIDE_TABS_IDS; + }[]; +} + +export interface IconLinkPropTypes { + icon: React.ReactNode; + label: string; + disabled?: boolean; +} diff --git a/widget/playground/src/components/SideNavigation/index.ts b/widget/playground/src/components/SideNavigation/index.ts new file mode 100644 index 0000000000..3f273a8496 --- /dev/null +++ b/widget/playground/src/components/SideNavigation/index.ts @@ -0,0 +1 @@ +export { SideNavigation } from './SideNavigation'; diff --git a/widget/playground/src/components/SingleList/SingleList.styles.ts b/widget/playground/src/components/SingleList/SingleList.styles.ts new file mode 100644 index 0000000000..34cd388cf4 --- /dev/null +++ b/widget/playground/src/components/SingleList/SingleList.styles.ts @@ -0,0 +1,37 @@ +import { Button, styled } from '@rango-dev/ui'; + +export const HeaderContainer = styled('div', { + display: 'flex', + justifyContent: 'space-between', + alignItems: 'center', + paddingTop: '$10', + '& .header': { + display: 'flex', + alignItems: 'center', + }, +}); + +export const RadioList = styled('div', { + height: '100%', +}); + +export const IconWrapper = styled('div', { + width: '$24', + height: '$24', + display: 'flex', + alignItems: 'center', + justifyContent: 'center', +}); + +export const StyledButton = styled(Button, { + position: 'absolute', + bottom: 10, + width: '100%', +}); + +export const EmptyContainer = styled('div', { + height: '100%', + display: 'flex', + justifyContent: 'center', + alignItems: 'center', +}); diff --git a/widget/playground/src/components/SingleList/SingleList.tsx b/widget/playground/src/components/SingleList/SingleList.tsx new file mode 100644 index 0000000000..c60b0ec7c2 --- /dev/null +++ b/widget/playground/src/components/SingleList/SingleList.tsx @@ -0,0 +1,142 @@ +import type { PropTypes } from './SingleList.types'; + +import { + Divider, + Image, + ListItemButton, + NotFound, + Radio, + RadioRoot, + Typography, + VirtualizedList, +} from '@rango-dev/ui'; +import React, { useEffect, useState } from 'react'; + +import { SearchInput } from '../SearchInput'; + +import { + EmptyContainer, + HeaderContainer, + RadioList, + StyledButton, +} from './SingleList.styles'; + +const PAGE_SIZE = 30; + +export function SingleList(props: PropTypes) { + const { list, onChange, defaultValue, title, icon, searchPlaceholder } = + props; + const [virtualList, setVirtualList] = useState(list); + const [hasNextPage, setHasNextPage] = useState(true); + + const [searchValue, setSearchValue] = useState(''); + const [item, setItem] = useState(''); + const filteredList = searchValue + ? list.filter((item) => + item.name.toLowerCase().includes(searchValue.toLowerCase()) + ) + : list; + + const handleConfirm = () => { + onChange(item); + }; + + useEffect(() => { + setHasNextPage(filteredList.length > virtualList.length); + }, [virtualList.length]); + useEffect(() => { + setVirtualList(filteredList.slice(0, PAGE_SIZE)); + }, [list, searchValue]); + + const loadNextPage = () => { + setVirtualList(list.slice(0, virtualList.length + PAGE_SIZE)); + }; + + const resultsNotFound = !virtualList.length && !!searchValue; + + return ( + <> + +
+ {icon} + + + {title} + +
+
+ + setSearchValue(value)} + /> + + {resultsNotFound ? ( + + + + ) : ( + + + { + const Icon = virtualList[index].Icon; + return ( +
+ + ) : Icon ? ( + + ) : null + } + hasDivider + onClick={() => setItem(virtualList[index].value || '')} + end={} + title={ + + {virtualList[index].name} + + } + key={`${virtualList[index].name}${virtualList[index].value}`} + id={`${virtualList[index].name}${virtualList[index].value}`} + /> +
+ ); + }} + totalCount={virtualList.length} + /> +
+
+ )} + + + {!resultsNotFound && ( + + Confirm + + )} + + ); +} diff --git a/widget/playground/src/components/SingleList/SingleList.types.ts b/widget/playground/src/components/SingleList/SingleList.types.ts new file mode 100644 index 0000000000..97a813a416 --- /dev/null +++ b/widget/playground/src/components/SingleList/SingleList.types.ts @@ -0,0 +1,13 @@ +export interface PropTypes { + title: string; + icon: React.ReactNode; + defaultValue?: string | null; + onChange: (item: string) => void; + list: { + name: string; + value: string | null; + image?: string; + Icon?: React.ComponentType<{ size?: number }>; + }[]; + searchPlaceholder?: string; +} diff --git a/widget/playground/src/components/SingleList/index.ts b/widget/playground/src/components/SingleList/index.ts new file mode 100644 index 0000000000..7f086daba9 --- /dev/null +++ b/widget/playground/src/components/SingleList/index.ts @@ -0,0 +1 @@ +export { SingleList, InnerElementType } from './SingleList'; diff --git a/widget/playground/src/components/Slider/Slider.styles.ts b/widget/playground/src/components/Slider/Slider.styles.ts new file mode 100644 index 0000000000..e1ac55f466 --- /dev/null +++ b/widget/playground/src/components/Slider/Slider.styles.ts @@ -0,0 +1,57 @@ +import { styled } from '@rango-dev/ui'; + +export const SliderContainer = styled('div', { + display: 'flex', + padding: '0 0 0 $10', + flexDirection: 'column', +}); +export const Content = styled('div', { + display: 'flex', + justifyContent: 'space-between', +}); +export const ValueSection = styled('div', { + display: 'flex', + justifyContent: 'center', + alignItems: 'center', + border: '1px solid $neutral300', + borderRadius: '$xs', + padding: '$4', + width: '$32', +}); +export const RangeWrapper = styled('div', { + display: 'flex', + justifyContent: 'center', + alignItems: 'center', + flexGrow: '0.8', + + '& .range': { + width: '100%', + cursor: 'pointer', + }, + '& .range-custom': { + height: '3px', + backgroundColor: '$neutral300', + '-webkit-appearance': 'none', + outline: 'none', + appearance: 'none', + borderRadius: '3px', + + '&::-webkit-slider-thumb': { + '-webkit-appearance': 'none', + appearance: 'none', + width: '10px', + height: '8px', + borderRadius: '2.5px', + backgroundColor: '$secondary500', + transition: '.2s ease-in-out', + }, + + '&::-moz-range-thumb': { + width: '10px', + height: '8px', + borderRadius: '2.5px', + backgroundColor: '$secondary500', + transition: '.2s ease-in-out', + }, + }, +}); diff --git a/widget/playground/src/components/Slider/Slider.tsx b/widget/playground/src/components/Slider/Slider.tsx new file mode 100644 index 0000000000..6384c924cf --- /dev/null +++ b/widget/playground/src/components/Slider/Slider.tsx @@ -0,0 +1,85 @@ +import type { PropTypes } from './Slider.types'; + +import { Typography } from '@rango-dev/ui'; +import React, { useEffect } from 'react'; + +import { DEFAULT_THEME_COLORS, PLAYGROUND_CONTAINER_ID } from '../../constants'; + +import { + Content, + RangeWrapper, + SliderContainer, + ValueSection, +} from './Slider.styles'; + +const MAX_VALUE = 100; +const DEFAULT_COLOR = DEFAULT_THEME_COLORS.light.secondary; +function Slider(props: PropTypes) { + const { + title, + showValue, + value, + onChange, + variant = 'custom', + min, + max = MAX_VALUE, + color = DEFAULT_COLOR, + id, + } = props; + + const progressScript = () => { + const sliderEl = document.querySelector(`#${id}`) as HTMLInputElement; + const sliderValue = parseInt(sliderEl.value); + const mainValue = sliderValue * (MAX_VALUE / (max as number)); + // Get CSS variables + const referenceElement = document.querySelector( + `#${PLAYGROUND_CONTAINER_ID}` + ) as Element; + const sliderActiveColor = color; + const sliderColorInactive = getComputedStyle( + referenceElement + ).getPropertyValue('--colors-secondary100'); + sliderEl.style.background = `linear-gradient(to right, ${sliderActiveColor} ${mainValue}%, ${sliderColorInactive} ${mainValue}%)`; + }; + + useEffect(() => { + progressScript(); + }, [value, color]); + + return ( + + {title && ( + + {title} + + )} + + + + + {showValue && ( + + + {value || 0} + + + )} + + + ); +} + +export default React.memo(Slider); diff --git a/widget/playground/src/components/Slider/Slider.types.ts b/widget/playground/src/components/Slider/Slider.types.ts new file mode 100644 index 0000000000..2d9dd2bd25 --- /dev/null +++ b/widget/playground/src/components/Slider/Slider.types.ts @@ -0,0 +1,13 @@ +import type { ChangeEventHandler } from 'react'; + +export interface PropTypes { + showValue?: boolean; + title?: string; + onChange: ChangeEventHandler; + value?: number; + variant?: 'custom' | 'regular'; + min?: string; + max?: string; + color?: string; + id: string; +} diff --git a/widget/playground/src/components/Slider/index.ts b/widget/playground/src/components/Slider/index.ts new file mode 100644 index 0000000000..0f4a4a25fc --- /dev/null +++ b/widget/playground/src/components/Slider/index.ts @@ -0,0 +1 @@ +export { default as Slider } from './Slider'; diff --git a/widget/playground/src/components/SourcesConfig.tsx b/widget/playground/src/components/SourcesConfig.tsx deleted file mode 100644 index b3de2bde47..0000000000 --- a/widget/playground/src/components/SourcesConfig.tsx +++ /dev/null @@ -1,59 +0,0 @@ -import { Spacer, Typography } from '@rango-dev/ui'; -import { LiquiditySource } from '@rango-dev/ui/dist/types/meta'; -import React from 'react'; -import { onChangeMultiSelects } from '../helpers'; -import { useConfigStore } from '../store/config'; -import { useMetaStore } from '../store/meta'; -import { ConfigurationContainer } from './ChainsConfig'; -import { MultiSelect } from './MultiSelect'; - -export function SourcesConfig() { - const swappers = useMetaStore.use.meta().swappers; - const liquiditySources = useConfigStore.use.config().liquiditySources; - const onChangeSources = useConfigStore.use.onChangeSources(); - const uniqueSwappersGroups: Array = []; - Array.from(new Set(swappers.map((s) => s.swapperGroup))) - .map((swapperGroup) => { - return swappers.find((s) => s.swapperGroup === swapperGroup); - }) - .find((s) => { - if (s) { - for (const type of s.types) { - uniqueSwappersGroups.push({ - title: s.swapperGroup, - logo: s.logo, - type, - selected: false, - }); - } - } - }); - const onChange = (source) => { - const SourceList = uniqueSwappersGroups.map((s) => s.title); - - const values = onChangeMultiSelects( - source, - liquiditySources, - SourceList, - (item) => item === source, - ); - - onChangeSources(values); - }; - return ( - <> - Liquidity sources - - - - - - ); -} diff --git a/widget/playground/src/components/StylesConfig.tsx b/widget/playground/src/components/StylesConfig.tsx deleted file mode 100644 index 44eb83c1af..0000000000 --- a/widget/playground/src/components/StylesConfig.tsx +++ /dev/null @@ -1,202 +0,0 @@ -import { - Checkbox, - ColorPicker, - Spacer, - styled, - Switch, - TextField, - Typography, -} from '@rango-dev/ui'; -import React, { useState } from 'react'; -import { languageS, FONTS } from '../constants'; -import { COLORS, useConfigStore } from '../store/config'; -import { ConfigurationContainer } from './ChainsConfig'; -import { Select } from './Select'; - -const COLORS = [ - { - name: 'background', - label: 'Background', - }, - { - name: 'primary', - label: 'Primary Color', - }, - - { - name: 'foreground', - label: 'Foreground Color', - }, - { - name: 'success', - label: 'Success', - }, - { - name: 'error', - label: 'Error', - }, - { - name: 'warning', - label: 'Warning', - }, -]; -const GridContent = styled('div', { - display: 'grid', - gridTemplateColumns: '1fr', - gap: 12, - '@md': { - gridTemplateColumns: '1fr 1fr', - }, - '@lg': { - gridTemplateColumns: '1fr 1fr 1fr', - }, -}); - -const ThemeContainer = styled('div', { - borderColor: '$neutrals600', - color: '$neutrals500', - border: '1px solid', - height: '$48', - borderRadius: '$5', - display: 'flex', - justifyContent: 'center', - alignItems: 'center', -}); -const Line = styled('div', { - height: '100%', - width: 1, - backgroundColor: '$foreground', -}); -export function StylesConfig() { - // const width = useConfigStore.use.config().theme.width; - // const height = useConfigStore.use.config().theme.height; - const language = useConfigStore.use.config().language; - const borderRadius = useConfigStore.use.config().theme.borderRadius; - const theme = useConfigStore.use.config().theme.mode; - const fontFamily = useConfigStore.use.config().theme.fontFamily; - const colors = useConfigStore.use.config().theme.colors; - - const onChangelanguage = useConfigStore.use.onChangelanguage(); - const onChangeTheme = useConfigStore.use.onChangeTheme(); - const onChangeColors = useConfigStore.use.onChangeColors(); - - const [checkedTheme, setChekedTheme] = useState(true); - return ( -
- Style - - - - - onChangeTheme('fontFamily', value)} - /> -
- - Theme - - - { - if (checked) onChangeTheme('mode', 'auto'); - else onChangeTheme('mode', 'light'); - setChekedTheme(checked); - }} - /> - - - - - Light - - { - if (!checkedTheme) { - let theme; - if (checked) theme = 'dark'; - else theme = 'light'; - onChangeTheme('mode', theme); - } - }} - /> - - Dark - - -
-
- - - {/*
- onChangeTheme('width', parseInt(e.target.value))} - name="width" - value={width} - label="Width" - type="number" - suffix="px" - /> -
*/} - {/*
- onChangeTheme('height', parseInt(e.target.value))} - name="height" - value={height} - label="Height" - type="number" - suffix="px" - /> -
*/} -
- onChangeTheme('borderRadius', parseInt(e.target.value))} - name="borderRadius" - value={borderRadius} - label="Border Radius" - type="number" - suffix="px" - /> -
-
- - -
- - - - {COLORS.map((color) => ( - onChangeColors(color.name as COLORS, c.hex)} - /> - ))} - - -
-
- ); -} diff --git a/widget/playground/src/components/TokenInfo.tsx b/widget/playground/src/components/TokenInfo.tsx deleted file mode 100644 index 281b747920..0000000000 --- a/widget/playground/src/components/TokenInfo.tsx +++ /dev/null @@ -1,224 +0,0 @@ -import React, { useEffect, useState } from 'react'; -import { - AngleDownIcon, - BlockchainSelector, - Button, - InfoCircleIcon, - Modal, - styled, - TextField, - TokenSelector, -} from '@rango-dev/ui'; -import { useMetaStore } from '../store/meta'; -import { useConfigStore } from '../store/config'; -import { Type } from '../types'; -import { tokensAreEqual } from '../helpers'; - -interface PropTypes { - type: Type; -} - -const ImagePlaceholder = styled('span', { - width: '24px', - height: '24px', - backgroundColor: '$neutrals300', - borderRadius: '99999px', -}); -const StyledImage = styled('img', { - width: '24px', -}); -const Container = styled('div', { - display: 'grid', - position: 'relative', - gap: 12, - gridTemplateColumns: '1fr', - '@md': { - gridTemplateColumns: '1fr 1fr', - }, - '@lg': { - gridTemplateColumns: '1fr 1fr 1fr', - }, -}); -const Label = styled('label', { - display: 'inline-block', - fontSize: '$14', - marginBottom: '$4', - color: '$foreground', -}); - -export function TokenInfo({ type }: PropTypes) { - const to = useConfigStore.use.config().to; - const from = useConfigStore.use.config().from; - const amount = useConfigStore.use.config().amount; - - const onChangeAmount = useConfigStore.use.onChangeAmount(); - const onChangeBlockChain = useConfigStore.use.onChangeBlockChain(); - const onChangeToken = useConfigStore.use.onChangeToken(); - const blockchains = useMetaStore.use.meta().blockchains; - const tokens = useMetaStore.use.meta().tokens; - const token = tokens.find((t) => tokensAreEqual(t, type === 'Source' ? from.token : to.token)); - const chain = blockchains.find( - (chain) => chain.name === (type === 'Source' ? from.blockchain : to.blockchain), - ); - const supportedChains = type === 'Source' ? from.blockchains : to.blockchains; - const supportedTokens = type == 'Source' ? from.tokens : to.tokens; - - const [modal, setModal] = useState({ open: false, isChain: false, isToken: false }); - const loadingStatus = useMetaStore.use.loadingStatus(); - - const ItemSuffix = ( -
- {loadingStatus === 'failed' && } - -
- ); - useEffect(() => { - if (!!supportedChains && !!chain && !supportedChains.includes(chain?.name)) { - onChangeBlockChain(undefined, type); - onChangeToken(undefined, type); - } - if ( - !!supportedTokens && - !!token && - !supportedTokens.filter((t) => tokensAreEqual(t, type === 'Source' ? from.token : to.token)) - .length - ) { - onChangeToken(undefined, type); - } - }, [supportedChains, supportedTokens, chain]); - - - return ( - -
- - - -
- -
- - -
- - {type !== 'Destination' ? ( -
- onChangeAmount(parseInt(e.target.value || '0'))} - value={amount} - label="Default Amount" - type="number" - size="large" - /> -
- ) : null} - - - setModal((prev) => ({ - ...prev, - open: false, - })) - } - content={ - modal.isChain ? ( - supportedChains.includes(chain.name)) - : blockchains - } - hasHeader={false} - selected={chain} - onChange={(chain) => { - onChangeBlockChain(chain.name, type); - onChangeToken(undefined, type); - setModal((prev) => ({ - ...prev, - open: !prev.open, - })); - }} - loadingStatus={loadingStatus} - /> - ) : ( - modal.isToken && ( - - supportedTokens.some((supportedToken) => - tokensAreEqual(supportedToken, token), - ), - ) - : tokens - ).filter((token) => token.blockchain === chain?.name)} - hasHeader={false} - // @ts-ignore - selected={token} - onChange={(token) => { - setModal((prev) => ({ - ...prev, - open: !prev.open, - })); - onChangeToken(token, type); - }} - /> - ) - ) - } - title={`Select ${type} Network`} - containerStyle={{ width: '560px', height: '655px' }}> -
- ); -} diff --git a/widget/playground/src/components/TokensPanel/TokensPanel.Chip.tsx b/widget/playground/src/components/TokensPanel/TokensPanel.Chip.tsx new file mode 100644 index 0000000000..e67dfb1d3e --- /dev/null +++ b/widget/playground/src/components/TokensPanel/TokensPanel.Chip.tsx @@ -0,0 +1,36 @@ +import type { BlockchainProps } from './TokensPanel.types'; + +import { Typography } from '@rango-dev/ui'; +import React from 'react'; + +import { ContainerChip } from './TokensPanel.styles'; + +export const BlockchainChip = (props: BlockchainProps) => { + const { label, itemCountLabel, isSelected, onClick } = props; + return ( + + + {label} + + {itemCountLabel !== 0 && ( + + {itemCountLabel} + + )} + + ); +}; diff --git a/widget/playground/src/components/TokensPanel/TokensPanel.List.tsx b/widget/playground/src/components/TokensPanel/TokensPanel.List.tsx new file mode 100644 index 0000000000..4c899a89bd --- /dev/null +++ b/widget/playground/src/components/TokensPanel/TokensPanel.List.tsx @@ -0,0 +1,188 @@ +import type { TokensListProps, TokenType } from './TokensPanel.types'; + +import { + Checkbox, + Divider, + IconButton, + Image, + ListItemButton, + NotFound, + PinIcon, + Switch, + Typography, + VirtualizedList, +} from '@rango-dev/ui'; +import React, { useEffect, useLayoutEffect, useState } from 'react'; + +import { + SelectButton, + SelectDeselectText, +} from '../MultiList/MultiList.styles'; +import { SearchInput } from '../SearchInput'; +import { EmptyContainer } from '../SingleList/SingleList.styles'; + +import { ListContainer, TokensHeaderList } from './TokensPanel.styles'; + +const PAGE_SIZE = 20; +export function TokensList(props: TokensListProps) { + const { + list, + onChange, + onChangeAll, + showSelectedTokens, + setShowSelectedTokens, + isAllSelected, + isExcluded, + } = props; + const [searchValue, setSearchValue] = useState(''); + const [virtualList, setVirtualList] = useState(list); + const [hasNextPage, setHasNextPage] = useState(true); + + // Filter tokens based on search criteria + const filteredTokens = searchValue + ? list.filter((token) => + token.symbol.toLowerCase().includes(searchValue.toLowerCase()) + ) + : list; + + // Tokens to display, either all or selected + const tokensToDisplay = showSelectedTokens + ? filteredTokens.filter((token) => token.checked) + : filteredTokens; + + useEffect(() => { + setHasNextPage(tokensToDisplay.length > virtualList.length); + }, [virtualList.length]); + + useLayoutEffect(() => { + setVirtualList(tokensToDisplay.slice(0, PAGE_SIZE)); + }, [searchValue, showSelectedTokens, list]); + + const loadNextPage = () => { + setVirtualList(tokensToDisplay.slice(0, virtualList.length + PAGE_SIZE)); + }; + + const toggleTokenSelection = (token: TokenType) => { + onChange(token, 'checked'); + }; + + // Toggle displaying selected tokens + const toggleShowSelectedTokens = () => { + setShowSelectedTokens(!showSelectedTokens); + }; + + const resultsNotFound = !virtualList.length && !!searchValue; + + //Change the list of pinned tokens + const togglePinToken = (token: TokenType) => { + onChange(token, 'pinned'); + }; + + return ( + <> + setSearchValue(value)} + /> + + + {resultsNotFound ? ( + + + + ) : ( + <> + + onChangeAll(!isAllSelected)}> + + {isAllSelected ? 'Deselect all' : 'Select all'} + + +
+ + {isExcluded ? 'Excluded' : 'Included'} Tokens + + + +
+
+ + + { + return ( +
+ + ) : null + } + hasDivider + onClick={() => toggleTokenSelection(virtualList[index])} + end={ + <> + {((virtualList[index].checked && !isExcluded) || + (!virtualList[index].checked && isExcluded)) && ( + <> + { + e.stopPropagation(); + togglePinToken(virtualList[index]); + }}> + + + + + )} + + + } + title={ + + {virtualList[index].symbol} + + } + key={`${virtualList[index].symbol}${virtualList[index].address}`} + id={`${virtualList[index].symbol}${virtualList[index].address}`} + /> +
+ ); + }} + totalCount={virtualList.length} + /> +
+ + )} + + + ); +} diff --git a/widget/playground/src/components/TokensPanel/TokensPanel.styles.ts b/widget/playground/src/components/TokensPanel/TokensPanel.styles.ts new file mode 100644 index 0000000000..cbcdb09905 --- /dev/null +++ b/widget/playground/src/components/TokensPanel/TokensPanel.styles.ts @@ -0,0 +1,56 @@ +import { styled } from '@rango-dev/ui'; + +export const BlockchainsList = styled('div', { + maxHeight: '90px', + minHeight: '42px', + border: '1px solid $neutral300', + padding: '$10', + borderRadius: '$xm', + display: 'flex', + flexWrap: 'wrap', + overflow: 'auto', + gap: '$5', +}); + +export const TokensHeaderList = styled('div', { + display: 'flex', + justifyContent: 'space-between', + flexDirection: 'row-reverse', + alignItems: 'center', + '& .select_tokens': { + display: 'flex', + alignItems: 'center', + }, +}); + +export const ContainerChip = styled('div', { + borderRadius: '$md', + padding: '0 $10', + display: 'flex', + border: '1px solid transparent', + justifyContent: 'center', + alignItems: 'center', + height: '$20', + cursor: 'pointer', + gap: '$10', + '&:hover': { + borderColor: '$secondary200', + }, + variants: { + variant: { + selected: { + backgroundColor: '$secondary500', + }, + empty: { + backgroundColor: '$neutral300', + }, + regular: { + backgroundColor: '$secondary100', + }, + }, + }, +}); + +export const ListContainer = styled('div', { + height: '100%', +}); diff --git a/widget/playground/src/components/TokensPanel/TokensPanel.tsx b/widget/playground/src/components/TokensPanel/TokensPanel.tsx new file mode 100644 index 0000000000..356736b24b --- /dev/null +++ b/widget/playground/src/components/TokensPanel/TokensPanel.tsx @@ -0,0 +1,295 @@ +import type { PropTypes, TokenType } from './TokensPanel.types'; +import type { Tokens } from '@rango-dev/widget-embedded'; +import type { Asset } from 'rango-sdk'; + +import { ChainsIcon, Checkbox, Divider, Typography } from '@rango-dev/ui'; +import React, { useState } from 'react'; + +import { areTokensEqual } from '../../utils/common'; +import { + HeaderContainer, + SelectButton, + SelectDeselectText, +} from '../MultiList/MultiList.styles'; +import { StyledButton } from '../SingleList/SingleList.styles'; + +import { BlockchainChip } from './TokensPanel.Chip'; +import { TokensList } from './TokensPanel.List'; +import { BlockchainsList } from './TokensPanel.styles'; + +function getItemCountLabel(chain: string, list: TokenType[]) { + const filteredList = list.filter((item) => item.blockchain === chain); + const checkedCount = filteredList.filter((item) => item.checked).length; + return filteredList.length === checkedCount ? 'All' : checkedCount; +} + +export function TokensPanel(props: PropTypes) { + const { + list: listProps, + selectedBlockchains: selectedBlockchainsProps, + onChange, + tokensConfig, + } = props; + const [selectedBlockchain, setSelectedBlockchain] = useState( + selectedBlockchainsProps[0] + ); + + const [list, setList] = useState(listProps); + + const [supportedTokenList, setSupportedTokenList] = useState( + tokensConfig || {} + ); + const [showSelectedTokens, setShowSelectedTokens] = useState(false); + + const getTokens = ( + selected: boolean, + allTokensInBlockchain: Asset[], + token?: TokenType + ) => { + if (!token) { + return selected ? allTokensInBlockchain : []; + } + const { blockchain, symbol, address } = token; + if (!selected) { + return [ + ...supportedTokenList[blockchain].tokens.filter( + (t) => !areTokensEqual(t, token) + ), + ]; + } + return [ + ...supportedTokenList[blockchain].tokens, + { symbol, address, blockchain }, + ]; + }; + + /* + * This function is designed to operate in two scenarios: + * + * 1. Activating the checkbox by clicking on it. + * 2. Choosing "Select All" for each blockchain. + * + * If the token has been dispatched, it indicates that the checkbox has been selected. + * Conversely, if the token has not been dispatched, it implies that another one option has been chosen. + * The resulting output fulfills our configuration requirements. + */ + + const makeSupportedTokenList = ( + blockchain: string, + tokens: { + [blockchain: string]: Tokens; + }, + selected: boolean, + token?: TokenType + ) => { + const allTokensInBlockchain = list + .filter((item) => item.blockchain === blockchain) + .map(({ symbol, blockchain, address }) => ({ + symbol, + blockchain, + address, + })); + if (supportedTokenList[blockchain]) { + const blockchainTokens = supportedTokenList[blockchain].tokens; + if (!supportedTokenList[blockchain].isExcluded) { + /* + * This condition is for when the select option is true and show that all tokens have been selected. + * If there is a token, it means that one token has been added to the rest of the tokens, so its lenght is equal to all the tokens of that blockchain. + * If there is no token, it means that select all is selected done + */ + if ( + selected && + (blockchainTokens.length + 1 === allTokensInBlockchain.length || + !token) + ) { + const { [blockchain]: deletedKey, ...otherKeys } = tokens; + return otherKeys; + } + } + + return { + ...tokens, + [blockchain]: { + ...tokens[blockchain], + tokens: getTokens(selected, allTokensInBlockchain, token), + }, + }; + } + + return { + ...tokens, + [blockchain]: { + isExcluded: false, + tokens: + !token && !selected + ? [] + : allTokensInBlockchain.filter((t) => !areTokensEqual(t, token)), + }, + }; + }; + + const handleChange = (token: TokenType, type: 'checked' | 'pinned') => { + if (type === 'checked') { + setSupportedTokenList( + makeSupportedTokenList( + selectedBlockchain, + supportedTokenList, + !token.checked, + token + ) + ); + } + setList((prev) => + prev.map((item) => { + if (areTokensEqual(token, item)) { + const pinnedValue = + type === 'checked' && item.checked ? { pinned: false } : {}; + return { ...item, ...pinnedValue, [type]: !item[type] }; + } + return item; + }) + ); + }; + + const handleSelectDeselectInBlockchain = (selected: boolean) => { + const tokenList = { + ...makeSupportedTokenList( + selectedBlockchain, + supportedTokenList, + selected + ), + }; + + setSupportedTokenList(tokenList); + + setList((prev) => + prev.map((item) => { + if (item.blockchain === selectedBlockchain) { + return { ...item, checked: selected }; + } + return item; + }) + ); + }; + const notAllTokensSelected = list.some((item) => !item.checked); + + const handleResetTokens = () => { + if (notAllTokensSelected) { + setSupportedTokenList({}); + setList((prev) => + prev.map((item) => { + return { ...item, checked: true }; + }) + ); + } + }; + + const handleConfirmAllList = () => { + const allPinned = list.filter((item) => item.pinned); + onChange( + supportedTokenList && !Object.keys(supportedTokenList).length + ? undefined + : supportedTokenList, + allPinned + ); + }; + + const onExcludedChange = () => { + const allTokensInBlockchain = list.filter( + (item) => selectedBlockchain === item.blockchain + ); + const tokenList = { + ...supportedTokenList, + [selectedBlockchain]: { + isExcluded: supportedTokenList[selectedBlockchain] + ? !supportedTokenList[selectedBlockchain].isExcluded + : true, + tokens: allTokensInBlockchain + .filter((t) => !t.checked) + .map(({ symbol, blockchain, address }) => ({ + symbol, + blockchain, + address, + })), + }, + }; + setList((prev) => + prev.map((item) => { + if (item.blockchain === selectedBlockchain) { + return { ...item, checked: !item.checked }; + } + return item; + }) + ); + setSupportedTokenList(tokenList); + }; + + return ( + <> + +
+ + + + Supported Tokens + +
+ + + Reset Tokens + + +
+ + + {selectedBlockchainsProps.map((chain) => ( + setSelectedBlockchain(chain)} + isSelected={chain === selectedBlockchain} + /> + ))} + + + + Exclude {selectedBlockchain} Tokens + + } + /> + + token.blockchain === selectedBlockchain)} + onChange={handleChange} + isExcluded={supportedTokenList[selectedBlockchain]?.isExcluded || false} + setShowSelectedTokens={setShowSelectedTokens} + showSelectedTokens={showSelectedTokens} + isAllSelected={getItemCountLabel(selectedBlockchain, list) === 'All'} + onChangeAll={handleSelectDeselectInBlockchain} + /> + + item.checked)} + onClick={handleConfirmAllList}> + Confirm + + + ); +} diff --git a/widget/playground/src/components/TokensPanel/TokensPanel.types.ts b/widget/playground/src/components/TokensPanel/TokensPanel.types.ts new file mode 100644 index 0000000000..7ea341ca41 --- /dev/null +++ b/widget/playground/src/components/TokensPanel/TokensPanel.types.ts @@ -0,0 +1,30 @@ +import type { Tokens } from '@rango-dev/widget-embedded'; +import type { Token } from 'rango-sdk'; + +export type TokenType = Token & { checked?: boolean; pinned?: boolean }; +export interface PropTypes { + list: TokenType[]; + selectedBlockchains: string[]; + onChange: ( + items?: { [blockchain: string]: Tokens }, + pinnedTokens?: TokenType[] + ) => void; + tokensConfig?: { [blockchain: string]: Tokens }; +} + +export interface TokensListProps { + onChange: (item: TokenType, type: 'checked' | 'pinned') => void; + onChangeAll: (selected: boolean) => void; + showSelectedTokens: boolean; + setShowSelectedTokens: (show: boolean) => void; + list: TokenType[]; + isAllSelected: boolean; + isExcluded: boolean; +} + +export interface BlockchainProps { + onClick: () => void; + label: string; + itemCountLabel: 'All' | number; + isSelected: boolean; +} diff --git a/widget/playground/src/components/TokensPanel/index.ts b/widget/playground/src/components/TokensPanel/index.ts new file mode 100644 index 0000000000..43c60f328c --- /dev/null +++ b/widget/playground/src/components/TokensPanel/index.ts @@ -0,0 +1 @@ +export { TokensPanel } from './TokensPanel'; diff --git a/widget/playground/src/components/WalletsConfig.tsx b/widget/playground/src/components/WalletsConfig.tsx deleted file mode 100644 index 475f7c2d45..0000000000 --- a/widget/playground/src/components/WalletsConfig.tsx +++ /dev/null @@ -1,59 +0,0 @@ -import { Checkbox, Spacer, Typography } from '@rango-dev/ui'; -import { useWallets } from '@rango-dev/wallets-core'; -import { WalletType } from '@rango-dev/wallets-shared'; -import React from 'react'; -import { excludedWallets, onChangeMultiSelects } from '../helpers'; -import { useConfigStore } from '../store/config'; -import { ConfigurationContainer } from './ChainsConfig'; -import { MultiSelect } from './MultiSelect'; - -export function WalletsConfig() { - const { getWalletInfo } = useWallets(); - - const wallets = useConfigStore.use.config().wallets; - const multiWallets = useConfigStore.use.config().multiWallets; - - const onChangeWallets = useConfigStore.use.onChangeWallets(); - const onChangeBooleansConfig = useConfigStore.use.onChangeBooleansConfig(); - - const walletList = Object.values(WalletType) - .filter((wallet) => !excludedWallets.includes(wallet)) - .map((type) => { - const { name: title, img: logo } = getWalletInfo(type); - return { - title, - logo, - type, - }; - }); - - const onChange = (wallet) => { - const list = walletList.map((item) => item.type); - const values = onChangeMultiSelects(wallet, wallets, list, (item) => item === wallet); - onChangeWallets(values); - }; - - return ( - <> - Wallet - - - - - onChangeBooleansConfig('multiWallets', checked)} - id="multi_wallets" - label="Enable Multi Wallets Simultaneously" - checked={multiWallets} - /> - - - ); -} diff --git a/widget/playground/src/configs.ts b/widget/playground/src/configs.ts deleted file mode 100644 index a59981cda9..0000000000 --- a/widget/playground/src/configs.ts +++ /dev/null @@ -1,32 +0,0 @@ -export interface Configs { - API_KEY: string; -} - -// this API key is limited and -// it is only for test purpose -const RANGO_PUBLIC_API_KEY = 'c6381a79-2817-4602-83bf-6a641a409e32'; - -let configs: Configs = { - API_KEY: RANGO_PUBLIC_API_KEY, -}; - -export function getConfig(name: keyof Configs) { - return configs[name]; -} - -export function setConfig(name: keyof Configs, value: any) { - configs[name] = value; - - return value; -} - -export function initConfig(nextConfigs: Configs) { - let clonedConfigs; - if (typeof structuredClone === 'function') { - clonedConfigs = structuredClone(nextConfigs); - } else { - clonedConfigs = JSON.parse(JSON.stringify(nextConfigs)); - } - configs = clonedConfigs; - return configs; -} diff --git a/widget/playground/src/constants.ts b/widget/playground/src/constants.ts deleted file mode 100644 index c9d1041459..0000000000 --- a/widget/playground/src/constants.ts +++ /dev/null @@ -1,27 +0,0 @@ -export const languageS = [ - { - name: 'English (US)', - logo: 'https://upload.wikimedia.org/wikipedia/en/thumb/a/a4/Flag_of_the_United_States.svg/800px-Flag_of_the_United_States.svg.png?20151118161041', - value: 'en', - }, - { - name: 'Turkish', - logo: 'https://upload.wikimedia.org/wikipedia/commons/thumb/b/b4/Flag_of_Turkey.svg/800px-Flag_of_Turkey.svg.png', - value: 'tr', - }, -]; - -export const FONTS = [ - { - name: 'Roboto', - value: 'Roboto', - }, - { - name: 'Times New Roman', - value: 'Times New Roman', - }, - { - name: 'Arial', - value: 'Arial', - }, -]; diff --git a/widget/playground/src/constants/fonts.ts b/widget/playground/src/constants/fonts.ts new file mode 100644 index 0000000000..492d6da3d3 --- /dev/null +++ b/widget/playground/src/constants/fonts.ts @@ -0,0 +1 @@ +export const DEFAULT_FONT = 'Roboto'; diff --git a/widget/playground/src/constants/index.ts b/widget/playground/src/constants/index.ts new file mode 100644 index 0000000000..6219fb9564 --- /dev/null +++ b/widget/playground/src/constants/index.ts @@ -0,0 +1,12 @@ +export * from './languages'; +export * from './presets'; +export * from './styles'; + +export enum SIDE_TABS_IDS { + FUNCTIONAL = 'functional', + STYLE = 'style', +} + +export const NOT_FOUND = -1; + +export const PLAYGROUND_CONTAINER_ID = 'playgroundContainerId'; diff --git a/widget/playground/src/constants/languages.ts b/widget/playground/src/constants/languages.ts new file mode 100644 index 0000000000..34f2f00726 --- /dev/null +++ b/widget/playground/src/constants/languages.ts @@ -0,0 +1,76 @@ +import { + Bengali, + Catalonia, + Chinese, + Denmark, + English, + Finland, + French, + German, + Greece, + Hungary, + India, + Indonesian, + Italian, + Japanese, + Korea, + Lithuania, + Malay, + Netherlands, + Pakistan, + Philippines, + Poland, + Portuguese, + Russian, + SaudiArabia, + Serbia, + Slovakia, + SouthAfrica, + Spanish, + Swahili, + Swedish, + Thai, + Turkish, + Ukrainian, + Vietnamese, +} from '@rango-dev/ui'; + +export const DEFAULT_LANGUAGE = 'en'; + +export const LANGUAGES = [ + { name: 'Afrikaans', value: 'af', Icon: SouthAfrica }, + { name: 'Arabic', value: 'ar', Icon: SaudiArabia }, + { name: 'Bengali', value: 'bn', Icon: Bengali }, + { name: 'Catalan', value: 'ca', Icon: Catalonia }, + { name: 'Chinese (Simplified)', value: 'zh-CN', Icon: Chinese }, + { name: 'Chinese (Traditional)', value: 'zh-TW', Icon: Chinese }, + { name: 'Danish', value: 'da', Icon: Denmark }, + { name: 'Dutch', value: 'nl', Icon: Netherlands }, + { name: 'English', value: DEFAULT_LANGUAGE, Icon: English }, + { name: 'Filipino', value: 'fil', Icon: Philippines }, + { name: 'Finnish', value: 'fi', Icon: Finland }, + { name: 'French', value: 'fr', Icon: French }, + { name: 'German', value: 'de', Icon: German }, + { name: 'Greek', value: 'el', Icon: Greece }, + { name: 'Hindi', value: 'hi', Icon: India }, + { name: 'Hungarian', value: 'hu', Icon: Hungary }, + { name: 'Indonesian', value: 'id', Icon: Indonesian }, + { name: 'Italian', value: 'it', Icon: Italian }, + { name: 'Japanese', value: 'ja', Icon: Japanese }, + { name: 'Korean', value: 'ko', Icon: Korea }, + { name: 'Lithuanian', value: 'lt', Icon: Lithuania }, + { name: 'Malay', value: 'ms', Icon: Malay }, + { name: 'Polish', value: 'pl', Icon: Poland }, + { name: 'Portuguese', value: 'pt', Icon: Portuguese }, + { name: 'Russian', value: 'ru', Icon: Russian }, + { name: 'Serbian', value: 'sr', Icon: Serbia }, + { name: 'Slovak', value: 'sk', Icon: Slovakia }, + { name: 'Spanish', value: 'es', Icon: Spanish }, + { name: 'Swahili', value: 'sw', Icon: Swahili }, + { name: 'Swedish', value: 'sv', Icon: Swedish }, + { name: 'Thai', value: 'th', Icon: Thai }, + { name: 'Turkish', value: 'tr', Icon: Turkish }, + { name: 'Ukrainian', value: 'uk', Icon: Ukrainian }, + { name: 'Urdu', value: 'ur', Icon: Pakistan }, + { name: 'Vietnamese', value: 'vi', Icon: Vietnamese }, +]; diff --git a/widget/playground/src/constants/presets.ts b/widget/playground/src/constants/presets.ts new file mode 100644 index 0000000000..14938ca774 --- /dev/null +++ b/widget/playground/src/constants/presets.ts @@ -0,0 +1,173 @@ +import type { Mode } from '../store/config'; +import type { PresetType } from '../types'; +import type { + WidgetColors, + WidgetColorsKeys, +} from '@rango-dev/widget-embedded'; + +import { rangoDarkColors } from '@rango-dev/ui'; + +export const DEFAULT_PRESET_ID = 'DEFAULT_THEME_COLORS'; + +export const TABS: { id: Mode; title: string }[] = [ + { + id: 'light', + title: 'Light', + }, + + { + id: 'dark', + title: 'Dark', + }, + + { + id: 'auto', + title: 'System', + }, +]; + +export const PRESETS: PresetType = [ + { + id: 'DEFAULT_THEME_COLORS', + dark: { + primary: '#1C3CF1', + secondary: '#2284ED', + neutral: '#222222', + background: '#010101', + foreground: '#FDFDFD', + }, + light: { + primary: '#1C3CF1', + secondary: '#469BF5', + neutral: '#E6E6E6', + background: '#FDFDFD', + foreground: '#010101', + }, + }, + { + id: 'RANGO_THEME', + dark: { + ...rangoDarkColors, + primary: '#1C3CF1', + secondary: '#2284ED', + }, + light: { + primary: '#1C3CF1', + secondary: '#469BF5', + neutral: '#E6E6E6', + background: '#FDFDFD', + foreground: '#010101', + }, + }, + { + id: 1, + dark: { + primary: '#4c228a', + secondary: '#51278F', + neutral: '#222222', + foreground: '#FDFDFD', + background: '#010101', + }, + light: { + primary: '#4c228a', + secondary: '#51278F', + neutral: '#E6E6E6', + foreground: '#010101', + background: '#FDFDFD', + }, + }, + { + id: 2, + dark: { + foreground: '#FDFDFD', + background: '#010101', + primary: '#bb00b2', + secondary: '#7c1ca4', + neutral: '#222222', + }, + light: { + background: '#FDFDFD', + foreground: '#010101', + primary: '#bb00b2', + secondary: '#7c1ca4', + neutral: '#E6E6E6', + }, + }, + { + id: 3, + dark: { + primary: '#574660', + neutral: '#222222', + secondary: '#a002b0', + background: '#010101', + foreground: '#FDFDFD', + }, + }, + { + id: 4, + dark: { + foreground: '#FDFDFD', + background: '#010101', + secondary: '#6606e6', + primary: '#6606e6', + neutral: '#222222', + }, + light: { + background: '#FDFDFD', + foreground: '#010101', + neutral: '#E6E6E6', + secondary: '#6606e6', + primary: '#6606e6', + }, + }, + { + id: 5, + dark: { + background: '#010101', + primary: '#4838D4', + foreground: '#FDFDFD', + secondary: '#7161ff', + neutral: '#222222', + }, + }, + { + id: 6, + dark: { + background: '#010101', + primary: '#E0C072', + foreground: '#FDFDFD', + secondary: '#B0A385', + neutral: '#222222', + }, + }, +]; + +export const WIDGET_COLORS: { key: WidgetColorsKeys; label: string }[] = [ + { + key: 'primary', + label: 'Primary', + }, + { + key: 'secondary', + label: 'Secondary', + }, + { + key: 'neutral', + label: 'Neutral', + }, + { + key: 'background', + label: 'Background', + }, + { + key: 'foreground', + label: 'Foreground', + }, +]; + +export const DEFAULT_THEME_COLORS = { + dark: PRESETS.find((preset) => preset.id === DEFAULT_PRESET_ID) + ?.dark as WidgetColors, + light: PRESETS.find((preset) => preset.id === DEFAULT_PRESET_ID) + ?.light as WidgetColors, +}; diff --git a/widget/playground/src/constants/styles.ts b/widget/playground/src/constants/styles.ts new file mode 100644 index 0000000000..4051f52b3e --- /dev/null +++ b/widget/playground/src/constants/styles.ts @@ -0,0 +1,9 @@ +export const DEFAULT_PRIMARY_RADIUS = 20; +export const DEFAULT_SECONDARY_RADIUS = 25; + +export const WIDGET_MAX_HEIGHT = 700; +export const WIDGET_VARIANT_MAX_WIDTH = { + default: 390, + expanded: 796, + 'full-expanded': 1125, +}; diff --git a/widget/playground/src/constants/urls.ts b/widget/playground/src/constants/urls.ts new file mode 100644 index 0000000000..45391a438c --- /dev/null +++ b/widget/playground/src/constants/urls.ts @@ -0,0 +1,2 @@ +export const RANGO_DOCS_URL = 'https://docs.rango.exchange/'; +export const RANGO_WEBSITE_URL = 'https://widget.rango.exchange/'; diff --git a/widget/playground/src/constants/variants.ts b/widget/playground/src/constants/variants.ts new file mode 100644 index 0000000000..61caf64edd --- /dev/null +++ b/widget/playground/src/constants/variants.ts @@ -0,0 +1,16 @@ +import type { WidgetVariant } from '@rango-dev/widget-embedded'; + +export const VARIANTS: { label: string; value: WidgetVariant }[] = [ + { + label: 'Default', + value: 'default' as WidgetVariant, + }, + { + label: 'Expanded', + value: 'expanded' as WidgetVariant, + }, + { + label: 'Full Expanded', + value: 'full-expanded' as WidgetVariant, + }, +]; diff --git a/widget/playground/src/containers/BoundaryGuideContainer/BoundaryGuideContainer.styles.ts b/widget/playground/src/containers/BoundaryGuideContainer/BoundaryGuideContainer.styles.ts new file mode 100644 index 0000000000..1552971863 --- /dev/null +++ b/widget/playground/src/containers/BoundaryGuideContainer/BoundaryGuideContainer.styles.ts @@ -0,0 +1,84 @@ +import { styled } from '@rango-dev/ui'; + +import { + WIDGET_MAX_HEIGHT, + WIDGET_VARIANT_MAX_WIDTH, +} from '../../constants/styles'; + +const BOUNDARY_GUIDE_OUTLINE_WIDTH = 2; +const BOUNDARY_SIZE_HEIGHT = 26; + +export const Container = styled('div', { + position: 'relative', + display: 'flex', + justifyContent: 'center', + paddingTop: '40px', + transition: 'width .5s ease-in-out', + margin: 'auto', + height: '100%', + variants: { + variant: { + default: { width: WIDGET_VARIANT_MAX_WIDTH.default }, + expanded: { + width: WIDGET_VARIANT_MAX_WIDTH.expanded, + }, + 'full-expanded': { + width: WIDGET_VARIANT_MAX_WIDTH['full-expanded'], + }, + }, + boundaryVisible: { + true: { + minHeight: + WIDGET_MAX_HEIGHT + + 2 * (BOUNDARY_GUIDE_OUTLINE_WIDTH + BOUNDARY_SIZE_HEIGHT), + }, + false: { + minHeight: WIDGET_MAX_HEIGHT, + }, + }, + }, +}); + +export const BoundaryGuide = styled('div', { + position: 'absolute', + top: '40px', + left: 0, + width: '100%', + outlineStyle: 'dashed', + outlineColor: '$neutral600', + borderRadius: '20px', + display: 'flex', + justifyContent: 'center', + transition: 'height .5s ease-in-out, outline-width .5s ease-in-out', + variants: { + visible: { + true: { + height: WIDGET_MAX_HEIGHT, + outlineWidth: BOUNDARY_GUIDE_OUTLINE_WIDTH, + }, + false: { + height: 0, + outlineWidth: 0, + }, + }, + }, +}); + +export const BoundarySize = styled('div', { + position: 'absolute', + height: BOUNDARY_SIZE_HEIGHT, + display: 'flex', + padding: '$6 0', + variants: { + side: { + bottomLeft: { + left: 0, + bottom: -1 * (BOUNDARY_GUIDE_OUTLINE_WIDTH + BOUNDARY_SIZE_HEIGHT), + }, + topRight: { + top: -1 * (BOUNDARY_GUIDE_OUTLINE_WIDTH + BOUNDARY_SIZE_HEIGHT), + right: 0, + }, + }, + }, +}); diff --git a/widget/playground/src/containers/BoundaryGuideContainer/BoundaryGuideContainer.tsx b/widget/playground/src/containers/BoundaryGuideContainer/BoundaryGuideContainer.tsx new file mode 100644 index 0000000000..0f373c7022 --- /dev/null +++ b/widget/playground/src/containers/BoundaryGuideContainer/BoundaryGuideContainer.tsx @@ -0,0 +1,61 @@ +import type { PropTypes } from './BoundaryGuideContainer.types'; +import type { PropsWithChildren } from 'react'; + +import { + Divider, + HeightIcon, + NotSelectableTypography, + WidthIcon, +} from '@rango-dev/ui'; +import React from 'react'; + +import { WIDGET_VARIANT_MAX_WIDTH } from '../../constants/styles'; +import { VARIANTS } from '../../constants/variants'; +import { useConfigStore } from '../../store/config'; + +import { + BoundaryGuide, + BoundarySize, + Container, +} from './BoundaryGuideContainer.styles'; + +const BoundaryGuideContainer = (props: PropsWithChildren) => { + const { show, children } = props; + const variant = useConfigStore.use.config().variant || VARIANTS[0].value; + + const maxWidth = WIDGET_VARIANT_MAX_WIDTH[variant]; + + return ( + + + {show && ( + + + + + Max Width: {maxWidth} px + + + )} + {show && ( + + + + + Max Height: 700 px + + + )} + + {children} + + ); +}; + +export default BoundaryGuideContainer; diff --git a/widget/playground/src/containers/BoundaryGuideContainer/BoundaryGuideContainer.types.ts b/widget/playground/src/containers/BoundaryGuideContainer/BoundaryGuideContainer.types.ts new file mode 100644 index 0000000000..559fb88346 --- /dev/null +++ b/widget/playground/src/containers/BoundaryGuideContainer/BoundaryGuideContainer.types.ts @@ -0,0 +1,3 @@ +export type PropTypes = { + show: boolean; +}; diff --git a/widget/playground/src/containers/BoundaryGuideContainer/index.ts b/widget/playground/src/containers/BoundaryGuideContainer/index.ts new file mode 100644 index 0000000000..535ab2fc19 --- /dev/null +++ b/widget/playground/src/containers/BoundaryGuideContainer/index.ts @@ -0,0 +1,3 @@ +import BoundaryGuideContainer from './BoundaryGuideContainer'; + +export default BoundaryGuideContainer; diff --git a/widget/playground/src/containers/Config.tsx b/widget/playground/src/containers/Config.tsx deleted file mode 100644 index 73c0496cbb..0000000000 --- a/widget/playground/src/containers/Config.tsx +++ /dev/null @@ -1,69 +0,0 @@ -import React, { PropsWithChildren } from 'react'; -import { Alert, Spacer, styled, Typography } from '@rango-dev/ui'; -import { ChainsConfig } from '../components/ChainsConfig'; -import { WalletsConfig } from '../components/WalletsConfig'; -import { SourcesConfig } from '../components/SourcesConfig'; -import { StylesConfig } from '../components/StylesConfig'; -import { Provider } from '@rango-dev/wallets-core'; -import { allProviders } from '@rango-dev/provider-all'; -import { globalStyles } from '../globalStyles'; -import { useMetaStore } from '../store/meta'; - -const providers = allProviders(); - -const Container = styled('div', { - display: 'flex', - justifyContent: 'center', - backgroundColor: '$neutrals300', -}); -const SwapContent = styled('div', { - width: '100%', -}); -const ConfigContent = styled('div', { - display: 'flex', - flexDirection: 'column', - alignItems: 'end', - width: '100%', -}); - -const Swap = styled('div', { - position: 'sticky', - top: 0, - marginTop: 115, -}); - -export function Config(props: PropsWithChildren) { - globalStyles(); - const loadingStatus = useMetaStore.use.loadingStatus(); - - return ( - - - -
- Configuration - {loadingStatus === 'failed' && ( - - Error connecting server, please reload the app and try again - - )} - - - - - - - - - - -
-
-
- - - {props.children} - -
- ); -} diff --git a/widget/playground/src/containers/DefaultChainAndToken/DefaultChainAndToken.tsx b/widget/playground/src/containers/DefaultChainAndToken/DefaultChainAndToken.tsx new file mode 100644 index 0000000000..382ce8bf9e --- /dev/null +++ b/widget/playground/src/containers/DefaultChainAndToken/DefaultChainAndToken.tsx @@ -0,0 +1,137 @@ +import type { Type } from '../../types'; +import type { tokensConfigType } from '../../utils/configs'; + +import { ChainsIcon, Divider, Tooltip } from '@rango-dev/ui'; +import React, { useState } from 'react'; + +import { ItemPicker } from '../../components/ItemPicker'; +import { OverlayPanel } from '../../components/OverlayPanel'; +import { SingleList } from '../../components/SingleList'; +import { useConfigStore } from '../../store/config'; +import { useMetaStore } from '../../store/meta'; +import { areTokensEqual, tokenToString } from '../../utils/common'; +import { isTokenExcludedInConfig } from '../../utils/configs'; +import { ModalState } from '../FunctionalLayout/FunctionalLayout.types'; + +export function DefaultChainAndToken({ type }: { type: Type }) { + const [modalState, setModalState] = useState(null); + const { + config: { from, to }, + onChangeBlockChain, + onChangeToken, + } = useConfigStore(); + const { + meta: { blockchains, tokens }, + } = useMetaStore(); + + const selectedType = type === 'Source' ? from : to; + const tokensConfig = selectedType?.tokens as tokensConfigType; + const filteredTokens = selectedType?.blockchain + ? tokens.filter((token) => { + const isToken = isTokenExcludedInConfig(token, tokensConfig); + return token.blockchain === selectedType.blockchain && !isToken; + }) + : []; + const chainValue = blockchains.find( + (chain) => chain.name === selectedType?.blockchain + ); + const tokenValue = tokens.find((token) => + areTokensEqual(token, selectedType?.token) + ); + + const handleDefaultBlockchainConfirm = (item: string) => { + if (item) { + onChangeBlockChain(item, type); + onChangeToken(undefined, type); + } + onBack(); + }; + + const handleDefaultTokenConfirm = (item: string) => { + if (item) { + const selectedToken = filteredTokens.find( + (token) => tokenToString(token) === item + ); + if (selectedToken) { + onChangeToken( + { + blockchain: selectedToken.blockchain, + address: selectedToken.address, + symbol: selectedToken.symbol, + }, + type + ); + } + } + onBack(); + }; + + const onBack = () => setModalState(null); + + const filteredBlockchains = selectedType?.blockchains + ? blockchains.filter((chain) => + selectedType.blockchains?.includes(chain.name) + ) + : blockchains; + + return ( + <> + setModalState(ModalState.DEFAULT_BLOCKCHAIN)} + value={{ label: chainValue?.displayName, logo: chainValue?.logo }} + title="Default Chain" + hasLogo={true} + placeholder="Chain" + disabled={!blockchains?.length} + /> + + + setModalState(ModalState.DEFAULT_TOKEN)} + value={{ label: tokenValue?.symbol, logo: tokenValue?.image }} + title="Default Token" + hasLogo={true} + placeholder="Token" + disabled={!chainValue} + /> + + {modalState === ModalState.DEFAULT_BLOCKCHAIN && ( + + ({ + name: chain.displayName, + image: chain.logo, + value: chain.name, + }))} + title="Default Chain" + defaultValue={selectedType?.blockchain} + icon={} + searchPlaceholder="Search Chain" + /> + + )} + {modalState === ModalState.DEFAULT_TOKEN && ( + + ({ + name: token.symbol, + image: token.image, + value: tokenToString(token), + }))} + title="Default Token" + defaultValue={ + selectedType?.token ? tokenToString(selectedType?.token) : null + } + icon={} + searchPlaceholder="Search Token" + /> + + )} + + ); +} diff --git a/widget/playground/src/containers/DefaultChainAndToken/index.ts b/widget/playground/src/containers/DefaultChainAndToken/index.ts new file mode 100644 index 0000000000..5a03ab81d3 --- /dev/null +++ b/widget/playground/src/containers/DefaultChainAndToken/index.ts @@ -0,0 +1 @@ +export { DefaultChainAndToken } from './DefaultChainAndToken'; diff --git a/widget/playground/src/containers/FunctionalLayout/FunctionalLayout.From.tsx b/widget/playground/src/containers/FunctionalLayout/FunctionalLayout.From.tsx new file mode 100644 index 0000000000..829b845574 --- /dev/null +++ b/widget/playground/src/containers/FunctionalLayout/FunctionalLayout.From.tsx @@ -0,0 +1,52 @@ +import type { ChangeEvent } from 'react'; + +import { Divider, TextField, Typography } from '@rango-dev/ui'; +import React from 'react'; + +import { useConfigStore } from '../../store/config'; +import { DefaultChainAndToken } from '../DefaultChainAndToken'; +import { SupportedBlockchains } from '../SupportedBlockchains'; +import { SupportedTokens } from '../SupportedTokens'; + +import { + amountStyles, + FromAmount, + FromToContainer, +} from './FunctionalLayout.styles'; + +export function FromSection() { + const { + config: { amount }, + onChangeAmount, + } = useConfigStore(); + + const handleChangeAmount = (e: ChangeEvent) => { + onChangeAmount(parseFloat(e.target.value || '0')); + }; + + return ( + <> + + + + + + + + + Amount + + + + + + + + ); +} diff --git a/widget/playground/src/containers/FunctionalLayout/FunctionalLayout.Liquidities.tsx b/widget/playground/src/containers/FunctionalLayout/FunctionalLayout.Liquidities.tsx new file mode 100644 index 0000000000..4694a1003b --- /dev/null +++ b/widget/playground/src/containers/FunctionalLayout/FunctionalLayout.Liquidities.tsx @@ -0,0 +1,156 @@ +import type { LiquidityType } from './FunctionalLayout.types'; + +import { ChainsIcon, Checkbox, Divider, Typography } from '@rango-dev/ui'; +import React from 'react'; + +import { MultiSelect } from '../../components/MultiSelect'; +import { useConfigStore } from '../../store/config'; +import { useMetaStore } from '../../store/meta'; +import { removeDuplicates } from '../../utils/common'; + +import { filterByType, getLiquidityValue } from './FunctionalLayout.helpers'; +import { IncludeSourceText } from './FunctionalLayout.styles'; + +export function LiquiditiesSection() { + const { + onChangeSources, + onChangeBooleansConfig, + config: { liquiditySources, excludeLiquiditySources }, + } = useConfigStore(); + + const { + meta: { swappers }, + } = useMetaStore(); + + const excludedMode = excludeLiquiditySources ?? true; + const uniqueSwappersGroup = removeDuplicates(swappers, 'swapperGroup'); + + const defaultSelectedItems = (type: LiquidityType) => + liquiditySources?.filter((l) => + uniqueSwappersGroup.find( + (swapper) => swapper.swapperGroup === l && filterByType(type, swapper) + ) + ); + + const liquiditiesList = (type: LiquidityType) => + uniqueSwappersGroup + .filter((swapper) => filterByType(type, swapper)) + .map(({ title, logo, swapperGroup }) => ({ + logo, + title, + name: swapperGroup, + })); + + const selectedDexs = defaultSelectedItems('DEX'); + const selectedBridges = defaultSelectedItems('BRIDGE'); + const allDexs = liquiditiesList('DEX'); + const allBridges = liquiditiesList('BRIDGE'); + const allDexsNames = allDexs.map((dex) => dex.name); + const allBridgeNames = allBridges.map((bridge) => bridge.name); + const isAllSelected = !liquiditySources; + + const isJustAllBridgeSelected = + !isAllSelected && selectedBridges?.length === allBridges.length; + const isJustAllDexSelected = + !isAllSelected && selectedDexs?.length === allDexs.length; + + const handleChange = ( + categories: string[], + otherCategoryList: string[], + currentSelection?: string[], + previousSelection?: string[] + ) => { + const currentConfig = removeDuplicates([ + ...(liquiditySources || (excludedMode ? [] : otherCategoryList)), + ...categories, + ]); + + let sources; + if (currentSelection) { + sources = removeDuplicates([ + ...(previousSelection || (excludedMode ? [] : otherCategoryList)), + ...currentSelection, + ]); + } else if ( + currentConfig.length === uniqueSwappersGroup.length && + excludedMode + ) { + sources = removeDuplicates([...categories, ...currentConfig]); + } else { + sources = currentConfig; + } + + onChangeSources(sources); + }; + + const handleCheckChange = (checked: boolean) => { + onChangeBooleansConfig('excludeLiquiditySources', checked); + if (checked === false) { + onChangeSources([...allBridgeNames, ...allDexsNames]); + } else { + onChangeSources(undefined); + } + }; + + return ( + <> + } + type="DEXs" + value={getLiquidityValue( + isAllSelected, + excludedMode, + isJustAllDexSelected, + selectedDexs + )} + defaultSelectedItems={ + selectedDexs || (excludedMode ? [] : allDexsNames) + } + list={allDexs} + onChange={(items) => + handleChange(allDexsNames, allBridgeNames, items, selectedBridges) + } + disabled={!swappers?.length} + /> + + } + type="Bridges" + value={getLiquidityValue( + isAllSelected, + excludedMode, + isJustAllBridgeSelected, + selectedBridges + )} + defaultSelectedItems={ + selectedBridges || (excludedMode ? [] : allBridgeNames) + } + list={allBridges} + onChange={(items) => + handleChange(allBridgeNames, allDexsNames, items, selectedDexs) + } + disabled={!swappers?.length} + /> + + + Include New Sources + + } + /> + + + + If we add a new liquidity source, it will be added to your list as + well. + + + + ); +} diff --git a/widget/playground/src/containers/FunctionalLayout/FunctionalLayout.To.tsx b/widget/playground/src/containers/FunctionalLayout/FunctionalLayout.To.tsx new file mode 100644 index 0000000000..d8eed25bac --- /dev/null +++ b/widget/playground/src/containers/FunctionalLayout/FunctionalLayout.To.tsx @@ -0,0 +1,24 @@ +import { Divider } from '@rango-dev/ui'; +import React from 'react'; + +import { DefaultChainAndToken } from '../DefaultChainAndToken/DefaultChainAndToken'; +import { SupportedBlockchains } from '../SupportedBlockchains'; +import { SupportedTokens } from '../SupportedTokens'; + +import { FromToContainer } from './FunctionalLayout.styles'; + +export function ToSection() { + return ( + <> + + + + + + + + + + + ); +} diff --git a/widget/playground/src/containers/FunctionalLayout/FunctionalLayout.Wallets.tsx b/widget/playground/src/containers/FunctionalLayout/FunctionalLayout.Wallets.tsx new file mode 100644 index 0000000000..a26c0fddf8 --- /dev/null +++ b/widget/playground/src/containers/FunctionalLayout/FunctionalLayout.Wallets.tsx @@ -0,0 +1,165 @@ +import type { WalletType } from '@rango-dev/wallets-shared'; + +import { allProviders as getAllProviders } from '@rango-dev/provider-all'; +import { + Button, + Checkbox, + Divider, + Switch, + Typography, + WalletIcon, +} from '@rango-dev/ui'; +import { separateLegacyAndHubProviders } from '@rango-dev/wallets-react'; +import { WalletTypes } from '@rango-dev/wallets-shared'; +import { useWallets } from '@rango-dev/widget-embedded'; +import React from 'react'; + +import { MultiSelect } from '../../components/MultiSelect'; +import { useConfigStore } from '../../store/config'; +import { useMetaStore } from '../../store/meta'; +import { getCategoryNetworks } from '../../utils/blockchains'; +import { excludedWallets } from '../../utils/common'; + +import { + connectButtonStyles, + ExternalSection, + Footer, + SwitchField, +} from './FunctionalLayout.styles'; + +export function WalletSection() { + const { state, connect, disconnect } = useWallets(); + const { onChangeWallets, onChangeBooleansConfig, config } = useConfigStore(); + const { + meta: { blockchains }, + } = useMetaStore(); + + const getWalletsList = () => { + const envs = { + walletconnect2: { + WC_PROJECT_ID: config?.walletConnectProjectId || '', + DISABLE_MODAL_AND_OPEN_LINK: + config.__UNSTABLE_OR_INTERNAL__?.walletConnectListedDesktopWalletLink, + }, + selectedProviders: config.wallets, + trezor: config?.trezorManifest + ? { manifest: config.trezorManifest } + : undefined, + tonConnect: config?.tonConnect?.manifestUrl + ? { manifestUrl: config?.tonConnect.manifestUrl } + : undefined, + }; + const allProviders = getAllProviders(envs); + const allBuiltProviders = allProviders.map((build) => build()); + const [legacyProviders] = separateLegacyAndHubProviders(allBuiltProviders, { + isExperimentalEnabled: config.features?.experimentalWallet === 'enabled', + }); + const filteredProviders = legacyProviders.filter( + (provider) => + !excludedWallets.includes(provider.config.type as WalletTypes) + ); + + const allWalletList = filteredProviders.map((provider) => { + const walletInfo = provider.getWalletInfo(blockchains); + return { + title: walletInfo.name, + logo: walletInfo.img, + name: provider.config.type, + supportedNetworks: getCategoryNetworks(walletInfo.supportedChains), + }; + }); + + return allWalletList; + }; + + const { externalWallets, wallets, multiWallets } = config; + const allWalletList = getWalletsList(); + + const onChangeExternalWallet = (checked: boolean) => { + if (!checked) { + if (state('metamask').connected) { + void disconnect(WalletTypes.META_MASK); + } + } + onChangeBooleansConfig('externalWallets', checked); + }; + + const isSelectAllWallets = + wallets?.length === allWalletList.length || externalWallets; + + return ( + <> + } + type="Wallets" + value={isSelectAllWallets ? undefined : (wallets as WalletType[])} + defaultSelectedItems={ + (wallets as WalletType[]) || + allWalletList.map((wallet) => wallet.name) + } + list={allWalletList} + disabled={!!externalWallets} + onChange={onChangeWallets} + /> + + + onChangeBooleansConfig('multiWallets', checked) + } + checked={multiWallets ?? true} + label={ + + Enable Multi Wallets Simultaneously + + } + /> + + + + + + External Wallets + + + + + + It's a sample using metamask, You can use your own wallet or what we + already implemented, check it out here. + + +
+ +
+
+ + ); +} diff --git a/widget/playground/src/containers/FunctionalLayout/FunctionalLayout.helpers.ts b/widget/playground/src/containers/FunctionalLayout/FunctionalLayout.helpers.ts new file mode 100644 index 0000000000..b887c39450 --- /dev/null +++ b/widget/playground/src/containers/FunctionalLayout/FunctionalLayout.helpers.ts @@ -0,0 +1,24 @@ +import type { LiquidityType } from './FunctionalLayout.types'; +import type { SwapperMeta } from 'rango-sdk'; + +export const filterByType = (type: LiquidityType, swapper: SwapperMeta) => { + return ( + (type === 'DEX' && swapper.types.includes('DEX')) || + (type === 'BRIDGE' && !swapper.types.includes('DEX')) + ); +}; + +export const getLiquidityValue = ( + isAllSelected: boolean, + excludedMode: boolean, + isAllSelectedInCategory: boolean, + selectedList?: string[] +) => { + return isAllSelected + ? excludedMode + ? [] + : undefined + : isAllSelectedInCategory + ? undefined + : selectedList; +}; diff --git a/widget/playground/src/containers/FunctionalLayout/FunctionalLayout.styles.ts b/widget/playground/src/containers/FunctionalLayout/FunctionalLayout.styles.ts new file mode 100644 index 0000000000..14b4d55872 --- /dev/null +++ b/widget/playground/src/containers/FunctionalLayout/FunctionalLayout.styles.ts @@ -0,0 +1,52 @@ +import { css, styled } from '@rango-dev/ui'; + +export const amountStyles = css({ + fontSize: '$12', +}); +export const connectButtonStyles = css({}); + +export const ExternalSection = styled('div', { + borderRadius: '20px', + padding: '$20', + display: 'flex', + flexDirection: 'column', + placeContent: 'center', + backgroundColor: '$background', +}); + +export const Footer = styled('div', { + maxWidth: '$180', + [`& .${connectButtonStyles}`]: { + padding: '$5 $20', + }, +}); + +export const SwitchField = styled('div', { + display: 'flex', + justifyContent: 'space-between', + alignItems: 'center', +}); + +export const FromToContainer = styled('div', { + backgroundColor: '$background', + borderRadius: '$sm', + border: '1px solid $neutral300', + padding: '$15 $20', +}); + +export const FromAmount = styled('div', { + border: '1px solid $neutral300', + borderRadius: '$xm', + padding: '$2 $5', + [`& .${amountStyles}`]: { + color: '$neutral700', + fontSize: '$12', + }, + '&:hover': { + borderColor: '$secondary200', + }, +}); + +export const IncludeSourceText = styled('div', { + paddingLeft: '$24', +}); diff --git a/widget/playground/src/containers/FunctionalLayout/FunctionalLayout.tsx b/widget/playground/src/containers/FunctionalLayout/FunctionalLayout.tsx new file mode 100644 index 0000000000..8aa2ce573c --- /dev/null +++ b/widget/playground/src/containers/FunctionalLayout/FunctionalLayout.tsx @@ -0,0 +1,55 @@ +import { Divider } from '@rango-dev/ui'; +import React, { useState } from 'react'; + +import { Collapse } from '../../components/Collapse'; + +import { FromSection } from './FunctionalLayout.From'; +import { LiquiditiesSection } from './FunctionalLayout.Liquidities'; +import { ToSection } from './FunctionalLayout.To'; +import { FunctionalCollapseState } from './FunctionalLayout.types'; +import { WalletSection } from './FunctionalLayout.Wallets'; + +export function FunctionalLayout() { + const [openCollapse, toggleCollapse] = + useState(FunctionalCollapseState.FROM); + + const handleOpenCollapse = (name: FunctionalCollapseState) => () => { + if (openCollapse === name) { + toggleCollapse(null); + } else { + toggleCollapse(name); + } + }; + + return ( +
+ + + + + + + + + + + + + + + +
+ ); +} diff --git a/widget/playground/src/containers/FunctionalLayout/FunctionalLayout.types.ts b/widget/playground/src/containers/FunctionalLayout/FunctionalLayout.types.ts new file mode 100644 index 0000000000..64380f1ad8 --- /dev/null +++ b/widget/playground/src/containers/FunctionalLayout/FunctionalLayout.types.ts @@ -0,0 +1,13 @@ +export enum FunctionalCollapseState { + FROM = 'from', + WALLET = 'wallet', + LIQUIDITY_SOURCE = 'liquidity source', + TO = 'to', +} + +export enum ModalState { + DEFAULT_BLOCKCHAIN = 'blockchain', + DEFAULT_TOKEN = 'token', +} + +export type LiquidityType = 'DEX' | 'BRIDGE'; diff --git a/widget/playground/src/containers/FunctionalLayout/index.ts b/widget/playground/src/containers/FunctionalLayout/index.ts new file mode 100644 index 0000000000..afb7ce8e90 --- /dev/null +++ b/widget/playground/src/containers/FunctionalLayout/index.ts @@ -0,0 +1 @@ +export { FunctionalLayout } from './FunctionalLayout'; diff --git a/widget/playground/src/containers/StyleLayout/StyleLayout.CustomColors.tsx b/widget/playground/src/containers/StyleLayout/StyleLayout.CustomColors.tsx new file mode 100644 index 0000000000..6c8e421a07 --- /dev/null +++ b/widget/playground/src/containers/StyleLayout/StyleLayout.CustomColors.tsx @@ -0,0 +1,268 @@ +import type { CustomColorsTypes } from './StyleLayout.types'; +import type { Mode } from '../../store/config'; +import type { WidgetColorsKeys } from '@rango-dev/widget-embedded'; + +import { + ChevronDownIcon, + ChevronUpIcon, + Collapsible, + CustomColorsIcon, + Divider, + Typography, +} from '@rango-dev/ui'; +import React, { useEffect, useState } from 'react'; + +import { ColorPicker } from '../../components/ColorPicker'; +import { WIDGET_COLORS } from '../../constants'; +import { useConfigStore } from '../../store/config'; +import { getMainColor } from '../../utils/colors'; +import { shallowEqual } from '../../utils/common'; + +import { + ColoredCircle, + ColorsContent, + CustomColorCollapsible, + CustomColors, + FieldTitle, + Row, +} from './StyleLayout.styles'; + +const Colors = (props: { mainColor?: string; secondColor?: string }) => { + return ( + + + {props.secondColor !== undefined && ( + + )} + + ); +}; + +export function CustomColorsSection(props: CustomColorsTypes) { + const { tab, selectedPreset, onResetPreset } = props; + + const [openCustomColors, toggleCustomColors] = useState<{ + tab: Mode; + value: boolean; + }>({ tab, value: false }); + + const [openCustomColor, setOpenCustomColor] = + useState(null); + const onChangeColors = useConfigStore.use.onChangeColors(); + const isAutoTab = tab === 'auto'; + const singleTheme = !isAutoTab; + const { theme } = useConfigStore.use.config(); + + const isOpenCustomColors = + tab === openCustomColors.tab && openCustomColors.value; + + const handleOpenCollapse = (key: WidgetColorsKeys) => { + if (openCustomColor === key) { + setOpenCustomColor(null); + } else { + setOpenCustomColor(key); + } + }; + useEffect(() => { + setOpenCustomColor(null); + }, [tab]); + + const onResetColor = (name: WidgetColorsKeys, mode: 'light' | 'dark') => { + const color = !!selectedPreset ? selectedPreset?.[mode]?.[name] : undefined; + onChangeColors({ + name, + mode, + color, + singleTheme, + }); + }; + + useEffect(() => { + if ( + !shallowEqual(theme?.colors?.dark || {}, selectedPreset?.dark || {}) && + !shallowEqual(theme?.colors?.light || {}, selectedPreset?.light || {}) + ) { + onResetPreset(); + } + }, [theme?.colors]); + + const isCustomColorDisabled = + (tab === 'auto' && theme?.singleTheme) || // The system tab and a single theme is selected + (tab === 'light' && !!selectedPreset?.dark) || // The light tab and a system or dark theme is selected + (tab === 'dark' && !!selectedPreset?.light); // The dark tab and a system or light theme is selected + + useEffect(() => { + if (isCustomColorDisabled) { + setOpenCustomColor(null); + } + }, [isCustomColorDisabled]); + return ( + + toggleCustomColors((prev) => ({ + tab, + value: tab === prev.tab ? !prev.value : true, + })) + } + trigger={ + + ) : ( + + ) + }> + + + + + Custom Colors + + + + }> + + + {WIDGET_COLORS.map((widgetColor) => ( +
+ handleOpenCollapse(widgetColor.key)} + trigger={ + + + + + + {widgetColor.label} + + + {openCustomColor === widgetColor.key ? ( + + ) : ( + + )} + + }> + + + {isAutoTab ? ( + <> + + onChangeColors({ + name: widgetColor.key, + mode: 'light', + color, + singleTheme, + }) + } + onReset={() => onResetColor(widgetColor.key, 'light')} + resetDisable={ + getMainColor(widgetColor.key, tab, { + singleTheme: theme?.singleTheme, + colors: theme?.colors, + mode: 'light', + }) === selectedPreset?.light?.[widgetColor.key] + } + /> + + + + onChangeColors({ + name: widgetColor.key, + mode: 'dark', + color, + singleTheme, + }) + } + resetDisable={ + getMainColor(widgetColor.key, tab, { + singleTheme: theme?.singleTheme, + colors: theme?.colors, + mode: 'dark', + }) === selectedPreset?.dark?.[widgetColor.key] + } + onReset={() => onResetColor(widgetColor.key, 'dark')} + /> + + ) : ( + + onChangeColors({ + name: widgetColor.key, + mode: tab, + color, + singleTheme, + }) + } + onReset={() => onResetColor(widgetColor.key, tab)} + resetDisable={ + getMainColor(widgetColor.key, tab, { + singleTheme: theme?.singleTheme, + colors: theme?.colors, + mode: 'dark', + }) === + (selectedPreset + ? selectedPreset?.[tab]?.[widgetColor.key] + : undefined) + } + /> + )} + + +
+ ))} +
+ ); +} diff --git a/widget/playground/src/containers/StyleLayout/StyleLayout.General.tsx b/widget/playground/src/containers/StyleLayout/StyleLayout.General.tsx new file mode 100644 index 0000000000..d45963728c --- /dev/null +++ b/widget/playground/src/containers/StyleLayout/StyleLayout.General.tsx @@ -0,0 +1,212 @@ +import type { ChangeEvent } from 'react'; + +import { + BorderRadiusIcon, + Divider, + FontIcon, + InfoErrorIcon, + LanguageIcon, + Select, + Typography, + WidgetIcon, +} from '@rango-dev/ui'; +import { SUPPORTED_FONTS, useWidget } from '@rango-dev/widget-embedded'; +import React, { useCallback, useState } from 'react'; + +import { ItemPicker } from '../../components/ItemPicker'; +import { OverlayPanel } from '../../components/OverlayPanel'; +import { SingleList } from '../../components/SingleList'; +import { Slider } from '../../components/Slider'; +import { + DEFAULT_LANGUAGE, + DEFAULT_PRIMARY_RADIUS, + DEFAULT_SECONDARY_RADIUS, + LANGUAGES, + PLAYGROUND_CONTAINER_ID, +} from '../../constants'; +import { DEFAULT_FONT } from '../../constants/fonts'; +import { VARIANTS } from '../../constants/variants'; +import { useTheme } from '../../hooks/useTheme'; +import { useConfigStore } from '../../store/config'; + +import { Field, FieldTitle, GeneralContainer } from './StyleLayout.styles'; +import { ModalState } from './StyleLayout.types'; + +export function General() { + const [modalState, setModalState] = useState(null); + + const onBack = () => setModalState(null); + const onChangeLanguage = useConfigStore.use.onChangeLanguage(); + const onChangeTheme = useConfigStore.use.onChangeTheme(); + const onChangeVariant = useConfigStore.use.onChangeVariant(); + + const borderRadius = useConfigStore.use.config().theme?.borderRadius; + const colors = useConfigStore.use.config().theme?.colors; + const { activeStyle } = useTheme(); + const mode = activeStyle.indexOf('dark') !== -1 ? 'dark' : 'light'; + const secondaryBorderRadius = + useConfigStore.use.config().theme?.secondaryBorderRadius; + const fontFamily = + useConfigStore.use.config().theme?.fontFamily || DEFAULT_FONT; + const defaultLanguage = LANGUAGES.find( + (lng) => lng.value === DEFAULT_LANGUAGE + ); + const language = + useConfigStore.use.config().language || defaultLanguage?.value; + const variant = useConfigStore.use.config().variant || VARIANTS[0].value; + + const { resetLanguage } = useWidget(); + + const handleFontChange = (value: string) => { + if (value) { + onChangeTheme({ + name: 'fontFamily', + value: value === DEFAULT_FONT ? undefined : value, + }); + } + onBack(); + }; + + const handleLanguageChange = (value: string) => { + if (value) { + onChangeLanguage(value); + resetLanguage(); + } + onBack(); + }; + + const handleBorderRadius = useCallback( + (e: ChangeEvent) => { + const value = parseInt(e.target.value); + onChangeTheme({ + name: 'borderRadius', + value: value === DEFAULT_PRIMARY_RADIUS ? undefined : value, + }); + }, + [borderRadius] + ); + + const handleSecondaryBorderRadius = useCallback( + (e: ChangeEvent) => { + const value = parseInt(e.target.value); + onChangeTheme({ + name: 'secondaryBorderRadius', + value: value === DEFAULT_SECONDARY_RADIUS ? undefined : value, + }); + }, + [secondaryBorderRadius] + ); + + const selectedLanguage = LANGUAGES.find((l) => l.value === language); + + return ( + <> + + + + + + + Widget Variant + + + + setValue(item.value)} + /> + ); +}; diff --git a/widget/storybook/src/components/SelectableCategoryList/SelectableCategoryList.stories.tsx b/widget/storybook/src/components/SelectableCategoryList/SelectableCategoryList.stories.tsx new file mode 100644 index 0000000000..764109a87c --- /dev/null +++ b/widget/storybook/src/components/SelectableCategoryList/SelectableCategoryList.stories.tsx @@ -0,0 +1,36 @@ +import type { SelectableCategoryListPropTypes } from '@rango-dev/ui'; +import type { Meta } from '@storybook/react'; + +import { SelectableCategoryList } from '@rango-dev/ui'; +import React, { useState } from 'react'; + +import { blockchains } from './mock'; + +export default { + title: 'Components/SelectableCategoryList', + component: SelectableCategoryList, + args: { + blockchains, + isLoading: false, + }, + argTypes: { + category: { + type: 'string', + control: { type: 'text' }, + }, + setCategory: { + type: 'function', + }, + }, +} as Meta; + +export const Main = (args: SelectableCategoryListPropTypes) => { + const [category, setCategory] = useState(''); + return ( + + ); +}; diff --git a/widget/storybook/src/components/SelectableCategoryList/mock.ts b/widget/storybook/src/components/SelectableCategoryList/mock.ts new file mode 100644 index 0000000000..463036387f --- /dev/null +++ b/widget/storybook/src/components/SelectableCategoryList/mock.ts @@ -0,0 +1,235 @@ +export const blockchains = [ + { + name: 'ETH', + defaultDecimals: 18, + addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], + feeAssets: [ + { + blockchain: 'ETH', + symbol: 'ETH', + address: null, + }, + ], + logo: 'https://raw.githubusercontent.com/rango-exchange/assets/main/blockchains/ETH/icon.svg', + displayName: 'Ethereum', + shortName: 'ETH', + sort: 0, + color: '#ecf0f1', + enabled: true, + type: 'EVM', + chainId: '0x1', + info: { + infoType: 'EvmMetaInfo', + chainName: 'Ethereum Mainnet', + nativeCurrency: { + name: 'ETH', + symbol: 'ETH', + decimals: 18, + }, + rpcUrls: ['https://rpc.ankr.com/eth'], + blockExplorerUrls: ['https://etherscan.io'], + addressUrl: 'https://etherscan.io/address/{wallet}', + transactionUrl: 'https://etherscan.io/tx/{txHash}', + enableGasV2: true, + }, + }, + { + name: 'BSC', + defaultDecimals: 18, + addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], + feeAssets: [ + { + blockchain: 'BSC', + symbol: 'BNB', + address: null, + }, + ], + logo: 'https://raw.githubusercontent.com/rango-exchange/assets/main/blockchains/BSC/icon.svg', + displayName: 'BNB Smart Chain', + shortName: 'BSC', + sort: 1, + color: '#F3BA2F', + enabled: true, + type: 'EVM', + chainId: '0x38', + info: { + infoType: 'EvmMetaInfo', + chainName: 'Binance Smart Chain Mainnet', + nativeCurrency: { + name: 'BNB', + symbol: 'BNB', + decimals: 18, + }, + rpcUrls: ['https://bsc-dataseed1.ninicoin.io'], + blockExplorerUrls: ['https://bscscan.com'], + addressUrl: 'https://bscscan.com/address/{wallet}', + transactionUrl: 'https://bscscan.com/tx/{txHash}', + enableGasV2: false, + }, + }, + { + name: 'POLYGON', + defaultDecimals: 18, + addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], + feeAssets: [ + { + blockchain: 'POLYGON', + symbol: 'MATIC', + address: null, + }, + ], + logo: 'https://raw.githubusercontent.com/rango-exchange/assets/main/blockchains/POLYGON/icon.svg', + displayName: 'Polygon', + shortName: 'Polygon', + sort: 3, + color: '#8247E5', + enabled: true, + type: 'EVM', + chainId: '0x89', + info: { + infoType: 'EvmMetaInfo', + chainName: 'Polygon Mainnet', + nativeCurrency: { + name: 'MATIC', + symbol: 'MATIC', + decimals: 18, + }, + rpcUrls: ['https://polygon-rpc.com'], + blockExplorerUrls: ['https://polygonscan.com'], + addressUrl: 'https://polygonscan.com/address/{wallet}', + transactionUrl: 'https://polygonscan.com/tx/{txHash}', + enableGasV2: true, + }, + }, + { + name: 'TRON', + defaultDecimals: 18, + addressPatterns: ['^T[1-9A-HJ-NP-Za-km-z]{33}$'], + feeAssets: [ + { + blockchain: 'TRON', + symbol: 'TRX', + address: null, + }, + ], + logo: 'https://raw.githubusercontent.com/rango-exchange/assets/main/blockchains/TRON/icon.svg', + displayName: 'Tron', + shortName: 'Tron', + sort: 11, + color: '#FF060A', + enabled: true, + type: 'TRON', + chainId: '0x2b6653dc', + info: { + infoType: 'EvmMetaInfo', + chainName: 'TRON Mainnet', + nativeCurrency: { + name: 'TRX', + symbol: 'TRX', + decimals: 6, + }, + rpcUrls: ['https://api.trongrid.io/jsonrpc'], + blockExplorerUrls: ['https://tronscan.org/#'], + addressUrl: 'https://tronscan.org/#/address/{wallet}', + transactionUrl: 'https://tronscan.org/#/tx/{txHash}', + enableGasV2: false, + }, + }, + { + name: 'BTC', + defaultDecimals: 8, + addressPatterns: [ + '^[13][a-km-zA-HJ-NP-Z1-9]{25,34}$|^(bc1)[0-9A-Za-z]{39,59}$', + ], + feeAssets: [ + { + blockchain: 'BTC', + symbol: 'BTC', + address: null, + }, + ], + logo: 'https://raw.githubusercontent.com/rango-exchange/assets/main/blockchains/BTC/icon.svg', + displayName: 'Bitcoin', + shortName: 'BTC', + sort: 12, + color: '#F7931A', + enabled: true, + type: 'TRANSFER', + chainId: null, + info: null, + }, + { + name: 'COSMOS', + defaultDecimals: 6, + addressPatterns: ['^(cosmos1)[0-9a-z]{38}$'], + feeAssets: [ + { + blockchain: 'COSMOS', + symbol: 'ATOM', + address: null, + }, + ], + logo: 'https://raw.githubusercontent.com/rango-exchange/assets/main/blockchains/COSMOS/icon.svg', + displayName: 'Cosmos', + shortName: 'Cosmos', + sort: 14, + color: '#2E3148', + enabled: true, + type: 'COSMOS', + chainId: 'cosmoshub-4', + info: { + infoType: 'CosmosMetaInfo', + experimental: false, + rpc: 'https://cosmos-rpc.polkachu.com', + rest: 'https://lcd-cosmoshub.blockapsis.com', + cosmostationLcdUrl: 'https://lcd-cosmoshub.blockapsis.com', + cosmostationApiUrl: 'https://cosmos-rpc.polkachu.com', + cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', + mintScanName: 'cosmos', + chainName: 'Cosmos', + stakeCurrency: { + coinDenom: 'ATOM', + coinMinimalDenom: 'uatom', + coinDecimals: 6, + coinGeckoId: 'cosmos', + coinImageUrl: '/tokens/blockchain/cosmos.svg', + }, + bip44: { + coinType: 118, + }, + bech32Config: { + bech32PrefixAccAddr: 'cosmos', + bech32PrefixAccPub: 'cosmospub', + bech32PrefixValAddr: 'cosmosvaloper', + bech32PrefixValPub: 'cosmosvaloperpub', + bech32PrefixConsAddr: 'cosmosvalcons', + bech32PrefixConsPub: 'cosmosvalconspub', + }, + currencies: [ + { + coinDenom: 'ATOM', + coinMinimalDenom: 'uatom', + coinDecimals: 6, + coinGeckoId: 'cosmos', + coinImageUrl: '/tokens/blockchain/cosmos.svg', + }, + ], + feeCurrencies: [ + { + coinDenom: 'ATOM', + coinMinimalDenom: 'uatom', + coinDecimals: 6, + coinGeckoId: 'cosmos', + coinImageUrl: '/tokens/blockchain/cosmos.svg', + }, + ], + features: ['stargate', 'ibc-transfer'], + explorerUrlToTx: 'https://www.mintscan.io/cosmos/txs/{txHash}', + gasPriceStep: { + low: 0.01, + average: 0.025, + high: 0.04, + }, + }, + }, +]; diff --git a/widget/storybook/src/components/Skeleton.stories.tsx b/widget/storybook/src/components/Skeleton.stories.tsx new file mode 100644 index 0000000000..5ef5b0e2e9 --- /dev/null +++ b/widget/storybook/src/components/Skeleton.stories.tsx @@ -0,0 +1,47 @@ +import type { SkeletonPropTypes } from '@rango-dev/ui'; +import type { Meta } from '@storybook/react'; + +import { Divider, Skeleton, Typography } from '@rango-dev/ui'; +import React from 'react'; + +export default { + title: 'Components/Skeleton', + component: Skeleton, + args: { + width: 50, + height: 50, + }, + argTypes: { + variant: { + defaultValue: 'rounded', + options: ['text', 'circular', 'rectangular', 'rounded'], + description: 'text | circular| rectangular | rounded', + control: { + type: 'select', + }, + }, + + size: { + name: 'size', + defaultValue: 'small', + options: ['small', 'medium', 'large'], + description: 'small | medium| large', + control: { type: 'select' }, + }, + }, +} as Meta; + +export const Main = (args: SkeletonPropTypes) => ( + <> + + + + + + + + + + + +); diff --git a/widget/storybook/src/components/Spinner.stories.tsx b/widget/storybook/src/components/Spinner.stories.tsx new file mode 100644 index 0000000000..8a91edd54b --- /dev/null +++ b/widget/storybook/src/components/Spinner.stories.tsx @@ -0,0 +1,32 @@ +/* eslint-disable @typescript-eslint/no-magic-numbers */ +import type { SpinnerPropTypes } from '@rango-dev/ui'; +import type { Meta } from '@storybook/react'; + +import { Spinner } from '@rango-dev/ui'; +import React from 'react'; + +export default { + title: 'Components/Spinner', + component: Spinner, + args: { + color: 'primary', + size: 16, + }, + argTypes: { + color: { + name: 'color', + control: { type: 'select' }, + options: ['primary', 'error', 'warning', 'success', 'black', 'white'], + defaultValue: 'primary', + }, + + size: { + name: 'size', + control: { type: 'radio' }, + options: [16, 20, 24], + defaultValue: 16, + }, + }, +} as Meta; + +export const Main = (props: SpinnerPropTypes) => ; diff --git a/widget/storybook/src/components/StepDetails/StepDetails.stories.tsx b/widget/storybook/src/components/StepDetails/StepDetails.stories.tsx new file mode 100644 index 0000000000..1b84dc11c8 --- /dev/null +++ b/widget/storybook/src/components/StepDetails/StepDetails.stories.tsx @@ -0,0 +1,49 @@ +import type { Meta, StoryObj } from '@storybook/react'; + +import { Alert, StepDetails } from '@rango-dev/ui'; +import React from 'react'; + +import { step1 } from './mock'; + +const meta: Meta = { + component: StepDetails, +}; + +export default meta; +type Story = StoryObj; + +export const Main: Story = { + args: { + step: { ...step1, alerts: }, + type: 'swap-progress', + state: 'completed', + }, + + argTypes: { + type: { + options: ['quote-details', 'swap-progress'], + control: { type: 'radio' }, + description: 'quote-details | swap-progress', + type: 'string', + }, + hasSeparator: { + control: { type: 'boolean' }, + type: 'boolean', + }, + state: { + options: ['default', 'in-progress', 'completed', 'warning', 'error'], + control: { type: 'select' }, + description: + 'default | in-progress | completed | warning | error | undefined', + type: 'string', + }, + isFocused: { + control: { type: 'boolean' }, + type: 'boolean', + }, + tabIndex: { + control: { type: 'number' }, + type: 'number', + }, + }, +}; diff --git a/widget/storybook/src/components/StepDetails/mock.ts b/widget/storybook/src/components/StepDetails/mock.ts new file mode 100644 index 0000000000..a16034cf7d --- /dev/null +++ b/widget/storybook/src/components/StepDetails/mock.ts @@ -0,0 +1,35 @@ +import type { Step } from '@rango-dev/ui'; + +export const step1: Step = { + swapper: { + displayName: 'MayaProtocol', + image: 'https://api.rango.exchange/swappers/maya.jpg', + }, + from: { + token: { + displayName: 'BTC', + image: 'https://api.rango.exchange/tokens/BTC/BTC.png', + }, + chain: { + displayName: 'BTC', + image: 'https://api.rango.exchange/tokens/BTC/BTC.png', + }, + price: { + value: '1.00000000', + }, + }, + to: { + chain: { + displayName: 'ETH', + image: 'https://api.rango.exchange/blockchains/ethereum.svg', + }, + token: { + displayName: 'ETH', + + image: 'https://api.rango.exchange/tokens/ETH/ETH.png', + }, + price: { + value: '14.863736725876758517', + }, + }, +}; diff --git a/widget/storybook/src/components/Switch.stories.tsx b/widget/storybook/src/components/Switch.stories.tsx new file mode 100644 index 0000000000..641c4200b8 --- /dev/null +++ b/widget/storybook/src/components/Switch.stories.tsx @@ -0,0 +1,22 @@ +import type { SwitchPropTypes } from '@rango-dev/ui'; +import type { Meta } from '@storybook/react'; + +import { Switch } from '@rango-dev/ui'; +import React from 'react'; + +export default { + title: 'Components/Switch', + component: Switch, + + argTypes: { + onChange: { + type: 'function', + }, + checked: { + control: { type: 'boolean' }, + type: 'boolean', + }, + }, +} as Meta; + +export const Main = (args: SwitchPropTypes) => ; diff --git a/widget/storybook/src/components/Tabs/Tabs.stories.tsx b/widget/storybook/src/components/Tabs/Tabs.stories.tsx new file mode 100644 index 0000000000..dcc3d359eb --- /dev/null +++ b/widget/storybook/src/components/Tabs/Tabs.stories.tsx @@ -0,0 +1,87 @@ +import type { TabsPropTypes } from '@rango-dev/ui'; +import type { Meta } from '@storybook/react'; + +import { Tabs } from '@rango-dev/ui'; +import React, { useState } from 'react'; + +import { numbers, themes } from './mock'; + +export default { + title: 'Components/Tabs', + component: Tabs, + args: { + type: 'primary', + borderRadius: 'small', + value: 'light', + items: themes, + }, + + argTypes: { + type: { + control: { type: 'select' }, + options: ['primary', 'secondary', 'bordered'], + defaultValue: 'primary', + description: 'primary | secondary | bordered | undefined', + }, + className: { + control: { type: 'text' }, + type: 'string', + }, + borderRadius: { + control: { type: 'select' }, + options: ['medium', 'small', 'full'], + defaultValue: 'small', + description: 'medium | small | full | undefined', + }, + onChange: { + type: 'function', + }, + scrollable: { + defaultValue: false, + type: 'boolean', + }, + scrollButtons: { + defaultValue: true, + type: 'boolean', + }, + }, +} as Meta; + +export const Main = (args: TabsPropTypes) => { + const [value, setValue] = useState(args.value); + + return ( +
+ setValue(item.id as string)} + /> +
+ ); +}; + +export const Scrollable = (args: TabsPropTypes) => { + const [value, setValue] = useState(numbers[0].id); + + return ( +
+ setValue(item.id as string)} + /> +
+ ); +}; diff --git a/widget/storybook/src/components/Tabs/mock.tsx b/widget/storybook/src/components/Tabs/mock.tsx new file mode 100644 index 0000000000..0e764c043e --- /dev/null +++ b/widget/storybook/src/components/Tabs/mock.tsx @@ -0,0 +1,132 @@ +import type { TabsPropTypes } from '@rango-dev/ui'; + +import { + AutoThemeIcon, + DarkModeIcon, + LightModeIcon, + Typography, +} from '@rango-dev/ui'; +import React from 'react'; + +export const themes = [ + { + id: 'light', + icon: , + tooltip: ( + + Light + + ), + }, + { + id: 'dark', + icon: , + tooltip: ( + + Dark + + ), + }, + { + id: 'auto', + icon: , + tooltip: ( + + Auto + + ), + }, +]; + +export const numbers: TabsPropTypes['items'] = [ + { + id: 'one', + title: 'one', + tooltip: ( + + 1 + + ), + }, + { + id: 'two', + title: 'two', + tooltip: ( + + 2 + + ), + }, + { + id: 'three', + title: 'three', + tooltip: ( + + 3 + + ), + }, + { + id: 'four', + title: 'four', + tooltip: ( + + 4 + + ), + }, + { + id: 'five', + title: 'five', + tooltip: ( + + 5 + + ), + }, + { + id: 'six', + title: 'six', + tooltip: ( + + 6 + + ), + }, + { + id: 'seven', + title: 'seven', + tooltip: ( + + 7 + + ), + }, + { + id: 'eight', + title: 'eight', + tooltip: ( + + 8 + + ), + }, + { + id: 'nine', + title: 'nine', + tooltip: ( + + 9 + + ), + }, + { + id: 'ten', + title: 'ten', + tooltip: ( + + 10 + + ), + }, +]; diff --git a/widget/storybook/src/components/TextField.stories.tsx b/widget/storybook/src/components/TextField.stories.tsx new file mode 100644 index 0000000000..7e1f3d419e --- /dev/null +++ b/widget/storybook/src/components/TextField.stories.tsx @@ -0,0 +1,57 @@ +import type { TextFieldPropTypes } from '@rango-dev/ui'; +import type { Meta } from '@storybook/react'; + +import { SearchIcon, TextField } from '@rango-dev/ui'; +import React from 'react'; + +export default { + title: 'Components/Text Field', + + component: TextField, + + argTypes: { + disabled: { + control: { type: 'boolean' }, + type: 'boolean', + }, + placeholder: { + name: 'placeholder', + control: { type: 'text' }, + type: 'string', + }, + label: { + name: 'placeholder', + control: { type: 'text' }, + type: 'string', + }, + variant: { + control: { type: 'select' }, + options: ['contained', 'outlined', 'ghost'], + description: 'contained | outlined | ghost | undefined', + }, + size: { + control: { type: 'select' }, + options: ['small', 'size'], + description: 'small | size | undefined', + }, + fullWidth: { + type: 'boolean', + control: { type: 'boolean' }, + }, + }, + args: { + variant: 'contained', + placeholder: 'test', + fullWidth: false, + }, +} as Meta; + +export const Main = (args: TextFieldPropTypes) => ; + +export const WithPrefix = (args: TextFieldPropTypes) => ( + } /> +); + +export const WithSuffix = (args: TextFieldPropTypes) => ( + } /> +); diff --git a/widget/storybook/src/components/Toast.stories.tsx b/widget/storybook/src/components/Toast.stories.tsx new file mode 100644 index 0000000000..0bfb2d9b9f --- /dev/null +++ b/widget/storybook/src/components/Toast.stories.tsx @@ -0,0 +1,67 @@ +import type { ToastPropTypes } from '@rango-dev/ui'; +import type { Meta } from '@storybook/react'; + +import { Button, Toast, ToastProvider, useToast } from '@rango-dev/ui'; +import React from 'react'; + +export default { + title: 'Components/Toast', + component: Toast, + args: { + type: 'success', + title: 'Please change your wallet network to Polygon', + autoHideDuration: 5_000, + position: 'right-top', + variant: 'standard', + }, + argTypes: { + type: { + name: 'type', + options: ['success', 'warning', 'error', 'info', 'loading'], + control: { + type: 'select', + }, + }, + position: { + name: 'position', + options: [ + 'right-top', + 'left-top', + 'center-top', + 'right-bottom', + 'left-bottom', + 'center-bottom', + ], + control: { + type: 'select', + }, + }, + }, +} as Meta; + +export const Main = (props: ToastPropTypes) => { + return ( + + + + ); +}; + +const ToastComponent = (props: ToastPropTypes) => { + const { addToast } = useToast(); + + return ( +
+ +
+ ); +}; diff --git a/widget/storybook/src/components/TokenAmount.stories.tsx b/widget/storybook/src/components/TokenAmount.stories.tsx new file mode 100644 index 0000000000..80f8926641 --- /dev/null +++ b/widget/storybook/src/components/TokenAmount.stories.tsx @@ -0,0 +1,24 @@ +import type { Meta, StoryObj } from '@storybook/react'; + +import { TokenAmount } from '@rango-dev/ui'; + +const meta: Meta = { + component: TokenAmount, +}; + +export default meta; +type Story = StoryObj; + +export const Main: Story = { + args: { + type: 'output', + price: { value: '1', usdValue: '28,490' }, + percentageChange: '2.21', + warningLevel: 'low', + chain: { image: 'https://api.rango.exchange/swappers/osmosis.png' }, + token: { + image: 'https://api.rango.exchange/tokens/COSMOS/JUNO.png', + displayName: 'JUNO', + }, + }, +}; diff --git a/widget/storybook/src/components/Tooltip.stories.tsx b/widget/storybook/src/components/Tooltip.stories.tsx new file mode 100644 index 0000000000..9f6b0945fe --- /dev/null +++ b/widget/storybook/src/components/Tooltip.stories.tsx @@ -0,0 +1,40 @@ +import type { TooltipPropTypes } from '@rango-dev/ui'; +import type { Meta } from '@storybook/react'; + +import { AddIcon, Tooltip } from '@rango-dev/ui'; +import React from 'react'; + +export default { + title: 'Components/Tooltip', + component: Tooltip, + args: { + content: 'I am a tooltip', + side: 'top', + }, + argTypes: { + content: { + name: 'content', + control: { type: 'text' }, + defaultValue: 'I am a tooltip', + }, + side: { + name: 'side', + control: { type: 'select' }, + options: ['top', 'right', 'bottom', 'left'], + defaultValue: 'top', + }, + color: { + name: 'color', + control: { type: 'select' }, + options: ['primary', 'error', 'warning', 'success'], + }, + }, +} as Meta; + +export const Main = (props: TooltipPropTypes) => ( +
+ + + +
+); diff --git a/widget/storybook/src/components/Typography.stories.tsx b/widget/storybook/src/components/Typography.stories.tsx new file mode 100644 index 0000000000..969385445e --- /dev/null +++ b/widget/storybook/src/components/Typography.stories.tsx @@ -0,0 +1,124 @@ +import type { TypographyPropTypes } from '@rango-dev/ui'; +import type { Meta } from '@storybook/react'; + +import { Typography } from '@rango-dev/ui'; +import React from 'react'; + +export default { + title: 'Components/Typography', + component: Typography, + argTypes: { + variant: { + name: 'variant', + control: { type: 'select' }, + options: [ + 'body1', + 'body2', + 'body3', + 'h1', + 'h2', + 'h3', + 'h4', + 'h5', + 'h6', + 'caption', + ], + defaultValue: 'h1', + }, + align: { + name: 'align', + control: { type: 'select' }, + options: ['center', 'left', 'right'], + }, + noWrap: { + name: 'noWrap', + control: { type: 'boolean' }, + }, + }, +} satisfies Meta; + +export const Main = (props: TypographyPropTypes) => ( +
+
+ + Display Large + + {', '} + + Display Medium + + {', '} + + Display Small + +
+ +
+ + Headline Large + + {', '} + + Headline Medium + + {', '} + + Headline Small + + {', '} + + Headline Xsmall + +
+ +
+ + Title Large + + {', '} + + Title Medium + + {', '} + + Title Xmedium + + {', '} + + Title Small + +
+ +
+ + Label Large + + {', '} + + Label Medium + + {', '} + + Label Small + +
+ +
+ + Body Large + + {', '} + + Body Medium + + {', '} + + Body Small + + {', '} + + Body Xsmall + +
+
+); diff --git a/widget/storybook/src/components/Wallet/ClickableWallet.stories.tsx b/widget/storybook/src/components/Wallet/ClickableWallet.stories.tsx new file mode 100644 index 0000000000..88b6c84565 --- /dev/null +++ b/widget/storybook/src/components/Wallet/ClickableWallet.stories.tsx @@ -0,0 +1,35 @@ +import type { Meta, StoryObj } from '@storybook/react'; + +import { Wallet, WalletState } from '@rango-dev/ui'; + +const meta: Meta = { + component: Wallet, +}; + +export default meta; +type Story = StoryObj; + +export const Main: Story = { + args: { + title: 'Trust Wallet', + image: 'https://api.rango.exchange/blockchains/zksync.png', + onClick: (type) => { + console.log('Clicked on', type); + }, + type: 'wallet-connect-2', + state: WalletState.CONNECTED, + }, + argTypes: { + state: { + options: [ + WalletState.CONNECTED, + WalletState.CONNECTING, + WalletState.DISCONNECTED, + WalletState.NOT_INSTALLED, + ], + control: { type: 'select' }, + description: `${WalletState.CONNECTED} | ${WalletState.CONNECTING} | ${WalletState.DISCONNECTED} | ${WalletState.NOT_INSTALLED}`, + type: 'string', + }, + }, +}; diff --git a/widget/storybook/src/components/Wallet/SelectableWallet.stories.tsx b/widget/storybook/src/components/Wallet/SelectableWallet.stories.tsx new file mode 100644 index 0000000000..632f75b9e3 --- /dev/null +++ b/widget/storybook/src/components/Wallet/SelectableWallet.stories.tsx @@ -0,0 +1,37 @@ +import type { Meta, StoryObj } from '@storybook/react'; + +import { SelectableWallet, WalletState } from '@rango-dev/ui'; + +const meta: Meta = { + component: SelectableWallet, +}; + +export default meta; +type Story = StoryObj; + +export const Main: Story = { + args: { + title: 'Trust Wallet', + description: '0x......', + image: 'https://api.rango.exchange/blockchains/zksync.png', + onClick: (type) => { + console.log('Clicked on', type); + }, + selected: true, + state: WalletState.CONNECTED, + type: 'wallet-connect-2', + }, + argTypes: { + state: { + options: [ + WalletState.CONNECTED, + WalletState.CONNECTING, + WalletState.DISCONNECTED, + WalletState.NOT_INSTALLED, + ], + control: { type: 'select' }, + description: `${WalletState.CONNECTED} | ${WalletState.CONNECTING} | ${WalletState.DISCONNECTED} | ${WalletState.NOT_INSTALLED}`, + type: 'string', + }, + }, +}; diff --git a/widget/storybook/src/containers/ConnectWalletsModal/ConnectWallets.stories.tsx b/widget/storybook/src/containers/ConnectWalletsModal/ConnectWallets.stories.tsx new file mode 100644 index 0000000000..d2719806b0 --- /dev/null +++ b/widget/storybook/src/containers/ConnectWalletsModal/ConnectWallets.stories.tsx @@ -0,0 +1,27 @@ +import type { ConnectWalletsModalPropTypes } from '@rango-dev/ui'; +import type { Meta } from '@storybook/react'; + +import { ConnectWalletsModal } from '@rango-dev/ui'; +import React, { useState } from 'react'; + +import { walletsInfo } from './mock'; + +export default { + title: 'Containers/Connect Wallets Modal', + component: ConnectWalletsModal, +} as Meta; + +export const Main = (args: ConnectWalletsModalPropTypes) => { + const [open, setOpen] = useState(false); + return ( +
+ + setOpen(false)} + /> +
+ ); +}; diff --git a/widget/storybook/src/containers/ConnectWalletsModal/mock.ts b/widget/storybook/src/containers/ConnectWalletsModal/mock.ts new file mode 100644 index 0000000000..1ba3386f8b --- /dev/null +++ b/widget/storybook/src/containers/ConnectWalletsModal/mock.ts @@ -0,0 +1,152 @@ +import type { WalletInfo } from '@rango-dev/ui'; + +import { WalletState } from '@rango-dev/ui'; +import { WalletTypes } from '@rango-dev/wallets-shared'; + +export const walletsInfo: WalletInfo[] = [ + { + image: + 'https://raw.githubusercontent.com/rango-exchange/assets/main/wallets/coinbase/icon.svg', + title: 'Coinbase', + state: WalletState.DISCONNECTED, + link: '', + type: WalletTypes.COINBASE, + blockchainTypes: [], + }, + { + image: + 'https://raw.githubusercontent.com/rango-exchange/assets/main/wallets/coinbase/icon.svg', + title: 'Coinbase', + state: WalletState.CONNECTED, + link: '', + type: WalletTypes.COINBASE, + blockchainTypes: [], + }, + { + image: + 'https://raw.githubusercontent.com/rango-exchange/assets/main/wallets/coinbase/icon.svg', + title: 'Coinbase', + state: WalletState.CONNECTING, + link: '', + type: WalletTypes.COINBASE, + blockchainTypes: [], + }, + { + image: + 'https://raw.githubusercontent.com/rango-exchange/assets/main/wallets/coinbase/icon.svg', + title: 'Coinbase', + state: WalletState.NOT_INSTALLED, + type: WalletTypes.COINBASE, + blockchainTypes: [], + + link: 'https://chrome.google.com/webstore/detail/coinbase-wallet-extension/hnfanknocfeofbddgcijnmhnfnkdnaad?hl=en', + }, + { + image: + 'https://raw.githubusercontent.com/rango-exchange/assets/main/wallets/coinbase/icon.svg', + title: 'Coinbase', + state: WalletState.DISCONNECTED, + link: '', + type: WalletTypes.COINBASE, + blockchainTypes: [], + }, + { + image: + 'https://raw.githubusercontent.com/rango-exchange/assets/main/wallets/coinbase/icon.svg', + title: 'Coinbase', + state: WalletState.CONNECTED, + link: '', + type: WalletTypes.COINBASE, + blockchainTypes: [], + }, + { + image: + 'https://raw.githubusercontent.com/rango-exchange/assets/main/wallets/coinbase/icon.svg', + title: 'Coinbase', + state: WalletState.DISCONNECTED, + link: '', + type: WalletTypes.COINBASE, + blockchainTypes: [], + }, + { + image: + 'https://raw.githubusercontent.com/rango-exchange/assets/main/wallets/coinbase/icon.svg', + title: 'Coinbase', + state: WalletState.DISCONNECTED, + link: '', + type: WalletTypes.COINBASE, + blockchainTypes: [], + }, + { + image: + 'https://raw.githubusercontent.com/rango-exchange/assets/main/wallets/coinbase/icon.svg', + title: 'Coinbase', + state: WalletState.DISCONNECTED, + link: '', + type: WalletTypes.COINBASE, + blockchainTypes: [], + }, + { + image: + 'https://raw.githubusercontent.com/rango-exchange/assets/main/wallets/coinbase/icon.svg', + title: 'Coinbase', + state: WalletState.DISCONNECTED, + link: '', + type: WalletTypes.COINBASE, + blockchainTypes: [], + }, + { + image: + 'https://raw.githubusercontent.com/rango-exchange/assets/main/wallets/coinbase/icon.svg', + title: 'Coinbase', + state: WalletState.DISCONNECTED, + link: '', + type: WalletTypes.COINBASE, + blockchainTypes: [], + }, + { + image: + 'https://raw.githubusercontent.com/rango-exchange/assets/main/wallets/coinbase/icon.svg', + title: 'Coinbase', + state: WalletState.DISCONNECTED, + link: '', + type: WalletTypes.COINBASE, + blockchainTypes: [], + }, + { + image: + 'https://raw.githubusercontent.com/rango-exchange/assets/main/wallets/coinbase/icon.svg', + title: 'Coinbase', + state: WalletState.DISCONNECTED, + link: '', + type: WalletTypes.COINBASE, + blockchainTypes: [], + }, + { + image: + 'https://raw.githubusercontent.com/rango-exchange/assets/main/wallets/coinbase/icon.svg', + title: 'Coinbase', + state: WalletState.DISCONNECTED, + link: '', + type: WalletTypes.COINBASE, + blockchainTypes: [], + }, + { + image: + 'https://raw.githubusercontent.com/rango-exchange/assets/main/wallets/coinbase/icon.svg', + title: 'Coinbase', + state: WalletState.DISCONNECTED, + link: '', + type: WalletTypes.COINBASE, + blockchainTypes: [], + }, + { + image: + 'https://raw.githubusercontent.com/rango-exchange/assets/main/wallets/coinbase/icon.svg', + title: 'Coinbase', + state: WalletState.DISCONNECTED, + link: '', + type: WalletTypes.COINBASE, + blockchainTypes: [], + }, +]; diff --git a/widget/storybook/src/containers/SwapInput.stories.tsx b/widget/storybook/src/containers/SwapInput.stories.tsx new file mode 100644 index 0000000000..96959c3720 --- /dev/null +++ b/widget/storybook/src/containers/SwapInput.stories.tsx @@ -0,0 +1,39 @@ +import type { SwapInputPropTypes } from '@rango-dev/ui'; +import type { Meta } from '@storybook/react'; + +import { SwapInput } from '@rango-dev/ui'; +import React from 'react'; + +const meta: Meta = { + title: 'Containers/Swap Input', + component: SwapInput, + args: { + chain: { + image: 'https://api.rango.exchange/blockchains/bsc.svg', + displayName: 'BSC', + }, + token: { + displayName: 'BNB', + image: 'https://api.rango.exchange/tokens/ETH/BNB.png', + }, + label: 'From', + price: { value: '0.5', usdValue: '151.2' }, + }, +}; + +export default meta; + +export const SwapFrom = (args: SwapInputPropTypes) => ( + +); + +export const SwapTo = (args: SwapInputPropTypes) => ( + +); diff --git a/widget/storybook/tsconfig.build.json b/widget/storybook/tsconfig.build.json new file mode 100644 index 0000000000..21e339ad5f --- /dev/null +++ b/widget/storybook/tsconfig.build.json @@ -0,0 +1,15 @@ +{ + // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs + "extends": "../../tsconfig.lib.json", + "include": ["src", "types"], + "compilerOptions": { + "outDir": "storybook-static", + "lib": ["dom", "esnext"], + // match output dir to input dir. e.g. dist/index instead of dist/src/index + "baseUrl": ".", + "rootDirs": ["./src"], + + // transpile JSX to React.createElement + "jsx": "react" + } +} diff --git a/widget/storybook/tsconfig.json b/widget/storybook/tsconfig.json new file mode 100644 index 0000000000..a3a0b0f59d --- /dev/null +++ b/widget/storybook/tsconfig.json @@ -0,0 +1 @@ +{ "extends": "./tsconfig.build.json", "include": ["src", "tests"] } diff --git a/widget/ui/.babelrc.json b/widget/ui/.babelrc.json new file mode 100644 index 0000000000..487a5a4835 --- /dev/null +++ b/widget/ui/.babelrc.json @@ -0,0 +1,5 @@ +{ + "sourceType": "unambiguous", + "presets": ["@babel/preset-typescript", "@babel/preset-react"], + "plugins": [] +} diff --git a/widget/ui/.storybook/main.js b/widget/ui/.storybook/main.js deleted file mode 100644 index d8e2165675..0000000000 --- a/widget/ui/.storybook/main.js +++ /dev/null @@ -1,8 +0,0 @@ -module.exports = { - stories: ['../src/**/*.stories.@(ts|tsx|js|jsx)'], - addons: ['@storybook/addon-links', '@storybook/addon-essentials'], - // https://storybook.js.org/docs/react/configure/typescript#mainjs-configuration - typescript: { - check: true, // type-check stories during Storybook build - }, -}; diff --git a/widget/ui/CHANGELOG.md b/widget/ui/CHANGELOG.md new file mode 100644 index 0000000000..5cc0d27b35 --- /dev/null +++ b/widget/ui/CHANGELOG.md @@ -0,0 +1,351 @@ +# [0.43.0](https://github.com/rango-exchange/rango-client/compare/ui@0.42.0...ui@0.43.0) (2024-12-30) + + + +# [0.42.0](https://github.com/rango-exchange/rango-client/compare/ui@0.41.0...ui@0.42.0) (2024-11-27) + + + +# [0.41.0](https://github.com/rango-exchange/rango-client/compare/ui@0.40.0...ui@0.41.0) (2024-11-12) + + +### Features + +* add a prop to the tooltip component for collision padding ([f7dae29](https://github.com/rango-exchange/rango-client/commit/f7dae29f4b158af47ff4959ec0e22025e8211f41)) +* add more languages to widget ([bc37fe9](https://github.com/rango-exchange/rango-client/commit/bc37fe97586545f993d7a2675a43b64aaa743791)) + + + +# [0.40.0](https://github.com/rango-exchange/rango-client/compare/ui@0.39.0...ui@0.40.0) (2024-10-12) + + +### Bug Fixes + +* add chart icon and handle dark theme in BarChart component ([fd4f246](https://github.com/rango-exchange/rango-client/commit/fd4f24684e42deb1b47fb9a6584ac4f9a1519599)) +* bump sdk and fix type issues ([d442208](https://github.com/rango-exchange/rango-client/commit/d4422083bf5dd27d5f509ce1db7f9560d05428c8)) +* fix issues in the tabs component ([497c387](https://github.com/rango-exchange/rango-client/commit/497c3871241f3e067682526c156014dcd8189395)) + + +### Features + +* add id property to buttons ([39824e3](https://github.com/rango-exchange/rango-client/commit/39824e3ce8b1804b9944eb0faf71da7cdccf59ea)) +* add mobile menu icons ([d4358bc](https://github.com/rango-exchange/rango-client/commit/d4358bc189a61c49c508c517b2cd674d435aa3b7)) +* implement scrollable variant for tabs component ([0635f77](https://github.com/rango-exchange/rango-client/commit/0635f774af9dfd03fcc8f7adfcd32591c86efa25)) + + + +# [0.39.0](https://github.com/rango-exchange/rango-client/compare/ui@0.38.0...ui@0.39.0) (2024-09-10) + + +### Bug Fixes + +* add slippage icon to setting page ([2e29351](https://github.com/rango-exchange/rango-client/commit/2e29351d957f4e751a25f66b7cb173e5d9956378)) +* ensure proper cleanup of the modal component after it is removed from the dom ([394e4f0](https://github.com/rango-exchange/rango-client/commit/394e4f017eb09ac99f90a10be94ef8a742632586)) +* improve header component to center the title properly ([a9929bb](https://github.com/rango-exchange/rango-client/commit/a9929bb518ccbb2033b646fbcb5c034852b039b2)) + + +### Features + +* implement bordered variant for tabs component ([1de8888](https://github.com/rango-exchange/rango-client/commit/1de8888d6d4ae13a765aaee0173eebf0d49f4a11)) + + + +# [0.38.0](https://github.com/rango-exchange/rango-client/compare/ui@0.37.0...ui@0.38.0) (2024-08-17) + + +### Features + +* add functionality to support custom tokens ([a1aa0af](https://github.com/rango-exchange/rango-client/commit/a1aa0afed98f164488a3caffaaff2fd060ab8b3d)) + + + +# [0.37.0](https://github.com/rango-exchange/rango-client/compare/ui@0.36.1...ui@0.37.0) (2024-08-11) + + +### Bug Fixes + +* fix bug in swap input handling empty value ([3c9b082](https://github.com/rango-exchange/rango-client/commit/3c9b082b7b548ddd3981fff100d4dc880581b98d)) +* fix modal animation bug ([98814f6](https://github.com/rango-exchange/rango-client/commit/98814f60fae6f5ba112aeee01fcc47cad821cd5c)) +* fix modal animation inconsistency in different scrren sizes bug by improving styles ([eda308e](https://github.com/rango-exchange/rango-client/commit/eda308e41fe6d4f8fc0777cc5d7f059a83e46078)) +* fix swap price alignment ([e8e3bbb](https://github.com/rango-exchange/rango-client/commit/e8e3bbb25ab56c31b92d3a5af1806fa70275bb70)) + + +### Features + +* add filter and clear to widget history ([d43b603](https://github.com/rango-exchange/rango-client/commit/d43b603462feabf297d5be389fcaa35402d667b5)) +* changing the request ID copy process ([490cdfa](https://github.com/rango-exchange/rango-client/commit/490cdfa41131eea20d8a552f8f0714b77d21ac71)) +* hide balance and max button when no wallet connected ([80b2754](https://github.com/rango-exchange/rango-client/commit/80b27547376394a3070aea7065d4bb9652f454e4)) +* update bullhorn icon ([4829803](https://github.com/rango-exchange/rango-client/commit/4829803ee8aa5daad43d8224069b583f4138a316)) + + + +## [0.36.1](https://github.com/rango-exchange/rango-client/compare/ui@0.36.0...ui@0.36.1) (2024-07-14) + + + +# [0.36.0](https://github.com/rango-exchange/rango-client/compare/ui@0.34.0...ui@0.36.0) (2024-07-09) + + +### Bug Fixes + +* add credit and disconnect icons ([b5e5357](https://github.com/rango-exchange/rango-client/commit/b5e5357cf3a5b13f602b8d5cdb829f3699ee3197)) +* improve generate colors for tokens label and price impact color ([5f2893c](https://github.com/rango-exchange/rango-client/commit/5f2893c03b17af24a8b3886e12b1631b5cc208fb)) +* rerfactor numeric tooltip and fix missing translations ([59f1fb9](https://github.com/rango-exchange/rango-client/commit/59f1fb96027a9b51cea5f6362b247b6cf180d809)) +* update design for not-selected blockchain or token ([8915101](https://github.com/rango-exchange/rango-client/commit/8915101d4e7a7092fbb5f38bbd95789e124f8ae3)) + + +### Features + +* add a modal for setting custom derivation path for ledger ([5b74ec0](https://github.com/rango-exchange/rango-client/commit/5b74ec049393ed74e3e7547edc72b68bd70b7dce)) +* adding 'shadows' to widget config for theme ([2be1f1a](https://github.com/rango-exchange/rango-client/commit/2be1f1aa508fb642a797610471b63219cd3d2ccf)) +* display all notifications in the notification popover ([c3eda22](https://github.com/rango-exchange/rango-client/commit/c3eda22cf1f06b928fdf0c98512fd444cc46823c)) +* generate theme color tints and shades using the new method of overriding them separately ([a46b8a9](https://github.com/rango-exchange/rango-client/commit/a46b8a93bff1d8d6766c2fd636091983a8ee1baa)) +* update explorer icon and add paste to custom destination ([61468a0](https://github.com/rango-exchange/rango-client/commit/61468a0e227517b91def21a85a8f7d72b7411862)) +* update wallets page to add filter by transaction types (category) ([0aa7c73](https://github.com/rango-exchange/rango-client/commit/0aa7c73333bd32912f7b2e90a660f3f43e64f4f7)) + + + +# [0.35.0](https://github.com/rango-exchange/rango-client/compare/ui@0.34.0...ui@0.35.0) (2024-06-01) + + +### Bug Fixes + +* update design for not-selected blockchain or token ([8915101](https://github.com/rango-exchange/rango-client/commit/8915101d4e7a7092fbb5f38bbd95789e124f8ae3)) + + +### Features + +* generate theme color tints and shades using the new method of overriding them separately ([a46b8a9](https://github.com/rango-exchange/rango-client/commit/a46b8a93bff1d8d6766c2fd636091983a8ee1baa)) +* update explorer icon and add paste to custom destination ([61468a0](https://github.com/rango-exchange/rango-client/commit/61468a0e227517b91def21a85a8f7d72b7411862)) +* update wallets page to add filter by transaction types (category) ([0aa7c73](https://github.com/rango-exchange/rango-client/commit/0aa7c73333bd32912f7b2e90a660f3f43e64f4f7)) + + + +# [0.34.0](https://github.com/rango-exchange/rango-client/compare/ui@0.33.0...ui@0.34.0) (2024-05-14) + + +### Features + +* add a new package to deploy the storybook preview ([06aaa44](https://github.com/rango-exchange/rango-client/commit/06aaa444408f07c7a053432af081c9758f157052)) +* migrate storybook components to new package ([d926ae2](https://github.com/rango-exchange/rango-client/commit/d926ae220360077ef49ee919dbb2e15f6bec0548)) + + + +# [0.33.0](https://github.com/rango-exchange/rango-client/compare/ui@0.32.0...ui@0.33.0) (2024-04-24) + + + +# [0.32.0](https://github.com/rango-exchange/rango-client/compare/ui@0.31.0...ui@0.32.0) (2024-04-23) + + + +# [0.31.0](https://github.com/rango-exchange/rango-client/compare/ui@0.30.0...ui@0.31.0) (2024-04-09) + + +### Bug Fixes + +* address tooltips position ([5ee60d1](https://github.com/rango-exchange/rango-client/commit/5ee60d1622dab29091d97578d417a2187f2ca6cf)) +* correct showing wallets on mobile screens ([89ead7f](https://github.com/rango-exchange/rango-client/commit/89ead7f68e88352dfd69c2a3d1c6cb0b8cf2e5d5)) +* fix modal transition duration ([2fb2536](https://github.com/rango-exchange/rango-client/commit/2fb2536e0349585730611ef356d6f7b7fe7d36a8)) +* fix number textfield getting value ([5e603a8](https://github.com/rango-exchange/rango-client/commit/5e603a8ad222701ed93da7ed6f3fc393ab279c15)) + + +### Features + +* implement hover state for full-expanded-route ([1c851d7](https://github.com/rango-exchange/rango-client/commit/1c851d7c62b71fe8f4aa6c05edbc0d6cc78d5437)) + + + +# [0.30.0](https://github.com/rango-exchange/rango-client/compare/ui@0.29.0...ui@0.30.0) (2024-03-12) + + +### Bug Fixes + +* correct height of widget & address full-expanded hover & spacing ([6390316](https://github.com/rango-exchange/rango-client/commit/639031622644ee99d3e708f1a783c16e7268fa20)) +* fix console warning in widget ([d2353f2](https://github.com/rango-exchange/rango-client/commit/d2353f21945d38cfef4051d80b9577b7ab4da620)) +* fix full expanded design issues ([d1aaaa3](https://github.com/rango-exchange/rango-client/commit/d1aaaa30404da6ef8c1ff264a52e718db74f438f)) +* fix widget icon size issue and add connected wallet tooltip ([476267f](https://github.com/rango-exchange/rango-client/commit/476267feea9e176829a6df4bf0dbe6eef5ad4366)) + + +### Features + +* add a loading state for full-expanded-quote ([5c8fbe7](https://github.com/rango-exchange/rango-client/commit/5c8fbe744ae40f0d17e9c69d0653842d67a0d8a1)) +* add an expand mode for our compact widget ([eb90daa](https://github.com/rango-exchange/rango-client/commit/eb90daa540592c81efdca6e33032f6dbef371180)) +* add full expanded variant to widget ([a3907a0](https://github.com/rango-exchange/rango-client/commit/a3907a0be9f0716c366a2c482253191eebd66301)) +* add more languages to widget ([04f7855](https://github.com/rango-exchange/rango-client/commit/04f78551784b52e286f7f6206337d97bf8401063)) +* add sort filter for multi routing (compact mode) ([d90ddc6](https://github.com/rango-exchange/rango-client/commit/d90ddc6959c63a1ec2ef5908c09fc6ab8c3da23c)) +* implement expanded-mode route ([e75fcad](https://github.com/rango-exchange/rango-client/commit/e75fcad751dfdce0c4d84d08f2c9b41935584a75)) +* improve header buttons and notifications ([5f2188d](https://github.com/rango-exchange/rango-client/commit/5f2188d5cae62576bf13a5cefdc83625b9910c11)) +* improve playground mobile view and widget variants and liquidity sources ([3c2a4a6](https://github.com/rango-exchange/rango-client/commit/3c2a4a6375818d01a4c6682e03a60aa6972a8a02)) +* improve popover props & add some icons ([7bfd0dd](https://github.com/rango-exchange/rango-client/commit/7bfd0dd334054e0886420fff292ebe9858fb2300)) +* redesign switching theme in settings ([7fe0bc5](https://github.com/rango-exchange/rango-client/commit/7fe0bc510a56b717bed1bb20d7889d549c7144a1)) +* update colours for quote variant for rango/default theme ([897683f](https://github.com/rango-exchange/rango-client/commit/897683f5aa550af9a74e011e4ab3d734d7c595f7)) + + + +# [0.29.0](https://github.com/rango-exchange/rango-client/compare/ui@0.28.1...ui@0.29.0) (2024-02-20) + + +### Bug Fixes + +* apply playground improvements ([0ccf48b](https://github.com/rango-exchange/rango-client/commit/0ccf48bc14f582e55137a9c54df2f5679038f6d0)) +* fix widget ui minor bugs ([b881755](https://github.com/rango-exchange/rango-client/commit/b881755d59af22b41d8314f9925ecc4de04169db)) + + +### Features + +* add disabled state to reset configuration button and add successful reset toast - last changes ([3308718](https://github.com/rango-exchange/rango-client/commit/3308718f6a7699b946ec9471a96c2cd5ef1f5c19)) +* add portuguese language to widget ([a7d40e2](https://github.com/rango-exchange/rango-client/commit/a7d40e2604eede900901865fc5ff1707819929a6)) +* add TuneIcon & add style prop to popover ([6ba684d](https://github.com/rango-exchange/rango-client/commit/6ba684dcc230e4da35fe4c1f379fb60b957a9fa7)) +* add various transitions to toast component ([76e910c](https://github.com/rango-exchange/rango-client/commit/76e910ccd920714d42d8ba7011c3bf3ea09a1bbb)) +* change modal & toast interface ([009612e](https://github.com/rango-exchange/rango-client/commit/009612e09c2f269872b1e639fbcf7df8cce76f74)) +* implement multi routing in widget ([5003446](https://github.com/rango-exchange/rango-client/commit/50034463d25c552584201d0bd0d6a970fdda1d78)) +* passing enabled swappers/bridges to widget through the url for campaigns ([06a42a3](https://github.com/rango-exchange/rango-client/commit/06a42a3b1e3986a2735189d2e9f2d6b3725edd64)) + + + +## [0.28.1](https://github.com/rango-exchange/rango-client/compare/ui@0.28.0...ui@0.28.1) (2024-02-07) + + + +# [0.28.0](https://github.com/rango-exchange/rango-client/compare/ui@0.27.0...ui@0.28.0) (2024-02-05) + + +### Bug Fixes + +* widget ui bugs ([7d97336](https://github.com/rango-exchange/rango-client/commit/7d97336f2bc78a0c2f466124eccfe87772e760ad)) + + +### Features + +* add right anchor prop to modal component ([f3f2dac](https://github.com/rango-exchange/rango-client/commit/f3f2dacc1c96173dbf5455cf631aae4207c6a27b)) +* add transitionDuration prop to modal component ([b4241c7](https://github.com/rango-exchange/rango-client/commit/b4241c73fab7e341e51c177496f2406ec7346a74)) +* Adding title to config and export IDs for accessing blockchain image and swap input ([c3cdd97](https://github.com/rango-exchange/rango-client/commit/c3cdd979068a44a8d45ced7066a7e514a898325d)) +* feature management from server ([2075ac8](https://github.com/rango-exchange/rango-client/commit/2075ac8514e98df6ac3514fe541eb047ba2e196a)) +* implement toast component ([f88bc8c](https://github.com/rango-exchange/rango-client/commit/f88bc8c9b51299a0612c073e419dc4e75a83b7b1)) + + + +# [0.27.0](https://github.com/rango-exchange/rango-client/compare/ui@0.26.0...ui@0.27.0) (2024-01-22) + + +### Bug Fixes + +* address some minor bugs in swapHistory & wallet page loading ([1d4488e](https://github.com/rango-exchange/rango-client/commit/1d4488eee5926c2368bb9ba281ebf9fbc5c433e5)) +* apply some of playground feedbacks ([c3d6711](https://github.com/rango-exchange/rango-client/commit/c3d671158d5deea377538eef09f90e527f7d1b4e)) +* correct refresh icon style on firefox ([a788ecd](https://github.com/rango-exchange/rango-client/commit/a788ecd36aa91b369f7024ad6f9f3b5cc656c477)) +* correct token data type in storybook ([177f9fa](https://github.com/rango-exchange/rango-client/commit/177f9fa3b13d957f13004bfdb0de1d761f413742)) +* fix swap detail styles issue ([e74bb0c](https://github.com/rango-exchange/rango-client/commit/e74bb0cbbdd714f07a3128e1487200eeff25d8ba)) +* resolve issues for prices and dates, and add tooltips for prices ([7515215](https://github.com/rango-exchange/rango-client/commit/751521513aab2c108cecb150b81e0f921d1b603a)) +* styling issues on layout ([7f0e1bd](https://github.com/rango-exchange/rango-client/commit/7f0e1bd883045d6f0a398eeb353cf5280ac09455)) + + +### Features + +* add transition for tabs in playground ([067f782](https://github.com/rango-exchange/rango-client/commit/067f78287cd61de0f9ffba0bde6a9815ddd7613c)) +* adding a modal for fee on quote component ([d314516](https://github.com/rango-exchange/rango-client/commit/d314516b0af26ca71abf071462f19c9efef407e7)) +* export notifications from useWidget ([fc50baf](https://github.com/rango-exchange/rango-client/commit/fc50baf1b4043755162a54bcdd07f10fab94da39)) +* for long routes, we should show a shorter version and hide the rest in a button. ([378b3e4](https://github.com/rango-exchange/rango-client/commit/378b3e4508c8d9a32c0b7ba0b4c5f2a5ba32e193)) +* handle active tab in widget-embedded ([427a3bb](https://github.com/rango-exchange/rango-client/commit/427a3bb42dcaf899c4241aa5bd60c15a3475882a)) +* implement auto-refresh for routes ([9dfe80c](https://github.com/rango-exchange/rango-client/commit/9dfe80c00d01078bfd3f693c6a98ceb4038e58fb)) + + + +# [0.26.0](https://github.com/rango-exchange/rango-client/compare/ui@0.24.0...ui@0.26.0) (2023-12-24) + + +### Bug Fixes + +* fix HMR for widget and playground ([8524820](https://github.com/rango-exchange/rango-client/commit/8524820f10cf0b8921f3db0c4f620ff98daa4103)) +* fix quote info bugs ([3668d84](https://github.com/rango-exchange/rango-client/commit/3668d84a43e3d6055b8ff133f546aabce6fcf616)) +* fix wallet button state in swap details page ([ad57603](https://github.com/rango-exchange/rango-client/commit/ad57603885968b2792ed382dc80a3862dc0eebde)) +* improve widget for smaller screens ([75a3107](https://github.com/rango-exchange/rango-client/commit/75a310770ece2969833dda2789bee5b8ccda166e)) +* update blockchain category icons ([5ffd1ac](https://github.com/rango-exchange/rango-client/commit/5ffd1ac9bbe4cee26500c010718f4f530b1349f6)) +* update classNames to new pattern for conflict prevention ([3c89278](https://github.com/rango-exchange/rango-client/commit/3c8927893381774f8bc8dc5b049ffdfccea1ffe4)) + + +### Features + +* add dark/light theme to playground ([01c4c45](https://github.com/rango-exchange/rango-client/commit/01c4c45cf42a5b9a945e687fbaf3cb141ca19d13)) +* add langugage section to Playground ([c2deaec](https://github.com/rango-exchange/rango-client/commit/c2deaec91813f7e5cc4bccc2be78f5c297cc1a2d)) + + + +# [0.14.0](https://github.com/rango-exchange/rango-client/compare/ui@0.13.0...ui@0.14.0) (2023-08-03) + + + +# [0.13.0](https://github.com/rango-exchange/rango-client/compare/ui@0.12.0...ui@0.13.0) (2023-08-01) + + + +# [0.9.0](https://github.com/rango-exchange/rango-client/compare/ui@0.8.0...ui@0.9.0) (2023-07-31) + + +### Features + +* add project id as a external value ([0c80404](https://github.com/rango-exchange/rango-client/commit/0c80404a8cacb6c5b0338dea1e416b0b11db254b)) +* Support for WalletConnect 2 ([faedef0](https://github.com/rango-exchange/rango-client/commit/faedef0b5e6fc3c5ef881cbbe4ec05334cc1c910)) + + + +# [0.8.0](https://github.com/rango-exchange/rango-client/compare/ui@0.7.0...ui@0.8.0) (2023-07-11) + + +### Bug Fixes + +* adding lingui to ui and embedded packages ([efed0d6](https://github.com/rango-exchange/rango-client/commit/efed0d6da437bfd472f26a280adc55da1151966a)) +* fix lingui version ([b7de08b](https://github.com/rango-exchange/rango-client/commit/b7de08b457314192665b9d3afa809e63ecd311a8)) + + + +# [0.7.0](https://github.com/rango-exchange/rango-client/compare/ui@0.6.0...ui@0.7.0) (2023-07-11) + + + +# [0.6.0](https://github.com/rango-exchange/rango-client/compare/ui@0.5.0...ui@0.6.0) (2023-07-11) + + +### Features + +* setup lingui for multi-language in widget ([a3f1331](https://github.com/rango-exchange/rango-client/commit/a3f1331def487989a5717335b062dd9ef45876ad)) + + + +# [0.5.0](https://github.com/rango-exchange/rango-client/compare/ui@0.4.0...ui@0.5.0) (2023-05-31) + + + +# [0.4.0](https://github.com/rango-exchange/rango-client/compare/ui@0.3.0...ui@0.4.0) (2023-05-31) + + + +# [0.3.0](https://github.com/rango-exchange/rango-client/compare/ui@0.2.0...ui@0.3.0) (2023-05-30) + + + +# [0.2.0](https://github.com/rango-exchange/rango-client/compare/ui@0.1.15...ui@0.2.0) (2023-05-30) + + +### Bug Fixes + +* deleted consoles ([5fef4b9](https://github.com/rango-exchange/rango-client/commit/5fef4b912510ee2e1f0b4fe107140761e63c3ca8)) +* fix wallet adapter demo build ([43a3beb](https://github.com/rango-exchange/rango-client/commit/43a3bebb50ce10e7e72944f5465c0c66d01e265d)) +* fix widget ui build ([c3b5900](https://github.com/rango-exchange/rango-client/commit/c3b590058d3bd35b58ac053d1eb25b55e7e1b107)) +* images and preview of confirm swap, completed ([5da81f4](https://github.com/rango-exchange/rango-client/commit/5da81f4a76dda4d76f794d7042c9e39d8846e3ba)) +* Some functions were transferred to helper ([7d5756f](https://github.com/rango-exchange/rango-client/commit/7d5756fc476728e84b16300102918542520983a7)) +* theme.ts was broken on some build tools like webpack ([8577d21](https://github.com/rango-exchange/rango-client/commit/8577d218b5b6a1e91aef40d0671578e72f396b03)) + + + +## [0.1.14](https://github.com/rango-exchange/rango-client/compare/ui@0.1.13...ui@0.1.14) (2023-05-15) + + +### Bug Fixes + +* Fixed colorpicker ([d821340](https://github.com/rango-exchange/rango-client/commit/d821340fc3f5df07ccbfc3555ae4d7dba0cad49b)) +* some polishment on playground ([cf17f9e](https://github.com/rango-exchange/rango-client/commit/cf17f9e2ac2efc9467c4f550e09eaf19170bbbf0)) +* update rango-types and fix notification bugs ([993f185](https://github.com/rango-exchange/rango-client/commit/993f185e0b8c5e5e15a2c65ba2d85d1f9c8daa90)) + + + diff --git a/widget/ui/README.md b/widget/ui/README.md deleted file mode 100644 index 2c348a4cf6..0000000000 --- a/widget/ui/README.md +++ /dev/null @@ -1 +0,0 @@ -# @rango-dev/ui diff --git a/widget/ui/package.json b/widget/ui/package.json index 849dacd412..cbcdedc00b 100644 --- a/widget/ui/package.json +++ b/widget/ui/package.json @@ -1,88 +1,65 @@ { "name": "@rango-dev/ui", - "version": "0.1.12", + "version": "0.42.1-next.11", "license": "MIT", - "main": "dist/index.js", - "typings": "dist/index.d.ts", + "type": "module", + "source": "./src/index.ts", + "main": "./dist/index.js", + "exports": { + "types": "./dist/widget/ui/src/index.d.ts", + "default": "./dist/index.js" + }, + "typings": "./dist/widget/ui/src/index.d.ts", "files": [ "dist", "src" ], "scripts": { - "dev": "tsdx watch", - "build": "tsdx build --tsconfig ./tsconfig.json", - "test": "tsdx test --passWithNoTests", - "lint": "tsdx lint", - "prepare": "tsdx build --tsconfig ./tsconfig.json", - "size": "size-limit", - "analyze": "size-limit --why", - "storybook": "start-storybook -p 3000", - "build-storybook": "build-storybook" + "dev": "yarn bundle --watch", + "build": "node ../../scripts/build/command.mjs --path widget/ui", + "ts-check": "tsc --declaration --emitDeclarationOnly -p ./tsconfig.json", + "build:icons": "svgr svgs/resources/fill --config-file svgs/configs/.svgrrc.default.cjs", + "type-checking": "tsc --declaration --emitDeclarationOnly", + "clean": "rimraf dist", + "format": "prettier --write '{.,src}/**/*.{ts,tsx}'", + "lint": "eslint \"**/*.{ts,tsx}\" --ignore-path ../../.eslintignore" }, "peerDependencies": { - "@rango-dev/queue-manager-rango-preset": "*", + "@lingui/core": "4.2.1", + "@lingui/react": "4.2.1", "react": ">=16" }, - "husky": { - "hooks": { - "pre-commit": "tsdx lint" - } - }, - "prettier": { - "printWidth": 80, - "semi": true, - "singleQuote": true, - "trailingComma": "es5" - }, - "module": "dist/ui.esm.js", - "size-limit": [ - { - "path": "dist/ui.cjs.production.min.js", - "limit": "10 KB" - }, - { - "path": "dist/ui.esm.js", - "limit": "10 KB" - } - ], "devDependencies": { "@babel/core": "^7.20.2", - "@size-limit/preset-small-lib": "^8.1.0", - "@storybook/addon-essentials": "^6.5.13", - "@storybook/addon-info": "^5.3.21", - "@storybook/addon-links": "^6.5.13", - "@storybook/addons": "^6.5.13", - "@storybook/react": "^6.5.13", + "@babel/preset-env": "^7.21.4", + "@babel/preset-react": "^7.18.6", + "@babel/preset-typescript": "^7.21.4", + "@lingui/core": "4.2.1", + "@lingui/react": "4.2.1", + "@svgr/babel-plugin-remove-jsx-attribute": "8.0.0", + "@svgr/cli": "^8.0.1", "@types/react": "^18.0.25", "@types/react-dom": "^18.0.8", - "@types/react-virtualized-auto-sizer": "^1.0.1", - "@types/react-window": "^1.8.5", - "@types/react-window-infinite-loader": "^1.0.6", "babel-loader": "^9.1.0", - "husky": "^8.0.2", "react": "^18.2.0", "react-dom": "^18.2.0", - "react-is": "^18.2.0", - "size-limit": "^8.1.0", - "tsdx": "^0.14.1", - "tslib": "^2.4.1", - "typescript": "^4.8.4" + "react-is": "^18.2.0" }, "dependencies": { "@radix-ui/react-checkbox": "^1.0.1", + "@radix-ui/react-collapsible": "^1.0.3", + "@radix-ui/react-popover": "^1.0.6", "@radix-ui/react-radio-group": "^1.1.1", + "@radix-ui/react-select": "^2.0.0", "@radix-ui/react-switch": "^1.0.1", "@radix-ui/react-tooltip": "^1.0.2", - "@rango-dev/wallets-shared": "^0.1.11", + "@rango-dev/wallets-shared": "^0.40.1-next.6", "@stitches/react": "^1.2.8", - "@types/react-color": "^3.0.6", - "rango-sdk": "^0.1.20", - "react-color": "^2.19.3", - "react-virtualized-auto-sizer": "^1.0.7", - "react-window": "^1.8.8", - "react-window-infinite-loader": "^1.0.8" + "copy-to-clipboard": "^3.3.3", + "rango-types": "^0.1.74", + "react-virtuoso": "^4.6.2" }, "publishConfig": { "access": "public" } -} +} \ No newline at end of file diff --git a/widget/ui/readme.md b/widget/ui/readme.md new file mode 100644 index 0000000000..eab5cbaa7a --- /dev/null +++ b/widget/ui/readme.md @@ -0,0 +1,8 @@ +# @rango-dev/ui + +Rango UI components + +### Icons + +Add your svg icon to `svgs/resources/` then run `yarn build:icons`. + diff --git a/widget/ui/src/components/Alert/Alert.helpers.ts b/widget/ui/src/components/Alert/Alert.helpers.ts new file mode 100644 index 0000000000..4d8329d70b --- /dev/null +++ b/widget/ui/src/components/Alert/Alert.helpers.ts @@ -0,0 +1,28 @@ +import type { AlertPropTypes, Type } from './Alert.types.js'; + +export const getColor = (type: Type, variant: AlertPropTypes['variant']) => { + if (variant === 'regular') { + return undefined; + } + + switch (type) { + case 'success': + case 'warning': + case 'error': + case 'info': + return `${type}500`; + default: + return undefined; + } +}; + +export const mapVariantToSize = (variant: AlertPropTypes['variant']) => { + switch (variant) { + case 'alarm': + return 'small'; + case 'regular': + return 'xsmall'; + default: + return 'xsmall'; + } +}; diff --git a/widget/ui/src/components/Alert/Alert.icon.tsx b/widget/ui/src/components/Alert/Alert.icon.tsx new file mode 100644 index 0000000000..0594f88f29 --- /dev/null +++ b/widget/ui/src/components/Alert/Alert.icon.tsx @@ -0,0 +1,28 @@ +import type { AlertPropTypes } from './Alert.types.js'; + +import React from 'react'; + +import { + CompleteIcon, + ErrorIcon, + InfoErrorIcon, + WarningIcon, +} from '../../icons/index.js'; +import { Spinner } from '../Spinner/index.js'; + +function AlertIcon(props: Pick) { + switch (props.type) { + case 'success': + return ; + case 'warning': + return ; + case 'error': + return ; + case 'loading': + return ; + default: + return ; + } +} + +export default AlertIcon; diff --git a/widget/ui/src/components/Alert/Alert.stories.tsx b/widget/ui/src/components/Alert/Alert.stories.tsx deleted file mode 100644 index 111a2529d1..0000000000 --- a/widget/ui/src/components/Alert/Alert.stories.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import React from 'react'; -import { ComponentMeta } from '@storybook/react'; -import { Alert } from '.'; -import { PropTypes } from './Alert'; - -export default { - title: 'Alert', - component: Alert, - argTypes: { - type: { - defaultValue: 'success', - }, - title: { - defaultValue: 'Alert Title', - }, - description: { - defaultValue: 'Alert description ...', - }, - }, -} as ComponentMeta; - -export const Main = (args: PropTypes) => ; diff --git a/widget/ui/src/components/Alert/Alert.styles.ts b/widget/ui/src/components/Alert/Alert.styles.ts new file mode 100644 index 0000000000..7484a9cd2d --- /dev/null +++ b/widget/ui/src/components/Alert/Alert.styles.ts @@ -0,0 +1,169 @@ +import { darkTheme, styled } from '../../theme.js'; + +export const Container = styled('div', { + display: 'flex', + flexDirection: 'column', + borderRadius: '$xs', + '.title_typography': { + width: '100%', + }, + '.title_typography:first-letter': { + textTransform: 'uppercase', + }, + + '.footer': { + paddingTop: '$5', + paddingLeft: '$24', + }, + '.description': { + color: '$neutral700', + fontSize: '$10', + lineHeight: '$12', + }, + variants: { + type: { + success: {}, + warning: {}, + error: {}, + info: {}, + loading: {}, + }, + variant: { + regular: { + padding: '$5', + alignItems: 'flex-start', + backgroundColor: '$neutral400', + }, + alarm: { + padding: '$5 $10', + '.title_typography': { + fontWeight: '$medium', + }, + }, + }, + }, + + compoundVariants: [ + { + type: 'warning', + variant: 'alarm', + css: { + $$color: '$colors$warning100', + [`.${darkTheme} &`]: { + $$color: '$colors$warning700', + }, + backgroundColor: '$$color', + }, + }, + { + type: 'error', + variant: 'alarm', + css: { + $$color: '$colors$error100', + [`.${darkTheme} &`]: { + $$color: '$colors$error700', + }, + backgroundColor: '$$color', + }, + }, + { + type: 'info', + variant: 'alarm', + css: { + $$color: '$colors$info100', + [`.${darkTheme} &`]: { + $$color: '$colors$info700', + }, + backgroundColor: '$$color', + }, + }, + { + type: 'success', + variant: 'alarm', + css: { + $$color: '$colors$success100', + [`.${darkTheme} &`]: { + $$color: '$colors$success700', + }, + backgroundColor: '$$color', + }, + }, + ], +}); + +export const Main = styled('div', { + display: 'flex', + alignItems: 'center', + alignSelf: 'stretch', + variants: { + variant: { + regular: { + justifyContent: 'space-between', + }, + alarm: { + justifyContent: 'flex-start', + }, + }, + }, +}); + +export const TitleContainer = styled('div', { + display: 'flex', + alignItems: 'center', + flex: '1 0 0', +}); + +export const IconHighlight = styled('div', { + borderRadius: '$lg', + width: '$20', + height: '$20', + display: 'flex', + justifyContent: 'center', + alignItems: 'center', + alignSelf: 'flex-start', + flexShrink: 0, + variants: { + type: { + success: { + $$color: '$colors$success300', + [`.${darkTheme} &`]: { + $$color: '$colors$success600', + }, + backgroundColor: '$$color', + }, + warning: { + $$color: '$colors$warning300', + [`.${darkTheme} &`]: { + $$color: '$colors$warning600', + }, + backgroundColor: '$$color', + }, + error: { + $$color: '$colors$error300', + [`.${darkTheme} &`]: { + $$color: '$colors$error600', + }, + backgroundColor: '$$color', + }, + info: { + $$color: '$colors$info300', + [`.${darkTheme} &`]: { + $$color: '$colors$info600', + }, + backgroundColor: '$$color', + }, + loading: { + $$color: '$colors$info300', + [`.${darkTheme} &`]: { + $$color: '$colors$info600', + }, + backgroundColor: '$$color', + }, + }, + align: { + center: { + alignSelf: 'center', + }, + }, + }, +}); diff --git a/widget/ui/src/components/Alert/Alert.tsx b/widget/ui/src/components/Alert/Alert.tsx index cfe44f5c77..6a457412c8 100644 --- a/widget/ui/src/components/Alert/Alert.tsx +++ b/widget/ui/src/components/Alert/Alert.tsx @@ -1,102 +1,69 @@ -import React, { PropsWithChildren, ReactNode } from 'react'; -import { CheckCircleIcon, InfoCircleIcon, WarningIcon } from '../Icon'; -import { Typography } from '../Typography'; -import { styled } from '../../theme'; -import { Spacer } from '../Spacer'; +import type { AlertPropTypes } from './Alert.types.js'; +import type { PropsWithChildren } from 'react'; -const MainContainer = styled('div', { - width: '100%', - padding: '$16', - borderRadius: '$5', - backgroundColor: '$neutrals300', - color: '$neutrals800', +import React from 'react'; - '.main': { - display: 'flex', - alignItems: 'center', - }, +import { Divider } from '../Divider/index.js'; +import { Typography } from '../Typography/index.js'; - '.footer': { - paddingTop: '$8', - }, - '&.hasIcon .footer': { - paddingLeft: '$32', - }, - variants: { - type: { - primary: { - color: '$primary200', - }, - secondary: { - color: '$foreground', - }, - success: { - color: '$success300', - }, - warning: { - color: '$warning500', - }, - error: { - color: '$error300', - }, - }, - }, -}); +import { getColor, mapVariantToSize } from './Alert.helpers.js'; +import AlertIcon from './Alert.icon.js'; +import { + Container, + IconHighlight, + Main, + TitleContainer, +} from './Alert.styles.js'; -export interface PropTypes { - type?: 'primary' | 'secondary' | 'success' | 'warning' | 'error'; - title?: string; - footer?: ReactNode; -} - -export function Alert(props: PropsWithChildren) { - const { type, children, title } = props; - - const showIcon = ( - ['error', 'success', 'warning'] as PropTypes['type'][] - ).includes(type); +export function Alert(props: PropsWithChildren) { + const { + type, + title, + footer, + action, + containerStyles, + variant = 'regular', + titleAlign, + } = props; + const isFooterString = typeof footer === 'string'; return ( - -
- {showIcon && ( - <> -
- {type === 'success' && } - {type === 'warning' && } - {type === 'error' && } - -
- - )} -
+ +
+ + + + + {title && ( - <> - - {title} - - {!!children && } - + + {title} + )} - {children} + + {action ? ( + <> + +
{action}
+ + ) : null} +
+ {footer ? ( +
+ {footer}
-
- {props.footer ?
{props.footer}
: null} - + ) : null} + ); } + +Alert.toString = () => '._alert'; diff --git a/widget/ui/src/components/Alert/Alert.types.ts b/widget/ui/src/components/Alert/Alert.types.ts new file mode 100644 index 0000000000..5e510a3caf --- /dev/null +++ b/widget/ui/src/components/Alert/Alert.types.ts @@ -0,0 +1,15 @@ +import type { CSS } from '../../theme.js'; +import type { BaseAlign } from '../Typography/Typography.types.js'; +import type { ReactNode } from 'react'; + +export type Type = 'success' | 'warning' | 'error' | 'info' | 'loading'; + +export interface AlertPropTypes { + type: Type; + title?: ReactNode; + footer?: ReactNode; + action?: ReactNode; + variant?: 'alarm' | 'regular'; + containerStyles?: CSS; + titleAlign?: BaseAlign; +} diff --git a/widget/ui/src/components/Alert/LoadingFailedAlert.tsx b/widget/ui/src/components/Alert/LoadingFailedAlert.tsx deleted file mode 100644 index 703570106a..0000000000 --- a/widget/ui/src/components/Alert/LoadingFailedAlert.tsx +++ /dev/null @@ -1,11 +0,0 @@ -import React from 'react'; -import { Alert } from './Alert'; - -export function LoadingFailedAlert() { - return ( - - ); -} diff --git a/widget/ui/src/components/Alert/NotFoundAlert.tsx b/widget/ui/src/components/Alert/NotFoundAlert.tsx deleted file mode 100644 index c2ab57754b..0000000000 --- a/widget/ui/src/components/Alert/NotFoundAlert.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import React from 'react'; -import { Alert } from './Alert'; - -interface PropTypes { - catergory: string; - searchedFor?: string; -} - -export function NotFoundAlert(props: PropTypes) { - const { catergory, searchedFor } = props; - return ( - - ); -} diff --git a/widget/ui/src/components/Alert/index.ts b/widget/ui/src/components/Alert/index.ts index 076d532971..b617436f93 100644 --- a/widget/ui/src/components/Alert/index.ts +++ b/widget/ui/src/components/Alert/index.ts @@ -1,2 +1,2 @@ -export { Alert } from './Alert'; -export { LoadingFailedAlert } from './LoadingFailedAlert'; +export { Alert } from './Alert.js'; +export type { AlertPropTypes } from './Alert.types.js'; diff --git a/widget/ui/src/components/BestRoute/BestRoute.stories.tsx b/widget/ui/src/components/BestRoute/BestRoute.stories.tsx deleted file mode 100644 index 52b1e37355..0000000000 --- a/widget/ui/src/components/BestRoute/BestRoute.stories.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import React from 'react'; -import { ComponentMeta } from '@storybook/react'; -import { BestRoute, PropTypes } from './BestRoute'; -import { bestRoute, bestRouteExample2, bestRouteExample3 } from './mock'; - -export default { - title: 'Components/Best Route', - component: BestRoute, -} as ComponentMeta; - -export const Main = (props: PropTypes) => ( -
- -
-); -export const With4Step = (props: PropTypes) => ( -
- -
-); - -export const With2Step = (props: PropTypes) => ( -
- -
-); -export const WithError = (props: PropTypes) => ( -
- -
-); diff --git a/widget/ui/src/components/BestRoute/BestRoute.tsx b/widget/ui/src/components/BestRoute/BestRoute.tsx deleted file mode 100644 index 5e96c0c0be..0000000000 --- a/widget/ui/src/components/BestRoute/BestRoute.tsx +++ /dev/null @@ -1,229 +0,0 @@ -import React, { Fragment, PropsWithChildren } from 'react'; -import { GasIcon, TimeIcon } from '../../components/Icon'; -import { StepDetail } from '../../components/StepDetail'; -import { Typography } from '../../components/Typography'; -import { keyframes, styled } from '../../theme'; -import { Skeleton } from '../Skeleton'; -import { Spinner } from '../Spinner'; -import { BestRouteResponse } from 'rango-sdk'; -import { Tooltip } from '../Tooltip'; -import { Image } from '../common'; - -const Container = styled('div', { - borderRadius: '$5', - border: '1px solid $neutrals300', - display: 'flex', - alignItems: 'center', - minHeight: 126, - justifyContent: 'space-between', -}); - -const ErrorMsg = styled(Typography, { - color: '$error', -}); -const BestRouteContainer = styled('div', { - display: 'flex', - alignItems: 'center', - margin: '0 auto', - overflowX: 'auto', - overflowY: 'hidden', - alignSelf: 'stretch', - padding: '$4', - '@md': { - padding: '$8', - }, -}); -const Line = styled('div', { - height: '0', - width: '$20', - border: '1px dashed $foreground', - borderRadius: 'inherit', - '@lg': { - width: '$32', - }, -}); - -const HR = styled('hr', { - width: '100%', - border: '1px solid $neutrals400', - margin: '$8 0', -}); - -const RelativeContainer = styled('div', { - position: 'relative', -}); -const Dot = styled('div', { - width: '$6', - height: '$6', - backgroundColor: '$foreground', - position: 'absolute', - top: '45%', - right: -5, - marginLeft: '$8', - borderRadius: '50%', - '@md': { - width: '$8', - height: '$8', - right: -8, - top: '45%', - }, -}); -const ArrowRight = styled('div', { - width: '0px', - height: '0px', - borderTop: '5px solid transparent', - borderBottom: '5px solid transparent', - borderLeft: '5px solid $foreground', -}); - -export const pulse = keyframes({ - '0%': { - opacity: 1, - }, - '50%': { - opacity: 0.3, - }, - '100%': { - opacity: 1, - }, -}); - -const GasContainer = styled('div', { - backgroundColor: '$neutrals300', - borderRadius: '5px', - margin: '$4', - display: 'flex', - flexDirection: 'column', - justifyContent: 'center', - alignItems: 'center', - padding: '$4', - '@md': { - padding: '$8', - margin: '$8', - }, -}); - -const CostContainer = styled('div', { - display: 'flex', - flexDirection: 'column', - alignItems: 'center', - variants: { - warning: { - true: { - animation: `${pulse} 2s ease-in-out infinite`, - }, - }, - }, -}); - -const TotalFee = styled(Typography, { - variants: { - warning: { - true: { - color: '$warning300', - }, - }, - }, -}); - -const SkeletonContainer = styled('div', { - padding: '$4', - '@md': { - padding: '$8', - }, -}); -const SwapperContainer = styled('div', { - display: 'flex', - justifyContent: 'center', - alignItems: 'center', -}); - -export interface PropTypes { - data: BestRouteResponse | null; - totalFee: string; - feeWarning: boolean; - totalTime: string; - loading?: boolean; - error?: string; -} -export function BestRoute(props: PropsWithChildren) { - const { data, loading, error, totalFee, feeWarning, totalTime } = props; - return ( - - {loading ? ( - - - - ) : ( - - - - - - {error && '-'} - {!!data && `$${totalFee}`} - - - -
- - - - - {error && '-'} - {!!data && `~${totalTime}m`} - - - -
- )} - - {loading && } - - {error && {error}} - - {!!data && - data.result?.swaps.map((swap, index) => ( - - {index === 0 && ( - - - - - )} - - - {swap.swapperId} - - - - {index + 1 === data.result?.swaps.length && } - - - ))} - {!!data && !data?.result && ( - No routes found - )} - -
- ); -} diff --git a/widget/ui/src/components/BestRoute/index.ts b/widget/ui/src/components/BestRoute/index.ts deleted file mode 100644 index c880f8a2fa..0000000000 --- a/widget/ui/src/components/BestRoute/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { BestRoute } from './BestRoute'; diff --git a/widget/ui/src/components/BestRoute/mock.ts b/widget/ui/src/components/BestRoute/mock.ts deleted file mode 100644 index 83d5bb3f63..0000000000 --- a/widget/ui/src/components/BestRoute/mock.ts +++ /dev/null @@ -1,554 +0,0 @@ -import { RoutingResultType } from 'rango-sdk'; -import { BestRouteType } from '../../types/swaps'; - -// TODO: I used `internalSwaps: []` to fix ts error. fix it by using real data. - -export const bestRoute: BestRouteType = { - from: { blockchain: 'BSC', symbol: 'BNB', address: null }, - to: { blockchain: 'AVAX_CCHAIN', symbol: 'AVAX', address: null }, - requestAmount: '0.3', - requestId: '228529e3-27d7-4fa9-ab84-bb2b90eade6f', - result: { - resultType: RoutingResultType.OK, - outputAmount: '5.685715974132648891', - swaps: [ - { - // TODO: fix this and use real data - internalSwaps: [], - swapperId: 'AnySwap Aggregator', - swapperType: 'AGGREGATOR', - swapperLogo: 'https://api.rango.exchange/swappers/multichain.png', - maxRequiredSign: 1, - warnings: [], - from: { - symbol: 'BNB', - logo: 'https://api.rango.exchange/i/Y3v1KW', - blockchainLogo: 'https://api.rango.exchange/blockchains/binance.svg', - - address: null, - blockchain: 'BSC', - decimals: 18, - usdPrice: 279.2738558274085, - }, - to: { - symbol: 'WETH.E', - logo: 'https://api.rango.exchange/i/j9xgdC', - blockchainLogo: - 'https://api.rango.exchange/blockchains/avax_cchain.svg', - - address: '0x49d5c2bdffac6ce2bfdb6640f4f80f226bc10bab', - blockchain: 'AVAX_CCHAIN', - decimals: 18, - usdPrice: 1329.24, - }, - fromAmount: '0.300000000000000000', - fromAmountPrecision: null, - fromAmountMinValue: '0.047579322466294684272760', - fromAmountMaxValue: '79302.26195302606417382090', - fromAmountRestrictionType: 'INCLUSIVE', - toAmount: '0.062064305934309070', - fee: [ - { - asset: { - blockchain: 'BSC', - symbol: 'BNB', - address: null, - }, - expenseType: 'FROM_SOURCE_WALLET', - amount: '0.001388002000000000', - name: 'Network Fee', - }, - ], - estimatedTimeInSeconds: 300, - swapChainType: 'INTRA_CHAIN', - routes: null, - recommendedSlippage: null, - timeStat: { min: 162, avg: 260, max: 467 }, - includesDestinationTx: false, - }, - { - internalSwaps: [], - swapperId: 'PangolinSwap', - swapperLogo: 'https://api.rango.exchange/swappers/pangolin.png', - swapperType: 'DEX', - maxRequiredSign: 1, - warnings: [], - from: { - symbol: 'WETH.E', - logo: 'https://api.rango.exchange/i/j9xgdC', - address: '0x49d5c2bdffac6ce2bfdb6640f4f80f226bc10bab', - blockchain: 'AVAX_CCHAIN', - decimals: 18, - usdPrice: 1329.24, - blockchainLogo: - 'https://api.rango.exchange/blockchains/avax_cchain.svg', - }, - to: { - symbol: 'AVAX', - logo: 'https://api.rango.exchange/i/kX4edQ', - address: null, - blockchain: 'AVAX_CCHAIN', - decimals: 18, - usdPrice: 12.5, - blockchainLogo: - 'https://api.rango.exchange/blockchains/avax_cchain.svg', - }, - fromAmount: '0.062064305934309070', - fromAmountPrecision: null, - fromAmountMinValue: null, - fromAmountMaxValue: null, - fromAmountRestrictionType: 'EXCLUSIVE', - toAmount: '5.685715974132648891', - fee: [ - { - asset: { - blockchain: 'AVAX_CCHAIN', - symbol: 'WETH.E', - address: '0x49d5c2bdffac6ce2bfdb6640f4f80f226bc10bab', - }, - expenseType: 'DECREASE_FROM_OUTPUT', - name: 'Network Fee', - amount: - '0.00018619291780292721387591870688029381530892436558133340440690517425537109375', - }, - { - asset: { blockchain: 'AVAX_CCHAIN', symbol: 'AVAX', address: null }, - expenseType: 'FROM_SOURCE_WALLET', - name: 'Network Fee', - amount: '0.005370022532678750', - }, - ], - estimatedTimeInSeconds: 45, - swapChainType: 'INTER_CHAIN', - routes: [ - { - nodes: [ - { - nodes: [ - { - marketName: 'PangolinSwap', - marketId: 'PangolinSwap', - percent: 1.0, - }, - ], - from: 'WETH.e', - fromLogo: '', - fromAddress: '0x49d5c2bdffac6ce2bfdb6640f4f80f226bc10bab', - fromBlockchain: 'AVAX_CCHAIN', - to: 'WAVAX', - toLogo: '', - toAddress: '0xb31f66aa3c1e785363f0875a1b74e27b85fd66c7', - toBlockchain: 'AVAX_CCHAIN', - }, - ], - }, - ], - recommendedSlippage: null, - timeStat: { min: 6, avg: 39, max: 317 }, - includesDestinationTx: false, - }, - ], - }, - validationStatus: null, - missingBlockchains: [], - diagnosisMessages: [], - processingLimitReached: false, - walletNotSupportingFromBlockchain: false, -}; -export const bestRouteExample2: BestRouteType = { - from: { - blockchain: 'BSC', - symbol: 'USDC', - address: '0x8ac76a51cc950d9822d68b83fe1ad97b32cd580d', - }, - to: { blockchain: 'AKASH', symbol: 'AKT', address: null }, - requestAmount: '10', - requestId: '56a3f944-02ec-4011-b3c6-6c76c3ad049b', - result: { - resultType: RoutingResultType.OK, - outputAmount: '30.983906', - swaps: [ - { - internalSwaps: [], - maxRequiredSign: 1, - warnings: [], - swapperId: 'ParaSwap Bsc', - swapperType: 'DEX', - swapperLogo: 'https://api.rango.exchange/swappers/para-swap.png', - - from: { - symbol: 'USDC', - blockchainLogo: 'https://api.rango.exchange/blockchains/binance.svg', - - logo: 'https://api.rango.exchange/i/toXKGV', - address: '0x8ac76a51cc950d9822d68b83fe1ad97b32cd580d', - blockchain: 'BSC', - decimals: 18, - usdPrice: 1.0, - }, - to: { - symbol: 'AXLUSDC', - blockchainLogo: 'https://api.rango.exchange/blockchains/binance.svg', - logo: 'https://api.rango.exchange/tokens/COSMOS/AXLUSDC.png', - address: '0x4268b8f0b87b6eae5d897996e6b845ddbd99adf3', - blockchain: 'BSC', - decimals: 6, - usdPrice: 1.0, - }, - fromAmount: '10.000000000000000000', - fromAmountPrecision: null, - fromAmountMinValue: null, - fromAmountMaxValue: null, - fromAmountRestrictionType: 'EXCLUSIVE', - toAmount: '9.957577', - fee: [ - { - asset: { blockchain: 'BSC', symbol: 'BNB', address: null }, - expenseType: 'FROM_SOURCE_WALLET', - amount: '0.002179644500000000', - name: 'Network Fee', - }, - { - asset: { - blockchain: 'BSC', - symbol: 'AXLUSDC', - address: '0x4268b8f0b87b6eae5d897996e6b845ddbd99adf3', - }, - expenseType: 'DECREASE_FROM_OUTPUT', - amount: '0.004978', - name: 'Network Fee', - }, - ], - estimatedTimeInSeconds: 60, - swapChainType: 'INTER_CHAIN', - routes: [ - { - nodes: [ - { - nodes: [ - { - marketName: 'PancakeSwap', - marketId: 'PancakeSwap', - percent: 1.0, - }, - ], - from: 'USDC', - fromLogo: - 'https://tokens.pancakeswap.finance/images/0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d.png', - fromAddress: '0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d', - fromBlockchain: 'BSC', - to: 'BUSD', - toLogo: - 'https://tokens.pancakeswap.finance/images/0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56.png', - toAddress: '0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56', - toBlockchain: 'BSC', - }, - { - nodes: [ - { - marketName: 'Ellipsis', - marketId: 'Ellipsis', - percent: 1.0, - }, - ], - from: 'BUSD', - fromLogo: - 'https://tokens.pancakeswap.finance/images/0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56.png', - fromAddress: '0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56', - fromBlockchain: 'BSC', - to: 'axlUSDC', - toLogo: 'https://api.rango.exchange/tokens/COSMOS/AXLUSDC.png', - toAddress: '0x4268b8f0b87b6eae5d897996e6b845ddbd99adf3', - toBlockchain: 'BSC', - }, - ], - }, - ], - recommendedSlippage: null, - timeStat: { min: 6, avg: 52, max: 183 }, - includesDestinationTx: false, - }, - { - internalSwaps: [], - maxRequiredSign: 1, - warnings: [], - swapperId: 'Satellite', - swapperType: 'BRIDGE', - swapperLogo: 'https://api.rango.exchange/swappers/satellite.png', - from: { - symbol: 'AXLUSDC', - blockchainLogo: 'https://api.rango.exchange/blockchains/binance.svg', - logo: 'https://api.rango.exchange/tokens/COSMOS/AXLUSDC.png', - address: '0x4268b8f0b87b6eae5d897996e6b845ddbd99adf3', - blockchain: 'BSC', - decimals: 6, - usdPrice: 1.0, - }, - to: { - symbol: 'USDC', - blockchainLogo: 'https://api.rango.exchange/swappers/osmosis.png', - logo: 'https://api.rango.exchange/tokens/COSMOS/USDC.png', - address: - 'ibc/d189335c6e4a68b513c10ab227bf1c1d38c746766278ba3eeb4fb14124f1d858', - blockchain: 'OSMOSIS', - decimals: 6, - usdPrice: 1.0000000008037055, - }, - fromAmount: '9.957577', - fromAmountPrecision: null, - fromAmountMinValue: null, - fromAmountMaxValue: null, - fromAmountRestrictionType: 'EXCLUSIVE', - toAmount: '8.357577', - fee: [ - { - asset: { blockchain: 'BSC', symbol: 'BNB', address: null }, - expenseType: 'FROM_SOURCE_WALLET', - amount: - '0.0003850000000000000239784127112452447212753714467226018314249813556671142578125000000000000', - name: 'Network Fee', - }, - ], - estimatedTimeInSeconds: 360, - swapChainType: 'INTER_CHAIN', - routes: null, - recommendedSlippage: null, - timeStat: { min: 9, avg: 339, max: 1138 }, - includesDestinationTx: false, - }, - { - internalSwaps: [], - maxRequiredSign: 1, - warnings: [], - swapperId: 'Osmosis', - swapperType: 'DEX', - swapperLogo: 'https://api.rango.exchange/swappers/osmosis.png', - from: { - symbol: 'USDC', - logo: 'https://api.rango.exchange/tokens/COSMOS/USDC.png', - blockchainLogo: 'https://api.rango.exchange/swappers/osmosis.png', - address: - 'ibc/d189335c6e4a68b513c10ab227bf1c1d38c746766278ba3eeb4fb14124f1d858', - blockchain: 'OSMOSIS', - decimals: 6, - usdPrice: 1.0000000008037055, - }, - to: { - symbol: 'AKT', - logo: 'https://api.rango.exchange/tokens/COSMOS/AKT.png', - blockchainLogo: 'https://api.rango.exchange/swappers/osmosis.png', - address: - 'ibc/1480b8fd20ad5fcae81ea87584d269547dd4d436843c1d20f15e00eb64743ef4', - blockchain: 'OSMOSIS', - decimals: 6, - usdPrice: 0.2688829083335616, - }, - fromAmount: '8.357577', - fromAmountPrecision: null, - fromAmountMinValue: null, - fromAmountMaxValue: null, - fromAmountRestrictionType: 'EXCLUSIVE', - toAmount: '30.983906', - fee: [ - { - asset: { blockchain: 'OSMOSIS', symbol: 'OSMO', address: null }, - expenseType: 'FROM_SOURCE_WALLET', - amount: '0', - name: 'Network Fee', - }, - ], - estimatedTimeInSeconds: 45, - swapChainType: 'INTRA_CHAIN', - routes: [ - { - nodes: [ - { - nodes: [ - { marketName: 'pool#875', marketId: null, percent: 1.0 }, - ], - from: 'USDC', - fromLogo: 'https://api.rango.exchange/tokens/COSMOS/USDC.png', - fromAddress: - 'ibc/d189335c6e4a68b513c10ab227bf1c1d38c746766278ba3eeb4fb14124f1d858', - fromBlockchain: 'OSMOSIS', - to: 'ACRE', - toLogo: 'https://api.rango.exchange/tokens/COSMOS/ACRE.png', - toAddress: - 'ibc/bb936517f7e5d77a63e0adb05217a6608b0c4cf8fba7ea2f4bae4107a7238f06', - toBlockchain: 'OSMOSIS', - }, - { - nodes: [ - { marketName: 'pool#858', marketId: null, percent: 1.0 }, - ], - from: 'ACRE', - fromLogo: 'https://api.rango.exchange/tokens/COSMOS/ACRE.png', - fromAddress: - 'ibc/bb936517f7e5d77a63e0adb05217a6608b0c4cf8fba7ea2f4bae4107a7238f06', - fromBlockchain: 'OSMOSIS', - to: 'OSMO', - toLogo: 'https://api.rango.exchange/tokens/COSMOS/OSMO.png', - toAddress: null, - toBlockchain: 'OSMOSIS', - }, - { - nodes: [{ marketName: 'pool#3', marketId: null, percent: 1.0 }], - from: 'OSMO', - fromLogo: 'https://api.rango.exchange/tokens/COSMOS/OSMO.png', - fromAddress: null, - fromBlockchain: 'OSMOSIS', - to: 'AKT', - toLogo: 'https://api.rango.exchange/tokens/COSMOS/AKT.png', - toAddress: - 'ibc/1480b8fd20ad5fcae81ea87584d269547dd4d436843c1d20f15e00eb64743ef4', - toBlockchain: 'OSMOSIS', - }, - ], - }, - ], - recommendedSlippage: null, - timeStat: { min: 7, avg: 38, max: 187 }, - includesDestinationTx: false, - }, - { - internalSwaps: [], - maxRequiredSign: 1, - warnings: [], - swapperId: 'Osmosis', - swapperType: 'BRIDGE', - swapperLogo: 'https://api.rango.exchange/swappers/osmosis.png', - from: { - symbol: 'AKT', - logo: 'https://api.rango.exchange/tokens/COSMOS/AKT.png', - blockchainLogo: 'https://api.rango.exchange/swappers/osmosis.png', - address: - 'ibc/1480b8fd20ad5fcae81ea87584d269547dd4d436843c1d20f15e00eb64743ef4', - blockchain: 'OSMOSIS', - decimals: 6, - usdPrice: 0.2688829083335616, - }, - to: { - symbol: 'AKT', - logo: 'https://api.rango.exchange/i/3MAS1e', - blockchainLogo: 'https://api.rango.exchange/swappers/osmosis.png', - address: null, - blockchain: 'AKASH', - decimals: 6, - usdPrice: 0.2672300245136459, - }, - fromAmount: '30.983906', - fromAmountPrecision: null, - fromAmountMinValue: null, - fromAmountMaxValue: null, - fromAmountRestrictionType: 'EXCLUSIVE', - toAmount: '30.983906', - fee: [ - { - asset: { blockchain: 'OSMOSIS', symbol: 'OSMO', address: null }, - expenseType: 'FROM_SOURCE_WALLET', - amount: '0.005000', - name: 'Network Fee', - }, - ], - estimatedTimeInSeconds: 45, - swapChainType: 'INTRA_CHAIN', - routes: [ - { - nodes: [ - { - nodes: [ - { marketName: 'Osmosis', marketId: null, percent: 1.0 }, - ], - from: 'AKT', - fromLogo: 'https://api.rango.exchange/tokens/COSMOS/AKT.png', - fromAddress: - 'ibc/1480b8fd20ad5fcae81ea87584d269547dd4d436843c1d20f15e00eb64743ef4', - fromBlockchain: 'OSMOSIS', - to: 'AKT', - toLogo: 'https://api.rango.exchange/tokens/COSMOS/AKT.png', - toAddress: null, - toBlockchain: 'AKASH', - }, - ], - }, - ], - recommendedSlippage: null, - timeStat: { min: 7, avg: 38, max: 187 }, - includesDestinationTx: false, - }, - ], - }, - validationStatus: null, - missingBlockchains: [], - diagnosisMessages: [], - processingLimitReached: false, - walletNotSupportingFromBlockchain: false, -}; - -export const bestRouteExample3: BestRouteType = { - from: { blockchain: 'BSC', symbol: 'BNB', address: null }, - to: { blockchain: 'AVAX_CCHAIN', symbol: 'AVAX', address: null }, - requestAmount: '0.3', - requestId: '228529e3-27d7-4fa9-ab84-bb2b90eade6f', - result: { - resultType: RoutingResultType.OK, - outputAmount: '5.685715974132648891', - swaps: [ - { - internalSwaps: [], - maxRequiredSign: 1, - warnings: [], - swapperId: 'AnySwap Aggregator', - swapperType: 'AGGREGATOR', - swapperLogo: 'https://api.rango.exchange/swappers/multichain.png', - - from: { - symbol: 'BNB', - logo: 'https://api.rango.exchange/i/Y3v1KW', - blockchainLogo: 'https://api.rango.exchange/blockchains/binance.svg', - - address: null, - blockchain: 'BSC', - decimals: 18, - usdPrice: 279.2738558274085, - }, - to: { - symbol: 'WETH.E', - logo: 'https://api.rango.exchange/i/j9xgdC', - blockchainLogo: - 'https://api.rango.exchange/blockchains/avax_cchain.svg', - - address: '0x49d5c2bdffac6ce2bfdb6640f4f80f226bc10bab', - blockchain: 'AVAX_CCHAIN', - decimals: 18, - usdPrice: 1329.24, - }, - fromAmount: '0.300000000000000000', - fromAmountPrecision: null, - fromAmountMinValue: '0.047579322466294684272760', - fromAmountMaxValue: '79302.26195302606417382090', - fromAmountRestrictionType: 'INCLUSIVE', - toAmount: '0.062064305934309070', - fee: [ - { - asset: { blockchain: 'BSC', symbol: 'BNB', address: null }, - expenseType: 'FROM_SOURCE_WALLET', - amount: '0.001388002000000000', - name: 'Network Fee', - }, - ], - estimatedTimeInSeconds: 300, - swapChainType: 'INTRA_CHAIN', - routes: null, - recommendedSlippage: null, - timeStat: { min: 162, avg: 260, max: 467 }, - includesDestinationTx: false, - }, - ], - }, - validationStatus: null, - missingBlockchains: [], - diagnosisMessages: [], - processingLimitReached: false, - walletNotSupportingFromBlockchain: false, -}; diff --git a/widget/ui/src/components/BlockchainSelector/BlockchainSelector.stories.tsx b/widget/ui/src/components/BlockchainSelector/BlockchainSelector.stories.tsx deleted file mode 100644 index 8fd92bea38..0000000000 --- a/widget/ui/src/components/BlockchainSelector/BlockchainSelector.stories.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import React from 'react'; -import { ComponentMeta } from '@storybook/react'; -import { BlockchainSelector, PropTypes } from './BlockchainSelector'; -import { blockchainMeta } from '../BlockchainsList/mockData'; -import { SwapContainer } from '../SwapContainer/SwapContainer'; - -export default { - title: 'Blockchain Selector', - component: BlockchainSelector, - argTypes: { - type: { - defaultValue: 'Source', - }, - }, -} as ComponentMeta; - -export const Main = (args: PropTypes) => ( - - - -); diff --git a/widget/ui/src/components/BlockchainSelector/BlockchainSelector.tsx b/widget/ui/src/components/BlockchainSelector/BlockchainSelector.tsx deleted file mode 100644 index dee38f66c7..0000000000 --- a/widget/ui/src/components/BlockchainSelector/BlockchainSelector.tsx +++ /dev/null @@ -1,96 +0,0 @@ -import React from 'react'; -import { BlockchainMeta } from 'rango-sdk'; -import { BlockchainsList } from '../BlockchainsList'; -import { SecondaryPage } from '../SecondaryPage/SecondaryPage'; -import { Spinner } from '../Spinner'; -import { styled } from '../../theme'; -import { CSSProperties } from '@stitches/react'; -import { containsText } from '../../helper'; -import { LoadingStatus } from '../../types/meta'; -import { LoadingFailedAlert } from '../Alert/LoadingFailedAlert'; -import { NotFoundAlert } from '../Alert/NotFoundAlert'; -import { LoaderContainer } from '../TokenSelector/TokenSelector'; - -const ListContainer = styled('div', { - overflowY: 'auto', - padding: '0 $4', -}); - -const filterBlockchains = (list: BlockchainMeta[], searchedFor: string) => - list.filter( - (blockchain) => - containsText(blockchain.name, searchedFor) || - containsText(blockchain.displayName, searchedFor) - ); - -export interface PropTypes { - type?: 'Source' | 'Destination'; - list: BlockchainMeta[]; - selected?: BlockchainMeta | null; - onChange: (blockchain: BlockchainMeta) => void; - onBack?: () => void; - loadingStatus: LoadingStatus; - hasHeader?: boolean; - listContainerStyle?: CSSProperties; - multiSelect?: boolean; - selectedList?: BlockchainMeta[] | 'all'; -} - -export function BlockchainSelector(props: PropTypes) { - const { - type, - list, - onChange, - selected, - onBack, - loadingStatus, - hasHeader, - listContainerStyle, - multiSelect, - selectedList, - } = props; - - return ( - - {(searchedFor) => { - const filteredBlockchains = filterBlockchains(list, searchedFor); - return ( - <> - {loadingStatus === 'loading' && ( - - - - )} - - {loadingStatus === 'failed' && } - {loadingStatus === 'success' && ( - <> - {filteredBlockchains.length ? ( - - ) : ( - - )} - - )} - - - ); - }} - - ); -} diff --git a/widget/ui/src/components/BlockchainSelector/index.ts b/widget/ui/src/components/BlockchainSelector/index.ts deleted file mode 100644 index 81a37ed03e..0000000000 --- a/widget/ui/src/components/BlockchainSelector/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { BlockchainSelector } from './BlockchainSelector'; diff --git a/widget/ui/src/components/BlockchainsChip/BlockchainsChip.styles.ts b/widget/ui/src/components/BlockchainsChip/BlockchainsChip.styles.ts new file mode 100644 index 0000000000..5272ca208c --- /dev/null +++ b/widget/ui/src/components/BlockchainsChip/BlockchainsChip.styles.ts @@ -0,0 +1,45 @@ +import { darkTheme, styled } from '../../theme.js'; +import { ImageContainer } from '../common/index.js'; + +export const Chip = styled('button', { + padding: '$10', + borderRadius: '$sm', + width: '100%', + $$color: '$colors$neutral100', + [`.${darkTheme} &`]: { + $$color: '$colors$neutral300', + }, + backgroundColor: '$$color', + display: 'flex', + flexDirection: 'column', + justifyContent: 'center', + alignItems: 'center', + cursor: 'pointer', + border: 0, + fontFamily: 'inherit', + [`& ${ImageContainer}`]: { + borderRadius: '$xm', + overflow: 'hidden', + }, + '&:hover': { + $$color: '$colors$secondary100', + [`.${darkTheme} &`]: { + $$color: '$colors$neutral100', + }, + backgroundColor: '$$color', + }, + '&:focus-visible': { + outline: 0, + $$color: '$colors$secondary100', + [`.${darkTheme} &`]: { + $$color: '$colors$info700', + }, + backgroundColor: '$$color', + }, + variants: { + selected: { + true: { outline: '1px solid $secondary500' }, + false: { outline: 0 }, + }, + }, +}); diff --git a/widget/ui/src/components/BlockchainsChip/BlockchainsChip.tsx b/widget/ui/src/components/BlockchainsChip/BlockchainsChip.tsx new file mode 100644 index 0000000000..c3a0a1cb0a --- /dev/null +++ b/widget/ui/src/components/BlockchainsChip/BlockchainsChip.tsx @@ -0,0 +1,15 @@ +import type { PropTypes } from './BlockchainsChip.types.js'; +import type { PropsWithChildren } from 'react'; + +import React from 'react'; + +import { Chip } from './BlockchainsChip.styles.js'; + +export function BlockchainsChip(props: PropsWithChildren) { + const { children, selected, onClick } = props; + return ( + + {children} + + ); +} diff --git a/widget/ui/src/components/BlockchainsChip/BlockchainsChip.types.ts b/widget/ui/src/components/BlockchainsChip/BlockchainsChip.types.ts new file mode 100644 index 0000000000..10be309263 --- /dev/null +++ b/widget/ui/src/components/BlockchainsChip/BlockchainsChip.types.ts @@ -0,0 +1,4 @@ +export interface PropTypes { + selected?: boolean; + onClick?: React.MouseEventHandler; +} diff --git a/widget/ui/src/components/BlockchainsChip/index.ts b/widget/ui/src/components/BlockchainsChip/index.ts new file mode 100644 index 0000000000..629594373b --- /dev/null +++ b/widget/ui/src/components/BlockchainsChip/index.ts @@ -0,0 +1 @@ +export { BlockchainsChip } from './BlockchainsChip.js'; diff --git a/widget/ui/src/components/BlockchainsList/BlockchainsList.stories.tsx b/widget/ui/src/components/BlockchainsList/BlockchainsList.stories.tsx deleted file mode 100644 index 20ee1149d2..0000000000 --- a/widget/ui/src/components/BlockchainsList/BlockchainsList.stories.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import React from 'react'; -import { ComponentMeta } from '@storybook/react'; -import { BlockchainsList, PropTypes } from './BlockchainsList'; -import { blockchainMeta } from './mockData'; - -export default { - title: 'Blockchains List', - component: BlockchainsList, - argTypes: { - searchedText: { - type: 'string', - defaultValue: '', - }, - }, -} as ComponentMeta; - -export const Main = (args: PropTypes) => { - return ( - - ); -}; diff --git a/widget/ui/src/components/BlockchainsList/BlockchainsList.tsx b/widget/ui/src/components/BlockchainsList/BlockchainsList.tsx deleted file mode 100644 index 5c86b7a2a2..0000000000 --- a/widget/ui/src/components/BlockchainsList/BlockchainsList.tsx +++ /dev/null @@ -1,72 +0,0 @@ -import React, { useState } from 'react'; -import { styled } from '../../theme'; -import { BlockchainMeta } from 'rango-sdk'; -import { Button } from '../Button/Button'; -import { FilledCircle, Image } from '../common'; -import { Typography } from '../Typography'; - -export interface PropTypes { - list: BlockchainMeta[]; - selected?: BlockchainMeta | null; - onChange: (blockchain: BlockchainMeta) => void; - multiSelect?: boolean; - selectedList?: BlockchainMeta[] | 'all'; -} - -const ListContainer = styled('div', { - display: 'grid', - gap: '.5rem', - gridTemplateColumns: ' repeat(2, minmax(0, 1fr))', - alignContent: 'baseline', - width: '100%', - height: '100%', -}); - -const ImageContainer = styled('div', { - paddingRight: '$4', -}); - -export function BlockchainsList(props: PropTypes) { - const { list, onChange, multiSelect, selectedList } = props; - const [selected, setSelected] = useState(props.selected); - - const changeSelectedBlockchain = (blockchain: BlockchainMeta) => { - setSelected(blockchain); - onChange(blockchain); - }; - - const isSelect = (name: string) => { - if (multiSelect && selectedList) { - return ( - selectedList === 'all' || - selectedList.findIndex((item) => name === item.name) > -1 - ); - } - return name === selected?.name; - }; - - return ( - - {list.map((blockchain, index) => { - return ( - - ); - })} - - ); -} diff --git a/widget/ui/src/components/BlockchainsList/index.ts b/widget/ui/src/components/BlockchainsList/index.ts deleted file mode 100644 index 8a184fafe0..0000000000 --- a/widget/ui/src/components/BlockchainsList/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { BlockchainsList } from './BlockchainsList'; diff --git a/widget/ui/src/components/BlockchainsList/mockData.ts b/widget/ui/src/components/BlockchainsList/mockData.ts deleted file mode 100644 index 4b769728e2..0000000000 --- a/widget/ui/src/components/BlockchainsList/mockData.ts +++ /dev/null @@ -1,2972 +0,0 @@ -// import { PropTypes } from './BlockchainsList'; - -import { BlockchainMeta, TransactionType } from 'rango-sdk'; - -export const blockchainMeta: BlockchainMeta[] = [ - { - name: 'BSC', - defaultDecimals: 18, - addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], - feeAssets: [ - { - blockchain: 'BSC', - symbol: 'BNB', - address: null, - }, - ], - logo: 'https://api.rango.exchange/blockchains/binance.svg', - displayName: 'BSC', - shortName: 'BSC', - sort: 1, - color: '#F3BA2F', - enabled: true, - type: TransactionType.EVM, - chainId: '0x38', - info: { - infoType: 'EvmMetaInfo', - chainName: 'Binance Smart Chain Mainnet', - nativeCurrency: { - name: 'BNB', - symbol: 'BNB', - decimals: 18, - }, - rpcUrls: ['https://bsc-dataseed1.ninicoin.io'], - blockExplorerUrls: ['https://bscscan.com'], - addressUrl: 'https://bscscan.com/address/{wallet}', - transactionUrl: 'https://bscscan.com/tx/{txHash}', - }, - }, - { - name: 'POLYGON', - defaultDecimals: 18, - addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], - feeAssets: [ - { - blockchain: 'POLYGON', - symbol: 'MATIC', - address: null, - }, - ], - logo: 'https://api.rango.exchange/blockchains/polygon.svg', - displayName: 'Polygon', - shortName: 'Polygon', - sort: 2, - color: '#8247E5', - enabled: true, - type: TransactionType.EVM, - chainId: '0x89', - info: { - infoType: 'EvmMetaInfo', - chainName: 'Polygon Mainnet', - nativeCurrency: { - name: 'MATIC', - symbol: 'MATIC', - decimals: 18, - }, - rpcUrls: ['https://polygon-rpc.com'], - blockExplorerUrls: ['https://polygonscan.com'], - addressUrl: 'https://polygonscan.com/address/{wallet}', - transactionUrl: 'https://polygonscan.com/tx/{txHash}', - }, - }, - { - name: 'ETH', - defaultDecimals: 18, - addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], - feeAssets: [ - { - blockchain: 'ETH', - symbol: 'ETH', - address: null, - }, - ], - logo: 'https://api.rango.exchange/blockchains/ethereum.svg', - displayName: 'Ethereum', - shortName: 'ETH', - sort: 3, - color: '#ecf0f1', - enabled: true, - type: TransactionType.EVM, - chainId: '0x1', - info: { - infoType: 'EvmMetaInfo', - chainName: 'Ethereum Mainnet', - nativeCurrency: { - name: 'ETH', - symbol: 'ETH', - decimals: 18, - }, - rpcUrls: ['https://rpc.ankr.com/eth'], - blockExplorerUrls: ['https://etherscan.io'], - addressUrl: 'https://etherscan.io/address/{wallet}', - transactionUrl: 'https://etherscan.io/tx/{txHash}', - }, - }, - { - name: 'OSMOSIS', - defaultDecimals: 6, - addressPatterns: ['^(osmo1)[0-9a-z]{38}$'], - feeAssets: [ - { - blockchain: 'OSMOSIS', - symbol: 'OSMO', - address: null, - }, - ], - logo: 'https://api.rango.exchange/blockchains/osmosis.svg', - displayName: 'Osmosis', - shortName: 'Osmosis', - sort: 4, - color: '#7901B4', - enabled: true, - type: TransactionType.COSMOS, - chainId: 'osmosis-1', - info: { - infoType: 'CosmosMetaInfo', - experimental: false, - rpc: 'https://rpc-osmosis.keplr.app', - rest: 'https://lcd-osmosis.keplr.app', - cosmostationLcdUrl: 'https://lcd-osmosis.cosmostation.io', - cosmostationApiUrl: 'https://api-osmosis.cosmostation.io', - cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', - mintScanName: 'osmosis', - chainName: 'Osmosis', - stakeCurrency: { - coinDenom: 'OSMO', - coinMinimalDenom: 'uosmo', - coinDecimals: 6, - coinGeckoId: 'pool:uosmo', - coinImageUrl: '/tokens/blockchain/osmosis.svg', - }, - bip44: { - coinType: 118, - }, - bech32Config: { - bech32PrefixAccAddr: 'osmo', - bech32PrefixAccPub: 'osmopub', - bech32PrefixValAddr: 'osmovaloper', - bech32PrefixValPub: 'osmovaloperpub', - bech32PrefixConsAddr: 'osmovalcons', - bech32PrefixConsPub: 'osmovalconspub', - }, - currencies: [ - { - coinDenom: 'OSMO', - coinMinimalDenom: 'uosmo', - coinDecimals: 6, - coinGeckoId: 'pool:uosmo', - coinImageUrl: '/tokens/blockchain/osmosis.svg', - }, - { - coinDenom: 'ION', - coinMinimalDenom: 'uion', - coinDecimals: 6, - coinGeckoId: 'pool:uion', - coinImageUrl: '/tokens/blockchain/ion.png', - }, - ], - feeCurrencies: [ - { - coinDenom: 'OSMO', - coinMinimalDenom: 'uosmo', - coinDecimals: 6, - coinGeckoId: 'pool:uosmo', - coinImageUrl: '/tokens/blockchain/osmosis.svg', - }, - ], - features: ['stargate', 'ibc-transfer'], - explorerUrlToTx: 'https://www.mintscan.io/osmosis/txs/{txHash}', - gasPriceStep: { - low: 0, - average: 0.025, - high: 0.04, - }, - }, - }, - { - name: 'JUNO', - defaultDecimals: 6, - addressPatterns: ['^(juno1)[0-9a-z]{38}$'], - feeAssets: [ - { - blockchain: 'JUNO', - symbol: 'JUNO', - address: null, - }, - ], - logo: 'https://api.rango.exchange/blockchains/juno.svg', - displayName: 'Juno', - shortName: 'Juno', - sort: 5, - color: '#f0827d', - enabled: true, - type: TransactionType.COSMOS, - chainId: 'juno-1', - info: { - infoType: 'CosmosMetaInfo', - experimental: false, - rpc: 'https://rpc-juno.itastakers.com:443/', - rest: 'https://lcd-juno.keplr.app', - cosmostationLcdUrl: 'https://lcd-juno.cosmostation.io', - cosmostationApiUrl: 'https://api-juno.cosmostation.io', - cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', - mintScanName: 'juno', - chainName: 'Juno', - stakeCurrency: { - coinDenom: 'JUNO', - coinMinimalDenom: 'ujuno', - coinDecimals: 6, - coinGeckoId: 'juno-network', - coinImageUrl: '/tokens/blockchain/JUNO.png', - }, - bip44: { - coinType: 118, - }, - bech32Config: { - bech32PrefixAccAddr: 'juno', - bech32PrefixAccPub: 'junopub', - bech32PrefixValAddr: 'junovaloper', - bech32PrefixValPub: 'junovaloperpub', - bech32PrefixConsAddr: 'junovalcons', - bech32PrefixConsPub: 'junovalconspub', - }, - currencies: [ - { - coinDenom: 'JUNO', - coinMinimalDenom: 'ujuno', - coinDecimals: 6, - coinGeckoId: 'juno-network', - coinImageUrl: '/tokens/blockchain/JUNO.png', - }, - ], - feeCurrencies: [ - { - coinDenom: 'JUNO', - coinMinimalDenom: 'ujuno', - coinDecimals: 6, - coinGeckoId: 'juno-network', - coinImageUrl: '/tokens/blockchain/JUNO.png', - }, - ], - features: ['stargate', 'ibc-transfer'], - explorerUrlToTx: 'https://www.mintscan.io/juno/txs/{txHash}', - gasPriceStep: { - low: 0.001, - average: 0.0025, - high: 0.004, - }, - }, - }, - { - name: 'AVAX_CCHAIN', - defaultDecimals: 18, - addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], - feeAssets: [ - { - blockchain: 'AVAX_CCHAIN', - symbol: 'AVAX', - address: null, - }, - ], - logo: 'https://api.rango.exchange/blockchains/avax_cchain.svg', - displayName: 'Avalanche', - shortName: 'Avax', - sort: 6, - color: '#e84142', - enabled: true, - type: TransactionType.EVM, - chainId: '0xa86a', - info: { - infoType: 'EvmMetaInfo', - chainName: 'Avalanche C-Chain', - nativeCurrency: { - name: 'AVAX', - symbol: 'AVAX', - decimals: 18, - }, - rpcUrls: ['https://api.avax.network/ext/bc/C/rpc'], - blockExplorerUrls: ['https://snowtrace.io'], - addressUrl: 'https://snowtrace.io/address/{wallet}', - transactionUrl: 'https://snowtrace.io/tx/{txHash}', - }, - }, - { - name: 'ARBITRUM', - defaultDecimals: 18, - addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], - feeAssets: [ - { - blockchain: 'ARBITRUM', - symbol: 'ETH', - address: null, - }, - ], - logo: 'https://api.rango.exchange/blockchains/arbitrum.svg', - displayName: 'Arbitrum', - shortName: 'Arbitrum', - sort: 7, - color: '#28a0f0', - enabled: true, - type: TransactionType.EVM, - chainId: '0xa4b1', - info: { - infoType: 'EvmMetaInfo', - chainName: 'Arbitrum One', - nativeCurrency: { - name: 'ETH', - symbol: 'ETH', - decimals: 18, - }, - rpcUrls: ['https://arb1.arbitrum.io/rpc'], - blockExplorerUrls: ['https://arbiscan.io'], - addressUrl: 'https://arbiscan.io/address/{wallet}', - transactionUrl: 'https://arbiscan.io/tx/{txHash}', - }, - }, - { - name: 'TERRA', - defaultDecimals: 6, - addressPatterns: ['^(terra1)[0-9a-z]{38}$'], - feeAssets: [ - { - blockchain: 'TERRA', - symbol: 'Luna', - address: null, - }, - { - blockchain: 'TERRA', - symbol: 'UST', - address: null, - }, - { - blockchain: 'TERRA', - symbol: 'TERRA_EUT', - address: null, - }, - { - blockchain: 'TERRA', - symbol: 'KRT', - address: null, - }, - ], - logo: 'https://api.rango.exchange/blockchains/terra.svg', - displayName: 'Terra', - shortName: 'Terra', - sort: 8, - color: '#5493F7', - enabled: false, - type: TransactionType.COSMOS, - chainId: 'columbus-5', - info: { - infoType: 'CosmosMetaInfo', - experimental: true, - rpc: 'https://rpc-columbus.keplr.app', - rest: 'https://lcd-columbus.keplr.app', - cosmostationLcdUrl: null, - cosmostationApiUrl: 'https://lcd.terra.dev', - cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', - mintScanName: null, - chainName: 'Terra', - stakeCurrency: { - coinDenom: 'LUNA', - coinMinimalDenom: 'uluna', - coinDecimals: 6, - coinGeckoId: 'terra-luna', - coinImageUrl: '/tokens/blockchain/LUNA.png', - }, - bip44: { - coinType: 330, - }, - bech32Config: { - bech32PrefixAccAddr: 'terra', - bech32PrefixAccPub: 'terrapub', - bech32PrefixValAddr: 'terravaloper', - bech32PrefixValPub: 'terravaloperpub', - bech32PrefixConsAddr: 'terravalcons', - bech32PrefixConsPub: 'terravalconspub', - }, - currencies: [ - { - coinDenom: 'LUNA', - coinMinimalDenom: 'uluna', - coinDecimals: 6, - coinGeckoId: 'terra-luna', - coinImageUrl: '/tokens/blockchain/LUNA.png', - }, - { - coinDenom: 'UST', - coinMinimalDenom: 'uusd', - coinDecimals: 6, - coinGeckoId: 'terrausd', - coinImageUrl: '/tokens/blockchain/UST.png', - }, - ], - feeCurrencies: [ - { - coinDenom: 'LUNA', - coinMinimalDenom: 'uluna', - coinDecimals: 6, - coinGeckoId: 'terra-luna', - coinImageUrl: '/tokens/blockchain/LUNA.png', - }, - { - coinDenom: 'UST', - coinMinimalDenom: 'uusd', - coinDecimals: 6, - coinGeckoId: 'terrausd', - coinImageUrl: '/tokens/blockchain/UST.png', - }, - ], - features: ['stargate', 'ibc-transfer', 'no-legacy-stdTx'], - explorerUrlToTx: 'https://finder.terra.money/columbus-5/tx/{txHash}', - gasPriceStep: { - low: 0.0075, - average: 0.0075, - high: 0.0075, - }, - }, - }, - { - name: 'COSMOS', - defaultDecimals: 6, - addressPatterns: ['^(cosmos1)[0-9a-z]{38}$'], - feeAssets: [ - { - blockchain: 'COSMOS', - symbol: 'ATOM', - address: null, - }, - ], - logo: 'https://api.rango.exchange/blockchains/cosmos.svg', - displayName: 'Cosmos', - shortName: 'Cosmos', - sort: 8, - color: '#2E3148', - enabled: true, - type: TransactionType.COSMOS, - chainId: 'cosmoshub-4', - info: { - infoType: 'CosmosMetaInfo', - experimental: false, - rpc: 'https://cosmos-rpc.polkachu.com', - rest: 'https://lcd-cosmoshub.keplr.app', - cosmostationLcdUrl: 'https://lcd-cosmos.cosmostation.io', - cosmostationApiUrl: 'https://api-cosmos.cosmostation.io', - cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', - mintScanName: 'cosmos', - chainName: 'Cosmos', - stakeCurrency: { - coinDenom: 'ATOM', - coinMinimalDenom: 'uatom', - coinDecimals: 6, - coinGeckoId: 'cosmos', - coinImageUrl: '/tokens/blockchain/cosmos.svg', - }, - bip44: { - coinType: 118, - }, - bech32Config: { - bech32PrefixAccAddr: 'cosmos', - bech32PrefixAccPub: 'cosmospub', - bech32PrefixValAddr: 'cosmosvaloper', - bech32PrefixValPub: 'cosmosvaloperpub', - bech32PrefixConsAddr: 'cosmosvalcons', - bech32PrefixConsPub: 'cosmosvalconspub', - }, - currencies: [ - { - coinDenom: 'ATOM', - coinMinimalDenom: 'uatom', - coinDecimals: 6, - coinGeckoId: 'cosmos', - coinImageUrl: '/tokens/blockchain/cosmos.svg', - }, - ], - feeCurrencies: [ - { - coinDenom: 'ATOM', - coinMinimalDenom: 'uatom', - coinDecimals: 6, - coinGeckoId: 'cosmos', - coinImageUrl: '/tokens/blockchain/cosmos.svg', - }, - ], - features: ['stargate', 'ibc-transfer'], - explorerUrlToTx: 'https://www.mintscan.io/cosmos/txs/{txHash}', - gasPriceStep: { - low: 0.01, - average: 0.025, - high: 0.04, - }, - }, - }, - { - name: 'FANTOM', - defaultDecimals: 18, - addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], - feeAssets: [ - { - blockchain: 'FANTOM', - symbol: 'FTM', - address: null, - }, - ], - logo: 'https://api.rango.exchange/blockchains/fantom.png', - displayName: 'Fantom', - shortName: 'Fantom', - sort: 9, - color: '#337afe', - enabled: true, - type: TransactionType.EVM, - chainId: '0xfa', - info: { - infoType: 'EvmMetaInfo', - chainName: 'Fantom Opera', - nativeCurrency: { - name: 'FTM', - symbol: 'FTM', - decimals: 18, - }, - rpcUrls: ['https://rpc.ftm.tools'], - blockExplorerUrls: ['https://ftmscan.com'], - addressUrl: 'https://ftmscan.com/address/{wallet}', - transactionUrl: 'https://ftmscan.com/tx/{txHash}', - }, - }, - { - name: 'OPTIMISM', - defaultDecimals: 18, - addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], - feeAssets: [ - { - blockchain: 'OPTIMISM', - symbol: 'ETH', - address: null, - }, - ], - logo: 'https://api.rango.exchange/blockchains/optimism.svg', - displayName: 'Optimism', - shortName: 'Optimism', - sort: 10, - color: '#FF0420', - enabled: true, - type: TransactionType.EVM, - chainId: '0xa', - info: { - infoType: 'EvmMetaInfo', - chainName: 'Optimism', - nativeCurrency: { - name: 'ETH', - symbol: 'ETH', - decimals: 18, - }, - rpcUrls: ['https://mainnet.optimism.io'], - blockExplorerUrls: ['https://optimistic.etherscan.io'], - addressUrl: 'https://optimistic.etherscan.io/address/{wallet}', - transactionUrl: 'https://optimistic.etherscan.io/tx/{txHash}', - }, - }, - { - name: 'SOLANA', - defaultDecimals: 9, - addressPatterns: ['^[1-9A-HJ-NP-Za-km-z]{32,44}$'], - feeAssets: [ - { - blockchain: 'SOLANA', - symbol: 'SOL', - address: null, - }, - ], - logo: 'https://api.rango.exchange/blockchains/solana.svg', - displayName: 'Solana', - shortName: 'Solana', - sort: 11, - color: '#708DD2', - enabled: true, - type: TransactionType.SOLANA, - chainId: 'mainnet-beta', - info: null, - }, - { - name: 'OKC', - defaultDecimals: 18, - addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], - feeAssets: [ - { - blockchain: 'OKC', - symbol: 'OKT', - address: null, - }, - ], - logo: 'https://api.rango.exchange/blockchains/okx.png', - displayName: 'OKX Chain (OKC)', - shortName: 'Okx', - sort: 11, - color: '#29a0f0', - enabled: true, - type: TransactionType.EVM, - chainId: '0x42', - info: { - infoType: 'EvmMetaInfo', - chainName: 'OKX Chain', - nativeCurrency: { - name: 'OKT', - symbol: 'OKT', - decimals: 18, - }, - rpcUrls: ['https://exchainrpc.okex.org'], - blockExplorerUrls: ['https://www.oklink.com/en/okc'], - addressUrl: 'https://www.oklink.com/en/okc/address/{wallet}', - transactionUrl: 'https://www.oklink.com/en/okc/tx/{txHash}', - }, - }, - { - name: 'CRONOS', - defaultDecimals: 18, - addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], - feeAssets: [ - { - blockchain: 'CRONOS', - symbol: 'CRO', - address: null, - }, - ], - logo: 'https://api.rango.exchange/blockchains/cronos.svg', - displayName: 'Cronos', - shortName: 'Cronos', - sort: 12, - color: '#1a90ff', - enabled: true, - type: TransactionType.EVM, - chainId: '0x19', - info: { - infoType: 'EvmMetaInfo', - chainName: 'Cronos Mainnet Beta', - nativeCurrency: { - name: 'CRO', - symbol: 'CRO', - decimals: 18, - }, - rpcUrls: ['https://evm.cronos.org'], - blockExplorerUrls: ['https://cronoscan.com'], - addressUrl: 'https://cronoscan.com/address/{wallet}', - transactionUrl: 'https://cronoscan.com/tx/{txHash}', - }, - }, - { - name: 'MOONRIVER', - defaultDecimals: 18, - addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], - feeAssets: [ - { - blockchain: 'MOONRIVER', - symbol: 'MOVR', - address: null, - }, - ], - logo: 'https://api.rango.exchange/blockchains/moonriver.svg', - displayName: 'MoonRiver', - shortName: 'MoonRiver', - sort: 13, - color: '#F3B404', - enabled: true, - type: TransactionType.EVM, - chainId: '0x505', - info: { - infoType: 'EvmMetaInfo', - chainName: 'MoonRiver', - nativeCurrency: { - name: 'MOVR', - symbol: 'MOVR', - decimals: 18, - }, - rpcUrls: ['https://rpc.moonriver.moonbeam.network'], - blockExplorerUrls: ['https://moonriver.moonscan.io'], - addressUrl: 'https://moonriver.moonscan.io/address/{wallet}', - transactionUrl: 'https://moonriver.moonscan.io/tx/{txHash}', - }, - }, - { - name: 'MOONBEAM', - defaultDecimals: 18, - addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], - feeAssets: [ - { - blockchain: 'MOONBEAM', - symbol: 'GLMR', - address: null, - }, - ], - logo: 'https://api.rango.exchange/blockchains/moonbeam.png', - displayName: 'MoonBeam', - shortName: 'MoonBeam', - sort: 14, - color: '#B3206B', - enabled: true, - type: TransactionType.EVM, - chainId: '0x504', - info: { - infoType: 'EvmMetaInfo', - chainName: 'MoonBeam', - nativeCurrency: { - name: 'GLMR', - symbol: 'GLMR', - decimals: 18, - }, - rpcUrls: ['https://rpc.api.moonbeam.network'], - blockExplorerUrls: ['https://moonbeam.moonscan.io'], - addressUrl: 'https://moonbeam.moonscan.io/address/{wallet}', - transactionUrl: 'https://moonbeam.moonscan.io/tx/{txHash}', - }, - }, - { - name: 'POLKADOT', - defaultDecimals: 10, - addressPatterns: ['^(1)[0-9a-z-A-Z]{44,50}$'], - feeAssets: [], - logo: 'https://api.rango.exchange/blockchains/polkadot.svg', - displayName: 'Polkadot', - shortName: 'Polkadot', - sort: 14, - color: '#E6007A', - enabled: false, - type: TransactionType.TRANSFER, - chainId: null, - info: null, - }, - { - name: 'DOGE', - defaultDecimals: 8, - addressPatterns: ['^(D|A|9)[a-km-zA-HJ-NP-Z1-9]{33,34}$'], - feeAssets: [ - { - blockchain: 'DOGE', - symbol: 'DOGE', - address: null, - }, - ], - logo: 'https://api.rango.exchange/blockchains/doge.svg', - displayName: 'Doge', - shortName: 'Doge', - sort: 15, - color: '#BA9F33', - enabled: false, - type: TransactionType.TRANSFER, - chainId: null, - info: null, - }, - { - name: 'HECO', - defaultDecimals: 18, - addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], - feeAssets: [ - { - blockchain: 'HECO', - symbol: 'HT', - address: null, - }, - ], - logo: 'https://api.rango.exchange/blockchains/heco.png', - displayName: 'Heco', - shortName: 'Heco', - sort: 15, - color: '#4CA852', - enabled: true, - type: TransactionType.EVM, - chainId: '0x80', - info: { - infoType: 'EvmMetaInfo', - chainName: 'Huobi ECO Chain Mainnet', - nativeCurrency: { - name: 'HT', - symbol: 'HT', - decimals: 18, - }, - rpcUrls: ['https://http-mainnet.hecochain.com'], - blockExplorerUrls: ['https://hecoinfo.com'], - addressUrl: 'https://hecoinfo.com/address/{wallet}', - transactionUrl: 'https://hecoinfo.com/tx/{txHash}', - }, - }, - { - name: 'AURORA', - defaultDecimals: 18, - addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], - feeAssets: [ - { - blockchain: 'AURORA', - symbol: 'ETH', - address: null, - }, - ], - logo: 'https://api.rango.exchange/blockchains/aurora.svg', - displayName: 'Aurora', - shortName: 'Aurora', - sort: 15, - color: '#78d64b', - enabled: true, - type: TransactionType.EVM, - chainId: '0x4e454152', - info: { - infoType: 'EvmMetaInfo', - chainName: 'Aurora Mainnet', - nativeCurrency: { - name: 'ETH', - symbol: 'ETH', - decimals: 18, - }, - rpcUrls: ['https://mainnet.aurora.dev'], - blockExplorerUrls: ['https://explorer.mainnet.aurora.dev'], - addressUrl: 'https://explorer.mainnet.aurora.dev/address/{wallet}', - transactionUrl: 'https://explorer.mainnet.aurora.dev/tx/{txHash}', - }, - }, - { - name: 'HARMONY', - defaultDecimals: 18, - addressPatterns: ['^(one1)[0-9a-z]{38}$', '^(0x)[0-9A-Fa-f]{40}$'], - feeAssets: [ - { - blockchain: 'HARMONY', - symbol: 'ONE', - address: null, - }, - ], - logo: 'https://api.rango.exchange/blockchains/harmony.svg', - displayName: 'Harmony', - shortName: 'Harmony', - sort: 15, - color: '#50AEE9', - enabled: true, - type: TransactionType.EVM, - chainId: '0x63564c40', - info: { - infoType: 'EvmMetaInfo', - chainName: 'Harmony Mainnet', - nativeCurrency: { - name: 'ONE', - symbol: 'ONE', - decimals: 18, - }, - rpcUrls: ['https://rpc.ankr.com/harmony'], - blockExplorerUrls: ['https://explorer.harmony.one'], - addressUrl: 'https://explorer.harmony.one/address/{wallet}', - transactionUrl: 'https://explorer.harmony.one/tx/{txHash}', - }, - }, - { - name: 'EVMOS', - defaultDecimals: 18, - addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], - feeAssets: [ - { - blockchain: 'EVMOS', - symbol: 'EVMOS', - address: null, - }, - ], - logo: 'https://api.rango.exchange/blockchains/evmos.png', - displayName: 'Evmos', - shortName: 'Evmos', - sort: 15, - color: '#2D2925', - enabled: true, - type: TransactionType.EVM, - chainId: '0x2329', - info: { - infoType: 'EvmMetaInfo', - chainName: 'Evmos', - nativeCurrency: { - name: 'EVMOS', - symbol: 'EVMOS', - decimals: 18, - }, - rpcUrls: ['https://eth.bd.evmos.org:8545'], - blockExplorerUrls: ['https://evm.evmos.org'], - addressUrl: 'https://evm.evmos.org/address/{wallet}', - transactionUrl: 'https://evm.evmos.org/tx/{txHash}', - }, - }, - { - name: 'TRON', - defaultDecimals: 18, - addressPatterns: ['^T[1-9A-HJ-NP-Za-km-z]{33}$'], - feeAssets: [], - logo: 'https://api.rango.exchange/blockchains/tron.svg', - displayName: 'Tron', - shortName: 'Tron', - sort: 16, - color: '#FF060A', - enabled: false, - type: TransactionType.TRANSFER, - chainId: null, - info: null, - }, - { - name: 'SIF', - defaultDecimals: 18, - addressPatterns: ['^(sif1)[0-9a-z]{38}$'], - feeAssets: [ - { - blockchain: 'SIF', - symbol: 'ROWAN', - address: null, - }, - ], - logo: 'https://api.rango.exchange/blockchains/sif.png', - displayName: 'Sifchain', - shortName: 'Sifchain', - sort: 16, - color: '#CAAA3A', - enabled: true, - type: TransactionType.COSMOS, - chainId: 'sifchain-1', - info: { - infoType: 'CosmosMetaInfo', - experimental: false, - rpc: 'https://rpc.sifchain.finance', - rest: 'https://api-int.sifchain.finance', - cosmostationLcdUrl: 'https://lcd-sifchain.cosmostation.io', - cosmostationApiUrl: 'https://api.mintscan.io/v1/sifchain', - cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', - mintScanName: 'sifchain', - chainName: 'Sifchain', - stakeCurrency: { - coinDenom: 'ROWAN', - coinMinimalDenom: 'rowan', - coinDecimals: 18, - coinGeckoId: '', - coinImageUrl: '', - }, - bip44: { - coinType: 118, - }, - bech32Config: { - bech32PrefixAccAddr: 'sif', - bech32PrefixAccPub: 'sifpub', - bech32PrefixValAddr: 'sifvaloper', - bech32PrefixValPub: 'sifvaloperpub', - bech32PrefixConsAddr: 'sifvalcons', - bech32PrefixConsPub: 'sifvalconspub', - }, - currencies: [ - { - coinDenom: 'ROWAN', - coinMinimalDenom: 'rowan', - coinDecimals: 18, - coinGeckoId: '', - coinImageUrl: '', - }, - ], - feeCurrencies: [ - { - coinDenom: 'ROWAN', - coinMinimalDenom: 'rowan', - coinDecimals: 18, - coinGeckoId: '', - coinImageUrl: '', - }, - ], - features: ['stargate', 'ibc-transfer'], - explorerUrlToTx: 'https://www.mintscan.io/sifchain/txs/{txHash}', - gasPriceStep: { - low: 1000000000000, - average: 1500000000000, - high: 2000000000000, - }, - }, - }, - { - name: 'THOR', - defaultDecimals: 8, - addressPatterns: ['^(thor1)[0-9a-z]{38}$'], - feeAssets: [ - { - blockchain: 'THOR', - symbol: 'RUNE', - address: null, - }, - ], - logo: 'https://api.rango.exchange/blockchains/thorchain.svg', - displayName: 'Thorchain', - shortName: 'Thorchain', - sort: 17, - color: '#1AE6CB', - enabled: true, - type: TransactionType.TRANSFER, - chainId: null, - info: null, - }, - { - name: 'BRISE', - defaultDecimals: 18, - addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], - feeAssets: [ - { - blockchain: 'BRISE', - symbol: 'BRISE', - address: null, - }, - ], - logo: 'https://api.rango.exchange/blockchains/bitgert.png', - displayName: 'Brise', - shortName: 'Brise', - sort: 18, - color: '#0693E3', - enabled: true, - type: TransactionType.EVM, - chainId: '0x7f08', - info: { - infoType: 'EvmMetaInfo', - chainName: 'Brise', - nativeCurrency: { - name: 'BRISE', - symbol: 'BRISE', - decimals: 18, - }, - rpcUrls: ['https://rpc.icecreamswap.com'], - blockExplorerUrls: ['https://brisescan.com/'], - addressUrl: 'https://brisescan.com//address/{wallet}', - transactionUrl: 'https://brisescan.com//tx/{txHash}', - }, - }, - { - name: 'BNB', - defaultDecimals: 8, - addressPatterns: ['^(bnb1)[0-9a-z]{38}$'], - feeAssets: [ - { - blockchain: 'BNB', - symbol: 'BNB', - address: null, - }, - ], - logo: 'https://api.rango.exchange/blockchains/bnb.svg', - displayName: 'Binance Chain', - shortName: 'BNB', - sort: 18, - color: '#F3BA2F', - enabled: true, - type: TransactionType.COSMOS, - chainId: null, - info: null, - }, - { - name: 'STARGAZE', - defaultDecimals: 6, - addressPatterns: ['^(stars1)[0-9a-z]{38}$'], - feeAssets: [ - { - blockchain: 'STARGAZE', - symbol: 'STARS', - address: null, - }, - ], - logo: 'https://api.rango.exchange/blockchains/stargaze.png', - displayName: 'Stargaze', - shortName: 'Stargaze', - sort: 19, - color: '#231B60', - enabled: true, - type: TransactionType.COSMOS, - chainId: 'stargaze-1', - info: { - infoType: 'CosmosMetaInfo', - experimental: false, - rpc: 'https://rpc.stargaze-apis.com', - rest: 'https://rest.stargaze-apis.com', - cosmostationLcdUrl: 'https://lcd-stargaze.cosmostation.io', - cosmostationApiUrl: 'https://api-stargaze.cosmostation.io', - cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', - mintScanName: 'stargaze', - chainName: 'Stargaze', - stakeCurrency: { - coinDenom: 'STARS', - coinMinimalDenom: 'ustars', - coinDecimals: 6, - coinGeckoId: 'pool:ustars', - coinImageUrl: '/tokens/blockchain/STARS.png', - }, - bip44: { - coinType: 118, - }, - bech32Config: { - bech32PrefixAccAddr: 'stars', - bech32PrefixAccPub: 'starspub', - bech32PrefixValAddr: 'starsvaloper', - bech32PrefixValPub: 'starsvaloperpub', - bech32PrefixConsAddr: 'starsvalcons', - bech32PrefixConsPub: 'starsvalconspub', - }, - currencies: [ - { - coinDenom: 'STARS', - coinMinimalDenom: 'ustars', - coinDecimals: 6, - coinGeckoId: 'pool:ustars', - coinImageUrl: '/tokens/blockchain/STARS.png', - }, - ], - feeCurrencies: [ - { - coinDenom: 'STARS', - coinMinimalDenom: 'ustars', - coinDecimals: 6, - coinGeckoId: 'pool:ustars', - coinImageUrl: '/tokens/blockchain/STARS.png', - }, - ], - features: ['stargate', 'ibc-transfer', 'no-legacy-stdTx'], - explorerUrlToTx: 'https://www.mintscan.io/stargaze/txs/{txHash}', - gasPriceStep: { - low: 1, - average: 1, - high: 1, - }, - }, - }, - { - name: 'BTC', - defaultDecimals: 8, - addressPatterns: [ - '^[13][a-km-zA-HJ-NP-Z1-9]{25,34}$|^(bc1)[0-9A-Za-z]{39,59}$', - ], - feeAssets: [ - { - blockchain: 'BTC', - symbol: 'BTC', - address: null, - }, - ], - logo: 'https://api.rango.exchange/blockchains/btc.svg', - displayName: 'Bitcoin', - shortName: 'BTC', - sort: 20, - color: '#F7931A', - enabled: true, - type: TransactionType.TRANSFER, - chainId: null, - info: null, - }, - { - name: 'CRYPTO_ORG', - defaultDecimals: 8, - addressPatterns: ['^(cro1)[0-9a-z]{38}$'], - feeAssets: [ - { - blockchain: 'CRYPTO_ORG', - symbol: 'CRO', - address: null, - }, - ], - logo: 'https://api.rango.exchange/blockchains/crypto_org.png', - displayName: 'Crypto.org', - shortName: 'Crypto.org', - sort: 21, - color: '#103F68', - enabled: true, - type: TransactionType.COSMOS, - chainId: 'crypto-org-chain-mainnet-1', - info: { - infoType: 'CosmosMetaInfo', - experimental: false, - rpc: 'https://rpc-crypto-org.keplr.app', - rest: 'https://lcd-crypto-org.keplr.app', - cosmostationLcdUrl: 'https://lcd-cryptocom.cosmostation.io', - cosmostationApiUrl: 'https://api-cryptocom.cosmostation.io', - cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', - mintScanName: 'crypto-org', - chainName: 'Crypto.org', - stakeCurrency: { - coinDenom: 'CRO', - coinMinimalDenom: 'basecro', - coinDecimals: 8, - coinGeckoId: 'crypto-com-chain', - coinImageUrl: '/tokens/blockchain/cro.png', - }, - bip44: { - coinType: 394, - }, - bech32Config: { - bech32PrefixAccAddr: 'cro', - bech32PrefixAccPub: 'cropub', - bech32PrefixValAddr: 'crovaloper', - bech32PrefixValPub: 'crovaloperpub', - bech32PrefixConsAddr: 'crovalcons', - bech32PrefixConsPub: 'crovalconspub', - }, - currencies: [ - { - coinDenom: 'CRO', - coinMinimalDenom: 'basecro', - coinDecimals: 8, - coinGeckoId: 'crypto-com-chain', - coinImageUrl: '/tokens/blockchain/cro.png', - }, - ], - feeCurrencies: [ - { - coinDenom: 'CRO', - coinMinimalDenom: 'basecro', - coinDecimals: 8, - coinGeckoId: 'crypto-com-chain', - coinImageUrl: '/tokens/blockchain/cro.png', - }, - ], - features: ['stargate', 'ibc-transfer'], - explorerUrlToTx: 'https://www.mintscan.io/crypto-org/txs/{txHash}', - gasPriceStep: { - low: 0.025, - average: 0.03, - high: 0.04, - }, - }, - }, - { - name: 'CHIHUAHUA', - defaultDecimals: 6, - addressPatterns: ['^(chihuahua1)[0-9a-z]{38}$'], - feeAssets: [ - { - blockchain: 'CHIHUAHUA', - symbol: 'HUAHUA', - address: null, - }, - ], - logo: 'https://api.rango.exchange/blockchains/chihuahua.png', - displayName: 'Chihuahua', - shortName: 'Chihuahua', - sort: 22, - color: '#EFC92B', - enabled: true, - type: TransactionType.COSMOS, - chainId: 'chihuahua-1', - info: { - infoType: 'CosmosMetaInfo', - experimental: true, - rpc: 'https://rpc.chihuahua.wtf/', - rest: 'https://api.chihuahua.wtf/', - cosmostationLcdUrl: 'https://lcd-chihuahua.cosmostation.io', - cosmostationApiUrl: 'https://api-chihuahua.cosmostation.io', - cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', - mintScanName: 'chihuahua', - chainName: 'Chihuahua', - stakeCurrency: { - coinDenom: 'HUAHUA', - coinMinimalDenom: 'uhuahua', - coinDecimals: 6, - coinGeckoId: 'pool:uhuahua', - coinImageUrl: '/tokens/blockchain/HUAHUA.svg', - }, - bip44: { - coinType: 118, - }, - bech32Config: { - bech32PrefixAccAddr: 'chihuahua', - bech32PrefixAccPub: 'chihuahuapub', - bech32PrefixValAddr: 'chihuahuavaloper', - bech32PrefixValPub: 'chihuahuavaloperpub', - bech32PrefixConsAddr: 'chihuahuavalcons', - bech32PrefixConsPub: 'chihuahuavalconspub', - }, - currencies: [ - { - coinDenom: 'HUAHUA', - coinMinimalDenom: 'uhuahua', - coinDecimals: 6, - coinGeckoId: 'pool:uhuahua', - coinImageUrl: '/tokens/blockchain/HUAHUA.svg', - }, - ], - feeCurrencies: [ - { - coinDenom: 'HUAHUA', - coinMinimalDenom: 'uhuahua', - coinDecimals: 6, - coinGeckoId: 'pool:uhuahua', - coinImageUrl: '/tokens/blockchain/HUAHUA.svg', - }, - ], - features: ['stargate', 'ibc-transfer', 'no-legacy-stdTx'], - explorerUrlToTx: 'https://ping.pub/chihuahua/tx/{txHash}', - gasPriceStep: { - low: 0.025, - average: 0.03, - high: 0.035, - }, - }, - }, - { - name: 'BANDCHAIN', - defaultDecimals: 6, - addressPatterns: ['^(band1)[0-9a-z]{38}$'], - feeAssets: [ - { - blockchain: 'BANDCHAIN', - symbol: 'BAND', - address: null, - }, - ], - logo: 'https://api.rango.exchange/blockchains/bandchain.svg', - displayName: 'BandChain', - shortName: 'BandChain', - sort: 23, - color: '#4520E6', - enabled: true, - type: TransactionType.COSMOS, - chainId: 'laozi-mainnet', - info: { - infoType: 'CosmosMetaInfo', - experimental: true, - rpc: 'https://rpc.laozi3.bandchain.org/', - rest: 'https://lcd-band.cosmostation.io', - cosmostationLcdUrl: 'https://lcd-band.cosmostation.io', - cosmostationApiUrl: 'https://api-band.cosmostation.io', - cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', - mintScanName: 'band', - chainName: 'BandChain', - stakeCurrency: { - coinDenom: 'BAND', - coinMinimalDenom: 'uband', - coinDecimals: 6, - coinGeckoId: 'band-protocol', - coinImageUrl: '/tokens/blockchain/BAND.svg', - }, - bip44: { - coinType: 494, - }, - bech32Config: { - bech32PrefixAccAddr: 'band', - bech32PrefixAccPub: 'bandpub', - bech32PrefixValAddr: 'bandvaloper', - bech32PrefixValPub: 'bandvaloperpub', - bech32PrefixConsAddr: 'bandvalcons', - bech32PrefixConsPub: 'bandvalconspub', - }, - currencies: [ - { - coinDenom: 'BAND', - coinMinimalDenom: 'uband', - coinDecimals: 6, - coinGeckoId: 'band-protocol', - coinImageUrl: '/tokens/blockchain/BAND.svg', - }, - ], - feeCurrencies: [ - { - coinDenom: 'BAND', - coinMinimalDenom: 'uband', - coinDecimals: 6, - coinGeckoId: 'band-protocol', - coinImageUrl: '/tokens/blockchain/BAND.svg', - }, - ], - features: ['stargate', 'ibc-transfer', 'no-legacy-stdTx'], - explorerUrlToTx: 'https://cosmoscan.io/tx/{txHash}', - gasPriceStep: null, - }, - }, - { - name: 'COMDEX', - defaultDecimals: 6, - addressPatterns: ['^(comdex1)[0-9a-z]{38}$'], - feeAssets: [ - { - blockchain: 'COMDEX', - symbol: 'CMDX', - address: null, - }, - ], - logo: 'https://api.rango.exchange/blockchains/comdex.svg', - displayName: 'Comdex', - shortName: 'Comdex', - sort: 23, - color: '#FE4350', - enabled: true, - type: TransactionType.COSMOS, - chainId: 'comdex-1', - info: { - infoType: 'CosmosMetaInfo', - experimental: true, - rpc: 'https://rpc.comdex.one', - rest: 'https://rest.comdex.one', - cosmostationLcdUrl: 'https://lcd-comdex.cosmostation.io', - cosmostationApiUrl: 'https://api-comdex.cosmostation.io', - cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', - mintScanName: 'comdex', - chainName: 'Comdex', - stakeCurrency: { - coinDenom: 'CMDX', - coinMinimalDenom: 'ucmdx', - coinDecimals: 6, - coinGeckoId: 'comdex', - coinImageUrl: '/tokens/blockchain/CMDX.png', - }, - bip44: { - coinType: 118, - }, - bech32Config: { - bech32PrefixAccAddr: 'comdex', - bech32PrefixAccPub: 'comdexpub', - bech32PrefixValAddr: 'comdexvaloper', - bech32PrefixValPub: 'comdexvaloperpub', - bech32PrefixConsAddr: 'comdexvalcons', - bech32PrefixConsPub: 'comdexvalconspub', - }, - currencies: [ - { - coinDenom: 'CMDX', - coinMinimalDenom: 'ucmdx', - coinDecimals: 6, - coinGeckoId: 'comdex', - coinImageUrl: '/tokens/blockchain/CMDX.png', - }, - ], - feeCurrencies: [ - { - coinDenom: 'CMDX', - coinMinimalDenom: 'ucmdx', - coinDecimals: 6, - coinGeckoId: 'comdex', - coinImageUrl: '/tokens/blockchain/CMDX.png', - }, - ], - features: ['stargate', 'ibc-transfer', 'no-legacy-stdTx'], - explorerUrlToTx: 'https://www.mintscan.io/comdex/txs/{txHash}', - gasPriceStep: null, - }, - }, - { - name: 'REGEN', - defaultDecimals: 6, - addressPatterns: ['^(regen1)[0-9a-z]{38}$'], - feeAssets: [ - { - blockchain: 'REGEN', - symbol: 'REGEN', - address: null, - }, - ], - logo: 'https://api.rango.exchange/blockchains/regen.png', - displayName: 'Regen Network', - shortName: 'Regen Network', - sort: 24, - color: '#4FB573', - enabled: true, - type: TransactionType.COSMOS, - chainId: 'regen-1', - info: { - infoType: 'CosmosMetaInfo', - experimental: false, - rpc: 'https://rpc-regen.keplr.app', - rest: 'https://lcd-regen.keplr.app', - cosmostationLcdUrl: 'https://lcd-regen.keplr.app', - cosmostationApiUrl: 'https://api-regen.cosmostation.io/', - cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', - mintScanName: 'regen', - chainName: 'Regen Network', - stakeCurrency: { - coinDenom: 'REGEN', - coinMinimalDenom: 'uregen', - coinDecimals: 6, - coinGeckoId: 'pool:uregen', - coinImageUrl: '/tokens/blockchain/regen.png', - }, - bip44: { - coinType: 118, - }, - bech32Config: { - bech32PrefixAccAddr: 'regen', - bech32PrefixAccPub: 'regenpub', - bech32PrefixValAddr: 'regenvaloper', - bech32PrefixValPub: 'regenvaloperpub', - bech32PrefixConsAddr: 'regenvalcons', - bech32PrefixConsPub: 'regenvalconspub', - }, - currencies: [ - { - coinDenom: 'REGEN', - coinMinimalDenom: 'uregen', - coinDecimals: 6, - coinGeckoId: 'pool:uregen', - coinImageUrl: '/tokens/blockchain/regen.png', - }, - ], - feeCurrencies: [ - { - coinDenom: 'REGEN', - coinMinimalDenom: 'uregen', - coinDecimals: 6, - coinGeckoId: 'pool:uregen', - coinImageUrl: '/tokens/blockchain/regen.png', - }, - ], - features: ['stargate', 'ibc-transfer'], - explorerUrlToTx: 'https://regen.aneka.io/txs/{txHash}', - gasPriceStep: { - low: 0.015, - average: 0.025, - high: 0.04, - }, - }, - }, - { - name: 'IRIS', - defaultDecimals: 6, - addressPatterns: ['^(iaa1)[0-9a-z]{38}$'], - feeAssets: [ - { - blockchain: 'IRIS', - symbol: 'IRIS', - address: null, - }, - ], - logo: 'https://api.rango.exchange/blockchains/iris.png', - displayName: 'IRISnet', - shortName: 'IRISnet', - sort: 25, - color: '#8A4A8E', - enabled: true, - type: TransactionType.COSMOS, - chainId: 'irishub-1', - info: { - infoType: 'CosmosMetaInfo', - experimental: false, - rpc: 'https://rpc-iris.keplr.app', - rest: 'https://lcd-iris.keplr.app', - cosmostationLcdUrl: 'https://lcd-iris.cosmostation.io', - cosmostationApiUrl: 'https://api-iris.cosmostation.io', - cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', - mintScanName: 'iris', - chainName: 'IRISnet', - stakeCurrency: { - coinDenom: 'IRIS', - coinMinimalDenom: 'uiris', - coinDecimals: 6, - coinGeckoId: 'iris-network', - coinImageUrl: '/tokens/blockchain/iris.svg', - }, - bip44: { - coinType: 118, - }, - bech32Config: { - bech32PrefixAccAddr: 'iaa', - bech32PrefixAccPub: 'iaapub', - bech32PrefixValAddr: 'iaavaloper', - bech32PrefixValPub: 'iaavaloperpub', - bech32PrefixConsAddr: 'iaavalcons', - bech32PrefixConsPub: 'iaavalconspub', - }, - currencies: [ - { - coinDenom: 'IRIS', - coinMinimalDenom: 'uiris', - coinDecimals: 6, - coinGeckoId: 'iris-network', - coinImageUrl: '/tokens/blockchain/iris.svg', - }, - ], - feeCurrencies: [ - { - coinDenom: 'IRIS', - coinMinimalDenom: 'uiris', - coinDecimals: 6, - coinGeckoId: 'iris-network', - coinImageUrl: '/tokens/blockchain/iris.svg', - }, - ], - features: ['stargate', 'ibc-transfer'], - explorerUrlToTx: 'https://www.mintscan.io/iris/txs/{txHash}', - gasPriceStep: { - low: 0.2, - average: 0.3, - high: 0.4, - }, - }, - }, - { - name: 'EMONEY', - defaultDecimals: 6, - addressPatterns: ['^(emoney1)[0-9a-z]{38}$'], - feeAssets: [ - { - blockchain: 'EMONEY', - symbol: 'NGM', - address: null, - }, - ], - logo: 'https://api.rango.exchange/blockchains/emoney.svg', - displayName: 'e-Money', - shortName: 'e-Money', - sort: 25, - color: '#DFF5EF', - enabled: true, - type: TransactionType.COSMOS, - chainId: 'emoney-3', - info: { - infoType: 'CosmosMetaInfo', - experimental: true, - rpc: 'https://rpc-emoney.keplr.app', - rest: 'https://lcd-emoney.keplr.app', - cosmostationLcdUrl: 'https://lcd-emoney.cosmostation.io', - cosmostationApiUrl: 'https://api-emoney.cosmostation.io', - cosmostationDenomTracePath: - '/ibc/applications/transfer/v1beta1/denom_traces/', - mintScanName: 'emoney', - chainName: 'e-Money', - stakeCurrency: { - coinDenom: 'NGM', - coinMinimalDenom: 'ungm', - coinDecimals: 6, - coinGeckoId: 'e-money', - coinImageUrl: '/tokens/blockchain/NGM.png', - }, - bip44: { - coinType: 118, - }, - bech32Config: { - bech32PrefixAccAddr: 'emoney', - bech32PrefixAccPub: 'emoneypub', - bech32PrefixValAddr: 'emoneyvaloper', - bech32PrefixValPub: 'emoneyvaloperpub', - bech32PrefixConsAddr: 'emoneyvalcons', - bech32PrefixConsPub: 'emoneyvalconspub', - }, - currencies: [ - { - coinDenom: 'NGM', - coinMinimalDenom: 'ungm', - coinDecimals: 6, - coinGeckoId: 'e-money', - coinImageUrl: '/tokens/blockchain/NGM.png', - }, - { - coinDenom: 'EEUR', - coinMinimalDenom: 'eeur', - coinDecimals: 6, - coinGeckoId: 'e-money-eur', - coinImageUrl: '/tokens/blockchain/EEUR.png', - }, - ], - feeCurrencies: [ - { - coinDenom: 'NGM', - coinMinimalDenom: 'ungm', - coinDecimals: 6, - coinGeckoId: 'e-money', - coinImageUrl: '/tokens/blockchain/NGM.png', - }, - ], - features: ['stargate', 'ibc-transfer'], - explorerUrlToTx: 'https://emoney.bigdipper.live/transactions/{txHash}', - gasPriceStep: { - low: 1, - average: 1, - high: 1, - }, - }, - }, - { - name: 'GNOSIS', - defaultDecimals: 18, - addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], - feeAssets: [ - { - blockchain: 'GNOSIS', - symbol: 'XDAI', - address: null, - }, - ], - logo: 'https://api.rango.exchange/blockchains/gnosis.svg', - displayName: 'Gnosis', - shortName: 'Gnosis', - sort: 26, - color: '#3E6957', - enabled: true, - type: TransactionType.EVM, - chainId: '0x64', - info: { - infoType: 'EvmMetaInfo', - chainName: 'Gnosis Chain', - nativeCurrency: { - name: 'XDAI', - symbol: 'XDAI', - decimals: 18, - }, - rpcUrls: ['https://rpc.gnosischain.com'], - blockExplorerUrls: ['https://blockscout.com/xdai/mainnet'], - addressUrl: 'https://blockscout.com/xdai/mainnet/address/{wallet}', - transactionUrl: 'https://blockscout.com/xdai/mainnet/tx/{txHash}', - }, - }, - { - name: 'LTC', - defaultDecimals: 8, - addressPatterns: ['^(L|M|3)[A-Za-z0-9]{33}$|^(ltc1)[0-9A-Za-z]{39}$'], - feeAssets: [ - { - blockchain: 'LTC', - symbol: 'LTC', - address: null, - }, - ], - logo: 'https://api.rango.exchange/blockchains/ltc.svg', - displayName: 'LiteCoin', - shortName: 'LTC', - sort: 27, - color: '#345D9D', - enabled: true, - type: TransactionType.TRANSFER, - chainId: null, - info: null, - }, - { - name: 'BCH', - defaultDecimals: 8, - addressPatterns: ['^[13][a-km-zA-HJ-NP-Z1-9]{25,34}$|^[0-9A-Za-z]{42,42}$'], - feeAssets: [ - { - blockchain: 'BCH', - symbol: 'BCH', - address: null, - }, - ], - logo: 'https://api.rango.exchange/blockchains/bch.svg', - displayName: 'Bitcoin Cash', - shortName: 'BCH', - sort: 28, - color: '#0AC18E', - enabled: true, - type: TransactionType.TRANSFER, - chainId: null, - info: null, - }, - { - name: 'BITSONG', - defaultDecimals: 6, - addressPatterns: ['^(bitsong1)[0-9a-z]{38}$'], - feeAssets: [ - { - blockchain: 'BITSONG', - symbol: 'BTSG', - address: null, - }, - ], - logo: 'https://api.rango.exchange/blockchains/bitsong.svg', - displayName: 'BitSong', - shortName: 'BitSong', - sort: 29, - color: '#FF005C', - enabled: false, - type: TransactionType.COSMOS, - chainId: 'bitsong-2b', - info: { - infoType: 'CosmosMetaInfo', - experimental: true, - rpc: 'https://rpc.explorebitsong.com', - rest: 'https://lcd.explorebitsong.com', - cosmostationLcdUrl: 'https://lcd-bitsong.cosmostation.io', - cosmostationApiUrl: 'https://api-bitsong.cosmostation.io', - cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', - mintScanName: 'bitsong', - chainName: 'BitSong', - stakeCurrency: { - coinDenom: 'BTSG', - coinMinimalDenom: 'ubtsg', - coinDecimals: 6, - coinGeckoId: 'pool:ubtsg', - coinImageUrl: '/tokens/blockchain/BTSG.png', - }, - bip44: { - coinType: 639, - }, - bech32Config: { - bech32PrefixAccAddr: 'bitsong', - bech32PrefixAccPub: 'bitsongpub', - bech32PrefixValAddr: 'bitsongvaloper', - bech32PrefixValPub: 'bitsongvaloperpub', - bech32PrefixConsAddr: 'bitsongvalcons', - bech32PrefixConsPub: 'bitsongvalconspub', - }, - currencies: [ - { - coinDenom: 'BTSG', - coinMinimalDenom: 'ubtsg', - coinDecimals: 6, - coinGeckoId: 'pool:ubtsg', - coinImageUrl: '/tokens/blockchain/BTSG.png', - }, - ], - feeCurrencies: [ - { - coinDenom: 'BTSG', - coinMinimalDenom: 'ubtsg', - coinDecimals: 6, - coinGeckoId: 'pool:ubtsg', - coinImageUrl: '/tokens/blockchain/BTSG.png', - }, - ], - features: ['stargate', 'ibc-transfer', 'no-legacy-stdTx', 'ibc-go'], - explorerUrlToTx: 'https://explorebitsong.com/transactions/{txHash}', - gasPriceStep: null, - }, - }, - { - name: 'FUSE', - defaultDecimals: 18, - addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], - feeAssets: [ - { - blockchain: 'FUSE', - symbol: 'FUSE', - address: null, - }, - ], - logo: 'https://api.rango.exchange/blockchains/fuse.png', - displayName: 'Fuse', - shortName: 'Fuse', - sort: 29, - color: '#C5F9AD', - enabled: true, - type: TransactionType.EVM, - chainId: '0x7a', - info: { - infoType: 'EvmMetaInfo', - chainName: 'Fuse Mainnet', - nativeCurrency: { - name: 'FUSE', - symbol: 'FUSE', - decimals: 18, - }, - rpcUrls: ['https://rpc.fuse.io'], - blockExplorerUrls: ['https://explorer.fuse.io'], - addressUrl: 'https://explorer.fuse.io/address/{wallet}', - transactionUrl: 'https://explorer.fuse.io/tx/{txHash}', - }, - }, - { - name: 'AKASH', - defaultDecimals: 6, - addressPatterns: ['^(akash1)[0-9a-z]{38}$'], - feeAssets: [ - { - blockchain: 'AKASH', - symbol: 'AKT', - address: null, - }, - ], - logo: 'https://api.rango.exchange/blockchains/akash.svg', - displayName: 'Akash', - shortName: 'Akash', - sort: 30, - color: '#ED3524', - enabled: true, - type: TransactionType.COSMOS, - chainId: 'akashnet-2', - info: { - infoType: 'CosmosMetaInfo', - experimental: false, - rpc: 'https://rpc-akash.keplr.app', - rest: 'https://lcd-akash.keplr.app', - cosmostationLcdUrl: 'https://lcd-akash.cosmostation.io', - cosmostationApiUrl: 'https://api-akash.cosmostation.io', - cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', - mintScanName: 'akash', - chainName: 'Akash', - stakeCurrency: { - coinDenom: 'AKT', - coinMinimalDenom: 'uakt', - coinDecimals: 6, - coinGeckoId: 'akash-network', - coinImageUrl: '/tokens/blockchain/akt.svg', - }, - bip44: { - coinType: 118, - }, - bech32Config: { - bech32PrefixAccAddr: 'akash', - bech32PrefixAccPub: 'akashpub', - bech32PrefixValAddr: 'akashvaloper', - bech32PrefixValPub: 'akashvaloperpub', - bech32PrefixConsAddr: 'akashvalcons', - bech32PrefixConsPub: 'akashvalconspub', - }, - currencies: [ - { - coinDenom: 'AKT', - coinMinimalDenom: 'uakt', - coinDecimals: 6, - coinGeckoId: 'akash-network', - coinImageUrl: '/tokens/blockchain/akt.svg', - }, - ], - feeCurrencies: [ - { - coinDenom: 'AKT', - coinMinimalDenom: 'uakt', - coinDecimals: 6, - coinGeckoId: 'akash-network', - coinImageUrl: '/tokens/blockchain/akt.svg', - }, - ], - features: ['stargate', 'ibc-transfer'], - explorerUrlToTx: 'https://www.mintscan.io/akash/txs/{txHash}', - gasPriceStep: { - low: 0.001, - average: 0.0025, - high: 0.004, - }, - }, - }, - { - name: 'KI', - defaultDecimals: 6, - addressPatterns: ['^(ki1)[0-9a-z]{38}$'], - feeAssets: [ - { - blockchain: 'KI', - symbol: 'XKI', - address: null, - }, - ], - logo: 'https://api.rango.exchange/blockchains/ki.png', - displayName: 'Ki', - shortName: 'Ki', - sort: 30, - color: '#0F2B3D', - enabled: true, - type: TransactionType.COSMOS, - chainId: 'kichain-2', - info: { - infoType: 'CosmosMetaInfo', - experimental: true, - rpc: 'https://rpc-mainnet.blockchain.ki', - rest: 'https://api-mainnet.blockchain.ki', - cosmostationLcdUrl: 'https://lcd-kichain.cosmostation.io', - cosmostationApiUrl: 'https://api-kichain.cosmostation.io', - cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', - mintScanName: 'ki-chain', - chainName: 'Ki', - stakeCurrency: { - coinDenom: 'XKI', - coinMinimalDenom: 'uxki', - coinDecimals: 6, - coinGeckoId: 'pool:uxki', - coinImageUrl: '/tokens/blockchain/XKI.png', - }, - bip44: { - coinType: 118, - }, - bech32Config: { - bech32PrefixAccAddr: 'ki', - bech32PrefixAccPub: 'kipub', - bech32PrefixValAddr: 'kivaloper', - bech32PrefixValPub: 'kivaloperpub', - bech32PrefixConsAddr: 'kivalcons', - bech32PrefixConsPub: 'kivalconspub', - }, - currencies: [ - { - coinDenom: 'XKI', - coinMinimalDenom: 'uxki', - coinDecimals: 6, - coinGeckoId: 'pool:uxki', - coinImageUrl: '/tokens/blockchain/XKI.png', - }, - ], - feeCurrencies: [ - { - coinDenom: 'XKI', - coinMinimalDenom: 'uxki', - coinDecimals: 6, - coinGeckoId: 'pool:uxki', - coinImageUrl: '/tokens/blockchain/XKI.png', - }, - ], - features: ['stargate', 'ibc-transfer'], - explorerUrlToTx: 'https://www.mintscan.io/ki-chain/txs/{txHash}', - gasPriceStep: null, - }, - }, - { - name: 'KUJIRA', - defaultDecimals: 6, - addressPatterns: ['^(kujira1)[0-9a-z]{38}$'], - feeAssets: [ - { - blockchain: 'KUJIRA', - symbol: 'KUJI', - address: null, - }, - ], - logo: 'https://api.rango.exchange/blockchains/kuji.svg', - displayName: 'Kujira', - shortName: 'Kujira', - sort: 31, - color: '#DF3935', - enabled: true, - type: TransactionType.COSMOS, - chainId: 'kaiyo-1', - info: { - infoType: 'CosmosMetaInfo', - experimental: true, - rpc: 'https://rpc.kaiyo.kujira.setten.io', - rest: 'https://lcd.kaiyo.kujira.setten.io', - cosmostationLcdUrl: 'https://lcd-kujira.cosmostation.io', - cosmostationApiUrl: 'https://api-kujira.cosmostation.io', - cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', - mintScanName: 'kujira', - chainName: 'Kujira', - stakeCurrency: { - coinDenom: 'KUJI', - coinMinimalDenom: 'ukuji', - coinDecimals: 6, - coinGeckoId: 'kujira', - coinImageUrl: '/tokens/blockchain/kuji.svg', - }, - bip44: { - coinType: 118, - }, - bech32Config: { - bech32PrefixAccAddr: 'kujira', - bech32PrefixAccPub: 'kujirapub', - bech32PrefixValAddr: 'kujiravaloper', - bech32PrefixValPub: 'kujiravaloperpub', - bech32PrefixConsAddr: 'kujiravalcons', - bech32PrefixConsPub: 'kujiravalconspub', - }, - currencies: [ - { - coinDenom: 'KUJI', - coinMinimalDenom: 'ukuji', - coinDecimals: 6, - coinGeckoId: 'kujira', - coinImageUrl: '/tokens/blockchain/kuji.png', - }, - ], - feeCurrencies: [ - { - coinDenom: 'KUJI', - coinMinimalDenom: 'ukuji', - coinDecimals: 6, - coinGeckoId: 'kujira', - coinImageUrl: '/tokens/blockchain/kuji.png', - }, - ], - features: ['stargate', 'ibc-transfer'], - explorerUrlToTx: 'https://finder.kujira.app/kaiyo-1/tx/{txHash}', - gasPriceStep: { - low: 0.01, - average: 0.025, - high: 0.03, - }, - }, - }, - { - name: 'PERSISTENCE', - defaultDecimals: 6, - addressPatterns: ['^(persistence1)[0-9a-z]{38}$'], - feeAssets: [ - { - blockchain: 'PERSISTENCE', - symbol: 'XPRT', - address: null, - }, - ], - logo: 'https://api.rango.exchange/blockchains/persistence.png', - displayName: 'Persistence', - shortName: 'Persistence', - sort: 31, - color: '#383838', - enabled: true, - type: TransactionType.COSMOS, - chainId: 'core-1', - info: { - infoType: 'CosmosMetaInfo', - experimental: false, - rpc: 'https://rpc-persistence.keplr.app', - rest: 'https://lcd-persistence.keplr.app', - cosmostationLcdUrl: 'https://lcd-persistence.cosmostation.io', - cosmostationApiUrl: 'https://api-persistence.cosmostation.io', - cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', - mintScanName: 'persistence', - chainName: 'Persistence', - stakeCurrency: { - coinDenom: 'XPRT', - coinMinimalDenom: 'uxprt', - coinDecimals: 6, - coinGeckoId: 'persistence', - coinImageUrl: '/tokens/blockchain/xprt.png', - }, - bip44: { - coinType: 750, - }, - bech32Config: { - bech32PrefixAccAddr: 'persistence', - bech32PrefixAccPub: 'persistencepub', - bech32PrefixValAddr: 'persistencevaloper', - bech32PrefixValPub: 'persistencevaloperpub', - bech32PrefixConsAddr: 'persistencevalcons', - bech32PrefixConsPub: 'persistencevalconspub', - }, - currencies: [ - { - coinDenom: 'XPRT', - coinMinimalDenom: 'uxprt', - coinDecimals: 6, - coinGeckoId: 'persistence', - coinImageUrl: '/tokens/blockchain/xprt.png', - }, - ], - feeCurrencies: [ - { - coinDenom: 'XPRT', - coinMinimalDenom: 'uxprt', - coinDecimals: 6, - coinGeckoId: 'persistence', - coinImageUrl: '/tokens/blockchain/xprt.png', - }, - ], - features: ['stargate', 'ibc-transfer'], - explorerUrlToTx: 'https://www.mintscan.io/persistence/txs/{txHash}', - gasPriceStep: { - low: 0, - average: 0.025, - high: 0.04, - }, - }, - }, - { - name: 'MEDIBLOC', - defaultDecimals: 6, - addressPatterns: ['^(panacea1)[0-9a-z]{38}$'], - feeAssets: [ - { - blockchain: 'MEDIBLOC', - symbol: 'MED', - address: null, - }, - ], - logo: 'https://api.rango.exchange/blockchains/medibloc.png', - displayName: 'MediBloc', - shortName: 'MediBloc', - sort: 31, - color: '#4B66DC', - enabled: false, - type: TransactionType.COSMOS, - chainId: 'panacea-3', - info: { - infoType: 'CosmosMetaInfo', - experimental: true, - rpc: 'https://rpc.gopanacea.org', - rest: 'https://api.gopanacea.org', - cosmostationLcdUrl: 'https://lcd-medibloc.cosmostation.io', - cosmostationApiUrl: 'https://api-medibloc.cosmostation.io', - cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', - mintScanName: 'medibloc', - chainName: 'MediBloc', - stakeCurrency: { - coinDenom: 'MED', - coinMinimalDenom: 'umed', - coinDecimals: 6, - coinGeckoId: 'medibloc', - coinImageUrl: '/tokens/blockchain/MED.png', - }, - bip44: { - coinType: 118, - }, - bech32Config: { - bech32PrefixAccAddr: 'panacea', - bech32PrefixAccPub: 'panaceapub', - bech32PrefixValAddr: 'panaceavaloper', - bech32PrefixValPub: 'panaceavaloperpub', - bech32PrefixConsAddr: 'panaceavalcons', - bech32PrefixConsPub: 'panaceavalconspub', - }, - currencies: [ - { - coinDenom: 'MED', - coinMinimalDenom: 'umed', - coinDecimals: 6, - coinGeckoId: 'medibloc', - coinImageUrl: '/tokens/blockchain/MED.png', - }, - ], - feeCurrencies: [ - { - coinDenom: 'MED', - coinMinimalDenom: 'umed', - coinDecimals: 6, - coinGeckoId: 'medibloc', - coinImageUrl: '/tokens/blockchain/MED.png', - }, - ], - features: ['stargate', 'ibc-transfer'], - explorerUrlToTx: 'https://www.mintscan.io/medibloc/txs/{txHash}', - gasPriceStep: { - low: 5, - average: 7, - high: 9, - }, - }, - }, - { - name: 'SENTINEL', - defaultDecimals: 6, - addressPatterns: ['^(sent1)[0-9a-z]{38}$'], - feeAssets: [ - { - blockchain: 'SENTINEL', - symbol: 'DVPN', - address: null, - }, - ], - logo: 'https://api.rango.exchange/blockchains/sentinel.png', - displayName: 'Sentinel', - shortName: 'Sentinel', - sort: 32, - color: '#142E51', - enabled: true, - type: TransactionType.COSMOS, - chainId: 'sentinelhub-2', - info: { - infoType: 'CosmosMetaInfo', - experimental: false, - rpc: 'https://rpc-sentinel.keplr.app', - rest: 'https://lcd-sentinel.keplr.app', - cosmostationLcdUrl: 'https://lcd-sentinel.cosmostation.io', - cosmostationApiUrl: 'https://api-sentinel.cosmostation.io', - cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', - mintScanName: 'sentinel', - chainName: 'Sentinel', - stakeCurrency: { - coinDenom: 'DVPN', - coinMinimalDenom: 'udvpn', - coinDecimals: 6, - coinGeckoId: 'sentinel', - coinImageUrl: '/tokens/blockchain/dvpn.png', - }, - bip44: { - coinType: 118, - }, - bech32Config: { - bech32PrefixAccAddr: 'sent', - bech32PrefixAccPub: 'sentpub', - bech32PrefixValAddr: 'sentvaloper', - bech32PrefixValPub: 'sentvaloperpub', - bech32PrefixConsAddr: 'sentvalcons', - bech32PrefixConsPub: 'sentvalconspub', - }, - currencies: [ - { - coinDenom: 'DVPN', - coinMinimalDenom: 'udvpn', - coinDecimals: 6, - coinGeckoId: 'sentinel', - coinImageUrl: '/tokens/blockchain/dvpn.png', - }, - ], - feeCurrencies: [ - { - coinDenom: 'DVPN', - coinMinimalDenom: 'udvpn', - coinDecimals: 6, - coinGeckoId: 'sentinel', - coinImageUrl: '/tokens/blockchain/dvpn.png', - }, - ], - features: ['stargate', 'ibc-transfer'], - explorerUrlToTx: 'https://www.mintscan.io/sentinel/txs/{txHash}', - gasPriceStep: { - low: 0.1, - average: 0.25, - high: 0.4, - }, - }, - }, - { - name: 'INJECTIVE', - defaultDecimals: 6, - addressPatterns: ['^(inj1)[0-9a-z]{38}$'], - feeAssets: [ - { - blockchain: 'INJECTIVE', - symbol: 'INJ', - address: null, - }, - ], - logo: 'https://api.rango.exchange/blockchains/injective.svg', - displayName: 'Injective', - shortName: 'Injective', - sort: 33, - color: '#29B2F4', - enabled: false, - type: TransactionType.COSMOS, - chainId: 'injective-1', - info: { - infoType: 'CosmosMetaInfo', - experimental: true, - rpc: 'https://tm.injective.network', - rest: 'https://lcd.injective.network', - cosmostationLcdUrl: 'https://lcd-inj.cosmostation.io', - cosmostationApiUrl: 'https://api-inj.cosmostation.io', - cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', - mintScanName: 'injective', - chainName: 'Injective', - stakeCurrency: { - coinDenom: 'INJ', - coinMinimalDenom: 'uinj', - coinDecimals: 18, - coinGeckoId: 'injective', - coinImageUrl: '/tokens/INJECTIVE/inj.svg', - }, - bip44: { - coinType: 529, - }, - bech32Config: { - bech32PrefixAccAddr: 'inj', - bech32PrefixAccPub: 'injpub', - bech32PrefixValAddr: 'injvaloper', - bech32PrefixValPub: 'injvaloperpub', - bech32PrefixConsAddr: 'injvalcons', - bech32PrefixConsPub: 'injvalconspub', - }, - currencies: [ - { - coinDenom: 'INJ', - coinMinimalDenom: 'uinj', - coinDecimals: 18, - coinGeckoId: 'injective', - coinImageUrl: '/tokens/INJECTIVE/inj.svg', - }, - ], - feeCurrencies: [ - { - coinDenom: 'INJ', - coinMinimalDenom: 'uinj', - coinDecimals: 18, - coinGeckoId: 'injective', - coinImageUrl: '/tokens/INJECTIVE/inj.svg', - }, - ], - features: ['stargate', 'ibc-transfer'], - explorerUrlToTx: 'https://www.mintscan.io/injective/txs/{txHash}', - gasPriceStep: { - low: 500000000, - average: 500000000, - high: 500000000, - }, - }, - }, - { - name: 'SECRET', - defaultDecimals: 6, - addressPatterns: ['^(secret1)[0-9a-z]{38}$'], - feeAssets: [ - { - blockchain: 'SECRET', - symbol: 'SCRT', - address: null, - }, - ], - logo: 'https://api.rango.exchange/blockchains/secret.svg', - displayName: 'Secret', - shortName: 'Secret', - sort: 34, - color: '#1B1B1B', - enabled: false, - type: TransactionType.COSMOS, - chainId: 'secret-4', - info: { - infoType: 'CosmosMetaInfo', - experimental: false, - rpc: 'https://rpc-secret.keplr.app', - rest: 'https://lcd-secret.keplr.app', - cosmostationLcdUrl: 'https://lcd-secret.cosmostation.io', - cosmostationApiUrl: 'https://api-secret.cosmostation.io', - cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', - mintScanName: 'secret', - chainName: 'Secret', - stakeCurrency: { - coinDenom: 'SCRT', - coinMinimalDenom: 'uscrt', - coinDecimals: 6, - coinGeckoId: 'secret', - coinImageUrl: 'https://dhj8dql1kzq2v.cloudfront.net/white/secret.png', - }, - bip44: { - coinType: 529, - }, - bech32Config: { - bech32PrefixAccAddr: 'secret', - bech32PrefixAccPub: 'secretpub', - bech32PrefixValAddr: 'secretvaloper', - bech32PrefixValPub: 'secretvaloperpub', - bech32PrefixConsAddr: 'secretvalcons', - bech32PrefixConsPub: 'secretvalconspub', - }, - currencies: [ - { - coinDenom: 'SCRT', - coinMinimalDenom: 'uscrt', - coinDecimals: 6, - coinGeckoId: 'secret', - coinImageUrl: 'https://dhj8dql1kzq2v.cloudfront.net/white/secret.png', - }, - ], - feeCurrencies: [ - { - coinDenom: 'SCRT', - coinMinimalDenom: 'uscrt', - coinDecimals: 6, - coinGeckoId: 'secret', - coinImageUrl: 'https://dhj8dql1kzq2v.cloudfront.net/white/secret.png', - }, - ], - features: ['secretwasm'], - explorerUrlToTx: 'https://www.mintscan.io/injective/txs/{txHash}', - gasPriceStep: { - low: 0.1, - average: 0.25, - high: 0.3, - }, - }, - }, - { - name: 'STARNAME', - defaultDecimals: 6, - addressPatterns: ['^(star1)[0-9a-z]{38}$'], - feeAssets: [ - { - blockchain: 'STARNAME', - symbol: 'IOV', - address: null, - }, - ], - logo: 'https://api.rango.exchange/blockchains/starname.png', - displayName: 'Starname', - shortName: 'Starname', - sort: 35, - color: '#BC64BB', - enabled: true, - type: TransactionType.COSMOS, - chainId: 'iov-mainnet-ibc', - info: { - infoType: 'CosmosMetaInfo', - experimental: false, - rpc: 'https://rpc-iov.keplr.app', - rest: 'https://lcd-iov.keplr.app', - cosmostationLcdUrl: 'https://lcd-iov.cosmostation.io', - cosmostationApiUrl: 'https://api-iov.cosmostation.io', - cosmostationDenomTracePath: - '/ibc/applications/transfer/v1beta1/denom_traces/', - mintScanName: 'starname', - chainName: 'Starname', - stakeCurrency: { - coinDenom: 'IOV', - coinMinimalDenom: 'uiov', - coinDecimals: 6, - coinGeckoId: 'starname', - coinImageUrl: '/tokens/blockchain/IOV.png', - }, - bip44: { - coinType: 494, - }, - bech32Config: { - bech32PrefixAccAddr: 'star', - bech32PrefixAccPub: 'starpub', - bech32PrefixValAddr: 'starvaloper', - bech32PrefixValPub: 'starvaloperpub', - bech32PrefixConsAddr: 'starvalcons', - bech32PrefixConsPub: 'starvalconspub', - }, - currencies: [ - { - coinDenom: 'IOV', - coinMinimalDenom: 'uiov', - coinDecimals: 6, - coinGeckoId: 'starname', - coinImageUrl: '/tokens/blockchain/IOV.png', - }, - ], - feeCurrencies: [ - { - coinDenom: 'IOV', - coinMinimalDenom: 'uiov', - coinDecimals: 6, - coinGeckoId: 'starname', - coinImageUrl: '/tokens/blockchain/IOV.png', - }, - ], - features: ['stargate', 'ibc-transfer'], - explorerUrlToTx: 'https://www.mintscan.io/starname/txs/{txHash}', - gasPriceStep: { - low: 1, - average: 2, - high: 3, - }, - }, - }, - { - name: 'KONSTELLATION', - defaultDecimals: 6, - addressPatterns: ['^(darc1)[0-9a-z]{38}$'], - feeAssets: [ - { - blockchain: 'KONSTELLATION', - symbol: 'DARC', - address: null, - }, - ], - logo: 'https://api.rango.exchange/blockchains/konstellation.svg', - displayName: 'Konstellation', - shortName: 'Konstellation', - sort: 35, - color: '#3D7BC2', - enabled: false, - type: TransactionType.COSMOS, - chainId: 'darchub', - info: { - infoType: 'CosmosMetaInfo', - experimental: true, - rpc: 'https://node1.konstellation.tech:26657', - rest: 'https://node1.konstellation.tech:1318', - cosmostationLcdUrl: 'https://api-konstellation.cosmostation.io', - cosmostationApiUrl: 'https://api-konstellation.cosmostation.io', - cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', - mintScanName: 'konstellation', - chainName: 'Konstellation', - stakeCurrency: { - coinDenom: 'DARC', - coinMinimalDenom: 'udarc', - coinDecimals: 6, - coinGeckoId: 'pool:udarc', - coinImageUrl: '/tokens/blockchain/DARC.png', - }, - bip44: { - coinType: 118, - }, - bech32Config: { - bech32PrefixAccAddr: 'darc', - bech32PrefixAccPub: 'darcpub', - bech32PrefixValAddr: 'darcvaloper', - bech32PrefixValPub: 'darcvaloperpub', - bech32PrefixConsAddr: 'darcvalcons', - bech32PrefixConsPub: 'darcvalconspub', - }, - currencies: [ - { - coinDenom: 'DARC', - coinMinimalDenom: 'udarc', - coinDecimals: 6, - coinGeckoId: 'pool:udarc', - coinImageUrl: '/tokens/blockchain/DARC.png', - }, - ], - feeCurrencies: [ - { - coinDenom: 'DARC', - coinMinimalDenom: 'udarc', - coinDecimals: 6, - coinGeckoId: 'pool:udarc', - coinImageUrl: '/tokens/blockchain/DARC.png', - }, - ], - features: ['stargate', 'ibc-transfer', 'no-legacy-stdTx'], - explorerUrlToTx: 'https://www.mintscan.io/konstellation/txs/{txHash}', - gasPriceStep: null, - }, - }, - { - name: 'UMEE', - defaultDecimals: 6, - addressPatterns: ['^(umee1)[0-9a-z]{38}$'], - feeAssets: [ - { - blockchain: 'UMEE', - symbol: 'UMEE', - address: null, - }, - ], - logo: 'https://api.rango.exchange/blockchains/umee.svg', - displayName: 'Umee', - shortName: 'Umee', - sort: 36, - color: '#D2B6FF', - enabled: true, - type: TransactionType.COSMOS, - chainId: 'umee-1', - info: { - infoType: 'CosmosMetaInfo', - experimental: false, - rpc: 'https://api.barnacle.mainnet.network.umee.cc', - rest: 'https://lcd-umee.cosmostation.io', - cosmostationLcdUrl: 'https://lcd-umee.cosmostation.io', - cosmostationApiUrl: 'https://api-umee.cosmostation.io', - cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', - mintScanName: 'umee', - chainName: 'Umee', - stakeCurrency: { - coinDenom: 'UMEE', - coinMinimalDenom: 'uumee', - coinDecimals: 6, - coinGeckoId: 'pool:uumee', - coinImageUrl: '/tokens/blockchain/UMEE.png', - }, - bip44: { - coinType: 118, - }, - bech32Config: { - bech32PrefixAccAddr: 'umee', - bech32PrefixAccPub: 'umeepub', - bech32PrefixValAddr: 'umeevaloper', - bech32PrefixValPub: 'umeevaloperpub', - bech32PrefixConsAddr: 'umeevalcons', - bech32PrefixConsPub: 'umeevalconspub', - }, - currencies: [ - { - coinDenom: 'UMEE', - coinMinimalDenom: 'uumee', - coinDecimals: 6, - coinGeckoId: 'pool:uumee', - coinImageUrl: '/tokens/blockchain/UMEE.png', - }, - ], - feeCurrencies: [ - { - coinDenom: 'UMEE', - coinMinimalDenom: 'uumee', - coinDecimals: 6, - coinGeckoId: 'pool:uumee', - coinImageUrl: '/tokens/blockchain/UMEE.png', - }, - ], - features: ['stargate', 'ibc-transfer', 'no-legacy-stdTx'], - explorerUrlToTx: 'https://www.mintscan.io/umee/txs/{txHash}', - gasPriceStep: { - low: 0.05, - average: 0.06, - high: 0.1, - }, - }, - }, - { - name: 'BITCANNA', - defaultDecimals: 6, - addressPatterns: ['^(bcna1)[0-9a-z]{38}$'], - feeAssets: [ - { - blockchain: 'BITCANNA', - symbol: 'BCNA', - address: null, - }, - ], - logo: 'https://api.rango.exchange/blockchains/bitcanna.svg', - displayName: 'BitCanna', - shortName: 'BitCanna', - sort: 36, - color: '#3CC194', - enabled: true, - type: TransactionType.COSMOS, - chainId: 'bitcanna-1', - info: { - infoType: 'CosmosMetaInfo', - experimental: true, - rpc: 'https://rpc.bitcanna.io', - rest: 'https://lcd.bitcanna.io', - cosmostationLcdUrl: 'https://lcd-bitcanna.cosmostation.io', - cosmostationApiUrl: 'https://api-bitcanna.cosmostation.io', - cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', - mintScanName: 'bitcanna', - chainName: 'BitCanna', - stakeCurrency: { - coinDenom: 'BCNA', - coinMinimalDenom: 'ubcna', - coinDecimals: 6, - coinGeckoId: 'bitcanna', - coinImageUrl: '/tokens/blockchain/BCNA.png', - }, - bip44: { - coinType: 118, - }, - bech32Config: { - bech32PrefixAccAddr: 'bcna', - bech32PrefixAccPub: 'bcnapub', - bech32PrefixValAddr: 'bcnavaloper', - bech32PrefixValPub: 'bcnavaloperpub', - bech32PrefixConsAddr: 'bcnavalcons', - bech32PrefixConsPub: 'bcnavalconspub', - }, - currencies: [ - { - coinDenom: 'BCNA', - coinMinimalDenom: 'ubcna', - coinDecimals: 6, - coinGeckoId: 'bitcanna', - coinImageUrl: '/tokens/blockchain/BCNA.png', - }, - ], - feeCurrencies: [ - { - coinDenom: 'BCNA', - coinMinimalDenom: 'ubcna', - coinDecimals: 6, - coinGeckoId: 'bitcanna', - coinImageUrl: '/tokens/blockchain/BCNA.png', - }, - ], - features: ['stargate', 'ibc-transfer', 'no-legacy-stdTx'], - explorerUrlToTx: 'https://www.mintscan.io/bitcanna/txs/{txHash}', - gasPriceStep: null, - }, - }, - { - name: 'DESMOS', - defaultDecimals: 6, - addressPatterns: ['^(desmos1)[0-9a-z]{38}$'], - feeAssets: [ - { - blockchain: 'DESMOS', - symbol: 'DSM', - address: null, - }, - ], - logo: 'https://api.rango.exchange/blockchains/desmos.svg', - displayName: 'Desmos', - shortName: 'Desmos', - sort: 37, - color: '#DF6952', - enabled: true, - type: TransactionType.COSMOS, - chainId: 'desmos-mainnet', - info: { - infoType: 'CosmosMetaInfo', - experimental: true, - rpc: 'https://rpc.mainnet.desmos.network', - rest: 'https://api.mainnet.desmos.network', - cosmostationLcdUrl: 'https://lcd-desmos.cosmostation.io', - cosmostationApiUrl: 'https://api-desmos.cosmostation.io', - cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', - mintScanName: 'desmos', - chainName: 'Desmos', - stakeCurrency: { - coinDenom: 'DSM', - coinMinimalDenom: 'udsm', - coinDecimals: 6, - coinGeckoId: 'pool:udsm', - coinImageUrl: '/tokens/blockchain/DSM.png', - }, - bip44: { - coinType: 852, - }, - bech32Config: { - bech32PrefixAccAddr: 'desmos', - bech32PrefixAccPub: 'desmospub', - bech32PrefixValAddr: 'desmosvaloper', - bech32PrefixValPub: 'desmosvaloperpub', - bech32PrefixConsAddr: 'desmosvalcons', - bech32PrefixConsPub: 'desmosvalconspub', - }, - currencies: [ - { - coinDenom: 'DSM', - coinMinimalDenom: 'udsm', - coinDecimals: 6, - coinGeckoId: 'pool:udsm', - coinImageUrl: '/tokens/blockchain/DSM.png', - }, - ], - feeCurrencies: [ - { - coinDenom: 'DSM', - coinMinimalDenom: 'udsm', - coinDecimals: 6, - coinGeckoId: 'pool:udsm', - coinImageUrl: '/tokens/blockchain/DSM.png', - }, - ], - features: ['stargate', 'ibc-transfer', 'no-legacy-stdTx', 'ibc-go'], - explorerUrlToTx: 'https://explorer.desmos.network/transactions/{txHash}', - gasPriceStep: null, - }, - }, - { - name: 'LUMNETWORK', - defaultDecimals: 6, - addressPatterns: ['^(lum1)[0-9a-z]{38}$'], - feeAssets: [ - { - blockchain: 'LUMNETWORK', - symbol: 'LUM', - address: null, - }, - ], - logo: 'https://api.rango.exchange/blockchains/lumnetwork.svg', - displayName: 'Lum Network', - shortName: 'Lum Network', - sort: 38, - color: '#1B42B4', - enabled: true, - type: TransactionType.COSMOS, - chainId: 'lum-network-1', - info: { - infoType: 'CosmosMetaInfo', - experimental: true, - rpc: 'https://node0.mainnet.lum.network/rpc', - rest: 'https://node0.mainnet.lum.network/rest', - cosmostationLcdUrl: 'https://lcd-lum.cosmostation.io', - cosmostationApiUrl: 'https://api-lum.cosmostation.io', - cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', - mintScanName: 'lum', - chainName: 'Lum Network', - stakeCurrency: { - coinDenom: 'LUM', - coinMinimalDenom: 'ulum', - coinDecimals: 6, - coinGeckoId: 'pool:ulum', - coinImageUrl: '/tokens/blockchain/LUM.png', - }, - bip44: { - coinType: 118, - }, - bech32Config: { - bech32PrefixAccAddr: 'lum', - bech32PrefixAccPub: 'lumpub', - bech32PrefixValAddr: 'lumvaloper', - bech32PrefixValPub: 'lumvaloperpub', - bech32PrefixConsAddr: 'lumvalcons', - bech32PrefixConsPub: 'lumvalconspub', - }, - currencies: [ - { - coinDenom: 'LUM', - coinMinimalDenom: 'ulum', - coinDecimals: 6, - coinGeckoId: 'pool:ulum', - coinImageUrl: '/tokens/blockchain/LUM.png', - }, - ], - feeCurrencies: [ - { - coinDenom: 'LUM', - coinMinimalDenom: 'ulum', - coinDecimals: 6, - coinGeckoId: 'pool:ulum', - coinImageUrl: '/tokens/blockchain/LUM.png', - }, - ], - features: ['stargate', 'ibc-transfer', 'no-legacy-stdTx', 'ibc-go'], - explorerUrlToTx: 'https://www.mintscan.io/lum/txs/{txHash}', - gasPriceStep: null, - }, - }, - { - name: 'BOBA', - defaultDecimals: 18, - addressPatterns: ['^(0x)[0-9A-Fa-f]{40}$'], - feeAssets: [ - { - blockchain: 'BOBA', - symbol: 'ETH', - address: null, - }, - ], - logo: 'https://api.rango.exchange/blockchains/boba.png', - displayName: 'Boba', - shortName: 'Boba', - sort: 39, - color: '#ccff00', - enabled: true, - type: TransactionType.EVM, - chainId: '0x120', - info: { - infoType: 'EvmMetaInfo', - chainName: 'Boba Network', - nativeCurrency: { - name: 'ETH', - symbol: 'ETH', - decimals: 18, - }, - rpcUrls: ['https://mainnet.boba.network'], - blockExplorerUrls: ['https://bobascan.com/'], - addressUrl: 'https://bobascan.com//address/{wallet}', - transactionUrl: 'https://bobascan.com//tx/{txHash}', - }, - }, - { - name: 'AXELAR', - defaultDecimals: 6, - addressPatterns: ['^(axelar1)[0-9a-z]{38}$'], - feeAssets: [ - { - blockchain: 'AXELAR', - symbol: 'AXL', - address: null, - }, - ], - logo: 'https://api.rango.exchange/blockchains/axelar.png', - displayName: 'Axelar', - shortName: 'Axelar', - sort: 40, - color: '#15181C', - enabled: false, - type: TransactionType.COSMOS, - chainId: 'axelar-dojo-1', - info: { - infoType: 'CosmosMetaInfo', - experimental: false, - rpc: 'https://mainnet-rpc-router.axelar-dev.workers.dev/chain/axelar', - rest: 'https://axelar-lcd.quickapi.com', - cosmostationLcdUrl: 'https://axelar-lcd.quickapi.com', - cosmostationApiUrl: - 'https://mainnet-rpc-router.axelar-dev.workers.dev/chain/axelar', - cosmostationDenomTracePath: '/ibc/apps/transfer/v1/denom_traces/', - mintScanName: 'axelar', - chainName: 'Axelar', - stakeCurrency: { - coinDenom: 'AXL', - coinMinimalDenom: 'uaxl', - coinDecimals: 6, - coinGeckoId: 'axelar', - coinImageUrl: '/tokens/blockchain/axl.png', - }, - bip44: { - coinType: 118, - }, - bech32Config: { - bech32PrefixAccAddr: 'axl', - bech32PrefixAccPub: 'axlpub', - bech32PrefixValAddr: 'axlvaloper', - bech32PrefixValPub: 'axlvaloperpub', - bech32PrefixConsAddr: 'axlvalcons', - bech32PrefixConsPub: 'axlvalconspub', - }, - currencies: [ - { - coinDenom: 'AXL', - coinMinimalDenom: 'uaxl', - coinDecimals: 6, - coinGeckoId: 'axelar', - coinImageUrl: '/tokens/blockchain/axl.png', - }, - ], - feeCurrencies: [ - { - coinDenom: 'AXL', - coinMinimalDenom: 'uaxl', - coinDecimals: 6, - coinGeckoId: 'axelar', - coinImageUrl: '/tokens/blockchain/axl.png', - }, - ], - features: ['stargate', 'ibc-transfer'], - explorerUrlToTx: 'https://www.mintscan.io/axelar/txs/{txHash}', - gasPriceStep: { - low: 0.007, - average: 0.007, - high: 0.01, - }, - }, - }, -]; diff --git a/widget/ui/src/components/BottomLogo/BottomLogo.styles.ts b/widget/ui/src/components/BottomLogo/BottomLogo.styles.ts new file mode 100644 index 0000000000..147bc3404c --- /dev/null +++ b/widget/ui/src/components/BottomLogo/BottomLogo.styles.ts @@ -0,0 +1,15 @@ +import { styled } from '../../theme.js'; + +export const Container = styled('div', { + display: 'flex', + width: '100%', + justifyContent: 'end', + alignItems: 'center', +}); + +export const StyledAnchor = styled('a', { + display: 'flex', + justifyContent: 'center', + alignItems: 'center', + textDecoration: 'none', +}); diff --git a/widget/ui/src/components/BottomLogo/BottomLogo.tsx b/widget/ui/src/components/BottomLogo/BottomLogo.tsx new file mode 100644 index 0000000000..3f463ac084 --- /dev/null +++ b/widget/ui/src/components/BottomLogo/BottomLogo.tsx @@ -0,0 +1,27 @@ +import { i18n } from '@lingui/core'; +import React from 'react'; + +import { Divider } from '../Divider/index.js'; +import { Logo } from '../Logo/index.js'; +import { Typography } from '../Typography/index.js'; + +import { Container, StyledAnchor } from './BottomLogo.styles.js'; + +export function BottomLogo() { + return ( + + + {i18n.t('Powered By')} + + + + + + + + RANGO + + + + ); +} diff --git a/widget/ui/src/components/BottomLogo/index.ts b/widget/ui/src/components/BottomLogo/index.ts new file mode 100644 index 0000000000..6df9a89e4d --- /dev/null +++ b/widget/ui/src/components/BottomLogo/index.ts @@ -0,0 +1 @@ +export { BottomLogo } from './BottomLogo.js'; diff --git a/widget/ui/src/components/Button/Button.stories.tsx b/widget/ui/src/components/Button/Button.stories.tsx deleted file mode 100644 index 740e2704a7..0000000000 --- a/widget/ui/src/components/Button/Button.stories.tsx +++ /dev/null @@ -1,59 +0,0 @@ -import React from 'react'; -import { ComponentMeta } from '@storybook/react'; - -import { Button, PropTypes } from './Button'; -import { AddWalletIcon } from '../Icon'; - -export default { - title: 'Components/Button', - component: Button, - argTypes: { - variant: { - name: 'variant', - control: { type: 'select' }, - options: ['contained', 'outlined', 'ghost'], - defaultValue: 'contained', - }, - type: { - name: 'type', - control: { type: 'select' }, - options: ['primary', 'error', 'warning', 'success'], - }, - align: { - name: 'align', - control: { type: 'select' }, - options: ['start', 'grow'], - }, - size: { - name: 'size', - control: { type: 'radio' }, - options: ['small', 'medium', 'large', 'compact'], - defaultValue: 'medium', - }, - disabled: { - name: 'disabled', - control: { type: 'boolean' }, - }, - }, -} as ComponentMeta; - -export const Main = (props: PropTypes) => ( - -); - -export const WithPrefix = (args: PropTypes) => ( - -); - -export const WithSuffix = (args: PropTypes) => ( - -); -export const IconButton = (args: PropTypes) => ( -
-
-); diff --git a/widget/ui/src/components/Button/Button.styles.tsx b/widget/ui/src/components/Button/Button.styles.tsx new file mode 100644 index 0000000000..174aefe576 --- /dev/null +++ b/widget/ui/src/components/Button/Button.styles.tsx @@ -0,0 +1,566 @@ +import { darkTheme, keyframes, styled } from '../../theme.js'; + +export const ButtonBase = styled('button', { + position: 'relative', + display: 'flex', + overflow: 'hidden', + alignItems: 'center', + justifyContent: 'center', + fontSize: '$16', + fontWeight: '$400', + border: '0', + borderRadius: '$secondary', + cursor: 'pointer', + transition: 'all 0.35s', + fontFamily: 'inherit', + variants: { + size: { + xxsmall: { + fontSize: '$10', + lineHeight: '12px', + padding: '$4', + }, + xsmall: { + fontSize: '$12', + lineHeight: '12px', + padding: '$0 $4', + }, + small: { + fontSize: '$14', + fontWeight: '$medium', + lineHeight: '20px', + padding: '$4 $4', + }, + medium: { + fontSize: '$16', + lineHeight: '24px', + fontWeight: '$medium', + padding: '$8 $8', + }, + large: { + fontSize: '$18', + lineHeight: '26px', + padding: '$12 $24', + fontWeight: '$medium', + }, + }, + variant: { + contained: { + backgroundColor: '$background', + color: '$foreground', + border: 0, + '&:hover': { + backgroundColor: '$neutral300', + }, + '&:focus-visible': { + backgroundColor: '$neutral500', + outline: 0, + }, + '&:disabled': { + backgroundColor: '$neutral600', + $$color: '$colors$background', + [`.${darkTheme} &`]: { + $$color: '$colors$foreground', + backgroundColor: '$neutral700', + }, + color: '$$color', + pointerEvents: 'none', + }, + }, + outlined: { + backgroundColor: '$background', + border: 1, + borderStyle: 'solid', + color: '$foreground', + borderColor: '$neutral200', + '&:hover': { + borderColor: '$neutral300', + }, + '&:focus-visible': { + borderColor: '$neutral500', + outline: 0, + }, + '&:disabled': { + borderColor: '$neutral600', + color: '$neutral600', + pointerEvents: 'none', + }, + }, + ghost: { + backgroundColor: 'transparent', + color: '$neutral700', + '&:disabled': { + color: '$neutral600', + pointerEvents: 'none', + }, + '&:focus-visible': { + backgroundColor: '$neutral500', + outline: 0, + }, + '&:hover': { + color: '$secondary500', + }, + }, + default: {}, + }, + fullWidth: { + true: { + width: '100%', + }, + }, + type: { + primary: {}, + error: {}, + warning: {}, + success: {}, + secondary: {}, + }, + }, + + compoundVariants: [ + { + type: 'primary', + variant: 'contained', + css: { + background: '$primary500', + $$color: '$colors$background', + [`.${darkTheme} &`]: { + $$color: '$colors$foreground', + }, + color: '$$color', + '&:hover': { + background: '$primary550', + $$color: '$colors$background', + [`.${darkTheme} &`]: { + $$color: '$colors$foreground', + }, + color: '$$color', + }, + '&:disabled': { + $$color: '$colors$background', + background: '$neutral600', + [`.${darkTheme} &`]: { + $$color: '$colors$foreground', + backgroundColor: '$neutral700', + }, + color: '$$color', + pointerEvents: 'none', + }, + '&:visited': { + background: '$primary500', + }, + '&:active': { + backgroundColor: '$primary500', + backgroundSize: '100%', + transition: 'background 0s', + }, + '&:focus-visible': { + background: '$primary550', + outline: 0, + }, + }, + }, + { + type: 'primary', + variant: 'outlined', + css: { + color: '$primary500', + borderColor: '$primary500', + '&:hover': { + color: '$primary550', + borderColor: '$primary550', + }, + '&:focus-visible': { + color: '$primary550', + borderColor: '$primary550', + outline: 0, + }, + }, + }, + { + type: 'primary', + variant: 'ghost', + css: { + color: '$primary500', + '&:hover': { + color: '$primary550', + }, + '&:focus-visible': { + color: '$primary550', + outline: 0, + }, + }, + }, + { + type: 'secondary', + variant: 'contained', + css: { + background: '$secondary500', + $$color: '$colors$background', + [`.${darkTheme} &`]: { + $$color: '$colors$foreground', + }, + color: '$$color', + '&:hover': { + background: '$secondary550', + $$color: '$colors$background', + [`.${darkTheme} &`]: { + $$color: '$colors$foreground', + }, + color: '$$color', + }, + '&:visited': { + background: '$secondary500', + }, + '&:focus': { + background: '$secondary550', + outline: 0, + }, + '&:focus-visible': { + background: '$secondary550', + outline: 0, + }, + }, + }, + { + type: 'secondary', + variant: 'outlined', + css: { + color: '$secondary500', + borderColor: '$secondary500', + '&:hover': { + color: '$secondary550', + borderColor: '$secondary550', + }, + '&:visited': { + color: '$secondary500', + borderColor: '$secondary500', + }, + '&:focus': { + color: '$secondary550', + borderColor: '$secondary500', + outline: 0, + }, + '&:focus-visible': { + color: '$secondary550', + borderColor: '$secondary500', + outline: 0, + }, + }, + }, + { + type: 'secondary', + variant: 'ghost', + css: { + color: '$secondary500', + '&:hover': { + color: '$secondary550', + }, + '&:visited': { + color: '$secondary500', + }, + '&:focus': { + color: '$secondary550', + outline: 0, + }, + '&:focus-visible': { + color: '$secondary550', + outline: 0, + }, + }, + }, + { + type: 'error', + variant: 'contained', + css: { + background: '$error500', + $$color: '$colors$background', + [`.${darkTheme} &`]: { + $$color: '$colors$foreground', + }, + color: '$$color', + '&:hover': { + background: '$error500', + }, + '&:visited': { + background: '$error500', + }, + '&:focus': { + background: '$error500', + }, + '&:focus-visible': { + $$outline: '$colors$error600', + [`.${darkTheme} &`]: { + $$outline: '$colors$error300', + }, + outlineColor: '$$outline', + }, + }, + }, + { + type: 'error', + variant: 'outlined', + css: { + color: '$error500', + borderColor: '$error500', + '&:hover': { + color: '$error500', + borderColor: '$error500', + }, + '&:visited': { + color: '$error500', + borderColor: '$error500', + }, + '&:focus': { + color: '$error500', + borderColor: '$error500', + }, + '&:focus-visible': { + $$outline: '$colors$error600', + [`.${darkTheme} &`]: { + $$outline: '$colors$error300', + }, + color: '$$outline', + outlineColor: '$$outline', + }, + }, + }, + { + type: 'error', + variant: 'ghost', + css: { + color: '$error500', + '&:hover': { + color: '$error500', + }, + '&:visited': { + color: '$error500', + }, + '&:focus': { + color: '$error500', + }, + '&:focus-visible': { + $$outline: '$colors$error600', + [`.${darkTheme} &`]: { + $$outline: '$colors$error300', + }, + color: '$$outline', + outline: 0, + }, + }, + }, + { + type: 'warning', + variant: 'contained', + css: { + background: '$warning500', + $$color: '$colors$background', + [`.${darkTheme} &`]: { + $$color: '$colors$foreground', + }, + color: '$$color', + '&:hover': { + background: '$warning500', + $$color: '$colors$background', + [`.${darkTheme} &`]: { + $$color: '$colors$foreground', + }, + color: '$$color', + }, + '&:visited': { + background: '$warning500', + }, + '&:focus': { + background: '$warning500', + }, + '&:focus-visible': { + $$outline: '$colors$warning600', + [`.${darkTheme} &`]: { + $$outline: '$colors$warning300', + }, + outlineColor: '$$outline', + }, + }, + }, + { + type: 'warning', + variant: 'outlined', + css: { + color: '$warning500', + borderColor: '$warning500', + '&:hover': { + color: '$warning500', + borderColor: '$warning500', + }, + '&:visited': { + color: '$warning500', + borderColor: '$warning500', + }, + '&:focus': { + color: '$warning500', + borderColor: '$warning500', + }, + '&:focus-visible': { + $$outline: '$colors$warning600', + [`.${darkTheme} &`]: { + $$outline: '$colors$warning300', + }, + outlineColor: '$$outline', + color: '$$outline', + }, + }, + }, + { + type: 'warning', + variant: 'ghost', + css: { + color: '$warning500', + '&:hover': { + color: '$warning500', + }, + '&:visited': { + color: '$warning500', + }, + '&:focus': { + color: '$warning500', + }, + '&:focus-visible': { + $$outline: '$colors$warning600', + [`.${darkTheme} &`]: { + $$outline: '$colors$warning300', + }, + color: '$$outline', + }, + }, + }, + { + type: 'success', + variant: 'contained', + css: { + background: '$success500', + $$color: '$colors$background', + [`.${darkTheme} &`]: { + $$color: '$colors$foreground', + }, + color: '$$color', + '&:hover': { + background: '$success500', + $$color: '$colors$background', + [`.${darkTheme} &`]: { + $$color: '$colors$foreground', + }, + color: '$$color', + }, + '&:visited': { + background: '$success500', + }, + '&:focus': { + background: '$success500', + }, + '&:focus-visible': { + $$outline: '$colors$success600', + [`.${darkTheme} &`]: { + $$outline: '$colors$success300', + }, + outlineColor: '$$outline', + }, + }, + }, + { + type: 'success', + variant: 'outlined', + css: { + color: '$success500', + borderColor: '$success500', + '&:hover': { + color: '$success500', + borderColor: '$success500', + }, + '&:visited': { + color: '$success500', + borderColor: '$success500', + }, + '&:focus': { + color: '$success500', + borderColor: '$success500', + }, + '&:focus-visible': { + $$outline: '$colors$success600', + [`.${darkTheme} &`]: { + $$outline: '$colors$success300', + }, + outlineColor: '$$outline', + color: '$$outline', + }, + }, + }, + { + type: 'success', + variant: 'ghost', + css: { + color: '$success500', + '&:hover': { + color: '$success500', + }, + '&:visited': { + color: '$success500', + }, + '&:focus': { + color: '$success500', + }, + '&:focus-visible': { + $$outline: '$colors$success600', + [`.${darkTheme} &`]: { + $$outline: '$colors$success300', + }, + outline: 0, + color: '$$outline', + }, + }, + }, + ], + defaultVariants: { + size: 'medium', + variant: 'contained', + }, +}); + +export const Content = styled('span', { + flexGrow: 1, + display: 'inline-block', + variants: { + pl: { + true: { + paddingLeft: '$8', + }, + }, + pr: { + true: { + paddingRight: '$8', + }, + }, + }, +}); + +const ripple = keyframes({ + to: { + transform: 'scale(2)', + opacity: 0.1, + }, +}); + +export const RippleContainer = styled('div', { + position: 'absolute', + inset: '0', + overflow: 'hidden', + borderRadius: '$sm', + + '& span': { + transform: 'scale(0)', + borderRadius: '100%', + position: 'absolute', + opacity: '0.75', + backgroundColor: '$neutral500', + animation: `${ripple} 0.8s linear`, + }, +}); diff --git a/widget/ui/src/components/Button/Button.tsx b/widget/ui/src/components/Button/Button.tsx index ab36b9bf64..b0ceae5b53 100644 --- a/widget/ui/src/components/Button/Button.tsx +++ b/widget/ui/src/components/Button/Button.tsx @@ -1,421 +1,52 @@ -import { CSSProperties } from '@stitches/react'; -import React, { PropsWithChildren, HTMLAttributes } from 'react'; -import { darkTheme, styled } from '../../theme'; -import { Spinner } from '../Spinner'; -import { Typography } from '../Typography'; +import type { ButtonPropTypes, Ref } from './Button.types.js'; +import type { PropsWithChildren } from 'react'; -const ButtonContainer = styled('button', { - borderRadius: '$5', - fontSize: '$16', - fontWeight: '$400', - cursor: 'pointer', - padding: '0 $12', - display: 'flex', - alignItems: 'center', - justifyContent: 'center', - transition: 'all 0.35s', - border: '0', +import React from 'react'; - '&:active': { - transform: 'scale(0.95)', - }, +import { Spinner } from '../Spinner/Spinner.js'; - variants: { - align: { - start: { - display: 'flex', - width: '100%', - }, - grow: { - display: 'flex', - width: '100%', - }, - }, - size: { - compact: {}, - free: {}, - small: { - height: '$32', - }, - medium: { - height: '$40', - }, - large: { - height: '$48', - }, - }, - variant: { - contained: { - backgroundColor: '$neutrals300', - color: '$foreground', - border: 0, - '&:hover': { - backgroundColor: '$neutrals200', - }, - '&:disabled': { - background: '$neutrals400', - }, - '&:disabled:hover': { - background: '$neutrals400', - transform: 'unset', - }, - }, - outlined: { - backgroundColor: '$background', - border: 1, - borderStyle: 'solid', - borderColor: '$neutrals400', - color: '$foreground', - '&:hover': { - borderColor: '$neutrals600', - }, - '&:disabled': { - borderColor: '$neutrals300', - color: '$neutrals400', - }, - }, - ghost: { - color: '$foreground', - '&:hover': { - backgroundColor: '$neutrals200', - }, - '&:disabled': { - color: '$neutrals400 !important', - }, - background: 'transparent', - border: 0, +import { ButtonBase, Content } from './Button.styles.js'; +import Ripple from './Ripple.js'; - [`& ${Typography}`]: { - color: 'inherit', - }, - }, - }, - fullWidth: { - true: { - width: '100%', - }, - }, - loading: { - true: {}, - }, - type: { - primary: {}, - error: {}, - warning: {}, - success: {}, - }, - }, +function ButtonComponent(props: PropsWithChildren, ref?: Ref) { + const { + children, + loading, + disabled, + prefix, + suffix, + onClick, + disableRipple, + ...otherProps + } = props; - compoundVariants: [ - { - type: 'primary', - variant: 'contained', - css: { - background: '$primary', - color: '$white', - '&:hover': { - background: '$primary700', - }, - '&:visited': { - background: '$primary900', - }, - '&:focus': { - background: '$primary600', - }, - }, - }, - { - type: 'primary', - variant: 'outlined', - css: { - color: '$primary !important', - borderColor: '$primary', - '&:hover': { - color: '$primary700 !important', - borderColor: '$primary700 !important', - }, - '&:visited': { - color: '$primary900 !important', - borderColor: '$primary900 !important', - }, - '&:focus': { - color: '$primary600 !important', - borderColor: '$primary600 !important', - }, - }, - }, - { - type: 'primary', - variant: 'ghost', - css: { - color: '$primary', - '&:hover': { - color: '$primary700', - }, - '&:visited': { color: '$primary900' }, - '&:focus': { - color: '$primary600', - }, - }, - }, - { - type: 'error', - variant: 'contained', - css: { - background: '$error', - $$color: '$colors$background', - [`.${darkTheme} &`]: { - $$color: '$colors$foreground', - }, - color: '$$color !important', - '&:hover': { - background: '$error300', - }, - '&:visited': { - background: '$error700', - }, - '&:focus': { - background: '$error700', - }, - }, - }, - { - type: 'error', - variant: 'outlined', - css: { - color: '$error !important', - borderColor: '$error', - '&:hover': { - color: '$error300 !important', - borderColor: '$error300 !important', - }, - '&:visited': { - color: '$error700 !important', - borderColor: '$error700 !important', - }, - '&:focus': { - color: '$error700 !important', - borderColor: '$error700 !important', - }, - }, - }, - { - type: 'error', - variant: 'ghost', - css: { - color: '$error', - '&:hover': { - color: '$error300', - }, - '&:visited': { - color: '$error700', - }, - '&:focus': { - color: '$error700', - }, - }, - }, - { - type: 'warning', - variant: 'contained', - css: { - background: '$warning', - $$color: '$colors$background', - [`.${darkTheme} &`]: { - $$color: '$colors$foreground', - }, - color: '$$color !important', - '&:hover': { - background: '$warning300', - }, - '&:visited': { - background: '$warning700', - }, - '&:focus': { - background: '$warning700', - }, - }, - }, - { - type: 'warning', - variant: 'outlined', - css: { - color: '$warning !important', - borderColor: '$warning', - '&:hover': { - color: '$warning300 !important', - borderColor: '$warning300 !important', - }, - '&:visited': { - color: '$warning700 !important', - borderColor: '$warning700 !important', - }, - '&:focus': { - color: '$warning700 !important', - borderColor: '$warning700 !important', - }, - }, - }, - { - type: 'warning', - variant: 'ghost', - css: { - color: '$warning', - '&:hover': { - color: '$warning300', - }, - '&:visited': { - color: '$warning700', - }, - '&:focus': { - color: '$warning700', - }, - }, - }, - { - type: 'success', - variant: 'contained', - css: { - background: '$success', - $$color: '$colors$background', - [`.${darkTheme} &`]: { - $$color: '$colors$foreground', - }, - color: '$$color !important', - '&:hover': { - background: '$success300', - }, - '&:visited': { - background: '$success700', - }, - '&:focus': { - background: '$success700', - }, - }, - }, - { - type: 'success', - variant: 'outlined', - css: { - color: '$success !important', - borderColor: '$success', - '&:hover': { - color: '$success300 !important', - borderColor: '$success300 !important', - }, - '&:visited': { - color: '$success700 !important', - borderColor: '$success700 !important', - }, - '&:focus': { - color: '$success700 !important', - borderColor: '$success700 !important', - }, - }, - }, - { - type: 'success', - variant: 'ghost', - css: { - color: '$success', - '&:hover': { - color: '$success300', - }, - '&:visited': { - color: '$success700', - }, - '&:focus': { - color: '$success700', - }, - }, - }, - { - size: 'compact', - css: { - padding: '$2 $4', - fontSize: '$12', - }, - }, - ], - defaultVariants: { - size: 'medium', - variant: 'contained', - }, -}); + const shouldShowRipple = !disabled && !loading && !disableRipple; -const Content = styled('div', { - flex: 1, - variants: { - align: { - start: { - textAlign: 'left', - }, - grow: { - textAlign: 'center', - }, - }, - ml: { - true: { - marginLeft: '$8', - }, - }, - mr: { - true: { - marginRight: '$8', - }, - }, - flexContent: { - true: { - display: 'flex', - alignItems: 'center', - }, - }, - }, -}); - -export interface PropTypes - extends Omit, 'prefix'> { - onClick?: (event: React.MouseEvent) => void; - size?: 'small' | 'medium' | 'large' | 'compact' | 'free'; - variant?: 'contained' | 'outlined' | 'ghost'; - type?: 'primary' | 'error' | 'warning' | 'success'; - prefix?: React.ReactNode; - suffix?: React.ReactNode; - align?: 'start' | 'grow'; - loading?: boolean; - fullWidth?: boolean; - disabled?: boolean; - style?: CSSProperties; - flexContent?: boolean; -} - -export function Button({ - children, - loading, - disabled, - prefix, - suffix, - align, - flexContent, - ...props -}: PropsWithChildren) { - const isDisabled = loading || disabled; return ( - - {prefix} - {children && ( - - {children} - + + {loading ? ( + + ) : ( + <> + {prefix} + {children && ( + + {children} + + )} + {suffix} + )} - {loading && } - {suffix} - + {shouldShowRipple && } + ); } + +const Button = React.forwardRef(ButtonComponent); +Button.displayName = 'Button'; + +export { Button }; diff --git a/widget/ui/src/components/Button/Button.types.tsx b/widget/ui/src/components/Button/Button.types.tsx new file mode 100644 index 0000000000..c7084136ee --- /dev/null +++ b/widget/ui/src/components/Button/Button.types.tsx @@ -0,0 +1,28 @@ +import type { ButtonBase } from './Button.styles.js'; +import type * as Stitches from '@stitches/react'; +import type { HTMLAttributes } from 'react'; + +type BaseProps = Stitches.VariantProps; +type BaseSizes = Exclude; +type BaseVariants = Exclude; +type BaseTypes = Exclude; + +export type Ref = + | ((instance: HTMLButtonElement | null) => void) + | React.RefObject + | null + | undefined; + +type ButtonElement = Omit, 'prefix'>; + +export type ButtonPropTypes = ButtonElement & { + size?: BaseSizes; + variant?: BaseVariants; + type?: BaseTypes; + loading?: boolean; + disabled?: boolean; + prefix?: React.ReactNode; + suffix?: React.ReactNode; + fullWidth?: boolean; + disableRipple?: boolean; +}; diff --git a/widget/ui/src/components/Button/Ripple.tsx b/widget/ui/src/components/Button/Ripple.tsx new file mode 100644 index 0000000000..573ba794d3 --- /dev/null +++ b/widget/ui/src/components/Button/Ripple.tsx @@ -0,0 +1,82 @@ +import React, { useEffect, useState } from 'react'; + +import { RippleContainer } from './Button.styles.js'; + +const DURATION = 850; + +const useDebouncedRippleCleanUp = ( + rippleCount: number, + duration: number, + cleanUpFunction: () => void +) => { + useEffect(() => { + let bounce: ReturnType | null = null; + if (rippleCount > 0) { + if (bounce) { + clearTimeout(bounce); + } + + bounce = setTimeout(() => { + cleanUpFunction(); + if (bounce) { + clearTimeout(bounce); + } + }, duration); + } + + return () => { + if (bounce) { + clearTimeout(bounce); + } + }; + }, [rippleCount, duration, cleanUpFunction]); +}; + +const Ripple = ({ duration = DURATION }: { duration?: number }) => { + const [rippleArray, setRippleArray] = useState< + { x: number; y: number; size: number }[] + >([]); + + useDebouncedRippleCleanUp(rippleArray.length, duration, () => { + setRippleArray([]); + }); + + const addRipple = (event: React.MouseEvent) => { + const rippleContainer = event.currentTarget.getBoundingClientRect(); + const size = + rippleContainer.width > rippleContainer.height + ? rippleContainer.width + : rippleContainer.height; + const x = event.pageX - rippleContainer.x - size / 2; + const y = event.pageY - rippleContainer.y - size / 2; + const newRipple = { + x, + y, + size, + }; + + setRippleArray([...rippleArray, newRipple]); + }; + + return ( + + {rippleArray.length > 0 && + rippleArray.map((ripple, index) => { + const key = 'span' + index; + return ( + + ); + })} + + ); +}; + +export default Ripple; diff --git a/widget/ui/src/components/Button/index.ts b/widget/ui/src/components/Button/index.ts index fe9c53c511..3eece262b9 100644 --- a/widget/ui/src/components/Button/index.ts +++ b/widget/ui/src/components/Button/index.ts @@ -1 +1,2 @@ -export { Button } from './Button'; +export { Button } from './Button.js'; +export type { ButtonPropTypes } from './Button.types.js'; diff --git a/widget/ui/src/components/ChainToken/ChainToken.constants.ts b/widget/ui/src/components/ChainToken/ChainToken.constants.ts new file mode 100644 index 0000000000..e0ad6ec9d5 --- /dev/null +++ b/widget/ui/src/components/ChainToken/ChainToken.constants.ts @@ -0,0 +1,10 @@ +import type { ChainTokenPropTypes } from './ChainToken.types.js'; + +export const tokenChainSizeMap: { + [key in ChainTokenPropTypes['size']]: { token: number; chain: number }; +} = { + small: { token: 17, chain: 10 }, + xmedium: { token: 22, chain: 10 }, + medium: { token: 27, chain: 10 }, + large: { token: 30, chain: 15 }, +}; diff --git a/widget/ui/src/components/ChainToken/ChainToken.styles.ts b/widget/ui/src/components/ChainToken/ChainToken.styles.ts new file mode 100644 index 0000000000..fc790439e8 --- /dev/null +++ b/widget/ui/src/components/ChainToken/ChainToken.styles.ts @@ -0,0 +1,68 @@ +import { darkTheme, styled } from '../../theme.js'; +import { Image } from '../common/index.js'; + +export const Container = styled('div', { + position: 'relative', + display: 'flex', + [`& ${Image}`]: { borderRadius: '100%' }, +}); + +export const ChainImageContainer = styled('div', { + position: 'absolute', + borderRadius: '100%', + $$color: '$colors$neutral100', + [`.${darkTheme} &`]: { + $$color: '$colors$neutral300', + }, + backgroundColor: '$$color', + variants: { + size: { + small: { + right: '-3px', + bottom: '-3px', + }, + xmedium: { + right: '-3px', + bottom: '-3px', + }, + medium: { + right: '0', + bottom: '0', + }, + large: { + right: '-5px', + bottom: '-5px', + }, + }, + hasBorder: { + true: { + $$borderColor: '$colors$secondary250', + [`.${darkTheme} &`]: { + $$borderColor: '$colors$secondary550', + }, + border: '1px solid $$borderColor', + }, + false: {}, + }, + }, +}); +export const TokenImageContainer = styled('div', { + borderRadius: '100%', + width: '$30', + display: 'flex', + justifyContent: 'center', + alignItems: 'center', + + variants: { + hasBorder: { + true: { + $$borderColor: '$colors$secondary550', + [`.${darkTheme} &`]: { + $$borderColor: '$colors$secondary500', + }, + border: '1px solid $$borderColor', + }, + false: {}, + }, + }, +}); diff --git a/widget/ui/src/components/ChainToken/ChainToken.tsx b/widget/ui/src/components/ChainToken/ChainToken.tsx new file mode 100644 index 0000000000..ee99fad787 --- /dev/null +++ b/widget/ui/src/components/ChainToken/ChainToken.tsx @@ -0,0 +1,76 @@ +import type { ChainTokenPropTypes } from './ChainToken.types.js'; + +import React from 'react'; + +import { Image } from '../common/index.js'; +import { Skeleton } from '../Skeleton/index.js'; + +import { tokenChainSizeMap } from './ChainToken.constants.js'; +import { + ChainImageContainer, + Container, + TokenImageContainer, +} from './ChainToken.styles.js'; + +export const ChainToken: React.FC = (props) => { + const { + tokenImage, + chainImage, + chianImageId, + size, + useAsPlaceholder, + loading, + } = props; + + return ( + + {loading ? ( + + ) : ( + + + + )} + + {loading ? ( + + ) : ( + + )} + + + ); +}; diff --git a/widget/ui/src/components/ChainToken/ChainToken.types.ts b/widget/ui/src/components/ChainToken/ChainToken.types.ts new file mode 100644 index 0000000000..383d0a8e90 --- /dev/null +++ b/widget/ui/src/components/ChainToken/ChainToken.types.ts @@ -0,0 +1,14 @@ +import type { ChainImageContainer } from './ChainToken.styles.js'; +import type * as Stitches from '@stitches/react'; + +type BaseProps = Stitches.VariantProps; +type BaseSizes = Exclude; + +export type ChainTokenPropTypes = { + tokenImage: string; + chainImage: string; + chianImageId?: string; + size: NonNullable; + useAsPlaceholder?: boolean; + loading?: boolean; +}; diff --git a/widget/ui/src/components/ChainToken/index.ts b/widget/ui/src/components/ChainToken/index.ts new file mode 100644 index 0000000000..87a7fd3e9e --- /dev/null +++ b/widget/ui/src/components/ChainToken/index.ts @@ -0,0 +1,2 @@ +export { ChainToken } from './ChainToken.js'; +export type { ChainTokenPropTypes } from './ChainToken.types.js'; diff --git a/widget/ui/src/components/Checkbox/Checkbox.stories.tsx b/widget/ui/src/components/Checkbox/Checkbox.stories.tsx deleted file mode 100644 index ff1ac71824..0000000000 --- a/widget/ui/src/components/Checkbox/Checkbox.stories.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import React from 'react'; -import { ComponentMeta } from '@storybook/react'; -import { Checkbox, PropTypes } from './Checkbox'; - -export default { - title: 'Components/Checkbox', - component: Checkbox, - argTypes: { - label: { - name: 'label', - control: { type: 'text' }, - defaultValue: 'I am a checkbox', - }, - defaultChecked: { - name: 'defaultChecked', - control: { type: 'boolean' }, - defaultValue: true, - }, - }, -} as ComponentMeta; - -export const Main = (props: PropTypes) => ; diff --git a/widget/ui/src/components/Checkbox/Checkbox.styles.ts b/widget/ui/src/components/Checkbox/Checkbox.styles.ts new file mode 100644 index 0000000000..b66210e9be --- /dev/null +++ b/widget/ui/src/components/Checkbox/Checkbox.styles.ts @@ -0,0 +1,47 @@ +import * as RadixCheckbox from '@radix-ui/react-checkbox'; + +import { darkTheme, styled } from '../../theme.js'; + +export const CheckboxContainer = styled('div', { + display: 'flex', + alignItems: 'center', +}); + +export const CheckboxRoot = styled(RadixCheckbox.Root, { + borderRadius: '$xs', + position: 'relative', + width: '1rem', + height: '1rem', + padding: 0, + $$borderColor: '$colors$neutral600', + [`.${darkTheme} &`]: { + $$borderColor: '$colors$neutral700', + }, + border: '1px solid $$borderColor', + backgroundColor: 'transparent', + cursor: 'pointer', + '&[data-state="checked"]': { + $$color: '$colors$secondary500', + [`.${darkTheme} &`]: { + $$color: '$colors$secondary250', + }, + backgroundColor: '$$color', + borderColor: '$$color', + }, + '&[data-disabled]': { + backgroundColor: '$neutral600', + borderColor: '$neutral700', + }, +}); + +export const CheckboxIndicator = styled(RadixCheckbox.CheckboxIndicator, { + display: 'flex', + justifyContent: 'center', + alignItems: 'center', +}); + +export const Label = styled('label', { + color: '$foreground', + fontSize: '$m', + cursor: 'pointer', +}); diff --git a/widget/ui/src/components/Checkbox/Checkbox.tsx b/widget/ui/src/components/Checkbox/Checkbox.tsx index b2dc9bcc07..cf19d6631d 100644 --- a/widget/ui/src/components/Checkbox/Checkbox.tsx +++ b/widget/ui/src/components/Checkbox/Checkbox.tsx @@ -1,56 +1,36 @@ -import React, { PropsWithChildren } from 'react'; -import { styled } from '../../theme'; -import * as RadixCheckbox from '@radix-ui/react-checkbox'; -import { CheckIcon } from '../Icon'; +import type { CheckboxPropTypes } from './Checkbox.types.js'; +import type { PropsWithChildren } from 'react'; -const CheckboxContainer = styled('div', { - display: 'flex', - alignItems: 'center', -}); +import React from 'react'; -const CheckboxRoot = styled(RadixCheckbox.Root, { - borderRadius: '5px', - width: 20, - padding: 0, - height: 20, - border: '1px solid $foreground', - display: 'flex', - alignItems: 'center', - justifyContent: 'center', - marginRight: '$2', - backgroundColor: '$neutral-100', -}); -const Label = styled('label', { - color: '$foreground', - fontSize: '$m', - marginLeft: '$8', -}); +import { DoneIcon } from '../../icons/index.js'; +import { Divider } from '../Divider/index.js'; -export interface PropTypes { - id: string; - defaultChecked?: boolean; - label: string; - checked?: boolean; - onCheckedChange?: (checked: boolean) => void; - disabled?: boolean; - name?: string; -} +import { + CheckboxContainer, + CheckboxIndicator, + CheckboxRoot, + Label, +} from './Checkbox.styles.js'; -export function Checkbox({ - label, - id, - ...props -}: PropsWithChildren) { +export function Checkbox(props: PropsWithChildren) { + const { id, label, ...otherProps } = props; + const hasLabel = id && label; return ( - - - - + + + + - + {hasLabel ? ( + <> + + + + ) : null} ); } diff --git a/widget/ui/src/components/Checkbox/Checkbox.types.ts b/widget/ui/src/components/Checkbox/Checkbox.types.ts new file mode 100644 index 0000000000..468dde40df --- /dev/null +++ b/widget/ui/src/components/Checkbox/Checkbox.types.ts @@ -0,0 +1,18 @@ +import type { CheckboxProps } from '@radix-ui/react-checkbox'; + +type RadixCheckboxProps = Pick< + CheckboxProps, + 'defaultChecked' | 'checked' | 'disabled' | 'name' | 'onCheckedChange' +>; + +interface WithLabelProps { + id: string; + label: React.ReactNode; +} +interface ComponentProps { + id?: never; + label?: never; +} + +export type CheckboxPropTypes = RadixCheckboxProps & + (ComponentProps | WithLabelProps); diff --git a/widget/ui/src/components/Checkbox/index.ts b/widget/ui/src/components/Checkbox/index.ts index 8f59e4fbb5..9aa2cb73e1 100644 --- a/widget/ui/src/components/Checkbox/index.ts +++ b/widget/ui/src/components/Checkbox/index.ts @@ -1 +1,2 @@ -export { Checkbox } from './Checkbox'; +export { Checkbox } from './Checkbox.js'; +export type { CheckboxPropTypes } from './Checkbox.types.js'; diff --git a/widget/ui/src/components/Chip/Chip.stories.tsx b/widget/ui/src/components/Chip/Chip.stories.tsx deleted file mode 100644 index a2cc25efea..0000000000 --- a/widget/ui/src/components/Chip/Chip.stories.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import React from 'react'; -import { ComponentMeta } from '@storybook/react'; - -import { Chip, PropTypes } from './Chip'; - -export default { - title: 'Chip', - component: Chip, -} as ComponentMeta; - -export const Main = (args: PropTypes) => ; - -export const ChipWithPrefix = (args: PropTypes) => ( - - } - /> -); - -export const ChipWithSuffix = (args: PropTypes) => ( - - } - /> -); diff --git a/widget/ui/src/components/Chip/Chip.styles.ts b/widget/ui/src/components/Chip/Chip.styles.ts new file mode 100644 index 0000000000..ec3cb627b3 --- /dev/null +++ b/widget/ui/src/components/Chip/Chip.styles.ts @@ -0,0 +1,41 @@ +import { darkTheme, styled } from '../../theme.js'; + +export const ChipContainer = styled('button', { + display: 'inline-flex', + justifyContent: 'center', + alignItems: 'center', + borderRadius: '$xs', + padding: '$5 $15', + cursor: 'pointer', + transition: 'all 0.35s', + border: '1px solid transparent', + fontFamily: 'inherit', + $$color: '$colors$neutral100', + [`.${darkTheme} &`]: { + $$color: '$colors$neutral300', + }, + backgroundColor: '$$color', + + '&:hover': { + $$color: '$colors$secondary100', + [`.${darkTheme} &`]: { + $$color: '$colors$neutral100', + }, + backgroundColor: '$$color', + }, + + '&:focus-visible': { + $$color: '$colors$secondary100', + [`.${darkTheme} &`]: { + $$color: '$colors$info700', + }, + backgroundColor: '$$color', + outline: 0, + }, + + variants: { + selected: { + true: { border: '1px solid $secondary500' }, + }, + }, +}); diff --git a/widget/ui/src/components/Chip/Chip.tsx b/widget/ui/src/components/Chip/Chip.tsx index c080d109e9..1391ca6b19 100644 --- a/widget/ui/src/components/Chip/Chip.tsx +++ b/widget/ui/src/components/Chip/Chip.tsx @@ -1,48 +1,23 @@ -import { CSSProperties } from '@stitches/react'; -import React from 'react'; -import { styled } from '../../theme'; +import type { ChipPropTypes } from './Chip.types.js'; -const ChipCointainer = styled('div', { - display: 'inline-flex', - justifyContent: 'center', - alignItems: 'center', - borderRadius: '$5', - padding: '$4 $8', - height: '32', - fontSize: '$14', - cursor: 'pointer', - transition: 'all 0.35s', - color: '$foreground', +import React from 'react'; - '&:hover': { - backgroundColor: '$success700', - color: '$background', - }, - variants: { - selected: { - true: { backgroundColor: '$success', color: '$background' }, - false: { backgroundColor: '$background' }, - }, - }, -}); +import { Typography } from '../Typography/index.js'; -export interface PropTypes { - label: string; - selected?: boolean; - onClick?: React.MouseEventHandler; - className?: string; - style?: CSSProperties; - prefix?: React.ReactNode; - suffix?: React.ReactNode; -} +import { ChipContainer } from './Chip.styles.js'; -export function Chip(props: PropTypes) { - const { label, selected, prefix, suffix, onClick, style } = props; +export function Chip(props: ChipPropTypes) { + const { label, selected, prefix, suffix, ...otherProps } = props; return ( - + {prefix || null} - {label} + + {label} + {suffix || null} - + ); } diff --git a/widget/ui/src/components/Chip/Chip.types.ts b/widget/ui/src/components/Chip/Chip.types.ts new file mode 100644 index 0000000000..4ef730bcc1 --- /dev/null +++ b/widget/ui/src/components/Chip/Chip.types.ts @@ -0,0 +1,15 @@ +import type { CSSProperties } from '@stitches/react'; +import type { HTMLAttributes, ReactNode } from 'react'; + +type ButtonElement = Omit, 'prefix'>; + +interface ChipProps { + label: string; + selected?: boolean; + className?: string; + style?: CSSProperties; + prefix?: ReactNode; + suffix?: ReactNode; +} + +export type ChipPropTypes = ButtonElement & ChipProps; diff --git a/widget/ui/src/components/Chip/index.ts b/widget/ui/src/components/Chip/index.ts index 63314f5e37..e5df4b9cbd 100644 --- a/widget/ui/src/components/Chip/index.ts +++ b/widget/ui/src/components/Chip/index.ts @@ -1 +1,2 @@ -export { Chip } from './Chip'; +export { Chip } from './Chip.js'; +export type { ChipPropTypes } from './Chip.types.js'; diff --git a/widget/ui/src/components/Collapsible/Collapsible.styles.ts b/widget/ui/src/components/Collapsible/Collapsible.styles.ts new file mode 100644 index 0000000000..6aa11abab7 --- /dev/null +++ b/widget/ui/src/components/Collapsible/Collapsible.styles.ts @@ -0,0 +1,9 @@ +import * as Collapsible from '@radix-ui/react-collapsible'; + +import { styled } from '../../theme.js'; + +export const Trigger = styled(Collapsible.Trigger, { + border: 'none', + background: 'transparent', + width: '100%', +}); diff --git a/widget/ui/src/components/Collapsible/Collapsible.tsx b/widget/ui/src/components/Collapsible/Collapsible.tsx new file mode 100644 index 0000000000..08dc95ce87 --- /dev/null +++ b/widget/ui/src/components/Collapsible/Collapsible.tsx @@ -0,0 +1,21 @@ +import type { CollapsiblePropTypes } from './Collapsible.types.js'; +import type { PropsWithChildren } from 'react'; + +import * as Collapsible from '@radix-ui/react-collapsible'; +import React from 'react'; + +import { CollapsibleContent } from '../common/styles.js'; + +import { Trigger } from './Collapsible.styles.js'; + +export function CollapsibleComponent( + props: PropsWithChildren +) { + const { open, onOpenChange, trigger, children, ...otherProps } = props; + return ( + + {trigger} + {children} + + ); +} diff --git a/widget/ui/src/components/Collapsible/Collapsible.types.ts b/widget/ui/src/components/Collapsible/Collapsible.types.ts new file mode 100644 index 0000000000..1cebd9d501 --- /dev/null +++ b/widget/ui/src/components/Collapsible/Collapsible.types.ts @@ -0,0 +1,7 @@ +import type React from 'react'; + +export interface CollapsiblePropTypes { + trigger: React.ReactNode; + open: boolean; + onOpenChange: (open: boolean) => void; +} diff --git a/widget/ui/src/components/Collapsible/index.ts b/widget/ui/src/components/Collapsible/index.ts new file mode 100644 index 0000000000..296275e9f6 --- /dev/null +++ b/widget/ui/src/components/Collapsible/index.ts @@ -0,0 +1,2 @@ +export { CollapsibleComponent as Collapsible } from './Collapsible.js'; +export type { CollapsiblePropTypes } from './Collapsible.types.js'; diff --git a/widget/ui/src/components/ColorPicker/ColorPicker.stories.tsx b/widget/ui/src/components/ColorPicker/ColorPicker.stories.tsx deleted file mode 100644 index 067fab6a1b..0000000000 --- a/widget/ui/src/components/ColorPicker/ColorPicker.stories.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import React, { useState } from 'react'; -import { ComponentMeta } from '@storybook/react'; -import { ColorPicker, PropTypes } from './ColorPicker'; - -export default { - title: 'Components/ColorPicker', - component: ColorPicker, - argTypes: { - place: { - name: 'place', - control: { type: 'select' }, - options: ['top', 'bottom', 'left', 'right'], - defaultValue: 'top', - }, - }, -} as ComponentMeta; - -export const Main = (args: PropTypes) => { - const [color, setColor] = useState('#5FA425'); - return ( -
- setColor(color.hex)} - /> -
- ); -}; diff --git a/widget/ui/src/components/ColorPicker/ColorPicker.tsx b/widget/ui/src/components/ColorPicker/ColorPicker.tsx deleted file mode 100644 index 31f4037f42..0000000000 --- a/widget/ui/src/components/ColorPicker/ColorPicker.tsx +++ /dev/null @@ -1,85 +0,0 @@ -import React, { useState } from 'react'; -import { ChromePicker, ColorResult } from 'react-color'; -import { styled } from '../../theme'; -import { Button } from '../Button'; - -const Container = styled('div', { - position: 'relative', -}); - -const Color = styled('div', { - border: '1px solid $neutrals300', - borderRadius: '$5', - width: '$32', - height: '$32', -}); -const Cover = styled('div', { - position: 'fixed', - top: '0px', - right: '0px', - bottom: '0px', - left: '0px', -}); -const Popover = styled('div', { - position: 'absolute', - zIndex: '2', - variants: { - place: { - top: { - top: '-241px', - }, - bottom: {}, - left: { - top: '-50%', - left: '-225px', - }, - right: { - top: '-50%', - right: '-225px', - }, - }, - }, -}); -export interface PropTypes { - color: string; - place: 'top' | 'bottom' | 'left' | 'right'; - onChangeColor: ( - color: ColorResult, - event: React.ChangeEvent - ) => void; - label?: string; -} - -const Label = styled('label', { - display: 'inline-block', - fontSize: '$14', - marginBottom: '$4', - color: '$foreground', -}); - -export function ColorPicker({ color, onChangeColor, label, place }: PropTypes) { - const [displayColorPicker, setDisplayColorPicker] = useState(false); - - return ( - - - - - {displayColorPicker && ( - - setDisplayColorPicker(false)} /> - - - )} - - ); -} diff --git a/widget/ui/src/components/ColorPicker/index.ts b/widget/ui/src/components/ColorPicker/index.ts deleted file mode 100644 index 9fad6294d9..0000000000 --- a/widget/ui/src/components/ColorPicker/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { ColorPicker } from './ColorPicker'; diff --git a/widget/ui/src/components/ConnectWalletsModal/ConnectWallets.stories.tsx b/widget/ui/src/components/ConnectWalletsModal/ConnectWallets.stories.tsx deleted file mode 100644 index a768621da9..0000000000 --- a/widget/ui/src/components/ConnectWalletsModal/ConnectWallets.stories.tsx +++ /dev/null @@ -1,13 +0,0 @@ -import React from 'react'; -import { ComponentMeta } from '@storybook/react'; -import { ConnectWalletsModal, PropTypes } from './ConnectWalletsModal'; -import { walletsInfo } from './mockData'; - -export default { - title: 'Connect Wallets Modal', - component: ConnectWalletsModal, -} as ComponentMeta; - -export const Main = (args: PropTypes) => ( - -); diff --git a/widget/ui/src/components/ConnectWalletsModal/ConnectWalletsModal.tsx b/widget/ui/src/components/ConnectWalletsModal/ConnectWalletsModal.tsx deleted file mode 100644 index 5093ed260f..0000000000 --- a/widget/ui/src/components/ConnectWalletsModal/ConnectWalletsModal.tsx +++ /dev/null @@ -1,42 +0,0 @@ -import React from 'react'; -import { styled } from '../../theme'; -import { WalletInfo } from '../../types/wallet'; -import { Modal } from '../Modal'; -import { WalletType } from '@rango-dev/wallets-shared'; -import { Wallet } from '../Wallet'; - -export interface PropTypes { - open: boolean; - list: WalletInfo[]; - onSelect: (walletType: WalletType) => void; - onClose: () => void; - error?: string; -} - -const ModalContent = styled('div', { - display: 'grid', - gap: '$8', - gridTemplateColumns: 'repeat(2, minmax(0, 1fr))', -}); - -export function ConnectWalletsModal(props: PropTypes) { - const { open, list, onSelect, onClose } = props; - - const Content = ( - - {list.map((info, index) => ( - - ))} - - ); - - return ( - - ); -} diff --git a/widget/ui/src/components/ConnectWalletsModal/index.ts b/widget/ui/src/components/ConnectWalletsModal/index.ts deleted file mode 100644 index 27dbc59767..0000000000 --- a/widget/ui/src/components/ConnectWalletsModal/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { ConnectWalletsModal } from './ConnectWalletsModal'; diff --git a/widget/ui/src/components/ConnectWalletsModal/mockData.ts b/widget/ui/src/components/ConnectWalletsModal/mockData.ts deleted file mode 100644 index 3ea2e1b8f2..0000000000 --- a/widget/ui/src/components/ConnectWalletsModal/mockData.ts +++ /dev/null @@ -1,134 +0,0 @@ -import { WalletInfo, WalletState } from '../../types/wallet'; -import { WalletType } from '@rango-dev/wallets-shared'; - -export const walletsInfo: WalletInfo[] = [ - { - image: 'https://app.rango.exchange/wallets/coinbase.svg', - name: 'Coinbase', - state: WalletState.DISCONNECTED, - installLink: '', - type: WalletType.COINBASE, - showOnMobile: true, - }, - { - image: 'https://app.rango.exchange/wallets/coinbase.svg', - name: 'Coinbase', - state: WalletState.CONNECTED, - installLink: '', - type: WalletType.COINBASE, - showOnMobile: true, - }, - { - image: 'https://app.rango.exchange/wallets/coinbase.svg', - name: 'Coinbase', - state: WalletState.CONNECTING, - installLink: '', - type: WalletType.COINBASE, - showOnMobile: true, - }, - { - image: 'https://app.rango.exchange/wallets/coinbase.svg', - name: 'Coinbase', - state: WalletState.NOT_INSTALLED, - type: WalletType.COINBASE, - showOnMobile: true, - installLink: - 'https://chrome.google.com/webstore/detail/coinbase-wallet-extension/hnfanknocfeofbddgcijnmhnfnkdnaad?hl=en', - }, - { - image: 'https://app.rango.exchange/wallets/coinbase.svg', - name: 'Coinbase', - state: WalletState.DISCONNECTED, - installLink: '', - type: WalletType.COINBASE, - showOnMobile: true, - }, - { - image: 'https://app.rango.exchange/wallets/coinbase.svg', - name: 'Coinbase', - state: WalletState.CONNECTED, - installLink: '', - type: WalletType.COINBASE, - showOnMobile: true, - }, - { - image: 'https://app.rango.exchange/wallets/coinbase.svg', - name: 'Coinbase', - state: WalletState.DISCONNECTED, - installLink: '', - type: WalletType.COINBASE, - showOnMobile: true, - }, - { - image: 'https://app.rango.exchange/wallets/coinbase.svg', - name: 'Coinbase', - state: WalletState.DISCONNECTED, - installLink: '', - type: WalletType.COINBASE, - showOnMobile: true, - }, - { - image: 'https://app.rango.exchange/wallets/coinbase.svg', - name: 'Coinbase', - state: WalletState.DISCONNECTED, - installLink: '', - type: WalletType.COINBASE, - showOnMobile: true, - }, - { - image: 'https://app.rango.exchange/wallets/coinbase.svg', - name: 'Coinbase', - state: WalletState.DISCONNECTED, - installLink: '', - type: WalletType.COINBASE, - showOnMobile: true, - }, - { - image: 'https://app.rango.exchange/wallets/coinbase.svg', - name: 'Coinbase', - state: WalletState.DISCONNECTED, - installLink: '', - type: WalletType.COINBASE, - showOnMobile: true, - }, - { - image: 'https://app.rango.exchange/wallets/coinbase.svg', - name: 'Coinbase', - state: WalletState.DISCONNECTED, - installLink: '', - type: WalletType.COINBASE, - showOnMobile: true, - }, - { - image: 'https://app.rango.exchange/wallets/coinbase.svg', - name: 'Coinbase', - state: WalletState.DISCONNECTED, - installLink: '', - type: WalletType.COINBASE, - showOnMobile: true, - }, - { - image: 'https://app.rango.exchange/wallets/coinbase.svg', - name: 'Coinbase', - state: WalletState.DISCONNECTED, - installLink: '', - type: WalletType.COINBASE, - showOnMobile: true, - }, - { - image: 'https://app.rango.exchange/wallets/coinbase.svg', - name: 'Coinbase', - state: WalletState.DISCONNECTED, - installLink: '', - type: WalletType.COINBASE, - showOnMobile: true, - }, - { - image: 'https://app.rango.exchange/wallets/coinbase.svg', - name: 'Coinbase', - state: WalletState.DISCONNECTED, - installLink: '', - type: WalletType.COINBASE, - showOnMobile: true, - }, -]; diff --git a/widget/ui/src/components/Divider/Divider.styles.ts b/widget/ui/src/components/Divider/Divider.styles.ts new file mode 100644 index 0000000000..57b2dc2fad --- /dev/null +++ b/widget/ui/src/components/Divider/Divider.styles.ts @@ -0,0 +1,203 @@ +import { styled } from '../../theme.js'; + +export const DividerContainer = styled('div', { + flexShrink: 0, + variants: { + size: { + 2: {}, + 4: {}, + 8: {}, + 10: {}, + 12: {}, + 16: {}, + 18: {}, + 20: {}, + 24: {}, + 30: {}, + 32: {}, + 36: {}, + 40: {}, + }, + direction: { + vertical: {}, + horizontal: {}, + }, + }, + compoundVariants: [ + { + size: 2, + direction: 'horizontal', + css: { + width: 2, + }, + }, + { + size: 2, + direction: 'vertical', + css: { + height: 2, + }, + }, + { + size: 4, + direction: 'horizontal', + css: { + width: '$4', + }, + }, + { + size: 4, + direction: 'vertical', + css: { + height: '$4', + }, + }, + { + size: 8, + direction: 'horizontal', + css: { + width: '$8', + }, + }, + { + size: 8, + direction: 'vertical', + css: { + height: '$8', + }, + }, + { + size: 10, + direction: 'horizontal', + css: { + width: '$10', + }, + }, + { + size: 10, + direction: 'vertical', + css: { + height: '$10', + }, + }, + { + size: 12, + direction: 'horizontal', + css: { + width: '$12', + }, + }, + { + size: 12, + direction: 'vertical', + css: { + height: '$12', + }, + }, + { + size: 16, + direction: 'horizontal', + css: { + width: '$16', + }, + }, + { + size: 16, + direction: 'vertical', + css: { + height: '$16', + }, + }, + { + size: 18, + direction: 'horizontal', + css: { + width: '$18', + }, + }, + { + size: 18, + direction: 'vertical', + css: { + height: '$18', + }, + }, + { + size: 20, + direction: 'horizontal', + css: { + width: '$20', + }, + }, + { + size: 20, + direction: 'vertical', + css: { + height: '$20', + }, + }, + { + size: 24, + direction: 'horizontal', + css: { + width: '$24', + }, + }, + { + size: 24, + direction: 'vertical', + css: { + height: '$24', + }, + }, + { + size: 30, + direction: 'horizontal', + css: { + width: '$30', + }, + }, + { + size: 30, + direction: 'vertical', + css: { + height: '$30', + }, + }, + { + size: 32, + direction: 'horizontal', + css: { + width: '$32', + }, + }, + { + size: 36, + direction: 'vertical', + css: { + height: '$36', + }, + }, + { + size: 36, + direction: 'horizontal', + css: { + width: '$36', + }, + }, + { + size: 32, + direction: 'vertical', + css: { + height: '$32', + }, + }, + { + size: 40, + direction: 'vertical', + css: { + height: '$40', + }, + }, + ], +}); diff --git a/widget/ui/src/components/Divider/Divider.tsx b/widget/ui/src/components/Divider/Divider.tsx index 707b150333..69c76b8d46 100644 --- a/widget/ui/src/components/Divider/Divider.tsx +++ b/widget/ui/src/components/Divider/Divider.tsx @@ -1,41 +1,15 @@ +import type { PropTypes } from './Divider.types.js'; + import React from 'react'; -import { styled } from '../../theme'; -const DividerContainer = styled('div', { - variants: { - size: { - 4: { - height: '$4', - }, - 8: { - height: '$8', - }, - 12: { - height: '$12', - }, - 16: { - height: '$16', - }, - 18: { - height: '$18', - }, - 20: { - height: '$20', - }, - 24: { - height: '$24', - }, - 32: { - height: '$32', - }, - }, - }, -}); -export interface PropTypes { - size?: 4 | 8 | 12 | 16 | 18 | 20 | 24 | 32; - direction?: 'vertical' | 'horizontal'; -} +import { DividerContainer } from './Divider.styles.js'; + +const DEFAULT_SIZE = 12; -export function Divider({ size = 12 }: PropTypes) { - return ; +export function Divider({ + size = DEFAULT_SIZE, + direction = 'vertical', + ...props +}: PropTypes) { + return ; } diff --git a/widget/ui/src/components/Divider/Divider.types.ts b/widget/ui/src/components/Divider/Divider.types.ts new file mode 100644 index 0000000000..db7b9d2a61 --- /dev/null +++ b/widget/ui/src/components/Divider/Divider.types.ts @@ -0,0 +1,10 @@ +import type { DividerContainer } from './Divider.styles.js'; +import type * as Stitches from '@stitches/react'; + +type BaseProps = Stitches.VariantProps; +type BaseSizes = Exclude; + +export interface PropTypes { + size?: BaseSizes; + direction?: 'vertical' | 'horizontal'; +} diff --git a/widget/ui/src/components/Divider/index.ts b/widget/ui/src/components/Divider/index.ts index 8ba836ab71..4db3967ec2 100644 --- a/widget/ui/src/components/Divider/index.ts +++ b/widget/ui/src/components/Divider/index.ts @@ -1 +1 @@ -export { Divider } from './Divider'; +export { Divider } from './Divider.js'; diff --git a/widget/ui/src/components/Drawer/Drawer.stories.tsx b/widget/ui/src/components/Drawer/Drawer.stories.tsx deleted file mode 100644 index f0bee4d376..0000000000 --- a/widget/ui/src/components/Drawer/Drawer.stories.tsx +++ /dev/null @@ -1,86 +0,0 @@ -import React, { useState } from 'react'; -import { ComponentMeta } from '@storybook/react'; -import { Drawer, PropTypes } from './Drawer'; - -export default { - name: 'Components/Drawer', - component: Drawer, - argTypes: { - anchor: { - name: 'anchor', - control: { type: 'select' }, - options: ['bottom', 'left', 'right', 'top'], - defaultValue: 'bottom', - }, - }, -} as ComponentMeta; - -export const Main = (args: PropTypes) => { - const [open, setOpen] = useState(false); - return ( -
- - setOpen(false)} - /> -
- ); -}; - -export const EmptyContent = (args: PropTypes) => { - const [open, setOpen] = useState(false); - return ( -
- - setOpen(false)} /> -
- ); -}; -export const BottomAnchor = (args: PropTypes) => { - const [open, setOpen] = useState(false); - return ( -
- - setOpen(false)} - anchor="bottom" - content={ -
- {Array.from({ length: 50 }, (_, index) => ( -
Test {index}
- ))} -
- } - /> -
- ); -}; - -export const LeftAnchor = (args: PropTypes) => { - const [open, setOpen] = useState(false); - return ( -
- - setOpen(false)} - anchor="left" - content={ -
- {Array.from({ length: 50 }, (_, index) => ( - Test {index} - ))} -
- } - /> -
- ); -}; diff --git a/widget/ui/src/components/Drawer/Drawer.tsx b/widget/ui/src/components/Drawer/Drawer.tsx deleted file mode 100644 index d014eb7ee6..0000000000 --- a/widget/ui/src/components/Drawer/Drawer.tsx +++ /dev/null @@ -1,124 +0,0 @@ -import React from 'react'; -import { styled } from '../../theme'; -import { CloseIcon } from '../Icon'; -import { Typography } from '../Typography'; -import { createPortal } from 'react-dom'; - -export interface PropTypes { - title?: string; - open: boolean; - onClose: () => void; - content: React.ReactNode; - containerStyle?: React.CSSProperties; - anchor?: 'bottom' | 'left' | 'right' | 'top'; - showClose?: boolean; - footer?: React.ReactNode; - container: Element | null; -} - -const BackDrop = styled('div', { - position: 'absolute', - top: '0', - left: '0', - width: '100%', - height: '100%', - zIndex: 9999999, - backgroundColor: 'rgba(0,0,0,.1)', - borderRadius: '$10', -}); - -const DrawerContainer = styled('div', { - position: 'absolute', - boxShadow: '$s', - background: '$background', - padding: '$20', - display: 'flex', - flexDirection: 'column', - justifyContent: 'space-between', - zIndex: 9999999, - borderRadius: '$10', - - variants: { - anchor: { - left: { - top: 0, - left: 0, - height: '100%', - minWidth: '300px', - maxWidth: '90%', - }, - right: { - top: 0, - right: 0, - height: '100%', - minWidth: '300px', - maxWidth: '90%', - }, - bottom: { - bottom: 0, - width: '100%', - maxHeight: '90%', - }, - top: { - top: 0, - width: '100%', - maxHeight: '90%', - }, - }, - }, -}); - -const DrawerHeader = styled('div', { - display: 'flex', - justifyContent: 'space-between', - alignItems: 'center', - position: 'relative', - marginBottom: '$16', -}); - -const Body = styled('div', { - overflowY: 'auto', - height: '100%', -}); -const Footer = styled('footer', { - width: '100%', - marginTop: '$28', -}); - -export function Drawer(props: PropTypes) { - const { - title, - content, - open, - onClose, - containerStyle, - anchor = 'bottom', - showClose = false, - footer, - container, - } = props; - - const handleBackDropClick = (event: React.MouseEvent) => { - if (event.target === event.currentTarget) onClose(); - }; - - return ( - <> - {open && - container && - createPortal( - - - - {title} - {showClose && } - - {content} -
{footer}
-
-
, - container - )} - - ); -} diff --git a/widget/ui/src/components/Drawer/index.ts b/widget/ui/src/components/Drawer/index.ts deleted file mode 100644 index 777c3778c2..0000000000 --- a/widget/ui/src/components/Drawer/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { Drawer } from './Drawer'; diff --git a/widget/ui/src/components/Flags/Bengali.tsx b/widget/ui/src/components/Flags/Bengali.tsx new file mode 100644 index 0000000000..6695e0c2c4 --- /dev/null +++ b/widget/ui/src/components/Flags/Bengali.tsx @@ -0,0 +1,25 @@ +import type { FlagPropTypes } from './Flags.types.js'; + +import React from 'react'; + +import { DEFAULT_SIZE } from './Flags.constants.js'; + +export default function Bengali(props: FlagPropTypes) { + const { size = DEFAULT_SIZE } = props; + + return ( + + + + + + + + + + ); +} diff --git a/widget/ui/src/components/Flags/Catalonia.tsx b/widget/ui/src/components/Flags/Catalonia.tsx new file mode 100644 index 0000000000..78e63ce519 --- /dev/null +++ b/widget/ui/src/components/Flags/Catalonia.tsx @@ -0,0 +1,31 @@ +import type { FlagPropTypes } from './Flags.types.js'; + +import React from 'react'; + +import { DEFAULT_SIZE } from './Flags.constants.js'; + +export default function Catalonia(props: FlagPropTypes) { + const { size = DEFAULT_SIZE } = props; + + return ( + + + + + + + + + + ); +} diff --git a/widget/ui/src/components/Flags/Chinese.tsx b/widget/ui/src/components/Flags/Chinese.tsx new file mode 100644 index 0000000000..0f40625363 --- /dev/null +++ b/widget/ui/src/components/Flags/Chinese.tsx @@ -0,0 +1,28 @@ +import type { FlagPropTypes } from './Flags.types.js'; + +import React from 'react'; + +import { DEFAULT_SIZE } from './Flags.constants.js'; + +export default function Chinese(props: FlagPropTypes) { + const { size = DEFAULT_SIZE } = props; + + return ( + + + + + + + + + + ); +} diff --git a/widget/ui/src/components/Flags/Cyprus.tsx b/widget/ui/src/components/Flags/Cyprus.tsx new file mode 100644 index 0000000000..bf04e51922 --- /dev/null +++ b/widget/ui/src/components/Flags/Cyprus.tsx @@ -0,0 +1,32 @@ +import type { FlagPropTypes } from './Flags.types.js'; + +import React from 'react'; + +import { DEFAULT_SIZE } from './Flags.constants.js'; + +export default function Cyprus(props: FlagPropTypes) { + const { size = DEFAULT_SIZE } = props; + + return ( + + + + + + + + + + + ); +} diff --git a/widget/ui/src/components/Flags/Denmark.tsx b/widget/ui/src/components/Flags/Denmark.tsx new file mode 100644 index 0000000000..32412d6827 --- /dev/null +++ b/widget/ui/src/components/Flags/Denmark.tsx @@ -0,0 +1,31 @@ +import type { FlagPropTypes } from './Flags.types.js'; + +import React from 'react'; + +import { DEFAULT_SIZE } from './Flags.constants.js'; + +export default function Denmark(props: FlagPropTypes) { + const { size = DEFAULT_SIZE } = props; + + return ( + + + + + + + + + + ); +} diff --git a/widget/ui/src/components/Flags/English.tsx b/widget/ui/src/components/Flags/English.tsx new file mode 100644 index 0000000000..5ec65e0b84 --- /dev/null +++ b/widget/ui/src/components/Flags/English.tsx @@ -0,0 +1,35 @@ +import type { FlagPropTypes } from './Flags.types.js'; + +import React from 'react'; + +import { DEFAULT_SIZE } from './Flags.constants.js'; + +export default function English(props: FlagPropTypes) { + const { size = DEFAULT_SIZE } = props; + + return ( + + + + + + + + + + + ); +} diff --git a/widget/ui/src/components/Flags/Finland.tsx b/widget/ui/src/components/Flags/Finland.tsx new file mode 100644 index 0000000000..91c686ea23 --- /dev/null +++ b/widget/ui/src/components/Flags/Finland.tsx @@ -0,0 +1,31 @@ +import type { FlagPropTypes } from './Flags.types.js'; + +import React from 'react'; + +import { DEFAULT_SIZE } from './Flags.constants.js'; + +export default function Finland(props: FlagPropTypes) { + const { size = DEFAULT_SIZE } = props; + + return ( + + + + + + + + + + ); +} diff --git a/widget/ui/src/components/Flags/Flags.constants.ts b/widget/ui/src/components/Flags/Flags.constants.ts new file mode 100644 index 0000000000..eb52995038 --- /dev/null +++ b/widget/ui/src/components/Flags/Flags.constants.ts @@ -0,0 +1 @@ +export const DEFAULT_SIZE = '1em'; diff --git a/widget/ui/src/components/Flags/Flags.types.ts b/widget/ui/src/components/Flags/Flags.types.ts new file mode 100644 index 0000000000..538f5e4926 --- /dev/null +++ b/widget/ui/src/components/Flags/Flags.types.ts @@ -0,0 +1,3 @@ +export type FlagPropTypes = { + size?: number; +}; diff --git a/widget/ui/src/components/Flags/French.tsx b/widget/ui/src/components/Flags/French.tsx new file mode 100644 index 0000000000..525445e143 --- /dev/null +++ b/widget/ui/src/components/Flags/French.tsx @@ -0,0 +1,26 @@ +import type { FlagPropTypes } from './Flags.types.js'; + +import React from 'react'; + +import { DEFAULT_SIZE } from './Flags.constants.js'; + +export default function French(props: FlagPropTypes) { + const { size = DEFAULT_SIZE } = props; + + return ( + + + + + + + + + + + ); +} diff --git a/widget/ui/src/components/Flags/German.tsx b/widget/ui/src/components/Flags/German.tsx new file mode 100644 index 0000000000..7ce7078425 --- /dev/null +++ b/widget/ui/src/components/Flags/German.tsx @@ -0,0 +1,26 @@ +import type { FlagPropTypes } from './Flags.types.js'; + +import React from 'react'; + +import { DEFAULT_SIZE } from './Flags.constants.js'; + +export default function German(props: FlagPropTypes) { + const { size = DEFAULT_SIZE } = props; + + return ( + + + + + + + + + + + ); +} diff --git a/widget/ui/src/components/Flags/Greece.tsx b/widget/ui/src/components/Flags/Greece.tsx new file mode 100644 index 0000000000..9b493d3247 --- /dev/null +++ b/widget/ui/src/components/Flags/Greece.tsx @@ -0,0 +1,31 @@ +import type { FlagPropTypes } from './Flags.types.js'; + +import React from 'react'; + +import { DEFAULT_SIZE } from './Flags.constants.js'; + +export default function Greece(props: FlagPropTypes) { + const { size = DEFAULT_SIZE } = props; + + return ( + + + + + + + + + + ); +} diff --git a/widget/ui/src/components/Flags/Hindi.tsx b/widget/ui/src/components/Flags/Hindi.tsx new file mode 100644 index 0000000000..711a04de05 --- /dev/null +++ b/widget/ui/src/components/Flags/Hindi.tsx @@ -0,0 +1,29 @@ +import type { FlagPropTypes } from './Flags.types.js'; + +import React from 'react'; + +import { DEFAULT_SIZE } from './Flags.constants.js'; + +export default function Hindi(props: FlagPropTypes) { + const { size = DEFAULT_SIZE } = props; + + return ( + + + + + + + + + + + + + + ); +} diff --git a/widget/ui/src/components/Flags/Hungary.tsx b/widget/ui/src/components/Flags/Hungary.tsx new file mode 100644 index 0000000000..1a7eb127b0 --- /dev/null +++ b/widget/ui/src/components/Flags/Hungary.tsx @@ -0,0 +1,29 @@ +import type { FlagPropTypes } from './Flags.types.js'; + +import React from 'react'; + +import { DEFAULT_SIZE } from './Flags.constants.js'; + +export default function Hungary(props: FlagPropTypes) { + const { size = DEFAULT_SIZE } = props; + + return ( + + + + + + + + + + + ); +} diff --git a/widget/ui/src/components/Flags/India.tsx b/widget/ui/src/components/Flags/India.tsx new file mode 100644 index 0000000000..db5db5d9d9 --- /dev/null +++ b/widget/ui/src/components/Flags/India.tsx @@ -0,0 +1,29 @@ +import type { FlagPropTypes } from './Flags.types.js'; + +import React from 'react'; + +import { DEFAULT_SIZE } from './Flags.constants.js'; + +export default function India(props: FlagPropTypes) { + const { size = DEFAULT_SIZE } = props; + + return ( + + + + + + + + + + + + + + ); +} diff --git a/widget/ui/src/components/Flags/Indonesian.tsx b/widget/ui/src/components/Flags/Indonesian.tsx new file mode 100644 index 0000000000..13d6fafc33 --- /dev/null +++ b/widget/ui/src/components/Flags/Indonesian.tsx @@ -0,0 +1,25 @@ +import type { FlagPropTypes } from './Flags.types.js'; + +import React from 'react'; + +import { DEFAULT_SIZE } from './Flags.constants.js'; + +export default function Indonesian(props: FlagPropTypes) { + const { size = DEFAULT_SIZE } = props; + + return ( + + + + + + + + + + ); +} diff --git a/widget/ui/src/components/Flags/Italian.tsx b/widget/ui/src/components/Flags/Italian.tsx new file mode 100644 index 0000000000..d07910eeb6 --- /dev/null +++ b/widget/ui/src/components/Flags/Italian.tsx @@ -0,0 +1,26 @@ +import type { FlagPropTypes } from './Flags.types.js'; + +import React from 'react'; + +import { DEFAULT_SIZE } from './Flags.constants.js'; + +export default function Italian(props: FlagPropTypes) { + const { size = DEFAULT_SIZE } = props; + + return ( + + + + + + + + + + + ); +} diff --git a/widget/ui/src/components/Flags/Japanese.tsx b/widget/ui/src/components/Flags/Japanese.tsx new file mode 100644 index 0000000000..bfe48aa49f --- /dev/null +++ b/widget/ui/src/components/Flags/Japanese.tsx @@ -0,0 +1,25 @@ +import type { FlagPropTypes } from './Flags.types.js'; + +import React from 'react'; + +import { DEFAULT_SIZE } from './Flags.constants.js'; + +export default function Japanese(props: FlagPropTypes) { + const { size = DEFAULT_SIZE } = props; + + return ( + + + + + + + + + + ); +} diff --git a/widget/ui/src/components/Flags/Korea.tsx b/widget/ui/src/components/Flags/Korea.tsx new file mode 100644 index 0000000000..ca18c88f81 --- /dev/null +++ b/widget/ui/src/components/Flags/Korea.tsx @@ -0,0 +1,32 @@ +import type { FlagPropTypes } from './Flags.types.js'; + +import React from 'react'; + +import { DEFAULT_SIZE } from './Flags.constants.js'; + +export default function Korea(props: FlagPropTypes) { + const { size = DEFAULT_SIZE } = props; + + return ( + + + + + + + + + + + + + + ); +} diff --git a/widget/ui/src/components/Flags/Lithuania.tsx b/widget/ui/src/components/Flags/Lithuania.tsx new file mode 100644 index 0000000000..612fd11767 --- /dev/null +++ b/widget/ui/src/components/Flags/Lithuania.tsx @@ -0,0 +1,29 @@ +import type { FlagPropTypes } from './Flags.types.js'; + +import React from 'react'; + +import { DEFAULT_SIZE } from './Flags.constants.js'; + +export default function Lithuania(props: FlagPropTypes) { + const { size = DEFAULT_SIZE } = props; + + return ( + + + + + + + + + + + ); +} diff --git a/widget/ui/src/components/Flags/Malay.tsx b/widget/ui/src/components/Flags/Malay.tsx new file mode 100644 index 0000000000..68353f042a --- /dev/null +++ b/widget/ui/src/components/Flags/Malay.tsx @@ -0,0 +1,29 @@ +import type { FlagPropTypes } from './Flags.types.js'; + +import React from 'react'; + +import { DEFAULT_SIZE } from './Flags.constants.js'; + +export default function Malay(props: FlagPropTypes) { + const { size = DEFAULT_SIZE } = props; + + return ( + + + + + + + + + + + ); +} diff --git a/widget/ui/src/components/Flags/Netherlands.tsx b/widget/ui/src/components/Flags/Netherlands.tsx new file mode 100644 index 0000000000..2d9a36760e --- /dev/null +++ b/widget/ui/src/components/Flags/Netherlands.tsx @@ -0,0 +1,29 @@ +import type { FlagPropTypes } from './Flags.types.js'; + +import React from 'react'; + +import { DEFAULT_SIZE } from './Flags.constants.js'; + +export default function Netherlands(props: FlagPropTypes) { + const { size = DEFAULT_SIZE } = props; + + return ( + + + + + + + + + + + ); +} diff --git a/widget/ui/src/components/Flags/Pakistan.tsx b/widget/ui/src/components/Flags/Pakistan.tsx new file mode 100644 index 0000000000..60f39cb2d1 --- /dev/null +++ b/widget/ui/src/components/Flags/Pakistan.tsx @@ -0,0 +1,29 @@ +import type { FlagPropTypes } from './Flags.types.js'; + +import React from 'react'; + +import { DEFAULT_SIZE } from './Flags.constants.js'; + +export default function Pakistan(props: FlagPropTypes) { + const { size = DEFAULT_SIZE } = props; + + return ( + + + + + + + + + + + ); +} diff --git a/widget/ui/src/components/Flags/Philippines.tsx b/widget/ui/src/components/Flags/Philippines.tsx new file mode 100644 index 0000000000..1b4927eb65 --- /dev/null +++ b/widget/ui/src/components/Flags/Philippines.tsx @@ -0,0 +1,30 @@ +import type { FlagPropTypes } from './Flags.types.js'; + +import React from 'react'; + +import { DEFAULT_SIZE } from './Flags.constants.js'; + +export default function Philippines(props: FlagPropTypes) { + const { size = DEFAULT_SIZE } = props; + + return ( + + + + + + + + + + + + ); +} diff --git a/widget/ui/src/components/Flags/Poland.tsx b/widget/ui/src/components/Flags/Poland.tsx new file mode 100644 index 0000000000..f8b24f0e40 --- /dev/null +++ b/widget/ui/src/components/Flags/Poland.tsx @@ -0,0 +1,25 @@ +import type { FlagPropTypes } from './Flags.types.js'; + +import React from 'react'; + +import { DEFAULT_SIZE } from './Flags.constants.js'; + +export default function Poland(props: FlagPropTypes) { + const { size = DEFAULT_SIZE } = props; + + return ( + + + + + + + + + + ); +} diff --git a/widget/ui/src/components/Flags/Portuguese.tsx b/widget/ui/src/components/Flags/Portuguese.tsx new file mode 100644 index 0000000000..92386e2098 --- /dev/null +++ b/widget/ui/src/components/Flags/Portuguese.tsx @@ -0,0 +1,34 @@ +import type { FlagPropTypes } from './Flags.types.js'; + +import React from 'react'; + +import { DEFAULT_SIZE } from './Flags.constants.js'; + +export default function Portuguese(props: FlagPropTypes) { + const { size = DEFAULT_SIZE } = props; + + return ( + + + + + + + + + + + + + ); +} diff --git a/widget/ui/src/components/Flags/Russian.tsx b/widget/ui/src/components/Flags/Russian.tsx new file mode 100644 index 0000000000..e6b3de4bbe --- /dev/null +++ b/widget/ui/src/components/Flags/Russian.tsx @@ -0,0 +1,26 @@ +import type { FlagPropTypes } from './Flags.types.js'; + +import React from 'react'; + +import { DEFAULT_SIZE } from './Flags.constants.js'; + +export default function Russian(props: FlagPropTypes) { + const { size = DEFAULT_SIZE } = props; + + return ( + + + + + + + + + + + ); +} diff --git a/widget/ui/src/components/Flags/SaudiArabia.tsx b/widget/ui/src/components/Flags/SaudiArabia.tsx new file mode 100644 index 0000000000..2f728ca17c --- /dev/null +++ b/widget/ui/src/components/Flags/SaudiArabia.tsx @@ -0,0 +1,29 @@ +import type { FlagPropTypes } from './Flags.types.js'; + +import React from 'react'; + +import { DEFAULT_SIZE } from './Flags.constants.js'; + +export default function SaudiArabia(props: FlagPropTypes) { + const { size = DEFAULT_SIZE } = props; + + return ( + + + + + + + + + + + + + + ); +} diff --git a/widget/ui/src/components/Flags/Serbia.tsx b/widget/ui/src/components/Flags/Serbia.tsx new file mode 100644 index 0000000000..3e9bc68f60 --- /dev/null +++ b/widget/ui/src/components/Flags/Serbia.tsx @@ -0,0 +1,41 @@ +import type { FlagPropTypes } from './Flags.types.js'; + +import React from 'react'; + +import { DEFAULT_SIZE } from './Flags.constants.js'; + +export default function Serbia(props: FlagPropTypes) { + const { size = DEFAULT_SIZE } = props; + + return ( + + + + + + + + + + + + + + ); +} diff --git a/widget/ui/src/components/Flags/Slovakia.tsx b/widget/ui/src/components/Flags/Slovakia.tsx new file mode 100644 index 0000000000..a8048596a6 --- /dev/null +++ b/widget/ui/src/components/Flags/Slovakia.tsx @@ -0,0 +1,42 @@ +import type { FlagPropTypes } from './Flags.types.js'; + +import React from 'react'; + +import { DEFAULT_SIZE } from './Flags.constants.js'; + +export default function Slovakia(props: FlagPropTypes) { + const { size = DEFAULT_SIZE } = props; + + return ( + + + + + + + + + + + + + + + ); +} diff --git a/widget/ui/src/components/Flags/SouthAfrica.tsx b/widget/ui/src/components/Flags/SouthAfrica.tsx new file mode 100644 index 0000000000..ac52bc283b --- /dev/null +++ b/widget/ui/src/components/Flags/SouthAfrica.tsx @@ -0,0 +1,35 @@ +import type { FlagPropTypes } from './Flags.types.js'; + +import React from 'react'; + +import { DEFAULT_SIZE } from './Flags.constants.js'; + +export default function SouthAfrica(props: FlagPropTypes) { + const { size = DEFAULT_SIZE } = props; + + return ( + + + + + + + + + + + + + + ); +} diff --git a/widget/ui/src/components/Flags/Spanish.tsx b/widget/ui/src/components/Flags/Spanish.tsx new file mode 100644 index 0000000000..944cac306e --- /dev/null +++ b/widget/ui/src/components/Flags/Spanish.tsx @@ -0,0 +1,85 @@ +import type { FlagPropTypes } from './Flags.types.js'; + +import React from 'react'; + +import { DEFAULT_SIZE } from './Flags.constants.js'; + +export default function Spanish(props: FlagPropTypes) { + const { size = DEFAULT_SIZE } = props; + + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); +} diff --git a/widget/ui/src/components/Flags/Swahili.tsx b/widget/ui/src/components/Flags/Swahili.tsx new file mode 100644 index 0000000000..4fafcc52c9 --- /dev/null +++ b/widget/ui/src/components/Flags/Swahili.tsx @@ -0,0 +1,46 @@ +import type { FlagPropTypes } from './Flags.types.js'; + +import React from 'react'; + +import { DEFAULT_SIZE } from './Flags.constants.js'; + +export default function Swahili(props: FlagPropTypes) { + const { size = DEFAULT_SIZE } = props; + + return ( + + + + + + + + + + + + + + + + ); +} diff --git a/widget/ui/src/components/Flags/Swedish.tsx b/widget/ui/src/components/Flags/Swedish.tsx new file mode 100644 index 0000000000..234df23693 --- /dev/null +++ b/widget/ui/src/components/Flags/Swedish.tsx @@ -0,0 +1,31 @@ +import type { FlagPropTypes } from './Flags.types.js'; + +import React from 'react'; + +import { DEFAULT_SIZE } from './Flags.constants.js'; + +export default function Swedish(props: FlagPropTypes) { + const { size = DEFAULT_SIZE } = props; + + return ( + + + + + + + + + + ); +} diff --git a/widget/ui/src/components/Flags/Thai.tsx b/widget/ui/src/components/Flags/Thai.tsx new file mode 100644 index 0000000000..1a6979f582 --- /dev/null +++ b/widget/ui/src/components/Flags/Thai.tsx @@ -0,0 +1,32 @@ +import type { FlagPropTypes } from './Flags.types.js'; + +import React from 'react'; + +import { DEFAULT_SIZE } from './Flags.constants.js'; + +export default function Thai(props: FlagPropTypes) { + const { size = DEFAULT_SIZE } = props; + + return ( + + + + + + + + + + + ); +} diff --git a/widget/ui/src/components/Flags/Turkish.tsx b/widget/ui/src/components/Flags/Turkish.tsx new file mode 100644 index 0000000000..3ce0c8779f --- /dev/null +++ b/widget/ui/src/components/Flags/Turkish.tsx @@ -0,0 +1,28 @@ +import type { FlagPropTypes } from './Flags.types.js'; + +import React from 'react'; + +import { DEFAULT_SIZE } from './Flags.constants.js'; + +export default function Turkish(props: FlagPropTypes) { + const { size = DEFAULT_SIZE } = props; + + return ( + + + + + + + + + + + + + ); +} diff --git a/widget/ui/src/components/Flags/Ukrainian.tsx b/widget/ui/src/components/Flags/Ukrainian.tsx new file mode 100644 index 0000000000..f4a1a25bd0 --- /dev/null +++ b/widget/ui/src/components/Flags/Ukrainian.tsx @@ -0,0 +1,25 @@ +import type { FlagPropTypes } from './Flags.types.js'; + +import React from 'react'; + +import { DEFAULT_SIZE } from './Flags.constants.js'; + +export default function Ukrainian(props: FlagPropTypes) { + const { size = DEFAULT_SIZE } = props; + + return ( + + + + + + + + + + ); +} diff --git a/widget/ui/src/components/Flags/Vietnamese.tsx b/widget/ui/src/components/Flags/Vietnamese.tsx new file mode 100644 index 0000000000..53b41b0654 --- /dev/null +++ b/widget/ui/src/components/Flags/Vietnamese.tsx @@ -0,0 +1,28 @@ +import type { FlagPropTypes } from './Flags.types.js'; + +import React from 'react'; + +import { DEFAULT_SIZE } from './Flags.constants.js'; + +export default function Vietnamese(props: FlagPropTypes) { + const { size = DEFAULT_SIZE } = props; + + return ( + + + + + + + + + + ); +} diff --git a/widget/ui/src/components/Flags/index.ts b/widget/ui/src/components/Flags/index.ts new file mode 100644 index 0000000000..49cc3a3f59 --- /dev/null +++ b/widget/ui/src/components/Flags/index.ts @@ -0,0 +1,77 @@ +import Bengali from './Bengali.js'; +import Catalonia from './Catalonia.js'; +import Chinese from './Chinese.js'; +import Cyprus from './Cyprus.js'; +import Denmark from './Denmark.js'; +import English from './English.js'; +import Finland from './Finland.js'; +import French from './French.js'; +import German from './German.js'; +import Greece from './Greece.js'; +import Hindi from './Hindi.js'; +import Hungary from './Hungary.js'; +import India from './India.js'; +import Indonesian from './Indonesian.js'; +import Italian from './Italian.js'; +import Japanese from './Japanese.js'; +import Korea from './Korea.js'; +import Lithuania from './Lithuania.js'; +import Malay from './Malay.js'; +import Netherlands from './Netherlands.js'; +import Pakistan from './Pakistan.js'; +import Philippines from './Philippines.js'; +import Poland from './Poland.js'; +import Portuguese from './Portuguese.js'; +import Russian from './Russian.js'; +import SaudiArabia from './SaudiArabia.js'; +import Serbia from './Serbia.js'; +import Slovakia from './Slovakia.js'; +import SouthAfrica from './SouthAfrica.js'; +import Spanish from './Spanish.js'; +import Swahili from './Swahili.js'; +import Swedish from './Swedish.js'; +import Thai from './Thai.js'; +import Turkish from './Turkish.js'; +import Ukrainian from './Ukrainian.js'; +import Vietnamese from './Vietnamese.js'; + +export type { FlagPropTypes } from './Flags.types.js'; + +export { + English, + Spanish, + Japanese, + French, + Portuguese, + Hindi, + Chinese, + Bengali, + Russian, + Indonesian, + German, + Malay, + Swedish, + Thai, + Turkish, + Ukrainian, + Vietnamese, + Finland, + Netherlands, + Greece, + Italian, + Poland, + Catalonia, + Cyprus, + Denmark, + Hungary, + India, + Korea, + Lithuania, + Pakistan, + Philippines, + SaudiArabia, + Serbia, + Slovakia, + SouthAfrica, + Swahili, +}; diff --git a/widget/ui/src/components/FullExpandedQuote/FullExpandedQuote.Skeletons.tsx b/widget/ui/src/components/FullExpandedQuote/FullExpandedQuote.Skeletons.tsx new file mode 100644 index 0000000000..e9bab82708 --- /dev/null +++ b/widget/ui/src/components/FullExpandedQuote/FullExpandedQuote.Skeletons.tsx @@ -0,0 +1,71 @@ +import React from 'react'; + +import { ChainToken } from '../ChainToken/index.js'; +import { Skeleton } from '../Skeleton/index.js'; + +import { + FlexCenter, + OutputLoading, + Separator, + SkeletonItemLeftContainer, + VerticalLine, +} from './FullExpandedQuote.styles.js'; + +export function SkeletonHeader() { + return ( + <> + + + + + + + + + + + + ); +} + +export function SkeletonOutput() { + return ( + + + + + ); +} +export function SkeletonItemLeft() { + return ( + + + + ); +} + +export function SkeletonItemRight() { + return ( + + + + + ); +} diff --git a/widget/ui/src/components/FullExpandedQuote/FullExpandedQuote.TokenSection.tsx b/widget/ui/src/components/FullExpandedQuote/FullExpandedQuote.TokenSection.tsx new file mode 100644 index 0000000000..b4e070ac10 --- /dev/null +++ b/widget/ui/src/components/FullExpandedQuote/FullExpandedQuote.TokenSection.tsx @@ -0,0 +1,48 @@ +import type { TokenSectionPropTypes } from './FullExpandedQuote.types.js'; + +import React from 'react'; + +import { ChainToken } from '../ChainToken/index.js'; +import { NumericTooltip } from '../Tooltip/index.js'; +import { Typography } from '../Typography/index.js'; + +import { + TokenInfo, + tokenLabelStyles, + TokenSectionContainer, +} from './FullExpandedQuote.styles.js'; + +export function TokenSection(props: TokenSectionPropTypes) { + const { + style = {}, + chainImage, + tokenImage, + tooltipProps, + amount, + name, + isInternalSwap, + size = 'xmedium', + } = props; + return ( + + + + + + {amount} + + + + {name} + + + + ); +} diff --git a/widget/ui/src/components/FullExpandedQuote/FullExpandedQuote.Tooltip.tsx b/widget/ui/src/components/FullExpandedQuote/FullExpandedQuote.Tooltip.tsx new file mode 100644 index 0000000000..1d5e3c6813 --- /dev/null +++ b/widget/ui/src/components/FullExpandedQuote/FullExpandedQuote.Tooltip.tsx @@ -0,0 +1,101 @@ +import type { TooltipContentProps } from './FullExpandedQuote.types.js'; + +import { i18n } from '@lingui/core'; +import React from 'react'; + +import { ChevronRightIcon } from '../../icons/index.js'; +import { Image } from '../common/index.js'; +import { Divider } from '../Divider/index.js'; +import { QuoteCost } from '../QuoteCost/index.js'; +import { Typography } from '../Typography/index.js'; + +import { + FlexCenter, + Icon, + SwapperContainer, + SwapperImage, + TooltipContainer, + TooltipFooter, + TooltipHeader, +} from './FullExpandedQuote.styles.js'; +import { TokenSection } from './FullExpandedQuote.TokenSection.js'; + +export function TooltipContent(props: TooltipContentProps) { + const { internalSwaps, time, fee, alerts } = props; + const hasInternalSwaps = !!internalSwaps.length; + const hasFooter = hasInternalSwaps || !!alerts; + return ( + + + + + {hasFooter && ( + + {hasInternalSwaps && ( + <> + + {i18n.t('Aggregated Transaction')} + + + {internalSwaps.map((internalSwap, index, arr) => { + const key = `internal-item-${index}`; + const isLastItem = index === arr.length - 1; + return ( + + + + + + + + + + + + {internalSwap.swapper.displayName} + + + + + + {isLastItem && ( + <> + + + )} + + ); + })} + + + )} + {alerts} + + )} + + ); +} diff --git a/widget/ui/src/components/FullExpandedQuote/FullExpandedQuote.helpers.ts b/widget/ui/src/components/FullExpandedQuote/FullExpandedQuote.helpers.ts new file mode 100644 index 0000000000..559633fcd7 --- /dev/null +++ b/widget/ui/src/components/FullExpandedQuote/FullExpandedQuote.helpers.ts @@ -0,0 +1,32 @@ +import type { I18n } from '@lingui/core'; +import type { Tag } from 'rango-types/lib/api/main'; + +export const ITEM_SKELETON_COUNT = 3; +export const TOOLTIP_SIDE_OFFSET = 10; +const MAX_AMOUNT_LENGTH_DISPLAY = 4; +const MAX_NAME_LENGTH_DISPLAY = 6; + +export function shortenAmount(amount: string) { + if (!amount || amount.length <= MAX_AMOUNT_LENGTH_DISPLAY) { + return amount; + } + return amount.slice(0, MAX_AMOUNT_LENGTH_DISPLAY) + '...'; +} + +export function shortenDisplayName(name: string) { + if (!name || name.length <= MAX_NAME_LENGTH_DISPLAY) { + return name; + } + return name.slice(0, MAX_NAME_LENGTH_DISPLAY) + '...'; +} + +export function getTagLabel(tag: Tag, t: I18n['t']): string { + const data: Record = { + CENTRALIZED: t('Centralized'), + FASTEST: t('Fastest'), + HIGH_IMPACT: t('High Impact'), + LOWEST_FEE: t('Lowest Fee'), + RECOMMENDED: t('Recommended'), + }; + return data[tag]; +} diff --git a/widget/ui/src/components/FullExpandedQuote/FullExpandedQuote.styles.ts b/widget/ui/src/components/FullExpandedQuote/FullExpandedQuote.styles.ts new file mode 100644 index 0000000000..33fed069e6 --- /dev/null +++ b/widget/ui/src/components/FullExpandedQuote/FullExpandedQuote.styles.ts @@ -0,0 +1,307 @@ +import { css, darkTheme, styled } from '../../theme.js'; +import { PriceImpact } from '../PriceImpact/index.js'; + +export const tokenLabelStyles = css({}); + +export const FlexCenter = styled('div', { + display: 'flex', + justifyContent: 'center', + alignItems: 'center', +}); +export const RouteContainer = styled('div', { + border: '1px solid', + padding: '$20 $15', + backgroundColor: '$neutral200', + borderRadius: '$xm', + cursor: 'pointer', + gap: '$20', + display: 'flex', + flexDirection: 'column', + [`.${darkTheme} &`]: { + backgroundColor: '$neutral500', + }, + '&:hover': { + backgroundColor: '$neutral300', + [`.${darkTheme} &`]: { + backgroundColor: '$neutral400', + }, + }, + variants: { + selected: { + true: { + $$color: '$colors$secondary500', + [`.${darkTheme} &`]: { + $$color: '$colors$secondary250', + }, + borderColor: '$$color', + }, + false: { + borderColor: 'transparent', + }, + }, + hovered: { + true: { + '&:hover': { + backgroundColor: '$neutral200', + [`.${darkTheme} &`]: { + backgroundColor: '$neutral500', + }, + }, + }, + }, + }, +}); + +export const RouteHeader = styled('div', { + display: 'flex', + justifyContent: 'space-between', + variants: { + loading: { + true: { + padding: '$2', + }, + }, + }, +}); + +export const TagsContainer = styled('div', { + display: 'flex', + gap: '$5', +}); + +export const Steps = styled('div', { + display: 'flex', + height: '85px', +}); + +export const StepItem = styled('div', { + padding: '$10 $5 $5 0', + height: '100px', + display: 'flex', + width: '100%', + variants: { + isHovered: { + true: { + backgroundColor: '$neutral400', + boxShadow: '4px 4px 10px 0 #0000001A', + borderRadius: '$xs', + zIndex: 10, + }, + }, + }, +}); + +export const StepItemContainer = styled('div', { + width: '100%', + display: 'flex', + height: '100%', +}); + +export const TokenSectionContainer = styled(FlexCenter, { + minWidth: '42px', + position: 'relative', + variants: { + isInternalSwap: { + true: { + flexDirection: 'column', + gap: '$5', + + '& .token-info': { + position: 'static', + flexDirection: 'column-reverse', + }, + }, + }, + }, +}); + +export const SwapperSection = styled('div', { + width: '100%', + height: '50%', + borderBottom: '1px dashed', + borderColor: '$secondary200', + display: 'flex', + flexDirection: 'column', + justifyContent: 'flex-end', + gap: '2px', + [`.${darkTheme} &`]: { + borderColor: '$secondary550', + }, +}); + +export const TokenInfo = styled(FlexCenter, { + position: 'absolute', + flexDirection: 'column', + bottom: 0, + left: 0, + right: 0, + [`& .${tokenLabelStyles}`]: { + color: '$neutral700', + [`.${darkTheme} &`]: { + color: '$neutral900', + }, + }, +}); + +export const SwapperContainer = styled(FlexCenter, { + flexDirection: 'column', + '& ._typography': { + color: '$neutral700', + [`.${darkTheme} &`]: { + color: '$neutral900', + }, + }, +}); + +export const SwapperContent = styled(FlexCenter, { + flexDirection: 'column', + width: 'fit-content', +}); + +export const SwapperImagesContainer = styled(FlexCenter, { + position: 'relative', +}); + +export const SwapperImage = styled(FlexCenter, { + borderRadius: '$lg', + position: 'relative', + width: '$24', + height: '$24', + border: '1px solid transparent', + variants: { + state: { + warning: { + borderColor: '$warning500', + }, + error: { + borderColor: '$error500', + }, + }, + }, +}); + +export const IconHighlight = styled(FlexCenter, { + borderRadius: '$lg', + position: 'absolute', + width: '$10', + height: '$10', + bottom: -3, + right: -3, + variants: { + type: { + warning: { + $$color: '$colors$warning300', + [`.${darkTheme} &`]: { + $$color: '$colors$warning600', + }, + backgroundColor: '$$color', + }, + error: { + $$color: '$colors$error300', + [`.${darkTheme} &`]: { + $$color: '$colors$error600', + }, + backgroundColor: '$$color', + }, + }, + }, +}); + +export const OutputSection = styled(FlexCenter, { + flexDirection: 'column', + paddingLeft: '$8', +}); + +export const VerticalLine = styled('div', { + display: 'flex', + width: 'calc(50% + 1px)', + borderRight: '1px dashed', + height: '$10', + borderColor: '$secondary200', + [`.${darkTheme} &`]: { + borderColor: '$secondary550', + }, +}); + +export const StyledPriceImpact = styled(PriceImpact, { + justifyContent: 'center', + gap: '$4', +}); + +export const lastStepStyle = css({ + position: 'relative', + '&::after': { + content: '', + position: 'absolute', + bottom: '-6px', + right: '-3px', + transform: 'translate(-50%, -50%) rotate(45deg)', + width: '$6', + height: '$6', + borderTop: '2px solid', + borderRight: '2px solid', + borderColor: '$secondary200', + [`.${darkTheme} &`]: { + borderColor: '$secondary550', + }, + }, +}); + +// Styles for the skeleton + +export const Separator = styled('div', { + height: '$12', + marginLeft: '$10', + marginRight: '$10', + borderLeft: '1px solid $neutral700', +}); + +export const OutputLoading = styled(FlexCenter, { + padding: '$10 $2 0', + height: '85px', + gap: '$10', + flexDirection: 'column', +}); + +export const SkeletonItemLeftContainer = styled('div', { + display: 'flex', + alignItems: 'center', + paddingTop: '$25', +}); + +// Styles for the tooltip + +export const TooltipContainer = styled('div', { + display: 'flex', + justifyContent: 'center', + alignItems: 'flex-start', + flexDirection: 'column', + gap: '$10', +}); + +export const TooltipHeader = styled('div', { + width: '100%', + variants: { + hasFooter: { + true: { + paddingBottom: '$5', + borderBottom: '1px solid', + borderColor: '$neutral500', + [`.${darkTheme} &`]: { + borderColor: '$neutral800', + }, + }, + }, + }, +}); + +export const TooltipFooter = styled(FlexCenter, { + width: '100%', + flexDirection: 'column', + alignItems: 'stretch', + gap: '$10', +}); + +export const Icon = styled('div', { + paddingBottom: '$20', +}); diff --git a/widget/ui/src/components/FullExpandedQuote/FullExpandedQuote.tsx b/widget/ui/src/components/FullExpandedQuote/FullExpandedQuote.tsx new file mode 100644 index 0000000000..abe72bb1be --- /dev/null +++ b/widget/ui/src/components/FullExpandedQuote/FullExpandedQuote.tsx @@ -0,0 +1,276 @@ +import type { DataLoadedProps, PropTypes } from './FullExpandedQuote.types.js'; +import type { Tag } from 'rango-types/lib/api/main'; + +import { i18n } from '@lingui/core'; +import React, { useState } from 'react'; + +import { ErrorIcon, WarningIcon } from '../../icons/index.js'; +import { ChainToken } from '../ChainToken/index.js'; +import { Image } from '../common/index.js'; +import { Divider } from '../Divider/index.js'; +import { QuoteTag } from '../QuoteTag/index.js'; +import { NumericTooltip, Tooltip } from '../Tooltip/index.js'; +import { Typography } from '../Typography/index.js'; + +import { + getTagLabel, + ITEM_SKELETON_COUNT, + shortenAmount, + shortenDisplayName, + TOOLTIP_SIDE_OFFSET, +} from './FullExpandedQuote.helpers.js'; +import { + SkeletonHeader, + SkeletonItemLeft, + SkeletonItemRight, + SkeletonOutput, +} from './FullExpandedQuote.Skeletons.js'; +import { + IconHighlight, + lastStepStyle, + OutputSection, + RouteContainer, + RouteHeader, + StepItem, + StepItemContainer, + Steps, + StyledPriceImpact, + SwapperContainer, + SwapperContent, + SwapperImage, + SwapperImagesContainer, + SwapperSection, + TagsContainer, + VerticalLine, +} from './FullExpandedQuote.styles.js'; +import { TokenSection } from './FullExpandedQuote.TokenSection.js'; +import { TooltipContent } from './FullExpandedQuote.Tooltip.js'; + +export function FullExpandedQuote(props: PropTypes) { + const { + loading, + percentageChange, + warningLevel, + tooltipContainer, + onClick, + selected = false, + } = props; + const [hoveredItemIndex, setHoveredItemIndex] = useState(null); + + const steps: DataLoadedProps['steps'] = loading + ? Array(ITEM_SKELETON_COUNT).fill(undefined) + : props.steps; + const numberOfSteps = steps.length; + + return ( + + + {loading ? ( + + ) : ( + <> + {props.quoteCost} + + {props.tags.map((tag) => ( + + ))} + + + )} + + + {steps.map((step, index) => { + const key = `item-${index}`; + const isStepHovered = hoveredItemIndex === index; + const isLastItem = index === numberOfSteps - 1; + const isFirstItem = index === 0; + return ( + + + ) : null + }> + + {loading ? ( + + ) : ( + + )} + + {loading ? ( + + ) : ( + <> + + setHoveredItemIndex(index)} + onMouseLeave={() => setHoveredItemIndex(null)}> + + {!step.internalSwaps ? ( + + + + ) : ( + step.internalSwaps.map( + (internalswap, iIndex) => { + const key = `${iIndex}-swapper-image`; + return ( + + + + ); + } + ) + )} + {step.state && ( + + {step.state === 'error' ? ( + + ) : ( + + )} + + )} + + + + + {step.swapper.displayName} + + + + + + + )} + + {!loading && !isLastItem && ( + + )} + {!loading && isLastItem && ( + + + +
+ + + {props.outputPrice.value} + + + + {step.to.token.displayName} + + +
+ +
+ )} +
+
+
+ ); + })} + + {loading && } +
+
+ ); +} diff --git a/widget/ui/src/components/FullExpandedQuote/FullExpandedQuote.types.ts b/widget/ui/src/components/FullExpandedQuote/FullExpandedQuote.types.ts new file mode 100644 index 0000000000..0385f8a13f --- /dev/null +++ b/widget/ui/src/components/FullExpandedQuote/FullExpandedQuote.types.ts @@ -0,0 +1,56 @@ +import type { SwapInputPropTypes } from '../../containers/SwapInput/SwapInput.types.js'; +import type { ChainTokenPropTypes } from '../ChainToken/index.js'; +import type { PriceImpactPropTypes } from '../PriceImpact/PriceImpact.types.js'; +import type { PropTypes as QuoteCostProps } from '../QuoteCost/QuoteCost.types.js'; +import type { InternalSwap, Step } from '../StepDetails/StepDetails.types.js'; +import type { + NumericTooltipPropTypes, + TooltipPropTypes, +} from '../Tooltip/index.js'; +import type { CSSProperties } from '@stitches/react'; +import type { RouteTag } from 'rango-types/lib/api/main'; + +type BaseProps = { + percentageChange?: PriceImpactPropTypes['percentageChange']; + warningLevel?: PriceImpactPropTypes['warningLevel']; + tooltipContainer?: HTMLElement; + onClick?: () => void; + selected?: boolean; +}; + +export type DataLoadedProps = { + steps: Step[]; + tags: RouteTag[]; + time: QuoteCostProps['time']; + fee: QuoteCostProps['fee']; + outputPrice: SwapInputPropTypes['price']; + loading?: false; + quoteCost: React.ReactElement; +}; +type LoadingProps = { + loading: true; +}; + +export type PropTypes = BaseProps & (DataLoadedProps | LoadingProps); + +export interface TooltipContentProps { + internalSwaps: InternalSwap[]; + time: QuoteCostProps['time']; + fee: DataLoadedProps['fee']; + alerts?: Step['alerts']; +} + +export interface TokenSectionPropTypes { + style?: CSSProperties; + tooltipProps?: { + container: TooltipPropTypes['container']; + content: NumericTooltipPropTypes['content']; + open?: TooltipPropTypes['open']; + }; + isInternalSwap?: boolean; + tokenImage: ChainTokenPropTypes['tokenImage']; + chainImage: ChainTokenPropTypes['chainImage']; + size?: ChainTokenPropTypes['size']; + amount?: string; + name?: string; +} diff --git a/widget/ui/src/components/FullExpandedQuote/index.ts b/widget/ui/src/components/FullExpandedQuote/index.ts new file mode 100644 index 0000000000..2e01a32ab9 --- /dev/null +++ b/widget/ui/src/components/FullExpandedQuote/index.ts @@ -0,0 +1 @@ +export { FullExpandedQuote } from './FullExpandedQuote.js'; diff --git a/widget/ui/src/components/Header/Header.constants.ts b/widget/ui/src/components/Header/Header.constants.ts new file mode 100644 index 0000000000..4b72d4d928 --- /dev/null +++ b/widget/ui/src/components/Header/Header.constants.ts @@ -0,0 +1 @@ +export const HEADER_CORNDER_RADIUS = 20; diff --git a/widget/ui/src/components/Header/Header.styles.ts b/widget/ui/src/components/Header/Header.styles.ts new file mode 100644 index 0000000000..4b87744811 --- /dev/null +++ b/widget/ui/src/components/Header/Header.styles.ts @@ -0,0 +1,89 @@ +import { globalCss } from '@stitches/react'; + +import { darkTheme, styled } from '../../theme.js'; + +import { HEADER_CORNDER_RADIUS } from './Header.constants.js'; + +export const globalHeaderStyles = globalCss({ + '.rng-scrolled': { + '.rng-curve-left::before, rng-curve-right::before': { + borderRadius: '0 !important', + }, + }, +}); + +export const Container = styled('div', { + display: 'flex', + alignItems: 'center', + padding: '$20 $20 $15 $20', + $$color: '$colors$neutral100', + [`.${darkTheme} &`]: { + $$color: '$colors$neutral300', + }, + backgroundColor: '$$color', + position: 'relative', + + variants: { + titlePosition: { + left: { + justifyContent: 'start', + }, + center: { + justifyContent: 'center', + }, + right: { + justifyContent: 'end', + }, + }, + }, + + '.rng-curve-left,.rng-curve-right': { + width: HEADER_CORNDER_RADIUS * 2, + height: HEADER_CORNDER_RADIUS * 2, + position: 'absolute', + bottom: 0, + overflow: 'hidden', + transform: 'translateY(100%)', + + '&:before': { + width: HEADER_CORNDER_RADIUS * 2, + height: HEADER_CORNDER_RADIUS * 2, + display: 'block', + content: '', + position: 'absolute', + bottom: 0, + borderRadius: '50%', + transition: 'border-radius 0.5s', + }, + }, + '.rng-curve-left': { + left: 0, + '&:before': { + left: 0, + boxShadow: `-${HEADER_CORNDER_RADIUS}px -${HEADER_CORNDER_RADIUS}px 0 0 $$color`, + }, + }, + '.rng-curve-right': { + right: 0, + '&:before': { + right: 0, + boxShadow: `${HEADER_CORNDER_RADIUS}px -${HEADER_CORNDER_RADIUS}px 0 0 $$color`, + }, + }, +}); + +export const Prefix = styled('div', { + position: 'absolute', + left: '$20', + display: 'flex', + alignItems: 'center', + gap: '$5', +}); + +export const Suffix = styled('div', { + position: 'absolute', + right: '$20', + display: 'flex', + alignItems: 'center', + gap: '$5', +}); diff --git a/widget/ui/src/components/Header/Header.tsx b/widget/ui/src/components/Header/Header.tsx index 7ee8cffc34..22529e0964 100644 --- a/widget/ui/src/components/Header/Header.tsx +++ b/widget/ui/src/components/Header/Header.tsx @@ -1,39 +1,49 @@ -import { styled } from '../../theme'; -import React, { PropsWithChildren } from 'react'; -import { AngleLeftIcon } from '../Icon'; -import { Typography } from '../Typography'; -import { Button } from '../Button'; +import type { PropTypes } from './Header.types.js'; +import type { PropsWithChildren } from 'react'; -const HeaderContainer = styled('div', { - display: 'flex', - justifyContent: 'space-between', - alignItems: 'center', - padding: '$8 0', - position: 'relative', -}); +import React from 'react'; -const BackButton = styled(Button, { - padding: '$8', -}); +import { Typography } from '../Typography/index.js'; -interface PropTypes { - onBack?: () => void; - prefix?: React.ReactNode; - suffix?: React.ReactNode; - title: string; -} +import { Container, globalHeaderStyles, Prefix, Suffix } from './Header.styles'; + +export function Header({ + prefix, + suffix, + title, +}: PropsWithChildren) { + globalHeaderStyles(); + + const getTitlePosition = () => { + if (!prefix) { + return 'left'; + } + if (!suffix) { + return 'right'; + } + return 'center'; + }; + + const renderTitle = () => { + if (!title) { + return null; + } else if (typeof title === 'string') { + return ( + + {title} + + ); + } + return title; + }; -export function Header(props: PropsWithChildren) { return ( - - {props.onBack ? ( - - - - ) : null} - {props.prefix} - {props.title} - {props.suffix ||
} -
+ + {prefix} + {renderTitle()} + {suffix} +
+
+
); } diff --git a/widget/ui/src/components/Header/Header.types.ts b/widget/ui/src/components/Header/Header.types.ts new file mode 100644 index 0000000000..ec266c7409 --- /dev/null +++ b/widget/ui/src/components/Header/Header.types.ts @@ -0,0 +1,5 @@ +export interface PropTypes { + prefix?: React.ReactNode; + suffix?: React.ReactNode; + title?: string | React.ReactNode; +} diff --git a/widget/ui/src/components/Header/index.ts b/widget/ui/src/components/Header/index.ts index 29429dc97e..fca4047533 100644 --- a/widget/ui/src/components/Header/index.ts +++ b/widget/ui/src/components/Header/index.ts @@ -1 +1,2 @@ -export { Header } from './Header'; +export { Header } from './Header.js'; +export { HEADER_CORNDER_RADIUS } from './Header.constants.js'; diff --git a/widget/ui/src/components/I18nManager/I18nManager.tsx b/widget/ui/src/components/I18nManager/I18nManager.tsx new file mode 100644 index 0000000000..9202d545ab --- /dev/null +++ b/widget/ui/src/components/I18nManager/I18nManager.tsx @@ -0,0 +1,113 @@ +import type { PropsWithChildren } from 'react'; + +import { i18n } from '@lingui/core'; +import { I18nProvider } from '@lingui/react'; +import React, { useEffect, useReducer } from 'react'; + +/* + *Note: esbuild doesn't work properly with paths yet, so I couldn't use `paths` to make this path shorter. + *e.g: + *"paths": { + * "translations/*": ["../../translations/*"] + *} + */ +import { messages as afMessages } from '../../../../../translations/af.js'; +import { messages as arMessages } from '../../../../../translations/ar.js'; +import { messages as bnMessages } from '../../../../../translations/bn.js'; +import { messages as caMessages } from '../../../../../translations/ca.js'; +import { messages as daMessages } from '../../../../../translations/da.js'; +import { messages as deMessages } from '../../../../../translations/de.js'; +import { messages as elMessages } from '../../../../../translations/el.js'; +import { messages as enMessages } from '../../../../../translations/en.js'; +import { messages as esMessages } from '../../../../../translations/es.js'; +import { messages as fiMessages } from '../../../../../translations/fi.js'; +import { messages as filMessages } from '../../../../../translations/fil.js'; +import { messages as frMessages } from '../../../../../translations/fr.js'; +import { messages as hiMessages } from '../../../../../translations/hi.js'; +import { messages as huMessages } from '../../../../../translations/hu.js'; +import { messages as idMessages } from '../../../../../translations/id.js'; +import { messages as itMessages } from '../../../../../translations/it.js'; +import { messages as jaMessages } from '../../../../../translations/ja.js'; +import { messages as koMessages } from '../../../../../translations/ko.js'; +import { messages as ltMessages } from '../../../../../translations/lt.js'; +import { messages as msMessages } from '../../../../../translations/ms.js'; +import { messages as nlMessages } from '../../../../../translations/nl.js'; +import { messages as plMessages } from '../../../../../translations/pl.js'; +import { messages as ptMessages } from '../../../../../translations/pt.js'; +import { messages as ruMessages } from '../../../../../translations/ru.js'; +import { messages as skMessages } from '../../../../../translations/sk.js'; +import { messages as srMessages } from '../../../../../translations/sr.js'; +import { messages as svMessages } from '../../../../../translations/sv.js'; +import { messages as swMessages } from '../../../../../translations/sw.js'; +import { messages as thMessages } from '../../../../../translations/th.js'; +import { messages as trMessages } from '../../../../../translations/tr.js'; +import { messages as ukMessages } from '../../../../../translations/uk.js'; +import { messages as urMessages } from '../../../../../translations/ur.js'; +import { messages as viMessages } from '../../../../../translations/vi.js'; +import { messages as zh_CNMessages } from '../../../../../translations/zh-CN.js'; +import { messages as zh_TWMessages } from '../../../../../translations/zh-TW.js'; + +const messages = { + af: afMessages, + ar: arMessages, + bn: bnMessages, + ca: caMessages, + da: daMessages, + de: deMessages, + el: elMessages, + en: enMessages, + es: esMessages, + fi: fiMessages, + fil: filMessages, + fr: frMessages, + hi: hiMessages, + hu: huMessages, + id: idMessages, + it: itMessages, + ja: jaMessages, + ko: koMessages, + lt: ltMessages, + ms: msMessages, + nl: nlMessages, + pl: plMessages, + pt: ptMessages, + ru: ruMessages, + sk: skMessages, + sr: srMessages, + sv: svMessages, + sw: swMessages, + th: thMessages, + tr: trMessages, + uk: ukMessages, + ur: urMessages, + vi: viMessages, + 'zh-CN': zh_CNMessages, + 'zh-TW': zh_TWMessages, +}; + +i18n.load(messages); + +export type Language = keyof typeof messages; +interface PropTypes { + language: Language; +} + +function I18nManager(props: PropsWithChildren) { + const [count, forceUpdate] = useReducer((x) => x + 1, 0); + useEffect(() => { + i18n.on('change', () => { + forceUpdate(); + }); + }, [i18n]); + useEffect(() => { + i18n.activate(props.language); + }, [props.language]); + + return ( + + {props.children} + + ); +} + +export { I18nManager }; diff --git a/widget/ui/src/components/I18nManager/index.ts b/widget/ui/src/components/I18nManager/index.ts new file mode 100644 index 0000000000..a9a3ab91c5 --- /dev/null +++ b/widget/ui/src/components/I18nManager/index.ts @@ -0,0 +1,2 @@ +export { I18nManager } from './I18nManager.js'; +export type { Language } from './I18nManager.js'; diff --git a/widget/ui/src/components/Icon/AddCircleIcon.tsx b/widget/ui/src/components/Icon/AddCircleIcon.tsx deleted file mode 100644 index c5c36a67ba..0000000000 --- a/widget/ui/src/components/Icon/AddCircleIcon.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import * as React from 'react'; -import { SvgWithStrokeColor } from './common'; -import { IconProps } from './types'; - -export const AddCircleIcon: React.FC = ({ - size = 16, - color, - ...props -}) => { - return ( - - - - ); -}; - -AddCircleIcon.toString = () => '._icon'; diff --git a/widget/ui/src/components/Icon/AddIcon.tsx b/widget/ui/src/components/Icon/AddIcon.tsx deleted file mode 100644 index 7243d2766c..0000000000 --- a/widget/ui/src/components/Icon/AddIcon.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import * as React from 'react'; -import { SvgWithStrokeColor } from './common'; -import { IconProps } from './types'; - -export const AddIcon: React.FC = ({ - size = 16, - color, - ...props -}) => { - return ( - - - - ); -}; - -AddIcon.toString = () => '._icon'; diff --git a/widget/ui/src/components/Icon/AddWalletIcon.tsx b/widget/ui/src/components/Icon/AddWalletIcon.tsx deleted file mode 100644 index 50ba306ea8..0000000000 --- a/widget/ui/src/components/Icon/AddWalletIcon.tsx +++ /dev/null @@ -1,50 +0,0 @@ -import * as React from 'react'; -import { SvgWithFillColor } from './common'; -import { IconProps } from './types'; - -export const AddWalletIcon: React.FC = ({ - size = 16, - color, - ...props -}) => { - return ( - - - - - - - - ); -}; - -AddWalletIcon.toString = () => '._icon'; diff --git a/widget/ui/src/components/Icon/AngleDownIcon.tsx b/widget/ui/src/components/Icon/AngleDownIcon.tsx deleted file mode 100644 index 46967400a1..0000000000 --- a/widget/ui/src/components/Icon/AngleDownIcon.tsx +++ /dev/null @@ -1,30 +0,0 @@ -import React from 'react'; -import { IconProps } from './types'; -import { SvgWithStrokeColor } from './common'; - -export const AngleDownIcon: React.FC = ({ - size = 16, - color, - ...props -}) => ( - - - -); - -AngleDownIcon.toString = () => '._icon'; diff --git a/widget/ui/src/components/Icon/AngleLeftIcon.tsx b/widget/ui/src/components/Icon/AngleLeftIcon.tsx deleted file mode 100644 index 2da9627172..0000000000 --- a/widget/ui/src/components/Icon/AngleLeftIcon.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import * as React from 'react'; -import { IconProps } from './types'; -import { SvgWithStrokeColor } from './common'; -import { AngleDownIcon } from './AngleDownIcon'; - -export const AngleLeftIcon: React.FC = ({ - size = 16, - color, - ...props -}) => { - return ( - - - - ); -}; - -AngleDownIcon.toString = () => '._icon'; diff --git a/widget/ui/src/components/Icon/AngleRightIcon.tsx b/widget/ui/src/components/Icon/AngleRightIcon.tsx deleted file mode 100644 index 223f8de0ad..0000000000 --- a/widget/ui/src/components/Icon/AngleRightIcon.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import * as React from 'react'; -import { IconProps } from './types'; -import { SvgWithStrokeColor } from './common'; - -export const AngleRightIcon: React.FC = ({ - size = 16, - color, - ...props -}) => { - return ( - - - - ); -}; - -AngleRightIcon.toString = () => '._icon'; diff --git a/widget/ui/src/components/Icon/AngleUpIcon.tsx b/widget/ui/src/components/Icon/AngleUpIcon.tsx deleted file mode 100644 index d2f106ebf7..0000000000 --- a/widget/ui/src/components/Icon/AngleUpIcon.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import * as React from 'react'; -import { IconProps } from './types'; -import { SvgWithStrokeColor } from './common'; - -export const AngleUpIcon: React.FC = ({ - size = 16, - color, - ...props -}) => { - return ( - - - - ); -}; - -AngleUpIcon.toString = () => '._icon'; diff --git a/widget/ui/src/components/Icon/ArrowRightIcon.tsx b/widget/ui/src/components/Icon/ArrowRightIcon.tsx deleted file mode 100644 index 7d2683f9ea..0000000000 --- a/widget/ui/src/components/Icon/ArrowRightIcon.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import * as React from 'react'; -import { IconProps } from './types'; -import { SvgWithStrokeColor } from './common'; - -export const ArrowRightIcon: React.FC = ({ - size = 16, - color, - ...props -}) => { - return ( - - - - - ); -}; - -ArrowRightIcon.toString = () => '._icon'; diff --git a/widget/ui/src/components/Icon/BagIcon.tsx b/widget/ui/src/components/Icon/BagIcon.tsx deleted file mode 100644 index 225528c3d6..0000000000 --- a/widget/ui/src/components/Icon/BagIcon.tsx +++ /dev/null @@ -1,39 +0,0 @@ -import * as React from 'react'; -import { SvgWithStrokeColor } from './common'; -import { IconProps } from './types'; - -export const BagIcon: React.FC = ({ - size = 16, - color, - ...props -}) => { - return ( - - - - - - - - - - - - ); -}; - -BagIcon.toString = () => '._icon'; diff --git a/widget/ui/src/components/Icon/BanIcon.tsx b/widget/ui/src/components/Icon/BanIcon.tsx deleted file mode 100644 index 0eb4e42b22..0000000000 --- a/widget/ui/src/components/Icon/BanIcon.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import * as React from 'react'; -import { SvgWithStrokeColor } from './common'; -import { IconProps } from './types'; - -export const BanIcon: React.FC = ({ - size = 16, - color, - ...props -}) => { - return ( - - - - ); -}; - -BanIcon.toString = () => '._icon'; diff --git a/widget/ui/src/components/Icon/CheckCircleIcon.tsx b/widget/ui/src/components/Icon/CheckCircleIcon.tsx deleted file mode 100644 index 18c1ce3a6e..0000000000 --- a/widget/ui/src/components/Icon/CheckCircleIcon.tsx +++ /dev/null @@ -1,39 +0,0 @@ -import * as React from 'react'; -import { IconProps } from './types'; -import { SvgWithFillColor } from './common'; - -export const CheckCircleIcon: React.FC = ({ - size = 16, - color, - ...props -}) => { - return ( - - - - - ); -}; - -CheckCircleIcon.toString = () => '._icon'; diff --git a/widget/ui/src/components/Icon/CheckIcon.tsx b/widget/ui/src/components/Icon/CheckIcon.tsx deleted file mode 100644 index d163f5b831..0000000000 --- a/widget/ui/src/components/Icon/CheckIcon.tsx +++ /dev/null @@ -1,30 +0,0 @@ -import * as React from 'react'; -import { SvgWithFillColor } from './common'; -import { IconProps } from './types'; - -export const CheckIcon: React.FC = ({ - size = 16, - color, - ...props -}) => { - return ( - - - - ); -}; - -CheckIcon.toString = () => '._icon'; diff --git a/widget/ui/src/components/Icon/CheckSquareIcon.tsx b/widget/ui/src/components/Icon/CheckSquareIcon.tsx deleted file mode 100644 index 9978da845d..0000000000 --- a/widget/ui/src/components/Icon/CheckSquareIcon.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import * as React from 'react'; -import { SvgWithStrokeColor } from './common'; -import { IconProps } from './types'; - -export const CheckSquareIcon: React.FC = ({ - size = 16, - color, - ...props -}) => { - return ( - - - - - ); -}; - -CheckSquareIcon.toString = () => '._icon'; diff --git a/widget/ui/src/components/Icon/CheckWalletIcon.tsx b/widget/ui/src/components/Icon/CheckWalletIcon.tsx deleted file mode 100644 index f1231387fe..0000000000 --- a/widget/ui/src/components/Icon/CheckWalletIcon.tsx +++ /dev/null @@ -1,45 +0,0 @@ -import * as React from 'react'; -import { IconProps } from './types'; -import { SvgWithFillColor } from './common'; - -export const CheckWalletIcon: React.FC = ({ - size = 16, - color, - ...props -}) => { - return ( - - - - - - - ); -}; - -CheckWalletIcon.toString = () => '._icon'; diff --git a/widget/ui/src/components/Icon/ChevronRightIcon.tsx b/widget/ui/src/components/Icon/ChevronRightIcon.tsx deleted file mode 100644 index 54d64623a9..0000000000 --- a/widget/ui/src/components/Icon/ChevronRightIcon.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import * as React from 'react'; -import { SvgWithStrokeColor } from './common'; -import { IconProps } from './types'; - -export const ChevronRightIcon = React.forwardRef( - ({ color = 'black', size = 16, ...props }, forwardedRef) => { - return ( - - - - ); - } -); - -ChevronRightIcon.toString = () => '._icon'; diff --git a/widget/ui/src/components/Icon/CloseIcon.tsx b/widget/ui/src/components/Icon/CloseIcon.tsx deleted file mode 100644 index 836afd8acb..0000000000 --- a/widget/ui/src/components/Icon/CloseIcon.tsx +++ /dev/null @@ -1,9 +0,0 @@ -import { styled } from '../../theme'; -import { AddIcon } from './AddIcon'; - -export const CloseIcon = styled(AddIcon, { - transform: 'rotate(45deg)', - cursor: 'pointer', -}); - -CloseIcon.toString = () => '._icon'; diff --git a/widget/ui/src/components/Icon/CopyIcon.tsx b/widget/ui/src/components/Icon/CopyIcon.tsx deleted file mode 100644 index 25c2eb37cd..0000000000 --- a/widget/ui/src/components/Icon/CopyIcon.tsx +++ /dev/null @@ -1,59 +0,0 @@ -import * as React from 'react'; -import { SvgWithFillColor } from './common'; -import { IconProps } from './types'; - -export const CopyIcon: React.FC = ({ - size = 16, - color, - ...props -}) => { - return ( - - - - - - - - - - ); -}; - -CopyIcon.toString = () => '._icon'; diff --git a/widget/ui/src/components/Icon/DeleteCircleIcon.tsx b/widget/ui/src/components/Icon/DeleteCircleIcon.tsx deleted file mode 100644 index 46b24e9d4b..0000000000 --- a/widget/ui/src/components/Icon/DeleteCircleIcon.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import * as React from 'react'; -import { SvgWithStrokeColor } from './common'; -import { IconProps } from './types'; - -export const DeleteCircleIcon: React.FC = ({ - size = 16, - color, - ...props -}) => { - return ( - - - - ); -}; - -DeleteCircleIcon.toString = () => '._icon'; diff --git a/widget/ui/src/components/Icon/DeleteWalletIcon.tsx b/widget/ui/src/components/Icon/DeleteWalletIcon.tsx deleted file mode 100644 index 99d202e6c9..0000000000 --- a/widget/ui/src/components/Icon/DeleteWalletIcon.tsx +++ /dev/null @@ -1,50 +0,0 @@ -import * as React from 'react'; -import { SvgWithFillColor } from './common'; -import { IconProps } from './types'; - -export const DeleteWalletIcon: React.FC = ({ - size = 16, - color, - ...props -}) => { - return ( - - - - - - - - ); -}; - -DeleteWalletIcon.toString = () => '._icon'; diff --git a/widget/ui/src/components/Icon/DisconnectIcon.tsx b/widget/ui/src/components/Icon/DisconnectIcon.tsx deleted file mode 100644 index 61d849121f..0000000000 --- a/widget/ui/src/components/Icon/DisconnectIcon.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import * as React from 'react'; -import { SvgWithStrokeColor } from './common'; -import { IconProps } from './types'; - -export const DisconnectIcon = React.forwardRef( - ({ color = 'black', size = 16, ...props }, forwardedRef) => { - return ( - - - - - - ); - } -); - -DisconnectIcon.toString = () => '._icon'; diff --git a/widget/ui/src/components/Icon/DownloadIcon.tsx b/widget/ui/src/components/Icon/DownloadIcon.tsx deleted file mode 100644 index dfaff78bb6..0000000000 --- a/widget/ui/src/components/Icon/DownloadIcon.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import * as React from 'react'; -import { IconProps } from './types'; -import { SvgWithStrokeColor } from './common'; - -export const DownloadIcon: React.FC = ({ - size = 16, - color, - ...props -}) => { - return ( - - - - - ); -}; - -DownloadIcon.toString = () => '._icon'; diff --git a/widget/ui/src/components/Icon/GasIcon.tsx b/widget/ui/src/components/Icon/GasIcon.tsx deleted file mode 100644 index 84e3cedcab..0000000000 --- a/widget/ui/src/components/Icon/GasIcon.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import * as React from 'react'; -import { SvgWithStrokeColor } from './common'; -import { IconProps } from './types'; - -export const GasIcon: React.FC = ({ - size = 16, - color, - ...props -}) => { - return ( - - - - - ); -}; - -GasIcon.toString = () => '._icon'; diff --git a/widget/ui/src/components/Icon/HistoryIcon.tsx b/widget/ui/src/components/Icon/HistoryIcon.tsx deleted file mode 100644 index fa07c4fc3b..0000000000 --- a/widget/ui/src/components/Icon/HistoryIcon.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import * as React from 'react'; -import { SvgWithStrokeColor } from './common'; -import { IconProps } from './types'; - -export const HistoryIcon: React.FC = ({ - size = 16, - color, - ...props -}) => { - return ( - - - - - - - - ); -}; - -HistoryIcon.toString = () => '._icon'; diff --git a/widget/ui/src/components/Icon/HorizontalSwapIcon.tsx b/widget/ui/src/components/Icon/HorizontalSwapIcon.tsx deleted file mode 100644 index e2c3bb7f8e..0000000000 --- a/widget/ui/src/components/Icon/HorizontalSwapIcon.tsx +++ /dev/null @@ -1,38 +0,0 @@ -import * as React from 'react'; -import { SvgWithStrokeColor } from './common'; -import { IconProps } from './types'; - -export const HorizontalSwapIcon: React.FC = ({ - size = 16, - color, - ...props -}) => { - return ( - - - - - ); -}; - -HorizontalSwapIcon.toString = () => '._icon'; diff --git a/widget/ui/src/components/Icon/Icons.stories.tsx b/widget/ui/src/components/Icon/Icons.stories.tsx deleted file mode 100644 index 64043a2ac0..0000000000 --- a/widget/ui/src/components/Icon/Icons.stories.tsx +++ /dev/null @@ -1,44 +0,0 @@ -import React from 'react'; -import { Icon, IconProps } from './types'; -import * as Icons from '.'; -import { ComponentMeta } from '@storybook/react'; -import { styled } from '../../theme'; - -export default { - title: 'Components/Icons', - component: Icons.AngleRightIcon, - argTypes: { - color: { - name: 'color', - control: { type: 'select' }, - options: ['primary', 'error', 'warning', 'success', 'black', 'white'], - }, - - size: { - name: 'size', - control: { type: 'radio' }, - options: [16, 18, 20, 24, 28, 32, 36, 40], - defaultValue: 16, - }, - }, -} as ComponentMeta; - -const Container = styled('div', { - display: 'grid', - gridTemplateColumns: 'auto auto auto auto auto', - gap: 15, -}); - -export const Main = (props: IconProps) => ( - - {Object.keys(Icons).map(icon => { - const Component = Icons[icon as Icon]; - return ( -
- -

{icon}

-
- ); - })} -
-); diff --git a/widget/ui/src/components/Icon/InfoCircleIcon.tsx b/widget/ui/src/components/Icon/InfoCircleIcon.tsx deleted file mode 100644 index 65b9f05f39..0000000000 --- a/widget/ui/src/components/Icon/InfoCircleIcon.tsx +++ /dev/null @@ -1,39 +0,0 @@ -import * as React from 'react'; -import { IconProps } from './types'; -import { SvgWithFillColor } from './common'; - -export const InfoCircleIcon: React.FC = ({ - size = 16, - color, - ...props -}) => { - return ( - - - - - ); -}; - -InfoCircleIcon.toString = () => '._icon'; diff --git a/widget/ui/src/components/Icon/MinusCircleIcon.tsx b/widget/ui/src/components/Icon/MinusCircleIcon.tsx deleted file mode 100644 index 83dae43364..0000000000 --- a/widget/ui/src/components/Icon/MinusCircleIcon.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import * as React from 'react'; -import { SvgWithStrokeColor } from './common'; -import { IconProps } from './types'; - -export const MinusCircleIcon: React.FC = ({ - size = 16, - color, - ...props -}) => { - return ( - - - - ); -}; - -MinusCircleIcon.toString = () => '._icon'; diff --git a/widget/ui/src/components/Icon/RetryIcon.tsx b/widget/ui/src/components/Icon/RetryIcon.tsx deleted file mode 100644 index 39949c5307..0000000000 --- a/widget/ui/src/components/Icon/RetryIcon.tsx +++ /dev/null @@ -1,30 +0,0 @@ -import * as React from 'react'; -import { SvgWithStrokeColor } from './common'; -import { IconProps } from './types'; - -export const RetryIcon = React.forwardRef( - ({ color = 'black', size = 16, ...props }, forwardedRef) => { - return ( - - - - - ); - } -); - -RetryIcon.toString = () => '._icon'; diff --git a/widget/ui/src/components/Icon/RetryLeftIcon.tsx b/widget/ui/src/components/Icon/RetryLeftIcon.tsx deleted file mode 100644 index 3df493267c..0000000000 --- a/widget/ui/src/components/Icon/RetryLeftIcon.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import * as React from 'react'; -import { IconProps } from './types'; -import { SvgWithStrokeColor } from './common'; - -export const RetryLeftIcon: React.FC = ({ - size = 16, - color, - ...props -}) => { - return ( - - - - ); -}; - -RetryLeftIcon.toString = () => '._icon'; diff --git a/widget/ui/src/components/Icon/RetryRightIcon.tsx b/widget/ui/src/components/Icon/RetryRightIcon.tsx deleted file mode 100644 index d01a9120f3..0000000000 --- a/widget/ui/src/components/Icon/RetryRightIcon.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import * as React from 'react'; -import { SvgWithStrokeColor } from './common'; -import { IconProps } from './types'; - -export const RetryRightIcon: React.FC = ({ - size = 16, - color, - ...props -}) => { - return ( - - - - ); -}; - -RetryRightIcon.toString = () => '._icon'; diff --git a/widget/ui/src/components/Icon/SearchIcon.tsx b/widget/ui/src/components/Icon/SearchIcon.tsx deleted file mode 100644 index 8154bfc4c2..0000000000 --- a/widget/ui/src/components/Icon/SearchIcon.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import * as React from 'react'; -import { SvgWithStrokeColor } from './common'; -import { IconProps } from './types'; - -export const SearchIcon: React.FC = ({ - size = 16, - color, - ...props -}) => { - return ( - - - - ); -}; - -SearchIcon.toString = () => '._icon'; diff --git a/widget/ui/src/components/Icon/SearchMinusIcon.tsx b/widget/ui/src/components/Icon/SearchMinusIcon.tsx deleted file mode 100644 index 507e8b0863..0000000000 --- a/widget/ui/src/components/Icon/SearchMinusIcon.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import * as React from 'react'; -import { SvgWithStrokeColor } from './common'; -import { IconProps } from './types'; - -export const SearchMinusIcon: React.FC = ({ - size = 16, - color, - ...props -}) => { - return ( - - - - ); -}; - -SearchMinusIcon.toString = () => '._icon'; diff --git a/widget/ui/src/components/Icon/SettingIcon.tsx b/widget/ui/src/components/Icon/SettingIcon.tsx deleted file mode 100644 index 1afdac7a48..0000000000 --- a/widget/ui/src/components/Icon/SettingIcon.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import * as React from 'react'; -import { SvgWithStrokeColor } from './common'; -import { IconProps } from './types'; - -export const SettingsIcon: React.FC = ({ - size = 16, - color, - ...props -}) => { - return ( - - - - - ); -}; - -SettingsIcon.toString = () => '._icon'; diff --git a/widget/ui/src/components/Icon/SignatureIcon.tsx b/widget/ui/src/components/Icon/SignatureIcon.tsx deleted file mode 100644 index 8df2f2000b..0000000000 --- a/widget/ui/src/components/Icon/SignatureIcon.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import * as React from 'react'; -import { SvgWithFillColor } from './common'; -import { IconProps } from './types'; - -export const SignatureIcon: React.FC = ({ - size = 16, - color, - ...props -}) => { - return ( - - - - ); -}; - -SignatureIcon.toString = () => '._icon'; diff --git a/widget/ui/src/components/Icon/SwapWalletIcon.tsx b/widget/ui/src/components/Icon/SwapWalletIcon.tsx deleted file mode 100644 index db49c00868..0000000000 --- a/widget/ui/src/components/Icon/SwapWalletIcon.tsx +++ /dev/null @@ -1,50 +0,0 @@ -import * as React from 'react'; -import { SvgWithFillColor } from './common'; -import { IconProps } from './types'; - -export const SwapWalletIcon: React.FC = ({ - size = 16, - color, - ...props -}) => { - return ( - - - - - - - - ); -}; - -SwapWalletIcon.toString = () => '._icon'; diff --git a/widget/ui/src/components/Icon/TimeIcon.tsx b/widget/ui/src/components/Icon/TimeIcon.tsx deleted file mode 100644 index e142ea2c5b..0000000000 --- a/widget/ui/src/components/Icon/TimeIcon.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import * as React from 'react'; -import { SvgWithStrokeColor } from './common'; -import { IconProps } from './types'; - -export const TimeIcon = React.forwardRef( - ({ size = 16, ...props }, forwardedRef) => { - return ( - - - - - ); - } -); - -TimeIcon.toString = () => '._icon'; diff --git a/widget/ui/src/components/Icon/TrashIcon.tsx b/widget/ui/src/components/Icon/TrashIcon.tsx deleted file mode 100644 index f1cb76795f..0000000000 --- a/widget/ui/src/components/Icon/TrashIcon.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import * as React from 'react'; -import { SvgWithStrokeColor } from './common'; -import { IconProps } from './types'; - -export const TrashIcon: React.FC = ({ - size = 16, - color, - ...props -}) => { - return ( - - - - ); -}; - -TrashIcon.toString = () => '._icon'; diff --git a/widget/ui/src/components/Icon/TryAgainIcon.tsx b/widget/ui/src/components/Icon/TryAgainIcon.tsx deleted file mode 100644 index d94da8634c..0000000000 --- a/widget/ui/src/components/Icon/TryAgainIcon.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import * as React from 'react'; -import { SvgWithStrokeColor } from './common'; -import { IconProps } from './types'; - -export const TryAgainIcon: React.FC = ({ - size = 16, - color, - ...props -}) => { - return ( - - - - ); -}; - -TryAgainIcon.toString = () => '._icon'; diff --git a/widget/ui/src/components/Icon/VerticalSwapIcon.tsx b/widget/ui/src/components/Icon/VerticalSwapIcon.tsx deleted file mode 100644 index 43524a70e4..0000000000 --- a/widget/ui/src/components/Icon/VerticalSwapIcon.tsx +++ /dev/null @@ -1,38 +0,0 @@ -import * as React from 'react'; -import { SvgWithStrokeColor } from './common'; -import { IconProps } from './types'; - -export const VerticalSwapIcon: React.FC = ({ - size = 16, - color, - ...props -}) => { - return ( - - - - - ); -}; - -VerticalSwapIcon.toString = () => '._icon'; diff --git a/widget/ui/src/components/Icon/WalletIconIcon.tsx b/widget/ui/src/components/Icon/WalletIconIcon.tsx deleted file mode 100644 index 0898e5c542..0000000000 --- a/widget/ui/src/components/Icon/WalletIconIcon.tsx +++ /dev/null @@ -1,40 +0,0 @@ -import * as React from 'react'; -import { SvgWithFillColor } from './common'; -import { IconProps } from './types'; - -export const WalletIcon: React.FC = ({ - size = 16, - color, - ...props -}) => { - return ( - - - - - - ); -}; - -WalletIcon.toString = () => '._icon'; diff --git a/widget/ui/src/components/Icon/WarningIcon.tsx b/widget/ui/src/components/Icon/WarningIcon.tsx deleted file mode 100644 index 603b019db5..0000000000 --- a/widget/ui/src/components/Icon/WarningIcon.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import * as React from 'react'; -import { IconProps } from './types'; -import { SvgWithStrokeColor } from './common'; - -export const WarningIcon: React.FC = ({ - size = 16, - color, - ...props -}) => { - return ( - - - - - ); -}; - -WarningIcon.toString = () => '._icon'; diff --git a/widget/ui/src/components/Icon/common.ts b/widget/ui/src/components/Icon/common.ts deleted file mode 100644 index c7abf6655b..0000000000 --- a/widget/ui/src/components/Icon/common.ts +++ /dev/null @@ -1,79 +0,0 @@ -import { darkTheme, styled } from '../../theme'; - -export const SvgWithStrokeColor = styled('svg', { - stroke: '$foreground', - variants: { - color: { - primary: { - stroke: '$primary', - }, - error: { - stroke: '$error', - }, - warning: { - stroke: '$warning', - }, - success: { - stroke: '$success', - }, - black: { - $$color: '$colors$foreground', - [`.${darkTheme} &`]: { - $$color: '$colors$background', - }, - stroke: '$$color', - }, - white: { - $$color: '$colors$background', - [`.${darkTheme} &`]: { - $$color: '$colors$foreground', - }, - stroke: '$$color', - }, - }, - disabled: { - true: { - stroke: '$neutrals400', - }, - }, - }, -}); - -export const SvgWithFillColor = styled('svg', { - fill: '$foreground', - variants: { - color: { - primary: { - fill: '$primary', - }, - error: { - fill: '$error', - }, - warning: { - fill: '$warning', - }, - success: { - fill: '$success', - }, - black: { - $$color: '$colors$foreground', - [`.${darkTheme} &`]: { - $$color: '$colors$background', - }, - fill: '$$color', - }, - white: { - $$color: '$colors$background', - [`.${darkTheme} &`]: { - $$color: '$colors$foreground', - }, - fill: '$$color', - }, - }, - disabled: { - true: { - stroke: '$neutrals400', - }, - }, - }, -}); diff --git a/widget/ui/src/components/Icon/index.ts b/widget/ui/src/components/Icon/index.ts deleted file mode 100644 index bf64e0b4bc..0000000000 --- a/widget/ui/src/components/Icon/index.ts +++ /dev/null @@ -1,48 +0,0 @@ -export { DeleteCircleIcon } from './DeleteCircleIcon'; -export { CheckSquareIcon } from './CheckSquareIcon'; -export { AddIcon } from './AddIcon'; -export { InfoCircleIcon } from './InfoCircleIcon'; -export { AddCircleIcon } from './AddCircleIcon'; -export { MinusCircleIcon } from './MinusCircleIcon'; -export { CheckCircleIcon } from './CheckCircleIcon'; -export { CheckIcon } from './CheckIcon'; - -export { BanIcon } from './BanIcon'; -export { WarningIcon } from './WarningIcon'; - -export { HistoryIcon } from './HistoryIcon'; -export { GasIcon } from './GasIcon'; -export { SettingsIcon } from './SettingIcon'; -export { TrashIcon } from './TrashIcon'; - -export { SearchMinusIcon } from './SearchMinusIcon'; -export { SearchIcon } from './SearchIcon'; - -export { AngleRightIcon } from './AngleRightIcon'; -export { AngleUpIcon } from './AngleUpIcon'; -export { AngleDownIcon } from './AngleDownIcon'; -export { AngleLeftIcon } from './AngleLeftIcon'; -export { DownloadIcon } from './DownloadIcon'; -export { ChevronRightIcon } from './ChevronRightIcon'; -export { ArrowRightIcon } from './ArrowRightIcon'; - -export { RetryRightIcon } from './RetryRightIcon'; -export { RetryLeftIcon } from './RetryLeftIcon'; -export { TryAgainIcon } from './TryAgainIcon'; -export { VerticalSwapIcon } from './VerticalSwapIcon'; -export { HorizontalSwapIcon } from './HorizontalSwapIcon'; -export { RetryIcon } from './RetryIcon'; - -export { WalletIcon } from './WalletIconIcon'; -export { AddWalletIcon } from './AddWalletIcon'; -export { DeleteWalletIcon } from './DeleteWalletIcon'; -export { CheckWalletIcon } from './CheckWalletIcon'; -export { SwapWalletIcon } from './SwapWalletIcon'; -export { DisconnectIcon } from './DisconnectIcon'; - -export { BagIcon } from './BagIcon'; - -export { TimeIcon } from './TimeIcon'; -export { CloseIcon } from './CloseIcon'; -export { SignatureIcon } from './SignatureIcon'; -export { CopyIcon } from './CopyIcon'; diff --git a/widget/ui/src/components/Icon/types.tsx b/widget/ui/src/components/Icon/types.tsx deleted file mode 100644 index 952a0661a7..0000000000 --- a/widget/ui/src/components/Icon/types.tsx +++ /dev/null @@ -1,46 +0,0 @@ -import * as React from 'react'; - -export interface IconProps extends React.SVGAttributes { - size?: 12 | 16 | 18 | 20 | 24 | 28 | 32 | 36 | 40; - color?: 'primary' | 'error' | 'warning' | 'success' | 'black' | 'white'; - disabled?: boolean; -} - -export type Icon = - | 'DeleteCircleIcon' - | 'CheckSquareIcon' - | 'AddIcon' - | 'InfoCircleIcon' - | 'AddCircleIcon' - | 'MinusCircleIcon' - | 'CheckCircleIcon' - | 'CheckIcon' - | 'BanIcon' - | 'WarningIcon' - | 'HistoryIcon' - | 'GasIcon' - | 'SettingsIcon' - | 'TrashIcon' - | 'SearchMinusIcon' - | 'SearchIcon' - | 'AngleRightIcon' - | 'AngleUpIcon' - | 'AngleDownIcon' - | 'AngleLeftIcon' - | 'DownloadIcon' - | 'RetryRightIcon' - | 'RetryLeftIcon' - | 'TryAgainIcon' - | 'VerticalSwapIcon' - | 'HorizontalSwapIcon' - | 'RetryIcon' - | 'WalletIcon' - | 'AddWalletIcon' - | 'DeleteWalletIcon' - | 'CheckWalletIcon' - | 'SwapWalletIcon' - | 'BagIcon' - | 'TimeIcon' - | 'CloseIcon' - | 'SignatureIcon' - | 'CopyIcon'; diff --git a/widget/ui/src/components/IconButton/IconButton.tsx b/widget/ui/src/components/IconButton/IconButton.tsx new file mode 100644 index 0000000000..6c0a709ea7 --- /dev/null +++ b/widget/ui/src/components/IconButton/IconButton.tsx @@ -0,0 +1,33 @@ +import type { IconButtonPropTypes } from './IconButton.types.js'; +import type { PropsWithChildren, Ref } from 'react'; + +import React from 'react'; + +import { Button } from '../Button/index.js'; + +// border-radius: 100% + overflow: hidden +function IconButtonComponent( + props: PropsWithChildren, + ref: Ref +) { + const { style, ...otherProps } = props; + return ( + + ); +} + +const IconButton = React.forwardRef(IconButtonComponent); +IconButton.displayName = 'IconButton'; +IconButton.toString = () => '._icon-button'; + +export { IconButton }; diff --git a/widget/ui/src/components/IconButton/IconButton.types.ts b/widget/ui/src/components/IconButton/IconButton.types.ts new file mode 100644 index 0000000000..c66c7ca006 --- /dev/null +++ b/widget/ui/src/components/IconButton/IconButton.types.ts @@ -0,0 +1,13 @@ +import type { ButtonPropTypes } from '../Button/Button.types.js'; +import type { CSSProperties } from 'react'; + +export type IconButtonPropTypes = { + id?: ButtonPropTypes['id']; + size?: ButtonPropTypes['size']; + type?: ButtonPropTypes['type']; + variant?: ButtonPropTypes['variant']; + onClick?: ButtonPropTypes['onClick']; + style?: CSSProperties; + loading?: boolean; + disabled?: boolean; +}; diff --git a/widget/ui/src/components/IconButton/index.ts b/widget/ui/src/components/IconButton/index.ts new file mode 100644 index 0000000000..0e2f0f05ec --- /dev/null +++ b/widget/ui/src/components/IconButton/index.ts @@ -0,0 +1,2 @@ +export { IconButton } from './IconButton.js'; +export type { IconButtonPropTypes } from './IconButton.types.js'; diff --git a/widget/ui/src/components/LiquiditySourceList/LiquiditySource.stories.tsx b/widget/ui/src/components/LiquiditySourceList/LiquiditySource.stories.tsx deleted file mode 100644 index fcbc7a90ae..0000000000 --- a/widget/ui/src/components/LiquiditySourceList/LiquiditySource.stories.tsx +++ /dev/null @@ -1,13 +0,0 @@ -import React from 'react'; -import { ComponentMeta } from '@storybook/react'; -import { LiquiditySourceList, PropTypes } from './LiquiditySourceList'; -import { liquiditySources } from './mockData'; - -export default { - title: 'Liquidity Source List', - component: LiquiditySourceList, -} as ComponentMeta; - -export const Main = (args: PropTypes) => ( - -); diff --git a/widget/ui/src/components/LiquiditySourceList/LiquiditySourceList.tsx b/widget/ui/src/components/LiquiditySourceList/LiquiditySourceList.tsx deleted file mode 100644 index 92dd0c8f51..0000000000 --- a/widget/ui/src/components/LiquiditySourceList/LiquiditySourceList.tsx +++ /dev/null @@ -1,199 +0,0 @@ -import { CSSProperties } from '@stitches/react'; -import React, { useEffect, useState } from 'react'; -import { styled } from '../../theme'; -import { LiquiditySource, LoadingStatus } from '../../types/meta'; -import { Button } from '../Button/Button'; -import { Spacer } from '../Spacer'; -import { Switch } from '../Switch'; -import { Typography } from '../Typography'; -import { Spinner } from '../Spinner'; -import { LoadingFailedAlert } from '../Alert/LoadingFailedAlert'; -import { NotFoundAlert } from '../Alert/NotFoundAlert'; -import { Image } from '../common'; - -const groupLiquiditySources = ( - liquiditySources: LiquiditySource[] -): { [key in 'bridge' | 'exchange']: LiquiditySource[] } => ({ - bridge: liquiditySources.filter( - (liquiditySource) => - liquiditySource.type === 'BRIDGE' || liquiditySource.type === 'AGGREGATOR' - ), - exchange: liquiditySources.filter( - (liquiditySource) => liquiditySource.type === 'DEX' - ), -}); - -const MainContainer = styled('div', { - variants: { - loaded: { - true: { - overflowY: 'auto', - padding: '0 $4', - }, - }, - }, -}); - -const LiquiditySourceType = styled('div', { - position: 'sticky', - display: 'flex', - justifyContent: 'space-between', - alignItems: 'center', - top: '0', - backgroundColor: '$background', - zIndex: '9999', - paddingTop: '$8', - paddingBottom: '$8', -}); - -const LiquidityImageContainer = styled('div', { - paddingRight: '$16', -}); - -const LoaderContainer = styled('div', { - display: 'flex', - justifyContent: 'center', -}); - -export interface PropTypes { - list: LiquiditySource[]; - onChange: (liquiditySource: LiquiditySource) => void; - listContainerStyle?: CSSProperties; - loadingStatus: LoadingStatus; - searchedFor: string; -} - -export function LiquiditySourceList(props: PropTypes) { - const { list, onChange, listContainerStyle, loadingStatus, searchedFor } = - props; - - const [selected, setSelected] = useState( - list.filter((item) => item.selected) - ); - - const changeLiquiditySources = (clickedItem: LiquiditySource) => { - clickedItem.selected = !clickedItem.selected; - setSelected((prevState) => { - if (clickedItem.selected) return [...prevState, clickedItem]; - return prevState.filter((item) => item.title != clickedItem.title); - }); - onChange(clickedItem); - }; - - const isSelected = (liquiditySource: LiquiditySource) => - !!selected.find((item) => liquiditySource.title === item.title); - - useEffect(() => { - setSelected(list.filter((item) => item.selected)); - }, [list]); - - const sections = groupLiquiditySources(list); - const bridges = sections.bridge; - const exchanges = sections.exchange; - - const totalBridges = bridges.length; - const totalExchanges = exchanges.length; - // TODO: This is not performant - const totalSelectedBridges = bridges.filter(isSelected).length; - const totalSelectedExchanges = exchanges.filter(isSelected).length; - - return ( - -
- - Bridges - - {totalSelectedBridges === totalBridges - ? totalBridges - : `${totalSelectedBridges} / ${totalBridges}`} - - - - {loadingStatus === 'loading' && ( - - - - )} - {loadingStatus === 'failed' && } - {loadingStatus === 'success' && ( - <> - {totalBridges ? ( - bridges.map((liquiditySource, index) => ( - - )) - ) : ( - - )} - - )} -
-
- - Exchanges - - {totalSelectedExchanges === totalExchanges - ? totalExchanges - : `${totalSelectedExchanges} / ${totalExchanges}`} - - - - {loadingStatus === 'loading' && ( - - - - )} - {loadingStatus === 'failed' && } - {loadingStatus == 'success' && ( - <> - {totalExchanges ? ( - exchanges.map((liquiditySource, index) => ( - - )) - ) : ( - - )} - - )} -
-
- ); -} - -const LiquiditySourceItem = ({ - liquiditySource, - selected, - onChange, -}: { - liquiditySource: LiquiditySource; - selected: boolean; - onChange: (clickedItem: LiquiditySource) => void; -}) => ( - -); diff --git a/widget/ui/src/components/LiquiditySourceList/index.ts b/widget/ui/src/components/LiquiditySourceList/index.ts deleted file mode 100644 index 7ca2b7cd00..0000000000 --- a/widget/ui/src/components/LiquiditySourceList/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { LiquiditySourceList } from './LiquiditySourceList'; diff --git a/widget/ui/src/components/LiquiditySourceList/mockData.ts b/widget/ui/src/components/LiquiditySourceList/mockData.ts deleted file mode 100644 index a0ca5001ac..0000000000 --- a/widget/ui/src/components/LiquiditySourceList/mockData.ts +++ /dev/null @@ -1,316 +0,0 @@ -import { LiquiditySource } from '../../types/meta'; - -export const liquiditySources: LiquiditySource[] = [ - { - title: 'Pancake', - logo: 'https://api.rango.exchange/swappers/pancake-swap.png', - type: 'DEX', - selected: true, - }, - { - title: 'ThorChain', - logo: 'https://api.rango.exchange/swappers/Thorchain.svg', - type: 'BRIDGE', - selected: true, - }, - { - title: 'Horizon Bridge', - logo: 'https://api.rango.exchange/swappers/harmony-horizon.svg', - type: 'BRIDGE', - selected: true, - }, - { - title: '1Inch', - logo: 'https://api.rango.exchange/swappers/1inch.svg', - type: 'DEX', - selected: true, - }, - { - title: 'OpenOcean', - logo: 'https://api.rango.exchange/swappers/openocean.svg', - type: 'DEX', - selected: true, - }, - { - title: 'SushiSwap', - logo: 'https://api.rango.exchange/swappers/sushi.png', - type: 'DEX', - selected: true, - }, - { - title: 'OkcSwap', - logo: 'https://api.rango.exchange/swappers/okcswap.png', - type: 'DEX', - selected: true, - }, - { - title: 'CherrySwap', - logo: 'https://api.rango.exchange/swappers/cherry-swap.png', - type: 'DEX', - selected: true, - }, - { - title: 'Osmosis', - logo: 'https://api.rango.exchange/swappers/osmosis.png', - type: 'DEX', - selected: true, - }, - { - title: 'Osmosis', - logo: 'https://api.rango.exchange/swappers/osmosis.png', - type: 'BRIDGE', - selected: true, - }, - { - title: 'SolanaWrapper', - logo: 'https://api.rango.exchange/tokens/SOLANA/SOL.png', - type: 'DEX', - selected: true, - }, - { - title: 'Jupiter', - logo: 'https://api.rango.exchange/swappers/jupiter.svg', - type: 'DEX', - selected: true, - }, - { - title: 'stargate', - logo: 'https://api.rango.exchange/swappers/stargate.svg', - type: 'BRIDGE', - selected: true, - }, - { - title: 'Multichain', - logo: 'https://api.rango.exchange/swappers/multichain.png', - type: 'BRIDGE', - selected: true, - }, - { - title: 'Satellite', - logo: 'https://api.rango.exchange/swappers/satellite.png', - type: 'BRIDGE', - selected: true, - }, - { - title: 'Diffusion', - logo: 'https://api.rango.exchange/swappers/diffusion.png', - type: 'DEX', - selected: true, - }, - { - title: 'JunoSwap', - logo: 'https://api.rango.exchange/swappers/junoswap.svg', - type: 'BRIDGE', - selected: true, - }, - { - title: 'JunoSwap', - logo: 'https://api.rango.exchange/swappers/junoswap.svg', - type: 'DEX', - selected: true, - }, - { - title: 'PangolinSwap', - logo: 'https://api.rango.exchange/swappers/pangolin.png', - type: 'DEX', - selected: true, - }, - { - title: 'MMFinance', - logo: 'https://api.rango.exchange/swappers/mm-finance.png', - type: 'DEX', - selected: true, - }, - { - title: 'CronaSwap', - logo: 'https://api.rango.exchange/swappers/crona.png', - type: 'DEX', - selected: true, - }, - { - title: 'VVSFinance', - logo: 'https://api.rango.exchange/swappers/vvs-finance.svg', - type: 'DEX', - selected: true, - }, - { - title: 'MDexHeco', - logo: 'https://api.rango.exchange/swappers/mdex.png', - type: 'DEX', - selected: true, - }, - { - title: 'ParaSwap', - logo: 'https://api.rango.exchange/swappers/para-swap.png', - type: 'DEX', - selected: true, - }, - { - title: 'AuroraSwap', - logo: 'https://api.rango.exchange/swappers/aurora-swap.png', - type: 'DEX', - selected: true, - }, - { - title: 'Across', - logo: 'https://api.rango.exchange/swappers/across.png', - type: 'BRIDGE', - selected: true, - }, - { - title: 'Arbitrum Bridge', - logo: 'https://api.rango.exchange/swappers/arbitrum-bridge.svg', - type: 'BRIDGE', - selected: true, - }, - { - title: 'TrisolarisSwap', - logo: 'https://api.rango.exchange/swappers/trisolaris.svg', - type: 'DEX', - selected: true, - }, - { - title: 'Polygon Bridge', - logo: 'https://api.rango.exchange/swappers/polygon-bridge.png', - type: 'BRIDGE', - selected: true, - }, - { - title: 'SpookySwap', - logo: 'https://api.rango.exchange/swappers/spooky-swap.png', - type: 'DEX', - selected: true, - }, - { - title: 'Voyager', - logo: 'https://api.rango.exchange/swappers/voyager.svg', - type: 'BRIDGE', - selected: true, - }, - { - title: 'Rainbow Bridge', - logo: 'https://api.rango.exchange/swappers/rainbow-bridge.svg', - type: 'BRIDGE', - selected: true, - }, - { - title: 'Lido', - logo: 'https://api.rango.exchange/swappers/lido.png', - type: 'BRIDGE', - selected: true, - }, - { - title: 'Symbiosis', - logo: 'https://api.rango.exchange/swappers/symbiosis.png', - type: 'BRIDGE', - selected: true, - }, - { - title: 'Avalanche Bridge', - logo: 'https://api.rango.exchange/swappers/avalanche-bridge.png', - type: 'BRIDGE', - selected: true, - }, - { - title: 'VoltageSwap', - logo: 'https://api.rango.exchange/swappers/voltage.png', - type: 'DEX', - selected: true, - }, - { - title: 'XYFinance', - logo: 'https://api.rango.exchange/swappers/xy.png', - type: 'BRIDGE', - selected: true, - }, - { - title: 'cBridge v2.0', - logo: 'https://api.rango.exchange/swappers/cbridge.png', - type: 'AGGREGATOR', - selected: true, - }, - { - title: 'Hyphen', - logo: 'https://api.rango.exchange/swappers/hyphen.svg', - type: 'AGGREGATOR', - selected: true, - }, - { - title: 'Optimism Bridge', - logo: 'https://api.rango.exchange/swappers/optimism.svg', - type: 'BRIDGE', - selected: true, - }, - { - title: 'OolongSwap', - logo: 'https://api.rango.exchange/swappers/oolong.png', - type: 'DEX', - selected: true, - }, - { - title: 'QuickSwap', - logo: 'https://api.rango.exchange/swappers/quick-swap.png', - type: 'DEX', - selected: true, - }, - { - title: 'StellaSwap', - logo: 'https://api.rango.exchange/swappers/stella.png', - type: 'DEX', - selected: true, - }, - { - title: 'ViperSwap', - logo: 'https://api.rango.exchange/swappers/viper.png', - type: 'DEX', - selected: true, - }, - { - title: 'FinKujira', - logo: 'https://api.rango.exchange/swappers/finkujira.png', - type: 'DEX', - selected: true, - }, - { - title: 'Hop', - logo: 'https://api.rango.exchange/swappers/hop.svg', - type: 'BRIDGE', - selected: true, - }, - { - title: 'BeamSwap', - logo: 'https://api.rango.exchange/swappers/beam-swap.png', - type: 'DEX', - selected: true, - }, - { - title: 'SolarbeamSwap', - logo: 'https://api.rango.exchange/swappers/solarbeamlogo.png', - type: 'DEX', - selected: true, - }, - { - title: 'Sifchain', - logo: 'https://api.rango.exchange/swappers/sifchain.png', - type: 'BRIDGE', - selected: true, - }, - { - title: 'Sifchain', - logo: 'https://api.rango.exchange/swappers/sifchain.png', - type: 'DEX', - selected: true, - }, - { - title: 'Wormhole', - logo: 'https://api.rango.exchange/swappers/wormhole.png', - type: 'BRIDGE', - selected: true, - }, - { - title: 'UniSwapV2', - logo: 'https://api.rango.exchange/swappers/uniswap.png', - type: 'DEX', - selected: true, - }, -]; diff --git a/widget/ui/src/components/LiquiditySourcesSelector/LiquiditySourcesSelector.stories.tsx b/widget/ui/src/components/LiquiditySourcesSelector/LiquiditySourcesSelector.stories.tsx deleted file mode 100644 index eee19335a6..0000000000 --- a/widget/ui/src/components/LiquiditySourcesSelector/LiquiditySourcesSelector.stories.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import React from 'react'; -import { ComponentMeta } from '@storybook/react'; -import { - LiquiditySourcesSelector, - PropTypes, -} from './LiquiditySourcesSelector'; -import { liquiditySources } from '../LiquiditySourceList/mockData'; - -export default { - title: 'Liquidity Sources Selector', - component: LiquiditySourcesSelector, -} as ComponentMeta; - -export const Main = (args: PropTypes) => ( - -); diff --git a/widget/ui/src/components/LiquiditySourcesSelector/LiquiditySourcesSelector.tsx b/widget/ui/src/components/LiquiditySourcesSelector/LiquiditySourcesSelector.tsx deleted file mode 100644 index 806c1e79e7..0000000000 --- a/widget/ui/src/components/LiquiditySourcesSelector/LiquiditySourcesSelector.tsx +++ /dev/null @@ -1,61 +0,0 @@ -import { CSSProperties } from '@stitches/react'; -import React from 'react'; -import { containsText } from '../../helper'; -import { LiquiditySource, LoadingStatus } from '../../types/meta'; -import { Button } from '../Button'; -import { LiquiditySourceList } from '../LiquiditySourceList'; -import { SecondaryPage } from '../SecondaryPage/SecondaryPage'; - -const filterLiquiditySources = ( - liquiditySources: LiquiditySource[], - searchedFor: string -) => - liquiditySources.filter((liquiditySource) => - containsText(liquiditySource.title, searchedFor || '') - ); -export interface PropTypes { - list: LiquiditySource[]; - onChange: (liquiditySource: LiquiditySource) => void; - toggleAll?: () => void; - onBack?: () => void; - hasHeader?: boolean; - listContainerStyle?: CSSProperties; - loadingStatus: LoadingStatus; -} - -export function LiquiditySourcesSelector(props: PropTypes) { - const { - list, - onChange, - onBack, - hasHeader, - listContainerStyle, - toggleAll, - loadingStatus, - } = props; - - return ( - - {list.find((item) => item.selected) ? 'Deselect all' : 'Select all'} - - } - hasHeader={hasHeader} - onBack={onBack} - > - {(searchedFor) => ( - - )} - - ); -} diff --git a/widget/ui/src/components/LiquiditySourcesSelector/index.ts b/widget/ui/src/components/LiquiditySourcesSelector/index.ts deleted file mode 100644 index ed7ee352b7..0000000000 --- a/widget/ui/src/components/LiquiditySourcesSelector/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { LiquiditySourcesSelector } from './LiquiditySourcesSelector'; diff --git a/widget/ui/src/components/List/List.styles.tsx b/widget/ui/src/components/List/List.styles.tsx new file mode 100644 index 0000000000..05fefa4cd1 --- /dev/null +++ b/widget/ui/src/components/List/List.styles.tsx @@ -0,0 +1,7 @@ +import { styled } from '../../theme.js'; + +export const BaseList = styled('ul', { + padding: 0, + margin: 0, + listStyle: 'none', +}); diff --git a/widget/ui/src/components/List/List.tsx b/widget/ui/src/components/List/List.tsx new file mode 100644 index 0000000000..dc7d9f67ac --- /dev/null +++ b/widget/ui/src/components/List/List.tsx @@ -0,0 +1,29 @@ +import type { ListPropTypes } from './List.types.js'; + +import React from 'react'; + +import { ListItem } from '../ListItem/index.js'; + +import { BaseList } from './List.styles.js'; + +function List(props: ListPropTypes) { + return ( + + {props.items.map((item) => { + const { id, type, ...itemProps } = item; + const container = type || props.type; + + if (!!container) { + return React.cloneElement(container, { + ...itemProps, + key: id, + id, + }); + } + return ; + })} + + ); +} + +export { List }; diff --git a/widget/ui/src/components/List/List.types.ts b/widget/ui/src/components/List/List.types.ts new file mode 100644 index 0000000000..e72793cc1f --- /dev/null +++ b/widget/ui/src/components/List/List.types.ts @@ -0,0 +1,13 @@ +import type { ListItemPropTypes } from '../ListItem/index.js'; +import type * as Stitches from '@stitches/react'; +import type React from 'react'; + +export interface ListPropTypes { + type?: React.ReactElement; + items: (ListItemPropTypes & { + id: string; + type?: React.ReactElement; + })[]; + as?: 'div' | 'ul'; + css?: Stitches.CSS; +} diff --git a/widget/ui/src/components/List/index.ts b/widget/ui/src/components/List/index.ts new file mode 100644 index 0000000000..a1a67e05e0 --- /dev/null +++ b/widget/ui/src/components/List/index.ts @@ -0,0 +1,2 @@ +export { List } from './List.js'; +export type { ListPropTypes } from './List.types.js'; diff --git a/widget/ui/src/components/ListItem/ListItem.styles.ts b/widget/ui/src/components/ListItem/ListItem.styles.ts new file mode 100644 index 0000000000..156cf91538 --- /dev/null +++ b/widget/ui/src/components/ListItem/ListItem.styles.ts @@ -0,0 +1,62 @@ +import { darkTheme, styled } from '../../theme.js'; + +export const BaseListItem = styled('li', { + width: '100%', + overflow: 'hidden', + borderRadius: '$xs', + display: 'flex', + alignItems: 'center', + padding: '$10 $5', + border: 0, + backgroundColor: 'transparent', + + '.item-start-container': { + paddingRight: '$10', + flexShrink: 0, + + '& svg': { + display: 'block', + }, + }, + '.item-text-container': { + flexGrow: 1, + flexShrink: 1, + flexBasis: 'auto', + textAlign: 'left', + '._description': { + $$color: '$colors$neutral600', + [`.${darkTheme} &`]: { + $$color: '$colors$neutral700', + }, + color: '$$color', + }, + + '.item-text-title': { + fontWeight: 'bold', + display: 'flex', + alignItems: 'center', + color: '$foreground', + }, + }, + '.item-end-container': { + display: 'flex', + justifyContent: 'center', + alignItems: 'center', + paddingLeft: '$10', + overflow: 'hidden', + flexShrink: 0, + }, + variants: { + hasDivider: { + true: { + borderBottom: '1px solid', + borderColor: '$neutral300', + [`.${darkTheme} &`]: { + borderColor: '$neutral400', + }, + borderBottomRightRadius: 0, + borderBottomLeftRadius: 0, + }, + }, + }, +}); diff --git a/widget/ui/src/components/ListItem/ListItem.tsx b/widget/ui/src/components/ListItem/ListItem.tsx new file mode 100644 index 0000000000..29e43d3828 --- /dev/null +++ b/widget/ui/src/components/ListItem/ListItem.tsx @@ -0,0 +1,29 @@ +import type { ListItemPropTypes } from './ListItem.types.js'; + +import React from 'react'; + +import { Typography } from '../Typography/index.js'; + +import { BaseListItem } from './ListItem.styles.js'; + +function ListItem(props: ListItemPropTypes) { + const { start, title, description, end, onClick, hasDivider, ...restProps } = + props; + + return ( + + {start &&
{start}
} +
+ {title &&
{title}
} + {description && ( + + {description} + + )} +
+ {end &&
{end}
} +
+ ); +} + +export { ListItem }; diff --git a/widget/ui/src/components/ListItem/ListItem.types.ts b/widget/ui/src/components/ListItem/ListItem.types.ts new file mode 100644 index 0000000000..cf64dc93f7 --- /dev/null +++ b/widget/ui/src/components/ListItem/ListItem.types.ts @@ -0,0 +1,13 @@ +export type ListItemPropTypes = { + id?: string; + title?: string | React.ReactElement; + description?: string | React.ReactElement; + start?: React.ReactNode; + end?: React.ReactNode; + as?: 'div' | 'li'; + onClick?: () => void; + onKeyUp?: React.KeyboardEventHandler; + hasDivider?: boolean; + tabIndex?: number; + className?: string; +}; diff --git a/widget/ui/src/components/ListItem/index.ts b/widget/ui/src/components/ListItem/index.ts new file mode 100644 index 0000000000..d275065b88 --- /dev/null +++ b/widget/ui/src/components/ListItem/index.ts @@ -0,0 +1,2 @@ +export type { ListItemPropTypes } from './ListItem.types.js'; +export { ListItem } from './ListItem.js'; diff --git a/widget/ui/src/components/ListItemButton/ListItemButton.styles.ts b/widget/ui/src/components/ListItemButton/ListItemButton.styles.ts new file mode 100644 index 0000000000..3c66de8222 --- /dev/null +++ b/widget/ui/src/components/ListItemButton/ListItemButton.styles.ts @@ -0,0 +1,36 @@ +import { darkTheme, styled } from '../../theme.js'; +import { ListItem } from '../ListItem/ListItem.js'; + +export const BaseListItemButton = styled(ListItem, { + transition: 'all 0.35s', + '&:hover': { + borderRadius: '$xs', + $$color: '$colors$secondary100', + [`.${darkTheme} &`]: { + $$color: '$colors$neutral100', + }, + backgroundColor: '$$color', + cursor: 'pointer', + }, + '&:active': { + transform: 'scale(0.99)', + }, + + '&:focus-visible': { + borderRadius: '$xs', + + outline: 0, + $$color: '$colors$secondary100', + [`.${darkTheme} &`]: { + $$color: '$colors$info700', + }, + backgroundColor: '$$color', + }, + + variants: { + selected: { + true: { outline: '1px solid $secondary500' }, + false: { outline: 0 }, + }, + }, +}); diff --git a/widget/ui/src/components/ListItemButton/ListItemButton.tsx b/widget/ui/src/components/ListItemButton/ListItemButton.tsx new file mode 100644 index 0000000000..018d99413b --- /dev/null +++ b/widget/ui/src/components/ListItemButton/ListItemButton.tsx @@ -0,0 +1,30 @@ +import type { ListItemButtonProps } from './ListItemButton.types.js'; + +import React from 'react'; + +import { BaseListItemButton } from './ListItemButton.styles.js'; + +function ListItemButton(props: ListItemButtonProps) { + const { onClick, id, selected, ...restProps } = props; + const onClickWithKey = () => { + if (onClick) { + onClick(id); + } + }; + + return ( + { + e.key === 'Enter' && onClickWithKey(); + }} + tabIndex={0} + {...restProps} + /> + ); +} + +export { ListItemButton }; diff --git a/widget/ui/src/components/ListItemButton/ListItemButton.types.ts b/widget/ui/src/components/ListItemButton/ListItemButton.types.ts new file mode 100644 index 0000000000..b2adb24087 --- /dev/null +++ b/widget/ui/src/components/ListItemButton/ListItemButton.types.ts @@ -0,0 +1,9 @@ +import type { ListItemPropTypes } from '../ListItem/index.js'; +import type { CSSProperties } from '@stitches/react'; + +export type ListItemButtonProps = Omit & { + id: string; + onClick: (id: string) => void; + style?: CSSProperties; + selected?: boolean; +}; diff --git a/widget/ui/src/components/ListItemButton/index.ts b/widget/ui/src/components/ListItemButton/index.ts new file mode 100644 index 0000000000..12f47f84ec --- /dev/null +++ b/widget/ui/src/components/ListItemButton/index.ts @@ -0,0 +1,2 @@ +export type { ListItemButtonProps } from './ListItemButton.types.js'; +export { ListItemButton } from './ListItemButton.js'; diff --git a/widget/ui/src/components/Logo/Logo.tsx b/widget/ui/src/components/Logo/Logo.tsx new file mode 100644 index 0000000000..b7092dbca6 --- /dev/null +++ b/widget/ui/src/components/Logo/Logo.tsx @@ -0,0 +1,35 @@ +import type { SvgIconProps } from '../SvgIcon/index.js'; + +import React from 'react'; + +import { SvgWithColor } from '../SvgIcon/SvgIcon.style.js'; + +export function Logo(props: SvgIconProps) { + const { size = '1em', color } = props; + const commonProps = { + width: size, + height: size, + color: color, + className: '_icon', + }; + return ( + + + + + + + + ); +} diff --git a/widget/ui/src/components/Logo/index.tsx b/widget/ui/src/components/Logo/index.tsx new file mode 100644 index 0000000000..ed7a8bcbd7 --- /dev/null +++ b/widget/ui/src/components/Logo/index.tsx @@ -0,0 +1 @@ +export { Logo } from './Logo.js'; diff --git a/widget/ui/src/components/MessageBox/CollapsibleMessageBox.styles.tsx b/widget/ui/src/components/MessageBox/CollapsibleMessageBox.styles.tsx new file mode 100644 index 0000000000..81edc3333c --- /dev/null +++ b/widget/ui/src/components/MessageBox/CollapsibleMessageBox.styles.tsx @@ -0,0 +1,33 @@ +import * as Collapsible from '@radix-ui/react-collapsible'; + +import { darkTheme, styled } from '../../theme.js'; + +export const Trigger = styled(Collapsible.Trigger, { + padding: '$15', + paddingBottom: '$5', + borderRadius: '$xm', + cursor: 'pointer', + $$backgroundColor: '$colors$neutral200', + [`.${darkTheme} &`]: { + $$backgroundColor: '$colors$neutral500', + }, + backgroundColor: '$$backgroundColor', + textAlign: 'center', + border: 0, + width: '100%', + '&:hover': { + $$color: '$colors$secondary100', + [`.${darkTheme} &`]: { + $$color: '$colors$neutral100', + }, + backgroundColor: '$$color', + }, + '&:focus-visible': { + $$color: '$colors$secondary100', + [`.${darkTheme} &`]: { + $$color: '$colors$info700', + }, + backgroundColor: '$$color', + outline: 0, + }, +}); diff --git a/widget/ui/src/components/MessageBox/CollapsibleMessageBox.tsx b/widget/ui/src/components/MessageBox/CollapsibleMessageBox.tsx new file mode 100644 index 0000000000..fe987153b3 --- /dev/null +++ b/widget/ui/src/components/MessageBox/CollapsibleMessageBox.tsx @@ -0,0 +1,38 @@ +import type { PropTypes } from './CollapsibleMessageBox.types.js'; +import type { PropsWithChildren } from 'react'; + +import * as Collapsible from '@radix-ui/react-collapsible'; +import React, { useState } from 'react'; + +import { ChevronDownIcon, ChevronUpIcon } from '../../icons/index.js'; +import { CollapsibleContent } from '../common/styles.js'; +import { Divider } from '../Divider/index.js'; + +import { Trigger } from './CollapsibleMessageBox.styles.js'; + +import { MessageBox } from './index.js'; + +export function CollapsibleMessageBox(props: PropsWithChildren) { + const { description, status, title, children } = props; + const [open, setOpen] = useState(false); + + return ( + + + + + + + {children} + + + + {open ? ( + + ) : ( + + )} + + + ); +} diff --git a/widget/ui/src/components/MessageBox/CollapsibleMessageBox.types.tsx b/widget/ui/src/components/MessageBox/CollapsibleMessageBox.types.tsx new file mode 100644 index 0000000000..0c680a3228 --- /dev/null +++ b/widget/ui/src/components/MessageBox/CollapsibleMessageBox.types.tsx @@ -0,0 +1,11 @@ +import type { IconHighlight } from './MessageBox.styles.js'; +import type * as Stitches from '@stitches/react'; + +type BaseProps = Stitches.VariantProps; +type BaseTypes = Exclude; + +export interface PropTypes { + title: string; + description: string; + status: BaseTypes; +} diff --git a/widget/ui/src/components/MessageBox/DefaultMessageBox.tsx b/widget/ui/src/components/MessageBox/DefaultMessageBox.tsx new file mode 100644 index 0000000000..fe155f19c3 --- /dev/null +++ b/widget/ui/src/components/MessageBox/DefaultMessageBox.tsx @@ -0,0 +1,40 @@ +import type { PropTypes } from './MessageBox.types.js'; +import type { PropsWithChildren } from 'react'; + +import React from 'react'; + +import { Divider } from '../Divider/index.js'; +import { Typography } from '../Typography/index.js'; + +import { Container, Description, IconHighlight } from './MessageBox.styles.js'; +import StatusIcon from './StatusIcon.js'; + +export function MessageBox(props: PropsWithChildren) { + const { type, title, description, children, icon } = props; + + return ( + + + {icon || } + + + + {title} + + + + {typeof description === 'string' ? ( + + {description} + + ) : ( + description + )} + + {children} + + ); +} diff --git a/widget/ui/src/components/MessageBox/MessageBox.styles.tsx b/widget/ui/src/components/MessageBox/MessageBox.styles.tsx new file mode 100644 index 0000000000..4d133bb41a --- /dev/null +++ b/widget/ui/src/components/MessageBox/MessageBox.styles.tsx @@ -0,0 +1,61 @@ +import { darkTheme, styled } from '../../theme.js'; + +export const Container = styled('div', { + display: 'flex', + flexDirection: 'column', + alignItems: 'center', + width: '100%', +}); + +export const Description = styled('div', { + width: '100%', + textAlign: 'center', +}); + +export const IconHighlight = styled('div', { + borderRadius: '50%', + width: '$45', + height: '$45', + display: 'flex', + justifyContent: 'center', + alignItems: 'center', + variants: { + type: { + success: { + $$color: '$colors$success300', + [`.${darkTheme} &`]: { + $$color: '$colors$success600', + }, + backgroundColor: '$$color', + }, + warning: { + $$color: '$colors$warning300', + [`.${darkTheme} &`]: { + $$color: '$colors$warning600', + }, + backgroundColor: '$$color', + }, + error: { + $$color: '$colors$error300', + [`.${darkTheme} &`]: { + $$color: '$colors$error600', + }, + backgroundColor: '$$color', + }, + info: { + $$color: '$colors$info300', + [`.${darkTheme} &`]: { + $$color: '$colors$info600', + }, + backgroundColor: '$$color', + }, + loading: { + $$color: '$colors$info300', + [`.${darkTheme} &`]: { + $$color: '$colors$info600', + }, + backgroundColor: '$$color', + }, + }, + }, +}); diff --git a/widget/ui/src/components/MessageBox/MessageBox.tsx b/widget/ui/src/components/MessageBox/MessageBox.tsx new file mode 100644 index 0000000000..2b50873e36 --- /dev/null +++ b/widget/ui/src/components/MessageBox/MessageBox.tsx @@ -0,0 +1,2 @@ +export { MessageBox } from './DefaultMessageBox.js'; +export { CollapsibleMessageBox } from './CollapsibleMessageBox.js'; diff --git a/widget/ui/src/components/MessageBox/MessageBox.types.tsx b/widget/ui/src/components/MessageBox/MessageBox.types.tsx new file mode 100644 index 0000000000..4635ff2d6c --- /dev/null +++ b/widget/ui/src/components/MessageBox/MessageBox.types.tsx @@ -0,0 +1,13 @@ +import type { IconHighlight } from './MessageBox.styles.js'; +import type * as Stitches from '@stitches/react'; +import type { ReactNode } from 'react'; + +type BaseProps = Stitches.VariantProps; +export type MessageType = Exclude; + +export interface PropTypes { + type: MessageType; + title: string; + description?: string | ReactNode; + icon?: ReactNode; +} diff --git a/widget/ui/src/components/MessageBox/StatusIcon.tsx b/widget/ui/src/components/MessageBox/StatusIcon.tsx new file mode 100644 index 0000000000..b6f51c9231 --- /dev/null +++ b/widget/ui/src/components/MessageBox/StatusIcon.tsx @@ -0,0 +1,28 @@ +import type { PropTypes } from './MessageBox.types.js'; + +import React from 'react'; + +import { + CompleteIcon, + ErrorIcon, + InfoErrorIcon, + WarningIcon, +} from '../../icons/index.js'; +import { Spinner } from '../Spinner/index.js'; + +function StatusIcon(props: Pick) { + switch (props.type) { + case 'success': + return ; + case 'warning': + return ; + case 'error': + return ; + case 'loading': + return ; + default: + return ; + } +} + +export default StatusIcon; diff --git a/widget/ui/src/components/MessageBox/index.ts b/widget/ui/src/components/MessageBox/index.ts new file mode 100644 index 0000000000..94fa76d9a0 --- /dev/null +++ b/widget/ui/src/components/MessageBox/index.ts @@ -0,0 +1,2 @@ +export * from './MessageBox.js'; +export type { MessageType } from './MessageBox.types.js'; diff --git a/widget/ui/src/components/Modal/Modal.helpers.ts b/widget/ui/src/components/Modal/Modal.helpers.ts new file mode 100644 index 0000000000..516ff9a8d6 --- /dev/null +++ b/widget/ui/src/components/Modal/Modal.helpers.ts @@ -0,0 +1,4 @@ +// https://github.com/reactjs/react-transition-group/blob/master/src/CSSTransition.js#L48-L55 +export function forceReflow(node: HTMLElement) { + return node.scrollTop; +} diff --git a/widget/ui/src/components/Modal/Modal.stories.tsx b/widget/ui/src/components/Modal/Modal.stories.tsx deleted file mode 100644 index 986deec953..0000000000 --- a/widget/ui/src/components/Modal/Modal.stories.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import React, { useState } from 'react'; -import { ComponentMeta } from '@storybook/react'; -import { Modal, PropTypes } from './Modal'; - -export default { name: 'Modal', component: Modal } as ComponentMeta< - typeof Modal ->; - -export const Main = (args: PropTypes) => { - const [open, setOpen] = useState(false); - return ( -
- - setOpen(false)} - /> -
- ); -}; diff --git a/widget/ui/src/components/Modal/Modal.styles.ts b/widget/ui/src/components/Modal/Modal.styles.ts new file mode 100644 index 0000000000..4b15d5e3ae --- /dev/null +++ b/widget/ui/src/components/Modal/Modal.styles.ts @@ -0,0 +1,127 @@ +import { styled } from '../../theme.js'; +import { IconButton } from '../IconButton/index.js'; + +export const BackDrop = styled('div', { + position: 'absolute', + top: '0', + left: '0', + right: '0', + bottom: '0', + width: '100%', + height: '100%', + backgroundColor: 'transparent', + zIndex: 10, + borderRadius: '$primary', + overflow: 'hidden', + transition: 'background .35s', + + variants: { + active: { + true: { + backgroundColor: 'color-mix(in srgb, $neutral500 70%, transparent)', + }, + }, + }, +}); + +export const ModalContainer = styled('div', { + backgroundColor: '$background', + width: '100%', + borderRadius: '$primary', + display: 'flex', + flexDirection: 'column', + zIndex: 9999999, + position: 'absolute', + transition: + 'transform .45s ease-in-out, top .45s ease-in-out, left .45s ease-in-out', + + variants: { + anchor: { + right: { + left: '100%', + }, + center: { + top: '100%', + left: '50%', + transform: 'translateX(-50%)', + }, + bottom: { + top: '100%', + }, + }, + active: { + true: {}, + }, + }, + compoundVariants: [ + { + active: true, + anchor: 'right', + css: { + transform: 'translateX(-100%)', + }, + }, + { + active: true, + anchor: 'center', + css: { + top: '50%', + left: '50%', + transform: 'translate(-50%, -50%)', + }, + }, + { + active: true, + anchor: 'bottom', + css: { + transform: 'translateY(-100%)', + }, + }, + ], +}); + +export const Flex = styled('div', { + display: 'flex', + alignItems: 'center', + justifyContent: 'end', + [`& ${IconButton}`]: { + padding: '$5', + }, +}); +export const ModalHeader = styled('div', { + padding: '$20 $20 $0 $20', + display: 'flex', + justifyContent: 'space-between', + alignItems: 'center', + position: 'relative', + variants: { + noTitle: { + true: { + justifyContent: 'flex-end', + }, + }, + }, +}); + +export const Content = styled('div', { + display: 'flex', + flexDirection: 'column', + flex: 1, + padding: '$0 $20 $10 $20', + backgroundColor: '$background', + position: 'relative', + overflowY: 'auto', + overflowX: 'hidden', +}); + +export const Footer = styled('div', { + padding: '0 $20 $10', + '& .footer__logo': { + '&.logo__show': { + opacity: 1, + }, + '&.logo__hidden': { + visibility: 'hidden', + }, + }, +}); diff --git a/widget/ui/src/components/Modal/Modal.tsx b/widget/ui/src/components/Modal/Modal.tsx index 1e86d6fcf5..13d7098cf9 100644 --- a/widget/ui/src/components/Modal/Modal.tsx +++ b/widget/ui/src/components/Modal/Modal.tsx @@ -1,88 +1,158 @@ -import { CSSProperties } from '@stitches/react'; -import React, { useEffect } from 'react'; +import type { ModalPropTypes } from './Modal.types.js'; +import type { PropsWithChildren } from 'react'; + +import React, { useEffect, useRef, useState } from 'react'; import { createPortal } from 'react-dom'; -import { styled } from '../../theme'; -import { CloseIcon } from '../Icon/CloseIcon'; -import { Typography } from '../Typography'; - -export interface PropTypes { - title: string; - open: boolean; - onClose: () => void; - content: React.ReactNode; - action?: React.ReactNode; - containerStyle?: CSSProperties; -} -const BackDrop = styled('div', { - position: 'fixed', - display: 'flex', - justifyContent: 'center', - alignItems: 'center', - top: '0', - left: '0', - width: '100vw', - height: '100vh', - backgroundColor: 'rgba(0,0,0,.1)', -}); - -const ModalContainer = styled('div', { - backgroundColor: '$background', - borderRadius: '$10', - padding: '$16 $16', - display: 'flex', - flexDirection: 'column', - boxShadow: '$s', - zIndex: 10, -}); -const Row = styled('div', { - display: 'flex', - alignItems: 'center', -}); -const ModalHeader = styled('div', { - display: 'flex', - justifyContent: 'space-between', - alignItems: 'center', - position: 'relative', - marginBottom: '$16', -}); - - -export function Modal(props: PropTypes) { +import { CloseIcon } from '../../icons/index.js'; +import { BottomLogo } from '../BottomLogo/index.js'; +import { Divider } from '../Divider/index.js'; +import { IconButton } from '../IconButton/index.js'; +import { Typography } from '../Typography/index.js'; + +import { forceReflow } from './Modal.helpers.js'; +import { + BackDrop, + Content, + Flex, + Footer, + ModalContainer, + ModalHeader, +} from './Modal.styles.js'; + +export function Modal(props: PropsWithChildren) { const { title, - content, open, onClose, - containerStyle, - action, + onExit, + styles, + anchor = 'bottom', + container = document.body, + prefix, + header, + dismissible = true, + children, + suffix, + footer, + hasWatermark = true, + hasCloseIcon = true, } = props; + const [status, setStatus] = useState< + 'unmounted' | 'mounted' | 'activated' | 'deactivated' + >('unmounted'); + const active = status === 'activated'; + const isMount = + status == 'mounted' || status === 'activated' || status === 'deactivated'; + const modalContainerRef = useRef(null); + const exitCallbackRef = useRef(); + const handleBackDropClick = (event: React.MouseEvent) => { - if (event.target === event.currentTarget) onClose(); + event.stopPropagation(); + + if (event.target === event.currentTarget && dismissible) { + onClose(); + } }; + useEffect(() => { - if (open) document.body.style.overflow = 'hidden'; - else document.body.style.overflow = 'unset'; + exitCallbackRef.current = onExit; + }, [onExit]); + + useEffect(() => { + if (exitCallbackRef.current) { + modalContainerRef.current?.addEventListener( + 'transitionend', + exitCallbackRef.current + ); + } + + if (!open) { + if (status === 'activated') { + setStatus('deactivated'); + modalContainerRef.current?.addEventListener('transitionend', () => { + setStatus('unmounted'); + container.style.removeProperty('overflow'); + }); + } else { + setStatus('unmounted'); + } + } else { + setStatus('mounted'); + container.style.overflow = 'hidden'; + } + + return () => { + if (exitCallbackRef.current) { + modalContainerRef.current?.removeEventListener( + 'transitionend', + exitCallbackRef.current + ); + } + }; }, [open]); - return ( - <> - {open && - createPortal( - - - - {title} - - {action} - - - - {content} - - , - document.body + + useEffect(() => { + return () => { + //container might be null + container?.style.removeProperty('overflow'); + }; + }, []); + + useEffect(() => { + if (!!container && isMount) { + if (modalContainerRef.current) { + forceReflow(modalContainerRef.current); + } + setStatus('activated'); + } + }, [isMount, container]); + + if (status === 'unmounted' || !container) { + return null; + } + + return createPortal( + + (modalContainerRef.current = ref)}> + {header ?? ( + + {prefix} + {title && ( + + {title} + + )} + + {suffix} + {dismissible && hasCloseIcon && ( + + + + )} + + )} - + {children} + +
+ {footer &&
{footer}
} + +
+ + +
+
+
+
, + container ); } diff --git a/widget/ui/src/components/Modal/Modal.types.ts b/widget/ui/src/components/Modal/Modal.types.ts new file mode 100644 index 0000000000..ef71d57db7 --- /dev/null +++ b/widget/ui/src/components/Modal/Modal.types.ts @@ -0,0 +1,28 @@ +import type { ModalContainer } from './Modal.styles.js'; +import type { config } from '../../theme.js'; +import type * as Stitches from '@stitches/react'; + +type BaseProps = Stitches.VariantProps; +type BaseAnchor = Exclude; + +export interface ModalPropTypes { + title?: string; + open: boolean; + onClose: () => void; + onExit?: () => void; + anchor?: BaseAnchor; + dismissible?: boolean; + header?: React.ReactNode; + prefix?: React.ReactNode; + suffix?: React.ReactNode; + container?: HTMLElement; + styles?: { + root?: Stitches.CSS; + container?: Stitches.CSS; + content?: Stitches.CSS; + footer?: Stitches.CSS; + }; + footer?: React.ReactNode; + hasWatermark?: boolean; + hasCloseIcon?: boolean; +} diff --git a/widget/ui/src/components/Modal/index.ts b/widget/ui/src/components/Modal/index.ts index 8deb0a3dff..96a7adf9eb 100644 --- a/widget/ui/src/components/Modal/index.ts +++ b/widget/ui/src/components/Modal/index.ts @@ -1 +1,3 @@ -export { Modal } from './Modal'; +export { Modal } from './Modal.js'; +export { ModalHeader } from './Modal.styles.js'; +export type { ModalPropTypes } from './Modal.types.js'; diff --git a/widget/ui/src/components/NotFound/NotFound.styles.ts b/widget/ui/src/components/NotFound/NotFound.styles.ts new file mode 100644 index 0000000000..8a5a7c651d --- /dev/null +++ b/widget/ui/src/components/NotFound/NotFound.styles.ts @@ -0,0 +1,15 @@ +import { darkTheme, styled } from '../../theme'; + +export const Container = styled('div', { + display: 'flex', + justifyContent: 'center', + alignItems: 'center', + flexDirection: 'column', + textAlign: 'center', + '& .not-found-description': { + color: '$neutral700', + [`.${darkTheme} &`]: { + color: '$neutral900', + }, + }, +}); diff --git a/widget/ui/src/components/NotFound/NotFound.tsx b/widget/ui/src/components/NotFound/NotFound.tsx new file mode 100644 index 0000000000..90a2116e55 --- /dev/null +++ b/widget/ui/src/components/NotFound/NotFound.tsx @@ -0,0 +1,29 @@ +import type { NotFoundPropTypes } from './NotFound.types.js'; + +import React from 'react'; + +import { SearchIcon } from '../../icons/index.js'; +import { Divider } from '../Divider/index.js'; +import { Typography } from '../Typography/index.js'; + +import { Container } from './NotFound.styles.js'; + +export function NotFound(props: NotFoundPropTypes) { + const { icon, titleColor, hasIcon = true } = props; + return ( + + {hasIcon && (icon || )} + + + {props.title} + + + + {props.description} + + + ); +} diff --git a/widget/ui/src/components/NotFound/NotFound.types.ts b/widget/ui/src/components/NotFound/NotFound.types.ts new file mode 100644 index 0000000000..602ce6b100 --- /dev/null +++ b/widget/ui/src/components/NotFound/NotFound.types.ts @@ -0,0 +1,9 @@ +import type { ReactNode } from 'react'; + +export type NotFoundPropTypes = { + title: string; + description?: string; + titleColor?: string; + icon?: ReactNode; + hasIcon?: boolean; +}; diff --git a/widget/ui/src/components/NotFound/index.tsx b/widget/ui/src/components/NotFound/index.tsx new file mode 100644 index 0000000000..3a40e21fc1 --- /dev/null +++ b/widget/ui/src/components/NotFound/index.tsx @@ -0,0 +1,2 @@ +export { NotFound } from './NotFound.js'; +export type { NotFoundPropTypes } from './NotFound.types.js'; diff --git a/widget/ui/src/components/Popover/Popover.styles.ts b/widget/ui/src/components/Popover/Popover.styles.ts new file mode 100644 index 0000000000..348d95e3cc --- /dev/null +++ b/widget/ui/src/components/Popover/Popover.styles.ts @@ -0,0 +1,22 @@ +import * as RadixPopover from '@radix-ui/react-popover'; + +import { darkTheme, styled } from '../../theme.js'; + +export const PopoverContainer = styled(RadixPopover.Content, { + borderRadius: '$sm', + filter: 'drop-shadow(0px 5px 20px rgba(130, 130, 130, 0.20))', + backgroundColor: '$neutral100', + zIndex: 10, + [`.${darkTheme} &`]: { + backgroundColor: '$neutral300', + }, +}); + +export const PopoverArrow = styled(RadixPopover.Arrow, { + fill: '$neutral100', + [`.${darkTheme} &`]: { + fill: '$neutral300', + }, + width: '$16', + height: '$8', +}); diff --git a/widget/ui/src/components/Popover/Popover.tsx b/widget/ui/src/components/Popover/Popover.tsx new file mode 100644 index 0000000000..0dbc824f74 --- /dev/null +++ b/widget/ui/src/components/Popover/Popover.tsx @@ -0,0 +1,61 @@ +import type { ContentType, PopoverPropTypes, Ref } from './Popover.types.js'; +import type { PropsWithChildren } from 'react'; + +import * as RadixPopover from '@radix-ui/react-popover'; +import React from 'react'; + +import { PopoverArrow, PopoverContainer } from './Popover.styles.js'; + +const DEFAULT_SIDE_OFFSET = 0; +const DEFAULT_ALIGN_OFFSET = 0; + +export const PopoverContentComponent = ( + props: PropsWithChildren, + forwardedRef: Ref +) => { + const { container, children, styles, hasArrow = true, ...rest } = props; + return ( + + + {children} + {hasArrow && } + + + ); +}; + +const PopoverContent = React.forwardRef(PopoverContentComponent); +PopoverContent.displayName = 'PopoverContent'; + +export function Popover(props: PropsWithChildren) { + const { + children, + content, + side = 'bottom', + sideOffset = DEFAULT_SIDE_OFFSET, + alignOffset = DEFAULT_ALIGN_OFFSET, + align = 'center', + collisionBoundary = [], + collisionPadding = 0, + container = document.body, + onOpenChange, + open, + ...rest + } = props; + return ( + + {children} + + {content} + + + ); +} diff --git a/widget/ui/src/components/Popover/Popover.types.ts b/widget/ui/src/components/Popover/Popover.types.ts new file mode 100644 index 0000000000..c5ff04cfc2 --- /dev/null +++ b/widget/ui/src/components/Popover/Popover.types.ts @@ -0,0 +1,30 @@ +import type { CSS } from '../../theme.js'; +import type { ReactNode } from 'react'; + +export type Ref = + | ((instance: HTMLInputElement | null) => void) + | React.RefObject + | null + | undefined; + +type Side = 'top' | 'right' | 'bottom' | 'left'; + +export interface ContentType { + side?: Side; + sideOffset?: number; + alignOffset?: number; + align?: 'center' | 'start' | 'end'; + collisionBoundary?: Element | null | Array; + collisionPadding?: number | Partial>; + container?: HTMLElement; + styles?: { + arrowStyles?: CSS; + }; + hasArrow?: boolean; + onOpenChange?: (open: boolean) => void; +} + +export type PopoverPropTypes = ContentType & { + content: ReactNode; + open?: boolean; +}; diff --git a/widget/ui/src/components/Popover/index.ts b/widget/ui/src/components/Popover/index.ts new file mode 100644 index 0000000000..76567d0b5a --- /dev/null +++ b/widget/ui/src/components/Popover/index.ts @@ -0,0 +1,2 @@ +export { Popover } from './Popover.js'; +export type { PopoverPropTypes } from './Popover.types.js'; diff --git a/widget/ui/src/components/PriceImpact/PriceImpact.styles.ts b/widget/ui/src/components/PriceImpact/PriceImpact.styles.ts new file mode 100644 index 0000000000..c7a923201e --- /dev/null +++ b/widget/ui/src/components/PriceImpact/PriceImpact.styles.ts @@ -0,0 +1,38 @@ +import { darkTheme, styled } from '../../theme.js'; + +export const Container = styled('div', { + width: '100%', + display: 'flex', + justifyContent: 'end', + alignItems: 'center', +}); + +export const ValueTypography = styled('div', { + display: 'flex', + whiteSpace: 'nowrap', + overflow: 'hidden', + textOverflow: 'ellipsis', + '& ._typography': { + $$color: '$colors$neutral600', + [`.${darkTheme} &`]: { + $$color: '$colors$neutral700', + }, + color: '$$color', + }, + variants: { + hasWarning: { + true: { + '& ._typography': { + color: '$warning500', + }, + }, + }, + hasError: { + true: { + '& ._typography': { + color: '$error500', + }, + }, + }, + }, +}); diff --git a/widget/ui/src/components/PriceImpact/PriceImpact.tsx b/widget/ui/src/components/PriceImpact/PriceImpact.tsx new file mode 100644 index 0000000000..4d5ef6d208 --- /dev/null +++ b/widget/ui/src/components/PriceImpact/PriceImpact.tsx @@ -0,0 +1,62 @@ +import type { PriceImpactPropTypes } from './PriceImpact.types.js'; + +import React from 'react'; + +import { Divider, NumericTooltip, Typography } from '../index.js'; + +import { Container, ValueTypography } from './PriceImpact.styles.js'; + +export function PriceImpact(props: PriceImpactPropTypes) { + const { + size = 'medium', + outputUsdValue, + outputColor, + realOutputUsdValue, + percentageChange, + warningLevel, + error, + tooltipProps, + ...rest + } = props; + + const hasWarning = !outputUsdValue || warningLevel === 'low'; + const hasError = warningLevel === 'high'; + + return ( + + {outputUsdValue && ( + + + + {outputUsdValue === '0' ? '0.00' : `~$${outputUsdValue}`} + + + + )} + {((outputUsdValue && percentageChange) || !outputUsdValue) && ( + + + + {outputUsdValue && + percentageChange && + `(${ + percentageChange.includes('-') + ? percentageChange + : `-${percentageChange}` + }${percentageChange ? '%' : '-'})`} + + {!outputUsdValue && error} + + + )} + + ); +} diff --git a/widget/ui/src/components/PriceImpact/PriceImpact.types.ts b/widget/ui/src/components/PriceImpact/PriceImpact.types.ts new file mode 100644 index 0000000000..409905a1ac --- /dev/null +++ b/widget/ui/src/components/PriceImpact/PriceImpact.types.ts @@ -0,0 +1,18 @@ +import type { TooltipPropTypes } from '../Tooltip/Tooltip.types.js'; +import type { TypographyPropTypes } from '../Typography/index.js'; + +export type PriceImpactWarningLevel = 'low' | 'high' | undefined; + +export type PriceImpactPropTypes = { + size: TypographyPropTypes['size']; + outputUsdValue?: string; + outputColor?: string; + realOutputUsdValue?: string; + error?: string; + percentageChange?: string | null; + warningLevel?: PriceImpactWarningLevel; + tooltipProps?: { + container?: TooltipPropTypes['container']; + side?: TooltipPropTypes['side']; + }; +}; diff --git a/widget/ui/src/components/PriceImpact/index.ts b/widget/ui/src/components/PriceImpact/index.ts new file mode 100644 index 0000000000..b81a28b119 --- /dev/null +++ b/widget/ui/src/components/PriceImpact/index.ts @@ -0,0 +1,5 @@ +export { PriceImpact } from './PriceImpact.js'; +export type { + PriceImpactWarningLevel, + PriceImpactPropTypes, +} from './PriceImpact.types.js'; diff --git a/widget/ui/src/components/QuoteCost/QuoteCost.styles.ts b/widget/ui/src/components/QuoteCost/QuoteCost.styles.ts new file mode 100644 index 0000000000..7dd13783e1 --- /dev/null +++ b/widget/ui/src/components/QuoteCost/QuoteCost.styles.ts @@ -0,0 +1,57 @@ +import { css, keyframes, styled } from '../../theme.js'; + +export const Container = styled('div', { + borderRadius: '$xs', + display: 'flex', + justifyContent: 'start', + alignItems: 'center', +}); + +export const Separator = styled('div', { + height: '$12', + marginLeft: '$10', + marginRight: '$10', + borderLeft: '1px solid $foreground', +}); + +export const iconStyles = css({ + width: '$16', + height: '$16', + display: 'flex', + justifyContent: 'center', + alignItems: 'center', +}); + +const blinker = keyframes({ + '50%': { + opacity: 0.2, + }, +}); + +export const itemStyles = css({ + display: 'flex', + alignItems: 'center', + cursor: 'default', + + '&.feeSection': { + cursor: 'pointer', + '&:hover': { + svg: { + color: '$secondary', + }, + '._typography': { + color: '$secondary', + }, + }, + }, + '&.warning': { + animation: `${blinker} 2s linear infinite`, + + svg: { + color: '$warning500', + }, + '._typography': { + color: '$warning500', + }, + }, +}); diff --git a/widget/ui/src/components/QuoteCost/QuoteCost.tsx b/widget/ui/src/components/QuoteCost/QuoteCost.tsx new file mode 100644 index 0000000000..5a46de5679 --- /dev/null +++ b/widget/ui/src/components/QuoteCost/QuoteCost.tsx @@ -0,0 +1,76 @@ +import type { PropTypes } from './QuoteCost.types.js'; + +import React from 'react'; + +import { GasIcon, NumberIcon, TimeIcon } from '../../icons/index.js'; +import { Divider } from '../Divider/index.js'; +import { Tooltip } from '../Tooltip/index.js'; +import { Typography } from '../Typography/index.js'; + +import { + Container, + iconStyles, + itemStyles, + Separator, +} from './QuoteCost.styles.js'; + +export function QuoteCost(props: PropTypes) { + const { + fee, + time, + steps, + onClickFee, + tooltipGas, + feeWarning, + timeWarning, + tooltipContainer, + } = props; + return ( + + +
+
+ +
+ + + ${fee} + +
+
+ + +
+
+ +
+ + + {time} + +
+ {!!steps && ( + <> + +
+
+ +
+ + + {steps} + +
+ + )} +
+ ); +} diff --git a/widget/ui/src/components/QuoteCost/QuoteCost.types.ts b/widget/ui/src/components/QuoteCost/QuoteCost.types.ts new file mode 100644 index 0000000000..9a8ea04388 --- /dev/null +++ b/widget/ui/src/components/QuoteCost/QuoteCost.types.ts @@ -0,0 +1,10 @@ +export type PropTypes = { + fee: string; + time: string | number; + steps?: number; + onClickFee?: React.MouseEventHandler; + tooltipGas?: string; + feeWarning?: boolean; + timeWarning?: boolean; + tooltipContainer?: HTMLElement; +}; diff --git a/widget/ui/src/components/QuoteCost/index.ts b/widget/ui/src/components/QuoteCost/index.ts new file mode 100644 index 0000000000..1cb098ddfb --- /dev/null +++ b/widget/ui/src/components/QuoteCost/index.ts @@ -0,0 +1 @@ +export { QuoteCost } from './QuoteCost.js'; diff --git a/widget/ui/src/components/QuoteTag/QuoteTag.styles.ts b/widget/ui/src/components/QuoteTag/QuoteTag.styles.ts new file mode 100644 index 0000000000..097db09e6f --- /dev/null +++ b/widget/ui/src/components/QuoteTag/QuoteTag.styles.ts @@ -0,0 +1,44 @@ +import { css, darkTheme, styled } from '../../theme.js'; + +export const getLabelStyles = css({}); + +export const TagContainer = styled('div', { + backgroundColor: '$neutral400', + borderRadius: '$xs', + padding: '$2 $5', + display: 'flex', + justifyContent: 'center', + alignItems: 'center', + variants: { + type: { + RECOMMENDED: { + [`& .${getLabelStyles}`]: { + color: '$secondary500', + [`.${darkTheme} &`]: { + color: '$secondary250', + }, + }, + }, + FASTEST: { + [`& .${getLabelStyles}`]: { + color: '$success500', + }, + }, + HIGH_IMPACT: { + [`& .${getLabelStyles}`]: { + color: '$error500', + }, + }, + LOWEST_FEE: { + [`& .${getLabelStyles}`]: { + color: '#FF4DAD', + }, + }, + CENTRALIZED: { + [`& .${getLabelStyles}`]: { + color: '$warning500', + }, + }, + }, + }, +}); diff --git a/widget/ui/src/components/QuoteTag/QuoteTag.tsx b/widget/ui/src/components/QuoteTag/QuoteTag.tsx new file mode 100644 index 0000000000..9c455f9492 --- /dev/null +++ b/widget/ui/src/components/QuoteTag/QuoteTag.tsx @@ -0,0 +1,19 @@ +import type { RouteTag, Tag } from 'rango-types/lib/api/main'; + +import React from 'react'; + +import { Typography } from '../Typography/index.js'; + +import { getLabelStyles, TagContainer } from './QuoteTag.styles.js'; + +export const QuoteTag = (props: RouteTag) => { + const { value, label } = props; + + return ( + + + {label} + + + ); +}; diff --git a/widget/ui/src/components/QuoteTag/index.ts b/widget/ui/src/components/QuoteTag/index.ts new file mode 100644 index 0000000000..aa8236efe4 --- /dev/null +++ b/widget/ui/src/components/QuoteTag/index.ts @@ -0,0 +1 @@ +export { QuoteTag } from './QuoteTag.js'; diff --git a/widget/ui/src/components/Radio/Radio.stories.tsx b/widget/ui/src/components/Radio/Radio.stories.tsx deleted file mode 100644 index 2d70216492..0000000000 --- a/widget/ui/src/components/Radio/Radio.stories.tsx +++ /dev/null @@ -1,23 +0,0 @@ -import React from 'react'; -import { ComponentMeta } from '@storybook/react'; -import { PropTypes, Radio } from './Radio'; - -export default { - title: 'Radio', - component: Radio, - argTypes: { - options: { - defaultValue: [ - { value: 'one', label: 'One' }, - { value: 'two', label: 'Two' }, - { value: 'three', label: 'Three' }, - ], - }, - defaultValue: { defaultValue: 'one' }, - direction: { - defaultValue: 'horizontal', - }, - }, -} as ComponentMeta; - -export const Main = (args: PropTypes) => ; diff --git a/widget/ui/src/components/Radio/Radio.styles.tsx b/widget/ui/src/components/Radio/Radio.styles.tsx new file mode 100644 index 0000000000..6085fd0139 --- /dev/null +++ b/widget/ui/src/components/Radio/Radio.styles.tsx @@ -0,0 +1,42 @@ +import * as Radio from '@radix-ui/react-radio-group'; + +import { darkTheme, styled } from '../../theme.js'; + +export const StyledItem = styled(Radio.Item, { + padding: '0', + width: '16px', + height: '16px', + borderRadius: '100%', + cursor: 'pointer', + backgroundColor: 'transparent', + $$borderColor: '$colors$neutral600', + [`.${darkTheme} &`]: { + $$borderColor: '$colors$neutral700', + }, + border: '1px solid $$borderColor', + '&[data-state="checked"]': { + $$color: '$colors$secondary500', + [`.${darkTheme} &`]: { + $$color: '$colors$secondary250', + }, + backgroundColor: '$$color', + borderColor: '$$color', + }, +}); + +export const StyledIndicator = styled(Radio.Indicator, { + display: 'flex', + alignItems: 'center', + justifyContent: 'center', + width: '100%', + height: '100%', + position: 'relative', + '&::after': { + content: '', + display: 'block', + width: '8px', + height: '8px', + borderRadius: '50%', + backgroundColor: '$background', + }, +}); diff --git a/widget/ui/src/components/Radio/Radio.tsx b/widget/ui/src/components/Radio/Radio.tsx index 60b6a32407..1b975e2917 100644 --- a/widget/ui/src/components/Radio/Radio.tsx +++ b/widget/ui/src/components/Radio/Radio.tsx @@ -1,100 +1,14 @@ -import React from 'react'; -import * as RadioGroup from '@radix-ui/react-radio-group'; -import { styled } from '../../theme'; -import { Typography } from '../Typography'; -import { CSSProperties } from '@stitches/react'; - -const StyledRoot = styled(RadioGroup.Root, { - variants: { - direction: { - horizontal: { - display: 'flex', - flexDirection: 'row', - flexWrap: 'wrap', - }, - vertical: { - display: 'grid', - gridGap: '$24', - }, - }, - }, -}); - -const ItemContainer = styled('div', { - display: 'flex', - alignItems: 'center', - marginRight: '$8', -}); -const StyledItem = styled(RadioGroup.Item, { - padding: '0', - width: '20px', - height: '20px', - borderRadius: '100%', - cursor: 'pointer', - backgroundColor: '$background', - border: '1px solid $neutrals400', - - '&:hover': { - borderColor: '$neutrals600', - }, -}); +import type { RadioPropTypes } from './Radio.types.js'; -const Container = styled('div', { - display: 'flex', -}); - -const StyledIndicator = styled(RadioGroup.Indicator, { - display: 'flex', - alignItems: 'center', - justifyContent: 'center', - width: '100%', - height: '100%', - position: 'relative', - '&::after': { - content: '', - display: 'block', - width: '10px', - height: '10px', - borderRadius: '50%', - backgroundColor: '$success', - }, -}); - -const Label = styled('label', { - paddingLeft: '$8', - cursor: 'pointer', - color: '$foreground', -}); +import React from 'react'; -export interface PropTypes { - options: { label: string; value: string }[]; - value: string; - onChange: (value: string) => void; - direction?: 'vertical' | 'horizontal'; - style?: CSSProperties; -} +import { StyledIndicator, StyledItem } from './Radio.styles.js'; -export function Radio(props: PropTypes) { - const { value, onChange, direction = 'vertical', style } = props; +export function Radio(props: RadioPropTypes) { + const { value } = props; return ( - - - {props.options.map((option, index) => ( - - - - - - - ))} - - + + + ); } diff --git a/widget/ui/src/components/Radio/Radio.types.tsx b/widget/ui/src/components/Radio/Radio.types.tsx new file mode 100644 index 0000000000..906c9c3fde --- /dev/null +++ b/widget/ui/src/components/Radio/Radio.types.tsx @@ -0,0 +1,3 @@ +export interface RadioPropTypes { + value: string; +} diff --git a/widget/ui/src/components/Radio/index.ts b/widget/ui/src/components/Radio/index.ts index de3697b1a2..1d3bb7ec08 100644 --- a/widget/ui/src/components/Radio/index.ts +++ b/widget/ui/src/components/Radio/index.ts @@ -1 +1,2 @@ -export { Radio } from './Radio'; +export { Radio } from './Radio.js'; +export type { RadioPropTypes } from './Radio.types.js'; diff --git a/widget/ui/src/components/RadioGroup/RadioGroup.styles.tsx b/widget/ui/src/components/RadioGroup/RadioGroup.styles.tsx new file mode 100644 index 0000000000..39941a93bf --- /dev/null +++ b/widget/ui/src/components/RadioGroup/RadioGroup.styles.tsx @@ -0,0 +1,38 @@ +import * as RadioGroup from '@radix-ui/react-radio-group'; + +import { styled } from '../../theme.js'; + +export const RadioRoot = styled(RadioGroup.Root, { + variants: { + direction: { + horizontal: { + display: 'flex', + flexDirection: 'row', + flexWrap: 'wrap', + }, + vertical: { + display: 'grid', + gridGap: '$24', + }, + }, + }, +}); + +export const ItemContainer = styled('div', { + display: 'flex', + alignItems: 'center', + marginRight: '$8', +}); + +export const Container = styled('div', { + display: 'flex', +}); + +export const Label = styled('label', { + paddingLeft: '$8', + cursor: 'pointer', + color: '$foreground', + '& > span': { + display: 'block', + }, +}); diff --git a/widget/ui/src/components/RadioGroup/RadioGroup.tsx b/widget/ui/src/components/RadioGroup/RadioGroup.tsx new file mode 100644 index 0000000000..300a7d76ea --- /dev/null +++ b/widget/ui/src/components/RadioGroup/RadioGroup.tsx @@ -0,0 +1,37 @@ +import type { RadioGroupPropTypes } from './RadioGroup.types.js'; + +import React from 'react'; + +import { Radio } from '../Radio/index.js'; +import { Typography } from '../Typography/index.js'; + +import { + Container, + ItemContainer, + Label, + RadioRoot, +} from './RadioGroup.styles.js'; + +export function RadioGroup(props: RadioGroupPropTypes) { + const { value, onChange, direction = 'vertical', style, options } = props; + return ( + + + {options.map((option) => ( + + + + + ))} + + + ); +} diff --git a/widget/ui/src/components/RadioGroup/RadioGroup.types.tsx b/widget/ui/src/components/RadioGroup/RadioGroup.types.tsx new file mode 100644 index 0000000000..229b291fe0 --- /dev/null +++ b/widget/ui/src/components/RadioGroup/RadioGroup.types.tsx @@ -0,0 +1,13 @@ +import type { RadioPropTypes } from '../Radio/index.js'; +import type { CSSProperties } from '@stitches/react'; + +export interface RadioGroupPropTypes { + options: { + label: string; + value: RadioPropTypes['value']; + }[]; + value: RadioPropTypes['value']; + onChange: (value: string) => void; + direction?: 'vertical' | 'horizontal'; + style?: CSSProperties; +} diff --git a/widget/ui/src/components/RadioGroup/index.ts b/widget/ui/src/components/RadioGroup/index.ts new file mode 100644 index 0000000000..3df6c6af13 --- /dev/null +++ b/widget/ui/src/components/RadioGroup/index.ts @@ -0,0 +1,3 @@ +export { RadioGroup } from './RadioGroup.js'; +export { RadioRoot } from './RadioGroup.styles.js'; +export type { RadioGroupPropTypes } from './RadioGroup.types.js'; diff --git a/widget/ui/src/components/RefreshProgressButton/RefreshProgressButton.styles.ts b/widget/ui/src/components/RefreshProgressButton/RefreshProgressButton.styles.ts new file mode 100644 index 0000000000..7255967de9 --- /dev/null +++ b/widget/ui/src/components/RefreshProgressButton/RefreshProgressButton.styles.ts @@ -0,0 +1,28 @@ +import { styled } from '../../theme.js'; + +export const StyledEllipse = styled('ellipse', { + cx: '12.5px', + cy: '12.5px', + rx: '7.7px', + ry: '7.7px', + strokeLinecap: 'round', + fill: 'none', + strokeDasharray: 100, + transform: `rotate(20deg)`, + transformOrigin: 'center', + variants: { + type: { + 'in-progress': { + stroke: '$info500', + strokeWidth: 2, + }, + basic: { + strokeWidth: 1.8, + }, + }, + }, +}); + +export const StyledPath = styled('path', { + fill: '$info500', +}); diff --git a/widget/ui/src/components/RefreshProgressButton/RefreshProgressButton.tsx b/widget/ui/src/components/RefreshProgressButton/RefreshProgressButton.tsx new file mode 100644 index 0000000000..5e572e85e6 --- /dev/null +++ b/widget/ui/src/components/RefreshProgressButton/RefreshProgressButton.tsx @@ -0,0 +1,70 @@ +/* eslint-disable @typescript-eslint/no-magic-numbers */ +import type { SvgIconPropsWithChildren } from '../SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../SvgIcon/index.js'; + +import { StyledEllipse, StyledPath } from './RefreshProgressButton.styles.js'; + +const DEFAULT_STROKE_DASHOFFSET = 59; +const MAX_PERCENTAGE = 100; +const MAX_PROGRESS = 41; +const MIN_PROGRESS = 0; +const NORMALIZE_FACTOR = 10; +const OPACITY_THRESHOLD = 82; +const DIVISION_FACTOR = 2; + +const Ellipse = (props: { fill?: string; progress?: number }) => { + const type = props.progress ? 'in-progress' : 'basic'; + return ( + + ); +}; + +function RefreshProgressButton( + props: SvgIconPropsWithChildren & { progress: number } +) { + const normalizeValue = (value: number) => { + return (value - OPACITY_THRESHOLD) / NORMALIZE_FACTOR; + }; + const normalizedProgress = Math.min( + props.progress / DIVISION_FACTOR, + MAX_PROGRESS + ); + const opacity = + normalizedProgress !== MAX_PROGRESS + ? MIN_PROGRESS + : normalizeValue(props.progress); + + return createElement( + SvgIcon, + props, + + + + + + + + + + ); +} +export { RefreshProgressButton }; diff --git a/widget/ui/src/components/RefreshProgressButton/index.ts b/widget/ui/src/components/RefreshProgressButton/index.ts new file mode 100644 index 0000000000..44162d7c14 --- /dev/null +++ b/widget/ui/src/components/RefreshProgressButton/index.ts @@ -0,0 +1 @@ +export { RefreshProgressButton } from './RefreshProgressButton.js'; diff --git a/widget/ui/src/components/SecondaryPage/SecondaryPage.stories.tsx b/widget/ui/src/components/SecondaryPage/SecondaryPage.stories.tsx deleted file mode 100644 index eec252319b..0000000000 --- a/widget/ui/src/components/SecondaryPage/SecondaryPage.stories.tsx +++ /dev/null @@ -1,7 +0,0 @@ -import { ComponentMeta } from '@storybook/react'; -import { SecondaryPage } from './SecondaryPage'; - -export default { - title: 'Components/Secondary Page', - component: SecondaryPage, -} as ComponentMeta; diff --git a/widget/ui/src/components/SecondaryPage/SecondaryPage.tsx b/widget/ui/src/components/SecondaryPage/SecondaryPage.tsx deleted file mode 100644 index f039f2208e..0000000000 --- a/widget/ui/src/components/SecondaryPage/SecondaryPage.tsx +++ /dev/null @@ -1,68 +0,0 @@ -import React, { ReactNode, useState } from 'react'; -import { styled } from '../../theme'; -import { Divider } from '../Divider'; -import { Header } from '../Header'; -import { SearchIcon } from '../Icon'; -import { TextField } from '../TextField'; - -export type PropTypes = ( - | { - textField: true; - children?: (searchedFor: string) => ReactNode; - textFieldPlaceholder: string; - } - | { - textField: false; - children?: ReactNode; - } -) & { - title?: string; - onBack?: () => void; - TopButton?: React.ReactNode; - Footer?: React.ReactNode; - hasHeader?: boolean; -}; - -const ContentContainer = styled('div', { - overflow: 'hidden', - display: 'flex', - flexDirection: 'column', - flex: '1', - padding: '0 $4', -}); - -const TextFieldContainer = styled('div', { - padding: '1px', -}); - -export function SecondaryPage(props: PropTypes) { - const { title, Footer, TopButton, onBack, hasHeader = true } = props; - const [searchedFor, setSearchedFor] = useState(''); - - return ( - <> - {hasHeader && ( -
- )} - - - {props.textField && ( - - } - placeholder={props.textFieldPlaceholder} - onChange={(event) => setSearchedFor(event.target.value)} - value={searchedFor} - autoFocus - /> - - - )} - {props.textField && props.children?.(searchedFor)} - {!props.textField && props.children} - - {Footer} - - ); -} diff --git a/widget/ui/src/components/SecondaryPage/index.ts b/widget/ui/src/components/SecondaryPage/index.ts deleted file mode 100644 index dbdf99e718..0000000000 --- a/widget/ui/src/components/SecondaryPage/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { SecondaryPage } from './SecondaryPage'; diff --git a/widget/ui/src/components/Select/Select.styles.ts b/widget/ui/src/components/Select/Select.styles.ts new file mode 100644 index 0000000000..b65e1c215d --- /dev/null +++ b/widget/ui/src/components/Select/Select.styles.ts @@ -0,0 +1,96 @@ +import * as Select from '@radix-ui/react-select'; + +import { darkTheme, styled } from '../../theme.js'; + +export const EXPANDABLE_QUOTE_TRANSITION_DURATION = 300; + +export const SelectTrigger = styled(Select.Trigger, { + display: 'flex', + justifyContent: 'space-between', + alignItems: 'center', + cursor: 'pointer', + outline: 0, + whiteSpace: 'nowrap', + width: '100%', + '& svg': { + transition: `all ${EXPANDABLE_QUOTE_TRANSITION_DURATION}ms ease`, + }, + '& ._typography': { + whiteSpace: 'nowrap', + }, + variants: { + open: { + true: { + '& svg': { + transform: 'rotate(180deg)', + }, + }, + false: { + '& svg': { + transform: 'rotate(0)', + }, + }, + }, + variant: { + filled: { + border: 0, + borderRadius: '$sm', + padding: '$5 $10', + backgroundColor: '$neutral300', + [`.${darkTheme} &`]: { + backgroundColor: '$neutral400', + }, + '&:hover': { + backgroundColor: '$secondary100', + [`.${darkTheme} &`]: { + backgroundColor: '$neutral', + }, + }, + }, + outlined: { + backgroundColor: 'transparent', + padding: '$10', + border: '1px solid $neutral300', + borderRadius: '$xm', + '&:hover': { + borderColor: '$secondary200', + '& svg': { + color: '$secondary500', + }, + }, + }, + }, + }, +}); + +export const SelectContent = styled(Select.Content, { + width: 'var(--radix-select-trigger-width)', + maxHeight: 'var(--radix-select-content-available-height)', + overflowY: 'auto', + borderRadius: '$sm', + boxShadow: '-5px 5px 10px 0px rgba(86, 86, 86, 0.10)', + backgroundColor: '$background', +}); + +export const SelectItem = styled(Select.Item, { + padding: '$10', + listStyleType: 'none', + display: 'flex', + justifyContent: 'space-between', + alignItems: 'center', + cursor: 'pointer', + '&:focus': { + outline: 'none', + }, + + '&:hover': { + backgroundColor: '$secondary100', + '& ._text': { + color: '$secondary500', + }, + [`.${darkTheme} &`]: { + backgroundColor: '$neutral', + color: '$secondary500', + }, + }, +}); diff --git a/widget/ui/src/components/Select/Select.tsx b/widget/ui/src/components/Select/Select.tsx new file mode 100644 index 0000000000..f49b5f5345 --- /dev/null +++ b/widget/ui/src/components/Select/Select.tsx @@ -0,0 +1,97 @@ +import type { SelectPropTypes } from './Select.types.js'; + +import * as Select from '@radix-ui/react-select'; +import React, { useEffect, useRef, useState } from 'react'; + +import { ChevronDownIcon, ChevronUpIcon, DoneIcon } from '../../icons/index.js'; +import { Typography } from '../Typography/index.js'; + +import { SelectContent, SelectItem, SelectTrigger } from './Select.styles.js'; + +export function SelectComponent(props: SelectPropTypes) { + const [open, setOpen] = useState(false); + const selectRef = useRef(null); + const { options, value, container, handleItemClick, variant, styles } = props; + const handleToggle = () => { + setOpen((prev) => !prev); + }; + + const handleClickOutside = (e: MouseEvent) => { + if (selectRef.current && !selectRef.current.contains(e.target as Node)) { + setOpen(false); + } + }; + + useEffect(() => { + document.addEventListener('click', handleClickOutside); + return () => { + document.removeEventListener('click', handleClickOutside); + }; + }, []); + + const selectedLabel = options.find((option) => option.value === value)?.label; + + const wrapPortal = (children: React.ReactNode) => { + if (container) { + return {children}; + } + + return <>{children}; + }; + + return ( +
+ + event.key === 'Enter' && handleToggle()} + onClick={handleToggle} + open={open} + aria-label={selectedLabel} + css={styles?.trigger}> + + + {selectedLabel} + + + + + + + + {wrapPortal( + + + + + + + {options.map((option) => ( + { + handleItemClick && handleItemClick(option); + handleToggle(); + }} + key={option.value} + value={option.value}> + + + {option.label} + + + {option.value === value && ( + + )} + + ))} + + + + + + + )} + +
+ ); +} diff --git a/widget/ui/src/components/Select/Select.types.ts b/widget/ui/src/components/Select/Select.types.ts new file mode 100644 index 0000000000..c76e025a5c --- /dev/null +++ b/widget/ui/src/components/Select/Select.types.ts @@ -0,0 +1,19 @@ +import type * as Stitches from '@stitches/react'; + +type Item = { + value: T; + label: string; +}; + +type Variant = 'filled' | 'outlined'; + +export type SelectPropTypes = { + options: Item[]; + handleItemClick?: (item: Item) => void; + value: string; + container?: HTMLElement; + variant: Variant; + styles?: { + trigger?: Stitches.CSS; + }; +}; diff --git a/widget/ui/src/components/Select/index.ts b/widget/ui/src/components/Select/index.ts new file mode 100644 index 0000000000..5b3aecc760 --- /dev/null +++ b/widget/ui/src/components/Select/index.ts @@ -0,0 +1,2 @@ +export { SelectComponent as Select } from './Select.js'; +export type { SelectPropTypes } from './Select.types.js'; diff --git a/widget/ui/src/components/SelectableCategoryList/SelectableCategoryList.helpers.ts b/widget/ui/src/components/SelectableCategoryList/SelectableCategoryList.helpers.ts new file mode 100644 index 0000000000..49e27b3ee4 --- /dev/null +++ b/widget/ui/src/components/SelectableCategoryList/SelectableCategoryList.helpers.ts @@ -0,0 +1,62 @@ +import { type BlockchainMeta, TransactionType } from 'rango-types'; + +import { + CosmosCategoryIcon, + EvmCategoryIcon, + OtherCategoryIcon, + UtxoCategoryIcon, +} from '../../icons/index.js'; + +import { BlockchainCategories } from './SelectableCategoryList.types.js'; + +export const blockchainCategoryIcons = { + [BlockchainCategories.EVM]: EvmCategoryIcon, + [BlockchainCategories.COSMOS]: CosmosCategoryIcon, + [BlockchainCategories.UTXO]: UtxoCategoryIcon, + [BlockchainCategories.OTHER]: OtherCategoryIcon, +}; + +export const blockchainCategoryLabel = { + [BlockchainCategories.ALL]: 'All', + [BlockchainCategories.EVM]: 'EVM', + [BlockchainCategories.COSMOS]: 'Cosmos', + [BlockchainCategories.UTXO]: 'UTXO', + [BlockchainCategories.OTHER]: 'Other', +}; + +const filterByType = (blockchain: BlockchainMeta, type: string): boolean => { + switch (type) { + case BlockchainCategories.ALL: + return true; + case BlockchainCategories.UTXO: + return blockchain.type === TransactionType.TRANSFER; + case BlockchainCategories.OTHER: + return ( + blockchain.type !== TransactionType.TRANSFER && + blockchain.type !== TransactionType.COSMOS && + blockchain.type !== TransactionType.EVM + ); + default: + return blockchain.type === type; + } +}; + +export const hasAnyCategory = ( + list: BlockchainMeta[], + blockchainType: string +) => list.some((blockchain) => filterByType(blockchain, blockchainType)); + +export const getCategoriesCount = (list: BlockchainMeta[]) => { + const categoriesToCheck = Object.values(BlockchainCategories).filter( + (category) => category !== BlockchainCategories.ALL + ); + + const categoriesCount = categoriesToCheck.reduce((count, category) => { + const isCategoryPresent = list.some((blockchain) => + filterByType(blockchain, category) + ); + return count + (isCategoryPresent ? 1 : 0); + }, 0); + + return categoriesCount; +}; diff --git a/widget/ui/src/components/SelectableCategoryList/SelectableCategoryList.styles.ts b/widget/ui/src/components/SelectableCategoryList/SelectableCategoryList.styles.ts new file mode 100644 index 0000000000..c1623cf105 --- /dev/null +++ b/widget/ui/src/components/SelectableCategoryList/SelectableCategoryList.styles.ts @@ -0,0 +1,21 @@ +import { styled } from '../../theme.js'; + +export const Container = styled('div', { + display: 'grid', + gap: '$10', + gridTemplateColumns: 'auto 1fr 1fr 1fr 1fr', +}); + +export const ImageContent = styled('div', { + display: 'flex', + position: 'relative', + alignItems: 'center', + justifyContent: 'center', + paddingTop: '$10', +}); +export const FirstImage = styled('img', { + position: 'absolute', + top: -2, + width: 15, + height: 15, +}); diff --git a/widget/ui/src/components/SelectableCategoryList/SelectableCategoryList.tsx b/widget/ui/src/components/SelectableCategoryList/SelectableCategoryList.tsx new file mode 100644 index 0000000000..c58a72c93e --- /dev/null +++ b/widget/ui/src/components/SelectableCategoryList/SelectableCategoryList.tsx @@ -0,0 +1,77 @@ +/* eslint-disable @typescript-eslint/no-magic-numbers */ +import type { SelectableCategoryListPropTypes } from './SelectableCategoryList.types.js'; + +import { i18n } from '@lingui/core'; +import React from 'react'; + +import { BlockchainsChip } from '../BlockchainsChip/index.js'; +import { Divider, Skeleton, Typography } from '../index.js'; + +import { + blockchainCategoryIcons, + blockchainCategoryLabel, + hasAnyCategory, +} from './SelectableCategoryList.helpers.js'; +import { Container } from './SelectableCategoryList.styles.js'; +import { BlockchainCategories } from './SelectableCategoryList.types.js'; + +export function SelectableCategoryList(props: SelectableCategoryListPropTypes) { + const { setCategory, category, isLoading, blockchains } = props; + const categories = Object.keys( + BlockchainCategories + ) as BlockchainCategories[]; + return ( + + {isLoading && + Array.from(Array(5), (_, index) => ( + + ))} + {!isLoading && + categories.map((blockchainCategory) => { + const Logo = + blockchainCategory !== BlockchainCategories.ALL + ? blockchainCategoryIcons[blockchainCategory] + : null; + + const hasBlockchain = hasAnyCategory(blockchains, blockchainCategory); + + return ( + hasBlockchain && ( + setCategory(blockchainCategory)}> + {Logo && ( + <> + + + + )} + + {i18n.t({ + id: '{blockchainCategory}', + values: { + blockchainCategory: + blockchainCategoryLabel[blockchainCategory], + }, + })} + + + ) + ); + })} + + ); +} diff --git a/widget/ui/src/components/SelectableCategoryList/SelectableCategoryList.types.ts b/widget/ui/src/components/SelectableCategoryList/SelectableCategoryList.types.ts new file mode 100644 index 0000000000..a95e14217a --- /dev/null +++ b/widget/ui/src/components/SelectableCategoryList/SelectableCategoryList.types.ts @@ -0,0 +1,16 @@ +import type { BlockchainMeta } from 'rango-types'; + +export interface SelectableCategoryListPropTypes { + setCategory: (type: string) => void; + category: string; + blockchains: BlockchainMeta[]; + isLoading?: boolean; +} + +export enum BlockchainCategories { + ALL = 'ALL', + EVM = 'EVM', + COSMOS = 'COSMOS', + UTXO = 'UTXO', + OTHER = 'OTHER', +} diff --git a/widget/ui/src/components/SelectableCategoryList/index.ts b/widget/ui/src/components/SelectableCategoryList/index.ts new file mode 100644 index 0000000000..5caaebc411 --- /dev/null +++ b/widget/ui/src/components/SelectableCategoryList/index.ts @@ -0,0 +1,4 @@ +export { SelectableCategoryList } from './SelectableCategoryList.js'; +export type { SelectableCategoryListPropTypes } from './SelectableCategoryList.types.js'; +export { BlockchainCategories } from './SelectableCategoryList.types.js'; +export { getCategoriesCount } from './SelectableCategoryList.helpers.js'; diff --git a/widget/ui/src/components/SelectableWalletList/SelectableWalletList.stories.tsx b/widget/ui/src/components/SelectableWalletList/SelectableWalletList.stories.tsx deleted file mode 100644 index eda67d184e..0000000000 --- a/widget/ui/src/components/SelectableWalletList/SelectableWalletList.stories.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import React from 'react'; -import { ComponentMeta } from '@storybook/react'; - -import { SelectableWalletList, PropTypes } from './SelectableWalletList'; -import { data } from './mock'; - -export default { - title: 'Components/SelectableWalletList', - component: SelectableWalletList, -} as ComponentMeta; - -export const Main = (props: PropTypes) => ( - -); diff --git a/widget/ui/src/components/SelectableWalletList/SelectableWalletList.tsx b/widget/ui/src/components/SelectableWalletList/SelectableWalletList.tsx deleted file mode 100644 index 41358dd787..0000000000 --- a/widget/ui/src/components/SelectableWalletList/SelectableWalletList.tsx +++ /dev/null @@ -1,119 +0,0 @@ -import React, { PropsWithChildren, useEffect, useState } from 'react'; -import { styled } from '../../theme'; -import { SelectableWallet } from '../../types'; -import { Typography } from '../Typography'; -import { getConciseAddress } from '../../helper'; -import { Image } from '../common'; - -const Row = styled('div', { - display: 'flex', - flexWrap: 'wrap', -}); - -const Circle = styled('div', { - width: 12, - height: 12, - borderRadius: 6, - border: '1px solid $neutrals400', - position: 'absolute', - top: 12, - right: 12, - variants: { - checked: { - true: { - borderColor: '$success', - }, - false: { - borderColor: '$neutrals400', - }, - }, - }, -}); -const SolidCircle = styled('div', { - width: 6, - margin: '20% auto', - height: 6, - borderRadius: 3, - variants: { - checked: { - true: { - backgroundColor: '$success', - }, - false: { - backgroundColor: '$neutrals400', - }, - }, - }, -}); -const Container = styled('div', { - border: '1.5px solid', - borderRadius: '$5', - padding: '$12', - flexBasis: 'calc(33.33% - 10px)', - margin: 5, - display: 'flex', - flexDirection: 'column', - justifyContent: 'space-between', - width: 124, - height: 92, - cursor: 'pointer', - position: 'relative', - variants: { - checked: { - true: { - borderColor: '$success', - color: '$success', - }, - false: { - borderColor: '$neutrals400', - color: '$neutrals400', - }, - }, - }, -}); - -export interface PropTypes { - list: SelectableWallet[]; - onChange: (w: SelectableWallet) => void; -} - -export function SelectableWalletList({ - list, - onChange, -}: PropsWithChildren) { - const [active, setActive] = useState( - list.find((item) => item.selected)?.walletType || '' - ); - const onClick = (w: SelectableWallet) => { - setActive(w.walletType); - onChange(w); - }; - - useEffect(() => { - setActive(list.find((item) => item.selected)?.walletType || ''); - }, [list]); - - return ( - - {list.map((w, index) => { - const checked = active === w.walletType; - return ( - - {w.walletType} - {w.name} - - {getConciseAddress(w.address)} - - - - - - ); - })} - - ); -} diff --git a/widget/ui/src/components/SelectableWalletList/index.ts b/widget/ui/src/components/SelectableWalletList/index.ts deleted file mode 100644 index d07f2e905e..0000000000 --- a/widget/ui/src/components/SelectableWalletList/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { SelectableWalletList } from './SelectableWalletList'; diff --git a/widget/ui/src/components/SelectableWalletList/mock.ts b/widget/ui/src/components/SelectableWalletList/mock.ts deleted file mode 100644 index b72e6f44ee..0000000000 --- a/widget/ui/src/components/SelectableWalletList/mock.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { Network, WalletType } from '@rango-dev/wallets-shared'; -import { SelectableWallet } from '../../types'; - -export const data: SelectableWallet[] = [ - { - chain: Network.BTC, - name: Network.BTC, - walletType: WalletType.META_MASK, - address: '0x5423e28219d6d568dcf62a8134d623e6f4a1c2df', - image: 'https://app.rango.exchange/wallets/metamask.svg', - selected: true, - }, -]; diff --git a/widget/ui/src/components/Settings/Settings.stories.tsx b/widget/ui/src/components/Settings/Settings.stories.tsx deleted file mode 100644 index 8b052abdfa..0000000000 --- a/widget/ui/src/components/Settings/Settings.stories.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import React from 'react'; -import { ComponentMeta } from '@storybook/react'; -import { Settings, PropTypes } from './Settings'; -import { SwapContainer } from '../SwapContainer/SwapContainer'; -import { liquiditySources } from '../LiquiditySourceList/mockData'; - -export default { - title: 'Settings', - component: Settings, - argTypes: { - slippages: { - defaultValue: [0.5, 1, 3, 5, 8, 13, 20], - }, - selectedSlippage: { defaultValue: 3 }, - liquiditySources: { - defaultValue: liquiditySources, - }, - selectedLiquiditySources: { - defaultValue: liquiditySources.slice(0, 5), - }, - minSlippage: { - defaultValue: 1, - }, - maxSlippage: { - defaultValue: 10, - }, - }, -} as ComponentMeta; - -export const Main = (args: PropTypes) => ( - - - -); diff --git a/widget/ui/src/components/Settings/Settings.tsx b/widget/ui/src/components/Settings/Settings.tsx deleted file mode 100644 index d9d6b0110c..0000000000 --- a/widget/ui/src/components/Settings/Settings.tsx +++ /dev/null @@ -1,209 +0,0 @@ -import { styled } from '../../theme'; -import React, { useState } from 'react'; -import { AngleRightIcon } from '../Icon'; -import { SecondaryPage } from '../SecondaryPage/SecondaryPage'; -import { Typography } from '../Typography'; -import { Chip } from '../Chip'; -import { LiquiditySource, LoadingStatus } from '../../types/meta'; -import { TextField } from '../TextField'; -import { Radio } from '../Radio'; -import { Switch } from '../Switch'; -import { Button } from '../Button'; - -const BaseContainer = styled('div', { - borderRadius: '$5', - backgroundColor: '$neutrals300', - padding: '$16', -}); - -const Title = styled(Typography, { marginBottom: '$16' }); - -const SlippageChipsContainer = styled('div', { - display: 'grid', - rowGap: '$16', - gridTemplateColumns: 'repeat(auto-fill, 64px)', -}); - -const LiquiditySourceContainer = styled(BaseContainer, { - display: 'flex', - justifyContent: 'space-between', - marginTop: '$16', - cursor: 'pointer', -}); -const InfiniteContainer = styled(BaseContainer, { - display: 'flex', - justifyContent: 'space-between', - marginTop: '$16', -}); - -const StyledAngleRight = styled(AngleRightIcon, { marginLeft: '$8' }); - -const LiquiditySourceNumber = styled('div', { - display: 'flex', - alignItems: 'center', - justifyContent: 'center', -}); - -const ThemesContainer = styled(BaseContainer, { - marginTop: '$16', -}); - -const Head = styled('div', { - display: 'flex', - justifyContent: 'space-between', - alignItems: 'center', - paddingBottom: '$16', -}); - -type Theme = 'dark' | 'light' | 'auto'; - -export interface PropTypes { - slippages: number[]; - selectedSlippage: number; - customSlippage: number; - maxSlippage: number; - minSlippage: number; - liquiditySources: LiquiditySource[]; - onLiquiditySourcesClick: () => void; - selectedLiquiditySources: LiquiditySource[]; - onSlippageChange: (slippage: number) => void; - onCustomSlippageChange: (customSlippage: number | null) => void; - selectedTheme: Theme; - onThemeChange: (theme: Theme) => void; - onBack: () => void; - infiniteApprove: boolean; - toggleInfiniteApprove: (infinite: boolean) => void; - loadingStatus: LoadingStatus; -} - -export function Settings(props: PropTypes) { - const { - slippages, - selectedLiquiditySources, - liquiditySources, - onSlippageChange, - onLiquiditySourcesClick, - onBack, - customSlippage, - onCustomSlippageChange, - maxSlippage, - minSlippage, - selectedTheme, - onThemeChange, - toggleInfiniteApprove, - infiniteApprove, - loadingStatus, - } = props; - - const [selectedSlippage, setSelectedSlippage] = useState( - props.selectedSlippage - ); - - const changeSlippage = (slippage: number) => { - setSelectedSlippage(slippage); - onSlippageChange(slippage); - }; - - const PageContent = ( - <> - - - Slippage tolerance - {customSlippage ? ( - - {customSlippage}% Custom - - ) : undefined} - - - {slippages.map((slippage, index) => ( - { - if (customSlippage) onCustomSlippageChange(null); - changeSlippage(slippage); - }} - selected={!customSlippage && slippage === selectedSlippage} - label={`${slippage.toString()}%`} - style={{ - marginRight: '8px', - }} - /> - ))} - { - const parsedValue = parseFloat(event.target.value); - if ( - !parsedValue || - (parsedValue >= minSlippage && parsedValue <= maxSlippage) - ) - onCustomSlippageChange(parsedValue); - }} - suffix={ - customSlippage && % - } - size="small" - placeholder="Custom %" - style={{ - width: '128px', - flexGrow: 'initial', - }} - /> - - - - Theme - onThemeChange(value as Theme)} - direction="horizontal" - style={{ marginTop: '$24' }} - /> - - - Infinite Approval - - - - - - - ); - - return ( - - {PageContent} - - ); -} diff --git a/widget/ui/src/components/Settings/index.ts b/widget/ui/src/components/Settings/index.ts deleted file mode 100644 index ec5d9791b6..0000000000 --- a/widget/ui/src/components/Settings/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { Settings } from './Settings'; diff --git a/widget/ui/src/components/Skeleton/Skeleton.stories.tsx b/widget/ui/src/components/Skeleton/Skeleton.stories.tsx deleted file mode 100644 index b747988318..0000000000 --- a/widget/ui/src/components/Skeleton/Skeleton.stories.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import { ComponentMeta } from '@storybook/react'; -import React from 'react'; -import { Skeleton, PropTypes } from './Skeleton'; - -export default { - title: 'Components/Skeleton', - component: Skeleton, - argTypes: { - width: { - name: 'width', - control: { type: 'select' }, - options: [20, 24, 36, 48], - defaultValue: 20, - }, - height: { - name: 'height', - control: { type: 'select' }, - options: [20, 24, 36, 48], - defaultValue: 20, - }, - }, -} as ComponentMeta; - -export const Main = (props: PropTypes) => ; diff --git a/widget/ui/src/components/Skeleton/Skeleton.styles.ts b/widget/ui/src/components/Skeleton/Skeleton.styles.ts new file mode 100644 index 0000000000..6fbb010fcd --- /dev/null +++ b/widget/ui/src/components/Skeleton/Skeleton.styles.ts @@ -0,0 +1,66 @@ +import { darkTheme, keyframes, styled } from '../../theme.js'; + +const waveSquares = keyframes({ + '0%': { + backgroundPosition: '-468px 0', + }, + '100%': { + backgroundPosition: '468px 0', + }, +}); +// #2B3462 -0.15%, rgba(43, 52, 98, 0.20) 99.85% +export const SkeletonContainer = styled('div', { + $$background: + 'linear-gradient(90deg, $colors$secondary200 20%, rgba(200, 226, 255, 0.20) 70%, $colors$secondary200 100%)', + [`.${darkTheme} &`]: { + $$background: + 'linear-gradient(90deg, $colors$secondary550 0%,rgba(43, 52, 98, 0.20) 70%, $colors$secondary550 100%)', + }, + background: '$$background', + backgroundSize: '800px 100px', + animation: `${waveSquares} 2s infinite ease-out`, + variants: { + variant: { + text: { + borderRadius: '$sm', + }, + circular: { + borderRadius: '$lg', + }, + rectangular: {}, + rounded: { + borderRadius: '$sm', + }, + }, + + size: { + small: {}, + medium: {}, + large: {}, + }, + }, + + compoundVariants: [ + { + size: 'small', + variant: 'text', + css: { + height: '$8', + }, + }, + { + size: 'medium', + variant: 'text', + css: { + height: '$12', + }, + }, + { + size: 'large', + variant: 'text', + css: { + height: '$16', + }, + }, + ], +}); diff --git a/widget/ui/src/components/Skeleton/Skeleton.tsx b/widget/ui/src/components/Skeleton/Skeleton.tsx index 45f4332402..6aed4cd1e2 100644 --- a/widget/ui/src/components/Skeleton/Skeleton.tsx +++ b/widget/ui/src/components/Skeleton/Skeleton.tsx @@ -1,66 +1,17 @@ -import React from 'react'; -import { keyframes, styled } from '../../theme'; +import type { SkeletonPropTypes } from './Skeleton.types.js'; -const waveSquares = keyframes({ - '0%': { - backgroundPosition: '-468px 0', - }, - '100%': { - backgroundPosition: '468px 0', - }, -}); +import React from 'react'; -const SkeletonContainer = styled('div', { - borderRadius: '$5', - backgroundColor: '$neutrals300', - background: `linear-gradient(to right, rgba(130, 130, 130, 0.2) 8%, rgba(130, 130, 130, 0.3) 18%, rgba(130, 130, 130, 0.2) 33%)`, - backgroundSize: '800px 100px', - animation: `${waveSquares} 2s infinite ease-out`, - variants: { - width: { - 16: { - width: '$16', - }, - 20: { - width: '$20', - }, - 24: { - width: '$24', - }, - 36: { - width: '$36', - }, - 48: { - width: '$48', - }, - }, - height: { - 16: { - height: '$16', - }, - 20: { - height: '$20', - }, - 24: { - height: '$24', - }, - 36: { - height: '$36', - }, - 48: { - height: '$48', - }, - 94: { - height: 94, - }, - }, - }, -}); -export interface PropTypes { - width?: 20 | 24 | 36 | 48; - height?: 20 | 24 | 36 | 48 | 94; -} +import { SkeletonContainer } from './Skeleton.styles.js'; -export function Skeleton({ width = 20, height = 20 }: PropTypes) { - return ; +export function Skeleton(props: SkeletonPropTypes) { + const { width = '100%' } = props; + const customCss = + props.variant !== 'text' + ? { + width, + height: props.height, + } + : { width }; + return ; } diff --git a/widget/ui/src/components/Skeleton/Skeleton.types.ts b/widget/ui/src/components/Skeleton/Skeleton.types.ts new file mode 100644 index 0000000000..eb4f404ad0 --- /dev/null +++ b/widget/ui/src/components/Skeleton/Skeleton.types.ts @@ -0,0 +1,20 @@ +import type { SkeletonContainer } from './Skeleton.styles.js'; +import type { VariantProps } from '@stitches/react'; + +type BaseProps = VariantProps; +type BaseVariants = Exclude; +type BaseSizes = Exclude; + +type TextVariant = { + variant: 'text'; + size: BaseSizes; + width?: number; +}; + +type OtherVariant = { + variant: Exclude; + width?: number; + height: number; +}; + +export type SkeletonPropTypes = TextVariant | OtherVariant; diff --git a/widget/ui/src/components/Skeleton/index.ts b/widget/ui/src/components/Skeleton/index.ts index 3f34073b3f..2f60326e58 100644 --- a/widget/ui/src/components/Skeleton/index.ts +++ b/widget/ui/src/components/Skeleton/index.ts @@ -1 +1,2 @@ -export { Skeleton } from './Skeleton'; +export { Skeleton } from './Skeleton.js'; +export type { SkeletonPropTypes } from './Skeleton.types.js'; diff --git a/widget/ui/src/components/Spacer/Spacer.stories.tsx b/widget/ui/src/components/Spacer/Spacer.stories.tsx deleted file mode 100644 index a9f2b653e3..0000000000 --- a/widget/ui/src/components/Spacer/Spacer.stories.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import { ComponentMeta } from '@storybook/react'; -import React from 'react'; -import { Typography } from '../Typography'; -import { Spacer, PropTypes } from './Spacer'; - -export default { - title: 'Components/Spacer', - component: Spacer, - argTypes: { - size: { - name: 'size', - control: { type: 'select' }, - options: [12, 16, 18, 20], - defaultValue: 12, - }, - direction: { - name: 'direction', - control: { type: 'select' }, - options: ['vertical', 'horizontal'], - defaultValue: 'horizontal', - }, - }, -} as ComponentMeta; - -export const Main = (props: PropTypes) => ( -
- spacer - - spacer -
-); diff --git a/widget/ui/src/components/Spacer/Spacer.tsx b/widget/ui/src/components/Spacer/Spacer.tsx deleted file mode 100644 index 2401b45dea..0000000000 --- a/widget/ui/src/components/Spacer/Spacer.tsx +++ /dev/null @@ -1,128 +0,0 @@ -import React from 'react'; -import { styled } from '../../theme'; - -const SpacerContainer = styled('div', { - variants: { - size: { - 4: {}, - 8: {}, - 12: {}, - 16: {}, - 18: {}, - 20: {}, - 24: {}, - }, - direction: { - vertical: {}, - horizontal: {}, - }, - }, - compoundVariants: [ - { - size: 4, - direction: 'horizontal', - css: { - width: '$4', - }, - }, - { - size: 4, - direction: 'vertical', - css: { - height: '$4', - }, - }, - { - size: 8, - direction: 'horizontal', - css: { - width: '$8', - }, - }, - { - size: 8, - direction: 'vertical', - css: { - height: '$8', - }, - }, - { - size: 12, - direction: 'horizontal', - css: { - width: '$12', - }, - }, - { - size: 12, - direction: 'vertical', - css: { - height: '$12', - }, - }, - { - size: 16, - direction: 'horizontal', - css: { - width: '$16', - }, - }, - { - size: 16, - direction: 'vertical', - css: { - height: '$16', - }, - }, - { - size: 18, - direction: 'horizontal', - css: { - width: '$18', - }, - }, - { - size: 18, - direction: 'vertical', - css: { - height: '$18', - }, - }, - { - size: 20, - direction: 'horizontal', - css: { - width: '$20', - }, - }, - { - size: 20, - direction: 'vertical', - css: { - height: '$20', - }, - }, - { - size: 24, - direction: 'horizontal', - css: { - width: '$24', - }, - }, - { - size: 24, - direction: 'vertical', - css: { - height: '$24', - }, - }, - ], -}); -export interface PropTypes { - size?: 4 | 8 | 12 | 16 | 18 | 20 | 24; - direction?: 'vertical' | 'horizontal'; -} - -export function Spacer({ size = 12, direction = 'horizontal' }: PropTypes) { - return ; -} diff --git a/widget/ui/src/components/Spacer/index.ts b/widget/ui/src/components/Spacer/index.ts deleted file mode 100644 index e7a837e9eb..0000000000 --- a/widget/ui/src/components/Spacer/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { Spacer } from './Spacer'; diff --git a/widget/ui/src/components/Spinner/Spinner.stories.tsx b/widget/ui/src/components/Spinner/Spinner.stories.tsx deleted file mode 100644 index d67d8fcd19..0000000000 --- a/widget/ui/src/components/Spinner/Spinner.stories.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import { ComponentMeta } from '@storybook/react'; -import React from 'react'; -import { Spinner, PropTypes } from './Spinner'; - -export default { - title: 'Components/Spinner', - component: Spinner, - argTypes: { - color: { - name: 'color', - control: { type: 'select' }, - options: ['primary', 'error', 'warning', 'success', 'black', 'white'], - defaultValue: 'primary', - }, - - size: { - name: 'size', - control: { type: 'radio' }, - options: [16, 20, 24], - defaultValue: 16, - }, - }, -} as ComponentMeta; - -export const Main = (props: PropTypes) => ; diff --git a/widget/ui/src/components/Spinner/Spinner.styles.ts b/widget/ui/src/components/Spinner/Spinner.styles.ts new file mode 100644 index 0000000000..bc7a8e68a1 --- /dev/null +++ b/widget/ui/src/components/Spinner/Spinner.styles.ts @@ -0,0 +1,15 @@ +import { keyframes, styled } from '../../theme.js'; + +const spin = keyframes({ + '100%': { + transform: 'rotate(360deg)', + }, +}); + +export const SpinnerContainer = styled('div', { + position: 'relative', + animation: `${spin} 1.5s linear infinite`, + display: 'flex', + justifyContent: 'center', + alignItems: 'center', +}); diff --git a/widget/ui/src/components/Spinner/Spinner.tsx b/widget/ui/src/components/Spinner/Spinner.tsx index 2c9079d09e..1435fdd3cb 100644 --- a/widget/ui/src/components/Spinner/Spinner.tsx +++ b/widget/ui/src/components/Spinner/Spinner.tsx @@ -1,61 +1,16 @@ +import type { SpinnerPropTypes } from './Spinner.types.js'; + import React from 'react'; -import { keyframes, styled } from '../../theme'; -const spin = keyframes({ - '100%': { - transform: 'rotate(360deg)', - }, -}); +import { LoadingIcon } from '../../icons/index.js'; -const SpinnerContainer = styled('div', { - borderRadius: '50%', - position: 'relative', - border: `2px solid $neutrals300`, - borderRight: `2px solid`, - animation: `${spin} 1.5s linear infinite`, - margin: `0px $8`, - variants: { - color: { - primary: { - borderRightColor: '$primary', - }, - error: { - borderRightColor: '$error', - }, - warning: { - borderRightColor: '$warning', - }, - success: { - borderRightColor: '$success', - }, - black: { - borderRightColor: '$black', - }, - white: { - borderRightColor: '$white', - }, - }, - size: { - 16: { - width: '$16', - height: '$16', - }, - 20: { - width: '$20', - height: '$20', - }, - 24: { - width: '$24', - height: '$24', - }, - }, - }, -}); -export interface PropTypes { - size?: 16 | 20 | 24; - color?: 'primary' | 'error' | 'warning' | 'success' | 'black' | 'white'; -} +import { SpinnerContainer } from './Spinner.styles.js'; -export function Spinner({ size = 16, color = 'primary' }: PropTypes) { - return ; +export function Spinner(props: SpinnerPropTypes) { + const { size, color, css = {} } = props; + return ( + + + + ); } diff --git a/widget/ui/src/components/Spinner/Spinner.types.ts b/widget/ui/src/components/Spinner/Spinner.types.ts new file mode 100644 index 0000000000..93882b1768 --- /dev/null +++ b/widget/ui/src/components/Spinner/Spinner.types.ts @@ -0,0 +1,9 @@ +import type { SvgIconProps } from '../SvgIcon/index.js'; +import type * as Stitches from '@stitches/react'; + +export interface SpinnerPropTypes { + // eslint-disable-next-line @typescript-eslint/no-magic-numbers + size?: 12 | 16 | 20 | 24 | 30; + color?: SvgIconProps['color']; + css?: Stitches.CSS; +} diff --git a/widget/ui/src/components/Spinner/index.ts b/widget/ui/src/components/Spinner/index.ts index 1ce6cab2eb..cfdd2991e7 100644 --- a/widget/ui/src/components/Spinner/index.ts +++ b/widget/ui/src/components/Spinner/index.ts @@ -1 +1,2 @@ -export { Spinner } from './Spinner'; +export { Spinner } from './Spinner.js'; +export type { SpinnerPropTypes } from './Spinner.types.js'; diff --git a/widget/ui/src/components/StatusDrawer/StatusDrawer.stories.tsx b/widget/ui/src/components/StatusDrawer/StatusDrawer.stories.tsx deleted file mode 100644 index 524370e4de..0000000000 --- a/widget/ui/src/components/StatusDrawer/StatusDrawer.stories.tsx +++ /dev/null @@ -1,38 +0,0 @@ -import React, { useState } from 'react'; -import { ComponentMeta } from '@storybook/react'; -import { StatusDrawer, PropTypes } from './StatusDrawer'; -import { SwapContainer } from '../SwapContainer'; - -export default { - name: 'Components/StatusDrawer', - component: StatusDrawer, - argTypes: { - status: { - name: 'status', - control: { type: 'select' }, - options: ['continue', 'success', 'failed'], - defaultValue: 'success', - }, - title: { - name: 'title', - control: { type: 'text' }, - defaultValue: 'Swap successful', - }, - subtitle: { - name: 'subtitle', - control: { type: 'text' }, - defaultValue: - 'There are now 0.0493 BNB in 0x542...C2Df wallet on BSC chain.', - }, - }, -} as ComponentMeta; - -export const Main = (args: PropTypes) => { - const [open, setOpen] = useState(false); - return ( - - - setOpen(false)} /> - - ); -}; diff --git a/widget/ui/src/components/StatusDrawer/StatusDrawer.tsx b/widget/ui/src/components/StatusDrawer/StatusDrawer.tsx deleted file mode 100644 index f6f2e4511f..0000000000 --- a/widget/ui/src/components/StatusDrawer/StatusDrawer.tsx +++ /dev/null @@ -1,82 +0,0 @@ -import React from 'react'; -import { styled } from '../../theme'; -import { Button } from '../Button'; -import { Drawer } from '../Drawer'; -import { CheckCircleIcon, InfoCircleIcon, WarningIcon } from '../Icon'; -import { Spacer } from '../Spacer'; -import { Typography } from '../Typography'; - -export interface PropTypes { - open: boolean; - onClose: () => void; - status: 'continue' | 'success' | 'failed'; - title: string; - subtitle: string; - onSubmit?: (event: React.MouseEvent) => void; - onCancel?: (event: React.MouseEvent) => void; -} -const Header = styled('div', { - textAlign: 'center', - display: 'flex', - justifyContent: 'center', - alignItems: 'center', - marginBottom: '$16', -}); -const Footer = styled('div', { - padding: '$20', - display: 'flex', - alignItems: 'center', -}); -export function StatusDrawer({ - status = 'success', - title, - subtitle, - onSubmit, - onCancel, - ...props -}: PropTypes) { - return ( - -
- {status === 'success' ? ( - - ) : status === 'failed' ? ( - - ) : ( - - )} - {title} -
- {subtitle} - - } - footer={ -
- {status !== 'failed' && ( - - )} - - -
- } - anchor="bottom" - {...props} - /> - ); -} diff --git a/widget/ui/src/components/StatusDrawer/index.ts b/widget/ui/src/components/StatusDrawer/index.ts deleted file mode 100644 index 1232c83eaa..0000000000 --- a/widget/ui/src/components/StatusDrawer/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { StatusDrawer } from './StatusDrawer'; diff --git a/widget/ui/src/components/StepDetail/StepDetail.stories.tsx b/widget/ui/src/components/StepDetail/StepDetail.stories.tsx deleted file mode 100644 index f12d422613..0000000000 --- a/widget/ui/src/components/StepDetail/StepDetail.stories.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import React from 'react'; -import { ComponentMeta } from '@storybook/react'; -import { StepDetail, PropTypes } from './StepDetail'; - -export default { - title: 'Components/StepDetail', - component: StepDetail, - argTypes: { - logo: { - name: 'logo', - control: { type: 'text' }, - defaultValue: 'https://api.rango.exchange/tokens/COSMOS/JUNO.png', - }, - chainLogo: { - name: 'chainLogo', - control: { type: 'text' }, - defaultValue: 'https://api.rango.exchange/swappers/osmosis.png', - }, - amount: { - name: 'amount', - control: { type: 'text' }, - defaultValue: '1', - }, - symbol: { - name: 'symbol', - control: { type: 'text' }, - defaultValue: 'JUNO', - }, - blockchain: { - name: 'chainAlt', - control: { type: 'text' }, - defaultValue: 'OSMOSIS', - }, - }, -} as ComponentMeta; - -export const Main = (props: PropTypes) => ; diff --git a/widget/ui/src/components/StepDetail/StepDetail.tsx b/widget/ui/src/components/StepDetail/StepDetail.tsx deleted file mode 100644 index e173e47b73..0000000000 --- a/widget/ui/src/components/StepDetail/StepDetail.tsx +++ /dev/null @@ -1,142 +0,0 @@ -import React, { PropsWithChildren } from 'react'; -import { styled } from '../../theme'; -import { Typography } from '../Typography'; - -const StepLogoContainer = styled('div', { - position: 'relative', - width: '$28', - height: '$28', - variants: { - direction: { - vertical: { - margin: 'auto', - }, - horizontal: {}, - }, - }, -}); -const Logo = styled('img', { - width: '$28', - height: '$28', - borderRadius: '50%', -}); - -const ChainLogo = styled('div', { - position: 'absolute', - right: -4, - bottom: -4, - width: '$16', - height: '$16', - padding: '$2', - borderRadius: '50%', - backgroundColor: '$background', - border: '1px solid $neutrals400', - - img: { - width: '100%', - display: 'block', - }, -}); -const StepContainer = styled('div', { - display: 'flex', - variants: { - direction: { - horizontal: { - alignItems: 'center', - }, - vertical: { - flexDirection: 'column', - textAlign: 'center', - justifyContent: 'center', - }, - }, - success: { - true: { filter: 'none' }, - false: { - filter: 'grayscale(100%)', - }, - }, - }, -}); -const Detail = styled('div', { - variants: { - pl: { - true: { - paddingLeft: '$4', - '@lg': { - paddingLeft: '$8', - }, - }, - false: { - paddingTop: '$8', - }, - }, - }, -}); -const SubTitle = styled(Typography, { - color: '$neutrals600', - display: 'block', - paddingLeft: '$8', -}); -export interface PropTypes { - logo: string; - chainLogo: string; - amount: string; - symbol: string; - blockchain: string; - estimatedAmount?: string; - direction?: 'horizontal' | 'vertical'; - success?: boolean; -} - -export function StepDetail(props: PropsWithChildren) { - const { - logo, - chainLogo, - amount, - symbol, - blockchain, - estimatedAmount, - success = true, - direction = 'horizontal', - } = props; - return ( - - - - - {blockchain} - - - - {amount && ( - - {amount} - - )} - {!amount && estimatedAmount && ( - - {estimatedAmount} - - )} -   - - {symbol} - - - on {blockchain} - - - - ); -} diff --git a/widget/ui/src/components/StepDetail/index.ts b/widget/ui/src/components/StepDetail/index.ts deleted file mode 100644 index a1771ae71c..0000000000 --- a/widget/ui/src/components/StepDetail/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { StepDetail } from './StepDetail'; diff --git a/widget/ui/src/components/StepDetails/StepDetails.styles.ts b/widget/ui/src/components/StepDetails/StepDetails.styles.ts new file mode 100644 index 0000000000..c035e3701c --- /dev/null +++ b/widget/ui/src/components/StepDetails/StepDetails.styles.ts @@ -0,0 +1,165 @@ +import { css } from '@stitches/react'; + +import { darkTheme, styled } from '../../theme.js'; + +export const Container = styled('div', { + width: '100%', + position: 'relative', + padding: '0 0.5rem', + boxSizing: 'border-box', + border: '1px solid transparent', + variants: { + type: { + 'quote-details': { border: 'none' }, + 'swap-progress': { + backgroundColor: '$neutral100', + $$color: '$colors$neutral100', + [`.${darkTheme} &`]: { + $$color: '$colors$neutral300', + }, + borderRadius: '$xm', + padding: '$10 $15', + marginBottom: '15px', + }, + }, + state: { + default: { + borderColor: 'transparent', + }, + 'in-progress': { borderColor: '$info500' }, + completed: { + borderColor: '$success500', + }, + warning: { borderColor: '$warning500' }, + error: { borderColor: '$error500' }, + }, + }, +}); + +export const SwapperImage = styled('div', { + borderRadius: '100%', + width: '24px', + height: '24px', + overflow: 'hidden', + border: '1.5px solid transparent', + variants: { + state: { + default: { + borderColor: 'transparent', + }, + 'in-progress': { borderColor: '$info500' }, + completed: { + borderColor: '$success500', + }, + warning: { borderColor: '$warning500' }, + error: { borderColor: '$error500' }, + }, + }, +}); + +export const Alerts = styled('div', { + width: '100%', + variants: { + pb: { + true: { + paddingBottom: '35px', + }, + }, + }, +}); + +export const DashedLine = styled('div', { + borderLeft: '1px dashed $foreground', + minHeight: '64px', + margin: '0 11.5px', + alignSelf: 'stretch', + variants: { + invisible: { + true: { + visibility: 'hidden', + minHeight: 'unset', + }, + }, + }, +}); + +export const SwapperSeparator = styled('div', { + borderLeft: '1px solid transparent', + margin: '0 $12', + display: 'block', + height: '8px', + variants: { + state: { + default: { + borderColor: 'transparent', + }, + 'in-progress': { borderColor: '$info500' }, + completed: { + borderColor: '$success500', + }, + warning: { borderColor: '$warning500' }, + error: { borderColor: '$error500' }, + }, + }, +}); + +export const StepSeparator = styled('div', { + borderLeft: '1px dashed transparent', + margin: '0 $10', + alignSelf: 'stretch', + display: 'block', + height: '15px', + position: 'absolute', + top: '-16px', + left: '16px', + variants: { + state: { + default: { + borderColor: 'transparent', + }, + 'in-progress': { borderColor: '$info500' }, + completed: { + borderColor: '$success500', + }, + warning: { borderColor: '$warning500' }, + error: { borderColor: '$error500' }, + }, + }, +}); + +export const tokensContainerStyles = css({ + width: '100%', + overflow: 'hidden', +}); + +export const swappersStyles = css({ + display: 'flex', + flexDirection: 'column', + justifyContent: 'center', +}); + +export const swapperItemStyles = css({ + display: 'flex', + alignItems: 'center', +}); + +export const stepInfoStyles = css({ + display: 'flex', + flex: '1', + width: '100%', + alignItems: 'start', + variants: { + tx: { + true: { + paddingLeft: '36px', + }, + }, + }, +}); + +export const tokensStyles = css({ + display: 'flex', + paddingTop: '$5', + paddingBottom: '$10', + alignItems: 'center', +}); diff --git a/widget/ui/src/components/StepDetails/StepDetails.tsx b/widget/ui/src/components/StepDetails/StepDetails.tsx new file mode 100644 index 0000000000..fd6bf77fc2 --- /dev/null +++ b/widget/ui/src/components/StepDetails/StepDetails.tsx @@ -0,0 +1,178 @@ +import type { InternalSwap, StepDetailsProps } from './StepDetails.types.js'; + +import { i18n } from '@lingui/core'; +import React, { forwardRef, Fragment, memo, useEffect, useRef } from 'react'; + +import { ChainToken } from '../../components/ChainToken/index.js'; +import { NextIcon } from '../../icons/index.js'; +import { Image } from '../common/index.js'; +import { Divider } from '../Divider/index.js'; +import { NumericTooltip } from '../Tooltip/index.js'; +import { Typography } from '../Typography/index.js'; + +import { + Alerts, + Container, + DashedLine, + stepInfoStyles, + StepSeparator, + SwapperImage, + swapperItemStyles, + SwapperSeparator, + swappersStyles, + tokensContainerStyles, + tokensStyles, +} from './StepDetails.styles.js'; + +const StepDetailsComponent = forwardRef( + (props, parentRef) => { + const { + step, + hasSeparator, + type, + state, + isFocused, + tabIndex, + tooltipContainer, + } = props; + + const { from, to, swapper } = step; + const containerRef = useRef(null); + const isCompleted = state === 'completed' || state === 'error'; + const swappers: InternalSwap[] = step.internalSwaps?.length + ? step.internalSwaps + : [ + { + from, + to, + swapper, + }, + ]; + + useEffect(() => { + const parentElement = (parentRef as React.RefObject) + ?.current; + const childElement = containerRef.current; + if (isFocused && childElement && parentElement) { + parentElement.scrollTop = + childElement.offsetTop - parentElement.offsetTop; + } + }, [isFocused]); + + return ( + + {type === 'quote-details' && ( +
+ + + + + + {i18n.t({ + id: 'Swap on {fromChain} via {swapper}', + values: { + fromChain: step.from.chain.displayName, + swapper: step.swapper.displayName, + }, + })} + +
+ )} + + {type === 'swap-progress' && ( +
+ {hasSeparator && } + {swappers.map((swapperItem, index) => { + const key = `${swapperItem.swapper.displayName}-${index}`; + return ( + +
+ + + + + + {swapperItem?.swapper.type === 'DEX' + ? i18n.t({ + id: 'Swap on {fromChain} via {swapper}', + values: { + fromChain: swapperItem.from.chain.displayName, + swapper: swapperItem.swapper.displayName, + }, + }) + : i18n.t({ + id: 'Bridge to {toChain} via {swapper}', + values: { + toChain: swapperItem.to.chain.displayName, + swapper: swapperItem.swapper.displayName, + }, + })} + +
+ {index !== swappers.length - 1 && ( + + )} +
+ ); + })} +
+ )} + +
+ +
+
+ + + + {`${step.from.price.value} ${step.from.token.displayName}`} + + + + + + + + + + {`${ + isCompleted ? '' : '~' + }${step.to.price.value} ${ + step.to.token.displayName + }`} + +
+ + {step.alerts} + +
+
+
+ ); + } +); + +StepDetailsComponent.displayName = 'StepDetailsComponent'; + +export const StepDetails = memo(StepDetailsComponent); diff --git a/widget/ui/src/components/StepDetails/StepDetails.types.ts b/widget/ui/src/components/StepDetails/StepDetails.types.ts new file mode 100644 index 0000000000..e5f1d5abd2 --- /dev/null +++ b/widget/ui/src/components/StepDetails/StepDetails.types.ts @@ -0,0 +1,43 @@ +import type { SwapInputPropTypes } from '../../containers/SwapInput/SwapInput.types.js'; +import type { SwapperType } from 'rango-types'; +import type { ReactNode } from 'react'; + +type BaseStep = Pick; +type BaseInternalStep = { + chain: BaseStep['chain']; +} & Partial>; + +type SwapperInfo = SwapInputPropTypes['chain'] & { + type?: SwapperType; +}; + +export type InternalSwap = { + swapper: SwapperInfo; + from: BaseInternalStep; + to: BaseInternalStep; +}; + +export type Step = { + swapper: SwapperInfo; + from: BaseStep; + to: BaseStep; + error?: { + title?: string; + description?: string; + }; + alerts?: ReactNode; + state?: 'error' | 'warning'; + time?: string; + fee?: string; + internalSwaps?: InternalSwap[]; +}; + +export type StepDetailsProps = { + step: Step; + hasSeparator: boolean; + type: 'quote-details' | 'swap-progress'; + state?: 'default' | 'in-progress' | 'completed' | 'warning' | 'error'; + isFocused?: boolean; + tabIndex?: number; + tooltipContainer?: HTMLElement; +}; diff --git a/widget/ui/src/components/StepDetails/index.ts b/widget/ui/src/components/StepDetails/index.ts new file mode 100644 index 0000000000..e63f901a53 --- /dev/null +++ b/widget/ui/src/components/StepDetails/index.ts @@ -0,0 +1,2 @@ +export { StepDetails } from './StepDetails.js'; +export type { StepDetailsProps, Step } from './StepDetails.types.js'; diff --git a/widget/ui/src/components/SvgIcon/SvgIcon.style.ts b/widget/ui/src/components/SvgIcon/SvgIcon.style.ts new file mode 100644 index 0000000000..d53325583c --- /dev/null +++ b/widget/ui/src/components/SvgIcon/SvgIcon.style.ts @@ -0,0 +1,35 @@ +import { styled } from '../../theme.js'; + +export const SvgWithColor = styled('svg', { + variants: { + color: { + primary: { + color: '$primary500', + }, + secondary: { + color: '$secondary500', + }, + error: { + color: '$error500', + }, + warning: { + color: '$warning500', + }, + success: { + color: '$success500', + }, + black: { + color: '$foreground', + }, + white: { + color: '$background', + }, + info: { + color: '$info500', + }, + gray: { + color: '$neutral700', + }, + }, + }, +}); diff --git a/widget/ui/src/components/SvgIcon/SvgIcon.tsx b/widget/ui/src/components/SvgIcon/SvgIcon.tsx new file mode 100644 index 0000000000..f4920bf8a4 --- /dev/null +++ b/widget/ui/src/components/SvgIcon/SvgIcon.tsx @@ -0,0 +1,22 @@ +import type { SvgIconPropsWithChildren } from './SvgIcon.types.js'; + +import React from 'react'; + +import { SvgWithColor } from './SvgIcon.style.js'; + +export function SvgIcon(props: SvgIconPropsWithChildren) { + // eslint-disable-next-line @typescript-eslint/no-magic-numbers + const { size = '1em', color, children } = props; + const originalSvgProps = children?.props; + const commonProps = { + ...originalSvgProps, + width: size, + height: size, + color: color, + className: '_icon', + }; + + return ( + {children?.props.children} + ); +} diff --git a/widget/ui/src/components/SvgIcon/SvgIcon.types.ts b/widget/ui/src/components/SvgIcon/SvgIcon.types.ts new file mode 100644 index 0000000000..9c5c2ae120 --- /dev/null +++ b/widget/ui/src/components/SvgIcon/SvgIcon.types.ts @@ -0,0 +1,16 @@ +export interface SvgIconProps { + size?: number; + color?: + | 'primary' + | 'secondary' + | 'error' + | 'warning' + | 'success' + | 'black' + | 'white' + | 'info' + | 'gray'; +} +export type SvgIconPropsWithChildren = SvgIconProps & { + children?: React.ReactElement; +}; diff --git a/widget/ui/src/components/SvgIcon/index.ts b/widget/ui/src/components/SvgIcon/index.ts new file mode 100644 index 0000000000..f573927127 --- /dev/null +++ b/widget/ui/src/components/SvgIcon/index.ts @@ -0,0 +1,5 @@ +export { SvgIcon } from './SvgIcon.js'; +export type { + SvgIconPropsWithChildren, + SvgIconProps, +} from './SvgIcon.types.js'; diff --git a/widget/ui/src/components/SwapContainer/SwapContainer.stories.tsx b/widget/ui/src/components/SwapContainer/SwapContainer.stories.tsx deleted file mode 100644 index 2e55dd0313..0000000000 --- a/widget/ui/src/components/SwapContainer/SwapContainer.stories.tsx +++ /dev/null @@ -1,13 +0,0 @@ -import React from 'react'; -import { ComponentMeta } from '@storybook/react'; - -import { SwapContainer, PropTypes } from './SwapContainer'; - -export default { - title: 'Components/Swap Box', - component: SwapContainer, -} as ComponentMeta; - -export const Main = (args: PropTypes) => ( - -); diff --git a/widget/ui/src/components/SwapContainer/SwapContainer.tsx b/widget/ui/src/components/SwapContainer/SwapContainer.tsx deleted file mode 100644 index 8cbaa30601..0000000000 --- a/widget/ui/src/components/SwapContainer/SwapContainer.tsx +++ /dev/null @@ -1,42 +0,0 @@ -import { CSSProperties } from '@stitches/react'; -import React, { PropsWithChildren } from 'react'; -import { styled } from '../../theme'; - -const MainContainer = styled('div', { - position: 'relative', - display: 'flex', - flexDirection: 'column', - borderRadius: '$10', - boxShadow: '$s', - width: '100%', - minWidth: '375px', - maxWidth: '512px', - padding: '$16', - boxSizing: 'border-box', - backgroundColor: '$background', - variants: { - fixedHeight: { - true: { - height: '595px', - maxHeight: '595px', - }, - false: { - height: 'auto', - }, - }, - }, -}); - -export interface PropTypes { - style?: CSSProperties; - fixedHeight?: boolean; -} - -export function SwapContainer(props: PropsWithChildren) { - const { children, style, fixedHeight = true } = props; - return ( - - {children} - - ); -} diff --git a/widget/ui/src/components/SwapContainer/index.ts b/widget/ui/src/components/SwapContainer/index.ts deleted file mode 100644 index 977b884e84..0000000000 --- a/widget/ui/src/components/SwapContainer/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { SwapContainer } from './SwapContainer'; diff --git a/widget/ui/src/components/SwapDetail/SwapDetail.stories.tsx b/widget/ui/src/components/SwapDetail/SwapDetail.stories.tsx deleted file mode 100644 index 912d354802..0000000000 --- a/widget/ui/src/components/SwapDetail/SwapDetail.stories.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import React from 'react'; -import { ComponentMeta } from '@storybook/react'; -import { SwapDetail, PropTypes } from './SwapDetail'; -import { swap } from './mock'; - -export default { - title: 'Components/Swap Detail', - component: SwapDetail, - argTypes: { - status: { - name: 'status', - control: { type: 'select' }, - options: ['running', 'failed', 'success'], - defaultValue: 'running', - }, - }, -} as ComponentMeta; - -export const Main = (props: PropTypes) => ; diff --git a/widget/ui/src/components/SwapDetail/SwapDetail.tsx b/widget/ui/src/components/SwapDetail/SwapDetail.tsx deleted file mode 100644 index 4cd8ebee6d..0000000000 --- a/widget/ui/src/components/SwapDetail/SwapDetail.tsx +++ /dev/null @@ -1,104 +0,0 @@ -import React, { PropsWithChildren } from 'react'; -import { PendingSwap } from '../../containers/History/types'; -import { styled } from '../../theme'; -import { Button } from '../Button'; -import { ArrowRightIcon } from '../Icon'; -import { Spacer } from '../Spacer'; -import { Spinner } from '../Spinner'; -import { Token } from './Token'; -import { limitDecimalPlaces } from '../../helper'; - -const Container = styled('div', { - position: 'relative', - display: 'flex', - justifyContent: 'space-between', - alignItems: 'center', - padding: '$16 0', - borderBottom: '1px solid $neutrals300', - - '& > .info': { - display: 'flex', - alignItems: 'center', - }, - - '.status': { - textTransform: 'uppercase', - fontWeight: 'bold', - fontSize: '$12', - }, - - '&.failed .status': { - color: '$error', - }, - '&.success .status': { - color: '$success', - }, -}); - -export interface PropTypes { - swap: PendingSwap; - status: 'running' | 'failed' | 'success'; - onClick: (requestId: string) => void; -} - -export function SwapDetail({ - swap, - status, - onClick, -}: PropsWithChildren) { - const firstStep = swap.steps[0]; - const lastStep = swap.steps[swap.steps.length - 1]; - - return ( - - ); -} diff --git a/widget/ui/src/components/SwapDetail/Token.tsx b/widget/ui/src/components/SwapDetail/Token.tsx deleted file mode 100644 index b3e550f6d5..0000000000 --- a/widget/ui/src/components/SwapDetail/Token.tsx +++ /dev/null @@ -1,73 +0,0 @@ -import React from 'react'; -import { styled } from '../../theme'; -import { Spacer } from '../Spacer'; -import { Image } from '../common'; - -const TokenContainer = styled('div', { - display: 'flex', - alignItems: 'center', - width: '160px', - - '& .amount': { - fontWeight: 'bold', - }, - '& .estimated': { - color: '$neutrals600', - }, -}); - -const TokenImage = styled('div', { - position: 'relative', - - '.overlay': { - position: 'absolute', - right: -4, - bottom: -4, - width: '$16', - height: '$16', - padding: '$2', - borderRadius: '50%', - display: 'flex', - justifyContent: 'center', - alignItems: 'center', - backgroundColor: '$background', - border: '1px solid $neutrals400', - }, -}); - -interface PropTypes { - data: { - token: { - logo: string; - symbol: string; - }; - blockchain: { - logo: string; - name: string; - }; - amount: string; - estimatedAmount?: string; - }; -} -export function Token(props: PropTypes) { - const { - data: { token, blockchain, amount, estimatedAmount }, - } = props; - return ( - - - -
- {blockchain.name} -
-
- - {!!amount && {props.data.amount}} - {!amount && estimatedAmount && ( - {props.data.estimatedAmount} - )} - - {token.symbol} -
- ); -} diff --git a/widget/ui/src/components/SwapDetail/index.ts b/widget/ui/src/components/SwapDetail/index.ts deleted file mode 100644 index 86b6d38f23..0000000000 --- a/widget/ui/src/components/SwapDetail/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { SwapDetail } from './SwapDetail'; diff --git a/widget/ui/src/components/SwapDetail/mock.ts b/widget/ui/src/components/SwapDetail/mock.ts deleted file mode 100644 index 84d9528ad9..0000000000 --- a/widget/ui/src/components/SwapDetail/mock.ts +++ /dev/null @@ -1,276 +0,0 @@ -// @ts-nocheck -import { RoutingResultType, TransactionType } from 'rango-sdk'; -import { PendingSwap } from '../../containers/History/types'; - -export const swap: PendingSwap = { - creationTime: '1673164511955', - finishTime: '1673164550137', - requestId: '51e211d9-d61c-45d2-a4d4-1f9f7f90ee85', - inputAmount: '1', - wallets: { - OSMOSIS: { - walletType: 'keplr', - address: 'osmo1unf2rcytjxfpz8x8ar63h4qeftadptg5t0nqcl', - }, - }, - status: 'running', - isPaused: false, - extraMessage: null, - extraMessageSeverity: 'info', - extraMessageDetail: '', - extraMessageErrorCode: null, - networkStatusExtraMessage: null, - networkStatusExtraMessageDetail: null, - lastNotificationTime: null, - settings: { - slippage: '1.0', - disabledSwappersIds: [], - disabledSwappersGroups: [], - }, - simulationResult: { - resultType: RoutingResultType.OK, - outputAmount: '1.540670', - swaps: [ - { - swapperId: 'Osmosis', - swapperType: 'DEX', - swapperLogo: '', - from: { - symbol: 'JUNO', - logo: 'https://api.rango.exchange/tokens/COSMOS/JUNO.png', - address: - 'ibc/46b44899322f3cd854d2d46deef881958467cdd4b3b10086da49296bbed94bed', - blockchain: 'OSMOSIS', - blockchainLogo: 'https://api.rango.exchange/swappers/osmosis.png', - decimals: 6, - usdPrice: 1.1091996179668873, - }, - to: { - symbol: 'OSMO', - logo: 'https://api.rango.exchange/i/mJQPS2', - address: null, - blockchain: 'OSMOSIS', - decimals: 6, - blockchainLogo: 'https://api.rango.exchange/swappers/osmosis.png', - usdPrice: 0.7192435454440882, - }, - fromAmount: '1.000000', - fromAmountPrecision: null, - fromAmountMinValue: null, - fromAmountMaxValue: null, - fromAmountRestrictionType: 'EXCLUSIVE', - toAmount: '1.540670', - fee: [ - { - asset: { - blockchain: 'OSMOSIS', - symbol: 'OSMO', - address: null, - }, - expenseType: 'FROM_SOURCE_WALLET', - name: 'Network Fee', - amount: '0', - }, - ], - estimatedTimeInSeconds: 45, - swapChainType: 'INTRA_CHAIN', - routes: [ - { - nodes: [ - { - nodes: [ - { - marketName: 'pool#498', - marketId: null, - percent: 1, - }, - ], - from: 'JUNO', - fromLogo: 'https://api.rango.exchange/tokens/COSMOS/JUNO.png', - fromAddress: - 'ibc/46b44899322f3cd854d2d46deef881958467cdd4b3b10086da49296bbed94bed', - fromBlockchain: 'OSMOSIS', - to: 'ATOM', - toLogo: 'https://api.rango.exchange/tokens/COSMOS/ATOM.png', - toAddress: - 'ibc/27394fb092d2eccd56123c74f36e4c1f926001ceada9ca97ea622b25f41e5eb2', - toBlockchain: 'OSMOSIS', - }, - { - nodes: [ - { - marketName: 'pool#8', - marketId: null, - percent: 1, - }, - ], - from: 'ATOM', - fromLogo: 'https://api.rango.exchange/tokens/COSMOS/ATOM.png', - fromAddress: - 'ibc/27394fb092d2eccd56123c74f36e4c1f926001ceada9ca97ea622b25f41e5eb2', - fromBlockchain: 'OSMOSIS', - to: 'IRIS', - toLogo: 'https://api.rango.exchange/tokens/COSMOS/IRIS.png', - toAddress: - 'ibc/7c4d60aa95e5a7558b0a364860979ca34b7ff8aaf255b87af9e879374470cec0', - toBlockchain: 'OSMOSIS', - }, - { - nodes: [ - { - marketName: 'pool#7', - marketId: null, - percent: 1, - }, - ], - from: 'IRIS', - fromLogo: 'https://api.rango.exchange/tokens/COSMOS/IRIS.png', - fromAddress: - 'ibc/7c4d60aa95e5a7558b0a364860979ca34b7ff8aaf255b87af9e879374470cec0', - fromBlockchain: 'OSMOSIS', - to: 'OSMO', - toLogo: 'https://api.rango.exchange/tokens/COSMOS/OSMO.png', - toAddress: null, - toBlockchain: 'OSMOSIS', - }, - ], - }, - ], - recommendedSlippage: null, - timeStat: { - min: 6, - avg: 40, - max: 241, - }, - includesDestinationTx: false, - maxRequiredSign: 1, - warnings: [], - }, - ], - }, - validateBalanceOrFee: true, - steps: [ - { - id: 1, - fromBlockchain: 'OSMOSIS', - fromSymbol: 'JUNO', - swapperType: 'test', - fromSymbolAddress: - 'ibc/46b44899322f3cd854d2d46deef881958467cdd4b3b10086da49296bbed94bed', - fromDecimals: 6, - fromAmountPrecision: null, - fromAmountMinValue: null, - fromAmountMaxValue: null, - toBlockchainLogo: 'https://api.rango.exchange/swappers/osmosis.png', - fromBlockchainLogo: 'https://api.rango.exchange/swappers/osmosis.png', - toBlockchain: 'OSMOSIS', - fromLogo: 'https://api.rango.exchange/tokens/COSMOS/JUNO.png', - toSymbol: 'OSMO', - toSymbolAddress: null, - toDecimals: 6, - toLogo: 'https://api.rango.exchange/i/mJQPS2', - startTransactionTime: 1673164519916, - swapperId: 'Osmosis', - swapperLogo: 'https://api.rango.exchange/swappers/osmosis.png', - expectedOutputAmountHumanReadable: '1.540670', - outputAmount: '1.540658', - status: 'running', - networkStatus: null, - executedTransactionId: - '0f8f17eecc863c2d6be65ef52cfe3128ff3cd7baeddf133160bea8ccdfbf876b', - explorerUrl: [ - { - url: 'https://www.mintscan.io/osmosis/txs/0f8f17eecc863c2d6be65ef52cfe3128ff3cd7baeddf133160bea8ccdfbf876b', - description: null, - }, - ], - cosmosTransaction: { - type: TransactionType.COSMOS, - fromWalletAddress: 'osmo1unf2rcytjxfpz8x8ar63h4qeftadptg5t0nqcl', - blockChain: 'OSMOSIS', - data: { - chainId: 'osmosis-1', - account_number: 102721, - sequence: '308', - msgs: [ - { - __type: 'OsmosisSwapMessage', - type: 'osmosis/gamm/swap-exact-amount-in', - value: { - sender: 'osmo1unf2rcytjxfpz8x8ar63h4qeftadptg5t0nqcl', - routes: [ - { - pool_id: '498', - token_out_denom: - 'ibc/27394FB092D2ECCD56123C74F36E4C1F926001CEADA9CA97EA622B25F41E5EB2', - }, - { - pool_id: '8', - token_out_denom: - 'ibc/7C4D60AA95E5A7558B0A364860979CA34B7FF8AAF255B87AF9E879374470CEC0', - }, - { - pool_id: '7', - token_out_denom: 'uosmo', - }, - ], - token_in: { - denom: - 'ibc/46B44899322F3CD854D2D46DEEF881958467CDD4B3B10086DA49296BBED94BED', - amount: '1000000', - }, - token_out_min_amount: '1525264', - }, - }, - ], - protoMsgs: [ - { - type_url: '/osmosis.gamm.v1beta1.MsgSwapExactAmountIn', - value: [ - 10, 43, 111, 115, 109, 111, 49, 117, 110, 102, 50, 114, 99, 121, - 116, 106, 120, 102, 112, 122, 56, 120, 56, 97, 114, 54, 51, 104, - 52, 113, 101, 102, 116, 97, 100, 112, 116, 103, 53, 116, 48, - 110, 113, 99, 108, 18, 73, 8, -14, 3, 18, 68, 105, 98, 99, 47, - 50, 55, 51, 57, 52, 70, 66, 48, 57, 50, 68, 50, 69, 67, 67, 68, - 53, 54, 49, 50, 51, 67, 55, 52, 70, 51, 54, 69, 52, 67, 49, 70, - 57, 50, 54, 48, 48, 49, 67, 69, 65, 68, 65, 57, 67, 65, 57, 55, - 69, 65, 54, 50, 50, 66, 50, 53, 70, 52, 49, 69, 53, 69, 66, 50, - 18, 72, 8, 8, 18, 68, 105, 98, 99, 47, 55, 67, 52, 68, 54, 48, - 65, 65, 57, 53, 69, 53, 65, 55, 53, 53, 56, 66, 48, 65, 51, 54, - 52, 56, 54, 48, 57, 55, 57, 67, 65, 51, 52, 66, 55, 70, 70, 56, - 65, 65, 70, 50, 53, 53, 66, 56, 55, 65, 70, 57, 69, 56, 55, 57, - 51, 55, 52, 52, 55, 48, 67, 69, 67, 48, 18, 9, 8, 7, 18, 5, 117, - 111, 115, 109, 111, 26, 79, 10, 68, 105, 98, 99, 47, 52, 54, 66, - 52, 52, 56, 57, 57, 51, 50, 50, 70, 51, 67, 68, 56, 53, 52, 68, - 50, 68, 52, 54, 68, 69, 69, 70, 56, 56, 49, 57, 53, 56, 52, 54, - 55, 67, 68, 68, 52, 66, 51, 66, 49, 48, 48, 56, 54, 68, 65, 52, - 57, 50, 57, 54, 66, 66, 69, 68, 57, 52, 66, 69, 68, 18, 7, 49, - 48, 48, 48, 48, 48, 48, 34, 7, 49, 53, 50, 53, 50, 54, 52, - ], - }, - ], - memo: '', - source: null, - fee: { - gas: '900000', - amount: [ - { - denom: 'uosmo', - amount: '0', - }, - ], - }, - signType: 'AMINO', - rpcUrl: 'sample_rpc', - }, - rawTransfer: null, - }, - solanaTransaction: null, - evmTransaction: null, - evmApprovalTransaction: null, - transferTransaction: null, - diagnosisUrl: null, - internalSteps: null, - }, - ], -}; diff --git a/widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts b/widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts new file mode 100644 index 0000000000..f66ba4ded5 --- /dev/null +++ b/widget/ui/src/components/SwapListItem/SwapListItem.helpers.ts @@ -0,0 +1,51 @@ +import type { Status } from './SwapListItem.types.js'; + +import { i18n } from '@lingui/core'; + +export function getStatus(status: Status): string { + switch (status) { + case 'failed': + return i18n.t('Failed'); + case 'success': + return i18n.t('Completed'); + default: + return i18n.t('In progress'); + } +} + +export function formattedDateAndTime( + time: string, + onlyShowTime?: boolean +): string { + if (!time) { + return ''; + } + + const date = new Date(Number(time)); + const HOURS_IN_HALF_DAY = 12; // Constant for 12 hours + const MINUTES_IN_SINGLE_DIGIT = 10; // Constant for 10 minutes + + if (!onlyShowTime) { + const options: Intl.DateTimeFormatOptions = { + year: 'numeric', + month: 'long', + day: 'numeric', + }; + return date.toLocaleDateString(undefined, options); + } + + const hours = date.getHours(); + const minutes = date.getMinutes(); + const period = hours >= HOURS_IN_HALF_DAY ? 'pm' : 'am'; + + const formattedHours = + hours % HOURS_IN_HALF_DAY === 0 + ? HOURS_IN_HALF_DAY + : hours % HOURS_IN_HALF_DAY; + const formattedMinutes = + minutes < MINUTES_IN_SINGLE_DIGIT ? `0${minutes}` : minutes; + + const formattedTime = `${formattedHours}:${formattedMinutes} ${period}`; + + return formattedTime; +} diff --git a/widget/ui/src/components/SwapListItem/SwapListItem.styles.ts b/widget/ui/src/components/SwapListItem/SwapListItem.styles.ts new file mode 100644 index 0000000000..ac3f6bdb90 --- /dev/null +++ b/widget/ui/src/components/SwapListItem/SwapListItem.styles.ts @@ -0,0 +1,74 @@ +import { darkTheme, styled } from '../../theme.js'; + +export const Container = styled('div', { + display: 'flex', + justifyContent: 'space-between', + alignItems: 'flex-start', + flexDirection: 'column', + gap: 10, +}); + +export const Header = styled('div', { + display: 'flex', + padding: 0, + justifyContent: 'space-between', + alignItems: 'center', + alignSelf: 'stretch', +}); + +export const Main = styled('button', { + $$color: '$colors$neutral100', + [`.${darkTheme} &`]: { + $$color: '$colors$neutral300', + }, + backgroundColor: '$$color', + border: 'none', + width: '100%', + borderRadius: '$xm', + gap: 10, + padding: 15, + cursor: 'pointer', + fontFamily: 'inherit', + '&:hover': { + $$color: '$colors$secondary100', + [`.${darkTheme} &`]: { + $$color: '$colors$neutral100', + }, + backgroundColor: '$$color', + }, + '&:focus-visible': { + $$color: '$colors$secondary100', + [`.${darkTheme} &`]: { + $$color: '$colors$info700', + }, + backgroundColor: '$$color', + outline: 'none', + }, +}); + +export const Date = styled('div', { + display: 'flex', + padding: '$2', + alignItems: 'flex-start', +}); + +export const LoadingMain = styled('div', { + $$color: '$colors$neutral100', + [`.${darkTheme} &`]: { + $$color: '$colors$neutral300', + }, + backgroundColor: '$$color', + border: 'none', + width: '100%', + borderRadius: '$xm', + gap: 10, + padding: 15, +}); + +export const LoadingContainer = styled('div', { + display: 'flex', + justifyContent: 'space-between', + alignItems: 'flex-start', + flexDirection: 'column', + gap: 25, +}); diff --git a/widget/ui/src/components/SwapListItem/SwapListItem.tsx b/widget/ui/src/components/SwapListItem/SwapListItem.tsx new file mode 100644 index 0000000000..99665fb5ec --- /dev/null +++ b/widget/ui/src/components/SwapListItem/SwapListItem.tsx @@ -0,0 +1,69 @@ +import type { SwapListItemPropTypes } from './SwapListItem.types.js'; +import type { PropsWithChildren } from 'react'; + +import React from 'react'; + +import { Skeleton } from '../Skeleton/index.js'; +import { Typography } from '../Typography/index.js'; + +import { formattedDateAndTime, getStatus } from './SwapListItem.helpers.js'; +import { + Container, + Date, + Header, + LoadingContainer, + LoadingMain, + Main, +} from './SwapListItem.styles.js'; +import { StatusColors } from './SwapListItem.types.js'; +import { SwapToken } from './SwapToken.js'; + +export function SwapListItem(props: PropsWithChildren) { + if ('isLoading' in props) { + return ( + + +
+ + +
+ +
+
+ ); + } + + const { + onClick, + requestId, + creationTime, + onlyShowTime, + status, + swapTokenData, + tooltipContainer, + } = props; + return ( +
+ +
+ + + {formattedDateAndTime(creationTime, onlyShowTime)} + + + + {getStatus(status)} + +
+ +
+
+ ); +} diff --git a/widget/ui/src/components/SwapListItem/SwapListItem.types.ts b/widget/ui/src/components/SwapListItem/SwapListItem.types.ts new file mode 100644 index 0000000000..eb0c505516 --- /dev/null +++ b/widget/ui/src/components/SwapListItem/SwapListItem.types.ts @@ -0,0 +1,49 @@ +export type Status = 'running' | 'failed' | 'success'; + +export interface SwapListItemProps { + requestId: string; + creationTime: string; + status: Status; + onClick: (requestId: string) => void; + swapTokenData: SwapTokenData; + onlyShowTime?: boolean; + tooltipContainer?: HTMLElement; +} + +export interface LoadingProps { + isLoading: true; +} + +export type SwapListItemPropTypes = SwapListItemProps | LoadingProps; + +export const StatusColors = { + failed: 'error500', + running: 'info500', + success: 'success500', +}; + +export interface SwapTokenData { + from: { + token: { + image: string; + displayName: string; + }; + blockchain: { + image: string; + }; + amount: string; + realAmount: string; + }; + + to: { + token: { + image: string; + displayName: string; + }; + blockchain: { + image: string; + }; + amount: string; + realAmount: string; + }; +} diff --git a/widget/ui/src/components/SwapListItem/SwapToken.styles.ts b/widget/ui/src/components/SwapListItem/SwapToken.styles.ts new file mode 100644 index 0000000000..c8131472a5 --- /dev/null +++ b/widget/ui/src/components/SwapListItem/SwapToken.styles.ts @@ -0,0 +1,76 @@ +import { styled } from '../../theme.js'; + +export const TokenContainer = styled('div', { + display: 'flex', + padding: 0, + alignItems: 'center', + gap: 10, +}); + +export const Images = styled('div', { + display: 'flex', + padding: 0, + alignItems: 'center', + alignSelf: 'stretch', +}); + +export const Layout = styled('div', { + display: 'flex', + alignItems: 'flex-start', + variants: { + direction: { + column: { + flexDirection: 'column', + flex: '1 0 0', + }, + row: { + padding: 0, + }, + }, + }, +}); + +export const TopSection = styled('div', { + display: 'flex', + alignItems: 'center', + alignSelf: 'stretch', +}); + +export const TokenInfo = styled('div', { + display: 'flex', + padding: 0, + flexDirection: 'column', + justifyContent: 'center', + alignItems: 'flex-start', +}); + +export const Icon = styled('div', { + display: 'flex', + padding: '$4', + width: '$32', + height: '$32', + + justifyContent: 'center', + alignItems: 'center', +}); + +export const LayoutLoading = styled('div', { + display: 'flex', + alignItems: 'center', + justifyContent: 'center', +}); + +export const IconLoading = styled('div', { + display: 'flex', + width: '$24', + height: '$24', + justifyContent: 'center', + alignItems: 'center', +}); + +export const LoadingContainer = styled('div', { + display: 'flex', + padding: 0, + alignItems: 'center', + gap: 25, +}); diff --git a/widget/ui/src/components/SwapListItem/SwapToken.tsx b/widget/ui/src/components/SwapListItem/SwapToken.tsx new file mode 100644 index 0000000000..90e97cbfd9 --- /dev/null +++ b/widget/ui/src/components/SwapListItem/SwapToken.tsx @@ -0,0 +1,158 @@ +import type { PropTypes } from './SwapToken.types.js'; + +import { i18n } from '@lingui/core'; +import React from 'react'; + +import { NextIcon } from '../../icons/index.js'; +import { ChainToken } from '../ChainToken/index.js'; +import { Divider } from '../Divider/index.js'; +import { Skeleton } from '../Skeleton/index.js'; +import { NumericTooltip } from '../Tooltip/index.js'; +import { Typography } from '../Typography/index.js'; + +import { + Icon, + IconLoading, + Images, + Layout, + LayoutLoading, + TokenContainer, + TokenInfo, + TopSection, +} from './SwapToken.styles.js'; + +export function SwapToken(props: PropTypes) { + if ('isLoading' in props) { + return ( + + +
+ +
+
+ +
+
+ + + + + + + + + + + + + + + +
+ ); + } + + const { + data: { + from: { + token: fromToken, + amount: fromAmount, + blockchain: fromBlockchain, + realAmount: fromRealAmount, + }, + to: { + token: toToken, + amount: toAmount, + blockchain: toBlockchain, + realAmount: toRealAmount, + }, + }, + status, + tooltipContainer, + } = props; + + return ( + + +
+ +
+
+ +
+
+ {status === 'running' ? ( + + + + {fromToken.displayName} + + + + + + {toToken.displayName} + + + + {i18n.t('Waiting for bridge transaction')} + + + ) : ( + + + + {fromToken.displayName} + + {!!fromAmount && ( + + + {fromAmount} + + + )} + + + + + + + {toToken.displayName} + + + + {toAmount} + + + + + )} +
+ ); +} diff --git a/widget/ui/src/components/SwapListItem/SwapToken.types.ts b/widget/ui/src/components/SwapListItem/SwapToken.types.ts new file mode 100644 index 0000000000..e3770ad70f --- /dev/null +++ b/widget/ui/src/components/SwapListItem/SwapToken.types.ts @@ -0,0 +1,13 @@ +import type { + LoadingProps, + Status, + SwapTokenData, +} from './SwapListItem.types.js'; + +export interface SwapTokenProps { + data: SwapTokenData; + status: Status; + tooltipContainer?: HTMLElement; +} + +export type PropTypes = SwapTokenProps | LoadingProps; diff --git a/widget/ui/src/components/SwapListItem/index.ts b/widget/ui/src/components/SwapListItem/index.ts new file mode 100644 index 0000000000..dba21820a7 --- /dev/null +++ b/widget/ui/src/components/SwapListItem/index.ts @@ -0,0 +1,5 @@ +export { SwapListItem } from './SwapListItem.js'; +export type { + SwapTokenData, + SwapListItemPropTypes, +} from './SwapListItem.types.js'; diff --git a/widget/ui/src/components/Switch/Switch.stories.tsx b/widget/ui/src/components/Switch/Switch.stories.tsx deleted file mode 100644 index 1d207efc59..0000000000 --- a/widget/ui/src/components/Switch/Switch.stories.tsx +++ /dev/null @@ -1,9 +0,0 @@ -import { ComponentMeta } from '@storybook/react'; -import React from 'react'; -import { Switch, PropTypes } from './Switch'; - -export default { title: 'Switch', component: Switch } as ComponentMeta< - typeof Switch ->; - -export const Main = (args: PropTypes) => ; diff --git a/widget/ui/src/components/Switch/Switch.styles.tsx b/widget/ui/src/components/Switch/Switch.styles.tsx new file mode 100644 index 0000000000..d0dc15c21c --- /dev/null +++ b/widget/ui/src/components/Switch/Switch.styles.tsx @@ -0,0 +1,55 @@ +import * as RadixSwitch from '@radix-ui/react-switch'; + +import { darkTheme, styled } from '../../theme.js'; + +export const StyledSwitchRoot = styled(RadixSwitch.Root, { + boxSizing: 'border-box', + boxShadow: 'none', + width: '24px', + height: '16px', + $$color: '$colors$neutral600', + [`.${darkTheme} &`]: { + $$color: '$colors$neutral700', + }, + backgroundColor: '$$color', + border: 'none', + borderRadius: '99999px', + padding: '0', + cursor: 'pointer', + transition: 'all 0.35s', + overflow: 'hidden', + + '&[data-state="checked"]': { + $$color: '$colors$secondary500', + [`.${darkTheme} &`]: { + $$color: '$colors$secondary250', + }, + backgroundColor: '$$color', + borderColor: '$$color', + }, + '-webkit-tap-highlight-color': 'rgba(0, 0, 0, 0)', +}); + +export const StyledSwitchThumb = styled(RadixSwitch.Thumb, { + boxSizing: 'border-box', + position: 'relative', + left: '$2', + display: 'block', + width: '12px', + height: '12px', + backgroundColor: '$background', + borderColor: '$secondary100', + transition: ' transform 300ms', + borderRadius: '999999px', + willChange: 'transform', + '&:hover': { + boxShadow: 'rgba(0, 0, 0, 0.6) 0px 3px 8px', + '-moz-box-shadow': 'rgba(0, 0, 0, 0.6) 0px 3px 8px', + '-webkit-box-shadow': 'rgba(0, 0, 0, 0.6) 0px 3px 8px', + '-o-box-shadow': 'rgba(0, 0, 0, 0.6) 0px 3px 8px', + }, + + '&[data-state="checked"]': { + transform: 'translateX(8px)', + }, +}); diff --git a/widget/ui/src/components/Switch/Switch.tsx b/widget/ui/src/components/Switch/Switch.tsx index 9728b95302..f35b211cfe 100644 --- a/widget/ui/src/components/Switch/Switch.tsx +++ b/widget/ui/src/components/Switch/Switch.tsx @@ -1,51 +1,10 @@ -import React from 'react'; -import * as RadixSwitch from '@radix-ui/react-switch'; - -import { styled } from '../../theme'; - -const StyledSwitchRoot = styled(RadixSwitch.Root, { - boxSizing: 'border-box', - boxShadow: 'none', - borderStyle: 'solid', - width: '42px', - height: '22px', - backgroundColor: '$neutrals600', - borderColor: '$neutrals600', - borderRadius: '99999px', - position: 'relative', - padding: '0', - cursor: 'pointer', - - '&[data-state="checked"]': { - backgroundColor: '$success', - borderColor: '$success', - }, - '-webkit-tap-highlight-color': 'rgba(0, 0, 0, 0)', -}); +import type { SwitchPropTypes } from './Switch.types.js'; -const StyledSwitchThumb = styled(RadixSwitch.Thumb, { - position: 'absolute', - top: '0', - boxSizing: 'border-box', - display: 'block', - width: '18px', - height: '18px', - backgroundColor: '$white', - transition: ' transform 300ms', - borderRadius: '999999px', - willChange: 'transform', - - '&[data-state="checked"]': { - transform: 'translateX(20px)', - }, -}); +import React from 'react'; -export interface PropTypes { - checked: boolean; - onChange?: (checked: boolean) => void; -} +import { StyledSwitchRoot, StyledSwitchThumb } from './Switch.styles.js'; -export function Switch(props: PropTypes) { +export function Switch(props: SwitchPropTypes) { const { checked, onChange } = props; return ( diff --git a/widget/ui/src/components/Switch/Switch.types.tsx b/widget/ui/src/components/Switch/Switch.types.tsx new file mode 100644 index 0000000000..67eafe83d2 --- /dev/null +++ b/widget/ui/src/components/Switch/Switch.types.tsx @@ -0,0 +1,4 @@ +export interface SwitchPropTypes { + checked: boolean; + onChange?: (checked: boolean) => void; +} diff --git a/widget/ui/src/components/Switch/index.ts b/widget/ui/src/components/Switch/index.ts index cee89a18b1..bfc68058ca 100644 --- a/widget/ui/src/components/Switch/index.ts +++ b/widget/ui/src/components/Switch/index.ts @@ -1 +1,2 @@ -export { Switch } from './Switch'; +export { Switch } from './Switch.js'; +export type { SwitchPropTypes } from './Switch.types.js'; diff --git a/widget/ui/src/components/Tabs/Tabs.styles.tsx b/widget/ui/src/components/Tabs/Tabs.styles.tsx new file mode 100644 index 0000000000..0e63a01761 --- /dev/null +++ b/widget/ui/src/components/Tabs/Tabs.styles.tsx @@ -0,0 +1,238 @@ +import { darkTheme, styled } from '../../theme.js'; +import { Button } from '../Button/index.js'; +import { IconButton } from '../IconButton/IconButton.js'; + +export const Container = styled('div', { + position: 'relative', + variants: { + hasPadding: { + true: { + padding: '0 $32', + }, + }, + }, +}); + +export const Arrow = styled(IconButton, { + position: 'absolute', + height: '100%', + zIndex: 20, + borderRadius: '$xs !important', + variants: { + hidden: { + true: { + visibility: 'hidden', + }, + }, + }, +}); + +export const ArrowRight = styled(Arrow, { + right: 0, +}); + +export const ArrowLeft = styled(Arrow, { + left: 0, +}); + +export const Tabs = styled('div', { + display: 'flex', + flexDirection: 'row', + position: 'relative', + justifyContent: 'space-between', + height: '100%', + variants: { + type: { + secondary: { + border: '3px solid $neutral100', + backgroundColor: '$neutral100', + }, + primary: { + $$color: '$colors$neutral200', + [`.${darkTheme} &`]: { + $$color: '$colors$neutral500', + }, + borderColor: '$$color', + borderWidth: '5px', + borderStyle: 'solid', + backgroundColor: '$$color', + }, + bordered: {}, + }, + borderRadius: { + small: { + borderRadius: '$xs', + }, + medium: { + borderRadius: '$sm', + }, + full: { + borderRadius: '$xm', + }, + none: { + borderRadius: 'unset', + }, + }, + scrollable: { + true: { + overflowX: 'auto', + scrollBehavior: 'smooth', + scrollbarWidth: 'none', + '&::webkit-scrollbar': { + display: 'none', + }, + }, + }, + }, +}); + +export const Tab = styled(Button, { + color: '$neutral700', + flex: 1, + backgroundColor: 'transparent', + height: '100%', + zIndex: 10, + '& ._text': { + display: 'flex', + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'center', + }, + variants: { + borderRadius: { + small: { + borderRadius: '$xs', + }, + medium: { + borderRadius: '$sm', + }, + full: { + borderRadius: '$xm', + }, + none: { + borderRadius: 'unset', + }, + }, + type: { + primary: { + padding: '$5 $10', + height: '100%', + }, + secondary: {}, + bordered: { + padding: '$10 $20', + }, + }, + isActive: { + true: { + transition: 'color 0.8s linear', + }, + false: {}, + }, + }, + + compoundVariants: [ + { + type: 'secondary', + isActive: true, + css: { + $$color: '$colors$background', + [`.${darkTheme} &`]: { + $$color: '$colors$foreground', + }, + color: '$$color', + }, + }, + { + type: 'secondary', + isActive: false, + css: { + '&:hover': { + backgroundColor: '$secondary100', + color: '$secondary500', + [`.${darkTheme} &`]: { + backgroundColor: 'transparent', + color: '$neutral700', + }, + }, + }, + }, + + { + type: 'primary', + isActive: true, + css: { + color: '$secondary', + '& svg': { + color: '$secondary', + }, + }, + }, + { + type: 'primary', + isActive: false, + css: { + '&:hover': { + backgroundColor: 'transparent', + }, + }, + }, + { + type: 'bordered', + isActive: true, + css: { + color: '$secondary500', + }, + }, + { + type: 'bordered', + isActive: false, + css: { + color: '$neutral600', + fontWeight: '$regular', + '&:hover': { + color: '$secondary550', + }, + }, + }, + ], +}); + +export const BackdropTab = styled('div', { + padding: '$4', + boxSizing: 'border-box', + position: 'absolute', + inset: 0, + transition: 'transform 0.2s cubic-bezier(0, 0, 0.86, 1.2)', + '&.no-transition': { + transition: 'none', + }, + variants: { + type: { + secondary: { + backgroundColor: '$secondary500', + }, + primary: { + backgroundColor: '$background', + }, + bordered: { + borderRadius: '0 !important', + borderBottom: '$secondary500 solid 2px', + }, + }, + borderRadius: { + small: { + borderRadius: '$xs', + }, + medium: { + borderRadius: '$sm', + }, + full: { + borderRadius: '$xm', + }, + none: { + borderRadius: 'unset', + }, + }, + }, +}); diff --git a/widget/ui/src/components/Tabs/Tabs.tsx b/widget/ui/src/components/Tabs/Tabs.tsx new file mode 100644 index 0000000000..5820c95f44 --- /dev/null +++ b/widget/ui/src/components/Tabs/Tabs.tsx @@ -0,0 +1,225 @@ +import type { TabsPropTypes } from './Tabs.types.js'; + +import React, { useEffect, useRef, useState } from 'react'; +import { ChevronLeftIcon, ChevronRightIcon } from 'src/icons/index.js'; + +import { Divider } from '../Divider/index.js'; +import { Tooltip } from '../Tooltip/index.js'; + +import { + ArrowLeft, + ArrowRight, + BackdropTab, + Container, + Tab, + Tabs, +} from './Tabs.styles.js'; + +const INITIAL_RENDER_DELAY = 100; +export function TabsComponent(props: TabsPropTypes) { + const { + items: tabItems, + onChange, + container = document.body, + value, + type, + className, + scrollable, + scrollButtons = true, + } = props; + const [tabWidth, setTabWidth] = useState(0); + const tabRef = useRef(null); + const containerRef = useRef(null); + const leftArrowRef = useRef(null); + const currentIndex = tabItems.findIndex((item) => item.id === value); + // State variable to track the initial render + const [initialRender, setInitialRender] = useState(true); + const [transformPosition, setTransformPosition] = useState(0); + const [leftArrowDisabled, setLeftArrowDisabled] = useState(true); + const [rightArrowDisabled, setRightArrowDisabled] = useState(false); + const [showArrows, setShowArrows] = useState(false); + + let borderRadius: TabsPropTypes['borderRadius'] = 'medium'; + if (type === 'bordered') { + borderRadius = 'none'; + } else if (type && props.borderRadius) { + borderRadius = props.borderRadius; + } + + const handleScroll = (to: 'right' | 'left') => { + if (!containerRef.current) { + return; + } + const SCROLL_MULTIPLIER = 1.5; + const scrollWidth = + (containerRef.current.scrollWidth / tabItems.length) * SCROLL_MULTIPLIER; + + if (to === 'right') { + containerRef.current.scrollLeft -= scrollWidth; + } else { + containerRef.current.scrollLeft += scrollWidth; + } + }; + + const updateIndicator = () => { + if (tabRef.current && containerRef.current) { + const tabRect = tabRef.current.getBoundingClientRect(); + const containerRect = containerRef.current.getBoundingClientRect(); + setTabWidth(tabRect.width); + setTransformPosition(tabRef.current.offsetLeft); + const itemPartiallyVisibleOnLeft = tabRect.left < containerRect.left; + const itemPartiallyVisibleOnRight = tabRect.right > containerRect.right; + + if (itemPartiallyVisibleOnLeft) { + containerRef.current.scrollLeft = tabRef.current.offsetLeft; + } else if (itemPartiallyVisibleOnRight) { + const containerComputedStyles = window.getComputedStyle( + containerRef.current + ); + containerRef.current.scrollLeft = + containerRef.current.scrollLeft + + tabRect.right - + containerRect.right + + parseFloat(containerComputedStyles.borderRightWidth); + } + } + }; + + useEffect(() => { + // Set initialRender to false after a short delay + const timeout = setTimeout(() => { + setInitialRender(false); + clearTimeout(timeout); + }, INITIAL_RENDER_DELAY); + }, []); + + useEffect(() => { + updateIndicator(); + + const updateArrowsVisibility = () => { + if (scrollable && containerRef.current) { + const startOfTheScroll = containerRef.current.scrollLeft === 0; + const endOfTheScroll = + containerRef.current.scrollLeft + containerRef.current.clientWidth === + containerRef.current.scrollWidth; + + if (startOfTheScroll) { + setLeftArrowDisabled(true); + } else { + setLeftArrowDisabled(false); + } + if (endOfTheScroll) { + setRightArrowDisabled(true); + } else { + setRightArrowDisabled(false); + } + } + }; + + const resizeHandler: ResizeObserverCallback = (event) => { + updateIndicator(); + + if (!containerRef.current || !scrollable || !scrollButtons) { + return; + } + + updateArrowsVisibility(); + + const TOTAL_WIDTH_OF_ARROWS = 64; + const element = event[0].target; + const tabsContainerOverflown = + element.scrollWidth - TOTAL_WIDTH_OF_ARROWS > element.clientWidth; + + if (showArrows && !tabsContainerOverflown) { + setShowArrows(false); + } else if (element.scrollWidth > element.clientWidth) { + setShowArrows(true); + } + }; + + containerRef.current?.addEventListener('scroll', updateArrowsVisibility); + + const resizeObserver = new ResizeObserver(resizeHandler); + if (containerRef.current) { + resizeObserver.observe(containerRef.current); + } + + return () => { + if (containerRef.current) { + resizeObserver.unobserve(containerRef.current); + containerRef.current.removeEventListener( + 'scroll', + updateArrowsVisibility + ); + } + }; + }, [containerRef.current, showArrows, currentIndex]); + + return ( + + {scrollable && showArrows && scrollButtons && ( + <> + + + + )} + + {tabItems.map((item, index) => { + const isActive = item.id === value; + return ( + + onChange(item)} + size="small" + isActive={isActive} + data-active={isActive} + variant="default"> + {item.icon} + {!!item.icon && !!item.title && ( + + )} + {item.title} + + + ); + })} + + + + ); +} diff --git a/widget/ui/src/components/Tabs/Tabs.types.tsx b/widget/ui/src/components/Tabs/Tabs.types.tsx new file mode 100644 index 0000000000..7f72ec536c --- /dev/null +++ b/widget/ui/src/components/Tabs/Tabs.types.tsx @@ -0,0 +1,34 @@ +import type { Tabs } from './Tabs.styles.js'; +import type * as Stitches from '@stitches/react'; + +type BaseItem = { + id: string | number; + tooltip?: React.ReactNode; +}; + +type ItemWithTitle = BaseItem & { + title: string; + icon?: React.ReactNode; +}; + +type ItemWithIcon = BaseItem & { + icon: React.ReactNode; + title?: string; +}; + +type Item = ItemWithTitle | ItemWithIcon; +type BaseProps = Stitches.VariantProps; +type BaseType = Exclude; +type BaseBorderRadius = Exclude; + +export interface TabsPropTypes { + items: Item[]; + container?: HTMLElement; + onChange: (item: Item) => void; + value: string; + type: BaseType; + borderRadius?: BaseBorderRadius; + className?: string; + scrollable?: boolean; + scrollButtons?: boolean; +} diff --git a/widget/ui/src/components/Tabs/index.ts b/widget/ui/src/components/Tabs/index.ts new file mode 100644 index 0000000000..88684b3702 --- /dev/null +++ b/widget/ui/src/components/Tabs/index.ts @@ -0,0 +1,2 @@ +export { TabsComponent as Tabs } from './Tabs.js'; +export type { TabsPropTypes } from './Tabs.types.js'; diff --git a/widget/ui/src/components/TextField/TextField.stories.tsx b/widget/ui/src/components/TextField/TextField.stories.tsx deleted file mode 100644 index 9eaf27c4fd..0000000000 --- a/widget/ui/src/components/TextField/TextField.stories.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import React from 'react'; -import { ComponentMeta } from '@storybook/react'; - -import { TextField, PropTypes } from './TextField'; -import { SearchIcon } from '../Icon'; - -export default { - title: 'Components/Text Field', - - component: TextField, - argTypes: { - disabled: { - name: 'disabled', - type: 'boolean', - }, - placeholder: { - name: 'placeholder', - type: 'string', - }, - }, -} as ComponentMeta; - -export const Main = (args: PropTypes) => ; - -export const WithPrefix = (args: PropTypes) => ( - } /> -); - -export const WithSuffix = (args: PropTypes) => ( - } /> -); diff --git a/widget/ui/src/components/TextField/TextField.styles.ts b/widget/ui/src/components/TextField/TextField.styles.ts new file mode 100644 index 0000000000..d6c8b1aee7 --- /dev/null +++ b/widget/ui/src/components/TextField/TextField.styles.ts @@ -0,0 +1,127 @@ +import { darkTheme, styled } from '../../theme.js'; + +export const InputContainer = styled('div', { + borderRadius: '$xs', + display: 'flex', + justifyContent: 'center', + alignItems: 'center', + variants: { + fullWidth: { + true: { + width: '100%', + }, + false: { + width: 'fit-content', + }, + }, + size: { + small: { + padding: '$5 $15', + }, + large: { + padding: '$10', + borderRadius: '$xl', + }, + }, + variant: { + contained: { + $$color: '$colors$neutral100', + [`.${darkTheme} &`]: { + $$color: '$colors$neutral300', + }, + backgroundColor: '$$color', + '&:hover': { + $$color: '$colors$secondary100', + [`.${darkTheme} &`]: { + $$color: '$colors$neutral100', + }, + backgroundColor: '$$color', + }, + }, + outlined: { + backgroundColor: 'transparent', + border: '1px solid $neutral100', + '&:hover': { + $$color: '$colors$secondary100', + [`.${darkTheme} &`]: { + $$color: '$colors$neutral400', + }, + borderColor: '$$color', + }, + }, + ghost: { + background: 'transparent', + }, + }, + + disabled: { + true: {}, + false: {}, + }, + }, + + compoundVariants: [ + { + variant: 'contained', + disabled: true, + css: { + '&:hover': { + backgroundColor: '$neutral100', + }, + }, + }, + { + variant: 'outlined', + disabled: true, + css: { + '&:hover': { + borderColor: '$neutral100', + }, + }, + }, + ], +}); + +export const Input = styled('input', { + flexGrow: 1, + color: '$foreground', + fontSize: '$14', + lineHeight: '$20', + fontWeight: 400, + border: 'none', + outline: 'none', + fontFamily: 'inherit', + maxWidth: '100%', + variants: { + suffix: { + true: { marginRight: '$10' }, + }, + }, + backgroundColor: 'transparent', + '-webkit-appearance': 'none', + margin: 0, + '&:disabled': { + cursor: 'not-allowed', + }, + '&::-webkit-outer-spin-button, &::-webkit-inner-spin-button': { + '-webkit-appearance': 'none', + margin: 0, + }, + '&[type="number"]': { + '-moz-appearance': 'textfield', + }, + + '&::placeholder, &::-webkit-input-placeholder': { + color: '$neutral700', + [`.${darkTheme} &`]: { + color: '$neutral900', + }, + }, + '&:focus-visible': { + outline: 'none', + }, +}); + +export const Label = styled('label', { + display: 'inline-block', +}); diff --git a/widget/ui/src/components/TextField/TextField.tsx b/widget/ui/src/components/TextField/TextField.tsx index 1f23160e12..2c58eb12c2 100644 --- a/widget/ui/src/components/TextField/TextField.tsx +++ b/widget/ui/src/components/TextField/TextField.tsx @@ -1,149 +1,86 @@ -import React, { PropsWithChildren, RefObject } from 'react'; +import type { Ref, TextFieldPropTypes } from './TextField.types.js'; +import type { PropsWithChildren } from 'react'; -import { styled } from '../../theme'; +import React from 'react'; -const InputContainer = styled('div', { - backgroundColor: '$background', - padding: '1px', - boxSizing: 'border-box', - border: '1px solid $neutrals400', - borderRadius: '$5', - height: '$48', - display: 'flex', - flexGrow: 1, - position: 'relative', - alignItems: 'center', - color: '$foreground', - overflowX: 'hidden', - transition: 'border-color ease .3s', - '&:focus-within': { - borderColor: '$success', - outline: '1px solid $success', - }, - variants: { - size: { - small: { - height: '$32', - }, - medium: { - height: '$40', - }, - large: { - height: '$48', - }, - }, - disabled: { - true: { - backgroundColor: '$neutrals300', - cursor: 'not-allowed', - filter: 'grayscale(100%)', - }, - }, - prefix: { - true: { - paddingLeft: '$16', - }, - false: { - paddingLeft: '$0', - }, - }, - suffix: { - true: { - paddingRight: '$16', - }, - false: { - paddingRight: '$0', - }, - }, - }, - defaultVariants: { - size: 'medium', - }, -}); +import { Divider } from '../Divider/index.js'; +import { Typography } from '../Typography/index.js'; -const Input = styled('input', { - color: '$foreground', - paddingLeft: '$16', - paddingRight: '$16', - flexGrow: 1, - width: '100%', - border: 'none', - borderRadius: '$5', - outline: 'none', - fontSize: '$l', - backgroundColor: 'transparent', - '-webkit-appearance': 'none', - margin: 0, - '&:disabled': { - cursor: 'not-allowed', - }, - '&::-webkit-outer-spin-button, &::-webkit-inner-spin-button': { - '-webkit-appearance': 'none', - margin: 0, - }, - '&[type="number"]': { - '-moz-appearance': 'textfield', - }, -}); -const Label = styled('label', { - display: 'inline-block', - fontSize: '$14', - color: '$foreground', - marginBottom: '$4', -}); +import { Input, InputContainer, Label } from './TextField.styles.js'; -export type PropTypes = { - label?: string; - prefix?: React.ReactNode; - suffix?: React.ReactNode; - size?: 'small' | 'medium' | 'large'; -} & Omit, 'prefix' | 'size'> & { - ref?: - | ((instance: HTMLInputElement | null) => void) - | React.RefObject - | null - | undefined; +function TextFieldComponent( + props: PropsWithChildren, + ref?: Ref +) { + const { + label, + prefix, + suffix, + size = 'small', + style, + variant, + fullWidth, + labelProps, + ...inputAttributes + } = props; + + const handleKeyDown = (event: React.KeyboardEvent) => { + if (inputAttributes?.type === 'number') { + const disallowedKeys = ['-', '+']; + if (disallowedKeys.includes(event.key)) { + event.preventDefault(); + } + } + }; + + const handlePaste = (event: React.ClipboardEvent) => { + if (inputAttributes?.type === 'number') { + const data = event.clipboardData.getData('text'); + const numericPattern = /^\d+(\.\d+)?$/; + if (!numericPattern.test(data)) { + event.preventDefault(); + } + } }; -export const TextField = React.forwardRef( - ( - props: PropsWithChildren, - ref: - | RefObject - | ((instance: HTMLInputElement | null) => void) - | null - | undefined - ) => { - const { label, prefix, suffix, children, size, style, ...inputAttributes } = - props; - return ( - <> - {label && ( + return ( + <> + {label && ( + <> - )} - + + )} + + {prefix || null} + - {prefix || null} - - {suffix || null} - - - ); - } -); + ref={ref} + /> + {suffix || null} + + + ); +} + +const TextField = React.forwardRef(TextFieldComponent); +TextField.displayName = 'TextField'; +TextField.toString = () => '._text-field'; + +export { TextField }; diff --git a/widget/ui/src/components/TextField/TextField.types.tsx b/widget/ui/src/components/TextField/TextField.types.tsx new file mode 100644 index 0000000000..133ea4f6a1 --- /dev/null +++ b/widget/ui/src/components/TextField/TextField.types.tsx @@ -0,0 +1,24 @@ +import type { InputContainer } from './TextField.styles.js'; +import type { TypographyPropTypes } from '../Typography/index.js'; +import type * as Stitches from '@stitches/react'; + +type BaseProps = Stitches.VariantProps; +type BaseSizes = Exclude; +type BaseVariants = Exclude; + +export type Ref = + | ((instance: HTMLInputElement | null) => void) + | React.RefObject + | null + | undefined; + +export type TextFieldPropTypes = { + label?: string | React.ReactNode; + prefix?: React.ReactNode; + suffix?: React.ReactNode; + size?: BaseSizes; + variant?: BaseVariants; + fullWidth?: boolean; + labelProps?: TypographyPropTypes; + style?: Stitches.CSS; +} & Omit, 'prefix' | 'size'>; diff --git a/widget/ui/src/components/TextField/index.ts b/widget/ui/src/components/TextField/index.ts index 16355023c0..954847bf05 100644 --- a/widget/ui/src/components/TextField/index.ts +++ b/widget/ui/src/components/TextField/index.ts @@ -1 +1,2 @@ -export { TextField } from './TextField'; +export { TextField } from './TextField.js'; +export type { TextFieldPropTypes } from './TextField.types.js'; diff --git a/widget/ui/src/components/Toast/Toast.Provider.tsx b/widget/ui/src/components/Toast/Toast.Provider.tsx new file mode 100644 index 0000000000..395c5e501a --- /dev/null +++ b/widget/ui/src/components/Toast/Toast.Provider.tsx @@ -0,0 +1,129 @@ +import type { + ProviderContext, + ProviderPropTypes, + ToastPosition, + ToastPropTypes, + ToastType, +} from './Toast.types.js'; +import type { PropsWithChildren } from 'react'; + +import React, { createContext, useContext, useMemo, useState } from 'react'; +import { createPortal } from 'react-dom'; + +import { idGenerator } from './Toast.helpers.js'; +import { Toast } from './Toast.js'; +import { ToastContainer } from './Toast.styles.js'; + +const ToastContext = createContext(undefined); + +const renderToastContainer = ( + toasts: ToastPropTypes[], + position: ToastPosition +) => ( + <> + {toasts.length > 0 && ( + + {toasts.map((toast) => ( + + ))} + + )} + +); + +export const ToastProvider = (props: PropsWithChildren) => { + const generateId = useMemo(() => idGenerator(), []); + + const { children, container } = props; + const [leftTopToasts, setLeftTopToasts] = useState([]); + const [leftBottomToasts, setLeftBottomToasts] = useState( + [] + ); + const [rightTopToasts, setRightTopToasts] = useState([]); + const [rightBottomToasts, setRightBottomToasts] = useState( + [] + ); + const [centerTopToasts, setCenterTopToasts] = useState([]); + const [centerBottomToasts, setCenterBottomToasts] = useState< + ToastPropTypes[] + >([]); + + const getToastSetter = (position: ToastPosition) => { + switch (position) { + case 'right-top': + return setRightTopToasts; + case 'right-bottom': + return setRightBottomToasts; + case 'left-top': + return setLeftTopToasts; + case 'left-bottom': + return setLeftBottomToasts; + case 'center-top': + return setCenterTopToasts; + default: + return setCenterBottomToasts; + } + }; + + const handleAddToast = (content: ToastType) => { + const addToasts = () => getToastSetter(content.position); + + addToasts()((toasts) => { + const isToastExistById = toasts.find((toast) => toast.id === content.id); + if (isToastExistById) { + console.warn( + 'Trying to send a toast with an existing ID. Please update the toast ID or use it after the toast is hidden' + ); + return toasts; + } + return [ + ...toasts, + { + ...content, + id: content.id || generateId(), + }, + ]; + }); + }; + + const handleRemoveToast = (id: number | string, position: ToastPosition) => { + const removeFromToasts = () => getToastSetter(position); + + removeFromToasts()((toasts) => toasts.filter((t) => t.id !== id)); + }; + + // eslint-disable-next-line react/jsx-no-constructed-context-values + const toastApis = { + addToast: (content: ToastType) => handleAddToast(content), + removeToast: (id: number | string, position: ToastPosition) => + handleRemoveToast(id, position), + }; + + return ( + + {children} + {container && + createPortal( + <> + {renderToastContainer(rightTopToasts, 'right-top')} + {renderToastContainer(leftTopToasts, 'left-top')} + {renderToastContainer(centerTopToasts, 'center-top')} + {renderToastContainer(rightBottomToasts, 'right-bottom')} + {renderToastContainer(leftBottomToasts, 'left-bottom')} + {renderToastContainer(centerBottomToasts, 'center-bottom')} + , + container + )} + + ); +}; + +export function useToast(): ProviderContext { + const context = useContext(ToastContext); + if (!context) { + throw new Error( + 'useToast can only be used within the ToastProvider component' + ); + } + return context; +} diff --git a/widget/ui/src/components/Toast/Toast.helpers.ts b/widget/ui/src/components/Toast/Toast.helpers.ts new file mode 100644 index 0000000000..9bec2f0895 --- /dev/null +++ b/widget/ui/src/components/Toast/Toast.helpers.ts @@ -0,0 +1,12 @@ +export function idGenerator() { + let id = 1; + return () => { + id++; + return id; + }; +} + +export const TOAST_UNMOUNT_DELAY = 500; // the delay before the toast is unmounted +export const TOAST_TRANSITION_DURATION = 300; // the duration of the toast transition +export const HOVER_TRANSITION_DURATION = 200; // the duration of the toast transition hover +export const TOAST_HIDE_DELAY = 200; // the delay before the toast is invisible to shift remained toast smoothly diff --git a/widget/ui/src/components/Toast/Toast.styles.ts b/widget/ui/src/components/Toast/Toast.styles.ts new file mode 100644 index 0000000000..1c57903433 --- /dev/null +++ b/widget/ui/src/components/Toast/Toast.styles.ts @@ -0,0 +1,348 @@ +import { css, darkTheme, lightTheme, styled } from '../../theme.js'; +import { Typography } from '../Typography/index.js'; + +import { + HOVER_TRANSITION_DURATION, + TOAST_TRANSITION_DURATION, +} from './Toast.helpers.js'; + +export const toastContentStyles = css({ + transition: `transform ${HOVER_TRANSITION_DURATION}ms ease-in-out`, + '&:hover': { + transform: 'scale(0.99)', + }, +}); + +export const ToastContentContainer = styled('div', { + transition: `transform ${TOAST_TRANSITION_DURATION}ms cubic-bezier(0, 0, 0.75, 1.25)`, + cursor: 'pointer', + variants: { + isActive: { + true: {}, + }, + isVisible: { + true: {}, + }, + position: { + 'right-top': {}, + 'right-bottom': {}, + 'left-top': {}, + 'left-bottom': {}, + 'center-top': {}, + 'center-bottom': {}, + }, + }, + compoundVariants: [ + { + position: 'right-top', + isActive: true, + isVisible: true, + css: { + transform: 'translateX(0)', + maxHeight: '200px', + }, + }, + { + position: 'right-top', + isActive: false, + isVisible: true, + css: { + maxHeight: '200px', + transform: 'translateX(100%)', + }, + }, + { + position: 'right-top', + isActive: false, + isVisible: false, + css: { + maxHeight: '0px', + transform: 'translateX(100%)', + transition: `max-height ${TOAST_TRANSITION_DURATION}ms ease-in-out`, + }, + }, + { + position: 'right-bottom', + isActive: true, + isVisible: true, + css: { + transform: 'translateX(0)', + maxHeight: '200px', + }, + }, + { + position: 'right-bottom', + isActive: false, + isVisible: true, + css: { + transform: 'translateX(100%)', + maxHeight: '200px', + }, + }, + { + position: 'right-bottom', + isActive: false, + isVisible: false, + css: { + transform: 'translateX(100%)', + maxHeight: '0px', + transition: `max-height ${TOAST_TRANSITION_DURATION}ms ease-in-out`, + }, + }, + { + position: 'left-top', + isActive: true, + isVisible: true, + css: { + transform: 'translateX(0)', + maxHeight: '200px', + }, + }, + { + position: 'left-top', + isActive: false, + isVisible: true, + css: { + transform: 'translateX(-100%)', + maxHeight: '200px', + }, + }, + { + position: 'left-top', + isActive: false, + isVisible: false, + css: { + transform: 'translateX(-100%)', + maxHeight: '0px', + transition: `max-height ${TOAST_TRANSITION_DURATION}ms ease-in-out`, + }, + }, + { + position: 'left-bottom', + isActive: true, + isVisible: true, + css: { + transform: 'translateX(0)', + maxHeight: '200px', + }, + }, + { + position: 'left-bottom', + isActive: false, + isVisible: true, + css: { + transform: 'translateX(-100%)', + maxHeight: '200px', + }, + }, + { + position: 'left-bottom', + isActive: false, + isVisible: false, + css: { + transform: 'translateX(-100%)', + maxHeight: '0px', + transition: `max-height ${TOAST_TRANSITION_DURATION}ms ease-in-out`, + }, + }, + { + position: 'center-top', + isActive: true, + isVisible: true, + css: { + maxHeight: '200px', + transform: 'translateY(0)', + opacity: 1, + }, + }, + { + position: 'center-top', + isActive: false, + isVisible: true, + css: { + maxHeight: '200px', + transform: 'translateY(-1000%)', + opacity: 0, + }, + }, + { + position: 'center-top', + isActive: false, + isVisible: false, + css: { + maxHeight: '0px', + opacity: 0, + transform: 'translateY(-1000%)', + transition: `max-height ${TOAST_TRANSITION_DURATION}ms ease-in-out`, + }, + }, + { + position: 'center-bottom', + isActive: true, + isVisible: true, + css: { + transform: 'translateY(0)', + maxHeight: '200px', + opacity: 1, + }, + }, + { + position: 'center-bottom', + isActive: false, + isVisible: true, + css: { + transform: 'translateY(1000%)', + maxHeight: '200px', + opacity: 0, + }, + }, + { + position: 'center-bottom', + isActive: false, + isVisible: false, + css: { + transform: 'translateY(1000%)', + maxHeight: '0px', + opacity: 0, + transition: `max-height ${TOAST_TRANSITION_DURATION}ms ease-in-out`, + }, + }, + ], +}); + +export const ToastContainer = styled('div', { + overflow: 'hidden', + position: 'absolute', + zIndex: 9999, + display: 'flex', + gap: '$4', + flexDirection: 'column', + variants: { + position: { + 'right-top': { + right: 12, + top: 2, + }, + 'right-bottom': { + right: 12, + bottom: 2, + flexDirection: 'column-reverse', + }, + 'left-top': { + left: 12, + top: 2, + }, + 'left-bottom': { + left: 12, + bottom: 2, + flexDirection: 'column-reverse', + }, + 'center-top': { + left: '50%', + transform: 'translateX(-50%)', + top: 2, + }, + 'center-bottom': { + left: '50%', + transform: 'translateX(-50%)', + bottom: 2, + flexDirection: 'column-reverse', + }, + }, + }, +}); + +export const AlertBox = styled('div', { + display: 'flex', + borderRadius: '$sm', + width: '292px', + minHeight: '52px', + variants: { + variant: { + custom: { + backgroundColor: '$background', + borderRight: '1px solid', + '&:hover': { + backgroundColor: '$secondary100', + [`.${darkTheme} &`]: { + backgroundColor: '$neutral300', + }, + }, + }, + standard: { + '& ._alert': { + padding: '$10', + width: '100%', + justifyContent: 'center', + alignItems: 'center', + }, + }, + }, + type: { + error: {}, + success: {}, + warning: {}, + info: {}, + loading: {}, + }, + }, + compoundVariants: [ + { + variant: 'custom', + type: 'error', + + css: { + borderRightColor: '$error500', + }, + }, + { + variant: 'custom', + type: 'success', + css: { + borderRightColor: '$success500', + }, + }, + { + variant: 'custom', + type: 'warning', + css: { + borderRightColor: '$warning500', + }, + }, + { + variant: 'custom', + type: 'info', + css: { + borderRightColor: '$info500', + }, + }, + { + variant: 'custom', + type: 'loading', + css: { + borderRightColor: '$info500', + }, + }, + ], +}); + +export const AlertFlexContainer = styled('div', { + display: 'flex', + padding: '$10', + alignItems: 'center', +}); + +export const StyledTypography = styled(Typography, { + variants: { + hasColor: { + false: { + [`.${lightTheme} &`]: { + color: '$neutral700', + }, + [`.${darkTheme} &`]: { + color: '$neutral900', + }, + }, + }, + }, +}); diff --git a/widget/ui/src/components/Toast/Toast.tsx b/widget/ui/src/components/Toast/Toast.tsx new file mode 100644 index 0000000000..fe7624297c --- /dev/null +++ b/widget/ui/src/components/Toast/Toast.tsx @@ -0,0 +1,111 @@ +import type { ToastPropTypes } from './Toast.types.js'; + +import React, { useEffect, useState } from 'react'; + +import { CloseIcon } from '../../icons/index.js'; +import AlertIcon from '../Alert/Alert.icon.js'; +import { IconHighlight } from '../Alert/Alert.styles.js'; +import { Alert } from '../Alert/index.js'; +import { Divider } from '../Divider/index.js'; +import { IconButton } from '../IconButton/index.js'; + +import { TOAST_HIDE_DELAY, TOAST_UNMOUNT_DELAY } from './Toast.helpers.js'; +import { useToast } from './Toast.Provider.js'; +import { + AlertBox, + AlertFlexContainer, + StyledTypography, + ToastContentContainer, + toastContentStyles, +} from './Toast.styles.js'; + +export const Toast = (props: ToastPropTypes) => { + const { + id, + autoHideDuration, + onClose, + type, + title, + position, + hasCloseIcon = true, + hideOnTap = true, + variant = 'standard', + } = props; + const [isActive, setIsActive] = useState(false); + const [isVisible, setIsVisible] = useState(false); + const { removeToast } = useToast(); + useEffect(() => { + let cleanup; + + if (autoHideDuration) { + const timer = setTimeout(() => { + handleClose(); + }, autoHideDuration); + + cleanup = () => clearTimeout(timer); + } + + return cleanup; + }, [id]); + + const handleClose = () => { + setIsActive(false); + setTimeout(() => { + setIsVisible(false); + }, TOAST_HIDE_DELAY); + setTimeout(() => { + removeToast(id, position); + onClose?.(); + }, TOAST_UNMOUNT_DELAY); + }; + + useEffect(() => { + setIsVisible(true); + setTimeout(() => { + setIsActive(true); + }, 0); + }, []); + + return ( + +
+ + {variant === 'custom' ? ( + + + + + + + {props.title} + + + ) : ( + + + + ) : undefined + } + /> + )} + +
+
+ ); +}; diff --git a/widget/ui/src/components/Toast/Toast.types.ts b/widget/ui/src/components/Toast/Toast.types.ts new file mode 100644 index 0000000000..eb8bf54586 --- /dev/null +++ b/widget/ui/src/components/Toast/Toast.types.ts @@ -0,0 +1,33 @@ +import type { ToastContainer } from './Toast.styles.js'; +import type { Type } from '../Alert/Alert.types.js'; +import type * as Stitches from '@stitches/react'; +import type { CSSProperties } from 'react'; + +type BaseProps = Stitches.VariantProps; +export type ToastPosition = Exclude; +export interface ProviderPropTypes { + container: HTMLElement; +} + +export type ToastType = { + autoHideDuration?: number; + id?: number | string; + containerStyle?: CSSProperties; + onClose?: () => void; + position: ToastPosition; + title: string; + type: Type; + style?: CSSProperties; + hasCloseIcon?: boolean; + hideOnTap?: boolean; + variant?: 'custom' | 'standard'; +}; + +export type ToastPropTypes = ToastType & { + id: number | string; +}; + +export type ProviderContext = { + addToast: (content: ToastType) => void; + removeToast: (id: number | string, position: ToastPosition) => void; +}; diff --git a/widget/ui/src/components/Toast/index.ts b/widget/ui/src/components/Toast/index.ts new file mode 100644 index 0000000000..3843020c04 --- /dev/null +++ b/widget/ui/src/components/Toast/index.ts @@ -0,0 +1,3 @@ +export { Toast } from './Toast.js'; +export { ToastProvider, useToast } from './Toast.Provider.js'; +export type { ToastPropTypes } from './Toast.types.js'; diff --git a/widget/ui/src/components/TokenAmount/TokenAmount.styles.ts b/widget/ui/src/components/TokenAmount/TokenAmount.styles.ts new file mode 100644 index 0000000000..d342696dce --- /dev/null +++ b/widget/ui/src/components/TokenAmount/TokenAmount.styles.ts @@ -0,0 +1,33 @@ +import { css, styled } from '../../theme.js'; + +export const Container = styled('div', { + display: 'flex', + justifyContent: 'space-between', + variants: { + direction: { + vertical: { + flexDirection: 'column', + alignItems: 'start', + }, + horizontal: { flexDirection: 'row', width: '100%', alignItems: 'end' }, + }, + centerAlign: { + true: { alignItems: 'center', justifyContent: 'center' }, + }, + }, +}); + +export const tokenAmountStyles = css({ + display: 'flex', + justifyContent: 'center', + alignItems: 'center', +}); + +export const usdValueStyles = css({ + display: 'flex', + paddingTop: '$5', +}); + +export const tooltipRootStyle = { + width: 'fit-content', +}; diff --git a/widget/ui/src/components/TokenAmount/TokenAmount.tsx b/widget/ui/src/components/TokenAmount/TokenAmount.tsx new file mode 100644 index 0000000000..57219e640a --- /dev/null +++ b/widget/ui/src/components/TokenAmount/TokenAmount.tsx @@ -0,0 +1,86 @@ +import type { PropTypes } from './TokenAmount.types.js'; + +import React from 'react'; + +import { ChainToken } from '../ChainToken/index.js'; +import { Divider } from '../Divider/index.js'; +import { PriceImpact } from '../PriceImpact/index.js'; +import { ValueTypography } from '../PriceImpact/PriceImpact.styles.js'; +import { NumericTooltip } from '../Tooltip/index.js'; +import { Typography } from '../Typography/index.js'; + +import { + Container, + tokenAmountStyles, + tooltipRootStyle, + usdValueStyles, +} from './TokenAmount.styles.js'; + +export function TokenAmount(props: PropTypes) { + return ( + +
+ + + +
+ {props.label && ( + + {props.label} + + )} +
+ + + {props.price.value} + + + + {props.token.displayName} + + +
+
+
+ {props.price.usdValue && props.price.usdValue !== '0' && ( +
+ + {props.type === 'input' && ( + + + {`~$${props.price.usdValue}`} + + + )} + + {props.type === 'output' && ( + + )} +
+ )} +
+ ); +} diff --git a/widget/ui/src/components/TokenAmount/TokenAmount.types.ts b/widget/ui/src/components/TokenAmount/TokenAmount.types.ts new file mode 100644 index 0000000000..db1fa39754 --- /dev/null +++ b/widget/ui/src/components/TokenAmount/TokenAmount.types.ts @@ -0,0 +1,21 @@ +import type { SwapInputPropTypes } from '../../containers/SwapInput/SwapInput.types.js'; +import type { PriceImpactPropTypes } from '../PriceImpact/PriceImpact.types.js'; + +type BaseProps = Pick & { + chain: Pick; + direction?: 'vertical' | 'horizontal'; + centerAlign?: boolean; + label?: string; + tooltipContainer?: HTMLElement; +}; + +type InputAmountProps = { type: 'input' }; + +type OutputAmountProps = Pick< + PriceImpactPropTypes, + 'percentageChange' | 'warningLevel' +> & { + type: 'output'; +}; + +export type PropTypes = BaseProps & (InputAmountProps | OutputAmountProps); diff --git a/widget/ui/src/components/TokenAmount/index.ts b/widget/ui/src/components/TokenAmount/index.ts new file mode 100644 index 0000000000..95356077ba --- /dev/null +++ b/widget/ui/src/components/TokenAmount/index.ts @@ -0,0 +1 @@ +export { TokenAmount } from './TokenAmount.js'; diff --git a/widget/ui/src/components/TokenList/TokenItem.tsx b/widget/ui/src/components/TokenList/TokenItem.tsx deleted file mode 100644 index ba4d118189..0000000000 --- a/widget/ui/src/components/TokenList/TokenItem.tsx +++ /dev/null @@ -1,76 +0,0 @@ -import { Token } from 'rango-sdk'; -import React, { CSSProperties } from 'react'; -import { styled } from '../../theme'; -import { Button } from '../Button'; -import { Typography } from '../Typography'; -import { TokenWithAmount } from './TokenList'; -import { Image } from '../common'; - -const TokenImageContainer = styled('div', { - paddingRight: '$16', -}); - -const TokenNameContainer = styled('div', { - display: 'flex', - flexDirection: 'column', -}); - -const TokenAmountContainer = styled('div', { - display: 'flex', - flexDirection: 'column', - alignItems: 'flex-end', -}); - -interface PropTypes { - token: TokenWithAmount; - selected: boolean; - onClick: (token: Token) => void; - style?: CSSProperties; -} - -export function TokenItem(props: PropTypes) { - const { token, style, onClick, selected } = props; - return ( -
- -
- ); -} diff --git a/widget/ui/src/components/TokenList/TokenList.stories.tsx b/widget/ui/src/components/TokenList/TokenList.stories.tsx deleted file mode 100644 index 1a3e748d0a..0000000000 --- a/widget/ui/src/components/TokenList/TokenList.stories.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import React from 'react'; -import { ComponentMeta } from '@storybook/react'; -import { TokenList, PropTypes } from './TokenList'; -import { tokensMeta } from './mockData'; - -export default { - title: 'Token List', - component: TokenList, - argTypes: { - searchedText: { - defaultValue: '', - }, - }, -} as ComponentMeta; - -export const Main = (args: PropTypes) => ( - -); diff --git a/widget/ui/src/components/TokenList/TokenList.tsx b/widget/ui/src/components/TokenList/TokenList.tsx deleted file mode 100644 index f5f645e485..0000000000 --- a/widget/ui/src/components/TokenList/TokenList.tsx +++ /dev/null @@ -1,94 +0,0 @@ -import React, { forwardRef, useEffect, useState } from 'react'; -import { CommonProps } from 'react-window'; -import { Asset, Token } from 'rango-sdk'; -import { VirtualizedList } from '../VirtualizedList/VirtualizedList'; -import { TokenItem } from './TokenItem'; - -export interface TokenWithAmount extends Token { - balance?: { - amount: string; - usdValue: string; - }; -} - -const PAGE_SIZE = 20; -export interface PropTypes { - list: TokenWithAmount[]; - selected?: TokenWithAmount | null; - searchedText: string; - onChange: (token: TokenWithAmount) => void; - multiSelect?: boolean; - selectedList?: Asset[]; -} - -export function TokenList(props: PropTypes) { - const { list, searchedText, onChange, multiSelect, selectedList } = props; - const [selected, setSelected] = useState(props.selected); - - const changeSelected = (token: TokenWithAmount) => { - setSelected(token); - onChange(token); - }; - - const isSelected = (token: Token) => { - if (multiSelect && selectedList) { - return ( - selectedList - .map((item) => item.symbol + item.address) - .indexOf(token.symbol + token.address) > -1 - ); - } - return ( - selected?.symbol === token.symbol && selected?.address === token.address - ); - }; - - const [hasNextPage, setHasNextPage] = useState(true); - const [tokens, setTokens] = useState(list); - - const loadNextPage = () => { - setTokens(list.slice(0, tokens.length + PAGE_SIZE)); - }; - - useEffect(() => { - setTokens(list.slice(0, PAGE_SIZE)); - }, [searchedText, list]); - - useEffect(() => { - setHasNextPage(list.length > tokens.length); - }, [tokens.length]); - - const innerElementType: React.FC = forwardRef( - ({ style, ...rest }, ref) => { - return ( -
- ); - } - ); - - return ( - ( - - )} - hasNextPage={hasNextPage} - itemCount={tokens.length} - loadNextPage={loadNextPage} - innerElementType={innerElementType} - size={56} - /> - ); -} diff --git a/widget/ui/src/components/TokenList/mockData.ts b/widget/ui/src/components/TokenList/mockData.ts deleted file mode 100644 index 01987c0369..0000000000 --- a/widget/ui/src/components/TokenList/mockData.ts +++ /dev/null @@ -1,1721 +0,0 @@ -import { TokenWithAmount } from './TokenList'; - -export const tokensMeta: TokenWithAmount[] = [ - { - blockchain: 'OPTIMISM', - symbol: 'ETH', - image: 'https://api.rango.exchange/i/MTyH5i', - address: null, - usdPrice: 1542.686, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Ethereum', - decimals: 18, - balance: { amount: '1', usdValue: '2000' }, - }, - { - blockchain: 'OPTIMISM', - symbol: 'USDT', - image: 'https://api.rango.exchange/i/K6j5VN', - address: '0x94b008aa00579c1307b0ef2c499ad98a8ce58e58', - usdPrice: 0.999, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Tether USD', - decimals: 6, - }, - { - blockchain: 'OPTIMISM', - symbol: 'USDC', - image: 'https://api.rango.exchange/i/e4x0s8', - address: '0x7f5c764cbc14f9669b88837ca1490cca17c31607', - usdPrice: 0.999, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'USD Coin', - decimals: 6, - }, - { - blockchain: 'OPTIMISM', - symbol: 'DAI', - image: 'https://api.rango.exchange/i/zyZx0X', - address: '0xda10009cbd5d07dd0cecc66161fc93d7c9000da1', - usdPrice: 0.999, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Dai stable coin', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'WBTC', - image: 'https://api.rango.exchange/i/VgpSRg', - address: '0x68f180fcce6836688e9084f035309e29bf0a2095', - usdPrice: 20857, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Wrapped Bitcoin', - decimals: 8, - }, - { - blockchain: 'OPTIMISM', - symbol: 'LINK', - image: 'https://api.rango.exchange/i/3pQryj', - address: '0x350a791bfc2c21f9ed5d10980dad2e2638ffa7f6', - usdPrice: 6.62, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Chainlink', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'LDO', - image: 'https://api.rango.exchange/i/sFlDfK', - address: '0xfdb794692724153d1488ccdbe0c56c252596735f', - usdPrice: 2.14, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Lido DAO Token', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'TUSD', - image: 'https://api.rango.exchange/i/PSjWmQ', - address: '0xcb59a0a753fdb7491d5f3d794316f1ade197b21e', - usdPrice: 0.999, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'TrueUSD', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'USDD', - image: 'https://api.rango.exchange/i/POAbKK', - address: '0x7113370218f31764c1b6353bdf6004d86ff6b9cc', - usdPrice: 0.973, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Decentralized USD', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'FXS', - image: 'https://api.rango.exchange/i/l9Fize', - address: '0x67ccea5bb16181e7b4109c9c2143c24a1c2205be', - usdPrice: 8.74, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Frax Share', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'FXS', - image: 'https://api.rango.exchange/i/8iiMnZ', - address: '0x1619de6b6b20ed217a58d00f37b9d47c7663feca', - usdPrice: 9.366, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Frax Share', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'MKR', - image: 'https://api.rango.exchange/i/VQJlSL', - address: '0xab7badef82e9fe11f6f33f87bc9bc2aa27f2fcb5', - usdPrice: 687.605, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Maker', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'SNX', - image: 'https://api.rango.exchange/i/JTIwj3', - address: '0x8700daec35af8ff88c16bdf0418774cb3d7599b4', - usdPrice: 2.15, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Synthetix', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'CRV', - image: 'https://api.rango.exchange/i/Z48J0v', - address: '0x0994206dfe8de6ec6920ff4d779b0d950605fb53', - usdPrice: 0.871, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Curve DAO Token', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'OP', - image: 'https://api.rango.exchange/i/FzBSoh', - address: '0x4200000000000000000000000000000000000042', - usdPrice: 1.82, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Optimism', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'LRC', - image: 'https://api.rango.exchange/i/6qsh21', - address: '0xfeaa9194f9f8c1b65429e31341a103071464907e', - usdPrice: 0.275, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'LoopringCoin V2', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'WOO', - image: 'https://api.rango.exchange/i/70som0', - address: '0x871f2f2ff935fd1ed867842ff2a7bfd051a5e527', - usdPrice: 0.2, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Wootrade Network', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'BAL', - image: 'https://api.rango.exchange/i/QYy7Tz', - address: '0xfe8b128ba8c78aabc59d4c64cee7ff28e9379921', - usdPrice: 6.54, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Balancer', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'ENS', - image: 'https://api.rango.exchange/i/Gm5AMR', - address: '0x65559aa14915a70190438ef90104769e5e890a00', - usdPrice: 13.924, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Ethereum Name Service', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'MASK', - image: 'https://api.rango.exchange/i/dEArZW', - address: '0x3390108e913824b8ead638444cc52b9abdf63798', - usdPrice: 2.789, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Mask Network', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'ZRX', - image: 'https://api.rango.exchange/i/QffHaf', - address: '0xd1917629b3e6a72e6772aab5dbe58eb7fa3c2f33', - usdPrice: 0.203, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: '0x Protocol Token', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'OCEAN', - image: 'https://api.rango.exchange/i/coinga', - address: '0x667fd83e24ca1d935d36717d305d54fa0cac991c', - usdPrice: 0.262, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Ocean Token', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'UMA', - image: 'https://api.rango.exchange/i/IARnqG', - address: '0xe7798f023fc62146e8aa1b36da45fb70855a77ea', - usdPrice: 1.828, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'UMA Voting Token v1', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'KNC', - image: 'https://api.rango.exchange/i/2iSq2j', - address: '0x4518231a8fdf6ac553b9bbd51bbb86825b583263', - usdPrice: 0.715, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Kyber Network Crystal v2', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'KNC', - image: 'https://api.rango.exchange/i/oKUZZI', - address: '0xa00e3a3511aac35ca78530c85007afcd31753819', - usdPrice: 0.719, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Kyber Network Crystal v2', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'FRAX', - image: 'https://api.rango.exchange/i/pj7dhZ', - address: '0x2e3d870790dc77a83dd1d18184acc7439a53f475', - usdPrice: 0.997, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: 'https://api.rango.exchange/i/lYlZID', - name: 'FRAX', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'FRAX', - image: 'https://api.rango.exchange/i/P2A0pz', - address: '0xea129ae043c4cb73dcb241aaa074f9e667641ba0', - usdPrice: 1.002, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Frax', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'BICO', - image: 'https://api.rango.exchange/i/hyrkJU', - address: '0xd6909e9e702024eb93312b989ee46794c0fb1c9d', - usdPrice: 0.326, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: null, - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'SPELL', - image: 'https://api.rango.exchange/i/zW5ZK2', - address: '0xe3ab61371ecc88534c522922a026f2296116c109', - usdPrice: 0.000719, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Spell Token', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'STG', - image: 'https://api.rango.exchange/i/wL7ixz', - address: '0x296f55f8fb28e498b858d0bcda06d955b2cb3f97', - usdPrice: 0.456, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'StargateToken', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'SUSD', - image: 'https://api.rango.exchange/i/ROXCuw', - address: '0x8c6f28f2f1a3c87f0f938b96d27520d9751ec8d9', - usdPrice: 0.999, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Synth sUSD', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'PERP', - image: 'https://api.rango.exchange/i/GMFIKK', - address: '0x9e1028f5f1d5ede59748ffcee5532509976840e0', - usdPrice: 0.491, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Perpetual', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'TRB', - image: 'https://api.rango.exchange/i/oLKhFP', - address: '0xaf8ca653fa2772d58f4368b0a71980e9e3ceb888', - usdPrice: 15.657, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Tellor', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'ROUTE', - image: 'https://api.rango.exchange/tokens/ETH/ROUTE.png', - address: '0x8413041a7702603d9d991f2c4add29e4e8a241f8', - usdPrice: 2.439, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: null, - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'DF', - image: 'https://api.rango.exchange/i/QlStLN', - address: '0x9e5aac1ba1a2e6aed6b32689dfcf62a509ca96f3', - usdPrice: 0.0432, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'dForce', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'SUKU', - image: 'https://api.rango.exchange/i/GysPhu', - address: '0xef6301da234fc7b0545c6e877d3359fe0b9e50a4', - usdPrice: 0.0534, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'SUKU', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'RAI', - image: 'https://api.rango.exchange/i/uZexQ7', - address: '0x7fb688ccf682d58f86d7e38e03f9d22e7705448b', - usdPrice: 2.81, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Rai Reflex Index', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'ACX', - image: 'https://api.rango.exchange/i/REjipe', - address: '0xff733b2a3557a7ed6697007ab5d11b79fdd1b76b', - usdPrice: 0.0463, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Across Protocol Token', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'KROM', - image: 'https://api.rango.exchange/i/2ReiyM', - address: '0xf98dcd95217e15e05d8638da4c91125e59590b07', - usdPrice: 0.0666, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Kromatika', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'RGT', - image: 'https://api.rango.exchange/i/iSkRTz', - address: '0xb548f63d4405466b36c0c0ac3318a22fdcec711a', - usdPrice: 0.401, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Rari Governance Token', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'DFYN', - image: 'https://api.rango.exchange/tokens/ETH/DFYN.png', - address: '0xf44ff799ea2bbfec96f9a50498209aac3c2b3b8b', - usdPrice: 0.029, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: null, - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'XCHF', - image: 'https://api.rango.exchange/i/BEfoyQ', - address: '0xe4f27b04cc7729901876b44f4eaa5102ec150265', - usdPrice: 1.078, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'CryptoFranc', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'DHT', - image: 'https://api.rango.exchange/i/glNa3x', - address: '0xaf9fe3b5ccdae78188b1f8b9a49da7ae9510f151', - usdPrice: 0.0837, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'dHEDGE DAO Token', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'TAROT', - image: 'https://api.rango.exchange/i/jtWpVA', - address: '0x375488f097176507e39b9653b88fdc52cde736bf', - usdPrice: 0.042, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Tarot', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'ROOBEE', - image: 'https://api.rango.exchange/i/gWFhLm', - address: '0xb12c13e66ade1f72f71834f2fc5082db8c091358', - usdPrice: 0.00046, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'ROOBEE', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'PICKLE', - image: 'https://api.rango.exchange/i/2bUp8a', - address: '0x0c5b4c92c948691eebf185c17eeb9c230dc019e9', - usdPrice: 0.769, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'PickleToken', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'DCN', - image: 'https://api.rango.exchange/i/d8D3cu', - address: '0x1da650c3b2daa8aa9ff6f661d4156ce24d08a062', - usdPrice: 0.00000236, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Dentacoin', - decimals: 0, - }, - { - blockchain: 'OPTIMISM', - symbol: 'EQZ', - image: 'https://api.rango.exchange/i/ZAPkNY', - address: '0x81ab7e0d570b01411fcc4afd3d50ec8c241cb74b', - usdPrice: 0.0305, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Equalizer', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'BLAST', - image: 'https://api.rango.exchange/i/42zjvJ', - address: '0xd1a891e6eccb7471ebd6bc352f57150d4365db21', - usdPrice: 4.11e-9, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'SafeBLAST', - decimals: 9, - }, - { - blockchain: 'OPTIMISM', - symbol: 'GTC', - image: 'https://api.rango.exchange/i/xv1VA3', - address: '0x1eba7a6a72c894026cd654ac5cdcf83a46445b08', - usdPrice: 1.644, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Gitcoin', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'GRG', - image: 'https://api.rango.exchange/i/Lf1n3v', - address: '0xecf46257ed31c329f204eb43e254c609dee143b3', - usdPrice: 0.0995, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Rigo Token', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'FS', - image: 'https://api.rango.exchange/i/zR1Go9', - address: '0x22648c12acd87912ea1710357b1302c6a4154ebc', - usdPrice: 0.00162, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'FantomStarter', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'UNI', - image: 'https://api.rango.exchange/i/xWz66T', - address: '0x6fd9d7ad17242c41f7131d257212c54a0e816691', - usdPrice: 6.46, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Uniswap', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'WETH', - image: 'https://api.rango.exchange/i/yZ9N1N', - address: '0x4200000000000000000000000000000000000006', - usdPrice: 1544.29, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Wrapped Ether', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'SETH', - image: 'https://api.rango.exchange/i/xp4thb', - address: '0xe405de8f52ba7559f9df3c368500b6e6ae6cee49', - usdPrice: 1545.51, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Synth sETH', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'WSTETH', - image: 'https://api.rango.exchange/i/ERqilv', - address: '0x1f32b1c2345538c0c6f582fcb022739c4a194ebb', - usdPrice: 1694.413, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Wrapped liquid staked Ether 2.0', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'BOB', - image: 'https://api.rango.exchange/i/htAPRB', - address: '0xb0b195aefa3650a6908f15cdac7d92f8a5791b0b', - usdPrice: 0.998, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'BOB', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'VELO', - image: 'https://api.rango.exchange/i/XdkbNa', - address: '0x3c8b650257cfb5f272f799f5e2b4e65093a11a05', - usdPrice: 0.0286, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Velodrome', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'MIM', - image: 'https://api.rango.exchange/i/RmsZZl', - address: '0xb153fb3d196a8eb25522705560ac152eeec57901', - usdPrice: 0.998, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Magic Internet Money', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'LYRA', - image: 'https://api.rango.exchange/i/OXEHNF', - address: '0x50c5725949a6f0c72e6c4a641f24049a917db0cb', - usdPrice: 0.124, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Lyra Token', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'PREMIA', - image: 'https://api.rango.exchange/i/4FZ9eH', - address: '0x374ad0f47f4ca39c78e5cc54f1c9e426ff8f231a', - usdPrice: 0.996, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Premia', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'OKSE', - image: 'https://api.rango.exchange/i/1EFOfJ', - address: '0x259479fbeb1cde194afa297f36f4216e9c87728c', - usdPrice: 0.0801, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Okse', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'OATH', - image: 'https://api.rango.exchange/i/SqMCnQ', - address: '0x39fde572a18448f8139b7788099f0a0740f51205', - usdPrice: 0.0822, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Oath Token', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'EST', - image: 'https://api.rango.exchange/i/n1IkOq', - address: '0x7b0bcc23851bbf7601efc9e9fe532bf5284f65d3', - usdPrice: 0.0819, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Erica Social Token', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'HAN', - image: 'https://api.rango.exchange/i/qllm8I', - address: '0x50bce64397c75488465253c0a034b8097fea6578', - usdPrice: 6.038, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'HanChain', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'USD+', - image: 'https://api.rango.exchange/i/TkwVYP', - address: '0x73cb180bf0521828d8849bc8cf2b920918e23032', - usdPrice: 0.999, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'USD+', - decimals: 6, - }, - { - blockchain: 'OPTIMISM', - symbol: 'HMT', - image: 'https://api.rango.exchange/i/czyRF5', - address: '0x6b7a87899490ece95443e979ca9485cbe7e71522', - usdPrice: 0.0619, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Human Token', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'UNIDX', - image: 'https://api.rango.exchange/i/TZv5rn', - address: '0x5d47baba0d66083c52009271faf3f50dcc01023c', - usdPrice: 3.32, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'UniDex', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'DOLA', - image: 'https://api.rango.exchange/i/vocLZQ', - address: '0x8ae125e8653821e851f12a49f7765db9a9ce7384', - usdPrice: 0.999, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Dola USD Stablecoin', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'QI', - image: 'https://api.rango.exchange/i/06gFRW', - address: '0x3f56e0c36d275367b8c502090edf38289b3dea0d', - usdPrice: 0.117, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'QiDao', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'LQDR', - image: 'https://api.rango.exchange/i/XVWczf', - address: '0xd1c5966f9f5ee6881ff6b261bbeda45972b1b5f3', - usdPrice: 1.27, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Liquid Driver', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'HND', - image: 'https://api.rango.exchange/i/2SsRdS', - address: '0x10010078a54396f62c96df8532dc2b4847d47ed3', - usdPrice: 0.0202, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Hundred Finance', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'ALUSD', - image: 'https://api.rango.exchange/i/fDjUnb', - address: '0xcb8fa9a76b8e203d8c3797bf438d8fb81ea3326a', - usdPrice: 0.972, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Alchemix USD', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'ALUSD', - image: 'https://api.rango.exchange/i/ViMKW9', - address: '0xb2c22a9fb4fc02eb9d1d337655ce079a04a526c7', - usdPrice: 0.973, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Multichain alUSD', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'BEETS', - image: 'https://api.rango.exchange/i/Kgejqb', - address: '0x97513e975a7fa9072c72c92d8000b0db90b163c5', - usdPrice: 0.0553, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'BeethovenxToken', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'KWENTA', - image: 'https://api.rango.exchange/i/XZuzGh', - address: '0x920cf626a271321c151d027030d5d08af699456b', - usdPrice: 153.02, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Kwenta', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'ELK', - image: 'https://api.rango.exchange/i/mOK4dk', - address: '0xeeeeeb57642040be42185f49c52f7e9b38f8eeee', - usdPrice: 0.121, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Elk', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'AELIN', - image: 'https://api.rango.exchange/i/IKzkPr', - address: '0x61baadcf22d2565b0f471b291c475db5555e0b76', - usdPrice: 1162.614, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Aelin Token', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'RADIO', - image: 'https://api.rango.exchange/i/gCFO6O', - address: '0xf899e3909b4492859d44260e1de41a9e663e70f5', - usdPrice: 0.000695, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'RadioShack Token', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'POTS', - image: 'https://api.rango.exchange/i/q1Vrg9', - address: '0x76a3d96726c0ed756ea420d239d3feb998ebf528', - usdPrice: 0.0136, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Moonpot', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'MAI', - image: 'https://api.rango.exchange/i/pWU1Z5', - address: '0xdfa46478f9e5ea86d57387849598dbfb2e964b02', - usdPrice: 0.992, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Mai Stablecoin', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'POOL', - image: 'https://api.rango.exchange/i/RzlTWC', - address: '0x395ae52bb17aef68c2888d941736a71dc6d4e125', - usdPrice: 0.663, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'PoolTogether', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'BIFI', - image: 'https://api.rango.exchange/i/EuFqit', - address: '0x4e720dd3ac5cfe1e1fbde4935f386bb1c66f4642', - usdPrice: 411.652, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: 'https://api.rango.exchange/i/lYlZID', - name: 'BIFI', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'BUILD', - image: 'https://api.rango.exchange/i/UNYoAE', - address: '0xe4de4b87345815c71aa843ea4841bcdc682637bb', - usdPrice: 0.000144, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Build Token', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'THALES', - image: 'https://api.rango.exchange/i/0urxvO', - address: '0x217d47011b23bb961eb6d93ca9945b7501a5bb11', - usdPrice: 0.462, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Optimistic Thales Token', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'USX', - image: 'https://api.rango.exchange/i/Tb5xre', - address: '0xbfd291da8a403daaf7e5e9dc1ec0aceacd4848b9', - usdPrice: 0.99, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'dForce USD', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'OPX', - image: 'https://api.rango.exchange/i/b2nYiC', - address: '0xcdb4bb51801a1f399d4402c61bc098a72c382e65', - usdPrice: 1.344, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'OPX', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'PAPER', - image: 'https://api.rango.exchange/i/oGsTZA', - address: '0x00f932f0fe257456b32deda4758922e56a4f4b42', - usdPrice: 0.00174, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Paper', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'REVA', - image: 'https://api.rango.exchange/i/C2TzuV', - address: '0x23c748fef17518b8de55065338d7fa20327472eb', - usdPrice: 0.0555, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Reva Token', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'WAD', - image: 'https://api.rango.exchange/i/YgH5tl', - address: '0x703d57164ca270b0b330a87fd159cfef1490c0a5', - usdPrice: 0.0127, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'WardenSwap', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'POP', - image: 'https://api.rango.exchange/i/leXdL6', - address: '0x6f0fecbc276de8fc69257065fe47c5a03d986394', - usdPrice: 0.287, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Popcorn', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'IB', - image: 'https://api.rango.exchange/i/p2tRUT', - address: '0x00a35fd824c717879bf370e70ac6868b95870dfb', - usdPrice: 1.72, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'IronBank', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'SHACK', - image: 'https://api.rango.exchange/i/rQ1tn2', - address: '0x66e8617d1df7ab523a316a6c01d16aa5bed93681', - usdPrice: 0.00017, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Shack Token', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'L2DAO', - image: 'https://api.rango.exchange/i/R1EEHF', - address: '0xd52f94df742a6f4b4c8b033369fe13a41782bf44', - usdPrice: 0.0028, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Layer2DAO', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'SDL', - image: 'https://api.rango.exchange/i/APbCEx', - address: '0xae31207ac34423c41576ff59bfb4e036150f9cf7', - usdPrice: 0.0349, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Saddle DAO', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'MOM', - image: 'https://api.rango.exchange/i/4UeN5Z', - address: '0x5e70affe232e2919792f77eb94e566db0320fa88', - usdPrice: 1.2e-11, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Monetum', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'RODO', - image: 'https://api.rango.exchange/i/iYrcVq', - address: '0x82f0b8b456c1a451378467398982d4834b6829c1', - usdPrice: 8.274, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'RODO', - decimals: 2, - }, - { - blockchain: 'OPTIMISM', - symbol: 'GYSR', - image: 'https://api.rango.exchange/i/FWbb5c', - address: '0x117cfd9060525452db4a34d51c0b3b7599087f05', - usdPrice: 0.0739, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Geyser', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'CHAM', - image: 'https://api.rango.exchange/i/23FKlX', - address: '0xdeba4568ff4cc84b420bcbfb228de5b7f2807a5c', - usdPrice: 1.26, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Champion', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'RING', - image: 'https://api.rango.exchange/i/1VKIEf', - address: '0xb0ae108669ceb86e9e98e8fe9e40d98b867855fd', - usdPrice: 0.00887, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'OneRing', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'DUCK', - image: 'https://api.rango.exchange/i/OvRdkE', - address: '0x0e49ca6ea763190084c846d3fc18f28bc2ac689a', - usdPrice: 0.0229, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Unit protocol', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'SARCO', - image: 'https://api.rango.exchange/i/8DOFP7', - address: '0x7c6b91d9be155a6db01f749217d76ff02a7227f2', - usdPrice: 0.129, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Sarcophagus', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'HOP', - image: 'https://api.rango.exchange/i/5LjtC9', - address: '0xc5102fe9359fd9a28f877a67e36b0f050d81a3cc', - usdPrice: 0.0798, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Hop', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'LUSD', - image: 'https://api.rango.exchange/i/A5IHi8', - address: '0xc40f949f8a4e094d1b49a23ea9241d289b7b2819', - usdPrice: 1.009, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'LUSD Stablecoin', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'BANK', - image: 'https://api.rango.exchange/i/R63C1v', - address: '0x29faf5905bff9cfcc7cf56a5ed91e0f091f8664b', - usdPrice: 1.177, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Bankless Token', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'FLASH', - image: 'https://api.rango.exchange/i/40p5gX', - address: '0x86bea60374f220de9769b2fef2db725bc1cdd335', - usdPrice: 0.000127, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Flashstake', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'KITTY', - image: 'https://api.rango.exchange/i/hbdNHi', - address: '0x165dbb08de0476271714952c3c1f068693bd60d7', - usdPrice: 0.00359, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'KITTY', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'ALETH', - image: 'https://api.rango.exchange/i/RhYL8V', - address: '0x3e29d3a9316dab217754d13b28646b76607c5f04', - usdPrice: 1524.377, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Alchemix ETH', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'PAE', - image: 'https://api.rango.exchange/i/ZDUzxz', - address: '0xc46fedc533e9f14c99c4c5124e2085701fa9b255', - usdPrice: 0.123, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Ripae', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'ALTA', - image: 'https://api.rango.exchange/i/2Ji4fs', - address: '0xe0cca86b254005889ac3a81e737f56a14f4a38f5', - usdPrice: 1.28e-7, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Alta Finance', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'CRE8R', - image: 'https://api.rango.exchange/i/TWfRgc', - address: '0xabd380327fe66724ffda91a87c772fb8d00be488', - usdPrice: 0.00325, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'CRE8R DAO', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'XCRMRK', - image: 'https://api.rango.exchange/i/ZAuEIO', - address: '0xe6cdd3a275c976bca5d3de4f96c7514b899f0434', - usdPrice: 2.45, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'xcRMRK', - decimals: 10, - }, - { - blockchain: 'OPTIMISM', - symbol: 'ALETH', - image: 'https://api.rango.exchange/i/j9xgdC', - address: '0x1ccca1ce62c62f7be95d4a67722a8fdbed6eecb4', - usdPrice: 1544.16, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Multichain alETH', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'GTPS', - image: 'https://api.rango.exchange/i/SXWddi', - address: '0xd22a58f79e9481d1a88e00c343885a588b34b68b', - usdPrice: null, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Global Transaction Payment Solution', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'PONY', - image: 'https://api.rango.exchange/i/atDHKp', - address: '0x7f8bc696bebbbd29255f871cbef55b74e8f10e57', - usdPrice: 1.063, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'PONY Index', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'MOOVELODROMEMAI-USDC', - image: 'https://api.rango.exchange/i/zDalKJ', - address: '0x01d9cfb8a9d43013a1fdc925640412d8d2d900f0', - usdPrice: null, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Moo Velodrome MAI-USDC', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'MOOCURVEFSUSD', - image: 'https://api.rango.exchange/i/7fmlBZ', - address: '0x107dbf9c9c0ef2df114159e5c7dc2baf7c444cff', - usdPrice: null, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Moo Curve f-sUSD', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'MOOVELODROMESUSD-USDC', - image: 'https://api.rango.exchange/i/3EdQaf', - address: '0x2232455bf4622002c1416153ee59fd32b239863b', - usdPrice: null, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Moo Velodrome sUSD-USDC', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'SHN', - image: 'https://api.rango.exchange/i/oIqASS', - address: '0xce1bffbd5374dac86a2893119683f4911a2f7814', - usdPrice: 0.00368, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Shine', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'UNLOCK', - image: 'https://api.rango.exchange/i/10zCOG', - address: '0x7ae97042a4a0eb4d1eb370c34bfec71042a056b7', - usdPrice: 0.0222, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Unlock Token', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'aCRV', - image: 'https://api.rango.exchange/i/VnDnih', - address: '0x764ad60e1b81f6cacfec1a2926393d688d4493e6', - usdPrice: null, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'AladdinCRV', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'BAXA', - image: 'https://api.rango.exchange/i/jYdIVH', - address: '0xdb9888b842408b0b8efa1f5477bd9f351754999e', - usdPrice: null, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'BAXagent Coin', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'BitANT', - image: 'https://api.rango.exchange/i/Z4u93A', - address: '0x5029c236320b8f15ef0a657054b84d90bfbeded3', - usdPrice: null, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'BitANT', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'BitBTC', - image: 'https://api.rango.exchange/i/Hw8jqo', - address: '0xc98b98d17435aa00830c87ea02474c5007e1f272', - usdPrice: null, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'BitBTC', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'IBEX', - image: 'https://api.rango.exchange/i/0W1NG7', - address: '0xbb6bbaa0f6d839a00c82b10747abc3b7e2eecc82', - usdPrice: null, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Impermax', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'LIZ', - image: 'https://api.rango.exchange/i/enp0hk', - address: '0x3bb4445d30ac020a84c1b5a8a2c6248ebc9779d0', - usdPrice: null, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Theranos Coin', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'LPF', - image: 'https://api.rango.exchange/i/R8cSwy', - address: '0x0b3e851cf6508a16266bc68a651ea68b31ef673b', - usdPrice: null, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Loopfi', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'rETH', - image: 'https://api.rango.exchange/i/1kJlAT', - address: '0x9bcef72be871e61ed4fbbc7630889bee758eb81d', - usdPrice: 1641.841, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Rocket Pool ETH', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'RFWSTETH', - image: 'https://api.rango.exchange/i/ZUrCax', - address: '0xeaeadac73baaf4cb8b024de9d65b2eefa722856c', - usdPrice: null, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Respawn Finance Wrapped Staked Ethereum', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'sBTC', - image: 'https://api.rango.exchange/i/bSzjiI', - address: '0x298b9b95708152ff6968aafd889c6586e9169f1d', - usdPrice: 20826.471, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Synthetic Bitcoin', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'sLINK', - image: 'https://api.rango.exchange/i/WZVclC', - address: '0xc5db22719a06418028a40a9b5e9a7c02959d0d08', - usdPrice: null, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Synthetic Chainlink', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'TheDAO', - image: 'https://api.rango.exchange/i/nj6rMG', - address: '0xd8f365c2c85648f9b89d9f1bf72c0ae4b1c36cfd', - usdPrice: null, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'TheDAO', - decimals: 16, - }, - { - blockchain: 'OPTIMISM', - symbol: 'UST', - image: 'https://api.rango.exchange/i/RmqQuA', - address: '0xba28feb4b6a6b81e3f26f08b83a19e715c4294fd', - usdPrice: null, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'UST (Wormhole)', - decimals: 6, - }, - { - blockchain: 'OPTIMISM', - symbol: 'VALX', - image: 'https://api.rango.exchange/i/WMpYbe', - address: '0x0a9aaa1c7542b42233ac7ffda364e97ade21f160', - usdPrice: null, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'Validator', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'veKWENTA', - image: 'https://api.rango.exchange/i/na75UT', - address: '0x678d8f4ba8dfe6bad51796351824dcceceaeff2b', - usdPrice: null, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'veKwenta', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'MUXLP', - image: 'https://api.rango.exchange/i/LU6UXw', - address: '0x0509474f102b5cd3f1f09e1e91feb25938ef0f17', - usdPrice: null, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'MUXLP', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'muxAVAX', - image: 'https://api.rango.exchange/i/x8p1hZ', - address: '0x50ec9b92b3bd46969b1ae5e10543ca6fb49fba4f', - usdPrice: null, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'muxAVAX', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'muxBNB', - image: 'https://api.rango.exchange/i/wdOpD4', - address: '0x253be9f0e2a8749df6ac7466d096b264788745e0', - usdPrice: null, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'muxBNB', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'muxBTC', - image: 'https://api.rango.exchange/i/lln22n', - address: '0x1bba8683e28078306db88743a387eb34fb5f34ed', - usdPrice: null, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'muxBTC', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'muxETH', - image: 'https://api.rango.exchange/i/ivPWLz', - address: '0xff86404162bf14fe50cedcf82a56941dc5f48c77', - usdPrice: null, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'muxETH', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'muxFTM', - image: 'https://api.rango.exchange/i/mSbv0e', - address: '0xfd951e71a8ec5c03ad6139d35f800374ba500fa8', - usdPrice: null, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'muxFTM', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'muxOP', - image: 'https://api.rango.exchange/i/sMCOOC', - address: '0x69663eb604c7d534e9149fa855d89d9104e75363', - usdPrice: null, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'muxOP', - decimals: 18, - }, - { - blockchain: 'OPTIMISM', - symbol: 'muxUSD', - image: 'https://api.rango.exchange/i/M7nASF', - address: '0xe80e0b928f8f3024dfefa56e7608bc3baf389881', - usdPrice: null, - isSecondaryCoin: false, - coinSource: null, - coinSourceUrl: null, - name: 'muxUSD', - decimals: 18, - }, -]; diff --git a/widget/ui/src/components/TokenSelector/TokenSelector.stories.tsx b/widget/ui/src/components/TokenSelector/TokenSelector.stories.tsx deleted file mode 100644 index 58bcd6c714..0000000000 --- a/widget/ui/src/components/TokenSelector/TokenSelector.stories.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import React from 'react'; -import { ComponentMeta } from '@storybook/react'; -import { TokenSelector, PropTypes } from './TokenSelector'; -import { tokensMeta } from '../TokenList/mockData'; - -export default { - title: 'Token Selector', - component: TokenSelector, - argTypes: { - type: { - defaultValue: 'Source', - }, - }, -} as ComponentMeta; - -export const Main = (args: PropTypes) => ( - -); diff --git a/widget/ui/src/components/TokenSelector/TokenSelector.tsx b/widget/ui/src/components/TokenSelector/TokenSelector.tsx deleted file mode 100644 index d73a61c5b6..0000000000 --- a/widget/ui/src/components/TokenSelector/TokenSelector.tsx +++ /dev/null @@ -1,71 +0,0 @@ -import React from 'react'; -import { containsText } from '../../helper'; -import { SecondaryPage } from '../SecondaryPage/SecondaryPage'; -import { TokenList } from '../TokenList'; -import { TokenWithAmount } from '../TokenList/TokenList'; -import { LoadingStatus } from '../../types/meta'; -import { Spinner } from '../Spinner'; -import { LoadingFailedAlert } from '../Alert/LoadingFailedAlert'; -import { NotFoundAlert } from '../Alert/NotFoundAlert'; -import { styled } from '../../theme'; - -export const LoaderContainer = styled('div', { - display: 'flex', - justifyContent: 'center', - width: '100%', - paddingTop: '33%', - flex: 1, -}); -export interface PropTypes { - list: TokenWithAmount[]; - type?: 'Source' | 'Destination'; - selected: TokenWithAmount | null; - onChange: (token: TokenWithAmount) => void; - onBack?: () => void; - loadingStatus: LoadingStatus; - hasHeader?: boolean; -} - -const filterTokens = (list: TokenWithAmount[], searchedFor: string) => - list.filter( - (token) => - containsText(token.symbol, searchedFor) || - containsText(token.address || '', searchedFor) || - containsText(token.name || '', searchedFor) - ); - -export function TokenSelector(props: PropTypes) { - const { list, type, selected, hasHeader, onChange, onBack, loadingStatus } = - props; - - return ( - - {(searchedFor) => { - const filteredTokens = filterTokens(list, searchedFor); - - return loadingStatus === 'loading' ? ( - - - - ) : loadingStatus === 'failed' ? ( - - ) : filteredTokens.length ? ( - - ) : ( - - ); - }} - - ); -} diff --git a/widget/ui/src/components/TokenSelector/index.ts b/widget/ui/src/components/TokenSelector/index.ts deleted file mode 100644 index 9f139f6b46..0000000000 --- a/widget/ui/src/components/TokenSelector/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { TokenSelector } from './TokenSelector'; diff --git a/widget/ui/src/components/Tooltip/NumericTooltip.tsx b/widget/ui/src/components/Tooltip/NumericTooltip.tsx new file mode 100644 index 0000000000..a1e119faae --- /dev/null +++ b/widget/ui/src/components/Tooltip/NumericTooltip.tsx @@ -0,0 +1,16 @@ +import type { NumericTooltipPropTypes } from './NumericTooltip.types.js'; +import type { PropsWithChildren } from 'react'; + +import React from 'react'; + +import { Tooltip } from './Tooltip.js'; + +export function NumericTooltip( + props: PropsWithChildren +) { + const MAX_DECIMALS = 12; + const formattedNumber = Number(props.content) + .toFixed(props.maxDecimals || MAX_DECIMALS) + .replace(/(?:\.0*|(\.\d+?)0*)$/, '$1'); + return ; +} diff --git a/widget/ui/src/components/Tooltip/NumericTooltip.types.tsx b/widget/ui/src/components/Tooltip/NumericTooltip.types.tsx new file mode 100644 index 0000000000..2e4e218e19 --- /dev/null +++ b/widget/ui/src/components/Tooltip/NumericTooltip.types.tsx @@ -0,0 +1,6 @@ +import type { TooltipPropTypes } from './Tooltip.types.js'; + +export interface NumericTooltipPropTypes extends TooltipPropTypes { + content: string | number | null | undefined; + maxDecimals?: number; +} diff --git a/widget/ui/src/components/Tooltip/Tooltip.stories.tsx b/widget/ui/src/components/Tooltip/Tooltip.stories.tsx deleted file mode 100644 index 2510d37919..0000000000 --- a/widget/ui/src/components/Tooltip/Tooltip.stories.tsx +++ /dev/null @@ -1,52 +0,0 @@ -import React from 'react'; -import { ComponentMeta } from '@storybook/react'; - -import { Tooltip, PropTypes } from './Tooltip'; -import { AddWalletIcon } from '../Icon'; - -export default { - title: 'Components/Tooltip', - component: Tooltip, - argTypes: { - content: { - name: 'content', - control: { type: 'text' }, - defaultValue: 'I am a tooltip', - }, - side: { - name: 'side', - control: { type: 'select' }, - options: ['top', 'right', 'bottom', 'left'], - defaultValue: 'top', - }, - color: { - name: 'color', - control: { type: 'select' }, - options: [ - 'primary', - 'error', - 'warning', - 'success', - 'black', - 'white', - 'gray', - ], - defaultValue: 'gray', - }, - }, -} as ComponentMeta; - -export const Main = (props: PropTypes) => ( -
- - - -
-); diff --git a/widget/ui/src/components/Tooltip/Tooltip.styles.ts b/widget/ui/src/components/Tooltip/Tooltip.styles.ts new file mode 100644 index 0000000000..faa8928e55 --- /dev/null +++ b/widget/ui/src/components/Tooltip/Tooltip.styles.ts @@ -0,0 +1,24 @@ +import * as RadixTooltip from '@radix-ui/react-tooltip'; + +import { darkTheme, styled } from '../../theme.js'; +import { Typography } from '../Typography/index.js'; + +export const TooltipContent = styled(RadixTooltip.Content, { + zIndex: '999999', +}); + +export const TooltipTypography = styled(Typography, { + borderRadius: '$md', + padding: '$5 $10', + boxShadow: '5px 5px 10px 0px rgba(0, 0, 0, 0.10)', + backgroundColor: '$neutral200', + [`.${darkTheme} &`]: { + backgroundColor: '$neutral500', + }, +}); + +export const TriggerContent = styled('div', { + display: 'flex', + justifyContent: 'center', + alignItems: 'center', +}); diff --git a/widget/ui/src/components/Tooltip/Tooltip.tsx b/widget/ui/src/components/Tooltip/Tooltip.tsx index fa1e70569d..ed03bb898c 100644 --- a/widget/ui/src/components/Tooltip/Tooltip.tsx +++ b/widget/ui/src/components/Tooltip/Tooltip.tsx @@ -1,113 +1,51 @@ -import * as RadixTooltip from '@radix-ui/react-tooltip'; -import { styled } from '../../theme'; -import React, { PropsWithChildren } from 'react'; +import type { TooltipPropTypes } from './Tooltip.types.js'; +import type { PropsWithChildren } from 'react'; -export interface PropTypes { - content: string; - side?: 'top' | 'right' | 'bottom' | 'left'; - color?: - | 'primary' - | 'error' - | 'warning' - | 'success' - | 'gray' - | 'white' - | 'black'; -} -const TooltipTrigger = styled(RadixTooltip.Trigger, { - border: 0, - padding: 0, +import * as RadixTooltip from '@radix-ui/react-tooltip'; +import React from 'react'; - backgroundColor: 'transparent', -}); -const TooltipContent = styled(RadixTooltip.Content, { - borderRadius: '$5', - padding: '$4 $8', - fontSize: '$14', - animationDuration: '400ms', - animationTimingFunction: 'cubic-bezier(0.16, 1, 0.3, 1)', - willChange: 'transform, opacity', - variants: { - color: { - primary: { - backgroundColor: '$primary', - color: '$white', - }, - error: { - backgroundColor: '$error', - color: '$white', - }, - warning: { - backgroundColor: '$warning', - color: '$white', - }, - success: { - backgroundColor: '$success', - color: '$white', - }, - gray: { - backgroundColor: '$neutrals300', - color: '$black', - }, - black: { - backgroundColor: '$black', - color: '$white', - }, - white: { - backgroundColor: '$white', - color: '$black', - }, - }, - }, -}); -const TooltipArrow = styled(RadixTooltip.Arrow, { - variants: { - color: { - primary: { - fill: '$primary', - }, - error: { - fill: '$error', - }, - warning: { - fill: '$warning', - }, - success: { - fill: '$success', - }, - gray: { - fill: '$neutrals300', - }, - black: { - fill: '$black', - }, - white: { - fill: '$white', - }, - }, - }, -}); +import { + TooltipContent, + TooltipTypography, + TriggerContent, +} from './Tooltip.styles.js'; -const ChildrenWrapper = styled('div', { - display: 'inline-block', -}); +export function Tooltip(props: PropsWithChildren) { + const { + children, + content, + color, + sideOffset, + container, + open, + side = 'top', + styles, + align, + alignOffset, + collisionPadding, + } = props; -export function Tooltip({ - children, - content, - side = 'top', - color = 'gray', -}: PropsWithChildren) { return ( - - - - {children} - - - - {content} - + + + + {children} + + + + + {content} + diff --git a/widget/ui/src/components/Tooltip/Tooltip.types.ts b/widget/ui/src/components/Tooltip/Tooltip.types.ts new file mode 100644 index 0000000000..492fc07aff --- /dev/null +++ b/widget/ui/src/components/Tooltip/Tooltip.types.ts @@ -0,0 +1,22 @@ +import type { CSS } from '../../theme.js'; +import type * as RadixTooltip from '@radix-ui/react-tooltip'; +import type * as Stitches from '@stitches/react'; +import type { ComponentProps, ReactNode } from 'react'; + +type RadixTooltipContentProps = ComponentProps; + +export interface TooltipPropTypes { + content: ReactNode; + side?: RadixTooltipContentProps['side']; + color?: 'primary' | 'error' | 'warning' | 'success'; + sideOffset?: RadixTooltipContentProps['sideOffset']; + container?: HTMLElement; + open?: boolean; + styles?: { + root?: Stitches.CSSProperties; + content?: CSS; + }; + align?: RadixTooltipContentProps['align']; + alignOffset?: RadixTooltipContentProps['alignOffset']; + collisionPadding?: RadixTooltipContentProps['collisionPadding']; +} diff --git a/widget/ui/src/components/Tooltip/index.ts b/widget/ui/src/components/Tooltip/index.ts index b44d466fac..bf7601f67f 100644 --- a/widget/ui/src/components/Tooltip/index.ts +++ b/widget/ui/src/components/Tooltip/index.ts @@ -1 +1,4 @@ -export { Tooltip } from './Tooltip'; +export { Tooltip } from './Tooltip.js'; +export type { TooltipPropTypes } from './Tooltip.types.js'; +export { NumericTooltip } from './NumericTooltip.js'; +export type { NumericTooltipPropTypes } from './NumericTooltip.types.js'; diff --git a/widget/ui/src/components/Typography/NotSelectableTypography.ts b/widget/ui/src/components/Typography/NotSelectableTypography.ts new file mode 100644 index 0000000000..3786a18c80 --- /dev/null +++ b/widget/ui/src/components/Typography/NotSelectableTypography.ts @@ -0,0 +1,7 @@ +import { styled } from '../../theme.js'; + +import { Typography } from './Typography.js'; + +export const NotSelectableTypography = styled(Typography, { + userSelect: 'none', +}); diff --git a/widget/ui/src/components/Typography/Typography.stories.tsx b/widget/ui/src/components/Typography/Typography.stories.tsx deleted file mode 100644 index 5651a0744b..0000000000 --- a/widget/ui/src/components/Typography/Typography.stories.tsx +++ /dev/null @@ -1,72 +0,0 @@ -import React from 'react'; -import { ComponentMeta } from '@storybook/react'; - -import { Typography, PropTypes } from './Typography'; - -export default { - title: 'Components/Typography', - component: Typography, - argTypes: { - variant: { - name: 'variant', - control: { type: 'select' }, - options: [ - 'body1', - 'body2', - 'body3', - 'h1', - 'h2', - 'h3', - 'h4', - 'h5', - 'h6', - 'caption', - ], - defaultValue: 'h1', - }, - align: { - name: 'align', - control: { type: 'select' }, - options: ['center', 'left', 'right'], - }, - noWrap: { - name: 'noWrap', - control: { type: 'boolean' }, - }, - }, -} as ComponentMeta; - -export const Main = (props: PropTypes) => ( -
- - Heading 1 - - - Heading 2 - - - Heading 3 - - - Heading 4 - - - Heading 5 - - - Heading 6 - - - Body 1 - - - Body 2 - - - Body 3 - - - Caption - -
-); diff --git a/widget/ui/src/components/Typography/Typography.styles.tsx b/widget/ui/src/components/Typography/Typography.styles.tsx new file mode 100644 index 0000000000..10d85e74ef --- /dev/null +++ b/widget/ui/src/components/Typography/Typography.styles.tsx @@ -0,0 +1,206 @@ +import { styled } from '../../theme.js'; + +export const TypographyContainer = styled('span', { + display: 'inline-block', + variants: { + variant: { + display: {}, + headline: {}, + title: {}, + label: {}, + body: {}, + }, + size: { + large: {}, + medium: {}, + xmedium: {}, + small: {}, + xsmall: {}, + }, + align: { + center: { + textAlign: 'center', + }, + left: { + textAlign: 'left', + }, + right: { + textAlign: 'right', + }, + }, + noWrap: { + true: { + whiteSpace: 'nowrap', + }, + }, + }, + + compoundVariants: [ + { + size: 'large', + variant: 'display', + css: { + fontSize: '$48', + fontWeight: '$semiBold', + lineHeight: '$64', + }, + }, + { + size: 'medium', + variant: 'display', + css: { + fontSize: '$40', + fontWeight: '$semiBold', + lineHeight: '$52', + }, + }, + { + size: 'small', + variant: 'display', + css: { + fontSize: '$36', + fontWeight: '$semiBold', + lineHeight: '$44', + }, + }, + + { + size: 'large', + variant: 'headline', + css: { + fontSize: '$32', + fontWeight: '$semiBold', + lineHeight: '$40', + }, + }, + { + size: 'medium', + variant: 'headline', + css: { + fontSize: '$38', + fontWeight: '$semiBold', + lineHeight: '$36', + }, + }, + { + size: 'small', + variant: 'headline', + css: { + fontSize: '$22', + fontWeight: '$semiBold', + lineHeight: '$30', + }, + }, + { + size: 'xsmall', + variant: 'headline', + css: { + fontSize: '$20', + fontWeight: '$semiBold', + lineHeight: '$28', + }, + }, + + { + size: 'large', + variant: 'title', + css: { + fontSize: '$22', + fontWeight: '$medium', + lineHeight: '$28', + }, + }, + { + size: 'medium', + variant: 'title', + css: { + fontSize: '$18', + fontWeight: '$medium', + lineHeight: '$26', + }, + }, + { + size: 'xmedium', + variant: 'title', + css: { + fontSize: '$16', + fontWeight: '$medium', + lineHeight: '$24', + }, + }, + { + size: 'small', + variant: 'title', + css: { + fontSize: '$14', + fontWeight: '$medium', + lineHeight: '$20', + }, + }, + + { + size: 'large', + variant: 'label', + css: { + fontSize: '$14', + fontWeight: '$medium', + lineHeight: '$20', + }, + }, + { + size: 'medium', + variant: 'label', + css: { + fontSize: '$12', + fontWeight: '$medium', + lineHeight: '$16', + }, + }, + { + size: 'small', + variant: 'label', + css: { + fontSize: '$10', + fontWeight: '$medium', + lineHeight: '$16', + }, + }, + + { + size: 'large', + variant: 'body', + css: { + fontSize: '$16', + fontWeight: '$regular', + lineHeight: '$24', + }, + }, + { + size: 'medium', + variant: 'body', + css: { + fontSize: '$14', + fontWeight: '$regular', + lineHeight: '$20', + }, + }, + { + size: 'small', + variant: 'body', + css: { + fontSize: '$12', + fontWeight: '$regular', + lineHeight: '$16', + }, + }, + { + size: 'xsmall', + variant: 'body', + css: { + fontSize: '$10', + fontWeight: '$regular', + lineHeight: '$12', + }, + }, + ], +}); diff --git a/widget/ui/src/components/Typography/Typography.tsx b/widget/ui/src/components/Typography/Typography.tsx index 5a2173ed9a..07e4295efd 100644 --- a/widget/ui/src/components/Typography/Typography.tsx +++ b/widget/ui/src/components/Typography/Typography.tsx @@ -1,207 +1,16 @@ -import { CSSProperties } from '@stitches/react'; -import React, { PropsWithChildren } from 'react'; -import { styled } from '../../theme'; +import type { TypographyPropTypes } from './Typography.types.js'; +import type { PropsWithChildren } from 'react'; -const TypographyContainer = styled('span', { - margin: 0, - display: 'inline-block', - variants: { - variant: { - h1: { - fontSize: '$36', - fontWeight: '$700', - '@md': { - fontSize: '$40', - }, - '@lg': { - fontSize: '$48', - }, - }, - h2: { - fontSize: '$32', - fontWeight: '$700', - '@md': { - fontSize: '$36', - }, - '@lg': { - fontSize: '$40', - }, - }, - h3: { - fontSize: '$20', - fontWeight: '$700', - '@md': { - fontSize: '$24', - }, - '@lg': { - fontSize: '$32', - }, - }, - h4: { - fontSize: '$18', - fontWeight: '$600', - '@md': { - fontSize: '$20', - }, - '@lg': { - fontSize: '$24', - }, - }, - h5: { - fontSize: '$16', - fontWeight: '$600', - }, - h6: { - fontSize: '$14', - fontWeight: '$500', - '@md': { - fontSize: '$16', - }, - '@lg': { - fontSize: '$18', - }, - }, - title: { - fontSize: '$14', - fontWeight: '$500', - '@md': { - fontSize: '$15', - } - }, - body1: { - fontSize: '$14', - fontWeight: '$400', - '@md': { - fontSize: '$16', - }, - '@lg': { - fontSize: '$18', - }, - }, - body2: { - fontSize: '$14', - fontWeight: '$400', - // '@lg': { - // fontSize: '$14', - // }, - }, - body3: { - fontSize: '$12', - fontWeight: '$400', - }, - caption: { - fontSize: '$10', - fontWeight: '$400', - '@lg': { - fontSize: '$12', - }, - }, - }, - align: { - center: { - textAlign: 'center', - }, - left: { - textAlign: 'left', - }, - right: { - textAlign: 'right', - }, - }, - noWrap: { - true: { - whiteSpace: 'nowrap', - }, - }, - ml: { - 2: { - marginLeft: '$2', - }, - 4: { - marginLeft: '$4', - }, - 8: { - marginLeft: '$8', - }, - 12: { - marginLeft: '$12', - }, - }, - mt: { - 2: { - marginTop: '$2', - }, - 4: { - marginTop: '$4', - }, - 8: { - marginTop: '$8', - }, - 12: { - marginTop: '$12', - }, - }, - mr: { - 2: { - marginRight: '$2', - }, - 4: { - marginRight: '$4', - }, - 8: { - marginRight: '$8', - }, - 12: { - marginRight: '$12', - }, - }, - mb: { - 2: { - marginBottom: '$2', - }, - 4: { - marginBottom: '$4', - }, - 8: { - marginBottom: '$8', - }, - 12: { - marginBottom: '$12', - }, - }, - }, -}); +import React from 'react'; -export interface PropTypes { - variant: - | 'h1' - | 'h2' - | 'h3' - | 'h4' - | 'h5' - | 'h6' - | 'title' - | 'body1' - | 'body2' - | 'body3' - | 'caption'; - align?: 'center' | 'left' | 'right'; - noWrap?: boolean; - mt?: 2 | 4 | 8 | 12; - mb?: 2 | 4 | 8 | 12; - ml?: 2 | 4 | 8 | 12; - mr?: 2 | 4 | 8 | 12; - className?: string; - style?: CSSProperties; - color?: string; -} +import { TypographyContainer } from './Typography.styles.js'; export function Typography({ children, className, color, ...props -}: PropsWithChildren) { +}: PropsWithChildren) { const customCss = color ? { color: color.startsWith('$') ? color : `$${color}`, @@ -209,16 +18,12 @@ export function Typography({ : { color: '$foreground', }; - return ( + {...props}> {children} ); } - -Typography.toString = () => '._typography'; diff --git a/widget/ui/src/components/Typography/Typography.types.tsx b/widget/ui/src/components/Typography/Typography.types.tsx new file mode 100644 index 0000000000..3a8287d75a --- /dev/null +++ b/widget/ui/src/components/Typography/Typography.types.tsx @@ -0,0 +1,17 @@ +import type { TypographyContainer } from './Typography.styles.js'; +import type * as Stitches from '@stitches/react'; + +type BaseProps = Stitches.VariantProps; +type BaseSizes = Exclude; +type BaseVariants = Exclude; +export type BaseAlign = Exclude; + +export interface TypographyPropTypes { + variant: BaseVariants; + size: BaseSizes; + align?: BaseAlign; + noWrap?: boolean; + className?: string; + style?: Stitches.CSSProperties; + color?: string; +} diff --git a/widget/ui/src/components/Typography/index.ts b/widget/ui/src/components/Typography/index.ts index 5cbb1cc836..9b2ed5ad3e 100644 --- a/widget/ui/src/components/Typography/index.ts +++ b/widget/ui/src/components/Typography/index.ts @@ -1 +1,3 @@ -export { Typography } from './Typography'; +export { Typography } from './Typography.js'; +export { NotSelectableTypography } from './NotSelectableTypography.js'; +export type { TypographyPropTypes } from './Typography.types.js'; diff --git a/widget/ui/src/components/VirtualizedList/VirtualizedList.tsx b/widget/ui/src/components/VirtualizedList/VirtualizedList.tsx index 9c74dc96e9..baf718ae9b 100644 --- a/widget/ui/src/components/VirtualizedList/VirtualizedList.tsx +++ b/widget/ui/src/components/VirtualizedList/VirtualizedList.tsx @@ -1,62 +1,6 @@ -import React, { PropsWithChildren } from 'react'; -import { ReactElementType, VariableSizeList as List } from 'react-window'; -import InfiniteLoader from 'react-window-infinite-loader'; -import AutoSizer from 'react-virtualized-auto-sizer'; -import { CSSProperties } from '@stitches/react'; +import { + GroupedVirtuoso as GroupedVirtualizedList, + Virtuoso as VirtualizedList, +} from 'react-virtuoso'; -export type VirtualizedListItem = ({ - index, - style, -}: { - index: number; - style: CSSProperties | undefined; -}) => JSX.Element | null; - -type PropTypes = { - itemCount: number; - hasNextPage: boolean; - loadNextPage: () => void; - Item: VirtualizedListItem; - innerElementType: ReactElementType | undefined; - size: number; -}; - -export function VirtualizedList(props: PropsWithChildren) { - const { itemCount, hasNextPage, loadNextPage, Item, innerElementType, size } = - props; - - const isItemLoaded = (index: number) => !hasNextPage || index < itemCount; - - return ( - - {({ width, height }) => ( - - {({ onItemsRendered, ref }) => { - return ( - size} - itemCount={itemCount} - height={height || 0} - width={width || 0} - onItemsRendered={onItemsRendered} - > - {({ index, style }) => - isItemLoaded(index) ? ( - - ) : null - } - - ); - }} - - )} - - ); -} +export { VirtualizedList, GroupedVirtualizedList }; diff --git a/widget/ui/src/components/VirtualizedList/index.ts b/widget/ui/src/components/VirtualizedList/index.ts new file mode 100644 index 0000000000..e412d8f874 --- /dev/null +++ b/widget/ui/src/components/VirtualizedList/index.ts @@ -0,0 +1 @@ +export { VirtualizedList, GroupedVirtualizedList } from './VirtualizedList.js'; diff --git a/widget/ui/src/components/Wallet/ClickableWallet.tsx b/widget/ui/src/components/Wallet/ClickableWallet.tsx new file mode 100644 index 0000000000..2e4f73d7c4 --- /dev/null +++ b/widget/ui/src/components/Wallet/ClickableWallet.tsx @@ -0,0 +1,76 @@ +import type { WalletPropTypes } from './Wallet.types.js'; + +import { detectInstallLink } from '@rango-dev/wallets-shared'; +import React, { Fragment } from 'react'; + +import { Image } from '../common/index.js'; +import { Divider } from '../Divider/index.js'; +import { Skeleton } from '../Skeleton/index.js'; +import { Tooltip } from '../Tooltip/index.js'; +import { Typography } from '../Typography/index.js'; + +import { makeInfo } from './Wallet.helpers.js'; +import { + LoadingButton, + Text, + Title, + WalletButton, + WalletImageContainer, +} from './Wallet.styles.js'; +import { WalletState } from './Wallet.types.js'; + +function Wallet(props: WalletPropTypes) { + const { title, type, image, onClick, isLoading, disabled = false } = props; + const info = makeInfo(props.state); + + if (isLoading) { + return ( + + + + + + + + ); + } + + const WrapperComponent = disabled ? Fragment : Tooltip; + + return ( + + { + if (props.state === WalletState.NOT_INSTALLED) { + window.open(detectInstallLink(props.link), '_blank'); + } else { + onClick(type); + } + }}> + + + + + + + {title} + + + + {info.description} + + + + + ); +} + +export default Wallet; diff --git a/widget/ui/src/components/Wallet/SelectableWallet.tsx b/widget/ui/src/components/Wallet/SelectableWallet.tsx new file mode 100644 index 0000000000..93665c87aa --- /dev/null +++ b/widget/ui/src/components/Wallet/SelectableWallet.tsx @@ -0,0 +1,58 @@ +import { detectInstallLink } from '@rango-dev/wallets-shared'; +import React from 'react'; + +import { Image } from '../common/index.js'; +import { Typography } from '../Typography/index.js'; + +import { makeInfo } from './Wallet.helpers.js'; +import { + Text, + Title, + WalletButton, + WalletImageContainer, +} from './Wallet.styles.js'; +import { type SelectablePropTypes, WalletState } from './Wallet.types.js'; + +export function SelectableWallet(props: SelectablePropTypes) { + const { + title, + type, + image, + onClick, + selected, + description, + state, + disabled = false, + } = props; + const info = makeInfo(props.state); + return ( + { + if (props.state === WalletState.NOT_INSTALLED) { + window.open(detectInstallLink(props.link), '_blank'); + } else { + onClick(type); + } + }}> + + + + + + + {title} + + + + {description || info.description} + + + + ); +} diff --git a/widget/ui/src/components/Wallet/State.tsx b/widget/ui/src/components/Wallet/State.tsx deleted file mode 100644 index a9b5a627bb..0000000000 --- a/widget/ui/src/components/Wallet/State.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import React, { Fragment } from 'react'; -import { styled } from '../../theme'; -import { DisconnectIcon, DownloadIcon } from '../Icon'; -import { Spinner } from '../Spinner'; -import { WalletState } from '../../types/wallet'; -import { InstallObjects, detectInstallLink } from '@rango-dev/wallets-shared'; - -const StateIconContainer = styled('span', { - display: 'flex', - justifyContent: 'center', - alignItems: 'center', -}); - -export const State = ({ - walletState, - installLink, -}: { - walletState: WalletState; - installLink: InstallObjects | string; -}) => ( - - {walletState !== WalletState.DISCONNECTED && ( - - {walletState === WalletState.NOT_INSTALLED && ( - - - - )} - {walletState === WalletState.CONNECTING && } - {walletState === WalletState.CONNECTED && } - - )} - -); diff --git a/widget/ui/src/components/Wallet/Wallet.helpers.ts b/widget/ui/src/components/Wallet/Wallet.helpers.ts new file mode 100644 index 0000000000..37bdc72805 --- /dev/null +++ b/widget/ui/src/components/Wallet/Wallet.helpers.ts @@ -0,0 +1,36 @@ +import type { Info } from './Wallet.types.js'; + +import { i18n } from '@lingui/core'; + +import { WalletState } from './Wallet.types.js'; + +export function makeInfo(state: WalletState): Info { + switch (state) { + case WalletState.CONNECTED: + return { + color: 'success500', + description: i18n.t('Connected'), + tooltipText: i18n.t('Disconnect'), + }; + case WalletState.NOT_INSTALLED: + return { + color: 'info500', + description: i18n.t('Install'), + tooltipText: i18n.t('Install'), + }; + case WalletState.CONNECTING: + return { + color: 'neutral600', + description: i18n.t('Connecting ...'), + tooltipText: i18n.t('Connecting'), + }; + case WalletState.DISCONNECTED: + return { + color: 'neutral600', + description: i18n.t('Disconnected'), + tooltipText: i18n.t('Connect'), + }; + default: + throw new Error(i18n.t('you need to pass a correct state to Wallet.')); + } +} diff --git a/widget/ui/src/components/Wallet/Wallet.stories.tsx b/widget/ui/src/components/Wallet/Wallet.stories.tsx deleted file mode 100644 index 06f270ab62..0000000000 --- a/widget/ui/src/components/Wallet/Wallet.stories.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import React from 'react'; -import { ComponentMeta } from '@storybook/react'; - -import { PropTypes, Wallet } from './Wallet'; -import { WalletState } from '../../types/wallet'; - -export default { - title: 'Wallet chip', - component: Wallet, - argTypes: { - title: { - name: 'title', - type: 'string', - defaultValue: 'Coinbase', - }, - image: { - name: 'image', - type: 'string', - defaultValue: 'https://app.rango.exchange/wallets/coinbase.svg', - }, - disabled: { - name: 'disabled', - type: 'boolean', - defaultValue: false, - }, - state: { - name: 'wallet state', - control: { - type: 'select', - }, - options: Object.values(WalletState), - }, - }, -} as ComponentMeta; - -export const Main = (args: PropTypes) => ; diff --git a/widget/ui/src/components/Wallet/Wallet.styles.ts b/widget/ui/src/components/Wallet/Wallet.styles.ts new file mode 100644 index 0000000000..65f0bbdbf7 --- /dev/null +++ b/widget/ui/src/components/Wallet/Wallet.styles.ts @@ -0,0 +1,80 @@ +import { darkTheme, styled } from '../../theme.js'; +import { Typography } from '../Typography/index.js'; + +export const WalletImageContainer = styled('div', { + '& img': { + borderRadius: '50%', + }, +}); + +export const Title = styled(Typography, { + textTransform: 'capitalize', +}); + +export const Text = styled('div', { + display: 'flex', + flexDirection: 'column', + marginTop: '$10', +}); + +export const WalletButton = styled('button', { + borderRadius: '$xm', + padding: '$10', + border: '0', + display: 'flex', + flexDirection: 'column', + $$color: '$colors$neutral100', + [`.${darkTheme} &`]: { + $$color: '$colors$neutral300', + }, + backgroundColor: '$$color', + alignItems: 'center', + cursor: 'pointer', + width: 100, + position: 'relative', + fontFamily: 'inherit', + '&:hover': { + $$color: '$colors$secondary100', + [`.${darkTheme} &`]: { + $$color: '$colors$neutral100', + }, + backgroundColor: '$$color', + }, + '&:focus-visible': { + $$color: '$colors$secondary100', + [`.${darkTheme} &`]: { + $$color: '$colors$info700', + }, + backgroundColor: '$$color', + outline: 0, + }, + '&:disabled': { + filter: 'grayscale(1)', + pointerEvents: 'none', + }, + variants: { + selected: { + true: { + outlineWidth: 1, + $$outline: '$colors$secondary500', + [`.${darkTheme} &`]: { + $$outline: '$colors$secondary250', + }, + outlineColor: '$$outline', + outlineStyle: 'solid', + }, + }, + }, +}); + +export const LoadingButton = styled('div', { + borderRadius: '$xm', + padding: '$10 0', + border: '0', + display: 'flex', + flexDirection: 'column', + backgroundColor: '$neutral100', + alignItems: 'center', + justifyContent: 'center', + width: 100, +}); diff --git a/widget/ui/src/components/Wallet/Wallet.tsx b/widget/ui/src/components/Wallet/Wallet.tsx index 913e7dd786..bf3b067852 100644 --- a/widget/ui/src/components/Wallet/Wallet.tsx +++ b/widget/ui/src/components/Wallet/Wallet.tsx @@ -1,72 +1,2 @@ -import { detectInstallLink, WalletType } from '@rango-dev/wallets-shared'; -import React from 'react'; - -import { styled } from '../../theme'; -import { WalletInfo, WalletState } from '../../types/wallet'; -import { Button } from '../Button/Button'; -import { Typography } from '../Typography'; -import { State } from './State'; -import { Image } from '../common'; - -const WalletImageContainer = styled('div', { - paddingRight: '$12', -}); -const Text = styled('div', { - display: 'flex', - flexDirection: 'column', -}); - -const ExtendedButton = styled(Button, { - variants: { - type: { - primary: { - outline: '1px solid $primary', - borderColor: '$primary', - - '&:hover': { - borderColor: '$primary', - }, - }, - }, - }, -}); - -export type PropTypes = WalletInfo & { - onClick: (walletType: WalletType) => void; -}; - -export function Wallet(props: PropTypes) { - const { name, type, image, state, onClick, installLink } = props; - - return ( - { - if (state === WalletState.NOT_INSTALLED) { - window.open(detectInstallLink(installLink), '_blank'); - } else onClick(type); - }} - align="start" - variant="outlined" - size="large" - prefix={ - - - - } - suffix={} - > - - - {name} - - {state === WalletState.CONNECTED ? ( - - Connected - - ) : null} - - - ); -} +export { default as Wallet } from './ClickableWallet.js'; +export { SelectableWallet } from './SelectableWallet.js'; diff --git a/widget/ui/src/components/Wallet/Wallet.types.ts b/widget/ui/src/components/Wallet/Wallet.types.ts new file mode 100644 index 0000000000..36e2395c33 --- /dev/null +++ b/widget/ui/src/components/Wallet/Wallet.types.ts @@ -0,0 +1,54 @@ +import type { LegacyWalletInfo } from '@rango-dev/wallets-core/legacy'; +import type { InstallObjects, WalletType } from '@rango-dev/wallets-shared'; +import type { TransactionType } from 'rango-types'; + +export enum WalletState { + NOT_INSTALLED = 'not_installed', + DISCONNECTED = 'disconnected', + CONNECTING = 'connecting', + CONNECTED = 'connected', +} + +export type WalletInfo = { + state: WalletState; + link: InstallObjects | string; + title: string; + image: string; + type: string; + showOnMobile?: boolean; + blockchainTypes: TransactionType[]; + needsNamespace?: LegacyWalletInfo['needsNamespace']; + needsDerivationPath?: LegacyWalletInfo['needsDerivationPath']; +}; + +export interface Info { + color: string; + description: string; + tooltipText: string; +} + +export interface ContentProps { + image: string; + title: string; + description: string; + descriptionColor?: string; +} + +export interface WalletPropTypes { + state: WalletState; + title: string; + image: string; + link: InstallObjects | string; + type: WalletType; + onClick: (type: WalletType) => void; + selected?: boolean; + description?: string; + isLoading?: boolean; + container?: HTMLElement; + disabled?: boolean; +} + +export type SelectablePropTypes = WalletPropTypes & { + selected: boolean; + disabled?: boolean; +}; diff --git a/widget/ui/src/components/Wallet/index.ts b/widget/ui/src/components/Wallet/index.ts index 7df19835ed..dbf96e1c39 100644 --- a/widget/ui/src/components/Wallet/index.ts +++ b/widget/ui/src/components/Wallet/index.ts @@ -1 +1,3 @@ -export * from './Wallet'; +export * from './Wallet.js'; +export type { WalletInfo } from './Wallet.types.js'; +export { WalletState } from './Wallet.types.js'; diff --git a/widget/ui/src/components/common/FilledCircle.tsx b/widget/ui/src/components/common/FilledCircle.tsx deleted file mode 100644 index cc30ea0293..0000000000 --- a/widget/ui/src/components/common/FilledCircle.tsx +++ /dev/null @@ -1,8 +0,0 @@ -import { styled } from '../../theme'; - -export const FilledCircle = styled('span', { - width: '10px', - height: '10px', - backgroundColor: '$primary', - borderRadius: '99999px', -}); diff --git a/widget/ui/src/components/common/Image.tsx b/widget/ui/src/components/common/Image.tsx index eecc1e11d6..6aba636fb2 100644 --- a/widget/ui/src/components/common/Image.tsx +++ b/widget/ui/src/components/common/Image.tsx @@ -1,7 +1,8 @@ import React from 'react'; -import { styled } from '../../theme'; -const ImageContainer = styled('div', { +import { styled } from '../../theme.js'; + +export const ImageContainer = styled('div', { display: 'flex', justifyContent: 'center', alignItems: 'center', @@ -10,18 +11,44 @@ const ImageContainer = styled('div', { height: '100%', objectFit: 'contain', }, + '.circular': { + borderRadius: '$lg', + }, }); type PropTypes = { + id?: string; size: number; + useAsPlaceholder?: boolean; + backgroundColor?: string; + borderRadius?: string; + type?: 'circular' | 'rectangular'; } & React.ImgHTMLAttributes; export function Image(props: PropTypes) { - const { size, ...otherProps } = props; + const { + size, + useAsPlaceholder, + backgroundColor = '$secondary100', + type, + ...otherProps + } = props; + + const borderRadius = type === 'circular' ? '$lg' : '$xs'; return ( - - + + {!useAsPlaceholder && ( + + )} ); } diff --git a/widget/ui/src/components/common/index.ts b/widget/ui/src/components/common/index.ts index 15731dedf7..fb1cf3418e 100644 --- a/widget/ui/src/components/common/index.ts +++ b/widget/ui/src/components/common/index.ts @@ -1,2 +1 @@ -export { FilledCircle } from './FilledCircle'; -export { Image } from './Image'; +export { Image, ImageContainer } from './Image.js'; diff --git a/widget/ui/src/components/common/styles.ts b/widget/ui/src/components/common/styles.ts new file mode 100644 index 0000000000..2b781276bd --- /dev/null +++ b/widget/ui/src/components/common/styles.ts @@ -0,0 +1,35 @@ +import * as Collapsible from '@radix-ui/react-collapsible'; + +import { keyframes, styled } from '../../theme.js'; + +const slideDown = keyframes({ + from: { + height: 0, + }, + to: { + height: 'var(--radix-collapsible-content-height)', + }, +}); + +const slideUp = keyframes({ + from: { + height: 'var(--radix-collapsible-content-height)', + }, + to: { + height: 0, + }, +}); + +export const CollapsibleContent = styled(Collapsible.Content, { + overflow: 'hidden', + variants: { + open: { + true: { + animation: `${slideDown} 300ms ease-out`, + }, + false: { + animation: `${slideUp} 300ms ease-out`, + }, + }, + }, +}); diff --git a/widget/ui/src/components/index.ts b/widget/ui/src/components/index.ts index b3e09e58c6..89c441bcae 100644 --- a/widget/ui/src/components/index.ts +++ b/widget/ui/src/components/index.ts @@ -1,31 +1,49 @@ -export * from './BestRoute'; -export * from './BlockchainSelector'; -export * from './Button'; -export * from './Checkbox'; -export * from './Chip'; -export * from './ConnectWalletsModal'; -export * from './Icon'; -export * from './LiquiditySourcesSelector'; -export * from './Modal'; -export * from './SecondaryPage'; -export * from './SelectableWalletList'; -export * from './Settings'; -export * from './Spacer'; -export * from './Spinner'; -export * from './StepDetail'; -export * from './SwapContainer'; -export * from './SwapDetail'; -export * from './Switch'; -export * from './TextField'; -export * from './TokenSelector'; -export * from './Tooltip'; -export * from './Typography'; -export * from './Wallet'; -export * from './Alert'; -export * from './ColorPicker'; -export * from './Radio'; -export * from './TokenList'; -export * from './common'; -export * from './Drawer'; -export * from './Header'; -export * from './Divider'; +export * from './I18nManager/index.js'; +export * from './Alert/index.js'; +export * from './BlockchainsChip/index.js'; +export * from './BottomLogo/index.js'; +export * from './Button/index.js'; +export * from './IconButton/index.js'; +export * from './Collapsible/index.js'; +export * from './Checkbox/index.js'; +export * from './Chip/index.js'; +export * from './common/index.js'; +export * from './Divider/index.js'; +export * from './FullExpandedQuote/index.js'; +export * from './Header/index.js'; +export * from './Modal/index.js'; +export * from './MessageBox/index.js'; +export * from './RadioGroup/index.js'; +export * from './RefreshProgressButton/index.js'; +export * from './SelectableCategoryList/index.js'; +export * from './Spinner/index.js'; +export * from './SwapListItem/index.js'; +export * from './Switch/index.js'; +export * from './TextField/index.js'; +export * from './Toast/index.js'; +export * from './Tooltip/index.js'; +export * from './Typography/index.js'; +export * from './Wallet/index.js'; +export * from './Radio/index.js'; +export * from './PriceImpact/index.js'; +export * from './ChainToken/index.js'; +export * from './Skeleton/index.js'; +export * from './VirtualizedList/index.js'; +export * from './ListItemButton/index.js'; +export * from './List/index.js'; +export * from './ListItem/index.js'; +export * from './NotFound/index.js'; +export * from './MessageBox/index.js'; +export * from './IconButton/index.js'; +export * from './QuoteCost/index.js'; +export * from './TokenAmount/index.js'; +export * from './StepDetails/index.js'; +export * from './Popover/index.js'; +export * from './Flags/index.js'; +export * from './Select/index.js'; +export * from './QuoteTag/index.js'; +export * from './Tabs/index.js'; +export type { + SvgIconProps, + SvgIconPropsWithChildren, +} from './SvgIcon/index.js'; diff --git a/widget/ui/src/constants/index.ts b/widget/ui/src/constants/index.ts new file mode 100644 index 0000000000..758b295f31 --- /dev/null +++ b/widget/ui/src/constants/index.ts @@ -0,0 +1,6 @@ +export const UI_ID = { + SWAP_FROM_INPUT_CONTAINER_ID: 'rango-swap-from-input-container', + SWAP_TO_INPUT_CONTAINER_ID: 'rango-swap-to-input-container', + SWAP_FROM_CHAIN_IMAGE_ID: 'rango-swap-from-chain-image', + SWAP_TO_CHAIN_IMAGE_ID: 'rango-swap-to-chain-image', +}; diff --git a/widget/ui/src/containers/ConfirmSwap/ConfirmSwap.stories.tsx b/widget/ui/src/containers/ConfirmSwap/ConfirmSwap.stories.tsx deleted file mode 100644 index 4a92628a00..0000000000 --- a/widget/ui/src/containers/ConfirmSwap/ConfirmSwap.stories.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import React from 'react'; -import { ComponentMeta } from '@storybook/react'; -import { ConfirmSwap, PropTypes } from './ConfirmSwap'; -import { exampleFor5Wallets, wallets } from './mock'; - -export default { - title: 'Containers/ConfirmSwap', - component: ConfirmSwap, - argTypes: { - requiredWallets: { - defaultValue: ['BSC', 'OSMOSIS'], - }, - }, -} as ComponentMeta; - -export const Main = (props: PropTypes) => ( - -); - -export const With5Wallets = (props: PropTypes) => ( - -); diff --git a/widget/ui/src/containers/ConfirmSwap/ConfirmSwap.tsx b/widget/ui/src/containers/ConfirmSwap/ConfirmSwap.tsx deleted file mode 100644 index 081e170dc9..0000000000 --- a/widget/ui/src/containers/ConfirmSwap/ConfirmSwap.tsx +++ /dev/null @@ -1,180 +0,0 @@ -import React, { PropsWithChildren, ReactNode } from 'react'; -import { Alert, Spacer } from '../../components'; -import { Button } from '../../components/Button'; -import { SecondaryPage } from '../../components/SecondaryPage/SecondaryPage'; -import { SelectableWalletList } from '../../components/SelectableWalletList'; -import { Typography } from '../../components/Typography'; -import { styled } from '../../theme'; -import { SelectableWallet } from '../../types'; - -const MainContainer = styled('div', { - overflowY: 'auto', -}); - -const Section = styled('div', { - paddingBottom: '$32', - marginBottom: '$32', - borderBottom: '1px solid $neutrals400', -}); - -const Footer = styled('div', { - display: 'flex', - alignItems: 'center', -}); - -const AlertContainer = styled('div', { - padding: '$16 0', -}); - -const ConfirmButton = styled(Button, { - marginTop: '$16', -}); - -const Container = styled('div', { - paddingBottom: '$24', - - '.title': { - paddingBottom: '$8', - display: 'flex', - alignItems: 'center', - }, - '.num': { - backgroundColor: '$neutrals300', - display: 'inline-flex', - width: '24px', - height: '24px', - color: '$neutrals800', - borderRadius: '50%', - fontSize: '$14', - border: '1px solid $neutrals400', - justifyContent: 'center', - alignItems: 'center', - }, -}); - -const Alerts = styled('div', { paddingBottom: '$16' }); - -type Message = string | ReactNode - -export interface PropTypes { - onBack: () => void; - onConfirm?: (event: React.MouseEvent) => void; - confirmDisabled?: boolean; - loading?: boolean; - requiredWallets: string[]; - selectableWallets: SelectableWallet[]; - onChange: (w: SelectableWallet) => void; - isExperimentalChain?: (wallet: string) => boolean; - handleConnectChain?: (wallet: string) => void; - previewInputs?: ReactNode; - previewRoutes?: ReactNode; - confirmButtonTitle: string; - errors?: Message[]; - warnings?: Message[]; - extraMessages?: ReactNode; -} -export function ConfirmSwap(props: PropsWithChildren) { - const { - onBack, - loading, - onConfirm, - requiredWallets, - selectableWallets, - onChange, - confirmDisabled, - isExperimentalChain, - handleConnectChain, - confirmButtonTitle, - errors, - warnings, - extraMessages, - } = props; - - return ( - - - {confirmButtonTitle} - - - } - > - -
- {extraMessages || null} - - {errors?.map((error, index) => ( - <> - - - - ))} - {warnings?.map((warning, index) => ( - <> - - - - ))} - -
- {props.previewInputs || props.previewRoutes ? ( -
- {props.previewInputs} - {!!props.previewRoutes ? ( - - ) : null} - {props.previewRoutes} -
- ) : null} - - {requiredWallets.map((wallet, index) => { - const list = selectableWallets.filter((w) => wallet === w.chain); - return ( - -
-
{index + 1}
- - Your {wallet} Wallet -
- {list.length === 0 && ( - <> - - - You need to connect a compatible wallet with {wallet}. - - - {isExperimentalChain?.(wallet) && ( - - )} - - )} - {list.length != 0 && ( - - )} -
- ); - })} -
-
- ); -} diff --git a/widget/ui/src/containers/ConfirmSwap/index.ts b/widget/ui/src/containers/ConfirmSwap/index.ts deleted file mode 100644 index 8e886e4a00..0000000000 --- a/widget/ui/src/containers/ConfirmSwap/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { ConfirmSwap } from './ConfirmSwap'; diff --git a/widget/ui/src/containers/ConfirmSwap/mock.ts b/widget/ui/src/containers/ConfirmSwap/mock.ts deleted file mode 100644 index 74d0a57ae5..0000000000 --- a/widget/ui/src/containers/ConfirmSwap/mock.ts +++ /dev/null @@ -1,223 +0,0 @@ -// @ts-nocheck -import { WalletType } from '@rango-dev/wallets-shared'; -import { RoutingResultType } from 'rango-sdk'; -import { BestRouteType } from '../../types/swaps'; -import { SelectableWallet } from '../../types'; - -export const bestRoute: BestRouteType = { - from: { blockchain: 'BSC', symbol: 'BNB', address: null }, - to: { blockchain: 'AVAX_CCHAIN', symbol: 'AVAX', address: null }, - requestAmount: '0.3', - requestId: '228529e3-27d7-4fa9-ab84-bb2b90eade6f', - result: { - resultType: RoutingResultType.OK, - outputAmount: '5.685715974132648891', - swaps: [ - { - swapperId: 'AnySwap Aggregator', - swapperType: 'AGGREGATOR', - swapperLogo: 'https://api.rango.exchange/swappers/multichain.png', - - from: { - symbol: 'BNB', - logo: 'https://api.rango.exchange/i/Y3v1KW', - blockchainLogo: 'https://api.rango.exchange/blockchains/binance.svg', - - address: null, - blockchain: 'BSC', - decimals: 18, - usdPrice: 279.2738558274085, - }, - to: { - symbol: 'WETH.E', - logo: 'https://api.rango.exchange/i/j9xgdC', - blockchainLogo: - 'https://api.rango.exchange/blockchains/avax_cchain.svg', - - address: '0x49d5c2bdffac6ce2bfdb6640f4f80f226bc10bab', - blockchain: 'AVAX_CCHAIN', - decimals: 18, - usdPrice: 1329.24, - }, - fromAmount: '0.300000000000000000', - fromAmountPrecision: null, - fromAmountMinValue: '0.047579322466294684272760', - fromAmountMaxValue: '79302.26195302606417382090', - fromAmountRestrictionType: 'INCLUSIVE', - toAmount: '0.062064305934309070', - fee: [ - { - asset: { blockchain: 'BSC', symbol: 'BNB', address: null }, - expenseType: 'FROM_SOURCE_WALLET', - amount: '0.001388002000000000', - name: 'Network Fee', - }, - ], - estimatedTimeInSeconds: 300, - swapChainType: 'INTRA_CHAIN', - routes: null, - recommendedSlippage: null, - timeStat: { min: 162, avg: 260, max: 467 }, - includesDestinationTx: false, - maxRequiredSign: 1, - warnings: [], - }, - { - swapperId: 'PangolinSwap', - swapperLogo: 'https://api.rango.exchange/swappers/pangolin.png', - swapperType: 'DEX', - from: { - symbol: 'WETH.E', - logo: 'https://api.rango.exchange/i/j9xgdC', - address: '0x49d5c2bdffac6ce2bfdb6640f4f80f226bc10bab', - blockchain: 'AVAX_CCHAIN', - decimals: 18, - usdPrice: 1329.24, - blockchainLogo: - 'https://api.rango.exchange/blockchains/avax_cchain.svg', - }, - to: { - symbol: 'AVAX', - logo: 'https://api.rango.exchange/i/kX4edQ', - address: null, - blockchain: 'AVAX_CCHAIN', - decimals: 18, - usdPrice: 12.5, - blockchainLogo: - 'https://api.rango.exchange/blockchains/avax_cchain.svg', - }, - fromAmount: '0.062064305934309070', - fromAmountPrecision: null, - fromAmountMinValue: null, - fromAmountMaxValue: null, - fromAmountRestrictionType: 'EXCLUSIVE', - toAmount: '5.685715974132648891', - fee: [ - { - asset: { - blockchain: 'AVAX_CCHAIN', - symbol: 'WETH.E', - address: '0x49d5c2bdffac6ce2bfdb6640f4f80f226bc10bab', - }, - name: 'Network Fee', - expenseType: 'DECREASE_FROM_OUTPUT', - amount: - '0.00018619291780292721387591870688029381530892436558133340440690517425537109375', - }, - { - asset: { blockchain: 'AVAX_CCHAIN', symbol: 'AVAX', address: null }, - expenseType: 'FROM_SOURCE_WALLET', - amount: '0.005370022532678750', - name: 'Network Fee', - }, - ], - estimatedTimeInSeconds: 45, - swapChainType: 'INTER_CHAIN', - routes: [ - { - nodes: [ - { - nodes: [ - { - marketName: 'PangolinSwap', - marketId: 'PangolinSwap', - percent: 1.0, - }, - ], - from: 'WETH.e', - fromLogo: '', - fromAddress: '0x49d5c2bdffac6ce2bfdb6640f4f80f226bc10bab', - fromBlockchain: 'AVAX_CCHAIN', - to: 'WAVAX', - toLogo: '', - toAddress: '0xb31f66aa3c1e785363f0875a1b74e27b85fd66c7', - toBlockchain: 'AVAX_CCHAIN', - }, - ], - }, - ], - recommendedSlippage: null, - timeStat: { min: 6, avg: 39, max: 317 }, - includesDestinationTx: false, - maxRequiredSign: 1, - warnings: [], - }, - ], - }, - validationStatus: null, - missingBlockchains: [], - diagnosisMessages: [], - walletNotSupportingFromBlockchain: false, - processingLimitReached: false, -}; - -export const wallets: SelectableWallet[] = [ - { - walletType: WalletType.META_MASK, - address: '0x5423e28219d6d568dcf62a8134d623e6f4a1c2df', - image: 'https://app.rango.exchange/wallets/metamask.svg', - chain: 'BSC', - selected: false, - }, - { - walletType: WalletType.OKX, - address: '0x2702d89c1c8658b49c45dd460deebcc45faec03c', - image: 'https://app.rango.exchange/wallets/okx.png', - chain: 'BSC', - selected: false, - }, - - { - walletType: WalletType.KEPLR, - address: 'osmo1unf2rcytjxfpz8x8ar63h4qeftadptg5t0nqcl', - image: 'https://app.rango.exchange/wallets/keplr.png', - chain: 'OSMOSIS', - selected: false, - }, -]; - -export const exampleFor5Wallets: SelectableWallet[] = [ - { - walletType: WalletType.META_MASK, - address: '0x5423e28219d6d568dcf62a8134d623e6f4a1c2df', - image: 'https://app.rango.exchange/wallets/metamask.svg', - selected: false, - chain: 'BSC', - }, - { - walletType: WalletType.OKX, - address: '0x2702d89c1c8658b49c45dd460deebcc45faec03c', - image: 'https://app.rango.exchange/wallets/okx.png', - selected: false, - chain: 'BSC', - }, - { - walletType: WalletType.EXODUS, - address: '0x2702d89c1c8658b49c45dd460deebcc45faec03c', - image: 'https://app.rango.exchange/wallets/exodus.png', - selected: false, - chain: 'BSC', - }, - { - walletType: WalletType.MATH, - address: '0x2702d89c1c8658b49c45dd460deebcc45faec03c', - image: 'https://app.rango.exchange/wallets/math-wallet.png', - selected: false, - chain: 'BSC', - }, - { - walletType: WalletType.CLOVER, - address: '0x2702d89c1c8658b49c45dd460deebcc45faec03c', - image: 'https://app.rango.exchange/wallets/clover.jpeg', - selected: false, - chain: 'BSC', - }, - - { - walletType: WalletType.KEPLR, - address: 'osmo1unf2rcytjxfpz8x8ar63h4qeftadptg5t0nqcl', - image: 'https://app.rango.exchange/wallets/keplr.png', - selected: false, - chain: 'OSMOSIS', - }, -]; diff --git a/widget/ui/src/containers/ConnectWalletsModal/ConnectWalletsModal.styles.ts b/widget/ui/src/containers/ConnectWalletsModal/ConnectWalletsModal.styles.ts new file mode 100644 index 0000000000..54b56b8952 --- /dev/null +++ b/widget/ui/src/containers/ConnectWalletsModal/ConnectWalletsModal.styles.ts @@ -0,0 +1,8 @@ +import { styled } from '../../theme.js'; + +export const ModalContent = styled('div', { + display: 'grid', + gap: '$8', + gridTemplateColumns: 'repeat(2, minmax(0, 1fr))', + overflow: 'auto', +}); diff --git a/widget/ui/src/containers/ConnectWalletsModal/ConnectWalletsModal.tsx b/widget/ui/src/containers/ConnectWalletsModal/ConnectWalletsModal.tsx new file mode 100644 index 0000000000..5471b7a4bf --- /dev/null +++ b/widget/ui/src/containers/ConnectWalletsModal/ConnectWalletsModal.tsx @@ -0,0 +1,28 @@ +import type { ConnectWalletsModalPropTypes } from './ConnectWalletsModal.types.js'; + +import { i18n } from '@lingui/core'; +import React from 'react'; + +import { Modal, Wallet } from '../../components/index.js'; + +import { ModalContent } from './ConnectWalletsModal.styles.js'; + +export function ConnectWalletsModal(props: ConnectWalletsModalPropTypes) { + const { open, list, onSelect, onClose } = props; + + return ( + + + {list.map((info) => ( + + ))} + + + ); +} diff --git a/widget/ui/src/containers/ConnectWalletsModal/ConnectWalletsModal.types.ts b/widget/ui/src/containers/ConnectWalletsModal/ConnectWalletsModal.types.ts new file mode 100644 index 0000000000..1d7dedd5a2 --- /dev/null +++ b/widget/ui/src/containers/ConnectWalletsModal/ConnectWalletsModal.types.ts @@ -0,0 +1,10 @@ +import type { WalletInfo } from '../../components/index.js'; +import type { WalletType } from '@rango-dev/wallets-shared'; + +export interface ConnectWalletsModalPropTypes { + open: boolean; + list: WalletInfo[]; + onSelect: (walletType: WalletType) => void; + onClose: () => void; + error?: string; +} diff --git a/widget/ui/src/containers/ConnectWalletsModal/index.ts b/widget/ui/src/containers/ConnectWalletsModal/index.ts new file mode 100644 index 0000000000..cb8263e3de --- /dev/null +++ b/widget/ui/src/containers/ConnectWalletsModal/index.ts @@ -0,0 +1,2 @@ +export { ConnectWalletsModal } from './ConnectWalletsModal.js'; +export type { ConnectWalletsModalPropTypes } from './ConnectWalletsModal.types.js'; diff --git a/widget/ui/src/containers/History/History.stories.tsx b/widget/ui/src/containers/History/History.stories.tsx deleted file mode 100644 index 7ae56235a8..0000000000 --- a/widget/ui/src/containers/History/History.stories.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import React from 'react'; -import { ComponentMeta } from '@storybook/react'; - -import { History, PropTypes } from './History'; -import { pendingSwap } from './mock'; - -export default { - title: 'Containers/History', - component: History, -} as ComponentMeta; - -export const Main = (props: PropTypes) => ( - -); diff --git a/widget/ui/src/containers/History/History.tsx b/widget/ui/src/containers/History/History.tsx deleted file mode 100644 index 96a23d7bdb..0000000000 --- a/widget/ui/src/containers/History/History.tsx +++ /dev/null @@ -1,72 +0,0 @@ -import React, { PropsWithChildren } from 'react'; -import { Spinner } from '../../components'; -import { SecondaryPage } from '../../components/SecondaryPage'; -import { containsText } from '../../helper'; -import { styled } from '../../theme'; -import { PendingSwap } from './types'; -import { NotFoundAlert } from '../../components/Alert/NotFoundAlert'; -import { LoaderContainer } from '../../components/TokenSelector/TokenSelector'; -import { SwapsGroup, PropTypes as SwapsGroupPropTypes } from './SwapsGroup'; - -const Container = styled('div', { - overflowY: 'auto', -}); -const filteredHistory = ( - list: PendingSwap[], - searchedFor: string -): PendingSwap[] => { - return list.filter((swap) => { - const firstStep = swap.steps[0]; - const lastStep = swap.steps[swap.steps.length - 1]; - return ( - containsText(firstStep.fromBlockchain, searchedFor) || - containsText(firstStep.fromSymbol, searchedFor) || - containsText(lastStep.toBlockchain, searchedFor) || - containsText(lastStep.toSymbol, searchedFor) || - containsText(swap.requestId, searchedFor) - ); - }); -}; - -export type PropTypes = SwapsGroupPropTypes & { loading: boolean }; - -export function History(props: PropsWithChildren) { - const { list = [], onBack, onSwapClick, groupBy, loading } = props; - - return ( - - {(searchedFor) => { - const filterSwaps = filteredHistory(list, searchedFor); - return ( - <> - {loading && ( - - - - )} - - {!loading && ( - <> - {filterSwaps.length ? ( - - ) : ( - - )} - - )} - - - ); - }} - - ); -} diff --git a/widget/ui/src/containers/History/SwapsGroup.tsx b/widget/ui/src/containers/History/SwapsGroup.tsx deleted file mode 100644 index 86feb15433..0000000000 --- a/widget/ui/src/containers/History/SwapsGroup.tsx +++ /dev/null @@ -1,59 +0,0 @@ -import { PendingSwap } from '@rango-dev/queue-manager-rango-preset'; -import React from 'react'; -import { Typography, SwapDetail, Divider } from '../../components'; -import { styled } from '../../theme'; - -const Group = styled('div', { - '.group-title': { - textTransform: 'uppercase', - }, -}); - -export type GroupBy = (list: PendingSwap[]) => { - title: string; - swaps: PendingSwap[]; -}[]; - -export interface PropTypes { - list: PendingSwap[]; - onBack: () => void; - onSwapClick: (requestId: string) => void; - groupBy?: GroupBy; -} - -export function SwapsGroup(props: Omit) { - const { list, onSwapClick, groupBy } = props; - const groups = groupBy ? groupBy(list) : [{ title: 'History', swaps: list }]; - - return ( - <> - {groups - .filter((group) => group.swaps.length > 0) - .map((group, index) => ( - <> - - - {group.title} - - {group.swaps.map((swap: PendingSwap, index: number) => ( - <> - - - - ))} - - - - ))} - - ); -} diff --git a/widget/ui/src/containers/History/index.ts b/widget/ui/src/containers/History/index.ts deleted file mode 100644 index 1b57c1eff4..0000000000 --- a/widget/ui/src/containers/History/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { History } from './History'; -export { SwapsGroup, GroupBy } from './SwapsGroup'; diff --git a/widget/ui/src/containers/History/mock.ts b/widget/ui/src/containers/History/mock.ts deleted file mode 100644 index 57c4e6e5e0..0000000000 --- a/widget/ui/src/containers/History/mock.ts +++ /dev/null @@ -1,826 +0,0 @@ -// @ts-nocheck -import { RoutingResultType, TransactionType } from 'rango-sdk'; -import { PendingSwap } from './types'; - -export const pendingSwap: PendingSwap[] = [ - { - creationTime: '1673164511955', - finishTime: '1673164550137', - requestId: '51e211d9-d61c-45d2-a4d4-1f9f7f90ee85', - inputAmount: '1', - wallets: { - OSMOSIS: { - walletType: 'keplr', - address: 'osmo1unf2rcytjxfpz8x8ar63h4qeftadptg5t0nqcl', - }, - }, - status: 'running', - isPaused: false, - extraMessage: null, - extraMessageSeverity: 'info', - extraMessageDetail: '', - extraMessageErrorCode: null, - networkStatusExtraMessage: null, - networkStatusExtraMessageDetail: null, - lastNotificationTime: null, - settings: { - slippage: '1.0', - disabledSwappersIds: [], - disabledSwappersGroups: [], - }, - simulationResult: { - resultType: RoutingResultType.OK, - outputAmount: '1.540670', - swaps: [ - { - swapperId: 'Osmosis', - swapperType: 'DEX', - swapperLogo: '', - from: { - symbol: 'JUNO', - logo: 'https://api.rango.exchange/tokens/COSMOS/JUNO.png', - address: - 'ibc/46b44899322f3cd854d2d46deef881958467cdd4b3b10086da49296bbed94bed', - blockchain: 'OSMOSIS', - blockchainLogo: '', - decimals: 6, - usdPrice: 1.1091996179668873, - }, - to: { - symbol: 'OSMO', - logo: 'https://api.rango.exchange/i/mJQPS2', - address: null, - blockchain: 'OSMOSIS', - decimals: 6, - blockchainLogo: '', - usdPrice: 0.7192435454440882, - }, - fromAmount: '1.000000', - fromAmountPrecision: null, - fromAmountMinValue: null, - fromAmountMaxValue: null, - fromAmountRestrictionType: 'EXCLUSIVE', - toAmount: '1.540670', - fee: [ - { - asset: { - blockchain: 'OSMOSIS', - symbol: 'OSMO', - address: null, - }, - expenseType: 'FROM_SOURCE_WALLET', - amount: '0', - name: 'Network Fee', - }, - ], - estimatedTimeInSeconds: 45, - swapChainType: 'INTRA_CHAIN', - routes: [ - { - nodes: [ - { - nodes: [ - { - marketName: 'pool#498', - marketId: null, - percent: 1, - }, - ], - from: 'JUNO', - fromLogo: 'https://api.rango.exchange/tokens/COSMOS/JUNO.png', - fromAddress: - 'ibc/46b44899322f3cd854d2d46deef881958467cdd4b3b10086da49296bbed94bed', - fromBlockchain: 'OSMOSIS', - to: 'ATOM', - toLogo: 'https://api.rango.exchange/tokens/COSMOS/ATOM.png', - toAddress: - 'ibc/27394fb092d2eccd56123c74f36e4c1f926001ceada9ca97ea622b25f41e5eb2', - toBlockchain: 'OSMOSIS', - }, - { - nodes: [ - { - marketName: 'pool#8', - marketId: null, - percent: 1, - }, - ], - from: 'ATOM', - fromLogo: 'https://api.rango.exchange/tokens/COSMOS/ATOM.png', - fromAddress: - 'ibc/27394fb092d2eccd56123c74f36e4c1f926001ceada9ca97ea622b25f41e5eb2', - fromBlockchain: 'OSMOSIS', - to: 'IRIS', - toLogo: 'https://api.rango.exchange/tokens/COSMOS/IRIS.png', - toAddress: - 'ibc/7c4d60aa95e5a7558b0a364860979ca34b7ff8aaf255b87af9e879374470cec0', - toBlockchain: 'OSMOSIS', - }, - { - nodes: [ - { - marketName: 'pool#7', - marketId: null, - percent: 1, - }, - ], - from: 'IRIS', - fromLogo: 'https://api.rango.exchange/tokens/COSMOS/IRIS.png', - fromAddress: - 'ibc/7c4d60aa95e5a7558b0a364860979ca34b7ff8aaf255b87af9e879374470cec0', - fromBlockchain: 'OSMOSIS', - to: 'OSMO', - toLogo: 'https://api.rango.exchange/tokens/COSMOS/OSMO.png', - toAddress: null, - toBlockchain: 'OSMOSIS', - }, - ], - }, - ], - recommendedSlippage: null, - timeStat: { - min: 6, - avg: 40, - max: 241, - }, - includesDestinationTx: false, - maxRequiredSign: 1, - warnings: [], - }, - ], - }, - validateBalanceOrFee: true, - steps: [ - { - id: 1, - fromBlockchain: 'OSMOSIS', - fromSymbol: 'JUNO', - fromSymbolAddress: - 'ibc/46b44899322f3cd854d2d46deef881958467cdd4b3b10086da49296bbed94bed', - fromDecimals: 6, - fromAmountPrecision: null, - fromAmountMinValue: null, - fromAmountMaxValue: null, - toBlockchainLogo: 'https://api.rango.exchange/swappers/osmosis.png', - fromBlockchainLogo: 'https://api.rango.exchange/swappers/osmosis.png', - toBlockchain: 'OSMOSIS', - fromLogo: 'https://api.rango.exchange/tokens/COSMOS/JUNO.png', - toSymbol: 'OSMO', - toSymbolAddress: null, - swapperType: 'DEX', - toDecimals: 6, - toLogo: 'https://api.rango.exchange/i/mJQPS2', - startTransactionTime: 1673164519916, - swapperId: 'Osmosis', - swapperLogo: '', - expectedOutputAmountHumanReadable: '1.540670', - outputAmount: '1.540658', - status: 'running', - networkStatus: null, - executedTransactionId: - '0f8f17eecc863c2d6be65ef52cfe3128ff3cd7baeddf133160bea8ccdfbf876b', - explorerUrl: [ - { - url: 'https://www.mintscan.io/osmosis/txs/0f8f17eecc863c2d6be65ef52cfe3128ff3cd7baeddf133160bea8ccdfbf876b', - description: null, - }, - ], - cosmosTransaction: { - type: TransactionType.COSMOS, - fromWalletAddress: 'osmo1unf2rcytjxfpz8x8ar63h4qeftadptg5t0nqcl', - blockChain: 'OSMOSIS', - data: { - chainId: 'osmosis-1', - account_number: 102721, - sequence: '308', - msgs: [ - { - __type: 'OsmosisSwapMessage', - type: 'osmosis/gamm/swap-exact-amount-in', - value: { - sender: 'osmo1unf2rcytjxfpz8x8ar63h4qeftadptg5t0nqcl', - routes: [ - { - pool_id: '498', - token_out_denom: - 'ibc/27394FB092D2ECCD56123C74F36E4C1F926001CEADA9CA97EA622B25F41E5EB2', - }, - { - pool_id: '8', - token_out_denom: - 'ibc/7C4D60AA95E5A7558B0A364860979CA34B7FF8AAF255B87AF9E879374470CEC0', - }, - { - pool_id: '7', - token_out_denom: 'uosmo', - }, - ], - token_in: { - denom: - 'ibc/46B44899322F3CD854D2D46DEEF881958467CDD4B3B10086DA49296BBED94BED', - amount: '1000000', - }, - token_out_min_amount: '1525264', - }, - }, - ], - protoMsgs: [ - { - type_url: '/osmosis.gamm.v1beta1.MsgSwapExactAmountIn', - value: [ - 10, 43, 111, 115, 109, 111, 49, 117, 110, 102, 50, 114, 99, - 121, 116, 106, 120, 102, 112, 122, 56, 120, 56, 97, 114, 54, - 51, 104, 52, 113, 101, 102, 116, 97, 100, 112, 116, 103, 53, - 116, 48, 110, 113, 99, 108, 18, 73, 8, -14, 3, 18, 68, 105, - 98, 99, 47, 50, 55, 51, 57, 52, 70, 66, 48, 57, 50, 68, 50, - 69, 67, 67, 68, 53, 54, 49, 50, 51, 67, 55, 52, 70, 51, 54, - 69, 52, 67, 49, 70, 57, 50, 54, 48, 48, 49, 67, 69, 65, 68, - 65, 57, 67, 65, 57, 55, 69, 65, 54, 50, 50, 66, 50, 53, 70, - 52, 49, 69, 53, 69, 66, 50, 18, 72, 8, 8, 18, 68, 105, 98, 99, - 47, 55, 67, 52, 68, 54, 48, 65, 65, 57, 53, 69, 53, 65, 55, - 53, 53, 56, 66, 48, 65, 51, 54, 52, 56, 54, 48, 57, 55, 57, - 67, 65, 51, 52, 66, 55, 70, 70, 56, 65, 65, 70, 50, 53, 53, - 66, 56, 55, 65, 70, 57, 69, 56, 55, 57, 51, 55, 52, 52, 55, - 48, 67, 69, 67, 48, 18, 9, 8, 7, 18, 5, 117, 111, 115, 109, - 111, 26, 79, 10, 68, 105, 98, 99, 47, 52, 54, 66, 52, 52, 56, - 57, 57, 51, 50, 50, 70, 51, 67, 68, 56, 53, 52, 68, 50, 68, - 52, 54, 68, 69, 69, 70, 56, 56, 49, 57, 53, 56, 52, 54, 55, - 67, 68, 68, 52, 66, 51, 66, 49, 48, 48, 56, 54, 68, 65, 52, - 57, 50, 57, 54, 66, 66, 69, 68, 57, 52, 66, 69, 68, 18, 7, 49, - 48, 48, 48, 48, 48, 48, 34, 7, 49, 53, 50, 53, 50, 54, 52, - ], - }, - ], - memo: '', - source: null, - fee: { - gas: '900000', - amount: [ - { - denom: 'uosmo', - amount: '0', - }, - ], - }, - signType: 'AMINO', - rpcUrl: 'sample_rpc', - }, - rawTransfer: null, - }, - solanaTransaction: null, - evmTransaction: null, - evmApprovalTransaction: null, - transferTransaction: null, - diagnosisUrl: null, - internalSteps: null, - }, - ], - }, - { - creationTime: '1673164511955', - finishTime: '1673164550137', - requestId: '51e211d9-d61c-45d2-a4d4-1f9f7f90ee85', - inputAmount: '1', - wallets: { - OSMOSIS: { - walletType: 'keplr', - address: 'osmo1unf2rcytjxfpz8x8ar63h4qeftadptg5t0nqcl', - }, - }, - status: 'failed', - isPaused: false, - extraMessage: null, - extraMessageSeverity: 'info', - extraMessageDetail: '', - extraMessageErrorCode: null, - networkStatusExtraMessage: null, - networkStatusExtraMessageDetail: null, - lastNotificationTime: null, - settings: { - slippage: '1.0', - disabledSwappersIds: [], - disabledSwappersGroups: [], - }, - simulationResult: { - resultType: RoutingResultType.OK, - outputAmount: '1.540670', - swaps: [ - { - swapperId: 'Osmosis', - swapperLogo: '', - swapperType: 'DEX', - from: { - symbol: 'JUNO', - logo: 'https://api.rango.exchange/tokens/COSMOS/JUNO.png', - address: - 'ibc/46b44899322f3cd854d2d46deef881958467cdd4b3b10086da49296bbed94bed', - blockchain: 'OSMOSIS', - blockchainLogo: '', - decimals: 6, - usdPrice: 1.1091996179668873, - }, - to: { - symbol: 'OSMO', - logo: 'https://api.rango.exchange/i/mJQPS2', - address: null, - blockchain: 'OSMOSIS', - decimals: 6, - blockchainLogo: '', - usdPrice: 0.7192435454440882, - }, - fromAmount: '1.000000', - fromAmountPrecision: null, - fromAmountMinValue: null, - fromAmountMaxValue: null, - fromAmountRestrictionType: 'EXCLUSIVE', - toAmount: '1.540670', - fee: [ - { - asset: { - blockchain: 'OSMOSIS', - symbol: 'OSMO', - address: null, - }, - expenseType: 'FROM_SOURCE_WALLET', - amount: '0', - name: 'Network Fee', - }, - ], - estimatedTimeInSeconds: 45, - swapChainType: 'INTRA_CHAIN', - routes: [ - { - nodes: [ - { - nodes: [ - { - marketName: 'pool#498', - marketId: null, - percent: 1, - }, - ], - from: 'JUNO', - fromLogo: 'https://api.rango.exchange/tokens/COSMOS/JUNO.png', - fromAddress: - 'ibc/46b44899322f3cd854d2d46deef881958467cdd4b3b10086da49296bbed94bed', - fromBlockchain: 'OSMOSIS', - to: 'ATOM', - toLogo: 'https://api.rango.exchange/tokens/COSMOS/ATOM.png', - toAddress: - 'ibc/27394fb092d2eccd56123c74f36e4c1f926001ceada9ca97ea622b25f41e5eb2', - toBlockchain: 'OSMOSIS', - }, - { - nodes: [ - { - marketName: 'pool#8', - marketId: null, - percent: 1, - }, - ], - from: 'ATOM', - fromLogo: 'https://api.rango.exchange/tokens/COSMOS/ATOM.png', - fromAddress: - 'ibc/27394fb092d2eccd56123c74f36e4c1f926001ceada9ca97ea622b25f41e5eb2', - fromBlockchain: 'OSMOSIS', - to: 'IRIS', - toLogo: 'https://api.rango.exchange/tokens/COSMOS/IRIS.png', - toAddress: - 'ibc/7c4d60aa95e5a7558b0a364860979ca34b7ff8aaf255b87af9e879374470cec0', - toBlockchain: 'OSMOSIS', - }, - { - nodes: [ - { - marketName: 'pool#7', - marketId: null, - percent: 1, - }, - ], - from: 'IRIS', - fromLogo: 'https://api.rango.exchange/tokens/COSMOS/IRIS.png', - fromAddress: - 'ibc/7c4d60aa95e5a7558b0a364860979ca34b7ff8aaf255b87af9e879374470cec0', - fromBlockchain: 'OSMOSIS', - to: 'OSMO', - toLogo: 'https://api.rango.exchange/tokens/COSMOS/OSMO.png', - toAddress: null, - toBlockchain: 'OSMOSIS', - }, - ], - }, - ], - recommendedSlippage: null, - timeStat: { - min: 6, - avg: 40, - max: 241, - }, - includesDestinationTx: false, - maxRequiredSign: 1, - warnings: [], - }, - ], - }, - validateBalanceOrFee: true, - steps: [ - { - id: 1, - fromBlockchain: 'OSMOSIS', - fromSymbol: 'JUNO', - fromSymbolAddress: - 'ibc/46b44899322f3cd854d2d46deef881958467cdd4b3b10086da49296bbed94bed', - fromDecimals: 6, - fromAmountPrecision: null, - fromAmountMinValue: null, - fromAmountMaxValue: null, - toBlockchainLogo: 'https://api.rango.exchange/swappers/osmosis.png', - fromBlockchainLogo: 'https://api.rango.exchange/swappers/osmosis.png', - toBlockchain: 'OSMOSIS', - fromLogo: 'https://api.rango.exchange/tokens/COSMOS/JUNO.png', - toSymbol: 'OSMO', - toSymbolAddress: null, - toDecimals: 6, - toLogo: 'https://api.rango.exchange/i/mJQPS2', - startTransactionTime: 1673164519916, - swapperId: 'Osmosis', - swapperType: 'DEX', - swapperLogo: '', - expectedOutputAmountHumanReadable: '1.540670', - outputAmount: '1.540658', - status: 'failed', - networkStatus: null, - executedTransactionId: - '0f8f17eecc863c2d6be65ef52cfe3128ff3cd7baeddf133160bea8ccdfbf876b', - explorerUrl: [ - { - url: 'https://www.mintscan.io/osmosis/txs/0f8f17eecc863c2d6be65ef52cfe3128ff3cd7baeddf133160bea8ccdfbf876b', - description: null, - }, - ], - cosmosTransaction: { - type: TransactionType.COSMOS, - fromWalletAddress: 'osmo1unf2rcytjxfpz8x8ar63h4qeftadptg5t0nqcl', - blockChain: 'OSMOSIS', - data: { - chainId: 'osmosis-1', - account_number: 102721, - sequence: '308', - msgs: [ - { - __type: 'OsmosisSwapMessage', - type: 'osmosis/gamm/swap-exact-amount-in', - value: { - sender: 'osmo1unf2rcytjxfpz8x8ar63h4qeftadptg5t0nqcl', - routes: [ - { - pool_id: '498', - token_out_denom: - 'ibc/27394FB092D2ECCD56123C74F36E4C1F926001CEADA9CA97EA622B25F41E5EB2', - }, - { - pool_id: '8', - token_out_denom: - 'ibc/7C4D60AA95E5A7558B0A364860979CA34B7FF8AAF255B87AF9E879374470CEC0', - }, - { - pool_id: '7', - token_out_denom: 'uosmo', - }, - ], - token_in: { - denom: - 'ibc/46B44899322F3CD854D2D46DEEF881958467CDD4B3B10086DA49296BBED94BED', - amount: '1000000', - }, - token_out_min_amount: '1525264', - }, - }, - ], - protoMsgs: [ - { - type_url: '/osmosis.gamm.v1beta1.MsgSwapExactAmountIn', - value: [ - 10, 43, 111, 115, 109, 111, 49, 117, 110, 102, 50, 114, 99, - 121, 116, 106, 120, 102, 112, 122, 56, 120, 56, 97, 114, 54, - 51, 104, 52, 113, 101, 102, 116, 97, 100, 112, 116, 103, 53, - 116, 48, 110, 113, 99, 108, 18, 73, 8, -14, 3, 18, 68, 105, - 98, 99, 47, 50, 55, 51, 57, 52, 70, 66, 48, 57, 50, 68, 50, - 69, 67, 67, 68, 53, 54, 49, 50, 51, 67, 55, 52, 70, 51, 54, - 69, 52, 67, 49, 70, 57, 50, 54, 48, 48, 49, 67, 69, 65, 68, - 65, 57, 67, 65, 57, 55, 69, 65, 54, 50, 50, 66, 50, 53, 70, - 52, 49, 69, 53, 69, 66, 50, 18, 72, 8, 8, 18, 68, 105, 98, 99, - 47, 55, 67, 52, 68, 54, 48, 65, 65, 57, 53, 69, 53, 65, 55, - 53, 53, 56, 66, 48, 65, 51, 54, 52, 56, 54, 48, 57, 55, 57, - 67, 65, 51, 52, 66, 55, 70, 70, 56, 65, 65, 70, 50, 53, 53, - 66, 56, 55, 65, 70, 57, 69, 56, 55, 57, 51, 55, 52, 52, 55, - 48, 67, 69, 67, 48, 18, 9, 8, 7, 18, 5, 117, 111, 115, 109, - 111, 26, 79, 10, 68, 105, 98, 99, 47, 52, 54, 66, 52, 52, 56, - 57, 57, 51, 50, 50, 70, 51, 67, 68, 56, 53, 52, 68, 50, 68, - 52, 54, 68, 69, 69, 70, 56, 56, 49, 57, 53, 56, 52, 54, 55, - 67, 68, 68, 52, 66, 51, 66, 49, 48, 48, 56, 54, 68, 65, 52, - 57, 50, 57, 54, 66, 66, 69, 68, 57, 52, 66, 69, 68, 18, 7, 49, - 48, 48, 48, 48, 48, 48, 34, 7, 49, 53, 50, 53, 50, 54, 52, - ], - }, - ], - memo: '', - source: null, - fee: { - gas: '900000', - amount: [ - { - denom: 'uosmo', - amount: '0', - }, - ], - }, - signType: 'AMINO', - rpcUrl: 'sample_rpc', - }, - rawTransfer: null, - }, - solanaTransaction: null, - evmTransaction: null, - evmApprovalTransaction: null, - transferTransaction: null, - diagnosisUrl: null, - internalSteps: null, - }, - ], - }, - { - creationTime: '1673164511955', - finishTime: '1673164550137', - requestId: '51e211d9-d61c-45d2-a4d4-1f9f7f90ee85', - inputAmount: '1', - wallets: { - OSMOSIS: { - walletType: 'keplr', - address: 'osmo1unf2rcytjxfpz8x8ar63h4qeftadptg5t0nqcl', - }, - }, - status: 'success', - isPaused: false, - extraMessage: null, - extraMessageSeverity: 'info', - extraMessageDetail: '', - extraMessageErrorCode: null, - networkStatusExtraMessage: null, - networkStatusExtraMessageDetail: null, - lastNotificationTime: null, - settings: { - slippage: '1.0', - disabledSwappersIds: [], - disabledSwappersGroups: [], - }, - simulationResult: { - resultType: RoutingResultType.OK, - outputAmount: '1.540670', - swaps: [ - { - swapperId: 'Osmosis', - swapperType: 'DEX', - swapperLogo: '', - - from: { - symbol: 'JUNO', - logo: 'https://api.rango.exchange/tokens/COSMOS/JUNO.png', - address: - 'ibc/46b44899322f3cd854d2d46deef881958467cdd4b3b10086da49296bbed94bed', - blockchain: 'OSMOSIS', - blockchainLogo: '', - decimals: 6, - usdPrice: 1.1091996179668873, - }, - to: { - symbol: 'OSMO', - logo: 'https://api.rango.exchange/i/mJQPS2', - address: null, - blockchain: 'OSMOSIS', - decimals: 6, - blockchainLogo: '', - usdPrice: 0.7192435454440882, - }, - fromAmount: '1.000000', - fromAmountPrecision: null, - fromAmountMinValue: null, - fromAmountMaxValue: null, - fromAmountRestrictionType: 'EXCLUSIVE', - toAmount: '1.540670', - fee: [ - { - asset: { - blockchain: 'OSMOSIS', - symbol: 'OSMO', - address: null, - }, - expenseType: 'FROM_SOURCE_WALLET', - amount: '0', - name: 'Network Fee', - }, - ], - estimatedTimeInSeconds: 45, - swapChainType: 'INTRA_CHAIN', - routes: [ - { - nodes: [ - { - nodes: [ - { - marketName: 'pool#498', - marketId: null, - percent: 1, - }, - ], - from: 'JUNO', - fromLogo: 'https://api.rango.exchange/tokens/COSMOS/JUNO.png', - fromAddress: - 'ibc/46b44899322f3cd854d2d46deef881958467cdd4b3b10086da49296bbed94bed', - fromBlockchain: 'OSMOSIS', - to: 'ATOM', - toLogo: 'https://api.rango.exchange/tokens/COSMOS/ATOM.png', - toAddress: - 'ibc/27394fb092d2eccd56123c74f36e4c1f926001ceada9ca97ea622b25f41e5eb2', - toBlockchain: 'OSMOSIS', - }, - { - nodes: [ - { - marketName: 'pool#8', - marketId: null, - percent: 1, - }, - ], - from: 'ATOM', - fromLogo: 'https://api.rango.exchange/tokens/COSMOS/ATOM.png', - fromAddress: - 'ibc/27394fb092d2eccd56123c74f36e4c1f926001ceada9ca97ea622b25f41e5eb2', - fromBlockchain: 'OSMOSIS', - to: 'IRIS', - toLogo: 'https://api.rango.exchange/tokens/COSMOS/IRIS.png', - toAddress: - 'ibc/7c4d60aa95e5a7558b0a364860979ca34b7ff8aaf255b87af9e879374470cec0', - toBlockchain: 'OSMOSIS', - }, - { - nodes: [ - { - marketName: 'pool#7', - marketId: null, - percent: 1, - }, - ], - from: 'IRIS', - fromLogo: 'https://api.rango.exchange/tokens/COSMOS/IRIS.png', - fromAddress: - 'ibc/7c4d60aa95e5a7558b0a364860979ca34b7ff8aaf255b87af9e879374470cec0', - fromBlockchain: 'OSMOSIS', - to: 'OSMO', - toLogo: 'https://api.rango.exchange/tokens/COSMOS/OSMO.png', - toAddress: null, - toBlockchain: 'OSMOSIS', - }, - ], - }, - ], - recommendedSlippage: null, - timeStat: { - min: 6, - avg: 40, - max: 241, - }, - includesDestinationTx: false, - maxRequiredSign: 1, - warnings: [], - }, - ], - }, - validateBalanceOrFee: true, - steps: [ - { - id: 1, - fromBlockchain: 'OSMOSIS', - fromSymbol: 'JUNO', - fromSymbolAddress: - 'ibc/46b44899322f3cd854d2d46deef881958467cdd4b3b10086da49296bbed94bed', - fromDecimals: 6, - fromAmountPrecision: null, - fromAmountMinValue: null, - fromAmountMaxValue: null, - toBlockchainLogo: 'https://api.rango.exchange/swappers/osmosis.png', - fromBlockchainLogo: 'https://api.rango.exchange/swappers/osmosis.png', - toBlockchain: 'OSMOSIS', - fromLogo: 'https://api.rango.exchange/tokens/COSMOS/JUNO.png', - toSymbol: 'OSMO', - toSymbolAddress: null, - toDecimals: 6, - toLogo: 'https://api.rango.exchange/i/mJQPS2', - startTransactionTime: 1673164519916, - swapperId: 'Osmosis', - swapperType: 'DEX', - swapperLogo: '', - expectedOutputAmountHumanReadable: '1.540670', - outputAmount: '1.540658', - status: 'success', - networkStatus: null, - executedTransactionId: - '0f8f17eecc863c2d6be65ef52cfe3128ff3cd7baeddf133160bea8ccdfbf876b', - explorerUrl: [ - { - url: 'https://www.mintscan.io/osmosis/txs/0f8f17eecc863c2d6be65ef52cfe3128ff3cd7baeddf133160bea8ccdfbf876b', - description: null, - }, - ], - cosmosTransaction: { - type: TransactionType.COSMOS, - fromWalletAddress: 'osmo1unf2rcytjxfpz8x8ar63h4qeftadptg5t0nqcl', - blockChain: 'OSMOSIS', - data: { - chainId: 'osmosis-1', - account_number: 102721, - sequence: '308', - msgs: [ - { - __type: 'OsmosisSwapMessage', - type: 'osmosis/gamm/swap-exact-amount-in', - value: { - sender: 'osmo1unf2rcytjxfpz8x8ar63h4qeftadptg5t0nqcl', - routes: [ - { - pool_id: '498', - token_out_denom: - 'ibc/27394FB092D2ECCD56123C74F36E4C1F926001CEADA9CA97EA622B25F41E5EB2', - }, - { - pool_id: '8', - token_out_denom: - 'ibc/7C4D60AA95E5A7558B0A364860979CA34B7FF8AAF255B87AF9E879374470CEC0', - }, - { - pool_id: '7', - token_out_denom: 'uosmo', - }, - ], - token_in: { - denom: - 'ibc/46B44899322F3CD854D2D46DEEF881958467CDD4B3B10086DA49296BBED94BED', - amount: '1000000', - }, - token_out_min_amount: '1525264', - }, - }, - ], - protoMsgs: [ - { - type_url: '/osmosis.gamm.v1beta1.MsgSwapExactAmountIn', - value: [ - 10, 43, 111, 115, 109, 111, 49, 117, 110, 102, 50, 114, 99, - 121, 116, 106, 120, 102, 112, 122, 56, 120, 56, 97, 114, 54, - 51, 104, 52, 113, 101, 102, 116, 97, 100, 112, 116, 103, 53, - 116, 48, 110, 113, 99, 108, 18, 73, 8, -14, 3, 18, 68, 105, - 98, 99, 47, 50, 55, 51, 57, 52, 70, 66, 48, 57, 50, 68, 50, - 69, 67, 67, 68, 53, 54, 49, 50, 51, 67, 55, 52, 70, 51, 54, - 69, 52, 67, 49, 70, 57, 50, 54, 48, 48, 49, 67, 69, 65, 68, - 65, 57, 67, 65, 57, 55, 69, 65, 54, 50, 50, 66, 50, 53, 70, - 52, 49, 69, 53, 69, 66, 50, 18, 72, 8, 8, 18, 68, 105, 98, 99, - 47, 55, 67, 52, 68, 54, 48, 65, 65, 57, 53, 69, 53, 65, 55, - 53, 53, 56, 66, 48, 65, 51, 54, 52, 56, 54, 48, 57, 55, 57, - 67, 65, 51, 52, 66, 55, 70, 70, 56, 65, 65, 70, 50, 53, 53, - 66, 56, 55, 65, 70, 57, 69, 56, 55, 57, 51, 55, 52, 52, 55, - 48, 67, 69, 67, 48, 18, 9, 8, 7, 18, 5, 117, 111, 115, 109, - 111, 26, 79, 10, 68, 105, 98, 99, 47, 52, 54, 66, 52, 52, 56, - 57, 57, 51, 50, 50, 70, 51, 67, 68, 56, 53, 52, 68, 50, 68, - 52, 54, 68, 69, 69, 70, 56, 56, 49, 57, 53, 56, 52, 54, 55, - 67, 68, 68, 52, 66, 51, 66, 49, 48, 48, 56, 54, 68, 65, 52, - 57, 50, 57, 54, 66, 66, 69, 68, 57, 52, 66, 69, 68, 18, 7, 49, - 48, 48, 48, 48, 48, 48, 34, 7, 49, 53, 50, 53, 50, 54, 52, - ], - }, - ], - memo: '', - source: null, - fee: { - gas: '900000', - amount: [ - { - denom: 'uosmo', - amount: '0', - }, - ], - }, - signType: 'AMINO', - rpcUrl: 'sample_rpc', - }, - rawTransfer: null, - }, - solanaTransaction: null, - evmTransaction: null, - evmApprovalTransaction: null, - transferTransaction: null, - diagnosisUrl: null, - internalSteps: null, - }, - ], - }, -]; diff --git a/widget/ui/src/containers/History/types.tsx b/widget/ui/src/containers/History/types.tsx deleted file mode 100644 index 04d081210c..0000000000 --- a/widget/ui/src/containers/History/types.tsx +++ /dev/null @@ -1,47 +0,0 @@ -import { - CosmosTransaction, - EvmTransaction, - SolanaTransaction, - SwapExplorerUrl, - SwapperStatusStep, - Transfer, -} from 'rango-sdk'; -import { PendingSwapNetworkStatus, StepStatus } from '../../types/swaps'; -export { PendingSwap } from '@rango-dev/queue-manager-rango-preset'; - -export type PendingSwapStep = { - id: number; - fromBlockchain: string; - fromSymbol: string; - fromSymbolAddress: string | null; - fromDecimals: number; - fromAmountPrecision: string | null; - fromAmountMinValue: string | null; - fromAmountMaxValue: string | null; - fromLogo: string; - fromBlockchainLogo: string; - toBlockchainLogo: string; - toBlockchain: string; - toSymbol: string; - toSymbolAddress: string | null; - toDecimals: number; - toLogo: string; - swapperId: string; - swapperLogo: string; - swapperType: string; - feeInUsd: string; - expectedOutputAmountHumanReadable: string | null; - startTransactionTime: number; - outputAmount: string; - status: StepStatus; - networkStatus: PendingSwapNetworkStatus | null; - executedTransactionId: string | null; - explorerUrl: SwapExplorerUrl[] | null; - evmApprovalTransaction: EvmTransaction | null; - evmTransaction: EvmTransaction | null; - cosmosTransaction: CosmosTransaction | null; - transferTransaction: Transfer | null; - solanaTransaction: SolanaTransaction | null; - diagnosisUrl: string | null; - internalSteps: SwapperStatusStep[] | null; -}; diff --git a/widget/ui/src/containers/Notifications/NotificationNotFound.tsx b/widget/ui/src/containers/Notifications/NotificationNotFound.tsx new file mode 100644 index 0000000000..df7086b0d6 --- /dev/null +++ b/widget/ui/src/containers/Notifications/NotificationNotFound.tsx @@ -0,0 +1,19 @@ +import { i18n } from '@lingui/core'; +import React from 'react'; + +import { Divider, Typography } from '../../components/index.js'; +import { NoNotificationIcon } from '../../icons/index.js'; + +import { NotFoundContainer } from './Notifications.styles.js'; + +export function NotificationNotFound() { + return ( + + + + + {i18n.t('There are no notifications.')} + + + ); +} diff --git a/widget/ui/src/containers/Notifications/Notifications.styles.ts b/widget/ui/src/containers/Notifications/Notifications.styles.ts new file mode 100644 index 0000000000..81ddbe4942 --- /dev/null +++ b/widget/ui/src/containers/Notifications/Notifications.styles.ts @@ -0,0 +1,82 @@ +import { Button, ListItemButton } from '../../components/index.js'; +import { darkTheme, styled } from '../../theme.js'; + +export const Container = styled('div', { + borderRadius: '$sm', + padding: '0 $10 $10 $10', + width: '350px', + maxWidth: '90vw', + minHeight: '150px', + maxHeight: '207px', + overflowY: 'auto', + background: 'inherit', + variants: { + equalPadding: { + true: { + padding: '$10', + }, + }, + }, +}); + +export const Header = styled('div', { + padding: '$10 $10 0 $10', + display: 'flex', + justifyContent: 'space-between', + alignItems: 'center', + background: 'inherit', + position: 'sticky', + top: '0', + zIndex: 999, +}); + +export const ClearAllButton = styled(Button, { + padding: '$5 !important', +}); + +export const List = styled('ul', { + padding: 0, + margin: 0, + listStyle: 'none', + + '.to-chain-token': { + transform: 'translateX(-3px)', + }, +}); + +export const ListItem = styled(ListItemButton, { + variants: { + actionRequired: { + true: { + backgroundColor: '$error300', + [`.${darkTheme} &`]: { + backgroundColor: '$error600', + }, + }, + }, + }, +}); + +export const Images = styled('div', { + display: 'flex', + padding: '0 0 0 $5', + alignItems: 'center', + alignSelf: 'stretch', +}); + +export const NotFoundContainer = styled('div', { + display: 'flex', + justifyContent: 'center', + alignItems: 'center', + flexDirection: 'column', + padding: '$10', + width: '100%', + height: '150px', +}); + +export const IconContainer = styled('span', { + display: 'flex', + justifyContent: 'center', + alignItems: 'center', + paddingRight: '$8', +}); diff --git a/widget/ui/src/containers/Notifications/Notifications.tsx b/widget/ui/src/containers/Notifications/Notifications.tsx new file mode 100644 index 0000000000..e5453f3bcb --- /dev/null +++ b/widget/ui/src/containers/Notifications/Notifications.tsx @@ -0,0 +1,108 @@ +import type { PropTypes } from './Notifications.types.js'; + +import { i18n } from '@lingui/core'; +import React from 'react'; + +import { ChainToken, Divider, Typography } from '../../components/index.js'; +import { ChevronRightIcon } from '../../icons/index.js'; + +import { NotificationNotFound } from './NotificationNotFound.js'; +import { + ClearAllButton, + Container, + Header, + IconContainer, + Images, + List, + ListItem, +} from './Notifications.styles.js'; + +export function Notifications(props: PropTypes) { + const { + list, + getBlockchainImage, + getTokenImage, + onClickItem, + onClearAll, + containerStyles, + } = props; + return ( + + {list.length > 0 && ( + <> +
+ + {i18n.t('Notifications')} + + + + {i18n.t('Clear all')} + + +
+ + + )} + {list.length ? ( + + {list.map((notificationItem, index) => { + const { route, requestId, event } = notificationItem; + const fromTokenImage = getTokenImage(route.from); + + const fromBlockchainImage = getBlockchainImage( + route.from.blockchain + ); + + const toTokenImage = getTokenImage(route.to); + + const toBlockchainImage = getBlockchainImage(route.to.blockchain); + + return ( + + {index > 0 && } + onClickItem(requestId)} + actionRequired={event.messageSeverity === 'warning'} + title={ + + {i18n.t(event.message)} + + } + id={requestId} + start={ + + + + + } + end={ + + + + } + /> + + ); + })} + + ) : ( + + )} +
+ ); +} diff --git a/widget/ui/src/containers/Notifications/Notifications.types.ts b/widget/ui/src/containers/Notifications/Notifications.types.ts new file mode 100644 index 0000000000..623bfdcd61 --- /dev/null +++ b/widget/ui/src/containers/Notifications/Notifications.types.ts @@ -0,0 +1,17 @@ +import type { CSS } from '../../theme.js'; +import type { Asset } from 'rango-types'; + +type Notification = { + route: { from: Asset; to: Asset }; + event: { messageSeverity: string; message: string }; + requestId: string; +}; + +export type PropTypes = { + list: Notification[]; + getBlockchainImage: (blockchain: string) => string; + getTokenImage: (token: Asset) => string; + onClickItem: (requestId: string) => void; + onClearAll: () => void; + containerStyles?: CSS; +}; diff --git a/widget/ui/src/containers/Notifications/index.ts b/widget/ui/src/containers/Notifications/index.ts new file mode 100644 index 0000000000..aeaf237025 --- /dev/null +++ b/widget/ui/src/containers/Notifications/index.ts @@ -0,0 +1 @@ +export * from './Notifications.js'; diff --git a/widget/ui/src/containers/SwapHistory/SwapHistory.stories.tsx b/widget/ui/src/containers/SwapHistory/SwapHistory.stories.tsx deleted file mode 100644 index a3b6c7a5e8..0000000000 --- a/widget/ui/src/containers/SwapHistory/SwapHistory.stories.tsx +++ /dev/null @@ -1,13 +0,0 @@ -import React from 'react'; -import { ComponentMeta } from '@storybook/react'; -import { PropTypes, SwapHistory } from './SwapHistory'; -import { pendingSwap } from './mock'; - -export default { - title: 'Swap History', - component: SwapHistory, -} as ComponentMeta; - -export const Main = (args: PropTypes) => ( - -); diff --git a/widget/ui/src/containers/SwapHistory/SwapHistory.tsx b/widget/ui/src/containers/SwapHistory/SwapHistory.tsx deleted file mode 100644 index 68db6b29d5..0000000000 --- a/widget/ui/src/containers/SwapHistory/SwapHistory.tsx +++ /dev/null @@ -1,428 +0,0 @@ -import React, { useState } from 'react'; -import { - StepDetail, - SecondaryPage, - GasIcon, - Typography, - CheckCircleIcon, - InfoCircleIcon, - Spacer, - Button, - Alert, - Drawer, - Spinner, - Divider, - Image, -} from '../../components'; -import { styled } from '../../theme'; -import { PendingSwap } from '../History/types'; -import { pulse } from '../../components/BestRoute/BestRoute'; -import { - SwapMessages, - PropTypes as SwapMessagesPropTypes, -} from './SwapMessages'; - -export const SwapperContainer = styled('div', { - display: 'flex', - alignItems: 'center', - paddingLeft: '$4', - variants: { - created: { - true: { - filter: 'grayscale(100%)', - }, - }, - running: { - true: { - animation: `${pulse} 2s ease-in-out infinite`, - }, - }, - }, -}); - -export const BodyError = styled('div', { - height: '100%', - display: 'flex', - justifyContent: 'center', - alignItems: 'center', -}); - -export const ErrorMsg = styled(Typography, { - color: '$error', -}); - -export const FeeContainer = styled('div', { - paddingLeft: '$16', - color: '$neutrals800' -}); - -export const Fee = styled('div', { - display: 'flex', - alignItems: 'center', -}); - -export const RelativeContainer = styled('div', { - position: 'relative', -}); - -export const Footer = styled('div', { - display: 'flex', - alignItems: 'center', -}); - -export const Dot = styled('div', { - width: '$8', - height: '$8', - backgroundColor: '$foreground', - borderRadius: '4px', - marginLeft: '11px', -}); - -export const ArrowDown = styled('div', { - width: '0px', - height: '0px', - borderLeft: '5px solid transparent', - borderRight: '5px solid transparent', - borderTop: '5px solid $foreground', - marginLeft: '$10', -}); - -const StyledAnchor = styled('a', { - color: '$primary', - fontWeight: '$600', -}); - -const SwapInfoContainer = styled('div', { - display: 'flex', - flexDirection: 'column', - paddingBottom: '$16', - borderBottom: '1px solid $neutrals300', -}); - -const InternalDetailsContainer = styled('div', { - display: 'flex', - '.details': { - padding: '$8 0', - }, -}); - -const InternalDetail = styled('div', { - display: 'flex', - margin: '$12 0 $12 $20', -}); - -const DescriptionContainer = styled('div', { - display: 'flex', - alignItems: 'center', -}); - -const Description = styled(Typography, { - color: '$success', - paddingLeft: '$4', -}); - -export const Line = styled('div', { - width: '0', - minHeight: '$16', - marginLeft: '14px', - border: '1px dashed $foreground', - borderRadius: 'inherit', -}); - -const Row = styled('div', { - display: 'flex', - justifyContent: 'space-between', - alignItems: 'center', - fontSize: '$14', - padding: '$8 0', - - '.name': { - color: '$neutrals600', - }, - '.value': { - display: 'flex', - alignItems: 'center', - color: '$neutrals800', - justifyContent: 'flex-end', - }, - '.status': { - fontWeight: 'bold', - textTransform: 'uppercase', - }, - '.status.failed': { - color: '$error', - }, - '.status.success': { - color: '$success', - }, -}); - -const RequestId = styled('div', { - width: '150px', - whiteSpace: 'nowrap', - overflow: 'hidden', - textOverflow: 'ellipsis', - '@md': { - width: 'auto', - }, -}); - -const ExtraDetails = styled('div', { - padding: '0', - color: '$neutrals600', - fontSize: '$10', -}); - -const SwapFlowContainer = styled('div', { - overflowY: 'auto', - padding: '$8 $4 $2 $4', -}); - -export type PropTypes = { - pendingSwap: PendingSwap; - onCopy: (requestId: string) => void; - onBack: () => void; - isCopied: boolean; - onCancel: (requestId: string) => void; - onRetry?: () => void; - date: string; - previewInputs?: React.ReactNode; -} & SwapMessagesPropTypes; - -export function SwapHistory(props: PropTypes) { - const { - pendingSwap, - onBack, - onCopy, - isCopied, - onCancel, - date, - onRetry, - previewInputs, - ...extraMessageProps - } = props; - const [showDrawer, setShowDrawer] = useState(false); - - return ( - - {pendingSwap?.status === 'running' && ( - - )} - {!!onRetry && ( - - )} - - } - > -
- - -
- Request Id: - - {pendingSwap?.requestId} - - - -
-
- - {pendingSwap?.status} - {pendingSwap?.status === 'running' && ( - - )} - - {date} -
-
-
- {/* TODO: It was temporarily removed to find a better solution. - - */} -
- - {/*{previewInputs} */} - - {extraMessageProps.shortMessage && ( - - )} - - - - {pendingSwap?.steps.map((step, index) => ( -
- {index === 0 && ( - - - - - )} - - - {step.swapperId} - - - - {step.swapperType === 'DEX' ? 'Swap' : 'Bridge'} via{' '} - {step.swapperId} - - - - -   ${step.feeInUsd} estimated gas fee - - - - -
- - -
- {!!step.explorerUrl && ( -
- {step.explorerUrl.map((item, index) => ( - - - - - - - {!item.description ? ( - View transaction - ) : ( - - {item.description - .substring(0, 1) - .toUpperCase()} - {item.description.substring(1)} Tx - - )} - - - - - ))} -
- )} - {step.status === 'failed' && ( - - - - - Step failed - - - - )} -
-
-
- {index + 1 === pendingSwap.steps.length && } - -
- ))} - - -
- - - Warning: Cancel doesn't revert your transaction if you've - already signed and sent a transaction to the blockchain. It only - stops next steps from being executed. - - - } - footer={ -
- - - -
- } - container={document.getElementById('swap-box')!} - /> -
- ); -} diff --git a/widget/ui/src/containers/SwapHistory/SwapMessages.tsx b/widget/ui/src/containers/SwapHistory/SwapMessages.tsx deleted file mode 100644 index 284157a496..0000000000 --- a/widget/ui/src/containers/SwapHistory/SwapMessages.tsx +++ /dev/null @@ -1,116 +0,0 @@ -import React, { useState } from 'react'; -import { Alert, Button, Typography } from '../../components'; -import { styled } from '../../theme'; - -const getAlertType = (messageType: PropTypes['type']) => { - if (!messageType || messageType === 'info') return 'secondary'; - else return messageType; -}; - -const DetailedMessage = styled('div', { - width: '90%', - overflowWrap: 'break-word', - color: '$error500 !important', -}); - -export type PropTypes = { - currentStepBlockchain: string; - switchNetwork?: () => Promise; - shortMessage: string; - detailedMessage: { content: string; long: boolean }; - type?: 'success' | 'error' | 'warning' | 'info'; - lastConvertedTokenInFailedSwap?: { - symbol: string; - blockchain: string; - outputAmount: string; - }; -}; - -const SuccessText = styled(Typography, { - color: '$success500 !important', -}); - -export const SwapMessages: React.FC = (props) => { - const { - shortMessage, - detailedMessage, - currentStepBlockchain, - type, - lastConvertedTokenInFailedSwap, - } = props; - - const [expandedMessage, setExpandedMessage] = useState(false); - - const allowedNumberOfChars = detailedMessage.long ? 0 : 150; - - const shouldShowMoreDetailsButton = - !expandedMessage && detailedMessage.content.length > allowedNumberOfChars; - - return ( - !prevState)} - > - Show more details - - ), - })} - {...(!!props.switchNetwork && { - footer: ( - - ), - })} - > - {!!detailedMessage.content ? ( - - - {shouldShowMoreDetailsButton && !expandedMessage - ? detailedMessage.content.substring(0, allowedNumberOfChars) + - (allowedNumberOfChars > 0 ? '...' : '') - : detailedMessage.content} - - - ) : null} - {!!lastConvertedTokenInFailedSwap && ( - <> -

- - Don't worry, your fund is  - - - Safe - -

- -

- - It is converted to   - {lastConvertedTokenInFailedSwap.outputAmount} -   - - - {lastConvertedTokenInFailedSwap.symbol}  - - on your  - - {lastConvertedTokenInFailedSwap.blockchain}  - - wallet -

- - )} -
- ); -}; diff --git a/widget/ui/src/containers/SwapHistory/index.ts b/widget/ui/src/containers/SwapHistory/index.ts deleted file mode 100644 index cc48f8511a..0000000000 --- a/widget/ui/src/containers/SwapHistory/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { SwapHistory } from './SwapHistory'; diff --git a/widget/ui/src/containers/SwapHistory/mock.ts b/widget/ui/src/containers/SwapHistory/mock.ts deleted file mode 100644 index b8292ff463..0000000000 --- a/widget/ui/src/containers/SwapHistory/mock.ts +++ /dev/null @@ -1,276 +0,0 @@ -// @ts-nocheck -import { RoutingResultType, TransactionType } from 'rango-sdk'; -import { PendingSwap } from '../History/types'; - -export const pendingSwap: PendingSwap = { - creationTime: '1673164511955', - finishTime: '1673164550137', - requestId: '51e211d9-d61c-45d2-a4d4-1f9f7f90ee85', - inputAmount: '1', - wallets: { - OSMOSIS: { - walletType: 'keplr', - address: 'osmo1unf2rcytjxfpz8x8ar63h4qeftadptg5t0nqcl', - }, - }, - status: 'running', - isPaused: false, - extraMessage: null, - extraMessageSeverity: 'info', - extraMessageDetail: '', - extraMessageErrorCode: null, - networkStatusExtraMessage: null, - networkStatusExtraMessageDetail: null, - lastNotificationTime: null, - settings: { - slippage: '1.0', - disabledSwappersIds: [], - disabledSwappersGroups: [], - }, - simulationResult: { - resultType: RoutingResultType.OK, - outputAmount: '1.540670', - swaps: [ - { - swapperId: 'Osmosis', - swapperType: 'DEX', - swapperLogo: '', - from: { - symbol: 'JUNO', - logo: 'https://api.rango.exchange/tokens/COSMOS/JUNO.png', - address: - 'ibc/46b44899322f3cd854d2d46deef881958467cdd4b3b10086da49296bbed94bed', - blockchain: 'OSMOSIS', - blockchainLogo: '', - decimals: 6, - usdPrice: 1.1091996179668873, - }, - to: { - symbol: 'OSMO', - logo: 'https://api.rango.exchange/i/mJQPS2', - address: null, - blockchain: 'OSMOSIS', - decimals: 6, - blockchainLogo: '', - usdPrice: 0.7192435454440882, - }, - fromAmount: '1.000000', - fromAmountPrecision: null, - fromAmountMinValue: null, - fromAmountMaxValue: null, - fromAmountRestrictionType: 'EXCLUSIVE', - toAmount: '1.540670', - fee: [ - { - asset: { - blockchain: 'OSMOSIS', - symbol: 'OSMO', - address: null, - }, - expenseType: 'FROM_SOURCE_WALLET', - amount: '0', - name: 'Network Fee', - }, - ], - estimatedTimeInSeconds: 45, - swapChainType: 'INTRA_CHAIN', - routes: [ - { - nodes: [ - { - nodes: [ - { - marketName: 'pool#498', - marketId: null, - percent: 1, - }, - ], - from: 'JUNO', - fromLogo: 'https://api.rango.exchange/tokens/COSMOS/JUNO.png', - fromAddress: - 'ibc/46b44899322f3cd854d2d46deef881958467cdd4b3b10086da49296bbed94bed', - fromBlockchain: 'OSMOSIS', - to: 'ATOM', - toLogo: 'https://api.rango.exchange/tokens/COSMOS/ATOM.png', - toAddress: - 'ibc/27394fb092d2eccd56123c74f36e4c1f926001ceada9ca97ea622b25f41e5eb2', - toBlockchain: 'OSMOSIS', - }, - { - nodes: [ - { - marketName: 'pool#8', - marketId: null, - percent: 1, - }, - ], - from: 'ATOM', - fromLogo: 'https://api.rango.exchange/tokens/COSMOS/ATOM.png', - fromAddress: - 'ibc/27394fb092d2eccd56123c74f36e4c1f926001ceada9ca97ea622b25f41e5eb2', - fromBlockchain: 'OSMOSIS', - to: 'IRIS', - toLogo: 'https://api.rango.exchange/tokens/COSMOS/IRIS.png', - toAddress: - 'ibc/7c4d60aa95e5a7558b0a364860979ca34b7ff8aaf255b87af9e879374470cec0', - toBlockchain: 'OSMOSIS', - }, - { - nodes: [ - { - marketName: 'pool#7', - marketId: null, - percent: 1, - }, - ], - from: 'IRIS', - fromLogo: 'https://api.rango.exchange/tokens/COSMOS/IRIS.png', - fromAddress: - 'ibc/7c4d60aa95e5a7558b0a364860979ca34b7ff8aaf255b87af9e879374470cec0', - fromBlockchain: 'OSMOSIS', - to: 'OSMO', - toLogo: 'https://api.rango.exchange/tokens/COSMOS/OSMO.png', - toAddress: null, - toBlockchain: 'OSMOSIS', - }, - ], - }, - ], - recommendedSlippage: null, - timeStat: { - min: 6, - avg: 40, - max: 241, - }, - includesDestinationTx: false, - maxRequiredSign: 1, - warnings: [], - }, - ], - }, - validateBalanceOrFee: true, - steps: [ - { - id: 1, - fromBlockchain: 'OSMOSIS', - fromSymbol: 'JUNO', - fromSymbolAddress: - 'ibc/46b44899322f3cd854d2d46deef881958467cdd4b3b10086da49296bbed94bed', - fromDecimals: 6, - fromAmountPrecision: null, - fromAmountMinValue: null, - fromAmountMaxValue: null, - toBlockchainLogo: 'https://api.rango.exchange/swappers/osmosis.png', - fromBlockchainLogo: 'https://api.rango.exchange/swappers/osmosis.png', - toBlockchain: 'OSMOSIS', - fromLogo: 'https://api.rango.exchange/tokens/COSMOS/JUNO.png', - toSymbol: 'OSMO', - toSymbolAddress: null, - swapperType: 'DEX', - toDecimals: 6, - toLogo: 'https://api.rango.exchange/i/mJQPS2', - startTransactionTime: 1673164519916, - swapperId: 'Osmosis', - swapperLogo: '', - expectedOutputAmountHumanReadable: '1.540670', - outputAmount: '1.540658', - status: 'running', - networkStatus: null, - executedTransactionId: - '0f8f17eecc863c2d6be65ef52cfe3128ff3cd7baeddf133160bea8ccdfbf876b', - explorerUrl: [ - { - url: 'https://www.mintscan.io/osmosis/txs/0f8f17eecc863c2d6be65ef52cfe3128ff3cd7baeddf133160bea8ccdfbf876b', - description: null, - }, - ], - cosmosTransaction: { - type: TransactionType.COSMOS, - fromWalletAddress: 'osmo1unf2rcytjxfpz8x8ar63h4qeftadptg5t0nqcl', - blockChain: 'OSMOSIS', - data: { - chainId: 'osmosis-1', - account_number: 102721, - sequence: '308', - msgs: [ - { - __type: 'OsmosisSwapMessage', - type: 'osmosis/gamm/swap-exact-amount-in', - value: { - sender: 'osmo1unf2rcytjxfpz8x8ar63h4qeftadptg5t0nqcl', - routes: [ - { - pool_id: '498', - token_out_denom: - 'ibc/27394FB092D2ECCD56123C74F36E4C1F926001CEADA9CA97EA622B25F41E5EB2', - }, - { - pool_id: '8', - token_out_denom: - 'ibc/7C4D60AA95E5A7558B0A364860979CA34B7FF8AAF255B87AF9E879374470CEC0', - }, - { - pool_id: '7', - token_out_denom: 'uosmo', - }, - ], - token_in: { - denom: - 'ibc/46B44899322F3CD854D2D46DEEF881958467CDD4B3B10086DA49296BBED94BED', - amount: '1000000', - }, - token_out_min_amount: '1525264', - }, - }, - ], - protoMsgs: [ - { - type_url: '/osmosis.gamm.v1beta1.MsgSwapExactAmountIn', - value: [ - 10, 43, 111, 115, 109, 111, 49, 117, 110, 102, 50, 114, 99, 121, - 116, 106, 120, 102, 112, 122, 56, 120, 56, 97, 114, 54, 51, 104, - 52, 113, 101, 102, 116, 97, 100, 112, 116, 103, 53, 116, 48, - 110, 113, 99, 108, 18, 73, 8, -14, 3, 18, 68, 105, 98, 99, 47, - 50, 55, 51, 57, 52, 70, 66, 48, 57, 50, 68, 50, 69, 67, 67, 68, - 53, 54, 49, 50, 51, 67, 55, 52, 70, 51, 54, 69, 52, 67, 49, 70, - 57, 50, 54, 48, 48, 49, 67, 69, 65, 68, 65, 57, 67, 65, 57, 55, - 69, 65, 54, 50, 50, 66, 50, 53, 70, 52, 49, 69, 53, 69, 66, 50, - 18, 72, 8, 8, 18, 68, 105, 98, 99, 47, 55, 67, 52, 68, 54, 48, - 65, 65, 57, 53, 69, 53, 65, 55, 53, 53, 56, 66, 48, 65, 51, 54, - 52, 56, 54, 48, 57, 55, 57, 67, 65, 51, 52, 66, 55, 70, 70, 56, - 65, 65, 70, 50, 53, 53, 66, 56, 55, 65, 70, 57, 69, 56, 55, 57, - 51, 55, 52, 52, 55, 48, 67, 69, 67, 48, 18, 9, 8, 7, 18, 5, 117, - 111, 115, 109, 111, 26, 79, 10, 68, 105, 98, 99, 47, 52, 54, 66, - 52, 52, 56, 57, 57, 51, 50, 50, 70, 51, 67, 68, 56, 53, 52, 68, - 50, 68, 52, 54, 68, 69, 69, 70, 56, 56, 49, 57, 53, 56, 52, 54, - 55, 67, 68, 68, 52, 66, 51, 66, 49, 48, 48, 56, 54, 68, 65, 52, - 57, 50, 57, 54, 66, 66, 69, 68, 57, 52, 66, 69, 68, 18, 7, 49, - 48, 48, 48, 48, 48, 48, 34, 7, 49, 53, 50, 53, 50, 54, 52, - ], - }, - ], - memo: '', - source: null, - fee: { - gas: '900000', - amount: [ - { - denom: 'uosmo', - amount: '0', - }, - ], - }, - signType: 'AMINO', - rpcUrl: 'sample_rpc', - }, - rawTransfer: null, - }, - solanaTransaction: null, - evmTransaction: null, - evmApprovalTransaction: null, - transferTransaction: null, - diagnosisUrl: null, - internalSteps: null, - }, - ], -}; diff --git a/widget/ui/src/containers/SwapInput/SwapInput.styles.ts b/widget/ui/src/containers/SwapInput/SwapInput.styles.ts new file mode 100644 index 0000000000..2df7e50dcd --- /dev/null +++ b/widget/ui/src/containers/SwapInput/SwapInput.styles.ts @@ -0,0 +1,121 @@ +import { Button, TextField, Typography } from '../../components/index.js'; +import { css, darkTheme, styled } from '../../theme.js'; + +export const textStyles = css(); + +export const Container = styled('div', { + $$color: '$colors$neutral100', + [`.${darkTheme} &`]: { + $$color: '$colors$neutral300', + }, + backgroundColor: '$$color', + borderRadius: '$xm', + padding: '$15', + variants: { + sharpBottomStyle: { + true: { + borderBottomLeftRadius: '$0', + borderBottomRightRadius: '$0', + }, + }, + }, + [`& .${textStyles}`]: { + $$color: '$colors$neutral600', + [`.${darkTheme} &`]: { + $$color: '$colors$neutral700', + }, + color: '$$color', + }, +}); + +export const InputAmount = styled(TextField, { + width: '100%', + padding: '0', + fontSize: '$18', + lineHeight: '$26', + fontWeight: '$medium', + textAlign: 'right', + '&:disabled': { + cursor: 'unset', + }, +}); +export const MaxButton = styled(Button, { + $$color: '$colors$secondary200', + [`.${darkTheme} &`]: { + $$color: '$colors$secondary800', + }, + backgroundColor: '$$color', + '& ._typography': { + color: '$colors$secondary500', + [`.${darkTheme} &`]: { + color: '$colors$secondary250', + }, + }, +}); + +export const ValueTypography = styled('div', { + display: 'flex', + width: '100%', + textAlign: 'right', + whiteSpace: 'nowrap', + overflow: 'hidden', + textOverflow: 'ellipsis', + variants: { + hasWarning: { + true: { + '& ._typography': { + color: '$warning500', + }, + }, + false: { + '& ._typography': { + $$color: '$colors$neutral600', + [`.${darkTheme} &`]: { + $$color: '$colors$neutral700', + }, + color: '$$color', + }, + }, + }, + }, +}); + +export const formStyles = css({ + display: 'flex', + justifyContent: 'space-between', + alignItems: 'center', +}); + +export const labelStyles = css({ + display: 'flex', + justifyContent: 'space-between', + alignItems: 'center', +}); + +export const balanceStyles = css({ + display: 'flex', + justifyContent: 'center', + alignItems: 'center', +}); + +export const amountStyles = css({ + width: '45%', + maxWidth: '170px', + display: 'flex', + flexDirection: 'column', + justifyContent: 'center', + alignItems: 'end', + flexGrow: 1, +}); + +export const labelContainerStyles = css({ + paddingBottom: '$5', +}); + +export const UsdPrice = styled(Typography, { + width: '100%', + textAlign: 'right', + whiteSpace: 'nowrap', + overflow: 'hidden', + textOverflow: 'ellipsis', +}); diff --git a/widget/ui/src/containers/SwapInput/SwapInput.tsx b/widget/ui/src/containers/SwapInput/SwapInput.tsx new file mode 100644 index 0000000000..5b17669e6a --- /dev/null +++ b/widget/ui/src/containers/SwapInput/SwapInput.tsx @@ -0,0 +1,166 @@ +import type { SwapInputPropTypes } from './SwapInput.types.js'; + +import { i18n } from '@lingui/core'; +import React from 'react'; + +import { + Divider, + NumericTooltip, + PriceImpact, + Skeleton, + Typography, +} from '../../components/index.js'; +import { UI_ID } from '../../constants/index.js'; + +import { + amountStyles, + balanceStyles, + Container, + formStyles, + InputAmount, + labelContainerStyles, + labelStyles, + MaxButton, + textStyles, + UsdPrice, + ValueTypography, +} from './SwapInput.styles.js'; +import { TokenSection } from './TokenSection.js'; + +export function SwapInput(props: SwapInputPropTypes) { + const showBalance = + 'balance' in props && + !props.loading && + !props.loadingBalance && + props.token.displayName && + props.anyWalletConnected; + + const showBalanceSkeleton = + 'balance' in props && (props.loading || props.loadingBalance); + const price = props.price; + + const isUsdValueZeroOrFalsy = + !props.price.usdValue || props.price.usdValue === '0'; + + const displayUsdValue = + props.price.error || + (isUsdValueZeroOrFalsy ? '0.00' : `~$${props.price.usdValue}`); + + return ( + +
+
+ + {props.label} + + {showBalance && ( +
+ + {i18n.t('Balance')}: {props.balance} + + + + + {i18n.t('Max')} + + +
+ )} + {showBalanceSkeleton && ( +
+ +
+ )} +
+
+
+ +
+ {props.loading || (props.mode === 'To' && props.fetchingQuote) ? ( + <> + + + + + ) : ( + <> + + ) => + props.onInputChange(event.target.value), + })} + /> + + {'percentageChange' in props ? ( + + ) : ( + + + + {displayUsdValue} + + + + )} + + )} +
+
+
+ ); +} diff --git a/widget/ui/src/containers/SwapInput/SwapInput.types.ts b/widget/ui/src/containers/SwapInput/SwapInput.types.ts new file mode 100644 index 0000000000..91ec7a9d4c --- /dev/null +++ b/widget/ui/src/containers/SwapInput/SwapInput.types.ts @@ -0,0 +1,44 @@ +import type { PriceImpactWarningLevel } from '../../components/PriceImpact/PriceImpact.types.js'; + +export type BaseProps = { + chain: { + displayName: string; + image: string; + }; + token: { + displayName: string; + image: string; + }; + price: { + value: string; + usdValue?: string; + realValue?: string; + realUsdValue?: string; + error?: string; + }; + loading?: boolean; + error?: boolean; + disabled?: boolean; + label: string; + sharpBottomStyle?: boolean; + onClickToken: () => void; + tooltipContainer?: HTMLElement; +}; + +type FromProps = { + mode: 'From'; + balance?: string; + loadingBalance: boolean; + onSelectMaxBalance: () => void; + onInputChange: (inputAmount: string) => void; + anyWalletConnected: boolean; +}; + +type ToProps = { + mode: 'To'; + fetchingQuote?: boolean; + percentageChange: string | null; + warningLevel: PriceImpactWarningLevel; +}; + +export type SwapInputPropTypes = BaseProps & (FromProps | ToProps); diff --git a/widget/ui/src/containers/SwapInput/TokenSection.styles.ts b/widget/ui/src/containers/SwapInput/TokenSection.styles.ts new file mode 100644 index 0000000000..35f49d4d3b --- /dev/null +++ b/widget/ui/src/containers/SwapInput/TokenSection.styles.ts @@ -0,0 +1,76 @@ +import { ChainImageContainer } from '../../components/ChainToken/ChainToken.styles.js'; +import { Button } from '../../components/index.js'; +import { css, darkTheme, styled } from '../../theme.js'; + +export const Container = styled(Button, { + maxWidth: '180px', + minWidth: '130px', + flexGrow: 1, + backgroundColor: 'transparent', + borderRadius: '$xs', + + color: '$neutral700', + '&:disabled': { + color: '$neutral600', + }, + '&:focus-visible': { + $$color: '$colors$secondary100', + [`.${darkTheme} &`]: { + $$color: '$colors$info700', + }, + backgroundColor: '$$color !important', + outline: 0, + }, + '&:disabled:hover': { + backgroundColor: 'transparent', + }, + '&:hover': { + $$color: '$colors$secondary100', + [`.${darkTheme} &`]: { + $$color: '$colors$neutral100', + }, + backgroundColor: '$$color !important', + + [`& ${ChainImageContainer}`]: { + $$color: '$colors$secondary100', + [`.${darkTheme} &`]: { + $$color: '$colors$neutral100', + }, + backgroundColor: '$$color !important', + }, + }, +}); + +export const chainNameStyles = css(); + +export const TokenSectionContainer = styled('div', { + maxWidth: '170px', + padding: '$2 $5', + display: 'flex', + borderRadius: '$xs', + justifyContent: 'start', + boxSizing: 'border-box', + alignItems: 'center', + [`& .${chainNameStyles}`]: { + $$color: '$colors$neutral600', + [`.${darkTheme} &`]: { + $$color: '$colors$neutral700', + }, + color: '$$color', + }, +}); + +export const tokenChainStyles = css({ + display: 'flex', + flexDirection: 'column', + justifyContent: 'center', + alignItems: 'start', + paddingLeft: '$10', + flexGrow: 1, + textAlign: 'left', +}); + +export const skeletonStyles = css({ + width: '100%', + padding: '$5 $0', +}); diff --git a/widget/ui/src/containers/SwapInput/TokenSection.tsx b/widget/ui/src/containers/SwapInput/TokenSection.tsx new file mode 100644 index 0000000000..7ef3cd8bd5 --- /dev/null +++ b/widget/ui/src/containers/SwapInput/TokenSection.tsx @@ -0,0 +1,69 @@ +import type { TokenSectionProps } from './TokenSection.types.js'; + +import { i18n } from '@lingui/core'; +import React from 'react'; + +import { + ChainToken, + Divider, + Skeleton, + Typography, +} from '../../components/index.js'; + +import { + chainNameStyles, + Container, + skeletonStyles, + tokenChainStyles, + TokenSectionContainer, +} from './TokenSection.styles.js'; + +export function TokenSection(props: TokenSectionProps) { + const { + error, + chainImage, + tokenImage, + tokenSymbol, + chain, + chianImageId, + onClick, + loading, + } = props; + return ( + + + +
+ {loading ? ( +
+ + + +
+ ) : ( + <> + + {error || (!loading && !tokenSymbol) + ? i18n.t('Select Token') + : tokenSymbol} + + + {error || (!loading && !chain) ? i18n.t('Select Chain') : chain} + + + )} +
+
+
+ ); +} diff --git a/widget/ui/src/containers/SwapInput/TokenSection.types.ts b/widget/ui/src/containers/SwapInput/TokenSection.types.ts new file mode 100644 index 0000000000..a85b8f579e --- /dev/null +++ b/widget/ui/src/containers/SwapInput/TokenSection.types.ts @@ -0,0 +1,10 @@ +export type TokenSectionProps = { + chainImage: string; + tokenImage: string; + tokenSymbol: string; + chain: string; + chianImageId?: string; + error?: boolean; + onClick: () => void; + loading?: boolean; +}; diff --git a/widget/ui/src/containers/SwapInput/index.ts b/widget/ui/src/containers/SwapInput/index.ts new file mode 100644 index 0000000000..3e03536af0 --- /dev/null +++ b/widget/ui/src/containers/SwapInput/index.ts @@ -0,0 +1,2 @@ +export { SwapInput } from './SwapInput.js'; +export type { SwapInputPropTypes } from './SwapInput.types.js'; diff --git a/widget/ui/src/containers/Warnings/BalanceErrors.tsx b/widget/ui/src/containers/Warnings/BalanceErrors.tsx new file mode 100644 index 0000000000..05b6328411 --- /dev/null +++ b/widget/ui/src/containers/Warnings/BalanceErrors.tsx @@ -0,0 +1,40 @@ +import React from 'react'; + +import { Typography } from '../../components/index.js'; +import { styled } from '../../theme.js'; + +interface PropTypes { + messages: string[]; +} + +const List = styled('ul', { + padding: '$0 $0 $40 $0', + margin: 0, +}); + +const ListItem = styled('li', { + paddingBottom: '$10', +}); + +const Message = styled(Typography, { + display: 'block', +}); + +export function BalanceErrors({ messages }: PropTypes) { + return ( + <> + + {messages.map((warning, index) => { + const key = index + warning; + return ( + + + {warning} + + + ); + })} + + + ); +} diff --git a/widget/ui/src/containers/Warnings/index.ts b/widget/ui/src/containers/Warnings/index.ts new file mode 100644 index 0000000000..912ecfb10a --- /dev/null +++ b/widget/ui/src/containers/Warnings/index.ts @@ -0,0 +1 @@ +export { BalanceErrors } from './BalanceErrors.js'; diff --git a/widget/ui/src/containers/index.ts b/widget/ui/src/containers/index.ts index 16dc9ac34f..a1368aec2f 100644 --- a/widget/ui/src/containers/index.ts +++ b/widget/ui/src/containers/index.ts @@ -1,3 +1,4 @@ -export * from './ConfirmSwap'; -export * from './History'; -export * from './SwapHistory'; +export * from './ConnectWalletsModal/index.js'; +export * from './Warnings/index.js'; +export * from './SwapInput/index.js'; +export * from './Notifications/index.js'; diff --git a/widget/ui/src/helper/index.ts b/widget/ui/src/helper/index.ts deleted file mode 100644 index 5c38cfa9b8..0000000000 --- a/widget/ui/src/helper/index.ts +++ /dev/null @@ -1,31 +0,0 @@ -export function containsText(text: string, searchText: string): boolean { - return text.toLowerCase().indexOf(searchText.toLowerCase()) > -1; -} - -export function getConciseAddress( - address: string | null, - maxChars = 8, - ellipsisLength = 3 -): string | null { - if (!address) return null; - if (address.length < 2 * maxChars + ellipsisLength) return address; - const start = Math.ceil((address.length - maxChars) / 2); - const end = address.length - maxChars; - return `${address.substr(start, maxChars)}${'.'.repeat( - ellipsisLength - )}${address.substr(end)}`; -} - -export function limitDecimalPlaces( - numberString: string, - maxDecimalPlaces = 4 -): string { - const number = parseFloat(numberString); - if (isNaN(number)) - return numberString; // Return the original string if it's not a valid number - else { - const multiplier = Math.pow(10, maxDecimalPlaces); - const roundedNumber = Math.round(number * multiplier) / multiplier; - return roundedNumber.toString(); - } -} diff --git a/widget/ui/src/hooks/index.ts b/widget/ui/src/hooks/index.ts new file mode 100644 index 0000000000..9912a0ed10 --- /dev/null +++ b/widget/ui/src/hooks/index.ts @@ -0,0 +1 @@ +export { useCopyToClipboard } from './useCopyToClipboard.js'; diff --git a/widget/embedded/src/hooks/useCopyToClipboard.ts b/widget/ui/src/hooks/useCopyToClipboard.ts similarity index 88% rename from widget/embedded/src/hooks/useCopyToClipboard.ts rename to widget/ui/src/hooks/useCopyToClipboard.ts index af15182aaf..5af51543b8 100644 --- a/widget/embedded/src/hooks/useCopyToClipboard.ts +++ b/widget/ui/src/hooks/useCopyToClipboard.ts @@ -1,7 +1,7 @@ -import React from 'react'; import copy from 'copy-to-clipboard'; +import React from 'react'; -export default function useCopyToClipboard(resetInterval?: number) { +export function useCopyToClipboard(resetInterval?: number) { const [isCopied, setCopied] = React.useState(false); const handleCopy = React.useCallback((text: string | number) => { diff --git a/widget/ui/src/icons/Add.tsx b/widget/ui/src/icons/Add.tsx new file mode 100644 index 0000000000..e4f0baf0df --- /dev/null +++ b/widget/ui/src/icons/Add.tsx @@ -0,0 +1,25 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgAdd(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + ); +} +export default SvgAdd; diff --git a/widget/ui/src/icons/Affiliate.tsx b/widget/ui/src/icons/Affiliate.tsx new file mode 100644 index 0000000000..d4d9704818 --- /dev/null +++ b/widget/ui/src/icons/Affiliate.tsx @@ -0,0 +1,21 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgAffiliate(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + ); +} +export default SvgAffiliate; diff --git a/widget/ui/src/icons/AutoTheme.tsx b/widget/ui/src/icons/AutoTheme.tsx new file mode 100644 index 0000000000..e8a36fa642 --- /dev/null +++ b/widget/ui/src/icons/AutoTheme.tsx @@ -0,0 +1,45 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgAutoTheme(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + + + + + + ); +} +export default SvgAutoTheme; diff --git a/widget/ui/src/icons/Autorenew.tsx b/widget/ui/src/icons/Autorenew.tsx new file mode 100644 index 0000000000..df333c3080 --- /dev/null +++ b/widget/ui/src/icons/Autorenew.tsx @@ -0,0 +1,20 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgAutorenew(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + ); +} +export default SvgAutorenew; diff --git a/widget/ui/src/icons/BorderRadius.tsx b/widget/ui/src/icons/BorderRadius.tsx new file mode 100644 index 0000000000..725d30bd03 --- /dev/null +++ b/widget/ui/src/icons/BorderRadius.tsx @@ -0,0 +1,24 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgBorderRadius(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + + ); +} +export default SvgBorderRadius; diff --git a/widget/ui/src/icons/Bridges.tsx b/widget/ui/src/icons/Bridges.tsx new file mode 100644 index 0000000000..d3c94b7252 --- /dev/null +++ b/widget/ui/src/icons/Bridges.tsx @@ -0,0 +1,19 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgBridges(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + ); +} +export default SvgBridges; diff --git a/widget/ui/src/icons/BugReport.tsx b/widget/ui/src/icons/BugReport.tsx new file mode 100644 index 0000000000..4b8a2ab61a --- /dev/null +++ b/widget/ui/src/icons/BugReport.tsx @@ -0,0 +1,58 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgBugReport(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + + + + + + + + + + + + ); +} +export default SvgBugReport; diff --git a/widget/ui/src/icons/Bullhorn.tsx b/widget/ui/src/icons/Bullhorn.tsx new file mode 100644 index 0000000000..5e6a1194e5 --- /dev/null +++ b/widget/ui/src/icons/Bullhorn.tsx @@ -0,0 +1,25 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgBullhorn(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + + ); +} +export default SvgBullhorn; diff --git a/widget/ui/src/icons/Calendar.tsx b/widget/ui/src/icons/Calendar.tsx new file mode 100644 index 0000000000..3c23899f79 --- /dev/null +++ b/widget/ui/src/icons/Calendar.tsx @@ -0,0 +1,39 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgCalendar(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + + + ); +} +export default SvgCalendar; diff --git a/widget/ui/src/icons/Chains.tsx b/widget/ui/src/icons/Chains.tsx new file mode 100644 index 0000000000..f9de5d19a5 --- /dev/null +++ b/widget/ui/src/icons/Chains.tsx @@ -0,0 +1,19 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgChains(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + ); +} +export default SvgChains; diff --git a/widget/ui/src/icons/Chart.tsx b/widget/ui/src/icons/Chart.tsx new file mode 100644 index 0000000000..7227d4e794 --- /dev/null +++ b/widget/ui/src/icons/Chart.tsx @@ -0,0 +1,21 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgChart(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + ); +} +export default SvgChart; diff --git a/widget/ui/src/icons/ChevronDown.tsx b/widget/ui/src/icons/ChevronDown.tsx new file mode 100644 index 0000000000..e1be3b1cef --- /dev/null +++ b/widget/ui/src/icons/ChevronDown.tsx @@ -0,0 +1,21 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgChevronDown(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + ); +} +export default SvgChevronDown; diff --git a/widget/ui/src/icons/ChevronLeft.tsx b/widget/ui/src/icons/ChevronLeft.tsx new file mode 100644 index 0000000000..1dfc4f3c6c --- /dev/null +++ b/widget/ui/src/icons/ChevronLeft.tsx @@ -0,0 +1,21 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgChevronLeft(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + ); +} +export default SvgChevronLeft; diff --git a/widget/ui/src/icons/ChevronRight.tsx b/widget/ui/src/icons/ChevronRight.tsx new file mode 100644 index 0000000000..7008d4191a --- /dev/null +++ b/widget/ui/src/icons/ChevronRight.tsx @@ -0,0 +1,21 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgChevronRight(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + ); +} +export default SvgChevronRight; diff --git a/widget/ui/src/icons/ChevronUp.tsx b/widget/ui/src/icons/ChevronUp.tsx new file mode 100644 index 0000000000..169f19f0b1 --- /dev/null +++ b/widget/ui/src/icons/ChevronUp.tsx @@ -0,0 +1,21 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgChevronUp(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + ); +} +export default SvgChevronUp; diff --git a/widget/ui/src/icons/Close.tsx b/widget/ui/src/icons/Close.tsx new file mode 100644 index 0000000000..b5da62eb15 --- /dev/null +++ b/widget/ui/src/icons/Close.tsx @@ -0,0 +1,28 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgClose(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + + + + + + + ); +} +export default SvgClose; diff --git a/widget/ui/src/icons/Colors.tsx b/widget/ui/src/icons/Colors.tsx new file mode 100644 index 0000000000..9abca27b57 --- /dev/null +++ b/widget/ui/src/icons/Colors.tsx @@ -0,0 +1,33 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgColors(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + + ); +} +export default SvgColors; diff --git a/widget/ui/src/icons/Complete.tsx b/widget/ui/src/icons/Complete.tsx new file mode 100644 index 0000000000..c0fcdc917b --- /dev/null +++ b/widget/ui/src/icons/Complete.tsx @@ -0,0 +1,19 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgComplete(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + ); +} +export default SvgComplete; diff --git a/widget/ui/src/icons/Cookie.tsx b/widget/ui/src/icons/Cookie.tsx new file mode 100644 index 0000000000..2d30230c10 --- /dev/null +++ b/widget/ui/src/icons/Cookie.tsx @@ -0,0 +1,49 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgCookie(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + + + + + + + ); +} +export default SvgCookie; diff --git a/widget/ui/src/icons/Copy.tsx b/widget/ui/src/icons/Copy.tsx new file mode 100644 index 0000000000..207c73abcc --- /dev/null +++ b/widget/ui/src/icons/Copy.tsx @@ -0,0 +1,19 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgCopy(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + ); +} +export default SvgCopy; diff --git a/widget/ui/src/icons/CosmosCategory.tsx b/widget/ui/src/icons/CosmosCategory.tsx new file mode 100644 index 0000000000..8fb7843da7 --- /dev/null +++ b/widget/ui/src/icons/CosmosCategory.tsx @@ -0,0 +1,137 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgCosmosCategory(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); +} +export default SvgCosmosCategory; diff --git a/widget/ui/src/icons/CreditCard.tsx b/widget/ui/src/icons/CreditCard.tsx new file mode 100644 index 0000000000..5524718d6a --- /dev/null +++ b/widget/ui/src/icons/CreditCard.tsx @@ -0,0 +1,23 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgCreditCard(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + ); +} +export default SvgCreditCard; diff --git a/widget/ui/src/icons/CustomColors.tsx b/widget/ui/src/icons/CustomColors.tsx new file mode 100644 index 0000000000..0b7202feae --- /dev/null +++ b/widget/ui/src/icons/CustomColors.tsx @@ -0,0 +1,21 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgCustomColors(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + ); +} +export default SvgCustomColors; diff --git a/widget/ui/src/icons/CustomTokensZeroState.tsx b/widget/ui/src/icons/CustomTokensZeroState.tsx new file mode 100644 index 0000000000..4142423176 --- /dev/null +++ b/widget/ui/src/icons/CustomTokensZeroState.tsx @@ -0,0 +1,262 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon'; + +function SvgCustomTokensZeroState(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); +} +export default SvgCustomTokensZeroState; diff --git a/widget/ui/src/icons/CustomTokensZeroStateDark.tsx b/widget/ui/src/icons/CustomTokensZeroStateDark.tsx new file mode 100644 index 0000000000..8f04625a84 --- /dev/null +++ b/widget/ui/src/icons/CustomTokensZeroStateDark.tsx @@ -0,0 +1,415 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon'; + +function SvgCustomTokensZeroStateDark(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); +} +export default SvgCustomTokensZeroStateDark; diff --git a/widget/ui/src/icons/CustomerSupport.tsx b/widget/ui/src/icons/CustomerSupport.tsx new file mode 100644 index 0000000000..e4d6b06636 --- /dev/null +++ b/widget/ui/src/icons/CustomerSupport.tsx @@ -0,0 +1,21 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgCustomerSupport(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + ); +} +export default SvgCustomerSupport; diff --git a/widget/ui/src/icons/DarkMode.tsx b/widget/ui/src/icons/DarkMode.tsx new file mode 100644 index 0000000000..788bf3d4d2 --- /dev/null +++ b/widget/ui/src/icons/DarkMode.tsx @@ -0,0 +1,21 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgDarkMode(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + ); +} +export default SvgDarkMode; diff --git a/widget/ui/src/icons/Delete.tsx b/widget/ui/src/icons/Delete.tsx new file mode 100644 index 0000000000..343f7fb852 --- /dev/null +++ b/widget/ui/src/icons/Delete.tsx @@ -0,0 +1,33 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgDelete(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + + + + + + + ); +} +export default SvgDelete; diff --git a/widget/ui/src/icons/Desktop.tsx b/widget/ui/src/icons/Desktop.tsx new file mode 100644 index 0000000000..fd162a4b09 --- /dev/null +++ b/widget/ui/src/icons/Desktop.tsx @@ -0,0 +1,271 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgDesktop(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); +} +export default SvgDesktop; diff --git a/widget/ui/src/icons/Disconnect.tsx b/widget/ui/src/icons/Disconnect.tsx new file mode 100644 index 0000000000..2c33ddd6cd --- /dev/null +++ b/widget/ui/src/icons/Disconnect.tsx @@ -0,0 +1,26 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgDisconnect(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + + + + + + + ); +} +export default SvgDisconnect; diff --git a/widget/ui/src/icons/Discord.tsx b/widget/ui/src/icons/Discord.tsx new file mode 100644 index 0000000000..8f84d72184 --- /dev/null +++ b/widget/ui/src/icons/Discord.tsx @@ -0,0 +1,21 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgDiscord(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + ); +} +export default SvgDiscord; diff --git a/widget/ui/src/icons/Document.tsx b/widget/ui/src/icons/Document.tsx new file mode 100644 index 0000000000..d8afe6443c --- /dev/null +++ b/widget/ui/src/icons/Document.tsx @@ -0,0 +1,50 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgDocument(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + + + + + + ); +} +export default SvgDocument; diff --git a/widget/ui/src/icons/Documentation.tsx b/widget/ui/src/icons/Documentation.tsx new file mode 100644 index 0000000000..73f03c7c3f --- /dev/null +++ b/widget/ui/src/icons/Documentation.tsx @@ -0,0 +1,39 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgDocumentation(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + + + ); +} +export default SvgDocumentation; diff --git a/widget/ui/src/icons/Done.tsx b/widget/ui/src/icons/Done.tsx new file mode 100644 index 0000000000..64cf0bdde2 --- /dev/null +++ b/widget/ui/src/icons/Done.tsx @@ -0,0 +1,21 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgDone(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + ); +} +export default SvgDone; diff --git a/widget/ui/src/icons/Error.tsx b/widget/ui/src/icons/Error.tsx new file mode 100644 index 0000000000..341b30157b --- /dev/null +++ b/widget/ui/src/icons/Error.tsx @@ -0,0 +1,21 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgError(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + ); +} +export default SvgError; diff --git a/widget/ui/src/icons/EvmCategory.tsx b/widget/ui/src/icons/EvmCategory.tsx new file mode 100644 index 0000000000..e158a3b779 --- /dev/null +++ b/widget/ui/src/icons/EvmCategory.tsx @@ -0,0 +1,74 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgEvmCategory(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + + + + + + + + + + + + + + + + + + + + + + ); +} +export default SvgEvmCategory; diff --git a/widget/ui/src/icons/Exchange.tsx b/widget/ui/src/icons/Exchange.tsx new file mode 100644 index 0000000000..8aa7bc7b0f --- /dev/null +++ b/widget/ui/src/icons/Exchange.tsx @@ -0,0 +1,22 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgExchange(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + + ); +} +export default SvgExchange; diff --git a/widget/ui/src/icons/Exit.tsx b/widget/ui/src/icons/Exit.tsx new file mode 100644 index 0000000000..b7098c0754 --- /dev/null +++ b/widget/ui/src/icons/Exit.tsx @@ -0,0 +1,20 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgExit(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + ); +} +export default SvgExit; diff --git a/widget/ui/src/icons/Explorer.tsx b/widget/ui/src/icons/Explorer.tsx new file mode 100644 index 0000000000..d7778b751e --- /dev/null +++ b/widget/ui/src/icons/Explorer.tsx @@ -0,0 +1,20 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgExplorer(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + ); +} +export default SvgExplorer; diff --git a/widget/ui/src/icons/ExternalLink.tsx b/widget/ui/src/icons/ExternalLink.tsx new file mode 100644 index 0000000000..9b05a6061a --- /dev/null +++ b/widget/ui/src/icons/ExternalLink.tsx @@ -0,0 +1,21 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgExternalLink(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + ); +} +export default SvgExternalLink; diff --git a/widget/ui/src/icons/FeatureList.tsx b/widget/ui/src/icons/FeatureList.tsx new file mode 100644 index 0000000000..7de08b6935 --- /dev/null +++ b/widget/ui/src/icons/FeatureList.tsx @@ -0,0 +1,45 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgFeatureList(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + + + + ); +} +export default SvgFeatureList; diff --git a/widget/ui/src/icons/Filter.tsx b/widget/ui/src/icons/Filter.tsx new file mode 100644 index 0000000000..05e77dd852 --- /dev/null +++ b/widget/ui/src/icons/Filter.tsx @@ -0,0 +1,21 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgFilter(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + ); +} +export default SvgFilter; diff --git a/widget/ui/src/icons/First.tsx b/widget/ui/src/icons/First.tsx new file mode 100644 index 0000000000..dcee826ce7 --- /dev/null +++ b/widget/ui/src/icons/First.tsx @@ -0,0 +1,25 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgFirst(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + ); +} +export default SvgFirst; diff --git a/widget/ui/src/icons/Font.tsx b/widget/ui/src/icons/Font.tsx new file mode 100644 index 0000000000..86c95d7e14 --- /dev/null +++ b/widget/ui/src/icons/Font.tsx @@ -0,0 +1,31 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgFont(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + + + + + + ); +} +export default SvgFont; diff --git a/widget/ui/src/icons/Gas.tsx b/widget/ui/src/icons/Gas.tsx new file mode 100644 index 0000000000..77c87f2de9 --- /dev/null +++ b/widget/ui/src/icons/Gas.tsx @@ -0,0 +1,39 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgGas(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + + + ); +} +export default SvgGas; diff --git a/widget/ui/src/icons/Height.tsx b/widget/ui/src/icons/Height.tsx new file mode 100644 index 0000000000..64967723de --- /dev/null +++ b/widget/ui/src/icons/Height.tsx @@ -0,0 +1,24 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgHeight(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + + ); +} +export default SvgHeight; diff --git a/widget/ui/src/icons/InProgress.tsx b/widget/ui/src/icons/InProgress.tsx new file mode 100644 index 0000000000..aefbb77229 --- /dev/null +++ b/widget/ui/src/icons/InProgress.tsx @@ -0,0 +1,39 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgInProgress(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + + + + + + + + ); +} +export default SvgInProgress; diff --git a/widget/ui/src/icons/Infinity.tsx b/widget/ui/src/icons/Infinity.tsx new file mode 100644 index 0000000000..8b5f859208 --- /dev/null +++ b/widget/ui/src/icons/Infinity.tsx @@ -0,0 +1,21 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgInfinity(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + ); +} +export default SvgInfinity; diff --git a/widget/ui/src/icons/Info.tsx b/widget/ui/src/icons/Info.tsx new file mode 100644 index 0000000000..c64d0f8b20 --- /dev/null +++ b/widget/ui/src/icons/Info.tsx @@ -0,0 +1,29 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgInfo(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + + ); +} +export default SvgInfo; diff --git a/widget/ui/src/icons/InfoError.tsx b/widget/ui/src/icons/InfoError.tsx new file mode 100644 index 0000000000..ab7472067b --- /dev/null +++ b/widget/ui/src/icons/InfoError.tsx @@ -0,0 +1,19 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgInfoError(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + ); +} +export default SvgInfoError; diff --git a/widget/ui/src/icons/Key.tsx b/widget/ui/src/icons/Key.tsx new file mode 100644 index 0000000000..4242f9c281 --- /dev/null +++ b/widget/ui/src/icons/Key.tsx @@ -0,0 +1,32 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgKey(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + + + + ); +} +export default SvgKey; diff --git a/widget/ui/src/icons/Language.tsx b/widget/ui/src/icons/Language.tsx new file mode 100644 index 0000000000..f95d023b33 --- /dev/null +++ b/widget/ui/src/icons/Language.tsx @@ -0,0 +1,59 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgLanguage(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + + + + + + + + + + + + + ); +} +export default SvgLanguage; diff --git a/widget/ui/src/icons/Last.tsx b/widget/ui/src/icons/Last.tsx new file mode 100644 index 0000000000..2262eb45b9 --- /dev/null +++ b/widget/ui/src/icons/Last.tsx @@ -0,0 +1,25 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgLast(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + ); +} +export default SvgLast; diff --git a/widget/ui/src/icons/Legacy.tsx b/widget/ui/src/icons/Legacy.tsx new file mode 100644 index 0000000000..86065b59bb --- /dev/null +++ b/widget/ui/src/icons/Legacy.tsx @@ -0,0 +1,27 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgLegacy(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + ); +} +export default SvgLegacy; diff --git a/widget/ui/src/icons/LightMode.tsx b/widget/ui/src/icons/LightMode.tsx new file mode 100644 index 0000000000..e95f7a01f3 --- /dev/null +++ b/widget/ui/src/icons/LightMode.tsx @@ -0,0 +1,19 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgLightMode(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + ); +} +export default SvgLightMode; diff --git a/widget/ui/src/icons/Link.tsx b/widget/ui/src/icons/Link.tsx new file mode 100644 index 0000000000..7113e47320 --- /dev/null +++ b/widget/ui/src/icons/Link.tsx @@ -0,0 +1,21 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgLink(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + ); +} +export default SvgLink; diff --git a/widget/ui/src/icons/Loading.tsx b/widget/ui/src/icons/Loading.tsx new file mode 100644 index 0000000000..94bd087b48 --- /dev/null +++ b/widget/ui/src/icons/Loading.tsx @@ -0,0 +1,63 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgLoading(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + + + + + + + + + + + ); +} +export default SvgLoading; diff --git a/widget/ui/src/icons/LogoWithText.tsx b/widget/ui/src/icons/LogoWithText.tsx new file mode 100644 index 0000000000..61ee59d861 --- /dev/null +++ b/widget/ui/src/icons/LogoWithText.tsx @@ -0,0 +1,159 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgLogoWithText(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); +} +export default SvgLogoWithText; diff --git a/widget/ui/src/icons/Logout.tsx b/widget/ui/src/icons/Logout.tsx new file mode 100644 index 0000000000..73e5fa3b1a --- /dev/null +++ b/widget/ui/src/icons/Logout.tsx @@ -0,0 +1,28 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgLogout(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + + + + + + + ); +} +export default SvgLogout; diff --git a/widget/ui/src/icons/Medium.tsx b/widget/ui/src/icons/Medium.tsx new file mode 100644 index 0000000000..ed25eb85a7 --- /dev/null +++ b/widget/ui/src/icons/Medium.tsx @@ -0,0 +1,20 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgMedium(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + ); +} +export default SvgMedium; diff --git a/widget/ui/src/icons/Menu.tsx b/widget/ui/src/icons/Menu.tsx new file mode 100644 index 0000000000..65fb3bbaa0 --- /dev/null +++ b/widget/ui/src/icons/Menu.tsx @@ -0,0 +1,36 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgMenu(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + + ); +} +export default SvgMenu; diff --git a/widget/ui/src/icons/More.tsx b/widget/ui/src/icons/More.tsx new file mode 100644 index 0000000000..91db11d189 --- /dev/null +++ b/widget/ui/src/icons/More.tsx @@ -0,0 +1,30 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgMore(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + + ); +} +export default SvgMore; diff --git a/widget/ui/src/icons/Next.tsx b/widget/ui/src/icons/Next.tsx new file mode 100644 index 0000000000..5b44ad6fe7 --- /dev/null +++ b/widget/ui/src/icons/Next.tsx @@ -0,0 +1,21 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgNext(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + ); +} +export default SvgNext; diff --git a/widget/ui/src/icons/NoNotification.tsx b/widget/ui/src/icons/NoNotification.tsx new file mode 100644 index 0000000000..3d99f6a1f4 --- /dev/null +++ b/widget/ui/src/icons/NoNotification.tsx @@ -0,0 +1,31 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgNoNotification(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + + + + + ); +} +export default SvgNoNotification; diff --git a/widget/ui/src/icons/NoRoute.tsx b/widget/ui/src/icons/NoRoute.tsx new file mode 100644 index 0000000000..d003ab9b19 --- /dev/null +++ b/widget/ui/src/icons/NoRoute.tsx @@ -0,0 +1,64 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgNoRoute(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + + + + + + + + + ); +} +export default SvgNoRoute; diff --git a/widget/ui/src/icons/NotificationNumber.tsx b/widget/ui/src/icons/NotificationNumber.tsx new file mode 100644 index 0000000000..eef3887cd2 --- /dev/null +++ b/widget/ui/src/icons/NotificationNumber.tsx @@ -0,0 +1,41 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgNotificationNumber(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + + + + + + + + + ); +} +export default SvgNotificationNumber; diff --git a/widget/ui/src/icons/Notifications.tsx b/widget/ui/src/icons/Notifications.tsx new file mode 100644 index 0000000000..68e1d952b8 --- /dev/null +++ b/widget/ui/src/icons/Notifications.tsx @@ -0,0 +1,21 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgNotifications(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + ); +} +export default SvgNotifications; diff --git a/widget/ui/src/icons/Number.tsx b/widget/ui/src/icons/Number.tsx new file mode 100644 index 0000000000..bd70757d11 --- /dev/null +++ b/widget/ui/src/icons/Number.tsx @@ -0,0 +1,24 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgNumber(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + + ); +} +export default SvgNumber; diff --git a/widget/ui/src/icons/NumberBlocks.tsx b/widget/ui/src/icons/NumberBlocks.tsx new file mode 100644 index 0000000000..6f1f708c40 --- /dev/null +++ b/widget/ui/src/icons/NumberBlocks.tsx @@ -0,0 +1,56 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgNumberBlocks(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + + + + + ); +} +export default SvgNumberBlocks; diff --git a/widget/ui/src/icons/OtherCategory.tsx b/widget/ui/src/icons/OtherCategory.tsx new file mode 100644 index 0000000000..93d4a51f47 --- /dev/null +++ b/widget/ui/src/icons/OtherCategory.tsx @@ -0,0 +1,72 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgOtherCategory(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + + + + + + + + + + + + + + + + + + + + ); +} +export default SvgOtherCategory; diff --git a/widget/ui/src/icons/Paste.tsx b/widget/ui/src/icons/Paste.tsx new file mode 100644 index 0000000000..41d2f1c405 --- /dev/null +++ b/widget/ui/src/icons/Paste.tsx @@ -0,0 +1,26 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgPaste(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + + + + + + + ); +} +export default SvgPaste; diff --git a/widget/ui/src/icons/Pin.tsx b/widget/ui/src/icons/Pin.tsx new file mode 100644 index 0000000000..2a6c80b572 --- /dev/null +++ b/widget/ui/src/icons/Pin.tsx @@ -0,0 +1,31 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgPin(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + + + + + + + ); +} +export default SvgPin; diff --git a/widget/ui/src/icons/Profile.tsx b/widget/ui/src/icons/Profile.tsx new file mode 100644 index 0000000000..a1d728a728 --- /dev/null +++ b/widget/ui/src/icons/Profile.tsx @@ -0,0 +1,21 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgProfile(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + ); +} +export default SvgProfile; diff --git a/widget/ui/src/icons/RangoExplorer.tsx b/widget/ui/src/icons/RangoExplorer.tsx new file mode 100644 index 0000000000..518b323a72 --- /dev/null +++ b/widget/ui/src/icons/RangoExplorer.tsx @@ -0,0 +1,40 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgRangoExplorer(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + + + + + + + + ); +} +export default SvgRangoExplorer; diff --git a/widget/ui/src/icons/Rank.tsx b/widget/ui/src/icons/Rank.tsx new file mode 100644 index 0000000000..e02cc86384 --- /dev/null +++ b/widget/ui/src/icons/Rank.tsx @@ -0,0 +1,27 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgRank(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + ); +} +export default SvgRank; diff --git a/widget/ui/src/icons/Refresh.tsx b/widget/ui/src/icons/Refresh.tsx new file mode 100644 index 0000000000..f9b758f7cd --- /dev/null +++ b/widget/ui/src/icons/Refresh.tsx @@ -0,0 +1,27 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgRefresh(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + + ); +} +export default SvgRefresh; diff --git a/widget/ui/src/icons/Report.tsx b/widget/ui/src/icons/Report.tsx new file mode 100644 index 0000000000..8d06462734 --- /dev/null +++ b/widget/ui/src/icons/Report.tsx @@ -0,0 +1,20 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgReport(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + ); +} +export default SvgReport; diff --git a/widget/ui/src/icons/Request.tsx b/widget/ui/src/icons/Request.tsx new file mode 100644 index 0000000000..fb71a35bdb --- /dev/null +++ b/widget/ui/src/icons/Request.tsx @@ -0,0 +1,65 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgRequest(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + + + + + + + + + ); +} +export default SvgRequest; diff --git a/widget/ui/src/icons/Reverse.tsx b/widget/ui/src/icons/Reverse.tsx new file mode 100644 index 0000000000..4090174301 --- /dev/null +++ b/widget/ui/src/icons/Reverse.tsx @@ -0,0 +1,39 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgReverse(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + + + ); +} +export default SvgReverse; diff --git a/widget/ui/src/icons/Route.tsx b/widget/ui/src/icons/Route.tsx new file mode 100644 index 0000000000..33baf29588 --- /dev/null +++ b/widget/ui/src/icons/Route.tsx @@ -0,0 +1,33 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgRoute(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + + ); +} +export default SvgRoute; diff --git a/widget/ui/src/icons/Scanner.tsx b/widget/ui/src/icons/Scanner.tsx new file mode 100644 index 0000000000..3e1d04cffb --- /dev/null +++ b/widget/ui/src/icons/Scanner.tsx @@ -0,0 +1,27 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgScanner(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + ); +} +export default SvgScanner; diff --git a/widget/ui/src/icons/Score.tsx b/widget/ui/src/icons/Score.tsx new file mode 100644 index 0000000000..c775e22697 --- /dev/null +++ b/widget/ui/src/icons/Score.tsx @@ -0,0 +1,39 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgScore(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + + + ); +} +export default SvgScore; diff --git a/widget/ui/src/icons/Search.tsx b/widget/ui/src/icons/Search.tsx new file mode 100644 index 0000000000..70f7f3819f --- /dev/null +++ b/widget/ui/src/icons/Search.tsx @@ -0,0 +1,27 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgSearch(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + ); +} +export default SvgSearch; diff --git a/widget/ui/src/icons/Settings.tsx b/widget/ui/src/icons/Settings.tsx new file mode 100644 index 0000000000..76753a53b5 --- /dev/null +++ b/widget/ui/src/icons/Settings.tsx @@ -0,0 +1,21 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgSettings(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + ); +} +export default SvgSettings; diff --git a/widget/ui/src/icons/Share.tsx b/widget/ui/src/icons/Share.tsx new file mode 100644 index 0000000000..3dfbecaf2a --- /dev/null +++ b/widget/ui/src/icons/Share.tsx @@ -0,0 +1,28 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgShare(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + + + + + + + ); +} +export default SvgShare; diff --git a/widget/ui/src/icons/Slippage.tsx b/widget/ui/src/icons/Slippage.tsx new file mode 100644 index 0000000000..ab5761898c --- /dev/null +++ b/widget/ui/src/icons/Slippage.tsx @@ -0,0 +1,19 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon'; + +function SvgSlippage(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + ); +} +export default SvgSlippage; diff --git a/widget/ui/src/icons/Stats.tsx b/widget/ui/src/icons/Stats.tsx new file mode 100644 index 0000000000..52d926ee82 --- /dev/null +++ b/widget/ui/src/icons/Stats.tsx @@ -0,0 +1,28 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgStats(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + + + + + + + ); +} +export default SvgStats; diff --git a/widget/ui/src/icons/Style.tsx b/widget/ui/src/icons/Style.tsx new file mode 100755 index 0000000000..590166d796 --- /dev/null +++ b/widget/ui/src/icons/Style.tsx @@ -0,0 +1,43 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgStyle(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + + + + + + + ); +} +export default SvgStyle; diff --git a/widget/ui/src/icons/Support.tsx b/widget/ui/src/icons/Support.tsx new file mode 100644 index 0000000000..6c75945c9d --- /dev/null +++ b/widget/ui/src/icons/Support.tsx @@ -0,0 +1,40 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgSupport(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + + + + ); +} +export default SvgSupport; diff --git a/widget/ui/src/icons/Swap.tsx b/widget/ui/src/icons/Swap.tsx new file mode 100644 index 0000000000..16c2518b85 --- /dev/null +++ b/widget/ui/src/icons/Swap.tsx @@ -0,0 +1,61 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgSwap(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + + + + + + + + + + + + + + + ); +} +export default SvgSwap; diff --git a/widget/ui/src/icons/Target.tsx b/widget/ui/src/icons/Target.tsx new file mode 100644 index 0000000000..d46d851da9 --- /dev/null +++ b/widget/ui/src/icons/Target.tsx @@ -0,0 +1,24 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon'; + +function SvgTarget(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + + ); +} +export default SvgTarget; diff --git a/widget/ui/src/icons/Telegram.tsx b/widget/ui/src/icons/Telegram.tsx new file mode 100644 index 0000000000..c66b6163a2 --- /dev/null +++ b/widget/ui/src/icons/Telegram.tsx @@ -0,0 +1,20 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgTelegram(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + ); +} +export default SvgTelegram; diff --git a/widget/ui/src/icons/Time.tsx b/widget/ui/src/icons/Time.tsx new file mode 100644 index 0000000000..35647800ad --- /dev/null +++ b/widget/ui/src/icons/Time.tsx @@ -0,0 +1,33 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgTime(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + + ); +} +export default SvgTime; diff --git a/widget/ui/src/icons/Transaction.tsx b/widget/ui/src/icons/Transaction.tsx new file mode 100644 index 0000000000..a0f64bc11d --- /dev/null +++ b/widget/ui/src/icons/Transaction.tsx @@ -0,0 +1,21 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgTransaction(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + ); +} +export default SvgTransaction; diff --git a/widget/ui/src/icons/Tune.tsx b/widget/ui/src/icons/Tune.tsx new file mode 100644 index 0000000000..46722d0582 --- /dev/null +++ b/widget/ui/src/icons/Tune.tsx @@ -0,0 +1,51 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgTune(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + + + + + ); +} +export default SvgTune; diff --git a/widget/ui/src/icons/UtxoCategory.tsx b/widget/ui/src/icons/UtxoCategory.tsx new file mode 100644 index 0000000000..4628cbf2d7 --- /dev/null +++ b/widget/ui/src/icons/UtxoCategory.tsx @@ -0,0 +1,44 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgUtxoCategory(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + + + + + + + + + + + + ); +} +export default SvgUtxoCategory; diff --git a/widget/ui/src/icons/Wallet.tsx b/widget/ui/src/icons/Wallet.tsx new file mode 100644 index 0000000000..0eec514844 --- /dev/null +++ b/widget/ui/src/icons/Wallet.tsx @@ -0,0 +1,33 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgWallet(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + + + + + + + ); +} +export default SvgWallet; diff --git a/widget/ui/src/icons/Warning.tsx b/widget/ui/src/icons/Warning.tsx new file mode 100644 index 0000000000..c48ae9ea77 --- /dev/null +++ b/widget/ui/src/icons/Warning.tsx @@ -0,0 +1,19 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgWarning(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + ); +} +export default SvgWarning; diff --git a/widget/ui/src/icons/Widget.tsx b/widget/ui/src/icons/Widget.tsx new file mode 100644 index 0000000000..1c7370e6d6 --- /dev/null +++ b/widget/ui/src/icons/Widget.tsx @@ -0,0 +1,24 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgWidget(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + + ); +} +export default SvgWidget; diff --git a/widget/ui/src/icons/Width.tsx b/widget/ui/src/icons/Width.tsx new file mode 100644 index 0000000000..b0c6563af1 --- /dev/null +++ b/widget/ui/src/icons/Width.tsx @@ -0,0 +1,29 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgWidth(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + + + + + + + + ); +} +export default SvgWidth; diff --git a/widget/ui/src/icons/X.tsx b/widget/ui/src/icons/X.tsx new file mode 100644 index 0000000000..6e12d6f391 --- /dev/null +++ b/widget/ui/src/icons/X.tsx @@ -0,0 +1,20 @@ +import type { SvgIconPropsWithChildren } from '../components/SvgIcon/index.js'; + +import React, { createElement } from 'react'; + +import { SvgIcon } from '../components/SvgIcon/index.js'; + +function SvgX(props: SvgIconPropsWithChildren) { + return createElement( + SvgIcon, + props, + + + + ); +} +export default SvgX; diff --git a/widget/ui/src/icons/index.ts b/widget/ui/src/icons/index.ts new file mode 100644 index 0000000000..0ab7c265ad --- /dev/null +++ b/widget/ui/src/icons/index.ts @@ -0,0 +1,101 @@ +export { default as AddIcon } from './Add.js'; +export { default as AffiliateIcon } from './Affiliate.js'; +export { default as AutoThemeIcon } from './AutoTheme.js'; +export { default as AutorenewIcon } from './Autorenew.js'; +export { default as BorderRadiusIcon } from './BorderRadius.js'; +export { default as BridgesIcon } from './Bridges.js'; +export { default as BugReportIcon } from './BugReport.js'; +export { default as CalendarIcon } from './Calendar.js'; +export { default as ChevronDownIcon } from './ChevronDown.js'; +export { default as ChevronLeftIcon } from './ChevronLeft.js'; +export { default as ChevronRightIcon } from './ChevronRight.js'; +export { default as ChevronUpIcon } from './ChevronUp.js'; +export { default as CloseIcon } from './Close.js'; +export { default as CompleteIcon } from './Complete.js'; +export { default as CookieIcon } from './Cookie.js'; +export { default as CopyIcon } from './Copy.js'; +export { default as CosmosCategoryIcon } from './CosmosCategory.js'; +export { default as CreditCardIcon } from './CreditCard.js'; +export { default as CustomColorsIcon } from './CustomColors.js'; +export { default as CustomTokensZeroStateIcon } from './CustomTokensZeroState.js'; +export { default as CustomTokensZeroStateDarkIcon } from './CustomTokensZeroStateDark.js'; +export { default as CustomerSupportIcon } from './CustomerSupport.js'; +export { default as DarkModeIcon } from './DarkMode.js'; +export { default as DeleteIcon } from './Delete.js'; +export { default as DesktopIcon } from './Desktop.js'; +export { default as DisconnectIcon } from './Disconnect.js'; +export { default as DocumentIcon } from './Document.js'; +export { default as DocumentationIcon } from './Documentation.js'; +export { default as DoneIcon } from './Done.js'; +export { default as EvmCategoryIcon } from './EvmCategory.js'; +export { default as ErrorIcon } from './Error.js'; +export { default as ExchangeIcon } from './Exchange.js'; +export { default as ExitIcon } from './Exit.js'; +export { default as ExplorerIcon } from './Explorer.js'; +export { default as ExternalLinkIcon } from './ExternalLink.js'; +export { default as FeatureListIcon } from './FeatureList.js'; +export { default as FilterIcon } from './Filter.js'; +export { default as FirstIcon } from './First.js'; +export { default as FontIcon } from './Font.js'; +export { default as GasIcon } from './Gas.js'; +export { default as HeightIcon } from './Height.js'; +export { default as InProgressIcon } from './InProgress.js'; +export { default as InfoErrorIcon } from './InfoError.js'; +export { default as InfoIcon } from './Info.js'; +export { default as LanguageIcon } from './Language.js'; +export { default as LastIcon } from './Last.js'; +export { default as LegacyIcon } from './Legacy.js'; +export { default as LightModeIcon } from './LightMode.js'; +export { default as LinkIcon } from './Link.js'; +export { default as LoadingIcon } from './Loading.js'; +export { default as LogoWithTextIcon } from './LogoWithText.js'; +export { default as LogoutIcon } from './Logout.js'; +export { default as MenuIcon } from './Menu.js'; +export { default as MoreIcon } from './More.js'; +export { default as NoRouteIcon } from './NoRoute.js'; +export { default as NextIcon } from './Next.js'; +export { default as NoNotificationIcon } from './NoNotification.js'; +export { default as NotificationNumberIcon } from './NotificationNumber.js'; +export { default as NotificationsIcon } from './Notifications.js'; +export { default as NumberIcon } from './Number.js'; +export { default as NumberBlocksIcon } from './NumberBlocks.js'; +export { default as OtherCategoryIcon } from './OtherCategory.js'; +export { default as PasteIcon } from './Paste.js'; +export { default as PinIcon } from './Pin.js'; +export { default as ProfileIcon } from './Profile.js'; +export { default as RangoExplorerIcon } from './RangoExplorer.js'; +export { default as RankIcon } from './Rank.js'; +export { default as RefreshIcon } from './Refresh.js'; +export { default as ReportIcon } from './Report.js'; +export { default as RequestIcon } from './Request.js'; +export { default as ReverseIcon } from './Reverse.js'; +export { default as RouteIcon } from './Route.js'; +export { default as ScannerIcon } from './Scanner.js'; +export { default as ScoreIcon } from './Score.js'; +export { default as SearchIcon } from './Search.js'; +export { default as ShareIcon } from './Share.js'; +export { default as SlippageIcon } from './Slippage.js'; +export { default as StatsIcon } from './Stats.js'; +export { default as SupportIcon } from './Support.js'; +export { default as SwapIcon } from './Swap.js'; +export { default as TargetIcon } from './Target.js'; +export { default as TimeIcon } from './Time.js'; +export { default as TransactionIcon } from './Transaction.js'; +export { default as TuneIcon } from './Tune.js'; +export { default as UtxoCategoryIcon } from './UtxoCategory.js'; +export { default as WalletIcon } from './Wallet.js'; +export { default as WarningIcon } from './Warning.js'; +export { default as WidgetIcon } from './Widget.js'; +export { default as WidthIcon } from './Width.js'; +export { default as BullhornIcon } from './Bullhorn.js'; +export { default as ChainsIcon } from './Chains.js'; +export { default as ChartIcon } from './Chart.js'; +export { default as ColorsIcon } from './Colors.js'; +export { default as DiscordIcon } from './Discord.js'; +export { default as InfinityIcon } from './Infinity.js'; +export { default as KeyIcon } from './Key.js'; +export { default as MediumIcon } from './Medium.js'; +export { default as SettingsIcon } from './Settings.js'; +export { default as StyleIcon } from './Style.js'; +export { default as TelegramIcon } from './Telegram.js'; +export { default as XIcon } from './X.js'; diff --git a/widget/ui/src/index.ts b/widget/ui/src/index.ts index 75b8e56c9e..bde13f12e6 100644 --- a/widget/ui/src/index.ts +++ b/widget/ui/src/index.ts @@ -1,4 +1,7 @@ -export * from './components'; -export * from './containers'; -export * from './theme'; -export * from './types'; +export * from './components/index.js'; +export * from './containers/index.js'; +export * from './theme.js'; +export * from './types/index.js'; +export * from './hooks/index.js'; +export * from './icons/index.js'; +export * from './constants/index.js'; diff --git a/widget/ui/src/theme.ts b/widget/ui/src/theme.ts index f4f9642691..a6da173b30 100644 --- a/widget/ui/src/theme.ts +++ b/widget/ui/src/theme.ts @@ -1,115 +1,177 @@ -// TSDX + stiches doesn't work with import statement and has a bug. +import type { + DefaultThemeMap, + PropertyValue, + CSS as StitchesCSS, +} from '@stitches/react'; -import { PropertyValue, CreateStitches } from '@stitches/react'; -import { DefaultThemeMap } from '@stitches/react/types/config'; - -// Solution: (https://github.com/stitchesjs/stitches/issues/833#issuecomment-950707025) -const { createStitches } = require('@stitches/react'); +import { createStitches } from '@stitches/react'; /* ----------------------- Values ----------------------- */ -const theme = { + +export const theme = { colors: { - primary: '#5FA425', - primary100: '#9FC87C', - primary200: '#8FBF66', - primary300: '#7FB651', - primary400: '#6FAD3B', - primary500: '#5FA425', - primary600: '#4C831E', - primary700: '#396216', - primary800: '#26420F', - primary900: '#132107', - neutrals200: '#FAFAFA', - neutrals300: '#EAEAEA', - neutrals400: '#999999', - neutrals500: '#888888', - neutrals600: '#666666', - neutrals700: '#444444', - neutrals800: '#333333', - neutrals900: '#111111', - background: '#fff', - foreground: '#000', - success: '#0070F3', - success100: '#D3E5FF', - success300: '#3291FF', - success500: '#0070F3', - success700: '#0761D1', - warning: '#F5A623', - warning100: '#FFEFCF', - warning300: '#F7B955', - warning500: '#F5A623', - warning700: '#AB570A', - error: '#FF0000', - error100: '#F7D4D6', - error300: '#FF3333', - error500: '#FF0000', - error700: '#E60000', - // Only use this color when you are going to use white for both dark and light theme. - white: '#fff', + primary: '#1C3CF1', + primary500: '#1C3CF1', + primary550: '#0B27C4', + + secondary: '#469BF5', + secondary100: '#E9F3FF', + secondary150: '#D6EAFF', + secondary200: '#C8E2FF', + secondary250: '#B5D9FF', + secondary500: '#469BF5', + secondary550: '#2284ED', + + neutral: '#E6E6E6', + neutral100: '#F9F9F9', + neutral200: '#F6F6F6', + neutral300: '#F2F2F2', + neutral400: '#EEEEEE', + neutral500: '#E6E6E6', + neutral600: '#A2A2A2', + neutral700: '#727272', + neutral800: '#1B1B1B', + neutral900: '#121212', + + error100: '#FDF3F3', + error300: '#FFD7D7', + error500: '#FF3B3B', + error600: '#432F2F', + error700: '#191212', + + warning100: '#FFF1D4', + warning300: '#FFD8B4', + warning500: '#F17606', + warning600: '#38271F', + warning700: '#1A1412', + + info: '#5BABFF', + info100: '#E9F3FF', + info300: '#C8E2FF', + info500: '#5BABFF', + info600: '#2E2E41', + info700: '#121521', + + success100: '#CEFAE6', + success300: '#BDECD7', + success500: '#06C270', + success600: '#1F2825', + success700: '#0F1412', + + background: '#FDFDFD', + foreground: '#010101', }, space: { + 0: '0rem', + 5: '0.313rem', + 10: '0.625rem', + 15: '0.938rem', + 20: '1.25rem', + 25: '1.563rem', + 30: '1.875rem', + 40: '2.5rem', + 46: '2.875rem', + 50: '3.125rem', + 60: '3.75rem', + 70: '4.375rem', + 80: '5rem', + 90: '5.625rem', + 100: '6.25rem', + + //These should be removed 2: '2px', 4: '4px', 6: '6px', 8: '8px', - 10: '10px', 12: '12px', 16: '16px', - 20: '20px', 24: '24px', 28: '28px', - 30: '30px', 32: '32px', + 36: '36px', + }, + + radii: { + xs: '5px', + sm: '10px', + xm: '15px', + md: '25px', + xl: '35px', + lg: '40px', + primary: '20px', + secondary: `$md`, }, + fontSizes: { - 10: '10px', - 12: '12px', - 14: '14px', - 16: '16px', - 18: '18px', - 20: '20px', - 24: '24px', - 32: '32px', - 36: '36px', - 40: '40px', - 48: '48px', + 10: '0.625rem', + 12: '0.75rem', + 14: '0.875rem', + 16: '1rem', + 18: '1.125rem', + 20: '1.25rem', + 22: '1.375rem', + 24: '1.5rem', + 28: '1.75rem', + 32: '2rem', + 36: '2.25rem', + 40: '2.5rem', + 48: '3rem', + }, + fonts: { + primary: 'Roboto', + widget: '$primary', }, - fonts: {}, fontWeights: { - 400: '400', - 500: '500', - 600: '600', - 700: '700', + regular: 400, + medium: 500, + semiBold: 600, + bold: 700, + }, + lineHeights: { + 12: '0.75rem', + 16: '1rem', + 20: '1.25rem', + 24: '1.5rem', + 26: '1.625rem', + 28: '1.75rem', + 30: '1.875rem', + 36: '2.25rem', + 40: '2.5rem', + 44: '2.75rem', + 52: '3.25rem', + 64: '4rem', }, - lineHeights: {}, letterSpacings: {}, sizes: { 4: '4px', 6: '6px', 8: '8px', + 10: '10px', 12: '12px', 16: '16px', + 18: '18px', 20: '20px', 24: '24px', + 26: '26px', 28: '28px', + 30: '30px', 32: '32px', 36: '36px', 40: '40px', + 45: '45px', 48: '48px', }, borderWidths: {}, borderStyles: {}, - radii: { - 5: '8px', - 10: '12px', - }, shadows: { - s: '0px 3px 5px 3px #f0f2f5, 0px 6px 10px 3px #f0f2f5, 0px 1px 18px 3px #f0f2f5', + /** Shadow for swap box */ + mainContainer: '15px 15px 15px 0px rgba(0, 0, 0, 0.05)', }, zIndices: {}, transitions: {}, }; const media = { + xs: '(min-width: 375px)', sm: '(min-width: 640px)', md: '(min-width: 768px)', lg: '(min-width: 1024px)', @@ -120,44 +182,59 @@ const utils = { }), }; +export const darkColors = { + secondary: '#2284ED', + secondary250: '#469BF5', + secondary500: '#2284ED', + secondary550: '#2B3462', + + neutral: '#222222', + neutral900: '#E9E9E9', + neutral800: '#E6E6E6', + neutral700: '#B8B8B8', + neutral600: '#A2A2A2', + neutral500: '#222222', + neutral400: '#1B1B1B', + neutral300: '#121212', + neutral200: '#111111', + neutral100: '#101010', + + error500: '#FF5050', + + warning500: '#FF8A20', + + background: '#010101', + foreground: '#FDFDFD', +}; + /* ----------------------- End of Values ----------------------- */ -const typedCreateStiches = createStitches as CreateStitches; - -// Note: it seems there is a bug on tsdx and when it compiles the code, it goes through an error -// We can directly check it with `tsc` to see if the error is correct or not. -// We `ignore` it for now, to get safety check on VSCode. -// @ts-ignore -export const { styled, css, createTheme, keyframes, globalCss } = - typedCreateStiches< - '', - typeof media, - typeof theme, - DefaultThemeMap, - // TODO: Make `utils` typesafe as well. - {} - >({ +export const { styled, css, createTheme, keyframes, globalCss, config } = + createStitches<'', typeof media, typeof theme, DefaultThemeMap>({ media, theme, utils, }); -export const lightTheme = createTheme({}); +export type CSS = StitchesCSS; -export const darkTheme = createTheme({ - colors: { - neutrals200: '#111111', - neutrals300: '#333333', - neutrals400: '#444444', - neutrals500: '#666666', - neutrals600: '#888888', - neutrals700: '#999999', - neutrals800: '#EAEAEA', - neutrals900: '#FAFAFA', - foreground: '#fff', - background: '#000', - }, - shadows: { - s: '0px 3px 5px 3px #222, 0px 6px 10px 3px #222, 0px 1px 18px 3px #222', - }, +export const lightTheme = createTheme('light-theme-ui', {}); + +export const darkTheme = createTheme('dark-theme-ui', { + colors: darkColors, }); + +export const rangoDarkColors = { + secondary800: '#242D5B', + secondary850: '#131C49', + neutral: '#161C38', + neutral100: '#101327', + neutral200: '#0D122C', + neutral300: '#0F142E', + neutral400: '#111733', + neutral500: '#161C38', + neutral800: '#B8B8B8', + neutral900: '#E9E9E9', + background: '#070917', + foreground: '#FDFDFD', +}; diff --git a/widget/ui/src/types/index.ts b/widget/ui/src/types/index.ts index 66329dcfa2..780d8442ef 100644 --- a/widget/ui/src/types/index.ts +++ b/widget/ui/src/types/index.ts @@ -1,3 +1,5 @@ -export * from './wallet'; - -export { BestRouteWithFee } from './swaps'; +export type { ConnectedWallet } from './wallet.js'; +export type { + SimulationAssetAndAmount, + SimulationValidationStatus, +} from './swaps.js'; diff --git a/widget/ui/src/types/meta.ts b/widget/ui/src/types/meta.ts deleted file mode 100644 index 5e0cb94e48..0000000000 --- a/widget/ui/src/types/meta.ts +++ /dev/null @@ -1,22 +0,0 @@ -export type TokenMeta = { - blockchain: string; - symbol: string; - image: string; - address: string | null; - usdPrice: number | null; - isSecondaryCoin: boolean; - coinSource: string | null; - coinSourceUrl: string | null; - name: string | null; - decimals: number; - balance?: { amount: string; usdPrice: string }; -}; - -export interface LiquiditySource { - title: string; - logo: string; - type: 'BRIDGE' | 'AGGREGATOR' | 'DEX'; - selected: boolean; -} - -export type LoadingStatus = 'loading' | 'success' | 'failed'; diff --git a/widget/ui/src/types/swaps.ts b/widget/ui/src/types/swaps.ts index 900c6e6d3b..d070b2ebc5 100644 --- a/widget/ui/src/types/swaps.ts +++ b/widget/ui/src/types/swaps.ts @@ -1,44 +1,7 @@ -import { - BestRouteResponse, +import type { BlockchainValidationStatus, - SimulationResult, - SwapResult, WalletRequiredAssets, -} from 'rango-sdk'; -export type SwapStatus = 'running' | 'failed' | 'success'; -export type MessageSeverity = 'error' | 'warning' | 'info' | 'success'; - -export type StepStatus = - | 'created' - | 'running' - | 'failed' - | 'success' - | 'waitingForApproval' - | 'approved'; - -export enum PendingSwapNetworkStatus { - WaitingForConnectingWallet = 'waitingForConnectingWallet', - WaitingForQueue = 'waitingForQueue', - WaitingForNetworkChange = 'waitingForNetworkChange', - NetworkChanged = 'networkChanged', -} - -export type WalletTypeAndAddress = { - walletType: string; - address: string; -}; -export type SwapSavedSettings = { - slippage: string; - disabledSwappersIds: string[]; - disabledSwappersGroups: string[]; -}; +} from 'rango-types/lib/api/main'; export type SimulationAssetAndAmount = WalletRequiredAssets; export type SimulationValidationStatus = BlockchainValidationStatus; -export type BestRouteType = BestRouteResponse; - -export type BestRouteWithFee = Omit & { - result: Omit & { - swaps: (SwapResult & { feeInUsd?: string })[]; - }; -}; diff --git a/widget/ui/src/types/wallet.ts b/widget/ui/src/types/wallet.ts index a10c036076..fc91620f2e 100644 --- a/widget/ui/src/types/wallet.ts +++ b/widget/ui/src/types/wallet.ts @@ -1,30 +1,26 @@ -import { InstallObjects, WalletType } from '@rango-dev/wallets-shared'; +import type { WalletType } from '@rango-dev/wallets-shared'; -export enum WalletState { - NOT_INSTALLED = 'not installed', - DISCONNECTED = 'disconnected', - CONNECTING = 'connecting', - CONNECTED = 'connected', +interface Wallet { + chain: string; + address: string; + walletType: WalletType; } -export type WalletInfo = { - state: - | WalletState.CONNECTED - | WalletState.DISCONNECTED - | WalletState.CONNECTING - | WalletState.NOT_INSTALLED; - installLink: InstallObjects | string; - name: string; - image: string; - type: WalletType; - showOnMobile: boolean; +export type TokenBalance = { + chain: string; + symbol: string; + ticker: string; + address: string | null; + rawAmount: string; + decimal: number | null; + amount: string; + logo: string | null; + usdPrice: number | null; }; -export interface SelectableWallet { - chain: string; - walletType: WalletType; - address: string; - image: string; - selected: boolean; - name: string; +export interface ConnectedWallet extends Wallet { + balances: TokenBalance[] | null; + loading: boolean; + error: boolean; + explorerUrl: string | null; } diff --git a/widget/ui/svgo.config.js b/widget/ui/svgo.config.js new file mode 100644 index 0000000000..c823c3503d --- /dev/null +++ b/widget/ui/svgo.config.js @@ -0,0 +1,23 @@ +module.exports = { + multsipass: true, // boolean. false by default + datauri: 'enc', // 'base64' (default), 'enc' or 'unenc'. + js2svg: { + indent: 2, // string with spaces or number of spaces. 4 by default + pretty: true // boolean, false by default + }, + plugins: [ + // set of built-in plugins enabled by default + 'preset-default', + + // enable built-in plugins by name + 'prefixIds', + + // or by expanded notation which allows to configure plugin + { + name: 'sortAttrs', + params: { + xmlnsOrdser: 'alphabetical' + } + } + ] +}; diff --git a/widget/ui/svgs/configs/.svgrrc.default.cjs b/widget/ui/svgs/configs/.svgrrc.default.cjs new file mode 100755 index 0000000000..c09faf5ae8 --- /dev/null +++ b/widget/ui/svgs/configs/.svgrrc.default.cjs @@ -0,0 +1,29 @@ +module.exports = { + jsx: { + babelConfig: { + plugins: [ + [ + '@svgr/babel-plugin-remove-jsx-attribute', + { + elements: ['svg'], + attributes: ['id', 'width', 'height', 'class', 'title', 'fill'], + }, + ], + ], + }, + }, + icon: false, + plugins: ['@svgr/plugin-jsx', '@svgr/plugin-prettier'], + typescript: true, + outDir: 'src/icons', + expandProps: false, + prettier: true, + filenameCase: 'pascal', + jsxRuntime: 'automatic', + replaceAttrValues: { + '#373737': 'currentColor', + '#010101': 'currentColor', + }, + template: require('./template/react.cjs'), + indexTemplate: require('./template/index.cjs'), +}; diff --git a/widget/ui/svgs/configs/template/index.cjs b/widget/ui/svgs/configs/template/index.cjs new file mode 100644 index 0000000000..e6192379f2 --- /dev/null +++ b/widget/ui/svgs/configs/template/index.cjs @@ -0,0 +1,12 @@ +const path = require('path'); + +function defaultIndexTemplate(filePaths) { + const exportEntries = filePaths.map(({ path: filePath }) => { + const basename = path.basename(filePath, path.extname(filePath)); + const exportName = /^\d/.test(basename) ? `Svg${basename}` : basename; + return `export { default as ${exportName}Icon } from './${basename}.js'`; + }); + return exportEntries.join('\n'); +} + +module.exports = defaultIndexTemplate; diff --git a/widget/ui/svgs/configs/template/react.cjs b/widget/ui/svgs/configs/template/react.cjs new file mode 100644 index 0000000000..9df11acb01 --- /dev/null +++ b/widget/ui/svgs/configs/template/react.cjs @@ -0,0 +1,19 @@ +const template = (variables, options) => { + return options.tpl` + import React, {createElement} from 'react'; + import type {SvgIconPropsWithChildren} from '../components/SvgIcon/index.js'; + import {SvgIcon} from '../components/SvgIcon/index.js'; + + ${variables.imports}; + + ${variables.interfaces}; + + function ${variables.componentName}(props: SvgIconPropsWithChildren){ + return createElement(SvgIcon, props, ${variables.jsx}) + } + + ${variables.exports}; + `; +}; + +module.exports = template; diff --git a/widget/ui/svgs/resources/fill/Add.svg b/widget/ui/svgs/resources/fill/Add.svg new file mode 100644 index 0000000000..a336b64d24 --- /dev/null +++ b/widget/ui/svgs/resources/fill/Add.svg @@ -0,0 +1,4 @@ + + + + diff --git a/widget/ui/svgs/resources/fill/Affiliate.svg b/widget/ui/svgs/resources/fill/Affiliate.svg new file mode 100644 index 0000000000..6b1946eda1 --- /dev/null +++ b/widget/ui/svgs/resources/fill/Affiliate.svg @@ -0,0 +1,3 @@ + + + diff --git a/widget/ui/svgs/resources/fill/Auto-Theme.svg b/widget/ui/svgs/resources/fill/Auto-Theme.svg new file mode 100644 index 0000000000..fffab7386c --- /dev/null +++ b/widget/ui/svgs/resources/fill/Auto-Theme.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/widget/ui/svgs/resources/fill/Autorenew.svg b/widget/ui/svgs/resources/fill/Autorenew.svg new file mode 100644 index 0000000000..7ce671d06b --- /dev/null +++ b/widget/ui/svgs/resources/fill/Autorenew.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/widget/ui/svgs/resources/fill/Border-Radius.svg b/widget/ui/svgs/resources/fill/Border-Radius.svg new file mode 100644 index 0000000000..3962fbd4a1 --- /dev/null +++ b/widget/ui/svgs/resources/fill/Border-Radius.svg @@ -0,0 +1,8 @@ + + + + + + \ No newline at end of file diff --git a/widget/ui/svgs/resources/fill/Bridges.svg b/widget/ui/svgs/resources/fill/Bridges.svg new file mode 100644 index 0000000000..12448fc0e9 --- /dev/null +++ b/widget/ui/svgs/resources/fill/Bridges.svg @@ -0,0 +1,3 @@ + + + diff --git a/widget/ui/svgs/resources/fill/BugReport.svg b/widget/ui/svgs/resources/fill/BugReport.svg new file mode 100644 index 0000000000..4cf785c986 --- /dev/null +++ b/widget/ui/svgs/resources/fill/BugReport.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/widget/ui/svgs/resources/fill/Calendar.svg b/widget/ui/svgs/resources/fill/Calendar.svg new file mode 100644 index 0000000000..14e15c6ccf --- /dev/null +++ b/widget/ui/svgs/resources/fill/Calendar.svg @@ -0,0 +1,14 @@ + + + + + + \ No newline at end of file diff --git a/widget/ui/svgs/resources/fill/Chevron-Down.svg b/widget/ui/svgs/resources/fill/Chevron-Down.svg new file mode 100644 index 0000000000..972e0abebf --- /dev/null +++ b/widget/ui/svgs/resources/fill/Chevron-Down.svg @@ -0,0 +1,3 @@ + + + diff --git a/widget/ui/svgs/resources/fill/Chevron-Left.svg b/widget/ui/svgs/resources/fill/Chevron-Left.svg new file mode 100644 index 0000000000..679ee1b58a --- /dev/null +++ b/widget/ui/svgs/resources/fill/Chevron-Left.svg @@ -0,0 +1,3 @@ + + + diff --git a/widget/ui/svgs/resources/fill/Chevron-Right.svg b/widget/ui/svgs/resources/fill/Chevron-Right.svg new file mode 100644 index 0000000000..0104f355c9 --- /dev/null +++ b/widget/ui/svgs/resources/fill/Chevron-Right.svg @@ -0,0 +1,3 @@ + + + diff --git a/widget/ui/svgs/resources/fill/Chevron-Up.svg b/widget/ui/svgs/resources/fill/Chevron-Up.svg new file mode 100644 index 0000000000..b6b8d3e78a --- /dev/null +++ b/widget/ui/svgs/resources/fill/Chevron-Up.svg @@ -0,0 +1,3 @@ + + + diff --git a/widget/ui/svgs/resources/fill/Close.svg b/widget/ui/svgs/resources/fill/Close.svg new file mode 100644 index 0000000000..954243b0f7 --- /dev/null +++ b/widget/ui/svgs/resources/fill/Close.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/widget/ui/svgs/resources/fill/Complete.svg b/widget/ui/svgs/resources/fill/Complete.svg new file mode 100644 index 0000000000..fbed0b6539 --- /dev/null +++ b/widget/ui/svgs/resources/fill/Complete.svg @@ -0,0 +1,3 @@ + + + diff --git a/widget/ui/svgs/resources/fill/Cookie.svg b/widget/ui/svgs/resources/fill/Cookie.svg new file mode 100644 index 0000000000..6a4a945968 --- /dev/null +++ b/widget/ui/svgs/resources/fill/Cookie.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/widget/ui/svgs/resources/fill/Copy.svg b/widget/ui/svgs/resources/fill/Copy.svg new file mode 100644 index 0000000000..24591f50a5 --- /dev/null +++ b/widget/ui/svgs/resources/fill/Copy.svg @@ -0,0 +1,3 @@ + + + diff --git a/widget/ui/svgs/resources/fill/CosmosCategory.svg b/widget/ui/svgs/resources/fill/CosmosCategory.svg new file mode 100644 index 0000000000..082ae1fd74 --- /dev/null +++ b/widget/ui/svgs/resources/fill/CosmosCategory.svg @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/widget/ui/svgs/resources/fill/CreditCard.svg b/widget/ui/svgs/resources/fill/CreditCard.svg new file mode 100644 index 0000000000..00c541660f --- /dev/null +++ b/widget/ui/svgs/resources/fill/CreditCard.svg @@ -0,0 +1,4 @@ + + + + diff --git a/widget/ui/svgs/resources/fill/Custom-Colors.svg b/widget/ui/svgs/resources/fill/Custom-Colors.svg new file mode 100644 index 0000000000..b56adbbfb7 --- /dev/null +++ b/widget/ui/svgs/resources/fill/Custom-Colors.svg @@ -0,0 +1,3 @@ + + + diff --git a/widget/ui/svgs/resources/fill/CustomTokensZeroState.svg b/widget/ui/svgs/resources/fill/CustomTokensZeroState.svg new file mode 100644 index 0000000000..c7c737d6f4 --- /dev/null +++ b/widget/ui/svgs/resources/fill/CustomTokensZeroState.svg @@ -0,0 +1,97 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/widget/ui/svgs/resources/fill/CustomTokensZeroStateDark.svg b/widget/ui/svgs/resources/fill/CustomTokensZeroStateDark.svg new file mode 100644 index 0000000000..2afd5190b4 --- /dev/null +++ b/widget/ui/svgs/resources/fill/CustomTokensZeroStateDark.svg @@ -0,0 +1,112 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/widget/ui/svgs/resources/fill/CustomerSupport.svg b/widget/ui/svgs/resources/fill/CustomerSupport.svg new file mode 100644 index 0000000000..5aadcabe9b --- /dev/null +++ b/widget/ui/svgs/resources/fill/CustomerSupport.svg @@ -0,0 +1,3 @@ + + + diff --git a/widget/ui/svgs/resources/fill/Dark-Mode.svg b/widget/ui/svgs/resources/fill/Dark-Mode.svg new file mode 100644 index 0000000000..6639f00317 --- /dev/null +++ b/widget/ui/svgs/resources/fill/Dark-Mode.svg @@ -0,0 +1,3 @@ + + + diff --git a/widget/ui/svgs/resources/fill/Delete.svg b/widget/ui/svgs/resources/fill/Delete.svg new file mode 100644 index 0000000000..384a4ec727 --- /dev/null +++ b/widget/ui/svgs/resources/fill/Delete.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/widget/ui/svgs/resources/fill/Desktop.svg b/widget/ui/svgs/resources/fill/Desktop.svg new file mode 100644 index 0000000000..061bbc2064 --- /dev/null +++ b/widget/ui/svgs/resources/fill/Desktop.svg @@ -0,0 +1,98 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/widget/ui/svgs/resources/fill/Disconnect.svg b/widget/ui/svgs/resources/fill/Disconnect.svg new file mode 100644 index 0000000000..5b4ecfe1e7 --- /dev/null +++ b/widget/ui/svgs/resources/fill/Disconnect.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/widget/ui/svgs/resources/fill/Document.svg b/widget/ui/svgs/resources/fill/Document.svg new file mode 100644 index 0000000000..5af1f762b8 --- /dev/null +++ b/widget/ui/svgs/resources/fill/Document.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/widget/ui/svgs/resources/fill/Documentation.svg b/widget/ui/svgs/resources/fill/Documentation.svg new file mode 100644 index 0000000000..8bfeaab39a --- /dev/null +++ b/widget/ui/svgs/resources/fill/Documentation.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/widget/ui/svgs/resources/fill/Done.svg b/widget/ui/svgs/resources/fill/Done.svg new file mode 100644 index 0000000000..cfb4c2e155 --- /dev/null +++ b/widget/ui/svgs/resources/fill/Done.svg @@ -0,0 +1,3 @@ + + + diff --git a/widget/ui/svgs/resources/fill/EVMCategory.svg b/widget/ui/svgs/resources/fill/EVMCategory.svg new file mode 100644 index 0000000000..2727a37e0d --- /dev/null +++ b/widget/ui/svgs/resources/fill/EVMCategory.svg @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/widget/ui/svgs/resources/fill/Error.svg b/widget/ui/svgs/resources/fill/Error.svg new file mode 100644 index 0000000000..d2df43391d --- /dev/null +++ b/widget/ui/svgs/resources/fill/Error.svg @@ -0,0 +1,3 @@ + + + diff --git a/widget/ui/svgs/resources/fill/Exchange.svg b/widget/ui/svgs/resources/fill/Exchange.svg new file mode 100644 index 0000000000..3b032d5012 --- /dev/null +++ b/widget/ui/svgs/resources/fill/Exchange.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/widget/ui/svgs/resources/fill/Exit.svg b/widget/ui/svgs/resources/fill/Exit.svg new file mode 100644 index 0000000000..b1ea8bac77 --- /dev/null +++ b/widget/ui/svgs/resources/fill/Exit.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/widget/ui/svgs/resources/fill/Explorer.svg b/widget/ui/svgs/resources/fill/Explorer.svg new file mode 100644 index 0000000000..8dc5ab6217 --- /dev/null +++ b/widget/ui/svgs/resources/fill/Explorer.svg @@ -0,0 +1,3 @@ + + + diff --git a/widget/ui/svgs/resources/fill/External link.svg b/widget/ui/svgs/resources/fill/External link.svg new file mode 100644 index 0000000000..9cef99dd33 --- /dev/null +++ b/widget/ui/svgs/resources/fill/External link.svg @@ -0,0 +1,3 @@ + + + diff --git a/widget/ui/svgs/resources/fill/FeatureList.svg b/widget/ui/svgs/resources/fill/FeatureList.svg new file mode 100644 index 0000000000..89d12bf905 --- /dev/null +++ b/widget/ui/svgs/resources/fill/FeatureList.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/widget/ui/svgs/resources/fill/Filter.svg b/widget/ui/svgs/resources/fill/Filter.svg new file mode 100644 index 0000000000..9069318259 --- /dev/null +++ b/widget/ui/svgs/resources/fill/Filter.svg @@ -0,0 +1,3 @@ + + + diff --git a/widget/ui/svgs/resources/fill/First.svg b/widget/ui/svgs/resources/fill/First.svg new file mode 100644 index 0000000000..2d1bfec1d5 --- /dev/null +++ b/widget/ui/svgs/resources/fill/First.svg @@ -0,0 +1,8 @@ + + + + \ No newline at end of file diff --git a/widget/ui/svgs/resources/fill/Font.svg b/widget/ui/svgs/resources/fill/Font.svg new file mode 100644 index 0000000000..eb541b2c97 --- /dev/null +++ b/widget/ui/svgs/resources/fill/Font.svg @@ -0,0 +1,16 @@ + + + + + + + + + + \ No newline at end of file diff --git a/widget/ui/svgs/resources/fill/Gas.svg b/widget/ui/svgs/resources/fill/Gas.svg new file mode 100644 index 0000000000..1aef32abd2 --- /dev/null +++ b/widget/ui/svgs/resources/fill/Gas.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/widget/ui/svgs/resources/fill/Height.svg b/widget/ui/svgs/resources/fill/Height.svg new file mode 100644 index 0000000000..396fc34dc5 --- /dev/null +++ b/widget/ui/svgs/resources/fill/Height.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/widget/ui/svgs/resources/fill/InProgress.svg b/widget/ui/svgs/resources/fill/InProgress.svg new file mode 100644 index 0000000000..579c0af8d6 --- /dev/null +++ b/widget/ui/svgs/resources/fill/InProgress.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/widget/ui/svgs/resources/fill/Info-Error.svg b/widget/ui/svgs/resources/fill/Info-Error.svg new file mode 100644 index 0000000000..a3eef53ece --- /dev/null +++ b/widget/ui/svgs/resources/fill/Info-Error.svg @@ -0,0 +1,3 @@ + + + diff --git a/widget/ui/svgs/resources/fill/Info.svg b/widget/ui/svgs/resources/fill/Info.svg new file mode 100644 index 0000000000..26ac26cdd1 --- /dev/null +++ b/widget/ui/svgs/resources/fill/Info.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/widget/ui/svgs/resources/fill/Language.svg b/widget/ui/svgs/resources/fill/Language.svg new file mode 100644 index 0000000000..0168632773 --- /dev/null +++ b/widget/ui/svgs/resources/fill/Language.svg @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/widget/ui/svgs/resources/fill/Last.svg b/widget/ui/svgs/resources/fill/Last.svg new file mode 100644 index 0000000000..833a5d9578 --- /dev/null +++ b/widget/ui/svgs/resources/fill/Last.svg @@ -0,0 +1,8 @@ + + + + \ No newline at end of file diff --git a/widget/ui/svgs/resources/fill/Legacy.svg b/widget/ui/svgs/resources/fill/Legacy.svg new file mode 100644 index 0000000000..dda0950334 --- /dev/null +++ b/widget/ui/svgs/resources/fill/Legacy.svg @@ -0,0 +1,4 @@ + + + + diff --git a/widget/ui/svgs/resources/fill/Light-Mode.svg b/widget/ui/svgs/resources/fill/Light-Mode.svg new file mode 100644 index 0000000000..303a404da8 --- /dev/null +++ b/widget/ui/svgs/resources/fill/Light-Mode.svg @@ -0,0 +1,3 @@ + + + diff --git a/widget/ui/svgs/resources/fill/Link.svg b/widget/ui/svgs/resources/fill/Link.svg new file mode 100644 index 0000000000..9a064be592 --- /dev/null +++ b/widget/ui/svgs/resources/fill/Link.svg @@ -0,0 +1,3 @@ + + + diff --git a/widget/ui/svgs/resources/fill/Loading.svg b/widget/ui/svgs/resources/fill/Loading.svg new file mode 100644 index 0000000000..6a14fa68cd --- /dev/null +++ b/widget/ui/svgs/resources/fill/Loading.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/widget/ui/svgs/resources/fill/LogoWithText.svg b/widget/ui/svgs/resources/fill/LogoWithText.svg new file mode 100644 index 0000000000..e8eae06e6e --- /dev/null +++ b/widget/ui/svgs/resources/fill/LogoWithText.svg @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/widget/ui/svgs/resources/fill/Logout.svg b/widget/ui/svgs/resources/fill/Logout.svg new file mode 100644 index 0000000000..3d8b6a1516 --- /dev/null +++ b/widget/ui/svgs/resources/fill/Logout.svg @@ -0,0 +1,12 @@ + + + + + + + + + + \ No newline at end of file diff --git a/widget/ui/svgs/resources/fill/Menu.svg b/widget/ui/svgs/resources/fill/Menu.svg new file mode 100644 index 0000000000..04b78df617 --- /dev/null +++ b/widget/ui/svgs/resources/fill/Menu.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/widget/ui/svgs/resources/fill/More.svg b/widget/ui/svgs/resources/fill/More.svg new file mode 100644 index 0000000000..0d899f4b05 --- /dev/null +++ b/widget/ui/svgs/resources/fill/More.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/widget/ui/svgs/resources/fill/NO-Route.svg b/widget/ui/svgs/resources/fill/NO-Route.svg new file mode 100644 index 0000000000..b2d3367948 --- /dev/null +++ b/widget/ui/svgs/resources/fill/NO-Route.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/widget/ui/svgs/resources/fill/Next.svg b/widget/ui/svgs/resources/fill/Next.svg new file mode 100644 index 0000000000..5a874922c1 --- /dev/null +++ b/widget/ui/svgs/resources/fill/Next.svg @@ -0,0 +1,3 @@ + + + diff --git a/widget/ui/svgs/resources/fill/NoNotification.svg b/widget/ui/svgs/resources/fill/NoNotification.svg new file mode 100644 index 0000000000..97d5c520ae --- /dev/null +++ b/widget/ui/svgs/resources/fill/NoNotification.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/widget/ui/svgs/resources/fill/NotificationNumber.svg b/widget/ui/svgs/resources/fill/NotificationNumber.svg new file mode 100644 index 0000000000..891a9acec1 --- /dev/null +++ b/widget/ui/svgs/resources/fill/NotificationNumber.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/widget/ui/svgs/resources/fill/Notifications.svg b/widget/ui/svgs/resources/fill/Notifications.svg new file mode 100644 index 0000000000..6b48517d35 --- /dev/null +++ b/widget/ui/svgs/resources/fill/Notifications.svg @@ -0,0 +1,3 @@ + + + diff --git a/widget/ui/svgs/resources/fill/Number.svg b/widget/ui/svgs/resources/fill/Number.svg new file mode 100644 index 0000000000..91967d5d86 --- /dev/null +++ b/widget/ui/svgs/resources/fill/Number.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/widget/ui/svgs/resources/fill/NumberBlocks.svg b/widget/ui/svgs/resources/fill/NumberBlocks.svg new file mode 100644 index 0000000000..c2f3e8a23a --- /dev/null +++ b/widget/ui/svgs/resources/fill/NumberBlocks.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/widget/ui/svgs/resources/fill/OtherCategory.svg b/widget/ui/svgs/resources/fill/OtherCategory.svg new file mode 100644 index 0000000000..10600f4805 --- /dev/null +++ b/widget/ui/svgs/resources/fill/OtherCategory.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/widget/ui/svgs/resources/fill/Paste.svg b/widget/ui/svgs/resources/fill/Paste.svg new file mode 100644 index 0000000000..2b84a366cb --- /dev/null +++ b/widget/ui/svgs/resources/fill/Paste.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/widget/ui/svgs/resources/fill/Pin.svg b/widget/ui/svgs/resources/fill/Pin.svg new file mode 100644 index 0000000000..617dcc36c8 --- /dev/null +++ b/widget/ui/svgs/resources/fill/Pin.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/widget/ui/svgs/resources/fill/Profile.svg b/widget/ui/svgs/resources/fill/Profile.svg new file mode 100644 index 0000000000..c6fceb2592 --- /dev/null +++ b/widget/ui/svgs/resources/fill/Profile.svg @@ -0,0 +1,3 @@ + + + diff --git a/widget/ui/svgs/resources/fill/RangoExplorer.svg b/widget/ui/svgs/resources/fill/RangoExplorer.svg new file mode 100644 index 0000000000..f49146f400 --- /dev/null +++ b/widget/ui/svgs/resources/fill/RangoExplorer.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + diff --git a/widget/ui/svgs/resources/fill/Rank.svg b/widget/ui/svgs/resources/fill/Rank.svg new file mode 100644 index 0000000000..3c6cf356ab --- /dev/null +++ b/widget/ui/svgs/resources/fill/Rank.svg @@ -0,0 +1,8 @@ + + + + \ No newline at end of file diff --git a/widget/ui/svgs/resources/fill/Refresh.svg b/widget/ui/svgs/resources/fill/Refresh.svg new file mode 100644 index 0000000000..22f7079e6e --- /dev/null +++ b/widget/ui/svgs/resources/fill/Refresh.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/widget/ui/svgs/resources/fill/Report.svg b/widget/ui/svgs/resources/fill/Report.svg new file mode 100644 index 0000000000..3b86d7f1a3 --- /dev/null +++ b/widget/ui/svgs/resources/fill/Report.svg @@ -0,0 +1,3 @@ + + + diff --git a/widget/ui/svgs/resources/fill/Request.svg b/widget/ui/svgs/resources/fill/Request.svg new file mode 100644 index 0000000000..88ca235c54 --- /dev/null +++ b/widget/ui/svgs/resources/fill/Request.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/widget/ui/svgs/resources/fill/Reverse.svg b/widget/ui/svgs/resources/fill/Reverse.svg new file mode 100644 index 0000000000..06ea861627 --- /dev/null +++ b/widget/ui/svgs/resources/fill/Reverse.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/widget/ui/svgs/resources/fill/Route.svg b/widget/ui/svgs/resources/fill/Route.svg new file mode 100644 index 0000000000..181ce33f6a --- /dev/null +++ b/widget/ui/svgs/resources/fill/Route.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/widget/ui/svgs/resources/fill/Scanner.svg b/widget/ui/svgs/resources/fill/Scanner.svg new file mode 100644 index 0000000000..ac48b158bf --- /dev/null +++ b/widget/ui/svgs/resources/fill/Scanner.svg @@ -0,0 +1,4 @@ + + + + diff --git a/widget/ui/svgs/resources/fill/Score.svg b/widget/ui/svgs/resources/fill/Score.svg new file mode 100644 index 0000000000..3f11ed0504 --- /dev/null +++ b/widget/ui/svgs/resources/fill/Score.svg @@ -0,0 +1,14 @@ + + + + + + \ No newline at end of file diff --git a/widget/ui/svgs/resources/fill/Search.svg b/widget/ui/svgs/resources/fill/Search.svg new file mode 100644 index 0000000000..86abae5411 --- /dev/null +++ b/widget/ui/svgs/resources/fill/Search.svg @@ -0,0 +1,4 @@ + + + + diff --git a/widget/ui/svgs/resources/fill/Share.svg b/widget/ui/svgs/resources/fill/Share.svg new file mode 100644 index 0000000000..8cc76e7b8d --- /dev/null +++ b/widget/ui/svgs/resources/fill/Share.svg @@ -0,0 +1,12 @@ + + + + + + + + + + \ No newline at end of file diff --git a/widget/ui/svgs/resources/fill/Slippage.svg b/widget/ui/svgs/resources/fill/Slippage.svg new file mode 100644 index 0000000000..4d71c7673a --- /dev/null +++ b/widget/ui/svgs/resources/fill/Slippage.svg @@ -0,0 +1,3 @@ + + + diff --git a/widget/ui/svgs/resources/fill/Stats.svg b/widget/ui/svgs/resources/fill/Stats.svg new file mode 100644 index 0000000000..22436c1be9 --- /dev/null +++ b/widget/ui/svgs/resources/fill/Stats.svg @@ -0,0 +1,12 @@ + + + + + + + + + + \ No newline at end of file diff --git a/widget/ui/svgs/resources/fill/Support.svg b/widget/ui/svgs/resources/fill/Support.svg new file mode 100644 index 0000000000..067b4c1890 --- /dev/null +++ b/widget/ui/svgs/resources/fill/Support.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/widget/ui/svgs/resources/fill/Swap.svg b/widget/ui/svgs/resources/fill/Swap.svg new file mode 100644 index 0000000000..67c17022f0 --- /dev/null +++ b/widget/ui/svgs/resources/fill/Swap.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/widget/ui/svgs/resources/fill/Target.svg b/widget/ui/svgs/resources/fill/Target.svg new file mode 100644 index 0000000000..96a6cc2686 --- /dev/null +++ b/widget/ui/svgs/resources/fill/Target.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/widget/ui/svgs/resources/fill/Time.svg b/widget/ui/svgs/resources/fill/Time.svg new file mode 100644 index 0000000000..cc3765a124 --- /dev/null +++ b/widget/ui/svgs/resources/fill/Time.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/widget/ui/svgs/resources/fill/Transaction.svg b/widget/ui/svgs/resources/fill/Transaction.svg new file mode 100644 index 0000000000..116a4bc17b --- /dev/null +++ b/widget/ui/svgs/resources/fill/Transaction.svg @@ -0,0 +1,3 @@ + + + diff --git a/widget/ui/svgs/resources/fill/Tune.svg b/widget/ui/svgs/resources/fill/Tune.svg new file mode 100644 index 0000000000..082833d84a --- /dev/null +++ b/widget/ui/svgs/resources/fill/Tune.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/widget/ui/svgs/resources/fill/UTXOCategory.svg b/widget/ui/svgs/resources/fill/UTXOCategory.svg new file mode 100644 index 0000000000..24b6038fd6 --- /dev/null +++ b/widget/ui/svgs/resources/fill/UTXOCategory.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/widget/ui/svgs/resources/fill/Wallet.svg b/widget/ui/svgs/resources/fill/Wallet.svg new file mode 100644 index 0000000000..9f1bb3c326 --- /dev/null +++ b/widget/ui/svgs/resources/fill/Wallet.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/widget/ui/svgs/resources/fill/Warning.svg b/widget/ui/svgs/resources/fill/Warning.svg new file mode 100644 index 0000000000..761295ddeb --- /dev/null +++ b/widget/ui/svgs/resources/fill/Warning.svg @@ -0,0 +1,3 @@ + + + diff --git a/widget/ui/svgs/resources/fill/Widget.svg b/widget/ui/svgs/resources/fill/Widget.svg new file mode 100644 index 0000000000..45feade62d --- /dev/null +++ b/widget/ui/svgs/resources/fill/Widget.svg @@ -0,0 +1,8 @@ + + + + + + \ No newline at end of file diff --git a/widget/ui/svgs/resources/fill/Width.svg b/widget/ui/svgs/resources/fill/Width.svg new file mode 100644 index 0000000000..6892bd98bb --- /dev/null +++ b/widget/ui/svgs/resources/fill/Width.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/widget/ui/svgs/resources/fill/bullhorn.svg b/widget/ui/svgs/resources/fill/bullhorn.svg new file mode 100644 index 0000000000..c30c507fbb --- /dev/null +++ b/widget/ui/svgs/resources/fill/bullhorn.svg @@ -0,0 +1,7 @@ + + + + + \ No newline at end of file diff --git a/widget/ui/svgs/resources/fill/chains.svg b/widget/ui/svgs/resources/fill/chains.svg new file mode 100644 index 0000000000..7b9ca5f108 --- /dev/null +++ b/widget/ui/svgs/resources/fill/chains.svg @@ -0,0 +1,3 @@ + + + diff --git a/widget/ui/svgs/resources/fill/chart.svg b/widget/ui/svgs/resources/fill/chart.svg new file mode 100644 index 0000000000..87ad4a422a --- /dev/null +++ b/widget/ui/svgs/resources/fill/chart.svg @@ -0,0 +1,3 @@ + + + diff --git a/widget/ui/svgs/resources/fill/colors.svg b/widget/ui/svgs/resources/fill/colors.svg new file mode 100644 index 0000000000..19139d9b7b --- /dev/null +++ b/widget/ui/svgs/resources/fill/colors.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/widget/ui/svgs/resources/fill/discord.svg b/widget/ui/svgs/resources/fill/discord.svg new file mode 100644 index 0000000000..ede3ffc8d2 --- /dev/null +++ b/widget/ui/svgs/resources/fill/discord.svg @@ -0,0 +1,5 @@ + + + \ No newline at end of file diff --git a/widget/ui/svgs/resources/fill/infinity.svg b/widget/ui/svgs/resources/fill/infinity.svg new file mode 100644 index 0000000000..bbe3c0af80 --- /dev/null +++ b/widget/ui/svgs/resources/fill/infinity.svg @@ -0,0 +1,3 @@ + + + diff --git a/widget/ui/svgs/resources/fill/key.svg b/widget/ui/svgs/resources/fill/key.svg new file mode 100644 index 0000000000..03a4b2f9d6 --- /dev/null +++ b/widget/ui/svgs/resources/fill/key.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/widget/ui/svgs/resources/fill/medium.svg b/widget/ui/svgs/resources/fill/medium.svg new file mode 100644 index 0000000000..eade513699 --- /dev/null +++ b/widget/ui/svgs/resources/fill/medium.svg @@ -0,0 +1,3 @@ + + + diff --git a/widget/ui/svgs/resources/fill/settings.svg b/widget/ui/svgs/resources/fill/settings.svg new file mode 100644 index 0000000000..adab922ed4 --- /dev/null +++ b/widget/ui/svgs/resources/fill/settings.svg @@ -0,0 +1,3 @@ + + + diff --git a/widget/ui/svgs/resources/fill/style.svg b/widget/ui/svgs/resources/fill/style.svg new file mode 100644 index 0000000000..fe645c68aa --- /dev/null +++ b/widget/ui/svgs/resources/fill/style.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/widget/ui/svgs/resources/fill/telegram.svg b/widget/ui/svgs/resources/fill/telegram.svg new file mode 100644 index 0000000000..e24404ca36 --- /dev/null +++ b/widget/ui/svgs/resources/fill/telegram.svg @@ -0,0 +1,3 @@ + + + diff --git a/widget/ui/svgs/resources/fill/x.svg b/widget/ui/svgs/resources/fill/x.svg new file mode 100644 index 0000000000..86d8dbcdc2 --- /dev/null +++ b/widget/ui/svgs/resources/fill/x.svg @@ -0,0 +1,3 @@ + + + diff --git a/widget/ui/tsconfig.build.json b/widget/ui/tsconfig.build.json new file mode 100644 index 0000000000..f824dbc370 --- /dev/null +++ b/widget/ui/tsconfig.build.json @@ -0,0 +1,12 @@ +{ + "extends": "../../tsconfig.lib.json", + "include": ["src", "types"], + "compilerOptions": { + "outDir": "dist", + "lib": ["dom", "esnext"], + "baseUrl": ".", + "rootDirs": ["./src", "../../../translations"], + "jsx": "react", + "verbatimModuleSyntax": true + } +} diff --git a/widget/ui/tsconfig.json b/widget/ui/tsconfig.json index 2c85b2d991..a3a0b0f59d 100644 --- a/widget/ui/tsconfig.json +++ b/widget/ui/tsconfig.json @@ -1,35 +1 @@ -{ - // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs - "include": ["src", "types"], - "compilerOptions": { - "module": "esnext", - "lib": ["dom", "esnext"], - "importHelpers": true, - // output .d.ts declaration files for consumers - "declaration": true, - // output .js.map sourcemap files for consumers - "sourceMap": true, - // match output dir to input dir. e.g. dist/index instead of dist/src/index - "rootDir": "./src", - // stricter type-checking for stronger correctness. Recommended by TS - "strict": true, - // linter checks for common issues - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true, - // noUnused* overlap with @typescript-eslint/no-unused-vars, can disable if duplicative - "noUnusedLocals": true, - "noUnusedParameters": true, - // use Node's module resolution algorithm, instead of the legacy TS one - "moduleResolution": "node", - // transpile JSX to React.createElement - "jsx": "react", - // interop between ESM and CJS modules. Recommended by TS - "esModuleInterop": true, - // significant perf increase by skipping checking .d.ts files, particularly those in node_modules. Recommended by TS - "skipLibCheck": true, - // error out if import and file system have a casing mismatch. Recommended by TS - "forceConsistentCasingInFileNames": true, - // `tsdx build` ignores this option, but it is commonly used when type-checking separately with `tsc` - "noEmit": true, - } -} +{ "extends": "./tsconfig.build.json", "include": ["src", "tests"] } diff --git a/yarn.lock b/yarn.lock index 1377239dea..478d05a99b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,502 +2,675 @@ # yarn lockfile v1 -"@ampproject/remapping@^2.2.0": - version "2.2.0" - resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.0.tgz#56c133824780de3174aed5ab6834f3026790154d" - integrity sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w== +"@aashutoshrathi/word-wrap@^1.2.3": + version "1.2.6" + resolved "https://registry.yarnpkg.com/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz#bd9154aec9983f77b3a034ecaa015c2e4201f6cf" + integrity sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA== + +"@actions/core@^1.10.1": + version "1.10.1" + resolved "https://registry.yarnpkg.com/@actions/core/-/core-1.10.1.tgz#61108e7ac40acae95ee36da074fa5850ca4ced8a" + integrity sha512-3lBR9EDAY+iYIpTnTIXmWcNbX3T2kCkAEQGIQx4NVQ0575nk2k3GRZDTPQG+vVtS2izSLmINlxXf0uLtnrTP+g== dependencies: - "@jridgewell/gen-mapping" "^0.1.0" - "@jridgewell/trace-mapping" "^0.3.9" + "@actions/http-client" "^2.0.1" + uuid "^8.3.2" -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.18.6", "@babel/code-frame@^7.21.4", "@babel/code-frame@^7.5.5", "@babel/code-frame@^7.8.3": - version "7.21.4" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.21.4.tgz#d0fa9e4413aca81f2b23b9442797bda1826edb39" - integrity sha512-LYvhNKfwWSPpocw8GI7gpK2nq3HSDuEPC/uSYaALSJu9xjsalaaYFOq0Pwt5KmVqwEbZlDu81aLXwBOmD/Fv9g== +"@actions/http-client@^2.0.1": + version "2.2.1" + resolved "https://registry.yarnpkg.com/@actions/http-client/-/http-client-2.2.1.tgz#ed3fe7a5a6d317ac1d39886b0bb999ded229bb38" + integrity sha512-KhC/cZsq7f8I4LfZSJKgCvEwfkE8o1538VoBeoGzokVLLnbFDEAdFD3UhoMklxo2un9NJVBdANOresx7vTHlHw== dependencies: - "@babel/highlight" "^7.18.6" + tunnel "^0.0.6" + undici "^5.25.4" -"@babel/compat-data@^7.17.7", "@babel/compat-data@^7.20.5", "@babel/compat-data@^7.21.4": - version "7.21.4" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.21.4.tgz#457ffe647c480dff59c2be092fc3acf71195c87f" - integrity sha512-/DYyDpeCfaVinT40FPGdkkb+lYSKvsVuMjDAG7jPOWWiM1ibOaB9CXJAlc4d1QpP/U2q2P9jbrSlClKSErd55g== +"@adraffy/ens-normalize@1.10.0": + version "1.10.0" + resolved "https://registry.yarnpkg.com/@adraffy/ens-normalize/-/ens-normalize-1.10.0.tgz#d2a39395c587e092d77cbbc80acf956a54f38bf7" + integrity sha512-nA9XHtlAkYfJxY7bce8DcN7eKxWWCWkU+1GR9d+U6MbNpfwQp8TI7vqOsBsMcHoT4mBu2kypKoSKnghEzOOq5Q== -"@babel/core@7.12.9": - version "7.12.9" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.12.9.tgz#fd450c4ec10cdbb980e2928b7aa7a28484593fc8" - integrity sha512-gTXYh3M5wb7FRXQy+FErKFAv90BnlOuNn1QkCK2lREoPAjrQCO49+HVSrFoe5uakFAF5eenS75KbO2vQiLrTMQ== - dependencies: - "@babel/code-frame" "^7.10.4" - "@babel/generator" "^7.12.5" - "@babel/helper-module-transforms" "^7.12.1" - "@babel/helpers" "^7.12.5" - "@babel/parser" "^7.12.7" - "@babel/template" "^7.12.7" - "@babel/traverse" "^7.12.9" - "@babel/types" "^7.12.7" - convert-source-map "^1.7.0" - debug "^4.1.0" - gensync "^1.0.0-beta.1" - json5 "^2.1.2" - lodash "^4.17.19" - resolve "^1.3.2" - semver "^5.4.1" - source-map "^0.5.0" +"@adraffy/ens-normalize@1.10.1": + version "1.10.1" + resolved "https://registry.yarnpkg.com/@adraffy/ens-normalize/-/ens-normalize-1.10.1.tgz#63430d04bd8c5e74f8d7d049338f1cd9d4f02069" + integrity sha512-96Z2IP3mYmF1Xg2cDm8f1gWGf/HUVedQ3FMifV4kG/PQ4yEP51xDtRAEfhVNt5f/uzpNkZHwWQuUcu6D6K+Ekw== -"@babel/core@^7.1.0", "@babel/core@^7.12.10", "@babel/core@^7.12.3", "@babel/core@^7.18.6", "@babel/core@^7.20.2", "@babel/core@^7.20.7", "@babel/core@^7.4.4", "@babel/core@^7.7.5": - version "7.21.4" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.21.4.tgz#c6dc73242507b8e2a27fd13a9c1814f9fa34a659" - integrity sha512-qt/YV149Jman/6AfmlxJ04LMIu8bMoyl3RB91yTFrxQmgbrSvQMy7cI8Q62FHx1t8wJ8B5fu0UDoLwHAhUo1QA== +"@ampproject/remapping@^2.2.0": + version "2.2.1" + resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.1.tgz#99e8e11851128b8702cd57c33684f1d0f260b630" + integrity sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg== dependencies: - "@ampproject/remapping" "^2.2.0" - "@babel/code-frame" "^7.21.4" - "@babel/generator" "^7.21.4" - "@babel/helper-compilation-targets" "^7.21.4" - "@babel/helper-module-transforms" "^7.21.2" - "@babel/helpers" "^7.21.0" - "@babel/parser" "^7.21.4" - "@babel/template" "^7.20.7" - "@babel/traverse" "^7.21.4" - "@babel/types" "^7.21.4" - convert-source-map "^1.7.0" - debug "^4.1.0" - gensync "^1.0.0-beta.2" - json5 "^2.2.2" - semver "^6.3.0" + "@jridgewell/gen-mapping" "^0.3.0" + "@jridgewell/trace-mapping" "^0.3.9" -"@babel/generator@^7.12.11", "@babel/generator@^7.12.5", "@babel/generator@^7.18.6", "@babel/generator@^7.21.4": - version "7.21.4" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.21.4.tgz#64a94b7448989f421f919d5239ef553b37bb26bc" - integrity sha512-NieM3pVIYW2SwGzKoqfPrQsf4xGs9M9AIG3ThppsSRmO+m7eQhmI6amajKMUeIO37wFfsvnvcxQFx6x6iqxDnA== +"@ampproject/remapping@^2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.3.0.tgz#ed441b6fa600072520ce18b43d2c8cc8caecc7f4" + integrity sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw== dependencies: - "@babel/types" "^7.21.4" - "@jridgewell/gen-mapping" "^0.3.2" - "@jridgewell/trace-mapping" "^0.3.17" - jsesc "^2.5.1" + "@jridgewell/gen-mapping" "^0.3.5" + "@jridgewell/trace-mapping" "^0.3.24" -"@babel/helper-annotate-as-pure@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz#eaa49f6f80d5a33f9a5dd2276e6d6e451be0a6bb" - integrity sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA== +"@aw-web-design/x-default-browser@1.4.126": + version "1.4.126" + resolved "https://registry.yarnpkg.com/@aw-web-design/x-default-browser/-/x-default-browser-1.4.126.tgz#43e4bd8f0314ed907a8718d7e862a203af79bc16" + integrity sha512-Xk1sIhyNC/esHGGVjL/niHLowM0csl/kFO5uawBy4IrWwy0o1G8LGt3jP6nmWGz+USxeeqbihAmp/oVZju6wug== dependencies: - "@babel/types" "^7.18.6" + default-browser-id "3.0.0" -"@babel/helper-builder-binary-assignment-operator-visitor@^7.18.6": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.18.9.tgz#acd4edfd7a566d1d51ea975dff38fd52906981bb" - integrity sha512-yFQ0YCHoIqarl8BCRwBL8ulYUaZpz3bNsA7oFepAzee+8/+ImtADXNOmO5vJvsPff3qi+hvpkY/NYBTrBQgdNw== +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.16.7", "@babel/code-frame@^7.22.13", "@babel/code-frame@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.23.4.tgz#03ae5af150be94392cb5c7ccd97db5a19a5da6aa" + integrity sha512-r1IONyb6Ia+jYR2vvIDhdWdlTGhqbBoFqLTQidzZ4kepUFH15ejXvFHxCVbtl7BOXIudsIubf4E81xeA3h3IXA== dependencies: - "@babel/helper-explode-assignable-expression" "^7.18.6" - "@babel/types" "^7.18.9" + "@babel/highlight" "^7.23.4" + chalk "^2.4.2" -"@babel/helper-compilation-targets@^7.10.4", "@babel/helper-compilation-targets@^7.13.0", "@babel/helper-compilation-targets@^7.17.7", "@babel/helper-compilation-targets@^7.18.9", "@babel/helper-compilation-targets@^7.20.7", "@babel/helper-compilation-targets@^7.21.4": - version "7.21.4" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.21.4.tgz#770cd1ce0889097ceacb99418ee6934ef0572656" - integrity sha512-Fa0tTuOXZ1iL8IeDFUWCzjZcn+sJGd9RZdH9esYVjEejGmzf+FFYQpMi/kZUk2kPy/q1H3/GPw7np8qar/stfg== +"@babel/code-frame@^7.10.4": + version "7.26.2" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.26.2.tgz#4b5fab97d33338eff916235055f0ebc21e573a85" + integrity sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ== dependencies: - "@babel/compat-data" "^7.21.4" - "@babel/helper-validator-option" "^7.21.0" - browserslist "^4.21.3" - lru-cache "^5.1.1" - semver "^6.3.0" - -"@babel/helper-create-class-features-plugin@^7.18.6", "@babel/helper-create-class-features-plugin@^7.21.0": - version "7.21.4" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.21.4.tgz#3a017163dc3c2ba7deb9a7950849a9586ea24c18" - integrity sha512-46QrX2CQlaFRF4TkwfTt6nJD7IHq8539cCL7SDpqWSDeJKY1xylKKY5F/33mJhLZ3mFvKv2gGrVS6NkyF6qs+Q== - dependencies: - "@babel/helper-annotate-as-pure" "^7.18.6" - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-function-name" "^7.21.0" - "@babel/helper-member-expression-to-functions" "^7.21.0" - "@babel/helper-optimise-call-expression" "^7.18.6" - "@babel/helper-replace-supers" "^7.20.7" - "@babel/helper-skip-transparent-expression-wrappers" "^7.20.0" - "@babel/helper-split-export-declaration" "^7.18.6" - -"@babel/helper-create-regexp-features-plugin@^7.18.6", "@babel/helper-create-regexp-features-plugin@^7.20.5": - version "7.21.4" - resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.21.4.tgz#40411a8ab134258ad2cf3a3d987ec6aa0723cee5" - integrity sha512-M00OuhU+0GyZ5iBBN9czjugzWrEq2vDpf/zCYHxxf93ul/Q5rv+a5h+/+0WnI1AebHNVtl5bFV0qsJoH23DbfA== - dependencies: - "@babel/helper-annotate-as-pure" "^7.18.6" - regexpu-core "^5.3.1" + "@babel/helper-validator-identifier" "^7.25.9" + js-tokens "^4.0.0" + picocolors "^1.0.0" -"@babel/helper-define-polyfill-provider@^0.0.3": - version "0.0.3" - resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.0.3.tgz#df9da66285b884ce66417abdd0b6ca91198149bd" - integrity sha512-dULDd/APiP4JowYDAMosecKOi/1v+UId99qhBGiO3myM29KtAVKS/R3x3OJJNBR0FeYB1BcYb2dCwkhqvxWXXQ== +"@babel/code-frame@^7.23.5", "@babel/code-frame@^7.24.1", "@babel/code-frame@^7.24.2": + version "7.24.2" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.24.2.tgz#718b4b19841809a58b29b68cde80bc5e1aa6d9ae" + integrity sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ== dependencies: - "@babel/helper-compilation-targets" "^7.10.4" - "@babel/helper-module-imports" "^7.10.4" - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/traverse" "^7.11.5" - debug "^4.1.1" - lodash.debounce "^4.0.8" - resolve "^1.14.2" - semver "^6.1.2" + "@babel/highlight" "^7.24.2" + picocolors "^1.0.0" -"@babel/helper-define-polyfill-provider@^0.1.5": - version "0.1.5" - resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.1.5.tgz#3c2f91b7971b9fc11fe779c945c014065dea340e" - integrity sha512-nXuzCSwlJ/WKr8qxzW816gwyT6VZgiJG17zR40fou70yfAcqjoNyTLl/DQ+FExw5Hx5KNqshmN8Ldl/r2N7cTg== +"@babel/code-frame@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.24.7.tgz#882fd9e09e8ee324e496bd040401c6f046ef4465" + integrity sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA== dependencies: - "@babel/helper-compilation-targets" "^7.13.0" - "@babel/helper-module-imports" "^7.12.13" - "@babel/helper-plugin-utils" "^7.13.0" - "@babel/traverse" "^7.13.0" - debug "^4.1.1" - lodash.debounce "^4.0.8" - resolve "^1.14.2" - semver "^6.1.2" + "@babel/highlight" "^7.24.7" + picocolors "^1.0.0" -"@babel/helper-define-polyfill-provider@^0.3.3": - version "0.3.3" - resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.3.tgz#8612e55be5d51f0cd1f36b4a5a83924e89884b7a" - integrity sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww== - dependencies: - "@babel/helper-compilation-targets" "^7.17.7" - "@babel/helper-plugin-utils" "^7.16.7" - debug "^4.1.1" - lodash.debounce "^4.0.8" - resolve "^1.14.2" - semver "^6.1.2" +"@babel/compat-data@^7.22.6", "@babel/compat-data@^7.22.9", "@babel/compat-data@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.23.3.tgz#3febd552541e62b5e883a25eb3effd7c7379db11" + integrity sha512-BmR4bWbDIoFJmJ9z2cZ8Gmm2MXgEDgjdWgpKmKWUt54UGFJdlj31ECtbaDvCG/qVdG3AQ1SfpZEs01lUFbzLOQ== -"@babel/helper-environment-visitor@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz#0c0cee9b35d2ca190478756865bb3528422f51be" - integrity sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg== +"@babel/compat-data@^7.23.5", "@babel/compat-data@^7.24.4": + version "7.24.4" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.24.4.tgz#6f102372e9094f25d908ca0d34fc74c74606059a" + integrity sha512-vg8Gih2MLK+kOkHJp4gBEIkyaIi00jgWot2D9QOmmfLC8jINSOzmCLta6Bvz/JSBCqnegV0L80jhxkol5GWNfQ== -"@babel/helper-explode-assignable-expression@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.18.6.tgz#41f8228ef0a6f1a036b8dfdfec7ce94f9a6bc096" - integrity sha512-eyAYAsQmB80jNfg4baAtLeWAQHfHFiR483rzFK+BhETlGZaQC9bsfrugfXDCbRHLQbIA7U5NxhhOxN7p/dWIcg== +"@babel/core@^7.12.3", "@babel/core@^7.20.2", "@babel/core@^7.21.0", "@babel/core@^7.21.3", "@babel/core@^7.22.5": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.23.3.tgz#5ec09c8803b91f51cc887dedc2654a35852849c9" + integrity sha512-Jg+msLuNuCJDyBvFv5+OKOUjWMZgd85bKjbICd3zWrKAo+bJ49HJufi7CQE0q0uR8NGyO6xkCACScNqyjHSZew== dependencies: - "@babel/types" "^7.18.6" + "@ampproject/remapping" "^2.2.0" + "@babel/code-frame" "^7.22.13" + "@babel/generator" "^7.23.3" + "@babel/helper-compilation-targets" "^7.22.15" + "@babel/helper-module-transforms" "^7.23.3" + "@babel/helpers" "^7.23.2" + "@babel/parser" "^7.23.3" + "@babel/template" "^7.22.15" + "@babel/traverse" "^7.23.3" + "@babel/types" "^7.23.3" + convert-source-map "^2.0.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.2.3" + semver "^6.3.1" -"@babel/helper-function-name@^7.18.9", "@babel/helper-function-name@^7.19.0", "@babel/helper-function-name@^7.21.0": - version "7.21.0" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.21.0.tgz#d552829b10ea9f120969304023cd0645fa00b1b4" - integrity sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg== +"@babel/core@^7.18.9", "@babel/core@^7.23.0", "@babel/core@^7.23.2", "@babel/core@^7.23.9": + version "7.24.4" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.24.4.tgz#1f758428e88e0d8c563874741bc4ffc4f71a4717" + integrity sha512-MBVlMXP+kkl5394RBLSxxk/iLTeVGuXTV3cIDXavPpMMqnSnt6apKgan/U8O3USWZCWZT/TbgfEpKa4uMgN4Dg== dependencies: - "@babel/template" "^7.20.7" - "@babel/types" "^7.21.0" + "@ampproject/remapping" "^2.2.0" + "@babel/code-frame" "^7.24.2" + "@babel/generator" "^7.24.4" + "@babel/helper-compilation-targets" "^7.23.6" + "@babel/helper-module-transforms" "^7.23.3" + "@babel/helpers" "^7.24.4" + "@babel/parser" "^7.24.4" + "@babel/template" "^7.24.0" + "@babel/traverse" "^7.24.1" + "@babel/types" "^7.24.0" + convert-source-map "^2.0.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.2.3" + semver "^6.3.1" -"@babel/helper-hoist-variables@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz#d4d2c8fb4baeaa5c68b99cc8245c56554f926678" - integrity sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q== +"@babel/generator@^7.21.1", "@babel/generator@^7.23.3", "@babel/generator@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.23.4.tgz#4a41377d8566ec18f807f42962a7f3551de83d1c" + integrity sha512-esuS49Cga3HcThFNebGhlgsrVLkvhqvYDTzgjfFFlHJcIfLe5jFmRRfCQ1KuBfc4Jrtn3ndLgKWAKjBE+IraYQ== dependencies: - "@babel/types" "^7.18.6" + "@babel/types" "^7.23.4" + "@jridgewell/gen-mapping" "^0.3.2" + "@jridgewell/trace-mapping" "^0.3.17" + jsesc "^2.5.1" -"@babel/helper-member-expression-to-functions@^7.20.7", "@babel/helper-member-expression-to-functions@^7.21.0": - version "7.21.0" - resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.21.0.tgz#319c6a940431a133897148515877d2f3269c3ba5" - integrity sha512-Muu8cdZwNN6mRRNG6lAYErJ5X3bRevgYR2O8wN0yn7jJSnGDu6eG59RfT29JHxGUovyfrh6Pj0XzmR7drNVL3Q== +"@babel/generator@^7.23.0", "@babel/generator@^7.24.1", "@babel/generator@^7.24.4": + version "7.24.4" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.24.4.tgz#1fc55532b88adf952025d5d2d1e71f946cb1c498" + integrity sha512-Xd6+v6SnjWVx/nus+y0l1sxMOTOMBkyL4+BIdbALyatQnAe/SRVjANeDPSCYaX+i1iJmuGSKf3Z+E+V/va1Hvw== dependencies: - "@babel/types" "^7.21.0" + "@babel/types" "^7.24.0" + "@jridgewell/gen-mapping" "^0.3.5" + "@jridgewell/trace-mapping" "^0.3.25" + jsesc "^2.5.1" -"@babel/helper-module-imports@^7.0.0", "@babel/helper-module-imports@^7.10.4", "@babel/helper-module-imports@^7.12.13", "@babel/helper-module-imports@^7.18.6": - version "7.21.4" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.21.4.tgz#ac88b2f76093637489e718a90cec6cf8a9b029af" - integrity sha512-orajc5T2PsRYUN3ZryCEFeMDYwyw09c/pZeaQEZPH0MpKzSvn3e0uXsDBu3k03VI+9DBiRo+l22BfKTpKwa/Wg== +"@babel/generator@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.24.7.tgz#1654d01de20ad66b4b4d99c135471bc654c55e6d" + integrity sha512-oipXieGC3i45Y1A41t4tAqpnEZWgB/lC6Ehh6+rOviR5XWpTtMmLN+fGjz9vOiNRt0p6RtO6DtD0pdU3vpqdSA== dependencies: - "@babel/types" "^7.21.4" + "@babel/types" "^7.24.7" + "@jridgewell/gen-mapping" "^0.3.5" + "@jridgewell/trace-mapping" "^0.3.25" + jsesc "^2.5.1" -"@babel/helper-module-transforms@^7.12.1", "@babel/helper-module-transforms@^7.18.6", "@babel/helper-module-transforms@^7.20.11", "@babel/helper-module-transforms@^7.21.2": - version "7.21.2" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.21.2.tgz#160caafa4978ac8c00ac66636cb0fa37b024e2d2" - integrity sha512-79yj2AR4U/Oqq/WOV7Lx6hUjau1Zfo4cI+JLAVYeMV5XIlbOhmjEk5ulbTc9fMpmlojzZHkUUxAiK+UKn+hNQQ== +"@babel/helper-annotate-as-pure@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz#e7f06737b197d580a01edf75d97e2c8be99d3882" + integrity sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg== dependencies: - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-module-imports" "^7.18.6" - "@babel/helper-simple-access" "^7.20.2" - "@babel/helper-split-export-declaration" "^7.18.6" - "@babel/helper-validator-identifier" "^7.19.1" - "@babel/template" "^7.20.7" - "@babel/traverse" "^7.21.2" - "@babel/types" "^7.21.2" + "@babel/types" "^7.22.5" -"@babel/helper-optimise-call-expression@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.18.6.tgz#9369aa943ee7da47edab2cb4e838acf09d290ffe" - integrity sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA== +"@babel/helper-annotate-as-pure@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.7.tgz#5373c7bc8366b12a033b4be1ac13a206c6656aab" + integrity sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg== dependencies: - "@babel/types" "^7.18.6" + "@babel/types" "^7.24.7" -"@babel/helper-plugin-utils@7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz#2f75a831269d4f677de49986dff59927533cf375" - integrity sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg== - -"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.13.0", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.16.7", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.18.9", "@babel/helper-plugin-utils@^7.19.0", "@babel/helper-plugin-utils@^7.20.2", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": - version "7.20.2" - resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz#d1b9000752b18d0877cff85a5c376ce5c3121629" - integrity sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ== - -"@babel/helper-remap-async-to-generator@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.18.9.tgz#997458a0e3357080e54e1d79ec347f8a8cd28519" - integrity sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA== - dependencies: - "@babel/helper-annotate-as-pure" "^7.18.6" - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-wrap-function" "^7.18.9" - "@babel/types" "^7.18.9" +"@babel/helper-builder-binary-assignment-operator-visitor@^7.22.15": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.22.15.tgz#5426b109cf3ad47b91120f8328d8ab1be8b0b956" + integrity sha512-QkBXwGgaoC2GtGZRoma6kv7Szfv06khvhFav67ZExau2RaXzy8MpHSMO2PNoP2XtmQphJQRHFfg77Bq731Yizw== + dependencies: + "@babel/types" "^7.22.15" -"@babel/helper-replace-supers@^7.18.6", "@babel/helper-replace-supers@^7.20.7": - version "7.20.7" - resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.20.7.tgz#243ecd2724d2071532b2c8ad2f0f9f083bcae331" - integrity sha512-vujDMtB6LVfNW13jhlCrp48QNslK6JXi7lQG736HVbHz/mbf4Dc7tIRh1Xf5C0rF7BP8iiSxGMCmY6Ci1ven3A== +"@babel/helper-compilation-targets@^7.22.15", "@babel/helper-compilation-targets@^7.22.6": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.15.tgz#0698fc44551a26cf29f18d4662d5bf545a6cfc52" + integrity sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw== dependencies: - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-member-expression-to-functions" "^7.20.7" - "@babel/helper-optimise-call-expression" "^7.18.6" - "@babel/template" "^7.20.7" - "@babel/traverse" "^7.20.7" - "@babel/types" "^7.20.7" + "@babel/compat-data" "^7.22.9" + "@babel/helper-validator-option" "^7.22.15" + browserslist "^4.21.9" + lru-cache "^5.1.1" + semver "^6.3.1" -"@babel/helper-simple-access@^7.20.2": - version "7.20.2" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz#0ab452687fe0c2cfb1e2b9e0015de07fc2d62dd9" - integrity sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA== +"@babel/helper-compilation-targets@^7.23.6": + version "7.23.6" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz#4d79069b16cbcf1461289eccfbbd81501ae39991" + integrity sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ== dependencies: - "@babel/types" "^7.20.2" + "@babel/compat-data" "^7.23.5" + "@babel/helper-validator-option" "^7.23.5" + browserslist "^4.22.2" + lru-cache "^5.1.1" + semver "^6.3.1" + +"@babel/helper-create-class-features-plugin@^7.22.15": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.22.15.tgz#97a61b385e57fe458496fad19f8e63b63c867de4" + integrity sha512-jKkwA59IXcvSaiK2UN45kKwSC9o+KuoXsBDvHvU/7BecYIp8GQ2UwrVvFgJASUT+hBnwJx6MhvMCuMzwZZ7jlg== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-environment-visitor" "^7.22.5" + "@babel/helper-function-name" "^7.22.5" + "@babel/helper-member-expression-to-functions" "^7.22.15" + "@babel/helper-optimise-call-expression" "^7.22.5" + "@babel/helper-replace-supers" "^7.22.9" + "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" + semver "^6.3.1" + +"@babel/helper-create-class-features-plugin@^7.24.1", "@babel/helper-create-class-features-plugin@^7.24.4": + version "7.24.4" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.4.tgz#c806f73788a6800a5cfbbc04d2df7ee4d927cce3" + integrity sha512-lG75yeuUSVu0pIcbhiYMXBXANHrpUPaOfu7ryAzskCgKUHuAxRQI5ssrtmF0X9UXldPlvT0XM/A4F44OXRt6iQ== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-function-name" "^7.23.0" + "@babel/helper-member-expression-to-functions" "^7.23.0" + "@babel/helper-optimise-call-expression" "^7.22.5" + "@babel/helper-replace-supers" "^7.24.1" + "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" + semver "^6.3.1" + +"@babel/helper-create-class-features-plugin@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.7.tgz#2eaed36b3a1c11c53bdf80d53838b293c52f5b3b" + integrity sha512-kTkaDl7c9vO80zeX1rJxnuRpEsD5tA81yh11X1gQo+PhSti3JS+7qeZo9U4RHobKRiFPKaGK3svUAeb8D0Q7eg== + dependencies: + "@babel/helper-annotate-as-pure" "^7.24.7" + "@babel/helper-environment-visitor" "^7.24.7" + "@babel/helper-function-name" "^7.24.7" + "@babel/helper-member-expression-to-functions" "^7.24.7" + "@babel/helper-optimise-call-expression" "^7.24.7" + "@babel/helper-replace-supers" "^7.24.7" + "@babel/helper-skip-transparent-expression-wrappers" "^7.24.7" + "@babel/helper-split-export-declaration" "^7.24.7" + semver "^6.3.1" + +"@babel/helper-create-regexp-features-plugin@^7.18.6", "@babel/helper-create-regexp-features-plugin@^7.22.15", "@babel/helper-create-regexp-features-plugin@^7.22.5": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.15.tgz#5ee90093914ea09639b01c711db0d6775e558be1" + integrity sha512-29FkPLFjn4TPEa3RE7GpW+qbE8tlsu3jntNYNfcGsc49LphF1PQIiD+vMZ1z1xVOKt+93khA9tc2JBs3kBjA7w== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + regexpu-core "^5.3.1" + semver "^6.3.1" -"@babel/helper-skip-transparent-expression-wrappers@^7.20.0": - version "7.20.0" - resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.20.0.tgz#fbe4c52f60518cab8140d77101f0e63a8a230684" - integrity sha512-5y1JYeNKfvnT8sZcK9DVRtpTbGiomYIHviSP3OQWmDPU3DeH4a1ZlT/N2lyQ5P8egjcRaT/Y9aNqUxK0WsnIIg== +"@babel/helper-define-polyfill-provider@^0.4.3": + version "0.4.3" + resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.4.3.tgz#a71c10f7146d809f4a256c373f462d9bba8cf6ba" + integrity sha512-WBrLmuPP47n7PNwsZ57pqam6G/RGo1vw/87b0Blc53tZNGZ4x7YvZ6HgQe2vo1W/FR20OgjeZuGXzudPiXHFug== dependencies: - "@babel/types" "^7.20.0" + "@babel/helper-compilation-targets" "^7.22.6" + "@babel/helper-plugin-utils" "^7.22.5" + debug "^4.1.1" + lodash.debounce "^4.0.8" + resolve "^1.14.2" -"@babel/helper-split-export-declaration@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz#7367949bc75b20c6d5a5d4a97bba2824ae8ef075" - integrity sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA== +"@babel/helper-define-polyfill-provider@^0.6.1": + version "0.6.1" + resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.1.tgz#fadc63f0c2ff3c8d02ed905dcea747c5b0fb74fd" + integrity sha512-o7SDgTJuvx5vLKD6SFvkydkSMBvahDKGiNJzG22IZYXhiqoe9efY7zocICBgzHV4IRg5wdgl2nEL/tulKIEIbA== dependencies: - "@babel/types" "^7.18.6" + "@babel/helper-compilation-targets" "^7.22.6" + "@babel/helper-plugin-utils" "^7.22.5" + debug "^4.1.1" + lodash.debounce "^4.0.8" + resolve "^1.14.2" -"@babel/helper-string-parser@^7.19.4": - version "7.19.4" - resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz#38d3acb654b4701a9b77fb0615a96f775c3a9e63" - integrity sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw== +"@babel/helper-environment-visitor@^7.22.20", "@babel/helper-environment-visitor@^7.22.5": + version "7.22.20" + resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz#96159db61d34a29dba454c959f5ae4a649ba9167" + integrity sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA== -"@babel/helper-validator-identifier@^7.18.6", "@babel/helper-validator-identifier@^7.19.1": - version "7.19.1" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz#7eea834cf32901ffdc1a7ee555e2f9c27e249ca2" - integrity sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w== +"@babel/helper-environment-visitor@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz#4b31ba9551d1f90781ba83491dd59cf9b269f7d9" + integrity sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ== + dependencies: + "@babel/types" "^7.24.7" -"@babel/helper-validator-option@^7.18.6", "@babel/helper-validator-option@^7.21.0": - version "7.21.0" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.21.0.tgz#8224c7e13ace4bafdc4004da2cf064ef42673180" - integrity sha512-rmL/B8/f0mKS2baE9ZpyTcTavvEuWhTTW8amjzXNvYG4AwBsqTLikfXsEofsJEfKHf+HQVQbFOHy6o+4cnC/fQ== +"@babel/helper-function-name@^7.22.5", "@babel/helper-function-name@^7.23.0": + version "7.23.0" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz#1f9a3cdbd5b2698a670c30d2735f9af95ed52759" + integrity sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw== + dependencies: + "@babel/template" "^7.22.15" + "@babel/types" "^7.23.0" -"@babel/helper-wrap-function@^7.18.9": - version "7.20.5" - resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.20.5.tgz#75e2d84d499a0ab3b31c33bcfe59d6b8a45f62e3" - integrity sha512-bYMxIWK5mh+TgXGVqAtnu5Yn1un+v8DDZtqyzKRLUzrh70Eal2O3aZ7aPYiMADO4uKlkzOiRiZ6GX5q3qxvW9Q== +"@babel/helper-function-name@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.24.7.tgz#75f1e1725742f39ac6584ee0b16d94513da38dd2" + integrity sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA== dependencies: - "@babel/helper-function-name" "^7.19.0" - "@babel/template" "^7.18.10" - "@babel/traverse" "^7.20.5" - "@babel/types" "^7.20.5" + "@babel/template" "^7.24.7" + "@babel/types" "^7.24.7" -"@babel/helpers@^7.12.5", "@babel/helpers@^7.21.0": - version "7.21.0" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.21.0.tgz#9dd184fb5599862037917cdc9eecb84577dc4e7e" - integrity sha512-XXve0CBtOW0pd7MRzzmoyuSj0e3SEzj8pgyFxnTT1NJZL38BD1MK7yYrm8yefRPIDvNNe14xR4FdbHwpInD4rA== +"@babel/helper-hoist-variables@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz#c01a007dac05c085914e8fb652b339db50d823bb" + integrity sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw== dependencies: - "@babel/template" "^7.20.7" - "@babel/traverse" "^7.21.0" - "@babel/types" "^7.21.0" + "@babel/types" "^7.22.5" -"@babel/highlight@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.18.6.tgz#81158601e93e2563795adcbfbdf5d64be3f2ecdf" - integrity sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g== +"@babel/helper-hoist-variables@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.24.7.tgz#b4ede1cde2fd89436397f30dc9376ee06b0f25ee" + integrity sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ== dependencies: - "@babel/helper-validator-identifier" "^7.18.6" - chalk "^2.0.0" - js-tokens "^4.0.0" + "@babel/types" "^7.24.7" -"@babel/parser@^7.1.0", "@babel/parser@^7.11.5", "@babel/parser@^7.12.11", "@babel/parser@^7.12.7", "@babel/parser@^7.14.7", "@babel/parser@^7.18.6", "@babel/parser@^7.20.7", "@babel/parser@^7.21.4", "@babel/parser@^7.7.0": - version "7.21.4" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.21.4.tgz#94003fdfc520bbe2875d4ae557b43ddb6d880f17" - integrity sha512-alVJj7k7zIxqBZ7BTRhz0IqJFxW1VJbm6N8JbcYhQ186df9ZBPbZBmWSqAMXwHGsCJdYks7z/voa3ibiS5bCIw== +"@babel/helper-member-expression-to-functions@^7.22.15", "@babel/helper-member-expression-to-functions@^7.23.0": + version "7.23.0" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.23.0.tgz#9263e88cc5e41d39ec18c9a3e0eced59a3e7d366" + integrity sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA== + dependencies: + "@babel/types" "^7.23.0" -"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.18.6.tgz#da5b8f9a580acdfbe53494dba45ea389fb09a4d2" - integrity sha512-Dgxsyg54Fx1d4Nge8UnvTrED63vrwOdPmyvPzlNN/boaliRP54pm3pGzZD1SJUwrBA+Cs/xdG8kXX6Mn/RfISQ== +"@babel/helper-member-expression-to-functions@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.7.tgz#67613d068615a70e4ed5101099affc7a41c5225f" + integrity sha512-LGeMaf5JN4hAT471eJdBs/GK1DoYIJ5GCtZN/EsL6KUiiDZOvO/eKE11AMZJa2zP4zk4qe9V2O/hxAmkRc8p6w== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/traverse" "^7.24.7" + "@babel/types" "^7.24.7" -"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.20.7": - version "7.20.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.20.7.tgz#d9c85589258539a22a901033853101a6198d4ef1" - integrity sha512-sbr9+wNE5aXMBBFBICk01tt7sBf2Oc9ikRFEcem/ZORup9IMUdNhW7/wVLEbbtlWOsEubJet46mHAL2C8+2jKQ== +"@babel/helper-module-imports@^7.0.0", "@babel/helper-module-imports@^7.22.15": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz#16146307acdc40cc00c3b2c647713076464bdbf0" + integrity sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w== dependencies: - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/helper-skip-transparent-expression-wrappers" "^7.20.0" - "@babel/plugin-proposal-optional-chaining" "^7.20.7" + "@babel/types" "^7.22.15" + +"@babel/helper-module-imports@^7.24.1": + version "7.24.3" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.24.3.tgz#6ac476e6d168c7c23ff3ba3cf4f7841d46ac8128" + integrity sha512-viKb0F9f2s0BCS22QSF308z/+1YWKV/76mwt61NBzS5izMzDPwdq1pTrzf+Li3npBWX9KdQbkeCt1jSAM7lZqg== + dependencies: + "@babel/types" "^7.24.0" + +"@babel/helper-module-imports@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz#f2f980392de5b84c3328fc71d38bd81bbb83042b" + integrity sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA== + dependencies: + "@babel/traverse" "^7.24.7" + "@babel/types" "^7.24.7" + +"@babel/helper-module-transforms@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz#d7d12c3c5d30af5b3c0fcab2a6d5217773e2d0f1" + integrity sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ== + dependencies: + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-module-imports" "^7.22.15" + "@babel/helper-simple-access" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" + "@babel/helper-validator-identifier" "^7.22.20" -"@babel/plugin-proposal-async-generator-functions@^7.20.7": - version "7.20.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.20.7.tgz#bfb7276d2d573cb67ba379984a2334e262ba5326" - integrity sha512-xMbiLsn/8RK7Wq7VeVytytS2L6qE69bXPB10YCmMdDZbKF4okCqY74pI/jJQ/8U0b/F6NrT2+14b8/P9/3AMGA== - dependencies: - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/helper-remap-async-to-generator" "^7.18.9" - "@babel/plugin-syntax-async-generators" "^7.8.4" +"@babel/helper-module-transforms@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.24.7.tgz#31b6c9a2930679498db65b685b1698bfd6c7daf8" + integrity sha512-1fuJEwIrp+97rM4RWdO+qrRsZlAeL1lQJoPqtCYWv0NL115XM93hIH4CSRln2w52SqvmY5hqdtauB6QFCDiZNQ== + dependencies: + "@babel/helper-environment-visitor" "^7.24.7" + "@babel/helper-module-imports" "^7.24.7" + "@babel/helper-simple-access" "^7.24.7" + "@babel/helper-split-export-declaration" "^7.24.7" + "@babel/helper-validator-identifier" "^7.24.7" + +"@babel/helper-optimise-call-expression@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.22.5.tgz#f21531a9ccbff644fdd156b4077c16ff0c3f609e" + integrity sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw== + dependencies: + "@babel/types" "^7.22.5" -"@babel/plugin-proposal-class-properties@^7.12.1", "@babel/plugin-proposal-class-properties@^7.18.6", "@babel/plugin-proposal-class-properties@^7.4.4": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz#b110f59741895f7ec21a6fff696ec46265c446a3" - integrity sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ== - dependencies: - "@babel/helper-create-class-features-plugin" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" +"@babel/helper-optimise-call-expression@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.24.7.tgz#8b0a0456c92f6b323d27cfd00d1d664e76692a0f" + integrity sha512-jKiTsW2xmWwxT1ixIdfXUZp+P5yURx2suzLZr5Hi64rURpDYdMW0pv+Uf17EYk2Rd428Lx4tLsnjGJzYKDM/6A== + dependencies: + "@babel/types" "^7.24.7" -"@babel/plugin-proposal-class-static-block@^7.21.0": - version "7.21.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.21.0.tgz#77bdd66fb7b605f3a61302d224bdfacf5547977d" - integrity sha512-XP5G9MWNUskFuP30IfFSEFB0Z6HzLIUcjYM4bYOPHXl7eiJ9HFv8tWj6TXTN5QODiEhDZAeI4hLok2iHFFV4hw== - dependencies: - "@babel/helper-create-class-features-plugin" "^7.21.0" - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/plugin-syntax-class-static-block" "^7.14.5" +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.22.5", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz#dd7ee3735e8a313b9f7b05a773d892e88e6d7295" + integrity sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg== -"@babel/plugin-proposal-decorators@^7.12.12": - version "7.21.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.21.0.tgz#70e0c89fdcd7465c97593edb8f628ba6e4199d63" - integrity sha512-MfgX49uRrFUTL/HvWtmx3zmpyzMMr4MTj3d527MLlr/4RTT9G/ytFFP7qet2uM2Ve03b+BkpWUpK+lRXnQ+v9w== - dependencies: - "@babel/helper-create-class-features-plugin" "^7.21.0" - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/helper-replace-supers" "^7.20.7" - "@babel/helper-split-export-declaration" "^7.18.6" - "@babel/plugin-syntax-decorators" "^7.21.0" +"@babel/helper-plugin-utils@^7.24.0": + version "7.24.0" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.0.tgz#945681931a52f15ce879fd5b86ce2dae6d3d7f2a" + integrity sha512-9cUznXMG0+FxRuJfvL82QlTqIzhVW9sL0KjMPHhAOOvpQGL8QtdxnBKILjBqxlHyliz0yCa1G903ZXI/FuHy2w== -"@babel/plugin-proposal-dynamic-import@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.18.6.tgz#72bcf8d408799f547d759298c3c27c7e7faa4d94" - integrity sha512-1auuwmK+Rz13SJj36R+jqFPMJWyKEDd7lLSdOj4oJK0UTgGueSAtkrCvz9ewmgyU/P941Rv2fQwZJN8s6QruXw== - dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/plugin-syntax-dynamic-import" "^7.8.3" +"@babel/helper-plugin-utils@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz#98c84fe6fe3d0d3ae7bfc3a5e166a46844feb2a0" + integrity sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg== + +"@babel/helper-remap-async-to-generator@^7.22.20": + version "7.22.20" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.20.tgz#7b68e1cb4fa964d2996fd063723fb48eca8498e0" + integrity sha512-pBGyV4uBqOns+0UvhsTO8qgl8hO89PmiDYv+/COyp1aeMcmfrfruz+/nCMFiYyFF/Knn0yfrC85ZzNFjembFTw== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-wrap-function" "^7.22.20" + +"@babel/helper-replace-supers@^7.22.20", "@babel/helper-replace-supers@^7.22.9": + version "7.22.20" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.22.20.tgz#e37d367123ca98fe455a9887734ed2e16eb7a793" + integrity sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw== + dependencies: + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-member-expression-to-functions" "^7.22.15" + "@babel/helper-optimise-call-expression" "^7.22.5" + +"@babel/helper-replace-supers@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.24.1.tgz#7085bd19d4a0b7ed8f405c1ed73ccb70f323abc1" + integrity sha512-QCR1UqC9BzG5vZl8BMicmZ28RuUBnHhAMddD8yHFHDRH9lLTZ9uUPehX8ctVPT8l0TKblJidqcgUUKGVrePleQ== + dependencies: + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-member-expression-to-functions" "^7.23.0" + "@babel/helper-optimise-call-expression" "^7.22.5" + +"@babel/helper-replace-supers@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.24.7.tgz#f933b7eed81a1c0265740edc91491ce51250f765" + integrity sha512-qTAxxBM81VEyoAY0TtLrx1oAEJc09ZK67Q9ljQToqCnA+55eNwCORaxlKyu+rNfX86o8OXRUSNUnrtsAZXM9sg== + dependencies: + "@babel/helper-environment-visitor" "^7.24.7" + "@babel/helper-member-expression-to-functions" "^7.24.7" + "@babel/helper-optimise-call-expression" "^7.24.7" + +"@babel/helper-simple-access@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz#4938357dc7d782b80ed6dbb03a0fba3d22b1d5de" + integrity sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-simple-access@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz#bcade8da3aec8ed16b9c4953b74e506b51b5edb3" + integrity sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg== + dependencies: + "@babel/traverse" "^7.24.7" + "@babel/types" "^7.24.7" + +"@babel/helper-skip-transparent-expression-wrappers@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.22.5.tgz#007f15240b5751c537c40e77abb4e89eeaaa8847" + integrity sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-skip-transparent-expression-wrappers@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.24.7.tgz#5f8fa83b69ed5c27adc56044f8be2b3ea96669d9" + integrity sha512-IO+DLT3LQUElMbpzlatRASEyQtfhSE0+m465v++3jyyXeBTBUjtVZg28/gHeV5mrTJqvEKhKroBGAvhW+qPHiQ== + dependencies: + "@babel/traverse" "^7.24.7" + "@babel/types" "^7.24.7" + +"@babel/helper-split-export-declaration@^7.22.6": + version "7.22.6" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz#322c61b7310c0997fe4c323955667f18fcefb91c" + integrity sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-split-export-declaration@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz#83949436890e07fa3d6873c61a96e3bbf692d856" + integrity sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA== + dependencies: + "@babel/types" "^7.24.7" + +"@babel/helper-string-parser@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz#9478c707febcbbe1ddb38a3d91a2e054ae622d83" + integrity sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ== + +"@babel/helper-string-parser@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz#4d2d0f14820ede3b9807ea5fc36dfc8cd7da07f2" + integrity sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg== + +"@babel/helper-validator-identifier@^7.22.20": + version "7.22.20" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz#c4ae002c61d2879e724581d96665583dbc1dc0e0" + integrity sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A== + +"@babel/helper-validator-identifier@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz#75b889cfaf9e35c2aaf42cf0d72c8e91719251db" + integrity sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w== + +"@babel/helper-validator-identifier@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz#24b64e2c3ec7cd3b3c547729b8d16871f22cbdc7" + integrity sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ== + +"@babel/helper-validator-option@^7.22.15": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.22.15.tgz#694c30dfa1d09a6534cdfcafbe56789d36aba040" + integrity sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA== + +"@babel/helper-validator-option@^7.23.5": + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz#907a3fbd4523426285365d1206c423c4c5520307" + integrity sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw== + +"@babel/helper-validator-option@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.24.7.tgz#24c3bb77c7a425d1742eec8fb433b5a1b38e62f6" + integrity sha512-yy1/KvjhV/ZCL+SM7hBrvnZJ3ZuT9OuZgIJAGpPEToANvc3iM6iDvBnRjtElWibHU6n8/LPR/EjX9EtIEYO3pw== + +"@babel/helper-wrap-function@^7.22.20": + version "7.22.20" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.22.20.tgz#15352b0b9bfb10fc9c76f79f6342c00e3411a569" + integrity sha512-pms/UwkOpnQe/PDAEdV/d7dVCoBbB+R4FvYoHGZz+4VPcg7RtYy2KP7S2lbuWM6FCSgob5wshfGESbC/hzNXZw== + dependencies: + "@babel/helper-function-name" "^7.22.5" + "@babel/template" "^7.22.15" + "@babel/types" "^7.22.19" + +"@babel/helpers@^7.23.2": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.23.4.tgz#7d2cfb969aa43222032193accd7329851facf3c1" + integrity sha512-HfcMizYz10cr3h29VqyfGL6ZWIjTwWfvYBMsBVGwpcbhNGe3wQ1ZXZRPzZoAHhd9OqHadHqjQ89iVKINXnbzuw== + dependencies: + "@babel/template" "^7.22.15" + "@babel/traverse" "^7.23.4" + "@babel/types" "^7.23.4" + +"@babel/helpers@^7.24.4": + version "7.24.4" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.24.4.tgz#dc00907fd0d95da74563c142ef4cd21f2cb856b6" + integrity sha512-FewdlZbSiwaVGlgT1DPANDuCHaDMiOo+D/IDYRFYjHOuv66xMSJ7fQwwODwRNAPkADIO/z1EoF/l2BCWlWABDw== + dependencies: + "@babel/template" "^7.24.0" + "@babel/traverse" "^7.24.1" + "@babel/types" "^7.24.0" + +"@babel/highlight@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.23.4.tgz#edaadf4d8232e1a961432db785091207ead0621b" + integrity sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A== + dependencies: + "@babel/helper-validator-identifier" "^7.22.20" + chalk "^2.4.2" + js-tokens "^4.0.0" -"@babel/plugin-proposal-export-default-from@^7.12.1": - version "7.18.10" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-default-from/-/plugin-proposal-export-default-from-7.18.10.tgz#091f4794dbce4027c03cf4ebc64d3fb96b75c206" - integrity sha512-5H2N3R2aQFxkV4PIBUR/i7PUSwgTZjouJKzI8eKswfIjT0PhvzkPn0t0wIS5zn6maQuvtT0t1oHtMUz61LOuow== +"@babel/highlight@^7.24.2": + version "7.24.2" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.24.2.tgz#3f539503efc83d3c59080a10e6634306e0370d26" + integrity sha512-Yac1ao4flkTxTteCDZLEvdxg2fZfz1v8M4QpaGypq/WPDqg3ijHYbDfs+LG5hvzSoqaSZ9/Z9lKSP3CjZjv+pA== dependencies: - "@babel/helper-plugin-utils" "^7.18.9" - "@babel/plugin-syntax-export-default-from" "^7.18.6" + "@babel/helper-validator-identifier" "^7.22.20" + chalk "^2.4.2" + js-tokens "^4.0.0" + picocolors "^1.0.0" -"@babel/plugin-proposal-export-namespace-from@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.18.9.tgz#5f7313ab348cdb19d590145f9247540e94761203" - integrity sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA== +"@babel/highlight@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.24.7.tgz#a05ab1df134b286558aae0ed41e6c5f731bf409d" + integrity sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw== dependencies: - "@babel/helper-plugin-utils" "^7.18.9" - "@babel/plugin-syntax-export-namespace-from" "^7.8.3" + "@babel/helper-validator-identifier" "^7.24.7" + chalk "^2.4.2" + js-tokens "^4.0.0" + picocolors "^1.0.0" -"@babel/plugin-proposal-json-strings@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.18.6.tgz#7e8788c1811c393aff762817e7dbf1ebd0c05f0b" - integrity sha512-lr1peyn9kOdbYc0xr0OdHTZ5FMqS6Di+H0Fz2I/JwMzGmzJETNeOFq2pBySw6X/KFL5EWDjlJuMsUGRFb8fQgQ== - dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/plugin-syntax-json-strings" "^7.8.3" +"@babel/parser@^7.1.0", "@babel/parser@^7.20.7", "@babel/parser@^7.21.2", "@babel/parser@^7.22.15", "@babel/parser@^7.23.3", "@babel/parser@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.23.4.tgz#409fbe690c333bb70187e2de4021e1e47a026661" + integrity sha512-vf3Xna6UEprW+7t6EtOmFpHNAuxw3xqPZghy+brsnusscJRW5BMUzzHZc5ICjULee81WeUV2jjakG09MDglJXQ== -"@babel/plugin-proposal-logical-assignment-operators@^7.20.7": - version "7.20.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.20.7.tgz#dfbcaa8f7b4d37b51e8bfb46d94a5aea2bb89d83" - integrity sha512-y7C7cZgpMIjWlKE5T7eJwp+tnRYM89HmRvWM5EQuB5BoHEONjmQ8lSNmBUwOyy/GFRsohJED51YBF79hE1djug== - dependencies: - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" +"@babel/parser@^7.23.0", "@babel/parser@^7.24.0", "@babel/parser@^7.24.1", "@babel/parser@^7.24.4": + version "7.24.4" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.24.4.tgz#234487a110d89ad5a3ed4a8a566c36b9453e8c88" + integrity sha512-zTvEBcghmeBma9QIGunWevvBAp4/Qu9Bdq+2k0Ot4fVMD6v3dsC9WOcRSKk7tRRyBM/53yKMJko9xOatGQAwSg== -"@babel/plugin-proposal-nullish-coalescing-operator@^7.12.1", "@babel/plugin-proposal-nullish-coalescing-operator@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz#fdd940a99a740e577d6c753ab6fbb43fdb9467e1" - integrity sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA== - dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" +"@babel/parser@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.24.7.tgz#9a5226f92f0c5c8ead550b750f5608e766c8ce85" + integrity sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw== -"@babel/plugin-proposal-numeric-separator@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.18.6.tgz#899b14fbafe87f053d2c5ff05b36029c62e13c75" - integrity sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q== +"@babel/plugin-bugfix-firefox-class-in-computed-class-key@^7.24.4": + version "7.24.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.24.4.tgz#6125f0158543fb4edf1c22f322f3db67f21cb3e1" + integrity sha512-qpl6vOOEEzTLLcsuqYYo8yDtrTocmu2xkGvgNebvPjT9DTtfFYGmgDqY+rBYXNlqL4s9qLDn6xkrJv4RxAPiTA== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/plugin-syntax-numeric-separator" "^7.10.4" + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-plugin-utils" "^7.24.0" -"@babel/plugin-proposal-object-rest-spread@7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.12.1.tgz#def9bd03cea0f9b72283dac0ec22d289c7691069" - integrity sha512-s6SowJIjzlhx8o7lsFx5zmY4At6CTtDvgNQDdPzkBQucle58A6b/TTeEBYtyDgmcXjUTM+vE8YOGHZzzbc/ioA== +"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.23.3.tgz#5cd1c87ba9380d0afb78469292c954fee5d2411a" + integrity sha512-iRkKcCqb7iGnq9+3G6rZ+Ciz5VywC4XNRHe57lKM+jOeYAoR0lVqdeeDRfh0tQcTfw/+vBhHn926FmQhLtlFLQ== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-syntax-object-rest-spread" "^7.8.0" - "@babel/plugin-transform-parameters" "^7.12.1" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-proposal-object-rest-spread@^7.12.1", "@babel/plugin-proposal-object-rest-spread@^7.20.7": - version "7.20.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.20.7.tgz#aa662940ef425779c75534a5c41e9d936edc390a" - integrity sha512-d2S98yCiLxDVmBmE8UjGcfPvNEUbA1U5q5WxaWFUGRzJSVAZqm5W6MbPct0jxnegUZ0niLeNX+IOzEs7wYg9Dg== +"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.24.1.tgz#b645d9ba8c2bc5b7af50f0fe949f9edbeb07c8cf" + integrity sha512-y4HqEnkelJIOQGd+3g1bTeKsA5c6qM7eOn7VggGVbBc0y8MLSKHacwcIE2PplNlQSj0PqS9rrXL/nkPVK+kUNg== dependencies: - "@babel/compat-data" "^7.20.5" - "@babel/helper-compilation-targets" "^7.20.7" - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/plugin-syntax-object-rest-spread" "^7.8.3" - "@babel/plugin-transform-parameters" "^7.20.7" + "@babel/helper-plugin-utils" "^7.24.0" -"@babel/plugin-proposal-optional-catch-binding@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.18.6.tgz#f9400d0e6a3ea93ba9ef70b09e72dd6da638a2cb" - integrity sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw== +"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.23.3.tgz#f6652bb16b94f8f9c20c50941e16e9756898dc5d" + integrity sha512-WwlxbfMNdVEpQjZmK5mhm7oSwD3dS6eU+Iwsi4Knl9wAletWem7kaRsGOG+8UEbRyqxY4SS5zvtfXwX+jMxUwQ== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" + "@babel/plugin-transform-optional-chaining" "^7.23.3" -"@babel/plugin-proposal-optional-chaining@^7.12.7", "@babel/plugin-proposal-optional-chaining@^7.20.7", "@babel/plugin-proposal-optional-chaining@^7.21.0": - version "7.21.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.21.0.tgz#886f5c8978deb7d30f678b2e24346b287234d3ea" - integrity sha512-p4zeefM72gpmEe2fkUr/OnOXpWEf8nAgk7ZYVqqfFiyIG7oFfVZcCrU64hWn5xp4tQ9LkV4bTIa5rD0KANpKNA== +"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.24.1.tgz#da8261f2697f0f41b0855b91d3a20a1fbfd271d3" + integrity sha512-Hj791Ii4ci8HqnaKHAlLNs+zaLXb0EzSDhiAWp5VNlyvCNymYfacs64pxTxbH1znW/NcArSmwpmG9IKE/TUVVQ== dependencies: - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/helper-skip-transparent-expression-wrappers" "^7.20.0" - "@babel/plugin-syntax-optional-chaining" "^7.8.3" + "@babel/helper-plugin-utils" "^7.24.0" + "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" + "@babel/plugin-transform-optional-chaining" "^7.24.1" -"@babel/plugin-proposal-private-methods@^7.12.1", "@babel/plugin-proposal-private-methods@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.18.6.tgz#5209de7d213457548a98436fa2882f52f4be6bea" - integrity sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA== +"@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.23.3.tgz#20c60d4639d18f7da8602548512e9d3a4c8d7098" + integrity sha512-XaJak1qcityzrX0/IU5nKHb34VaibwP3saKqG6a/tppelgllOH13LUann4ZCIBcVOeE6H18K4Vx9QKkVww3z/w== dependencies: - "@babel/helper-create-class-features-plugin" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-proposal-private-property-in-object@^7.12.1", "@babel/plugin-proposal-private-property-in-object@^7.21.0": - version "7.21.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0.tgz#19496bd9883dd83c23c7d7fc45dcd9ad02dfa1dc" - integrity sha512-ha4zfehbJjc5MmXBlHec1igel5TJXXLDDRbuJ4+XT2TJcyD9/V1919BA8gMvsdHcNMBy4WBUBiRb3nw/EQUtBw== +"@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.24.1.tgz#1181d9685984c91d657b8ddf14f0487a6bab2988" + integrity sha512-m9m/fXsXLiHfwdgydIFnpk+7jlVbnvlK5B2EKiPdLUb6WX654ZaaEWJUjk8TftRbZpK0XibovlLWX4KIZhV6jw== dependencies: - "@babel/helper-annotate-as-pure" "^7.18.6" - "@babel/helper-create-class-features-plugin" "^7.21.0" - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/plugin-syntax-private-property-in-object" "^7.14.5" + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-plugin-utils" "^7.24.0" -"@babel/plugin-proposal-unicode-property-regex@^7.18.6", "@babel/plugin-proposal-unicode-property-regex@^7.4.4": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.18.6.tgz#af613d2cd5e643643b65cded64207b15c85cb78e" - integrity sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w== - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" +"@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2": + version "7.21.0-placeholder-for-preset-env.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz#7844f9289546efa9febac2de4cfe358a050bd703" + integrity sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w== "@babel/plugin-syntax-async-generators@^7.8.4": version "7.8.4" @@ -506,14 +679,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-bigint@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz#4c9a6f669f5d0cdf1b90a1671e9a146be5300cea" - integrity sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-class-properties@^7.12.13", "@babel/plugin-syntax-class-properties@^7.8.3": +"@babel/plugin-syntax-class-properties@^7.12.13": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz#b5c987274c4a3a82b89714796931a6b53544ae10" integrity sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA== @@ -527,13 +693,6 @@ dependencies: "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-syntax-decorators@^7.21.0": - version "7.21.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.21.0.tgz#d2b3f31c3e86fa86e16bb540b7660c55bd7d0e78" - integrity sha512-tIoPpGBR8UuM4++ccWN3gifhVvQu7ZizuR1fklhRJrd5ewgbkUS+0KVFeWWxELtn18NTLoW32XV7zyOgIAiz+w== - dependencies: - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/plugin-syntax-dynamic-import@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz#62bf98b2da3cd21d626154fc96ee5b3cb68eacb3" @@ -541,13 +700,6 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-export-default-from@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-export-default-from/-/plugin-syntax-export-default-from-7.18.6.tgz#8df076711a4818c4ce4f23e61d622b0ba2ff84bc" - integrity sha512-Kr//z3ujSVNx6E9z9ih5xXXMqK07VVTuqPmqGe6Mss/zW5XPeLZeSDZoP9ab/hT4wPKqAgjl2PnhPrcpk8Seew== - dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/plugin-syntax-export-namespace-from@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz#028964a9ba80dbc094c915c487ad7c4e7a66465a" @@ -555,21 +707,42 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.3" -"@babel/plugin-syntax-flow@^7.18.6": - version "7.21.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.21.4.tgz#3e37fca4f06d93567c1cd9b75156422e90a67107" - integrity sha512-l9xd3N+XG4fZRxEP3vXdK6RW7vN1Uf5dxzRC/09wV86wqZ/YYQooBIGNsiRdfNR3/q2/5pPzV4B54J/9ctX5jw== +"@babel/plugin-syntax-flow@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.24.1.tgz#875c25e3428d7896c87589765fc8b9d32f24bd8d" + integrity sha512-sxi2kLTI5DeW5vDtMUsk4mTPwvlUDbjOnoWayhynCwrw4QXRld4QEYwqzY8JmQXaJUtgUuCIurtSRH5sn4c7mA== dependencies: - "@babel/helper-plugin-utils" "^7.20.2" + "@babel/helper-plugin-utils" "^7.24.0" -"@babel/plugin-syntax-import-assertions@^7.20.0": - version "7.20.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.20.0.tgz#bb50e0d4bea0957235390641209394e87bdb9cc4" - integrity sha512-IUh1vakzNoWalR8ch/areW7qFopR2AEw03JlG7BbrDqmQ4X3q9uuipQwSGrUn7oGiemKjtSLDhNtQHzMHr1JdQ== +"@babel/plugin-syntax-import-assertions@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.23.3.tgz#9c05a7f592982aff1a2768260ad84bcd3f0c77fc" + integrity sha512-lPgDSU+SJLK3xmFDTV2ZRQAiM7UuUjGidwBywFavObCiZc1BeAAcMtHJKUya92hPHO+at63JJPLygilZard8jw== dependencies: - "@babel/helper-plugin-utils" "^7.19.0" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-syntax-import-meta@^7.8.3": +"@babel/plugin-syntax-import-assertions@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.24.1.tgz#db3aad724153a00eaac115a3fb898de544e34971" + integrity sha512-IuwnI5XnuF189t91XbxmXeCDz3qs6iDRO7GJ++wcfgeXNs/8FmIlKcpDSXNVyuLQxlwvskmI3Ct73wUODkJBlQ== + dependencies: + "@babel/helper-plugin-utils" "^7.24.0" + +"@babel/plugin-syntax-import-attributes@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.23.3.tgz#992aee922cf04512461d7dae3ff6951b90a2dc06" + integrity sha512-pawnE0P9g10xgoP7yKr6CK63K2FMsTE+FZidZO/1PwRdzmAPVs+HS1mAURUsgaoxammTJvULUdIkEK0gOcU2tA== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-syntax-import-attributes@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.24.1.tgz#c66b966c63b714c4eec508fcf5763b1f2d381093" + integrity sha512-zhQTMH0X2nVLnb04tz+s7AMuasX8U0FnpE+nHTOhSOINjWMnopoZTxtIKsd45n4GQ/HIZLyfIpoul8e2m0DnRA== + dependencies: + "@babel/helper-plugin-utils" "^7.24.0" + +"@babel/plugin-syntax-import-meta@^7.10.4": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz#ee601348c370fa334d2207be158777496521fd51" integrity sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g== @@ -583,21 +756,28 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-jsx@7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.12.1.tgz#9d9d357cc818aa7ae7935917c1257f67677a0926" - integrity sha512-1yRi7yAtB0ETgxdY9ti/p2TivUxJkTdhu/ZbF9MshVGqOx1TdB3b7xCXs49Fupgg50N45KcAsRP/ZqWjs9SRjg== +"@babel/plugin-syntax-jsx@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.23.3.tgz#8f2e4f8a9b5f9aa16067e142c1ac9cd9f810f473" + integrity sha512-EB2MELswq55OHUoRZLGg/zC7QWUKfNLpE57m/S2yr1uEneIgsTgrSzXP3NXEsMkVn76OlaVVnzN+ugObuYGwhg== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-syntax-jsx@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.24.1.tgz#3f6ca04b8c841811dbc3c5c5f837934e0d626c10" + integrity sha512-2eCtxZXf+kbkMIsXS4poTvT4Yu5rXiRa+9xGVT56raghjmBTKMpFNc9R4IDiB4emao9eO22Ox7CxuJG7BgExqA== + dependencies: + "@babel/helper-plugin-utils" "^7.24.0" -"@babel/plugin-syntax-jsx@^7.18.6", "@babel/plugin-syntax-jsx@^7.21.4": - version "7.21.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.21.4.tgz#f264ed7bf40ffc9ec239edabc17a50c4f5b6fea2" - integrity sha512-5hewiLct5OKyh6PLKEYaFclcqtIgCb6bmELouxjF6up5q3Sov7rOayW4RwhbaBL0dit8rA80GNfY+UuDp2mBbQ== +"@babel/plugin-syntax-jsx@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.24.7.tgz#39a1fa4a7e3d3d7f34e2acc6be585b718d30e02d" + integrity sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ== dependencies: - "@babel/helper-plugin-utils" "^7.20.2" + "@babel/helper-plugin-utils" "^7.24.7" -"@babel/plugin-syntax-logical-assignment-operators@^7.10.4", "@babel/plugin-syntax-logical-assignment-operators@^7.8.3": +"@babel/plugin-syntax-logical-assignment-operators@^7.10.4": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699" integrity sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig== @@ -611,14 +791,14 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-numeric-separator@^7.10.4", "@babel/plugin-syntax-numeric-separator@^7.8.3": +"@babel/plugin-syntax-numeric-separator@^7.10.4": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz#b9b070b3e33570cd9fd07ba7fa91c0dd37b9af97" integrity sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug== dependencies: "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-syntax-object-rest-spread@7.8.3", "@babel/plugin-syntax-object-rest-spread@^7.8.0", "@babel/plugin-syntax-object-rest-spread@^7.8.3": +"@babel/plugin-syntax-object-rest-spread@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== @@ -653,577 +833,1456 @@ dependencies: "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-syntax-typescript@^7.20.0": - version "7.21.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.21.4.tgz#2751948e9b7c6d771a8efa59340c15d4a2891ff8" - integrity sha512-xz0D39NvhQn4t4RNsHmDnnsaQizIlUkdtYvLs8La1BlfjQ6JEwxkJGeqJMW2tAXx+q6H+WFuUTXNdYVpEya0YA== +"@babel/plugin-syntax-typescript@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.23.3.tgz#24f460c85dbbc983cd2b9c4994178bcc01df958f" + integrity sha512-9EiNjVJOMwCO+43TqoTrgQ8jMwcAd0sWyXi9RPfIsLTj4R2MADDDQXELhffaUx/uJv2AYcxBgPwH6j4TIA4ytQ== dependencies: - "@babel/helper-plugin-utils" "^7.20.2" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-arrow-functions@^7.12.1", "@babel/plugin-transform-arrow-functions@^7.20.7": - version "7.20.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.20.7.tgz#bea332b0e8b2dab3dafe55a163d8227531ab0551" - integrity sha512-3poA5E7dzDomxj9WXWwuD6A5F3kc7VXwIJO+E+J8qtDtS+pXPAhrgEyh+9GBwBgPq1Z+bB+/JD60lp5jsN7JPQ== +"@babel/plugin-syntax-typescript@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.24.1.tgz#b3bcc51f396d15f3591683f90239de143c076844" + integrity sha512-Yhnmvy5HZEnHUty6i++gcfH1/l68AHnItFHnaCv6hn9dNh0hQvvQJsxpi4BMBFN5DLeHBuucT/0DgzXif/OyRw== dependencies: - "@babel/helper-plugin-utils" "^7.20.2" + "@babel/helper-plugin-utils" "^7.24.0" -"@babel/plugin-transform-async-to-generator@^7.20.7": - version "7.20.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.20.7.tgz#dfee18623c8cb31deb796aa3ca84dda9cea94354" - integrity sha512-Uo5gwHPT9vgnSXQxqGtpdufUiWp96gk7yiP4Mp5bm1QMkEmLXBO7PAGYbKoJ6DhAwiNkcHFBol/x5zZZkL/t0Q== +"@babel/plugin-syntax-typescript@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.24.7.tgz#58d458271b4d3b6bb27ee6ac9525acbb259bad1c" + integrity sha512-c/+fVeJBB0FeKsFvwytYiUD+LBvhHjGSI0g446PRGdSVGZLRNArBUno2PETbAly3tpiNAQR5XaZ+JslxkotsbA== dependencies: - "@babel/helper-module-imports" "^7.18.6" - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/helper-remap-async-to-generator" "^7.18.9" + "@babel/helper-plugin-utils" "^7.24.7" -"@babel/plugin-transform-block-scoped-functions@^7.18.6": +"@babel/plugin-syntax-unicode-sets-regex@^7.18.6": version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.18.6.tgz#9187bf4ba302635b9d70d986ad70f038726216a8" - integrity sha512-ExUcOqpPWnliRcPqves5HJcJOvHvIIWfuS4sroBUenPuMdmW+SMHDakmtS7qOo13sVppmUijqeTv7qqGsvURpQ== + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz#d49a3b3e6b52e5be6740022317580234a6a47357" + integrity sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg== dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.18.6" "@babel/helper-plugin-utils" "^7.18.6" -"@babel/plugin-transform-block-scoping@^7.12.12", "@babel/plugin-transform-block-scoping@^7.21.0": - version "7.21.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.21.0.tgz#e737b91037e5186ee16b76e7ae093358a5634f02" - integrity sha512-Mdrbunoh9SxwFZapeHVrwFmri16+oYotcZysSzhNIVDwIAb1UV+kvnxULSYq9J3/q5MDG+4X6w8QVgD1zhBXNQ== - dependencies: - "@babel/helper-plugin-utils" "^7.20.2" - -"@babel/plugin-transform-classes@^7.12.1", "@babel/plugin-transform-classes@^7.21.0": - version "7.21.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.21.0.tgz#f469d0b07a4c5a7dbb21afad9e27e57b47031665" - integrity sha512-RZhbYTCEUAe6ntPehC4hlslPWosNHDox+vAs4On/mCLRLfoDVHf6hVEd7kuxr1RnHwJmxFfUM3cZiZRmPxJPXQ== - dependencies: - "@babel/helper-annotate-as-pure" "^7.18.6" - "@babel/helper-compilation-targets" "^7.20.7" - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-function-name" "^7.21.0" - "@babel/helper-optimise-call-expression" "^7.18.6" - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/helper-replace-supers" "^7.20.7" - "@babel/helper-split-export-declaration" "^7.18.6" - globals "^11.1.0" +"@babel/plugin-transform-arrow-functions@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.23.3.tgz#94c6dcfd731af90f27a79509f9ab7fb2120fc38b" + integrity sha512-NzQcQrzaQPkaEwoTm4Mhyl8jI1huEL/WWIEvudjTCMJ9aBZNpsJbMASx7EQECtQQPS/DcnFpo0FIh3LvEO9cxQ== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-computed-properties@^7.20.7": - version "7.20.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.20.7.tgz#704cc2fd155d1c996551db8276d55b9d46e4d0aa" - integrity sha512-Lz7MvBK6DTjElHAmfu6bfANzKcxpyNPeYBGEafyA6E5HtRpjpZwU+u7Qrgz/2OR0z+5TvKYbPdphfSaAcZBrYQ== +"@babel/plugin-transform-arrow-functions@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.24.1.tgz#2bf263617060c9cc45bcdbf492b8cc805082bf27" + integrity sha512-ngT/3NkRhsaep9ck9uj2Xhv9+xB1zShY3tM3g6om4xxCELwCDN4g4Aq5dRn48+0hasAql7s2hdBOysCfNpr4fw== dependencies: - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/template" "^7.20.7" + "@babel/helper-plugin-utils" "^7.24.0" -"@babel/plugin-transform-destructuring@^7.12.1", "@babel/plugin-transform-destructuring@^7.21.3": - version "7.21.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.21.3.tgz#73b46d0fd11cd6ef57dea8a381b1215f4959d401" - integrity sha512-bp6hwMFzuiE4HqYEyoGJ/V2LeIWn+hLVKc4pnj++E5XQptwhtcGmSayM029d/j2X1bPKGTlsyPwAubuU22KhMA== +"@babel/plugin-transform-async-generator-functions@^7.23.3": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.23.4.tgz#93ac8e3531f347fba519b4703f9ff2a75c6ae27a" + integrity sha512-efdkfPhHYTtn0G6n2ddrESE91fgXxjlqLsnUtPWnJs4a4mZIbUaK7ffqKIIUKXSHwcDvaCVX6GXkaJJFqtX7jw== dependencies: - "@babel/helper-plugin-utils" "^7.20.2" + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-remap-async-to-generator" "^7.22.20" + "@babel/plugin-syntax-async-generators" "^7.8.4" -"@babel/plugin-transform-dotall-regex@^7.18.6", "@babel/plugin-transform-dotall-regex@^7.4.4": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.18.6.tgz#b286b3e7aae6c7b861e45bed0a2fafd6b1a4fef8" - integrity sha512-6S3jpun1eEbAxq7TdjLotAsl4WpQI9DxfkycRcKrjhQYzU87qpXdknpBg/e+TdcMehqGnLFi7tnFUBR02Vq6wg== +"@babel/plugin-transform-async-generator-functions@^7.24.3": + version "7.24.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.24.3.tgz#8fa7ae481b100768cc9842c8617808c5352b8b89" + integrity sha512-Qe26CMYVjpQxJ8zxM1340JFNjZaF+ISWpr1Kt/jGo+ZTUzKkfw/pphEWbRCb+lmSM6k/TOgfYLvmbHkUQ0asIg== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-plugin-utils" "^7.24.0" + "@babel/helper-remap-async-to-generator" "^7.22.20" + "@babel/plugin-syntax-async-generators" "^7.8.4" -"@babel/plugin-transform-duplicate-keys@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.18.9.tgz#687f15ee3cdad6d85191eb2a372c4528eaa0ae0e" - integrity sha512-d2bmXCtZXYc59/0SanQKbiWINadaJXqtvIQIzd4+hNwkWBgyCd5F/2t1kXoUdvPMrxzPvhK6EMQRROxsue+mfw== +"@babel/plugin-transform-async-to-generator@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.23.3.tgz#d1f513c7a8a506d43f47df2bf25f9254b0b051fa" + integrity sha512-A7LFsKi4U4fomjqXJlZg/u0ft/n8/7n7lpffUP/ZULx/DtV9SGlNKZolHH6PE8Xl1ngCc0M11OaeZptXVkfKSw== dependencies: - "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-module-imports" "^7.22.15" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-remap-async-to-generator" "^7.22.20" -"@babel/plugin-transform-exponentiation-operator@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.18.6.tgz#421c705f4521888c65e91fdd1af951bfefd4dacd" - integrity sha512-wzEtc0+2c88FVR34aQmiz56dxEkxr2g8DQb/KfaFa1JYXOFVsbhvAonFN6PwVWj++fKmku8NP80plJ5Et4wqHw== +"@babel/plugin-transform-async-to-generator@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.24.1.tgz#0e220703b89f2216800ce7b1c53cb0cf521c37f4" + integrity sha512-AawPptitRXp1y0n4ilKcGbRYWfbbzFWz2NqNu7dacYDtFtz0CMjG64b3LQsb3KIgnf4/obcUL78hfaOS7iCUfw== dependencies: - "@babel/helper-builder-binary-assignment-operator-visitor" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-module-imports" "^7.24.1" + "@babel/helper-plugin-utils" "^7.24.0" + "@babel/helper-remap-async-to-generator" "^7.22.20" -"@babel/plugin-transform-flow-strip-types@^7.21.0": - version "7.21.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.21.0.tgz#6aeca0adcb81dc627c8986e770bfaa4d9812aff5" - integrity sha512-FlFA2Mj87a6sDkW4gfGrQQqwY/dLlBAyJa2dJEZ+FHXUVHBflO2wyKvg+OOEzXfrKYIa4HWl0mgmbCzt0cMb7w== +"@babel/plugin-transform-block-scoped-functions@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.23.3.tgz#fe1177d715fb569663095e04f3598525d98e8c77" + integrity sha512-vI+0sIaPIO6CNuM9Kk5VmXcMVRiOpDh7w2zZt9GXzmE/9KD70CUEVhvPR/etAeNK/FAEkhxQtXOzVF3EuRL41A== dependencies: - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/plugin-syntax-flow" "^7.18.6" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-for-of@^7.12.1", "@babel/plugin-transform-for-of@^7.21.0": - version "7.21.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.21.0.tgz#964108c9988de1a60b4be2354a7d7e245f36e86e" - integrity sha512-LlUYlydgDkKpIY7mcBWvyPPmMcOphEyYA27Ef4xpbh1IiDNLr0kZsos2nf92vz3IccvJI25QUwp86Eo5s6HmBQ== +"@babel/plugin-transform-block-scoped-functions@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.24.1.tgz#1c94799e20fcd5c4d4589523bbc57b7692979380" + integrity sha512-TWWC18OShZutrv9C6mye1xwtam+uNi2bnTOCBUd5sZxyHOiWbU6ztSROofIMrK84uweEZC219POICK/sTYwfgg== dependencies: - "@babel/helper-plugin-utils" "^7.20.2" + "@babel/helper-plugin-utils" "^7.24.0" -"@babel/plugin-transform-function-name@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.18.9.tgz#cc354f8234e62968946c61a46d6365440fc764e0" - integrity sha512-WvIBoRPaJQ5yVHzcnJFor7oS5Ls0PYixlTYE63lCj2RtdQEl15M68FXQlxnG6wdraJIXRdR7KI+hQ7q/9QjrCQ== +"@babel/plugin-transform-block-scoping@^7.23.3": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.23.4.tgz#b2d38589531c6c80fbe25e6b58e763622d2d3cf5" + integrity sha512-0QqbP6B6HOh7/8iNR4CQU2Th/bbRtBp4KS9vcaZd1fZ0wSh5Fyssg0UCIHwxh+ka+pNDREbVLQnHCMHKZfPwfw== dependencies: - "@babel/helper-compilation-targets" "^7.18.9" - "@babel/helper-function-name" "^7.18.9" - "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-literals@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.18.9.tgz#72796fdbef80e56fba3c6a699d54f0de557444bc" - integrity sha512-IFQDSRoTPnrAIrI5zoZv73IFeZu2dhu6irxQjY9rNjTT53VmKg9fenjvoiOWOkJ6mm4jKVPtdMzBY98Fp4Z4cg== +"@babel/plugin-transform-block-scoping@^7.24.4": + version "7.24.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.24.4.tgz#28f5c010b66fbb8ccdeef853bef1935c434d7012" + integrity sha512-nIFUZIpGKDf9O9ttyRXpHFpKC+X3Y5mtshZONuEUYBomAKoM4y029Jr+uB1bHGPhNmK8YXHevDtKDOLmtRrp6g== dependencies: - "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-plugin-utils" "^7.24.0" -"@babel/plugin-transform-member-expression-literals@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.18.6.tgz#ac9fdc1a118620ac49b7e7a5d2dc177a1bfee88e" - integrity sha512-qSF1ihLGO3q+/g48k85tUjD033C29TNTVB2paCwZPVmOsjn9pClvYYrM2VeJpBY2bcNkuny0YUyTNRyRxJ54KA== +"@babel/plugin-transform-class-properties@^7.22.5", "@babel/plugin-transform-class-properties@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.24.1.tgz#bcbf1aef6ba6085cfddec9fc8d58871cf011fc29" + integrity sha512-OMLCXi0NqvJfORTaPQBwqLXHhb93wkBKZ4aNwMl6WtehO7ar+cmp+89iPEQPqxAnxsOKTaMcs3POz3rKayJ72g== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-create-class-features-plugin" "^7.24.1" + "@babel/helper-plugin-utils" "^7.24.0" -"@babel/plugin-transform-modules-amd@^7.20.11": - version "7.20.11" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.20.11.tgz#3daccca8e4cc309f03c3a0c4b41dc4b26f55214a" - integrity sha512-NuzCt5IIYOW0O30UvqktzHYR2ud5bOWbY0yaxWZ6G+aFzOMJvrs5YHNikrbdaT15+KNO31nPOy5Fim3ku6Zb5g== +"@babel/plugin-transform-class-properties@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.23.3.tgz#35c377db11ca92a785a718b6aa4e3ed1eb65dc48" + integrity sha512-uM+AN8yCIjDPccsKGlw271xjJtGii+xQIF/uMPS8H15L12jZTsLfF4o5vNO7d/oUguOyfdikHGc/yi9ge4SGIg== dependencies: - "@babel/helper-module-transforms" "^7.20.11" - "@babel/helper-plugin-utils" "^7.20.2" + "@babel/helper-create-class-features-plugin" "^7.22.15" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-modules-commonjs@^7.21.2": - version "7.21.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.21.2.tgz#6ff5070e71e3192ef2b7e39820a06fb78e3058e7" - integrity sha512-Cln+Yy04Gxua7iPdj6nOV96smLGjpElir5YwzF0LBPKoPlLDNJePNlrGGaybAJkd0zKRnOVXOgizSqPYMNYkzA== +"@babel/plugin-transform-class-static-block@^7.23.3": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.23.4.tgz#2a202c8787a8964dd11dfcedf994d36bfc844ab5" + integrity sha512-nsWu/1M+ggti1SOALj3hfx5FXzAY06fwPJsUZD4/A5e1bWi46VUIWtD+kOX6/IdhXGsXBWllLFDSnqSCdUNydQ== dependencies: - "@babel/helper-module-transforms" "^7.21.2" - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/helper-simple-access" "^7.20.2" + "@babel/helper-create-class-features-plugin" "^7.22.15" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-class-static-block" "^7.14.5" -"@babel/plugin-transform-modules-systemjs@^7.20.11": - version "7.20.11" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.20.11.tgz#467ec6bba6b6a50634eea61c9c232654d8a4696e" - integrity sha512-vVu5g9BPQKSFEmvt2TA4Da5N+QVS66EX21d8uoOihC+OCpUoGvzVsXeqFdtAEfVa5BILAeFt+U7yVmLbQnAJmw== +"@babel/plugin-transform-class-static-block@^7.24.4": + version "7.24.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.24.4.tgz#1a4653c0cf8ac46441ec406dece6e9bc590356a4" + integrity sha512-B8q7Pz870Hz/q9UgP8InNpY01CSLDSCyqX7zcRuv3FcPl87A2G17lASroHWaCtbdIcbYzOZ7kWmXFKbijMSmFg== dependencies: - "@babel/helper-hoist-variables" "^7.18.6" - "@babel/helper-module-transforms" "^7.20.11" - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/helper-validator-identifier" "^7.19.1" + "@babel/helper-create-class-features-plugin" "^7.24.4" + "@babel/helper-plugin-utils" "^7.24.0" + "@babel/plugin-syntax-class-static-block" "^7.14.5" -"@babel/plugin-transform-modules-umd@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.18.6.tgz#81d3832d6034b75b54e62821ba58f28ed0aab4b9" - integrity sha512-dcegErExVeXcRqNtkRU/z8WlBLnvD4MRnHgNs3MytRO1Mn1sHRyhbcpYbVMGclAqOjdW+9cfkdZno9dFdfKLfQ== +"@babel/plugin-transform-classes@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.23.3.tgz#73380c632c095b03e8503c24fd38f95ad41ffacb" + integrity sha512-FGEQmugvAEu2QtgtU0uTASXevfLMFfBeVCIIdcQhn/uBQsMTjBajdnAtanQlOcuihWh10PZ7+HWvc7NtBwP74w== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-compilation-targets" "^7.22.15" + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-function-name" "^7.23.0" + "@babel/helper-optimise-call-expression" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-replace-supers" "^7.22.20" + "@babel/helper-split-export-declaration" "^7.22.6" + globals "^11.1.0" + +"@babel/plugin-transform-classes@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.24.1.tgz#5bc8fc160ed96378184bc10042af47f50884dcb1" + integrity sha512-ZTIe3W7UejJd3/3R4p7ScyyOoafetUShSf4kCqV0O7F/RiHxVj/wRaRnQlrGwflvcehNA8M42HkAiEDYZu2F1Q== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-compilation-targets" "^7.23.6" + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-function-name" "^7.23.0" + "@babel/helper-plugin-utils" "^7.24.0" + "@babel/helper-replace-supers" "^7.24.1" + "@babel/helper-split-export-declaration" "^7.22.6" + globals "^11.1.0" + +"@babel/plugin-transform-computed-properties@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.23.3.tgz#652e69561fcc9d2b50ba4f7ac7f60dcf65e86474" + integrity sha512-dTj83UVTLw/+nbiHqQSFdwO9CbTtwq1DsDqm3CUEtDrZNET5rT5E6bIdTlOftDTDLMYxvxHNEYO4B9SLl8SLZw== dependencies: - "@babel/helper-module-transforms" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/template" "^7.22.15" -"@babel/plugin-transform-named-capturing-groups-regex@^7.20.5": - version "7.20.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.20.5.tgz#626298dd62ea51d452c3be58b285d23195ba69a8" - integrity sha512-mOW4tTzi5iTLnw+78iEq3gr8Aoq4WNRGpmSlrogqaiCBoR1HFhpU4JkpQFOHfeYx3ReVIFWOQJS4aZBRvuZ6mA== +"@babel/plugin-transform-computed-properties@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.24.1.tgz#bc7e787f8e021eccfb677af5f13c29a9934ed8a7" + integrity sha512-5pJGVIUfJpOS+pAqBQd+QMaTD2vCL/HcePooON6pDpHgRp4gNRmzyHTPIkXntwKsq3ayUFVfJaIKPw2pOkOcTw== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.20.5" - "@babel/helper-plugin-utils" "^7.20.2" + "@babel/helper-plugin-utils" "^7.24.0" + "@babel/template" "^7.24.0" -"@babel/plugin-transform-new-target@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.18.6.tgz#d128f376ae200477f37c4ddfcc722a8a1b3246a8" - integrity sha512-DjwFA/9Iu3Z+vrAn+8pBUGcjhxKguSMlsFqeCKbhb9BAV756v0krzVK04CRDi/4aqmk8BsHb4a/gFcaA5joXRw== +"@babel/plugin-transform-destructuring@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.23.3.tgz#8c9ee68228b12ae3dff986e56ed1ba4f3c446311" + integrity sha512-n225npDqjDIr967cMScVKHXJs7rout1q+tt50inyBCPkyZ8KxeI6d+GIbSBTT/w/9WdlWDOej3V9HE5Lgk57gw== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-object-super@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.18.6.tgz#fb3c6ccdd15939b6ff7939944b51971ddc35912c" - integrity sha512-uvGz6zk+pZoS1aTZrOvrbj6Pp/kK2mp45t2B+bTDre2UgsZZ8EZLSJtUg7m/no0zOJUWgFONpB7Zv9W2tSaFlA== +"@babel/plugin-transform-destructuring@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.24.1.tgz#b1e8243af4a0206841973786292b8c8dd8447345" + integrity sha512-ow8jciWqNxR3RYbSNVuF4U2Jx130nwnBnhRw6N6h1bOejNkABmcI5X5oz29K4alWX7vf1C+o6gtKXikzRKkVdw== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/helper-replace-supers" "^7.18.6" + "@babel/helper-plugin-utils" "^7.24.0" -"@babel/plugin-transform-parameters@^7.12.1", "@babel/plugin-transform-parameters@^7.20.7", "@babel/plugin-transform-parameters@^7.21.3": - version "7.21.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.21.3.tgz#18fc4e797cf6d6d972cb8c411dbe8a809fa157db" - integrity sha512-Wxc+TvppQG9xWFYatvCGPvZ6+SIUxQ2ZdiBP+PHYMIjnPXD+uThCshaz4NZOnODAtBjjcVQQ/3OKs9LW28purQ== +"@babel/plugin-transform-dotall-regex@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.23.3.tgz#3f7af6054882ede89c378d0cf889b854a993da50" + integrity sha512-vgnFYDHAKzFaTVp+mneDsIEbnJ2Np/9ng9iviHw3P/KVcgONxpNULEW/51Z/BaFojG2GI2GwwXck5uV1+1NOYQ== dependencies: - "@babel/helper-plugin-utils" "^7.20.2" + "@babel/helper-create-regexp-features-plugin" "^7.22.15" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-property-literals@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.18.6.tgz#e22498903a483448e94e032e9bbb9c5ccbfc93a3" - integrity sha512-cYcs6qlgafTud3PAzrrRNbQtfpQ8+y/+M5tKmksS9+M1ckbH6kzY8MrexEM9mcA6JDsukE19iIRvAyYl463sMg== +"@babel/plugin-transform-dotall-regex@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.24.1.tgz#d56913d2f12795cc9930801b84c6f8c47513ac13" + integrity sha512-p7uUxgSoZwZ2lPNMzUkqCts3xlp8n+o05ikjy7gbtFJSt9gdU88jAmtfmOxHM14noQXBxfgzf2yRWECiNVhTCw== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-create-regexp-features-plugin" "^7.22.15" + "@babel/helper-plugin-utils" "^7.24.0" -"@babel/plugin-transform-react-display-name@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.18.6.tgz#8b1125f919ef36ebdfff061d664e266c666b9415" - integrity sha512-TV4sQ+T013n61uMoygyMRm+xf04Bd5oqFpv2jAEQwSZ8NwQA7zeRPg1LMVg2PWi3zWBz+CLKD+v5bcpZ/BS0aA== +"@babel/plugin-transform-duplicate-keys@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.23.3.tgz#664706ca0a5dfe8d066537f99032fc1dc8b720ce" + integrity sha512-RrqQ+BQmU3Oyav3J+7/myfvRCq7Tbz+kKLLshUmMwNlDHExbGL7ARhajvoBJEvc+fCguPPu887N+3RRXBVKZUA== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-react-jsx-development@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.18.6.tgz#dbe5c972811e49c7405b630e4d0d2e1380c0ddc5" - integrity sha512-SA6HEjwYFKF7WDjWcMcMGUimmw/nhNRDWxr+KaLSCrkD/LMDBvWRmHAYgE1HDeF8KUuI8OAu+RT6EOtKxSW2qA== +"@babel/plugin-transform-duplicate-keys@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.24.1.tgz#5347a797fe82b8d09749d10e9f5b83665adbca88" + integrity sha512-msyzuUnvsjsaSaocV6L7ErfNsa5nDWL1XKNnDePLgmz+WdU4w/J8+AxBMrWfi9m4IxfL5sZQKUPQKDQeeAT6lA== dependencies: - "@babel/plugin-transform-react-jsx" "^7.18.6" + "@babel/helper-plugin-utils" "^7.24.0" -"@babel/plugin-transform-react-jsx@^7.12.12", "@babel/plugin-transform-react-jsx@^7.18.6": - version "7.21.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.21.0.tgz#656b42c2fdea0a6d8762075d58ef9d4e3c4ab8a2" - integrity sha512-6OAWljMvQrZjR2DaNhVfRz6dkCAVV+ymcLUmaf8bccGOHn2v5rHJK3tTpij0BuhdYWP4LLaqj5lwcdlpAAPuvg== +"@babel/plugin-transform-dynamic-import@^7.23.3": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.23.4.tgz#c7629e7254011ac3630d47d7f34ddd40ca535143" + integrity sha512-V6jIbLhdJK86MaLh4Jpghi8ho5fGzt3imHOBu/x0jlBaPYqDoWz4RDXjmMOfnh+JWNaQleEAByZLV0QzBT4YQQ== dependencies: - "@babel/helper-annotate-as-pure" "^7.18.6" - "@babel/helper-module-imports" "^7.18.6" - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/plugin-syntax-jsx" "^7.18.6" - "@babel/types" "^7.21.0" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-dynamic-import" "^7.8.3" -"@babel/plugin-transform-react-pure-annotations@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.18.6.tgz#561af267f19f3e5d59291f9950fd7b9663d0d844" - integrity sha512-I8VfEPg9r2TRDdvnHgPepTKvuRomzA8+u+nhY7qSI1fR2hRNebasZEETLyM5mAUr0Ku56OkXJ0I7NHJnO6cJiQ== +"@babel/plugin-transform-dynamic-import@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.24.1.tgz#2a5a49959201970dd09a5fca856cb651e44439dd" + integrity sha512-av2gdSTyXcJVdI+8aFZsCAtR29xJt0S5tas+Ef8NvBNmD1a+N/3ecMLeMBgfcK+xzsjdLDT6oHt+DFPyeqUbDA== dependencies: - "@babel/helper-annotate-as-pure" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-plugin-utils" "^7.24.0" + "@babel/plugin-syntax-dynamic-import" "^7.8.3" -"@babel/plugin-transform-regenerator@^7.20.5": - version "7.20.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.20.5.tgz#57cda588c7ffb7f4f8483cc83bdcea02a907f04d" - integrity sha512-kW/oO7HPBtntbsahzQ0qSE3tFvkFwnbozz3NWFhLGqH75vLEg+sCGngLlhVkePlCs3Jv0dBBHDzCHxNiFAQKCQ== +"@babel/plugin-transform-exponentiation-operator@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.23.3.tgz#ea0d978f6b9232ba4722f3dbecdd18f450babd18" + integrity sha512-5fhCsl1odX96u7ILKHBj4/Y8vipoqwsJMh4csSA8qFfxrZDEA4Ssku2DyNvMJSmZNOEBT750LfFPbtrnTP90BQ== dependencies: - "@babel/helper-plugin-utils" "^7.20.2" - regenerator-transform "^0.15.1" + "@babel/helper-builder-binary-assignment-operator-visitor" "^7.22.15" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-reserved-words@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.18.6.tgz#b1abd8ebf8edaa5f7fe6bbb8d2133d23b6a6f76a" - integrity sha512-oX/4MyMoypzHjFrT1CdivfKZ+XvIPMFXwwxHp/r0Ddy2Vuomt4HDFGmft1TAY2yiTKiNSsh3kjBAzcM8kSdsjA== +"@babel/plugin-transform-exponentiation-operator@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.24.1.tgz#6650ebeb5bd5c012d5f5f90a26613a08162e8ba4" + integrity sha512-U1yX13dVBSwS23DEAqU+Z/PkwE9/m7QQy8Y9/+Tdb8UWYaGNDYwTLi19wqIAiROr8sXVum9A/rtiH5H0boUcTw== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-builder-binary-assignment-operator-visitor" "^7.22.15" + "@babel/helper-plugin-utils" "^7.24.0" -"@babel/plugin-transform-shorthand-properties@^7.12.1", "@babel/plugin-transform-shorthand-properties@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.18.6.tgz#6d6df7983d67b195289be24909e3f12a8f664dc9" - integrity sha512-eCLXXJqv8okzg86ywZJbRn19YJHU4XUa55oz2wbHhaQVn/MM+XhukiT7SYqp/7o00dg52Rj51Ny+Ecw4oyoygw== +"@babel/plugin-transform-export-namespace-from@^7.23.3": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.23.4.tgz#084c7b25e9a5c8271e987a08cf85807b80283191" + integrity sha512-GzuSBcKkx62dGzZI1WVgTWvkkz84FZO5TC5T8dl/Tht/rAla6Dg/Mz9Yhypg+ezVACf/rgDuQt3kbWEv7LdUDQ== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-export-namespace-from" "^7.8.3" -"@babel/plugin-transform-spread@^7.12.1", "@babel/plugin-transform-spread@^7.20.7": - version "7.20.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.20.7.tgz#c2d83e0b99d3bf83e07b11995ee24bf7ca09401e" - integrity sha512-ewBbHQ+1U/VnH1fxltbJqDeWBU1oNLG8Dj11uIv3xVf7nrQu0bPGe5Rf716r7K5Qz+SqtAOVswoVunoiBtGhxw== +"@babel/plugin-transform-export-namespace-from@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.24.1.tgz#f033541fc036e3efb2dcb58eedafd4f6b8078acd" + integrity sha512-Ft38m/KFOyzKw2UaJFkWG9QnHPG/Q/2SkOrRk4pNBPg5IPZ+dOxcmkK5IyuBcxiNPyyYowPGUReyBvrvZs7IlQ== dependencies: - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/helper-skip-transparent-expression-wrappers" "^7.20.0" + "@babel/helper-plugin-utils" "^7.24.0" + "@babel/plugin-syntax-export-namespace-from" "^7.8.3" -"@babel/plugin-transform-sticky-regex@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.18.6.tgz#c6706eb2b1524028e317720339583ad0f444adcc" - integrity sha512-kfiDrDQ+PBsQDO85yj1icueWMfGfJFKN1KCkndygtu/C9+XUfydLC8Iv5UYJqRwy4zk8EcplRxEOeLyjq1gm6Q== +"@babel/plugin-transform-flow-strip-types@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.24.1.tgz#fa8d0a146506ea195da1671d38eed459242b2dcc" + integrity sha512-iIYPIWt3dUmUKKE10s3W+jsQ3icFkw0JyRVyY1B7G4yK/nngAOHLVx8xlhA6b/Jzl/Y0nis8gjqhqKtRDQqHWQ== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-plugin-utils" "^7.24.0" + "@babel/plugin-syntax-flow" "^7.24.1" -"@babel/plugin-transform-template-literals@^7.12.1", "@babel/plugin-transform-template-literals@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.18.9.tgz#04ec6f10acdaa81846689d63fae117dd9c243a5e" - integrity sha512-S8cOWfT82gTezpYOiVaGHrCbhlHgKhQt8XH5ES46P2XWmX92yisoZywf5km75wv5sYcXDUCLMmMxOLCtthDgMA== +"@babel/plugin-transform-for-of@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.23.3.tgz#afe115ff0fbce735e02868d41489093c63e15559" + integrity sha512-X8jSm8X1CMwxmK878qsUGJRmbysKNbdpTv/O1/v0LuY/ZkZrng5WYiekYSdg9m09OTmDDUWeEDsTE+17WYbAZw== dependencies: - "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-typeof-symbol@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.18.9.tgz#c8cea68263e45addcd6afc9091429f80925762c0" - integrity sha512-SRfwTtF11G2aemAZWivL7PD+C9z52v9EvMqH9BuYbabyPuKUvSWks3oCg6041pT925L4zVFqaVBeECwsmlguEw== +"@babel/plugin-transform-for-of@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.24.1.tgz#67448446b67ab6c091360ce3717e7d3a59e202fd" + integrity sha512-OxBdcnF04bpdQdR3i4giHZNZQn7cm8RQKcSwA17wAAqEELo1ZOwp5FFgeptWUQXFyT9kwHo10aqqauYkRZPCAg== dependencies: - "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-plugin-utils" "^7.24.0" + "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" -"@babel/plugin-transform-typescript@^7.21.3": - version "7.21.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.21.3.tgz#316c5be579856ea890a57ebc5116c5d064658f2b" - integrity sha512-RQxPz6Iqt8T0uw/WsJNReuBpWpBqs/n7mNo18sKLoTbMp+UrEekhH+pKSVC7gWz+DNjo9gryfV8YzCiT45RgMw== +"@babel/plugin-transform-function-name@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.23.3.tgz#8f424fcd862bf84cb9a1a6b42bc2f47ed630f8dc" + integrity sha512-I1QXp1LxIvt8yLaib49dRW5Okt7Q4oaxao6tFVKS/anCdEOMtYwWVKoiOA1p34GOWIZjUK0E+zCp7+l1pfQyiw== dependencies: - "@babel/helper-annotate-as-pure" "^7.18.6" - "@babel/helper-create-class-features-plugin" "^7.21.0" - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/plugin-syntax-typescript" "^7.20.0" + "@babel/helper-compilation-targets" "^7.22.15" + "@babel/helper-function-name" "^7.23.0" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-unicode-escapes@^7.18.10": - version "7.18.10" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.18.10.tgz#1ecfb0eda83d09bbcb77c09970c2dd55832aa246" - integrity sha512-kKAdAI+YzPgGY/ftStBFXTI1LZFju38rYThnfMykS+IXy8BVx+res7s2fxf1l8I35DV2T97ezo6+SGrXz6B3iQ== +"@babel/plugin-transform-function-name@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.24.1.tgz#8cba6f7730626cc4dfe4ca2fa516215a0592b361" + integrity sha512-BXmDZpPlh7jwicKArQASrj8n22/w6iymRnvHYYd2zO30DbE277JO20/7yXJT3QxDPtiQiOxQBbZH4TpivNXIxA== dependencies: - "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-compilation-targets" "^7.23.6" + "@babel/helper-function-name" "^7.23.0" + "@babel/helper-plugin-utils" "^7.24.0" -"@babel/plugin-transform-unicode-regex@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.18.6.tgz#194317225d8c201bbae103364ffe9e2cea36cdca" - integrity sha512-gE7A6Lt7YLnNOL3Pb9BNeZvi+d8l7tcRrG4+pwJjK9hD2xX4mEvjlQW60G9EEmfXVYRPv9VRQcyegIVHCql/AA== +"@babel/plugin-transform-json-strings@^7.23.3": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.23.4.tgz#a871d9b6bd171976efad2e43e694c961ffa3714d" + integrity sha512-81nTOqM1dMwZ/aRXQ59zVubN9wHGqk6UtqRK+/q+ciXmRy8fSolhGVvG09HHRGo4l6fr/c4ZhXUQH0uFW7PZbg== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-json-strings" "^7.8.3" -"@babel/preset-env@^7.11.0", "@babel/preset-env@^7.12.11", "@babel/preset-env@^7.18.6": - version "7.21.4" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.21.4.tgz#a952482e634a8dd8271a3fe5459a16eb10739c58" - integrity sha512-2W57zHs2yDLm6GD5ZpvNn71lZ0B/iypSdIeq25OurDKji6AdzV07qp4s3n1/x5BqtiGaTrPN3nerlSCaC5qNTw== - dependencies: - "@babel/compat-data" "^7.21.4" - "@babel/helper-compilation-targets" "^7.21.4" - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/helper-validator-option" "^7.21.0" - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.18.6" - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.20.7" - "@babel/plugin-proposal-async-generator-functions" "^7.20.7" - "@babel/plugin-proposal-class-properties" "^7.18.6" - "@babel/plugin-proposal-class-static-block" "^7.21.0" - "@babel/plugin-proposal-dynamic-import" "^7.18.6" - "@babel/plugin-proposal-export-namespace-from" "^7.18.9" - "@babel/plugin-proposal-json-strings" "^7.18.6" - "@babel/plugin-proposal-logical-assignment-operators" "^7.20.7" - "@babel/plugin-proposal-nullish-coalescing-operator" "^7.18.6" - "@babel/plugin-proposal-numeric-separator" "^7.18.6" - "@babel/plugin-proposal-object-rest-spread" "^7.20.7" - "@babel/plugin-proposal-optional-catch-binding" "^7.18.6" - "@babel/plugin-proposal-optional-chaining" "^7.21.0" - "@babel/plugin-proposal-private-methods" "^7.18.6" - "@babel/plugin-proposal-private-property-in-object" "^7.21.0" - "@babel/plugin-proposal-unicode-property-regex" "^7.18.6" - "@babel/plugin-syntax-async-generators" "^7.8.4" - "@babel/plugin-syntax-class-properties" "^7.12.13" - "@babel/plugin-syntax-class-static-block" "^7.14.5" - "@babel/plugin-syntax-dynamic-import" "^7.8.3" - "@babel/plugin-syntax-export-namespace-from" "^7.8.3" - "@babel/plugin-syntax-import-assertions" "^7.20.0" +"@babel/plugin-transform-json-strings@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.24.1.tgz#08e6369b62ab3e8a7b61089151b161180c8299f7" + integrity sha512-U7RMFmRvoasscrIFy5xA4gIp8iWnWubnKkKuUGJjsuOH7GfbMkB+XZzeslx2kLdEGdOJDamEmCqOks6e8nv8DQ== + dependencies: + "@babel/helper-plugin-utils" "^7.24.0" "@babel/plugin-syntax-json-strings" "^7.8.3" - "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" - "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" - "@babel/plugin-syntax-numeric-separator" "^7.10.4" - "@babel/plugin-syntax-object-rest-spread" "^7.8.3" - "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" - "@babel/plugin-syntax-optional-chaining" "^7.8.3" - "@babel/plugin-syntax-private-property-in-object" "^7.14.5" - "@babel/plugin-syntax-top-level-await" "^7.14.5" - "@babel/plugin-transform-arrow-functions" "^7.20.7" - "@babel/plugin-transform-async-to-generator" "^7.20.7" - "@babel/plugin-transform-block-scoped-functions" "^7.18.6" - "@babel/plugin-transform-block-scoping" "^7.21.0" - "@babel/plugin-transform-classes" "^7.21.0" - "@babel/plugin-transform-computed-properties" "^7.20.7" - "@babel/plugin-transform-destructuring" "^7.21.3" - "@babel/plugin-transform-dotall-regex" "^7.18.6" - "@babel/plugin-transform-duplicate-keys" "^7.18.9" - "@babel/plugin-transform-exponentiation-operator" "^7.18.6" - "@babel/plugin-transform-for-of" "^7.21.0" - "@babel/plugin-transform-function-name" "^7.18.9" - "@babel/plugin-transform-literals" "^7.18.9" - "@babel/plugin-transform-member-expression-literals" "^7.18.6" - "@babel/plugin-transform-modules-amd" "^7.20.11" - "@babel/plugin-transform-modules-commonjs" "^7.21.2" - "@babel/plugin-transform-modules-systemjs" "^7.20.11" - "@babel/plugin-transform-modules-umd" "^7.18.6" - "@babel/plugin-transform-named-capturing-groups-regex" "^7.20.5" - "@babel/plugin-transform-new-target" "^7.18.6" - "@babel/plugin-transform-object-super" "^7.18.6" - "@babel/plugin-transform-parameters" "^7.21.3" - "@babel/plugin-transform-property-literals" "^7.18.6" - "@babel/plugin-transform-regenerator" "^7.20.5" - "@babel/plugin-transform-reserved-words" "^7.18.6" - "@babel/plugin-transform-shorthand-properties" "^7.18.6" - "@babel/plugin-transform-spread" "^7.20.7" - "@babel/plugin-transform-sticky-regex" "^7.18.6" - "@babel/plugin-transform-template-literals" "^7.18.9" - "@babel/plugin-transform-typeof-symbol" "^7.18.9" - "@babel/plugin-transform-unicode-escapes" "^7.18.10" - "@babel/plugin-transform-unicode-regex" "^7.18.6" - "@babel/preset-modules" "^0.1.5" - "@babel/types" "^7.21.4" - babel-plugin-polyfill-corejs2 "^0.3.3" - babel-plugin-polyfill-corejs3 "^0.6.0" - babel-plugin-polyfill-regenerator "^0.4.1" - core-js-compat "^3.25.1" - semver "^6.3.0" - -"@babel/preset-flow@^7.12.1": - version "7.21.4" - resolved "https://registry.yarnpkg.com/@babel/preset-flow/-/preset-flow-7.21.4.tgz#a5de2a1cafa61f0e0b3af9b30ff0295d38d3608f" - integrity sha512-F24cSq4DIBmhq4OzK3dE63NHagb27OPE3eWR+HLekt4Z3Y5MzIIUGF3LlLgV0gN8vzbDViSY7HnrReNVCJXTeA== - dependencies: - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/helper-validator-option" "^7.21.0" - "@babel/plugin-transform-flow-strip-types" "^7.21.0" - -"@babel/preset-modules@^0.1.5": - version "0.1.5" - resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.5.tgz#ef939d6e7f268827e1841638dc6ff95515e115d9" - integrity sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA== + +"@babel/plugin-transform-literals@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.23.3.tgz#8214665f00506ead73de157eba233e7381f3beb4" + integrity sha512-wZ0PIXRxnwZvl9AYpqNUxpZ5BiTGrYt7kueGQ+N5FiQ7RCOD4cm8iShd6S6ggfVIWaJf2EMk8eRzAh52RfP4rQ== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-proposal-unicode-property-regex" "^7.4.4" - "@babel/plugin-transform-dotall-regex" "^7.4.4" - "@babel/types" "^7.4.4" - esutils "^2.0.2" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/preset-react@^7.12.10": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.18.6.tgz#979f76d6277048dc19094c217b507f3ad517dd2d" - integrity sha512-zXr6atUmyYdiWRVLOZahakYmOBHtWc2WGCkP8PYTgZi0iJXDY2CN180TdrIW4OGOAdLc7TifzDIvtx6izaRIzg== +"@babel/plugin-transform-literals@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.24.1.tgz#0a1982297af83e6b3c94972686067df588c5c096" + integrity sha512-zn9pwz8U7nCqOYIiBaOxoQOtYmMODXTJnkxG4AtX8fPmnCRYWBOHD0qcpwS9e2VDSp1zNJYpdnFMIKb8jmwu6g== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/helper-validator-option" "^7.18.6" - "@babel/plugin-transform-react-display-name" "^7.18.6" - "@babel/plugin-transform-react-jsx" "^7.18.6" - "@babel/plugin-transform-react-jsx-development" "^7.18.6" - "@babel/plugin-transform-react-pure-annotations" "^7.18.6" - -"@babel/preset-typescript@^7.12.7", "@babel/preset-typescript@^7.18.6": - version "7.21.4" - resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.21.4.tgz#b913ac8e6aa8932e47c21b01b4368d8aa239a529" - integrity sha512-sMLNWY37TCdRH/bJ6ZeeOH1nPuanED7Ai9Y/vH31IPqalioJ6ZNFUWONsakhv4r4n+I6gm5lmoE0olkgib/j/A== - dependencies: - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/helper-validator-option" "^7.21.0" - "@babel/plugin-syntax-jsx" "^7.21.4" - "@babel/plugin-transform-modules-commonjs" "^7.21.2" - "@babel/plugin-transform-typescript" "^7.21.3" - -"@babel/register@^7.12.1": - version "7.21.0" - resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.21.0.tgz#c97bf56c2472e063774f31d344c592ebdcefa132" - integrity sha512-9nKsPmYDi5DidAqJaQooxIhsLJiNMkGr8ypQ8Uic7cIox7UCDsM7HuUGxdGT7mSDTYbqzIdsOWzfBton/YJrMw== + "@babel/helper-plugin-utils" "^7.24.0" + +"@babel/plugin-transform-logical-assignment-operators@^7.23.3": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.23.4.tgz#e599f82c51d55fac725f62ce55d3a0886279ecb5" + integrity sha512-Mc/ALf1rmZTP4JKKEhUwiORU+vcfarFVLfcFiolKUo6sewoxSEgl36ak5t+4WamRsNr6nzjZXQjM35WsU+9vbg== dependencies: - clone-deep "^4.0.1" - find-cache-dir "^2.0.0" - make-dir "^2.1.0" - pirates "^4.0.5" - source-map-support "^0.5.16" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" -"@babel/regjsgen@^0.8.0": - version "0.8.0" - resolved "https://registry.yarnpkg.com/@babel/regjsgen/-/regjsgen-0.8.0.tgz#f0ba69b075e1f05fb2825b7fad991e7adbb18310" - integrity sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA== +"@babel/plugin-transform-logical-assignment-operators@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.24.1.tgz#719d8aded1aa94b8fb34e3a785ae8518e24cfa40" + integrity sha512-OhN6J4Bpz+hIBqItTeWJujDOfNP+unqv/NJgyhlpSqgBTPm37KkMmZV6SYcOj+pnDbdcl1qRGV/ZiIjX9Iy34w== + dependencies: + "@babel/helper-plugin-utils" "^7.24.0" + "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" + +"@babel/plugin-transform-member-expression-literals@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.23.3.tgz#e37b3f0502289f477ac0e776b05a833d853cabcc" + integrity sha512-sC3LdDBDi5x96LA+Ytekz2ZPk8i/Ck+DEuDbRAll5rknJ5XRTSaPKEYwomLcs1AA8wg9b3KjIQRsnApj+q51Ag== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-member-expression-literals@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.24.1.tgz#896d23601c92f437af8b01371ad34beb75df4489" + integrity sha512-4ojai0KysTWXzHseJKa1XPNXKRbuUrhkOPY4rEGeR+7ChlJVKxFa3H3Bz+7tWaGKgJAXUWKOGmltN+u9B3+CVg== + dependencies: + "@babel/helper-plugin-utils" "^7.24.0" -"@babel/runtime@7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.12.1.tgz#b4116a6b6711d010b2dad3b7b6e43bf1b9954740" - integrity sha512-J5AIf3vPj3UwXaAzb5j1xM4WAQDX3EMgemF8rjCP3SoW09LfRKAXQKt6CoVYl230P6iWdRcBbnLDDdnqWxZSCA== +"@babel/plugin-transform-modules-amd@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.23.3.tgz#e19b55436a1416829df0a1afc495deedfae17f7d" + integrity sha512-vJYQGxeKM4t8hYCKVBlZX/gtIY2I7mRGFNcm85sgXGMTBcoV3QdVtdpbcWEbzbfUIUZKwvgFT82mRvaQIebZzw== + dependencies: + "@babel/helper-module-transforms" "^7.23.3" + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-modules-amd@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.24.1.tgz#b6d829ed15258536977e9c7cc6437814871ffa39" + integrity sha512-lAxNHi4HVtjnHd5Rxg3D5t99Xm6H7b04hUS7EHIXcUl2EV4yl1gWdqZrNzXnSrHveL9qMdbODlLF55mvgjAfaQ== dependencies: - regenerator-runtime "^0.13.4" + "@babel/helper-module-transforms" "^7.23.3" + "@babel/helper-plugin-utils" "^7.24.0" -"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.10.4", "@babel/runtime@^7.12.13", "@babel/runtime@^7.12.5", "@babel/runtime@^7.13.10", "@babel/runtime@^7.17.2", "@babel/runtime@^7.17.8", "@babel/runtime@^7.19.4", "@babel/runtime@^7.20.6", "@babel/runtime@^7.20.7", "@babel/runtime@^7.3.1", "@babel/runtime@^7.5.0", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.2", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2": - version "7.21.0" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.21.0.tgz#5b55c9d394e5fcf304909a8b00c07dc217b56673" - integrity sha512-xwII0//EObnq89Ji5AKYQaRYiW/nZ3llSv29d49IuxPhKbtJoLP+9QUUZ4nVragQVtaVGeZrpB+ZtG/Pdy/POw== +"@babel/plugin-transform-modules-commonjs@^7.23.0", "@babel/plugin-transform-modules-commonjs@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.24.1.tgz#e71ba1d0d69e049a22bf90b3867e263823d3f1b9" + integrity sha512-szog8fFTUxBfw0b98gEWPaEqF42ZUD/T3bkynW/wtgx2p/XCP55WEsb+VosKceRSd6njipdZvNogqdtI4Q0chw== dependencies: - regenerator-runtime "^0.13.11" + "@babel/helper-module-transforms" "^7.23.3" + "@babel/helper-plugin-utils" "^7.24.0" + "@babel/helper-simple-access" "^7.22.5" -"@babel/standalone@^7.4.5": - version "7.21.4" - resolved "https://registry.yarnpkg.com/@babel/standalone/-/standalone-7.21.4.tgz#f1a7131775df87c526cc393c36d013acd2b3c609" - integrity sha512-Rw4nGqH/iyVeYxARKcz7iGP+njkPsVqJ45TmXMONoGoxooWjXCAs+CUcLeAZdBGCLqgaPvHKCYvIaDT2Iq+KfA== +"@babel/plugin-transform-modules-commonjs@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.23.3.tgz#661ae831b9577e52be57dd8356b734f9700b53b4" + integrity sha512-aVS0F65LKsdNOtcz6FRCpE4OgsP2OFnW46qNxNIX9h3wuzaNcSQsJysuMwqSibC98HPrf2vCgtxKNwS0DAlgcA== + dependencies: + "@babel/helper-module-transforms" "^7.23.3" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-simple-access" "^7.22.5" -"@babel/template@^7.12.7", "@babel/template@^7.18.10", "@babel/template@^7.20.7", "@babel/template@^7.3.3": - version "7.20.7" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.20.7.tgz#a15090c2839a83b02aa996c0b4994005841fd5a8" - integrity sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw== +"@babel/plugin-transform-modules-commonjs@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.24.7.tgz#9fd5f7fdadee9085886b183f1ad13d1ab260f4ab" + integrity sha512-iFI8GDxtevHJ/Z22J5xQpVqFLlMNstcLXh994xifFwxxGslr2ZXXLWgtBeLctOD63UFDArdvN6Tg8RFw+aEmjQ== dependencies: - "@babel/code-frame" "^7.18.6" - "@babel/parser" "^7.20.7" - "@babel/types" "^7.20.7" + "@babel/helper-module-transforms" "^7.24.7" + "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-simple-access" "^7.24.7" -"@babel/traverse@^7.1.0", "@babel/traverse@^7.1.6", "@babel/traverse@^7.11.5", "@babel/traverse@^7.12.11", "@babel/traverse@^7.12.9", "@babel/traverse@^7.13.0", "@babel/traverse@^7.18.6", "@babel/traverse@^7.20.5", "@babel/traverse@^7.20.7", "@babel/traverse@^7.21.0", "@babel/traverse@^7.21.2", "@babel/traverse@^7.21.4", "@babel/traverse@^7.7.0": - version "7.21.4" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.21.4.tgz#a836aca7b116634e97a6ed99976236b3282c9d36" - integrity sha512-eyKrRHKdyZxqDm+fV1iqL9UAHMoIg0nDaGqfIOd8rKH17m5snv7Gn4qgjBoFfLz9APvjFU/ICT00NVCv1Epp8Q== - dependencies: - "@babel/code-frame" "^7.21.4" - "@babel/generator" "^7.21.4" - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-function-name" "^7.21.0" - "@babel/helper-hoist-variables" "^7.18.6" - "@babel/helper-split-export-declaration" "^7.18.6" - "@babel/parser" "^7.21.4" - "@babel/types" "^7.21.4" - debug "^4.1.0" - globals "^11.1.0" +"@babel/plugin-transform-modules-systemjs@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.23.3.tgz#fa7e62248931cb15b9404f8052581c302dd9de81" + integrity sha512-ZxyKGTkF9xT9YJuKQRo19ewf3pXpopuYQd8cDXqNzc3mUNbOME0RKMoZxviQk74hwzfQsEe66dE92MaZbdHKNQ== + dependencies: + "@babel/helper-hoist-variables" "^7.22.5" + "@babel/helper-module-transforms" "^7.23.3" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-validator-identifier" "^7.22.20" -"@babel/types@^7.0.0", "@babel/types@^7.12.11", "@babel/types@^7.12.7", "@babel/types@^7.18.6", "@babel/types@^7.18.9", "@babel/types@^7.2.0", "@babel/types@^7.20.0", "@babel/types@^7.20.2", "@babel/types@^7.20.5", "@babel/types@^7.20.7", "@babel/types@^7.21.0", "@babel/types@^7.21.2", "@babel/types@^7.21.4", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4", "@babel/types@^7.7.0": - version "7.21.4" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.21.4.tgz#2d5d6bb7908699b3b416409ffd3b5daa25b030d4" - integrity sha512-rU2oY501qDxE8Pyo7i/Orqma4ziCOrby0/9mvbDUGEfvZjb279Nk9k19e2fiCxHbRRpY2ZyrgW1eq22mvmOIzA== +"@babel/plugin-transform-modules-systemjs@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.24.1.tgz#2b9625a3d4e445babac9788daec39094e6b11e3e" + integrity sha512-mqQ3Zh9vFO1Tpmlt8QPnbwGHzNz3lpNEMxQb1kAemn/erstyqw1r9KeOlOfo3y6xAnFEcOv2tSyrXfmMk+/YZA== dependencies: - "@babel/helper-string-parser" "^7.19.4" - "@babel/helper-validator-identifier" "^7.19.1" - to-fast-properties "^2.0.0" + "@babel/helper-hoist-variables" "^7.22.5" + "@babel/helper-module-transforms" "^7.23.3" + "@babel/helper-plugin-utils" "^7.24.0" + "@babel/helper-validator-identifier" "^7.22.20" -"@base2/pretty-print-object@1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@base2/pretty-print-object/-/pretty-print-object-1.0.1.tgz#371ba8be66d556812dc7fb169ebc3c08378f69d4" - integrity sha512-4iri8i1AqYHJE2DstZYkyEprg6Pq6sKx3xn5FpySk9sNhH7qN2LLlHJCfDTZRILNwQNPD7mATWM0TBui7uC1pA== +"@babel/plugin-transform-modules-umd@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.23.3.tgz#5d4395fccd071dfefe6585a4411aa7d6b7d769e9" + integrity sha512-zHsy9iXX2nIsCBFPud3jKn1IRPWg3Ing1qOZgeKV39m1ZgIdpJqvlWVeiHBZC6ITRG0MfskhYe9cLgntfSFPIg== + dependencies: + "@babel/helper-module-transforms" "^7.23.3" + "@babel/helper-plugin-utils" "^7.22.5" -"@bcoe/v8-coverage@^0.2.3": - version "0.2.3" - resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" - integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== +"@babel/plugin-transform-modules-umd@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.24.1.tgz#69220c66653a19cf2c0872b9c762b9a48b8bebef" + integrity sha512-tuA3lpPj+5ITfcCluy6nWonSL7RvaG0AOTeAuvXqEKS34lnLzXpDb0dcP6K8jD0zWZFNDVly90AGFJPnm4fOYg== + dependencies: + "@babel/helper-module-transforms" "^7.23.3" + "@babel/helper-plugin-utils" "^7.24.0" -"@binance-chain/javascript-sdk@^4.1.1": - version "4.2.0" - resolved "https://registry.yarnpkg.com/@binance-chain/javascript-sdk/-/javascript-sdk-4.2.0.tgz#9f05e39209d45344c998ad0fe9497f2533413545" - integrity sha512-TGBZ2M1e7XnDCsNfHvNf0Zj8diH81scUzhkiPJ+4cJRZmOZL4yBy6g9dhM4SLUAB3R8t87arexd2BD3C/sfjjQ== - dependencies: - "@babel/runtime" "^7.10.4" - "@ledgerhq/hw-transport-u2f" "^5.9.0" - "@ledgerhq/hw-transport-web-ble" "^5.9.0" - "@types/bech32" "^1.1.2" - "@types/big.js" "^4.0.5" - "@types/bn.js" "^4.11.6" - "@types/crypto-js" "^3.1.43" - "@types/elliptic" "^6.4.12" - "@types/jest" "^25.1.4" - "@types/ledgerhq__hw-transport" "^4.21.2" - "@types/lodash" "^4.14.149" - "@types/node" "^13.9.0" - "@types/pumpify" "^1.4.1" - "@types/tiny-secp256k1" "^1.0.0" - "@types/uuid" "^7.0.0" - axios "^0.19.0" - bech32 "^1.1.3" - big.js "^5.2.2" - bip32 "^2.0.5" - bip39 "^3.0.2" - bn.js "^4.11.8" - camelcase "^5.3.1" - crypto-browserify "^3.12.0" - crypto-js "^3.1.9-1" - elliptic "^6.0.0" - eslint-utils "^1.4.2" - events "^3.0.0" - is_js "^0.9.0" - lodash "^4.17.19" - minimist "^1.2.5" - ndjson "^1.5.0" - protocol-buffers-encodings "^1.1.0" - pumpify "^2.0.1" - secure-random "^1.1.2" - tiny-secp256k1 "^1.1.3" - url "^0.11.0" - uuid "^3.3.2" - websocket-stream "^5.5.0" - optionalDependencies: - "@ledgerhq/hw-transport-node-hid" "^5.10.0" +"@babel/plugin-transform-named-capturing-groups-regex@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.22.5.tgz#67fe18ee8ce02d57c855185e27e3dc959b2e991f" + integrity sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-new-target@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.23.3.tgz#5491bb78ed6ac87e990957cea367eab781c4d980" + integrity sha512-YJ3xKqtJMAT5/TIZnpAR3I+K+WaDowYbN3xyxI8zxx/Gsypwf9B9h0VB+1Nh6ACAAPRS5NSRje0uVv5i79HYGQ== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-new-target@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.24.1.tgz#29c59988fa3d0157de1c871a28cd83096363cc34" + integrity sha512-/rurytBM34hYy0HKZQyA0nHbQgQNFm4Q/BOc9Hflxi2X3twRof7NaE5W46j4kQitm7SvACVRXsa6N/tSZxvPug== + dependencies: + "@babel/helper-plugin-utils" "^7.24.0" + +"@babel/plugin-transform-nullish-coalescing-operator@^7.22.11", "@babel/plugin-transform-nullish-coalescing-operator@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.24.1.tgz#0cd494bb97cb07d428bd651632cb9d4140513988" + integrity sha512-iQ+caew8wRrhCikO5DrUYx0mrmdhkaELgFa+7baMcVuhxIkN7oxt06CZ51D65ugIb1UWRQ8oQe+HXAVM6qHFjw== + dependencies: + "@babel/helper-plugin-utils" "^7.24.0" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" -"@cnakazawa/watch@^1.0.3": - version "1.0.4" - resolved "https://registry.yarnpkg.com/@cnakazawa/watch/-/watch-1.0.4.tgz#f864ae85004d0fcab6f50be9141c4da368d1656a" - integrity sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ== +"@babel/plugin-transform-nullish-coalescing-operator@^7.23.3": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.23.4.tgz#45556aad123fc6e52189ea749e33ce090637346e" + integrity sha512-jHE9EVVqHKAQx+VePv5LLGHjmHSJR76vawFPTdlxR/LVJPfOEGxREQwQfjuZEOPTwG92X3LINSh3M40Rv4zpVA== dependencies: - exec-sh "^0.3.2" - minimist "^1.2.0" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" + +"@babel/plugin-transform-numeric-separator@^7.23.3": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.23.4.tgz#03d08e3691e405804ecdd19dd278a40cca531f29" + integrity sha512-mps6auzgwjRrwKEZA05cOwuDc9FAzoyFS4ZsG/8F43bTLf/TgkJg7QXOrPO1JO599iA3qgK9MXdMGOEC8O1h6Q== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-numeric-separator" "^7.10.4" + +"@babel/plugin-transform-numeric-separator@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.24.1.tgz#5bc019ce5b3435c1cadf37215e55e433d674d4e8" + integrity sha512-7GAsGlK4cNL2OExJH1DzmDeKnRv/LXq0eLUSvudrehVA5Rgg4bIrqEUW29FbKMBRT0ztSqisv7kjP+XIC4ZMNw== + dependencies: + "@babel/helper-plugin-utils" "^7.24.0" + "@babel/plugin-syntax-numeric-separator" "^7.10.4" + +"@babel/plugin-transform-object-rest-spread@^7.23.3": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.23.4.tgz#2b9c2d26bf62710460bdc0d1730d4f1048361b83" + integrity sha512-9x9K1YyeQVw0iOXJlIzwm8ltobIIv7j2iLyP2jIhEbqPRQ7ScNgwQufU2I0Gq11VjyG4gI4yMXt2VFags+1N3g== + dependencies: + "@babel/compat-data" "^7.23.3" + "@babel/helper-compilation-targets" "^7.22.15" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-transform-parameters" "^7.23.3" + +"@babel/plugin-transform-object-rest-spread@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.24.1.tgz#5a3ce73caf0e7871a02e1c31e8b473093af241ff" + integrity sha512-XjD5f0YqOtebto4HGISLNfiNMTTs6tbkFf2TOqJlYKYmbo+mN9Dnpl4SRoofiziuOWMIyq3sZEUqLo3hLITFEA== + dependencies: + "@babel/helper-compilation-targets" "^7.23.6" + "@babel/helper-plugin-utils" "^7.24.0" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-transform-parameters" "^7.24.1" + +"@babel/plugin-transform-object-super@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.23.3.tgz#81fdb636dcb306dd2e4e8fd80db5b2362ed2ebcd" + integrity sha512-BwQ8q0x2JG+3lxCVFohg+KbQM7plfpBwThdW9A6TMtWwLsbDA01Ek2Zb/AgDN39BiZsExm4qrXxjk+P1/fzGrA== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-replace-supers" "^7.22.20" + +"@babel/plugin-transform-object-super@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.24.1.tgz#e71d6ab13483cca89ed95a474f542bbfc20a0520" + integrity sha512-oKJqR3TeI5hSLRxudMjFQ9re9fBVUU0GICqM3J1mi8MqlhVr6hC/ZN4ttAyMuQR6EZZIY6h/exe5swqGNNIkWQ== + dependencies: + "@babel/helper-plugin-utils" "^7.24.0" + "@babel/helper-replace-supers" "^7.24.1" + +"@babel/plugin-transform-optional-catch-binding@^7.23.3": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.23.4.tgz#318066de6dacce7d92fa244ae475aa8d91778017" + integrity sha512-XIq8t0rJPHf6Wvmbn9nFxU6ao4c7WhghTR5WyV8SrJfUFzyxhCm4nhC+iAp3HFhbAKLfYpgzhJ6t4XCtVwqO5A== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" + +"@babel/plugin-transform-optional-catch-binding@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.24.1.tgz#92a3d0efe847ba722f1a4508669b23134669e2da" + integrity sha512-oBTH7oURV4Y+3EUrf6cWn1OHio3qG/PVwO5J03iSJmBg6m2EhKjkAu/xuaXaYwWW9miYtvbWv4LNf0AmR43LUA== + dependencies: + "@babel/helper-plugin-utils" "^7.24.0" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" + +"@babel/plugin-transform-optional-chaining@^7.23.0", "@babel/plugin-transform-optional-chaining@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.24.1.tgz#26e588acbedce1ab3519ac40cc748e380c5291e6" + integrity sha512-n03wmDt+987qXwAgcBlnUUivrZBPZ8z1plL0YvgQalLm+ZE5BMhGm94jhxXtA1wzv1Cu2aaOv1BM9vbVttrzSg== + dependencies: + "@babel/helper-plugin-utils" "^7.24.0" + "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" + +"@babel/plugin-transform-optional-chaining@^7.23.3": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.23.4.tgz#6acf61203bdfc4de9d4e52e64490aeb3e52bd017" + integrity sha512-ZU8y5zWOfjM5vZ+asjgAPwDaBjJzgufjES89Rs4Lpq63O300R/kOz30WCLo6BxxX6QVEilwSlpClnG5cZaikTA== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" + +"@babel/plugin-transform-parameters@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.23.3.tgz#83ef5d1baf4b1072fa6e54b2b0999a7b2527e2af" + integrity sha512-09lMt6UsUb3/34BbECKVbVwrT9bO6lILWln237z7sLaWnMsTi7Yc9fhX5DLpkJzAGfaReXI22wP41SZmnAA3Vw== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-parameters@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.24.1.tgz#983c15d114da190506c75b616ceb0f817afcc510" + integrity sha512-8Jl6V24g+Uw5OGPeWNKrKqXPDw2YDjLc53ojwfMcKwlEoETKU9rU0mHUtcg9JntWI/QYzGAXNWEcVHZ+fR+XXg== + dependencies: + "@babel/helper-plugin-utils" "^7.24.0" + +"@babel/plugin-transform-private-methods@^7.22.5", "@babel/plugin-transform-private-methods@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.24.1.tgz#a0faa1ae87eff077e1e47a5ec81c3aef383dc15a" + integrity sha512-tGvisebwBO5em4PaYNqt4fkw56K2VALsAbAakY0FjTYqJp7gfdrgr7YX76Or8/cpik0W6+tj3rZ0uHU9Oil4tw== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.24.1" + "@babel/helper-plugin-utils" "^7.24.0" + +"@babel/plugin-transform-private-methods@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.23.3.tgz#b2d7a3c97e278bfe59137a978d53b2c2e038c0e4" + integrity sha512-UzqRcRtWsDMTLrRWFvUBDwmw06tCQH9Rl1uAjfh6ijMSmGYQ+fpdB+cnqRC8EMh5tuuxSv0/TejGL+7vyj+50g== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.22.15" + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-private-property-in-object@^7.23.3": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.23.4.tgz#3ec711d05d6608fd173d9b8de39872d8dbf68bf5" + integrity sha512-9G3K1YqTq3F4Vt88Djx1UZ79PDyj+yKRnUy7cZGSMe+a7jkwD259uKKuUzQlPkGam7R+8RJwh5z4xO27fA1o2A== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-create-class-features-plugin" "^7.22.15" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-private-property-in-object" "^7.14.5" + +"@babel/plugin-transform-private-property-in-object@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.24.1.tgz#756443d400274f8fb7896742962cc1b9f25c1f6a" + integrity sha512-pTHxDVa0BpUbvAgX3Gat+7cSciXqUcY9j2VZKTbSB6+VQGpNgNO9ailxTGHSXlqOnX1Hcx1Enme2+yv7VqP9bg== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-create-class-features-plugin" "^7.24.1" + "@babel/helper-plugin-utils" "^7.24.0" + "@babel/plugin-syntax-private-property-in-object" "^7.14.5" + +"@babel/plugin-transform-property-literals@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.23.3.tgz#54518f14ac4755d22b92162e4a852d308a560875" + integrity sha512-jR3Jn3y7cZp4oEWPFAlRsSWjxKe4PZILGBSd4nis1TsC5qeSpb+nrtihJuDhNI7QHiVbUaiXa0X2RZY3/TI6Nw== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-property-literals@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.24.1.tgz#d6a9aeab96f03749f4eebeb0b6ea8e90ec958825" + integrity sha512-LetvD7CrHmEx0G442gOomRr66d7q8HzzGGr4PMHGr+5YIm6++Yke+jxj246rpvsbyhJwCLxcTn6zW1P1BSenqA== + dependencies: + "@babel/helper-plugin-utils" "^7.24.0" + +"@babel/plugin-transform-react-display-name@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.23.3.tgz#70529f034dd1e561045ad3c8152a267f0d7b6200" + integrity sha512-GnvhtVfA2OAtzdX58FJxU19rhoGeQzyVndw3GgtdECQvQFXPEZIOVULHVZGAYmOgmqjXpVpfocAbSjh99V/Fqw== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-react-jsx-development@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.22.5.tgz#e716b6edbef972a92165cd69d92f1255f7e73e87" + integrity sha512-bDhuzwWMuInwCYeDeMzyi7TaBgRQei6DqxhbyniL7/VG4RSS7HtSL2QbY4eESy1KJqlWt8g3xeEBGPuo+XqC8A== + dependencies: + "@babel/plugin-transform-react-jsx" "^7.22.5" + +"@babel/plugin-transform-react-jsx@^7.22.15", "@babel/plugin-transform-react-jsx@^7.22.5": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.23.4.tgz#393f99185110cea87184ea47bcb4a7b0c2e39312" + integrity sha512-5xOpoPguCZCRbo/JeHlloSkTA8Bld1J/E1/kLfD1nsuiW1m8tduTA1ERCgIZokDflX/IBzKcqR3l7VlRgiIfHA== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-module-imports" "^7.22.15" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-jsx" "^7.23.3" + "@babel/types" "^7.23.4" + +"@babel/plugin-transform-react-pure-annotations@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.23.3.tgz#fabedbdb8ee40edf5da96f3ecfc6958e3783b93c" + integrity sha512-qMFdSS+TUhB7Q/3HVPnEdYJDQIk57jkntAwSuz9xfSE4n+3I+vHYCli3HoHawN1Z3RfCz/y1zXA/JXjG6cVImQ== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-regenerator@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.23.3.tgz#141afd4a2057298602069fce7f2dc5173e6c561c" + integrity sha512-KP+75h0KghBMcVpuKisx3XTu9Ncut8Q8TuvGO4IhY+9D5DFEckQefOuIsB/gQ2tG71lCke4NMrtIPS8pOj18BQ== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + regenerator-transform "^0.15.2" + +"@babel/plugin-transform-regenerator@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.24.1.tgz#625b7545bae52363bdc1fbbdc7252b5046409c8c" + integrity sha512-sJwZBCzIBE4t+5Q4IGLaaun5ExVMRY0lYwos/jNecjMrVCygCdph3IKv0tkP5Fc87e/1+bebAmEAGBfnRD+cnw== + dependencies: + "@babel/helper-plugin-utils" "^7.24.0" + regenerator-transform "^0.15.2" + +"@babel/plugin-transform-reserved-words@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.23.3.tgz#4130dcee12bd3dd5705c587947eb715da12efac8" + integrity sha512-QnNTazY54YqgGxwIexMZva9gqbPa15t/x9VS+0fsEFWplwVpXYZivtgl43Z1vMpc1bdPP2PP8siFeVcnFvA3Cg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-reserved-words@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.24.1.tgz#8de729f5ecbaaf5cf83b67de13bad38a21be57c1" + integrity sha512-JAclqStUfIwKN15HrsQADFgeZt+wexNQ0uLhuqvqAUFoqPMjEcFCYZBhq0LUdz6dZK/mD+rErhW71fbx8RYElg== + dependencies: + "@babel/helper-plugin-utils" "^7.24.0" + +"@babel/plugin-transform-shorthand-properties@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.23.3.tgz#97d82a39b0e0c24f8a981568a8ed851745f59210" + integrity sha512-ED2fgqZLmexWiN+YNFX26fx4gh5qHDhn1O2gvEhreLW2iI63Sqm4llRLCXALKrCnbN4Jy0VcMQZl/SAzqug/jg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-shorthand-properties@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.24.1.tgz#ba9a09144cf55d35ec6b93a32253becad8ee5b55" + integrity sha512-LyjVB1nsJ6gTTUKRjRWx9C1s9hE7dLfP/knKdrfeH9UPtAGjYGgxIbFfx7xyLIEWs7Xe1Gnf8EWiUqfjLhInZA== + dependencies: + "@babel/helper-plugin-utils" "^7.24.0" + +"@babel/plugin-transform-spread@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.23.3.tgz#41d17aacb12bde55168403c6f2d6bdca563d362c" + integrity sha512-VvfVYlrlBVu+77xVTOAoxQ6mZbnIq5FM0aGBSFEcIh03qHf+zNqA4DC/3XMUozTg7bZV3e3mZQ0i13VB6v5yUg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" + +"@babel/plugin-transform-spread@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.24.1.tgz#a1acf9152cbf690e4da0ba10790b3ac7d2b2b391" + integrity sha512-KjmcIM+fxgY+KxPVbjelJC6hrH1CgtPmTvdXAfn3/a9CnWGSTY7nH4zm5+cjmWJybdcPSsD0++QssDsjcpe47g== + dependencies: + "@babel/helper-plugin-utils" "^7.24.0" + "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" + +"@babel/plugin-transform-sticky-regex@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.23.3.tgz#dec45588ab4a723cb579c609b294a3d1bd22ff04" + integrity sha512-HZOyN9g+rtvnOU3Yh7kSxXrKbzgrm5X4GncPY1QOquu7epga5MxKHVpYu2hvQnry/H+JjckSYRb93iNfsioAGg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-sticky-regex@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.24.1.tgz#f03e672912c6e203ed8d6e0271d9c2113dc031b9" + integrity sha512-9v0f1bRXgPVcPrngOQvLXeGNNVLc8UjMVfebo9ka0WF3/7+aVUHmaJVT3sa0XCzEFioPfPHZiOcYG9qOsH63cw== + dependencies: + "@babel/helper-plugin-utils" "^7.24.0" + +"@babel/plugin-transform-template-literals@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.23.3.tgz#5f0f028eb14e50b5d0f76be57f90045757539d07" + integrity sha512-Flok06AYNp7GV2oJPZZcP9vZdszev6vPBkHLwxwSpaIqx75wn6mUd3UFWsSsA0l8nXAKkyCmL/sR02m8RYGeHg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-template-literals@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.24.1.tgz#15e2166873a30d8617e3e2ccadb86643d327aab7" + integrity sha512-WRkhROsNzriarqECASCNu/nojeXCDTE/F2HmRgOzi7NGvyfYGq1NEjKBK3ckLfRgGc6/lPAqP0vDOSw3YtG34g== + dependencies: + "@babel/helper-plugin-utils" "^7.24.0" + +"@babel/plugin-transform-typeof-symbol@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.23.3.tgz#9dfab97acc87495c0c449014eb9c547d8966bca4" + integrity sha512-4t15ViVnaFdrPC74be1gXBSMzXk3B4Us9lP7uLRQHTFpV5Dvt33pn+2MyyNxmN3VTTm3oTrZVMUmuw3oBnQ2oQ== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-typeof-symbol@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.24.1.tgz#6831f78647080dec044f7e9f68003d99424f94c7" + integrity sha512-CBfU4l/A+KruSUoW+vTQthwcAdwuqbpRNB8HQKlZABwHRhsdHZ9fezp4Sn18PeAlYxTNiLMlx4xUBV3AWfg1BA== + dependencies: + "@babel/helper-plugin-utils" "^7.24.0" + +"@babel/plugin-transform-typescript@^7.23.3": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.23.4.tgz#da12914d17b3c4b307f32c5fd91fbfdf17d56f86" + integrity sha512-39hCCOl+YUAyMOu6B9SmUTiHUU0t/CxJNUmY3qRdJujbqi+lrQcL11ysYUsAvFWPBdhihrv1z0oRG84Yr3dODQ== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-create-class-features-plugin" "^7.22.15" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-typescript" "^7.23.3" + +"@babel/plugin-transform-typescript@^7.24.1": + version "7.24.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.24.4.tgz#03e0492537a4b953e491f53f2bc88245574ebd15" + integrity sha512-79t3CQ8+oBGk/80SQ8MN3Bs3obf83zJ0YZjDmDaEZN8MqhMI760apl5z6a20kFeMXBwJX99VpKT8CKxEBp5H1g== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-create-class-features-plugin" "^7.24.4" + "@babel/helper-plugin-utils" "^7.24.0" + "@babel/plugin-syntax-typescript" "^7.24.1" + +"@babel/plugin-transform-typescript@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.24.7.tgz#b006b3e0094bf0813d505e0c5485679eeaf4a881" + integrity sha512-iLD3UNkgx2n/HrjBesVbYX6j0yqn/sJktvbtKKgcaLIQ4bTTQ8obAypc1VpyHPD2y4Phh9zHOaAt8e/L14wCpw== + dependencies: + "@babel/helper-annotate-as-pure" "^7.24.7" + "@babel/helper-create-class-features-plugin" "^7.24.7" + "@babel/helper-plugin-utils" "^7.24.7" + "@babel/plugin-syntax-typescript" "^7.24.7" + +"@babel/plugin-transform-unicode-escapes@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.23.3.tgz#1f66d16cab01fab98d784867d24f70c1ca65b925" + integrity sha512-OMCUx/bU6ChE3r4+ZdylEqAjaQgHAgipgW8nsCfu5pGqDcFytVd91AwRvUJSBZDz0exPGgnjoqhgRYLRjFZc9Q== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-unicode-escapes@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.24.1.tgz#fb3fa16676549ac7c7449db9b342614985c2a3a4" + integrity sha512-RlkVIcWT4TLI96zM660S877E7beKlQw7Ig+wqkKBiWfj0zH5Q4h50q6er4wzZKRNSYpfo6ILJ+hrJAGSX2qcNw== + dependencies: + "@babel/helper-plugin-utils" "^7.24.0" + +"@babel/plugin-transform-unicode-property-regex@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.23.3.tgz#19e234129e5ffa7205010feec0d94c251083d7ad" + integrity sha512-KcLIm+pDZkWZQAFJ9pdfmh89EwVfmNovFBcXko8szpBeF8z68kWIPeKlmSOkT9BXJxs2C0uk+5LxoxIv62MROA== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.22.15" + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-unicode-property-regex@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.24.1.tgz#56704fd4d99da81e5e9f0c0c93cabd91dbc4889e" + integrity sha512-Ss4VvlfYV5huWApFsF8/Sq0oXnGO+jB+rijFEFugTd3cwSObUSnUi88djgR5528Csl0uKlrI331kRqe56Ov2Ng== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.22.15" + "@babel/helper-plugin-utils" "^7.24.0" + +"@babel/plugin-transform-unicode-regex@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.23.3.tgz#26897708d8f42654ca4ce1b73e96140fbad879dc" + integrity sha512-wMHpNA4x2cIA32b/ci3AfwNgheiva2W0WUKWTK7vBHBhDKfPsc5cFGNWm69WBqpwd86u1qwZ9PWevKqm1A3yAw== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.22.15" + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-unicode-regex@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.24.1.tgz#57c3c191d68f998ac46b708380c1ce4d13536385" + integrity sha512-2A/94wgZgxfTsiLaQ2E36XAOdcZmGAaEEgVmxQWwZXWkGhvoHbaqXcKnU8zny4ycpu3vNqg0L/PcCiYtHtA13g== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.22.15" + "@babel/helper-plugin-utils" "^7.24.0" + +"@babel/plugin-transform-unicode-sets-regex@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.23.3.tgz#4fb6f0a719c2c5859d11f6b55a050cc987f3799e" + integrity sha512-W7lliA/v9bNR83Qc3q1ip9CQMZ09CcHDbHfbLRDNuAhn1Mvkr1ZNF7hPmztMQvtTGVLJ9m8IZqWsTkXOml8dbw== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.22.15" + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-unicode-sets-regex@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.24.1.tgz#c1ea175b02afcffc9cf57a9c4658326625165b7f" + integrity sha512-fqj4WuzzS+ukpgerpAoOnMfQXwUHFxXUZUE84oL2Kao2N8uSlvcpnAidKASgsNgzZHBsHWvcm8s9FPWUhAb8fA== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.22.15" + "@babel/helper-plugin-utils" "^7.24.0" + +"@babel/preset-env@^7.21.4": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.23.3.tgz#d299e0140a7650684b95c62be2db0ef8c975143e" + integrity sha512-ovzGc2uuyNfNAs/jyjIGxS8arOHS5FENZaNn4rtE7UdKMMkqHCvboHfcuhWLZNX5cB44QfcGNWjaevxMzzMf+Q== + dependencies: + "@babel/compat-data" "^7.23.3" + "@babel/helper-compilation-targets" "^7.22.15" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-validator-option" "^7.22.15" + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.23.3" + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.23.3" + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly" "^7.23.3" + "@babel/plugin-proposal-private-property-in-object" "7.21.0-placeholder-for-preset-env.2" + "@babel/plugin-syntax-async-generators" "^7.8.4" + "@babel/plugin-syntax-class-properties" "^7.12.13" + "@babel/plugin-syntax-class-static-block" "^7.14.5" + "@babel/plugin-syntax-dynamic-import" "^7.8.3" + "@babel/plugin-syntax-export-namespace-from" "^7.8.3" + "@babel/plugin-syntax-import-assertions" "^7.23.3" + "@babel/plugin-syntax-import-attributes" "^7.23.3" + "@babel/plugin-syntax-import-meta" "^7.10.4" + "@babel/plugin-syntax-json-strings" "^7.8.3" + "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" + "@babel/plugin-syntax-numeric-separator" "^7.10.4" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" + "@babel/plugin-syntax-private-property-in-object" "^7.14.5" + "@babel/plugin-syntax-top-level-await" "^7.14.5" + "@babel/plugin-syntax-unicode-sets-regex" "^7.18.6" + "@babel/plugin-transform-arrow-functions" "^7.23.3" + "@babel/plugin-transform-async-generator-functions" "^7.23.3" + "@babel/plugin-transform-async-to-generator" "^7.23.3" + "@babel/plugin-transform-block-scoped-functions" "^7.23.3" + "@babel/plugin-transform-block-scoping" "^7.23.3" + "@babel/plugin-transform-class-properties" "^7.23.3" + "@babel/plugin-transform-class-static-block" "^7.23.3" + "@babel/plugin-transform-classes" "^7.23.3" + "@babel/plugin-transform-computed-properties" "^7.23.3" + "@babel/plugin-transform-destructuring" "^7.23.3" + "@babel/plugin-transform-dotall-regex" "^7.23.3" + "@babel/plugin-transform-duplicate-keys" "^7.23.3" + "@babel/plugin-transform-dynamic-import" "^7.23.3" + "@babel/plugin-transform-exponentiation-operator" "^7.23.3" + "@babel/plugin-transform-export-namespace-from" "^7.23.3" + "@babel/plugin-transform-for-of" "^7.23.3" + "@babel/plugin-transform-function-name" "^7.23.3" + "@babel/plugin-transform-json-strings" "^7.23.3" + "@babel/plugin-transform-literals" "^7.23.3" + "@babel/plugin-transform-logical-assignment-operators" "^7.23.3" + "@babel/plugin-transform-member-expression-literals" "^7.23.3" + "@babel/plugin-transform-modules-amd" "^7.23.3" + "@babel/plugin-transform-modules-commonjs" "^7.23.3" + "@babel/plugin-transform-modules-systemjs" "^7.23.3" + "@babel/plugin-transform-modules-umd" "^7.23.3" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.22.5" + "@babel/plugin-transform-new-target" "^7.23.3" + "@babel/plugin-transform-nullish-coalescing-operator" "^7.23.3" + "@babel/plugin-transform-numeric-separator" "^7.23.3" + "@babel/plugin-transform-object-rest-spread" "^7.23.3" + "@babel/plugin-transform-object-super" "^7.23.3" + "@babel/plugin-transform-optional-catch-binding" "^7.23.3" + "@babel/plugin-transform-optional-chaining" "^7.23.3" + "@babel/plugin-transform-parameters" "^7.23.3" + "@babel/plugin-transform-private-methods" "^7.23.3" + "@babel/plugin-transform-private-property-in-object" "^7.23.3" + "@babel/plugin-transform-property-literals" "^7.23.3" + "@babel/plugin-transform-regenerator" "^7.23.3" + "@babel/plugin-transform-reserved-words" "^7.23.3" + "@babel/plugin-transform-shorthand-properties" "^7.23.3" + "@babel/plugin-transform-spread" "^7.23.3" + "@babel/plugin-transform-sticky-regex" "^7.23.3" + "@babel/plugin-transform-template-literals" "^7.23.3" + "@babel/plugin-transform-typeof-symbol" "^7.23.3" + "@babel/plugin-transform-unicode-escapes" "^7.23.3" + "@babel/plugin-transform-unicode-property-regex" "^7.23.3" + "@babel/plugin-transform-unicode-regex" "^7.23.3" + "@babel/plugin-transform-unicode-sets-regex" "^7.23.3" + "@babel/preset-modules" "0.1.6-no-external-plugins" + babel-plugin-polyfill-corejs2 "^0.4.6" + babel-plugin-polyfill-corejs3 "^0.8.5" + babel-plugin-polyfill-regenerator "^0.5.3" + core-js-compat "^3.31.0" + semver "^6.3.1" + +"@babel/preset-env@^7.23.2": + version "7.24.4" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.24.4.tgz#46dbbcd608771373b88f956ffb67d471dce0d23b" + integrity sha512-7Kl6cSmYkak0FK/FXjSEnLJ1N9T/WA2RkMhu17gZ/dsxKJUuTYNIylahPTzqpLyJN4WhDif8X0XK1R8Wsguo/A== + dependencies: + "@babel/compat-data" "^7.24.4" + "@babel/helper-compilation-targets" "^7.23.6" + "@babel/helper-plugin-utils" "^7.24.0" + "@babel/helper-validator-option" "^7.23.5" + "@babel/plugin-bugfix-firefox-class-in-computed-class-key" "^7.24.4" + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.24.1" + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.24.1" + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly" "^7.24.1" + "@babel/plugin-proposal-private-property-in-object" "7.21.0-placeholder-for-preset-env.2" + "@babel/plugin-syntax-async-generators" "^7.8.4" + "@babel/plugin-syntax-class-properties" "^7.12.13" + "@babel/plugin-syntax-class-static-block" "^7.14.5" + "@babel/plugin-syntax-dynamic-import" "^7.8.3" + "@babel/plugin-syntax-export-namespace-from" "^7.8.3" + "@babel/plugin-syntax-import-assertions" "^7.24.1" + "@babel/plugin-syntax-import-attributes" "^7.24.1" + "@babel/plugin-syntax-import-meta" "^7.10.4" + "@babel/plugin-syntax-json-strings" "^7.8.3" + "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" + "@babel/plugin-syntax-numeric-separator" "^7.10.4" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" + "@babel/plugin-syntax-private-property-in-object" "^7.14.5" + "@babel/plugin-syntax-top-level-await" "^7.14.5" + "@babel/plugin-syntax-unicode-sets-regex" "^7.18.6" + "@babel/plugin-transform-arrow-functions" "^7.24.1" + "@babel/plugin-transform-async-generator-functions" "^7.24.3" + "@babel/plugin-transform-async-to-generator" "^7.24.1" + "@babel/plugin-transform-block-scoped-functions" "^7.24.1" + "@babel/plugin-transform-block-scoping" "^7.24.4" + "@babel/plugin-transform-class-properties" "^7.24.1" + "@babel/plugin-transform-class-static-block" "^7.24.4" + "@babel/plugin-transform-classes" "^7.24.1" + "@babel/plugin-transform-computed-properties" "^7.24.1" + "@babel/plugin-transform-destructuring" "^7.24.1" + "@babel/plugin-transform-dotall-regex" "^7.24.1" + "@babel/plugin-transform-duplicate-keys" "^7.24.1" + "@babel/plugin-transform-dynamic-import" "^7.24.1" + "@babel/plugin-transform-exponentiation-operator" "^7.24.1" + "@babel/plugin-transform-export-namespace-from" "^7.24.1" + "@babel/plugin-transform-for-of" "^7.24.1" + "@babel/plugin-transform-function-name" "^7.24.1" + "@babel/plugin-transform-json-strings" "^7.24.1" + "@babel/plugin-transform-literals" "^7.24.1" + "@babel/plugin-transform-logical-assignment-operators" "^7.24.1" + "@babel/plugin-transform-member-expression-literals" "^7.24.1" + "@babel/plugin-transform-modules-amd" "^7.24.1" + "@babel/plugin-transform-modules-commonjs" "^7.24.1" + "@babel/plugin-transform-modules-systemjs" "^7.24.1" + "@babel/plugin-transform-modules-umd" "^7.24.1" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.22.5" + "@babel/plugin-transform-new-target" "^7.24.1" + "@babel/plugin-transform-nullish-coalescing-operator" "^7.24.1" + "@babel/plugin-transform-numeric-separator" "^7.24.1" + "@babel/plugin-transform-object-rest-spread" "^7.24.1" + "@babel/plugin-transform-object-super" "^7.24.1" + "@babel/plugin-transform-optional-catch-binding" "^7.24.1" + "@babel/plugin-transform-optional-chaining" "^7.24.1" + "@babel/plugin-transform-parameters" "^7.24.1" + "@babel/plugin-transform-private-methods" "^7.24.1" + "@babel/plugin-transform-private-property-in-object" "^7.24.1" + "@babel/plugin-transform-property-literals" "^7.24.1" + "@babel/plugin-transform-regenerator" "^7.24.1" + "@babel/plugin-transform-reserved-words" "^7.24.1" + "@babel/plugin-transform-shorthand-properties" "^7.24.1" + "@babel/plugin-transform-spread" "^7.24.1" + "@babel/plugin-transform-sticky-regex" "^7.24.1" + "@babel/plugin-transform-template-literals" "^7.24.1" + "@babel/plugin-transform-typeof-symbol" "^7.24.1" + "@babel/plugin-transform-unicode-escapes" "^7.24.1" + "@babel/plugin-transform-unicode-property-regex" "^7.24.1" + "@babel/plugin-transform-unicode-regex" "^7.24.1" + "@babel/plugin-transform-unicode-sets-regex" "^7.24.1" + "@babel/preset-modules" "0.1.6-no-external-plugins" + babel-plugin-polyfill-corejs2 "^0.4.10" + babel-plugin-polyfill-corejs3 "^0.10.4" + babel-plugin-polyfill-regenerator "^0.6.1" + core-js-compat "^3.31.0" + semver "^6.3.1" + +"@babel/preset-flow@^7.22.15": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/preset-flow/-/preset-flow-7.24.1.tgz#da7196c20c2d7dd4e98cfd8b192fe53b5eb6f0bb" + integrity sha512-sWCV2G9pcqZf+JHyv/RyqEIpFypxdCSxWIxQjpdaQxenNog7cN1pr76hg8u0Fz8Qgg0H4ETkGcJnXL8d4j0PPA== + dependencies: + "@babel/helper-plugin-utils" "^7.24.0" + "@babel/helper-validator-option" "^7.23.5" + "@babel/plugin-transform-flow-strip-types" "^7.24.1" + +"@babel/preset-modules@0.1.6-no-external-plugins": + version "0.1.6-no-external-plugins" + resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz#ccb88a2c49c817236861fee7826080573b8a923a" + integrity sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/types" "^7.4.4" + esutils "^2.0.2" + +"@babel/preset-react@^7.18.6": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.23.3.tgz#f73ca07e7590f977db07eb54dbe46538cc015709" + integrity sha512-tbkHOS9axH6Ysf2OUEqoSZ6T3Fa2SrNH6WTWSPBboxKzdxNc9qOICeLXkNG0ZEwbQ1HY8liwOce4aN/Ceyuq6w== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-validator-option" "^7.22.15" + "@babel/plugin-transform-react-display-name" "^7.23.3" + "@babel/plugin-transform-react-jsx" "^7.22.15" + "@babel/plugin-transform-react-jsx-development" "^7.22.5" + "@babel/plugin-transform-react-pure-annotations" "^7.23.3" + +"@babel/preset-typescript@^7.21.4": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.23.3.tgz#14534b34ed5b6d435aa05f1ae1c5e7adcc01d913" + integrity sha512-17oIGVlqz6CchO9RFYn5U6ZpWRZIngayYCtrPRSgANSwC2V1Jb+iP74nVxzzXJte8b8BYxrL1yY96xfhTBrNNQ== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-validator-option" "^7.22.15" + "@babel/plugin-syntax-jsx" "^7.23.3" + "@babel/plugin-transform-modules-commonjs" "^7.23.3" + "@babel/plugin-transform-typescript" "^7.23.3" + +"@babel/preset-typescript@^7.23.0": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.24.1.tgz#89bdf13a3149a17b3b2a2c9c62547f06db8845ec" + integrity sha512-1DBaMmRDpuYQBPWD8Pf/WEwCrtgRHxsZnP4mIy9G/X+hFfbI47Q2G4t1Paakld84+qsk2fSsUPMKg71jkoOOaQ== + dependencies: + "@babel/helper-plugin-utils" "^7.24.0" + "@babel/helper-validator-option" "^7.23.5" + "@babel/plugin-syntax-jsx" "^7.24.1" + "@babel/plugin-transform-modules-commonjs" "^7.24.1" + "@babel/plugin-transform-typescript" "^7.24.1" + +"@babel/preset-typescript@^7.23.3": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.24.7.tgz#66cd86ea8f8c014855671d5ea9a737139cbbfef1" + integrity sha512-SyXRe3OdWwIwalxDg5UtJnJQO+YPcTfwiIY2B0Xlddh9o7jpWLvv8X1RthIeDOxQ+O1ML5BLPCONToObyVQVuQ== + dependencies: + "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-validator-option" "^7.24.7" + "@babel/plugin-syntax-jsx" "^7.24.7" + "@babel/plugin-transform-modules-commonjs" "^7.24.7" + "@babel/plugin-transform-typescript" "^7.24.7" + +"@babel/register@^7.22.15": + version "7.23.7" + resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.23.7.tgz#485a5e7951939d21304cae4af1719fdb887bc038" + integrity sha512-EjJeB6+kvpk+Y5DAkEAmbOBEFkh9OASx0huoEkqYTFxAZHzOAX2Oh5uwAUuL2rUddqfM0SA+KPXV2TbzoZ2kvQ== + dependencies: + clone-deep "^4.0.1" + find-cache-dir "^2.0.0" + make-dir "^2.1.0" + pirates "^4.0.6" + source-map-support "^0.5.16" + +"@babel/regjsgen@^0.8.0": + version "0.8.0" + resolved "https://registry.yarnpkg.com/@babel/regjsgen/-/regjsgen-0.8.0.tgz#f0ba69b075e1f05fb2825b7fad991e7adbb18310" + integrity sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA== + +"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.12.13", "@babel/runtime@^7.12.5", "@babel/runtime@^7.13.10", "@babel/runtime@^7.17.2", "@babel/runtime@^7.17.8", "@babel/runtime@^7.20.13", "@babel/runtime@^7.20.6", "@babel/runtime@^7.21.0", "@babel/runtime@^7.3.1", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.4.tgz#36fa1d2b36db873d25ec631dcc4923fdc1cf2e2e" + integrity sha512-2Yv65nlWnWlSpe3fXEyX5i7fx5kIKo4Qbcj+hMO0odwaneFjfXw5fdum+4yL20O0QiaHpia0cYQ9xpNMqrBwHg== + dependencies: + regenerator-runtime "^0.14.0" + +"@babel/runtime@^7.23.4": + version "7.24.4" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.24.4.tgz#de795accd698007a66ba44add6cc86542aff1edd" + integrity sha512-dkxf7+hn8mFBwKjs9bvBlArzLVxVbS8usaPUDd5p2a9JCL9tB8OaOVN1isD4+Xyk4ns89/xeOmbQvgdK7IIVdA== + dependencies: + regenerator-runtime "^0.14.0" + +"@babel/runtime@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.24.7.tgz#f4f0d5530e8dbdf59b3451b9b3e594b6ba082e12" + integrity sha512-UwgBRMjJP+xv857DCngvqXI3Iq6J4v0wXmwc6sapg+zyhbwmQX67LUEFrkK5tbyJ30jGuG3ZvWpBiB9LCy1kWw== + dependencies: + regenerator-runtime "^0.14.0" + +"@babel/standalone@^7.4.5": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/standalone/-/standalone-7.23.4.tgz#e5266b448f7d5f834c8bfaf8b777d60f6507c626" + integrity sha512-cXT2Xi9YVJEi7kLjqoeZBXjrNt1PASOh4Zi3jp5yXT06Gt4ZeRETfYH9y5x3RQhFTpNxaA1300lzK1obiy6tcQ== + +"@babel/template@^7.22.15": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.22.15.tgz#09576efc3830f0430f4548ef971dde1350ef2f38" + integrity sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w== + dependencies: + "@babel/code-frame" "^7.22.13" + "@babel/parser" "^7.22.15" + "@babel/types" "^7.22.15" + +"@babel/template@^7.24.0": + version "7.24.0" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.24.0.tgz#c6a524aa93a4a05d66aaf31654258fae69d87d50" + integrity sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA== + dependencies: + "@babel/code-frame" "^7.23.5" + "@babel/parser" "^7.24.0" + "@babel/types" "^7.24.0" + +"@babel/template@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.24.7.tgz#02efcee317d0609d2c07117cb70ef8fb17ab7315" + integrity sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig== + dependencies: + "@babel/code-frame" "^7.24.7" + "@babel/parser" "^7.24.7" + "@babel/types" "^7.24.7" + +"@babel/traverse@^7.18.9", "@babel/traverse@^7.23.2", "@babel/traverse@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.24.1.tgz#d65c36ac9dd17282175d1e4a3c49d5b7988f530c" + integrity sha512-xuU6o9m68KeqZbQuDt2TcKSxUw/mrsvavlEqQ1leZ/B+C9tk6E4sRWy97WaXgvq5E+nU3cXMxv3WKOCanVMCmQ== + dependencies: + "@babel/code-frame" "^7.24.1" + "@babel/generator" "^7.24.1" + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-function-name" "^7.23.0" + "@babel/helper-hoist-variables" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" + "@babel/parser" "^7.24.1" + "@babel/types" "^7.24.0" + debug "^4.3.1" + globals "^11.1.0" + +"@babel/traverse@^7.23.3", "@babel/traverse@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.23.4.tgz#c2790f7edf106d059a0098770fe70801417f3f85" + integrity sha512-IYM8wSUwunWTB6tFC2dkKZhxbIjHoWemdK+3f8/wq8aKhbUscxD5MX72ubd90fxvFknaLPeGw5ycU84V1obHJg== + dependencies: + "@babel/code-frame" "^7.23.4" + "@babel/generator" "^7.23.4" + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-function-name" "^7.23.0" + "@babel/helper-hoist-variables" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" + "@babel/parser" "^7.23.4" + "@babel/types" "^7.23.4" + debug "^4.1.0" + globals "^11.1.0" + +"@babel/traverse@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.24.7.tgz#de2b900163fa741721ba382163fe46a936c40cf5" + integrity sha512-yb65Ed5S/QAcewNPh0nZczy9JdYXkkAbIsEo+P7BE7yO3txAY30Y/oPa3QkQ5It3xVG2kpKMg9MsdxZaO31uKA== + dependencies: + "@babel/code-frame" "^7.24.7" + "@babel/generator" "^7.24.7" + "@babel/helper-environment-visitor" "^7.24.7" + "@babel/helper-function-name" "^7.24.7" + "@babel/helper-hoist-variables" "^7.24.7" + "@babel/helper-split-export-declaration" "^7.24.7" + "@babel/parser" "^7.24.7" + "@babel/types" "^7.24.7" + debug "^4.3.1" + globals "^11.1.0" + +"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.21.2", "@babel/types@^7.21.3", "@babel/types@^7.22.15", "@babel/types@^7.22.19", "@babel/types@^7.22.5", "@babel/types@^7.23.0", "@babel/types@^7.23.3", "@babel/types@^7.23.4", "@babel/types@^7.4.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.23.4.tgz#7206a1810fc512a7f7f7d4dace4cb4c1c9dbfb8e" + integrity sha512-7uIFwVYpoplT5jp/kVv6EF93VaJ8H+Yn5IczYiaAi98ajzjfoZfslet/e0sLh+wVBjb2qqIut1b0S26VSafsSQ== + dependencies: + "@babel/helper-string-parser" "^7.23.4" + "@babel/helper-validator-identifier" "^7.22.20" + to-fast-properties "^2.0.0" + +"@babel/types@^7.18.9", "@babel/types@^7.24.0": + version "7.24.0" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.24.0.tgz#3b951f435a92e7333eba05b7566fd297960ea1bf" + integrity sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w== + dependencies: + "@babel/helper-string-parser" "^7.23.4" + "@babel/helper-validator-identifier" "^7.22.20" + to-fast-properties "^2.0.0" + +"@babel/types@^7.24.7": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.24.7.tgz#6027fe12bc1aa724cd32ab113fb7f1988f1f66f2" + integrity sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q== + dependencies: + "@babel/helper-string-parser" "^7.24.7" + "@babel/helper-validator-identifier" "^7.24.7" + to-fast-properties "^2.0.0" + +"@base2/pretty-print-object@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@base2/pretty-print-object/-/pretty-print-object-1.0.1.tgz#371ba8be66d556812dc7fb169ebc3c08378f69d4" + integrity sha512-4iri8i1AqYHJE2DstZYkyEprg6Pq6sKx3xn5FpySk9sNhH7qN2LLlHJCfDTZRILNwQNPD7mATWM0TBui7uC1pA== + +"@bcoe/v8-coverage@^0.2.3": + version "0.2.3" + resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" + integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== + +"@chromatic-com/storybook@^1.3.3": + version "1.3.3" + resolved "https://registry.yarnpkg.com/@chromatic-com/storybook/-/storybook-1.3.3.tgz#102d173d7e67cbc7f974648eaa459aa3d3d53f91" + integrity sha512-1y9r691T5vVGDZ0HY3YrCXUnvtrT2YrhDuvDZSvYSNUVpM/Imz6i1dnNMKb3eoI1qRsH55mI4zCt+Iq94NLedQ== + dependencies: + chromatic "^11.3.0" + filesize "^10.0.12" + jsonfile "^6.1.0" + react-confetti "^6.1.0" + strip-ansi "^7.1.0" + +"@classic-terra/terra.proto@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@classic-terra/terra.proto/-/terra.proto-1.1.0.tgz#e314d89f59b49e79a04db25f66f658e5e5aa1890" + integrity sha512-bYhQG5LUaGF0KPRY9hYT/HEcd1QExZPQd6zLV/rQkCe/eDxfwFRLzZHpaaAdfWoAAZjsRWqJbUCqCg7gXBbJpw== + dependencies: + "@improbable-eng/grpc-web" "^0.14.1" + google-protobuf "^3.17.3" + long "^4.0.0" + protobufjs "~6.11.2" "@colors/colors@1.5.0": version "1.5.0" resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.5.0.tgz#bb504579c1cae923e6576a4f5da43d25f97bdbd9" integrity sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ== +"@commitlint/cli@^18.6.1": + version "18.6.1" + resolved "https://registry.yarnpkg.com/@commitlint/cli/-/cli-18.6.1.tgz#78bffdfa00d6f01425d53096954993d83f2b343d" + integrity sha512-5IDE0a+lWGdkOvKH892HHAZgbAjcj1mT5QrfA/SVbLJV/BbBMGyKN0W5mhgjekPJJwEQdVNvhl9PwUacY58Usw== + dependencies: + "@commitlint/format" "^18.6.1" + "@commitlint/lint" "^18.6.1" + "@commitlint/load" "^18.6.1" + "@commitlint/read" "^18.6.1" + "@commitlint/types" "^18.6.1" + execa "^5.0.0" + lodash.isfunction "^3.0.9" + resolve-from "5.0.0" + resolve-global "1.0.0" + yargs "^17.0.0" + +"@commitlint/config-conventional@^18.6.2": + version "18.6.2" + resolved "https://registry.yarnpkg.com/@commitlint/config-conventional/-/config-conventional-18.6.2.tgz#617f3ee761578040cade530631058699642cbd78" + integrity sha512-PcgSYg1AKGQIwDQKbaHtJsfqYy4uJTC7crLVZ83lfjcPaec4Pry2vLeaWej7ao2KsT20l9dWoMPpEGg8LWdUuA== + dependencies: + "@commitlint/types" "^18.6.1" + conventional-changelog-conventionalcommits "^7.0.2" + +"@commitlint/config-validator@^18.6.1": + version "18.6.1" + resolved "https://registry.yarnpkg.com/@commitlint/config-validator/-/config-validator-18.6.1.tgz#e0d71a99c984a68586c7ae7afd3f52342022fae8" + integrity sha512-05uiToBVfPhepcQWE1ZQBR/Io3+tb3gEotZjnI4tTzzPk16NffN6YABgwFQCLmzZefbDcmwWqJWc2XT47q7Znw== + dependencies: + "@commitlint/types" "^18.6.1" + ajv "^8.11.0" + +"@commitlint/ensure@^18.6.1": + version "18.6.1" + resolved "https://registry.yarnpkg.com/@commitlint/ensure/-/ensure-18.6.1.tgz#17141e083200ca94d8480dc23b0e8f8b1fd37b7f" + integrity sha512-BPm6+SspyxQ7ZTsZwXc7TRQL5kh5YWt3euKmEIBZnocMFkJevqs3fbLRb8+8I/cfbVcAo4mxRlpTPfz8zX7SnQ== + dependencies: + "@commitlint/types" "^18.6.1" + lodash.camelcase "^4.3.0" + lodash.kebabcase "^4.1.1" + lodash.snakecase "^4.1.1" + lodash.startcase "^4.4.0" + lodash.upperfirst "^4.3.1" + +"@commitlint/execute-rule@^18.6.1": + version "18.6.1" + resolved "https://registry.yarnpkg.com/@commitlint/execute-rule/-/execute-rule-18.6.1.tgz#18175e043fe6fb5fceea7b8530316c644f93dfe6" + integrity sha512-7s37a+iWyJiGUeMFF6qBlyZciUkF8odSAnHijbD36YDctLhGKoYltdvuJ/AFfRm6cBLRtRk9cCVPdsEFtt/2rg== + +"@commitlint/format@^18.6.1": + version "18.6.1" + resolved "https://registry.yarnpkg.com/@commitlint/format/-/format-18.6.1.tgz#5f2b8b3ae4d8d80bd9239178e97df63e5b8d280a" + integrity sha512-K8mNcfU/JEFCharj2xVjxGSF+My+FbUHoqR+4GqPGrHNqXOGNio47ziiR4HQUPKtiNs05o8/WyLBoIpMVOP7wg== + dependencies: + "@commitlint/types" "^18.6.1" + chalk "^4.1.0" + +"@commitlint/is-ignored@^18.6.1": + version "18.6.1" + resolved "https://registry.yarnpkg.com/@commitlint/is-ignored/-/is-ignored-18.6.1.tgz#4ee08ba91ff3defb06e0ef19259a9c6734a8d06e" + integrity sha512-MOfJjkEJj/wOaPBw5jFjTtfnx72RGwqYIROABudOtJKW7isVjFe9j0t8xhceA02QebtYf4P/zea4HIwnXg8rvA== + dependencies: + "@commitlint/types" "^18.6.1" + semver "7.6.0" + +"@commitlint/lint@^18.6.1": + version "18.6.1" + resolved "https://registry.yarnpkg.com/@commitlint/lint/-/lint-18.6.1.tgz#fe3834636c99ee14534a8eb3832831ac362e9fd8" + integrity sha512-8WwIFo3jAuU+h1PkYe5SfnIOzp+TtBHpFr4S8oJWhu44IWKuVx6GOPux3+9H1iHOan/rGBaiacicZkMZuluhfQ== + dependencies: + "@commitlint/is-ignored" "^18.6.1" + "@commitlint/parse" "^18.6.1" + "@commitlint/rules" "^18.6.1" + "@commitlint/types" "^18.6.1" + +"@commitlint/load@^18.6.1": + version "18.6.1" + resolved "https://registry.yarnpkg.com/@commitlint/load/-/load-18.6.1.tgz#fb79ed7ee8b5897a9b5c274c1e24eda9162df816" + integrity sha512-p26x8734tSXUHoAw0ERIiHyW4RaI4Bj99D8YgUlVV9SedLf8hlWAfyIFhHRIhfPngLlCe0QYOdRKYFt8gy56TA== + dependencies: + "@commitlint/config-validator" "^18.6.1" + "@commitlint/execute-rule" "^18.6.1" + "@commitlint/resolve-extends" "^18.6.1" + "@commitlint/types" "^18.6.1" + chalk "^4.1.0" + cosmiconfig "^8.3.6" + cosmiconfig-typescript-loader "^5.0.0" + lodash.isplainobject "^4.0.6" + lodash.merge "^4.6.2" + lodash.uniq "^4.5.0" + resolve-from "^5.0.0" + +"@commitlint/message@^18.6.1": + version "18.6.1" + resolved "https://registry.yarnpkg.com/@commitlint/message/-/message-18.6.1.tgz#107bd40923ad23d2de56c92a68b179ebfb7e314e" + integrity sha512-VKC10UTMLcpVjMIaHHsY1KwhuTQtdIKPkIdVEwWV+YuzKkzhlI3aNy6oo1eAN6b/D2LTtZkJe2enHmX0corYRw== + +"@commitlint/parse@^18.6.1": + version "18.6.1" + resolved "https://registry.yarnpkg.com/@commitlint/parse/-/parse-18.6.1.tgz#2946b814125e907b9c4d63d3e71d0c1b54b30b62" + integrity sha512-eS/3GREtvVJqGZrwAGRwR9Gdno3YcZ6Xvuaa+vUF8j++wsmxrA2En3n0ccfVO2qVOLJC41ni7jSZhQiJpMPGOQ== + dependencies: + "@commitlint/types" "^18.6.1" + conventional-changelog-angular "^7.0.0" + conventional-commits-parser "^5.0.0" + +"@commitlint/read@^18.6.1": + version "18.6.1" + resolved "https://registry.yarnpkg.com/@commitlint/read/-/read-18.6.1.tgz#8c138311ed9749427920c369f6276be136f2aa50" + integrity sha512-ia6ODaQFzXrVul07ffSgbZGFajpe8xhnDeLIprLeyfz3ivQU1dIoHp7yz0QIorZ6yuf4nlzg4ZUkluDrGN/J/w== + dependencies: + "@commitlint/top-level" "^18.6.1" + "@commitlint/types" "^18.6.1" + git-raw-commits "^2.0.11" + minimist "^1.2.6" + +"@commitlint/resolve-extends@^18.6.1": + version "18.6.1" + resolved "https://registry.yarnpkg.com/@commitlint/resolve-extends/-/resolve-extends-18.6.1.tgz#f0572c682fc24dbabe2e0f42873261e0fa42c91a" + integrity sha512-ifRAQtHwK+Gj3Bxj/5chhc4L2LIc3s30lpsyW67yyjsETR6ctHAHRu1FSpt0KqahK5xESqoJ92v6XxoDRtjwEQ== + dependencies: + "@commitlint/config-validator" "^18.6.1" + "@commitlint/types" "^18.6.1" + import-fresh "^3.0.0" + lodash.mergewith "^4.6.2" + resolve-from "^5.0.0" + resolve-global "^1.0.0" + +"@commitlint/rules@^18.6.1": + version "18.6.1" + resolved "https://registry.yarnpkg.com/@commitlint/rules/-/rules-18.6.1.tgz#da25aeffe6c0e1c7625e44f46089fb8860986caf" + integrity sha512-kguM6HxZDtz60v/zQYOe0voAtTdGybWXefA1iidjWYmyUUspO1zBPQEmJZ05/plIAqCVyNUTAiRPWIBKLCrGew== + dependencies: + "@commitlint/ensure" "^18.6.1" + "@commitlint/message" "^18.6.1" + "@commitlint/to-lines" "^18.6.1" + "@commitlint/types" "^18.6.1" + execa "^5.0.0" + +"@commitlint/to-lines@^18.6.1": + version "18.6.1" + resolved "https://registry.yarnpkg.com/@commitlint/to-lines/-/to-lines-18.6.1.tgz#d28827a4a540c98eea1aae31dafd66f80b2f1b9e" + integrity sha512-Gl+orGBxYSNphx1+83GYeNy5N0dQsHBQ9PJMriaLQDB51UQHCVLBT/HBdOx5VaYksivSf5Os55TLePbRLlW50Q== + +"@commitlint/top-level@^18.6.1": + version "18.6.1" + resolved "https://registry.yarnpkg.com/@commitlint/top-level/-/top-level-18.6.1.tgz#429fcb985e3beaba9b17e05c0ae61926c647baf0" + integrity sha512-HyiHQZUTf0+r0goTCDs/bbVv/LiiQ7AVtz6KIar+8ZrseB9+YJAIo8HQ2IC2QT1y3N1lbW6OqVEsTHjbT6hGSw== + dependencies: + find-up "^5.0.0" + +"@commitlint/types@^18.6.1": + version "18.6.1" + resolved "https://registry.yarnpkg.com/@commitlint/types/-/types-18.6.1.tgz#7eb3ab2d799d9166fbb98b96b0744581e59a4ad4" + integrity sha512-gwRLBLra/Dozj2OywopeuHj2ac26gjGkz2cZ+86cTJOdtWfiRRr4+e77ZDAGc6MDWxaWheI+mAV5TLWWRwqrFg== + dependencies: + chalk "^4.1.0" + "@confio/ics23@^0.6.8": version "0.6.8" resolved "https://registry.yarnpkg.com/@confio/ics23/-/ics23-0.6.8.tgz#2a6b4f1f2b7b20a35d9a0745bb5a446e72930b3d" @@ -1242,15 +2301,25 @@ "@cosmjs/math" "0.27.1" "@cosmjs/utils" "0.27.1" -"@cosmjs/amino@^0.29.5": - version "0.29.5" - resolved "https://registry.yarnpkg.com/@cosmjs/amino/-/amino-0.29.5.tgz#053b4739a90b15b9e2b781ccd484faf64bd49aec" - integrity sha512-Qo8jpC0BiziTSUqpkNatBcwtKNhCovUnFul9SlT/74JUCdLYaeG5hxr3q1cssQt++l4LvlcpF+OUXL48XjNjLw== +"@cosmjs/amino@^0.25.4", "@cosmjs/amino@^0.25.6": + version "0.25.6" + resolved "https://registry.yarnpkg.com/@cosmjs/amino/-/amino-0.25.6.tgz#cdf9632253bfab7b1d2ef967124953d7bf16351f" + integrity sha512-9dXN2W7LHjDtJUGNsQ9ok0DfxeN3ca/TXnxCR3Ikh/5YqBqxI8Gel1J9PQO9L6EheYyh045Wff4bsMaLjyEeqQ== dependencies: - "@cosmjs/crypto" "^0.29.5" - "@cosmjs/encoding" "^0.29.5" - "@cosmjs/math" "^0.29.5" - "@cosmjs/utils" "^0.29.5" + "@cosmjs/crypto" "^0.25.6" + "@cosmjs/encoding" "^0.25.6" + "@cosmjs/math" "^0.25.6" + "@cosmjs/utils" "^0.25.6" + +"@cosmjs/amino@^0.31.3": + version "0.31.3" + resolved "https://registry.yarnpkg.com/@cosmjs/amino/-/amino-0.31.3.tgz#0f4aa6bd68331c71bd51b187fa64f00eb075db0a" + integrity sha512-36emtUq895sPRX8PTSOnG+lhJDCVyIcE0Tr5ct59sUbgQiI14y43vj/4WAlJ/utSOxy+Zhj9wxcs4AZfu0BHsw== + dependencies: + "@cosmjs/crypto" "^0.31.3" + "@cosmjs/encoding" "^0.31.3" + "@cosmjs/math" "^0.31.3" + "@cosmjs/utils" "^0.31.3" "@cosmjs/crypto@0.27.1": version "0.27.1" @@ -1286,18 +2355,34 @@ sha.js "^2.4.11" unorm "^1.5.0" -"@cosmjs/crypto@^0.29.5": - version "0.29.5" - resolved "https://registry.yarnpkg.com/@cosmjs/crypto/-/crypto-0.29.5.tgz#ab99fc382b93d8a8db075780cf07487a0f9519fd" - integrity sha512-2bKkaLGictaNL0UipQCL6C1afaisv6k8Wr/GCLx9FqiyFkh9ZgRHDyetD64ZsjnWV/N/D44s/esI+k6oPREaiQ== +"@cosmjs/crypto@^0.25.6": + version "0.25.6" + resolved "https://registry.yarnpkg.com/@cosmjs/crypto/-/crypto-0.25.6.tgz#695d2d0d2195bdbdd5825d415385646244900bbb" + integrity sha512-ec+YcQLrg2ibcxtNrh4FqQnG9kG9IE/Aik2NH6+OXQdFU/qFuBTxSFcKDgzzBOChwlkXwydllM9Jjbp+dgIzRw== + dependencies: + "@cosmjs/encoding" "^0.25.6" + "@cosmjs/math" "^0.25.6" + "@cosmjs/utils" "^0.25.6" + bip39 "^3.0.2" + bn.js "^4.11.8" + elliptic "^6.5.3" + js-sha3 "^0.8.0" + libsodium-wrappers "^0.7.6" + ripemd160 "^2.0.2" + sha.js "^2.4.11" + +"@cosmjs/crypto@^0.31.3": + version "0.31.3" + resolved "https://registry.yarnpkg.com/@cosmjs/crypto/-/crypto-0.31.3.tgz#c752cb6d682fdc735dcb45a2519f89c56ba16c26" + integrity sha512-vRbvM9ZKR2017TO73dtJ50KxoGcFzKtKI7C8iO302BQ5p+DuB+AirUg1952UpSoLfv5ki9O416MFANNg8UN/EQ== dependencies: - "@cosmjs/encoding" "^0.29.5" - "@cosmjs/math" "^0.29.5" - "@cosmjs/utils" "^0.29.5" + "@cosmjs/encoding" "^0.31.3" + "@cosmjs/math" "^0.31.3" + "@cosmjs/utils" "^0.31.3" "@noble/hashes" "^1" bn.js "^5.2.0" elliptic "^6.5.4" - libsodium-wrappers "^0.7.6" + libsodium-wrappers-sumo "^0.7.11" "@cosmjs/encoding@0.27.1": version "0.27.1" @@ -1326,21 +2411,30 @@ bech32 "^1.1.4" readonly-date "^1.0.0" -"@cosmjs/encoding@^0.29.5": - version "0.29.5" - resolved "https://registry.yarnpkg.com/@cosmjs/encoding/-/encoding-0.29.5.tgz#009a4b1c596cdfd326f30ccfa79f5e56daa264f2" - integrity sha512-G4rGl/Jg4dMCw5u6PEZHZcoHnUBlukZODHbm/wcL4Uu91fkn5jVo5cXXZcvs4VCkArVGrEj/52eUgTZCmOBGWQ== +"@cosmjs/encoding@^0.25.6": + version "0.25.6" + resolved "https://registry.yarnpkg.com/@cosmjs/encoding/-/encoding-0.25.6.tgz#da741a33eaf063a6d3611d7d68db5ca3938e0ef5" + integrity sha512-0imUOB8XkUstI216uznPaX1hqgvLQ2Xso3zJj5IV5oJuNlsfDj9nt/iQxXWbJuettc6gvrFfpf+Vw2vBZSZ75g== dependencies: base64-js "^1.3.0" bech32 "^1.1.4" readonly-date "^1.0.0" -"@cosmjs/json-rpc@^0.29.5": - version "0.29.5" - resolved "https://registry.yarnpkg.com/@cosmjs/json-rpc/-/json-rpc-0.29.5.tgz#5e483a9bd98a6270f935adf0dfd8a1e7eb777fe4" - integrity sha512-C78+X06l+r9xwdM1yFWIpGl03LhB9NdM1xvZpQHwgCOl0Ir/WV8pw48y3Ez2awAoUBRfTeejPe4KvrE6NoIi/w== +"@cosmjs/encoding@^0.31.3": + version "0.31.3" + resolved "https://registry.yarnpkg.com/@cosmjs/encoding/-/encoding-0.31.3.tgz#2519d9c9ae48368424971f253775c4580b54c5aa" + integrity sha512-6IRtG0fiVYwyP7n+8e54uTx2pLYijO48V3t9TLiROERm5aUAIzIlz6Wp0NYaI5he9nh1lcEGJ1lkquVKFw3sUg== dependencies: - "@cosmjs/stream" "^0.29.5" + base64-js "^1.3.0" + bech32 "^1.1.4" + readonly-date "^1.0.0" + +"@cosmjs/json-rpc@^0.31.3": + version "0.31.3" + resolved "https://registry.yarnpkg.com/@cosmjs/json-rpc/-/json-rpc-0.31.3.tgz#11e5cf0f6d9ab426dff470bb8d68d5d31cd6ab13" + integrity sha512-7LVYerXjnm69qqYR3uA6LGCrBW2EO5/F7lfJxAmY+iII2C7xO3a0vAjMSt5zBBh29PXrJVS6c2qRP22W1Le2Wg== + dependencies: + "@cosmjs/stream" "^0.31.3" xstream "^11.14.0" "@cosmjs/launchpad@^0.24.0-alpha.25", "@cosmjs/launchpad@^0.24.1": @@ -1389,10 +2483,17 @@ dependencies: bn.js "^4.11.8" -"@cosmjs/math@^0.29.5": - version "0.29.5" - resolved "https://registry.yarnpkg.com/@cosmjs/math/-/math-0.29.5.tgz#722c96e080d6c2b62215ce9f4c70da7625b241b6" - integrity sha512-2GjKcv+A9f86MAWYLUkjhw1/WpRl2R1BTb3m9qPG7lzMA7ioYff9jY5SPCfafKdxM4TIQGxXQlYGewQL16O68Q== +"@cosmjs/math@^0.25.6": + version "0.25.6" + resolved "https://registry.yarnpkg.com/@cosmjs/math/-/math-0.25.6.tgz#25c7b106aaded889a5b80784693caa9e654b0c28" + integrity sha512-Fmyc9FJ8KMU34n7rdapMJrT/8rx5WhMw2F7WLBu7AVLcBh0yWsXIcMSJCoPHTOnMIiABjXsnrrwEaLrOOBfu6A== + dependencies: + bn.js "^4.11.8" + +"@cosmjs/math@^0.31.3": + version "0.31.3" + resolved "https://registry.yarnpkg.com/@cosmjs/math/-/math-0.31.3.tgz#767f7263d12ba1b9ed2f01f68d857597839fd957" + integrity sha512-kZ2C6glA5HDb9hLz1WrftAjqdTBb3fWQsRR+Us2HsjAYdeE6M3VdXMsYCP5M3yiihal1WDwAY2U7HmfJw7Uh4A== dependencies: bn.js "^5.2.0" @@ -1405,66 +2506,75 @@ long "^4.0.0" protobufjs "~6.10.2" -"@cosmjs/proto-signing@^0.29.5": - version "0.29.5" - resolved "https://registry.yarnpkg.com/@cosmjs/proto-signing/-/proto-signing-0.29.5.tgz#af3b62a46c2c2f1d2327d678b13b7262db1fe87c" - integrity sha512-QRrS7CiKaoETdgIqvi/7JC2qCwCR7lnWaUsTzh/XfRy3McLkEd+cXbKAW3cygykv7IN0VAEIhZd2lyIfT8KwNA== - dependencies: - "@cosmjs/amino" "^0.29.5" - "@cosmjs/crypto" "^0.29.5" - "@cosmjs/encoding" "^0.29.5" - "@cosmjs/math" "^0.29.5" - "@cosmjs/utils" "^0.29.5" - cosmjs-types "^0.5.2" +"@cosmjs/proto-signing@^0.25.4": + version "0.25.6" + resolved "https://registry.yarnpkg.com/@cosmjs/proto-signing/-/proto-signing-0.25.6.tgz#d9fc57b8e0a46cda97e192bd0435157b24949ff8" + integrity sha512-JpQ+Vnv9s6i3x8f3Jo0lJZ3VMnj3R5sMgX+8ti1LtB7qEYRR85qbDrEG9hDGIKqJJabvrAuCHnO6hYi0vJEJHA== + dependencies: + "@cosmjs/amino" "^0.25.6" + long "^4.0.0" + protobufjs "~6.10.2" + +"@cosmjs/proto-signing@^0.31.3": + version "0.31.3" + resolved "https://registry.yarnpkg.com/@cosmjs/proto-signing/-/proto-signing-0.31.3.tgz#20440b7b96fb2cd924256a10e656fd8d4481cdcd" + integrity sha512-24+10/cGl6lLS4VCrGTCJeDRPQTn1K5JfknzXzDIHOx8THR31JxA7/HV5eWGHqWgAbudA7ccdSvEK08lEHHtLA== + dependencies: + "@cosmjs/amino" "^0.31.3" + "@cosmjs/crypto" "^0.31.3" + "@cosmjs/encoding" "^0.31.3" + "@cosmjs/math" "^0.31.3" + "@cosmjs/utils" "^0.31.3" + cosmjs-types "^0.8.0" long "^4.0.0" -"@cosmjs/socket@^0.29.5": - version "0.29.5" - resolved "https://registry.yarnpkg.com/@cosmjs/socket/-/socket-0.29.5.tgz#a48df6b4c45dc6a6ef8e47232725dd4aa556ac2d" - integrity sha512-5VYDupIWbIXq3ftPV1LkS5Ya/T7Ol/AzWVhNxZ79hPe/mBfv1bGau/LqIYOm2zxGlgm9hBHOTmWGqNYDwr9LNQ== +"@cosmjs/socket@^0.31.3": + version "0.31.3" + resolved "https://registry.yarnpkg.com/@cosmjs/socket/-/socket-0.31.3.tgz#52086380f4de2fc3514b90b0484b4b1c4c50e39e" + integrity sha512-aqrDGGi7os/hsz5p++avI4L0ZushJ+ItnzbqA7C6hamFSCJwgOkXaOUs+K9hXZdX4rhY7rXO4PH9IH8q09JkTw== dependencies: - "@cosmjs/stream" "^0.29.5" + "@cosmjs/stream" "^0.31.3" isomorphic-ws "^4.0.1" ws "^7" xstream "^11.14.0" -"@cosmjs/stargate@^0.29.4": - version "0.29.5" - resolved "https://registry.yarnpkg.com/@cosmjs/stargate/-/stargate-0.29.5.tgz#d597af1c85a3c2af7b5bdbec34d5d40692cc09e4" - integrity sha512-hjEv8UUlJruLrYGJcUZXM/CziaINOKwfVm2BoSdUnNTMxGvY/jC1ABHKeZUYt9oXHxEJ1n9+pDqzbKc8pT0nBw== +"@cosmjs/stargate@^0.31.0": + version "0.31.3" + resolved "https://registry.yarnpkg.com/@cosmjs/stargate/-/stargate-0.31.3.tgz#a2b38e398097a00f897dbd8f02d4d347d8fed818" + integrity sha512-53NxnzmB9FfXpG4KjOUAYAvWLYKdEmZKsutcat/u2BrDXNZ7BN8jim/ENcpwXfs9/Og0K24lEIdvA4gsq3JDQw== dependencies: "@confio/ics23" "^0.6.8" - "@cosmjs/amino" "^0.29.5" - "@cosmjs/encoding" "^0.29.5" - "@cosmjs/math" "^0.29.5" - "@cosmjs/proto-signing" "^0.29.5" - "@cosmjs/stream" "^0.29.5" - "@cosmjs/tendermint-rpc" "^0.29.5" - "@cosmjs/utils" "^0.29.5" - cosmjs-types "^0.5.2" + "@cosmjs/amino" "^0.31.3" + "@cosmjs/encoding" "^0.31.3" + "@cosmjs/math" "^0.31.3" + "@cosmjs/proto-signing" "^0.31.3" + "@cosmjs/stream" "^0.31.3" + "@cosmjs/tendermint-rpc" "^0.31.3" + "@cosmjs/utils" "^0.31.3" + cosmjs-types "^0.8.0" long "^4.0.0" protobufjs "~6.11.3" xstream "^11.14.0" -"@cosmjs/stream@^0.29.5": - version "0.29.5" - resolved "https://registry.yarnpkg.com/@cosmjs/stream/-/stream-0.29.5.tgz#350981cac496d04939b92ee793b9b19f44bc1d4e" - integrity sha512-TToTDWyH1p05GBtF0Y8jFw2C+4783ueDCmDyxOMM6EU82IqpmIbfwcdMOCAm0JhnyMh+ocdebbFvnX/sGKzRAA== +"@cosmjs/stream@^0.31.3": + version "0.31.3" + resolved "https://registry.yarnpkg.com/@cosmjs/stream/-/stream-0.31.3.tgz#53428fd62487ec08fc3886a50a3feeb8b2af2e66" + integrity sha512-8keYyI7X0RjsLyVcZuBeNjSv5FA4IHwbFKx7H60NHFXszN8/MvXL6aZbNIvxtcIHHsW7K9QSQos26eoEWlAd+w== dependencies: xstream "^11.14.0" -"@cosmjs/tendermint-rpc@^0.29.5": - version "0.29.5" - resolved "https://registry.yarnpkg.com/@cosmjs/tendermint-rpc/-/tendermint-rpc-0.29.5.tgz#f205c10464212bdf843f91bb2e4a093b618cb5c2" - integrity sha512-ar80twieuAxsy0x2za/aO3kBr2DFPAXDmk2ikDbmkda+qqfXgl35l9CVAAjKRqd9d+cRvbQyb5M4wy6XQpEV6w== - dependencies: - "@cosmjs/crypto" "^0.29.5" - "@cosmjs/encoding" "^0.29.5" - "@cosmjs/json-rpc" "^0.29.5" - "@cosmjs/math" "^0.29.5" - "@cosmjs/socket" "^0.29.5" - "@cosmjs/stream" "^0.29.5" - "@cosmjs/utils" "^0.29.5" +"@cosmjs/tendermint-rpc@^0.31.3": + version "0.31.3" + resolved "https://registry.yarnpkg.com/@cosmjs/tendermint-rpc/-/tendermint-rpc-0.31.3.tgz#d1a2bc5b3c98743631c9b55888589d352403c9b3" + integrity sha512-s3TiWkPCW4QceTQjpYqn4xttUJH36mTPqplMl+qyocdqk5+X5mergzExU/pHZRWQ4pbby8bnR7kMvG4OC1aZ8g== + dependencies: + "@cosmjs/crypto" "^0.31.3" + "@cosmjs/encoding" "^0.31.3" + "@cosmjs/json-rpc" "^0.31.3" + "@cosmjs/math" "^0.31.3" + "@cosmjs/socket" "^0.31.3" + "@cosmjs/stream" "^0.31.3" + "@cosmjs/utils" "^0.31.3" axios "^0.21.2" readonly-date "^1.0.0" xstream "^11.14.0" @@ -1484,40 +2594,21 @@ resolved "https://registry.yarnpkg.com/@cosmjs/utils/-/utils-0.24.1.tgz#0adfefe63b7f17222bc2bc12f71296f35e7ad378" integrity sha512-VA3WFx1lMFb7esp9BqHWkDgMvHoA3D9w+uDRvWhVRpUpDc7RYHxMbWExASjz+gNblTCg556WJGzF64tXnf9tdQ== -"@cosmjs/utils@^0.29.5": - version "0.29.5" - resolved "https://registry.yarnpkg.com/@cosmjs/utils/-/utils-0.29.5.tgz#3fed1b3528ae8c5f1eb5d29b68755bebfd3294ee" - integrity sha512-m7h+RXDUxOzEOGt4P+3OVPX7PuakZT3GBmaM/Y2u+abN3xZkziykD/NvedYFvvCCdQo714XcGl33bwifS9FZPQ== +"@cosmjs/utils@^0.25.6": + version "0.25.6" + resolved "https://registry.yarnpkg.com/@cosmjs/utils/-/utils-0.25.6.tgz#934d9a967180baa66163847616a74358732227ca" + integrity sha512-ofOYiuxVKNo238vCPPlaDzqPXy2AQ/5/nashBo5rvPZJkxt9LciGfUEQWPCOb1BIJDNx2Dzu0z4XCf/dwzl0Dg== -"@cspotcode/source-map-support@^0.8.0": - version "0.8.1" - resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1" - integrity sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw== - dependencies: - "@jridgewell/trace-mapping" "0.3.9" +"@cosmjs/utils@^0.31.3": + version "0.31.3" + resolved "https://registry.yarnpkg.com/@cosmjs/utils/-/utils-0.31.3.tgz#f97bbfda35ad69e80cd5c7fe0a270cbda16db1ed" + integrity sha512-VBhAgzrrYdIe0O5IbKRqwszbQa7ZyQLx9nEQuHQ3HUplQW7P44COG/ye2n6AzCudtqxmwdX7nyX8ta1J07GoqA== "@discoveryjs/json-ext@^0.5.3": version "0.5.7" resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70" integrity sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw== -"@edge-runtime/format@1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@edge-runtime/format/-/format-1.1.0.tgz#5a209221a8bae7791d6e465c480f146249d1e15f" - integrity sha512-MkLDDtPhXZIMx83NykdFmOpF7gVWIdd6GBHYb8V/E+PKWvD2pK/qWx9B30oN1iDJ2XBm0SGDjz02S8nDHI9lMQ== - -"@edge-runtime/primitives@2.0.0": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@edge-runtime/primitives/-/primitives-2.0.0.tgz#b4bf44f9cab36aee3027fe4c3ff3cc1d5713e155" - integrity sha512-AXqUq1zruTJAICrllUvZcgciIcEGHdF6KJ3r6FM0n4k8LpFxZ62tPWVIJ9HKm+xt+ncTBUZxwgUaQ73QMUQEKw== - -"@edge-runtime/vm@2.0.0": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@edge-runtime/vm/-/vm-2.0.0.tgz#9170d2d03761eff4e27687888c4b2d9af1f94c7d" - integrity sha512-BOLrAX8IWHRXu1siZocwLguKJPEUv7cr+rG8tI4hvHgMdIsBWHJlLeB8EjuUVnIURFrUiM49lVKn8DRrECmngw== - dependencies: - "@edge-runtime/primitives" "2.0.0" - "@emotion/cache@^10.0.27": version "10.0.29" resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-10.0.29.tgz#87e7e64f412c060102d589fe7c6dc042e6f9d1e0" @@ -1554,11 +2645,6 @@ resolved "https://registry.yarnpkg.com/@emotion/hash/-/hash-0.8.0.tgz#bbbff68978fefdbe68ccb533bc8cbe1d1afb5413" integrity sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow== -"@emotion/hash@^0.9.0": - version "0.9.0" - resolved "https://registry.yarnpkg.com/@emotion/hash/-/hash-0.9.0.tgz#c5153d50401ee3c027a57a177bc269b16d889cb7" - integrity sha512-14FtKiHhy2QoPIzdTcvh//8OyBlknNs2nXRwIhG904opCby3l+9Xaf/wuPvICBF0rc1ZCNBd3nKe9cd2mecVkQ== - "@emotion/is-prop-valid@0.8.8": version "0.8.8" resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz#db28b1c4368a259b60a97311d6a952d4fd01ac1a" @@ -1615,6 +2701,11 @@ resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.7.5.tgz#77211291c1900a700b8a78cfafda3160d76949ed" integrity sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg== +"@emotion/use-insertion-effect-with-fallbacks@^1.0.0", "@emotion/use-insertion-effect-with-fallbacks@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.1.tgz#08de79f54eb3406f9daaf77c76e35313da963963" + integrity sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw== + "@emotion/utils@0.11.3": version "0.11.3" resolved "https://registry.yarnpkg.com/@emotion/utils/-/utils-0.11.3.tgz#a759863867befa7e583400d322652a3f44820924" @@ -1625,349 +2716,538 @@ resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.2.5.tgz#8eed982e2ee6f7f4e44c253e12962980791efd46" integrity sha512-6U71C2Wp7r5XtFtQzYrW5iKFT67OixrSxjI4MptCHzdSVlgabczzqLe0ZSgnub/5Kp4hSbpDB1tMytZY9pwxxA== -"@esbuild-plugins/node-modules-polyfill@^0.1.4": - version "0.1.4" - resolved "https://registry.yarnpkg.com/@esbuild-plugins/node-modules-polyfill/-/node-modules-polyfill-0.1.4.tgz#eb2f55da11967b2986c913f1a7957d1c868849c0" - integrity sha512-uZbcXi0zbmKC/050p3gJnne5Qdzw8vkXIv+c2BW0Lsc1ji1SkrxbKPUy5Efr0blbTu1SL8w4eyfpnSdPg3G0Qg== - dependencies: - escape-string-regexp "^4.0.0" - rollup-plugin-node-polyfills "^0.2.1" - -"@esbuild/android-arm64@0.16.3": - version "0.16.3" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.16.3.tgz#6af6d16be6d534d776a51fc215bfd81a68906d2c" - integrity sha512-RolFVeinkeraDvN/OoRf1F/lP0KUfGNb5jxy/vkIMeRRChkrX/HTYN6TYZosRJs3a1+8wqpxAo5PI5hFmxyPRg== - -"@esbuild/android-arm64@0.17.15": - version "0.17.15" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.17.15.tgz#893ad71f3920ccb919e1757c387756a9bca2ef42" - integrity sha512-0kOB6Y7Br3KDVgHeg8PRcvfLkq+AccreK///B4Z6fNZGr/tNHX0z2VywCc7PTeWp+bPvjA5WMvNXltHw5QjAIA== - -"@esbuild/android-arm64@0.17.6": - version "0.17.6" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.17.6.tgz#b11bd4e4d031bb320c93c83c137797b2be5b403b" - integrity sha512-YnYSCceN/dUzUr5kdtUzB+wZprCafuD89Hs0Aqv9QSdwhYQybhXTaSTcrl6X/aWThn1a/j0eEpUBGOE7269REg== - -"@esbuild/android-arm@0.16.3": - version "0.16.3" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.16.3.tgz#2a091222f3b1928e3246fb3c5202eaca88baab67" - integrity sha512-mueuEoh+s1eRbSJqq9KNBQwI4QhQV6sRXIfTyLXSHGMpyew61rOK4qY21uKbXl1iBoMb0AdL1deWFCQVlN2qHA== - -"@esbuild/android-arm@0.17.15": - version "0.17.15" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.17.15.tgz#143e0d4e4c08c786ea410b9a7739779a9a1315d8" - integrity sha512-sRSOVlLawAktpMvDyJIkdLI/c/kdRTOqo8t6ImVxg8yT7LQDUYV5Rp2FKeEosLr6ZCja9UjYAzyRSxGteSJPYg== - -"@esbuild/android-arm@0.17.6": - version "0.17.6" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.17.6.tgz#ac6b5674da2149997f6306b3314dae59bbe0ac26" - integrity sha512-bSC9YVUjADDy1gae8RrioINU6e1lCkg3VGVwm0QQ2E1CWcC4gnMce9+B6RpxuSsrsXsk1yojn7sp1fnG8erE2g== - -"@esbuild/android-x64@0.16.3": - version "0.16.3" - resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.16.3.tgz#a6d749c58b022d371dc40d50ac1bb4aebd1eb953" - integrity sha512-SFpTUcIT1bIJuCCBMCQWq1bL2gPTjWoLZdjmIhjdcQHaUfV41OQfho6Ici5uvvkMmZRXIUGpM3GxysP/EU7ifQ== - -"@esbuild/android-x64@0.17.15": - version "0.17.15" - resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.17.15.tgz#d2d12a7676b2589864281b2274355200916540bc" - integrity sha512-MzDqnNajQZ63YkaUWVl9uuhcWyEyh69HGpMIrf+acR4otMkfLJ4sUCxqwbCyPGicE9dVlrysI3lMcDBjGiBBcQ== - -"@esbuild/android-x64@0.17.6": - version "0.17.6" - resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.17.6.tgz#18c48bf949046638fc209409ff684c6bb35a5462" - integrity sha512-MVcYcgSO7pfu/x34uX9u2QIZHmXAB7dEiLQC5bBl5Ryqtpj9lT2sg3gNDEsrPEmimSJW2FXIaxqSQ501YLDsZQ== - -"@esbuild/darwin-arm64@0.16.3": - version "0.16.3" - resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.16.3.tgz#92d1826ed2f21dcac5830b70d7215c6afbb744e2" - integrity sha512-DO8WykMyB+N9mIDfI/Hug70Dk1KipavlGAecxS3jDUwAbTpDXj0Lcwzw9svkhxfpCagDmpaTMgxWK8/C/XcXvw== - -"@esbuild/darwin-arm64@0.17.15": - version "0.17.15" - resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.17.15.tgz#2e88e79f1d327a2a7d9d06397e5232eb0a473d61" - integrity sha512-7siLjBc88Z4+6qkMDxPT2juf2e8SJxmsbNVKFY2ifWCDT72v5YJz9arlvBw5oB4W/e61H1+HDB/jnu8nNg0rLA== - -"@esbuild/darwin-arm64@0.17.6": - version "0.17.6" - resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.17.6.tgz#b3fe19af1e4afc849a07c06318124e9c041e0646" - integrity sha512-bsDRvlbKMQMt6Wl08nHtFz++yoZHsyTOxnjfB2Q95gato+Yi4WnRl13oC2/PJJA9yLCoRv9gqT/EYX0/zDsyMA== - -"@esbuild/darwin-x64@0.16.3": - version "0.16.3" - resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.16.3.tgz#7fc3570c2b16e9ff4fc178593a0a4adb1ae8ea57" - integrity sha512-uEqZQ2omc6BvWqdCiyZ5+XmxuHEi1SPzpVxXCSSV2+Sh7sbXbpeNhHIeFrIpRjAs0lI1FmA1iIOxFozKBhKgRQ== - -"@esbuild/darwin-x64@0.17.15": - version "0.17.15" - resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.17.15.tgz#9384e64c0be91388c57be6d3a5eaf1c32a99c91d" - integrity sha512-NbImBas2rXwYI52BOKTW342Tm3LTeVlaOQ4QPZ7XuWNKiO226DisFk/RyPk3T0CKZkKMuU69yOvlapJEmax7cg== - -"@esbuild/darwin-x64@0.17.6": - version "0.17.6" - resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.17.6.tgz#f4dacd1ab21e17b355635c2bba6a31eba26ba569" - integrity sha512-xh2A5oPrYRfMFz74QXIQTQo8uA+hYzGWJFoeTE8EvoZGHb+idyV4ATaukaUvnnxJiauhs/fPx3vYhU4wiGfosg== - -"@esbuild/freebsd-arm64@0.16.3": - version "0.16.3" - resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.16.3.tgz#16735ce16f8c9a4e7289e9e259aa01a8d9874307" - integrity sha512-nJansp3sSXakNkOD5i5mIz2Is/HjzIhFs49b1tjrPrpCmwgBmH9SSzhC/Z1UqlkivqMYkhfPwMw1dGFUuwmXhw== - -"@esbuild/freebsd-arm64@0.17.15": - version "0.17.15" - resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.15.tgz#2ad5a35bc52ebd9ca6b845dbc59ba39647a93c1a" - integrity sha512-Xk9xMDjBVG6CfgoqlVczHAdJnCs0/oeFOspFap5NkYAmRCT2qTn1vJWA2f419iMtsHSLm+O8B6SLV/HlY5cYKg== - -"@esbuild/freebsd-arm64@0.17.6": - version "0.17.6" - resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.6.tgz#ea4531aeda70b17cbe0e77b0c5c36298053855b4" - integrity sha512-EnUwjRc1inT4ccZh4pB3v1cIhohE2S4YXlt1OvI7sw/+pD+dIE4smwekZlEPIwY6PhU6oDWwITrQQm5S2/iZgg== - -"@esbuild/freebsd-x64@0.16.3": - version "0.16.3" - resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.16.3.tgz#f4edd1464cb072799ed6b8ab5178478e71c13459" - integrity sha512-TfoDzLw+QHfc4a8aKtGSQ96Wa+6eimljjkq9HKR0rHlU83vw8aldMOUSJTUDxbcUdcgnJzPaX8/vGWm7vyV7ug== - -"@esbuild/freebsd-x64@0.17.15": - version "0.17.15" - resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.17.15.tgz#b513a48446f96c75fda5bef470e64d342d4379cd" - integrity sha512-3TWAnnEOdclvb2pnfsTWtdwthPfOz7qAfcwDLcfZyGJwm1SRZIMOeB5FODVhnM93mFSPsHB9b/PmxNNbSnd0RQ== - -"@esbuild/freebsd-x64@0.17.6": - version "0.17.6" - resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.17.6.tgz#1896170b3c9f63c5e08efdc1f8abc8b1ed7af29f" - integrity sha512-Uh3HLWGzH6FwpviUcLMKPCbZUAFzv67Wj5MTwK6jn89b576SR2IbEp+tqUHTr8DIl0iDmBAf51MVaP7pw6PY5Q== - -"@esbuild/linux-arm64@0.16.3": - version "0.16.3" - resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.16.3.tgz#4b7ae6fe3618d9a40d6ca39c6edc991ac1447203" - integrity sha512-7I3RlsnxEFCHVZNBLb2w7unamgZ5sVwO0/ikE2GaYvYuUQs9Qte/w7TqWcXHtCwxvZx/2+F97ndiUQAWs47ZfQ== - -"@esbuild/linux-arm64@0.17.15": - version "0.17.15" - resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.17.15.tgz#9697b168175bfd41fa9cc4a72dd0d48f24715f31" - integrity sha512-T0MVnYw9KT6b83/SqyznTs/3Jg2ODWrZfNccg11XjDehIved2oQfrX/wVuev9N936BpMRaTR9I1J0tdGgUgpJA== - -"@esbuild/linux-arm64@0.17.6": - version "0.17.6" - resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.17.6.tgz#967dfb951c6b2de6f2af82e96e25d63747f75079" - integrity sha512-bUR58IFOMJX523aDVozswnlp5yry7+0cRLCXDsxnUeQYJik1DukMY+apBsLOZJblpH+K7ox7YrKrHmJoWqVR9w== - -"@esbuild/linux-arm@0.16.3": - version "0.16.3" - resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.16.3.tgz#4b3e9f849822e16a76a70844c4db68075b259a58" - integrity sha512-VwswmSYwVAAq6LysV59Fyqk3UIjbhuc6wb3vEcJ7HEJUtFuLK9uXWuFoH1lulEbE4+5GjtHi3MHX+w1gNHdOWQ== - -"@esbuild/linux-arm@0.17.15": - version "0.17.15" - resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.17.15.tgz#5b22062c54f48cd92fab9ffd993732a52db70cd3" - integrity sha512-MLTgiXWEMAMr8nmS9Gigx43zPRmEfeBfGCwxFQEMgJ5MC53QKajaclW6XDPjwJvhbebv+RzK05TQjvH3/aM4Xw== - -"@esbuild/linux-arm@0.17.6": - version "0.17.6" - resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.17.6.tgz#097a0ee2be39fed3f37ea0e587052961e3bcc110" - integrity sha512-7YdGiurNt7lqO0Bf/U9/arrPWPqdPqcV6JCZda4LZgEn+PTQ5SMEI4MGR52Bfn3+d6bNEGcWFzlIxiQdS48YUw== - -"@esbuild/linux-ia32@0.16.3": - version "0.16.3" - resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.16.3.tgz#2ff3936b91bfff62f9ecf7f6411ef399b29ed22d" - integrity sha512-X8FDDxM9cqda2rJE+iblQhIMYY49LfvW4kaEjoFbTTQ4Go8G96Smj2w3BRTwA8IHGoi9dPOPGAX63dhuv19UqA== - -"@esbuild/linux-ia32@0.17.15": - version "0.17.15" - resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.17.15.tgz#eb28a13f9b60b5189fcc9e98e1024f6b657ba54c" - integrity sha512-wp02sHs015T23zsQtU4Cj57WiteiuASHlD7rXjKUyAGYzlOKDAjqK6bk5dMi2QEl/KVOcsjwL36kD+WW7vJt8Q== - -"@esbuild/linux-ia32@0.17.6": - version "0.17.6" - resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.17.6.tgz#a38a789d0ed157495a6b5b4469ec7868b59e5278" - integrity sha512-ujp8uoQCM9FRcbDfkqECoARsLnLfCUhKARTP56TFPog8ie9JG83D5GVKjQ6yVrEVdMie1djH86fm98eY3quQkQ== - -"@esbuild/linux-loong64@0.16.3": - version "0.16.3" - resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.16.3.tgz#ff8aa59f49d9ccbc1ff952ba1f5cd01a534562df" - integrity sha512-hIbeejCOyO0X9ujfIIOKjBjNAs9XD/YdJ9JXAy1lHA+8UXuOqbFe4ErMCqMr8dhlMGBuvcQYGF7+kO7waj2KHw== - -"@esbuild/linux-loong64@0.17.15": - version "0.17.15" - resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.17.15.tgz#32454bdfe144cf74b77895a8ad21a15cb81cfbe5" - integrity sha512-k7FsUJjGGSxwnBmMh8d7IbObWu+sF/qbwc+xKZkBe/lTAF16RqxRCnNHA7QTd3oS2AfGBAnHlXL67shV5bBThQ== - -"@esbuild/linux-loong64@0.17.6": - version "0.17.6" - resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.17.6.tgz#ae3983d0fb4057883c8246f57d2518c2af7cf2ad" - integrity sha512-y2NX1+X/Nt+izj9bLoiaYB9YXT/LoaQFYvCkVD77G/4F+/yuVXYCWz4SE9yr5CBMbOxOfBcy/xFL4LlOeNlzYQ== - -"@esbuild/linux-mips64el@0.16.3": - version "0.16.3" - resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.16.3.tgz#5dd5e118071c3912df69beedbfd11fb117f0fe5e" - integrity sha512-znFRzICT/V8VZQMt6rjb21MtAVJv/3dmKRMlohlShrbVXdBuOdDrGb+C2cZGQAR8RFyRe7HS6klmHq103WpmVw== - -"@esbuild/linux-mips64el@0.17.15": - version "0.17.15" - resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.17.15.tgz#af12bde0d775a318fad90eb13a0455229a63987c" - integrity sha512-ZLWk6czDdog+Q9kE/Jfbilu24vEe/iW/Sj2d8EVsmiixQ1rM2RKH2n36qfxK4e8tVcaXkvuV3mU5zTZviE+NVQ== - -"@esbuild/linux-mips64el@0.17.6": - version "0.17.6" - resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.17.6.tgz#15fbbe04648d944ec660ee5797febdf09a9bd6af" - integrity sha512-09AXKB1HDOzXD+j3FdXCiL/MWmZP0Ex9eR8DLMBVcHorrWJxWmY8Nms2Nm41iRM64WVx7bA/JVHMv081iP2kUA== - -"@esbuild/linux-ppc64@0.16.3": - version "0.16.3" - resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.16.3.tgz#36c62e24eae7fa3f0d921506da8fc1e6098a1364" - integrity sha512-EV7LuEybxhXrVTDpbqWF2yehYRNz5e5p+u3oQUS2+ZFpknyi1NXxr8URk4ykR8Efm7iu04//4sBg249yNOwy5Q== - -"@esbuild/linux-ppc64@0.17.15": - version "0.17.15" - resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.17.15.tgz#34c5ed145b2dfc493d3e652abac8bd3baa3865a5" - integrity sha512-mY6dPkIRAiFHRsGfOYZC8Q9rmr8vOBZBme0/j15zFUKM99d4ILY4WpOC7i/LqoY+RE7KaMaSfvY8CqjJtuO4xg== - -"@esbuild/linux-ppc64@0.17.6": - version "0.17.6" - resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.17.6.tgz#38210094e8e1a971f2d1fd8e48462cc65f15ef19" - integrity sha512-AmLhMzkM8JuqTIOhxnX4ubh0XWJIznEynRnZAVdA2mMKE6FAfwT2TWKTwdqMG+qEaeyDPtfNoZRpJbD4ZBv0Tg== - -"@esbuild/linux-riscv64@0.16.3": - version "0.16.3" - resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.16.3.tgz#f0fec8e7affb5bcc817fefc61a21cbb95539e393" - integrity sha512-uDxqFOcLzFIJ+r/pkTTSE9lsCEaV/Y6rMlQjUI9BkzASEChYL/aSQjZjchtEmdnVxDKETnUAmsaZ4pqK1eE5BQ== - -"@esbuild/linux-riscv64@0.17.15": - version "0.17.15" - resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.17.15.tgz#87bd515e837f2eb004b45f9e6a94dc5b93f22b92" - integrity sha512-EcyUtxffdDtWjjwIH8sKzpDRLcVtqANooMNASO59y+xmqqRYBBM7xVLQhqF7nksIbm2yHABptoioS9RAbVMWVA== - -"@esbuild/linux-riscv64@0.17.6": - version "0.17.6" - resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.17.6.tgz#bc3c66d5578c3b9951a6ed68763f2a6856827e4a" - integrity sha512-Y4Ri62PfavhLQhFbqucysHOmRamlTVK10zPWlqjNbj2XMea+BOs4w6ASKwQwAiqf9ZqcY9Ab7NOU4wIgpxwoSQ== - -"@esbuild/linux-s390x@0.16.3": - version "0.16.3" - resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.16.3.tgz#22e10edd6e91f53c2e1f60e46abd453d7794409b" - integrity sha512-NbeREhzSxYwFhnCAQOQZmajsPYtX71Ufej3IQ8W2Gxskfz9DK58ENEju4SbpIj48VenktRASC52N5Fhyf/aliQ== - -"@esbuild/linux-s390x@0.17.15": - version "0.17.15" - resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.17.15.tgz#20bf7947197f199ddac2ec412029a414ceae3aa3" - integrity sha512-BuS6Jx/ezxFuHxgsfvz7T4g4YlVrmCmg7UAwboeyNNg0OzNzKsIZXpr3Sb/ZREDXWgt48RO4UQRDBxJN3B9Rbg== - -"@esbuild/linux-s390x@0.17.6": - version "0.17.6" - resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.17.6.tgz#d7ba7af59285f63cfce6e5b7f82a946f3e6d67fc" - integrity sha512-SPUiz4fDbnNEm3JSdUW8pBJ/vkop3M1YwZAVwvdwlFLoJwKEZ9L98l3tzeyMzq27CyepDQ3Qgoba44StgbiN5Q== - -"@esbuild/linux-x64@0.16.3": - version "0.16.3" - resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.16.3.tgz#38388b73fd9eebe45b073d7d8099b9c2e54f7139" - integrity sha512-SDiG0nCixYO9JgpehoKgScwic7vXXndfasjnD5DLbp1xltANzqZ425l7LSdHynt19UWOcDjG9wJJzSElsPvk0w== - -"@esbuild/linux-x64@0.17.15": - version "0.17.15" - resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.17.15.tgz#31b93f9c94c195e852c20cd3d1914a68aa619124" - integrity sha512-JsdS0EgEViwuKsw5tiJQo9UdQdUJYuB+Mf6HxtJSPN35vez1hlrNb1KajvKWF5Sa35j17+rW1ECEO9iNrIXbNg== - -"@esbuild/linux-x64@0.17.6": - version "0.17.6" - resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.17.6.tgz#ba51f8760a9b9370a2530f98964be5f09d90fed0" - integrity sha512-a3yHLmOodHrzuNgdpB7peFGPx1iJ2x6m+uDvhP2CKdr2CwOaqEFMeSqYAHU7hG+RjCq8r2NFujcd/YsEsFgTGw== - -"@esbuild/netbsd-x64@0.16.3": - version "0.16.3" - resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.16.3.tgz#e0270569567f1530b8dbe6d11d5b4930b9cc71ae" - integrity sha512-AzbsJqiHEq1I/tUvOfAzCY15h4/7Ivp3ff/o1GpP16n48JMNAtbW0qui2WCgoIZArEHD0SUQ95gvR0oSO7ZbdA== - -"@esbuild/netbsd-x64@0.17.15": - version "0.17.15" - resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.17.15.tgz#8da299b3ac6875836ca8cdc1925826498069ac65" - integrity sha512-R6fKjtUysYGym6uXf6qyNephVUQAGtf3n2RCsOST/neIwPqRWcnc3ogcielOd6pT+J0RDR1RGcy0ZY7d3uHVLA== - -"@esbuild/netbsd-x64@0.17.6": - version "0.17.6" - resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.17.6.tgz#e84d6b6fdde0261602c1e56edbb9e2cb07c211b9" - integrity sha512-EanJqcU/4uZIBreTrnbnre2DXgXSa+Gjap7ifRfllpmyAU7YMvaXmljdArptTHmjrkkKm9BK6GH5D5Yo+p6y5A== - -"@esbuild/openbsd-x64@0.16.3": - version "0.16.3" - resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.16.3.tgz#3b16642d443848bca605f33ee3978a1890911e6d" - integrity sha512-gSABi8qHl8k3Cbi/4toAzHiykuBuWLZs43JomTcXkjMZVkp0gj3gg9mO+9HJW/8GB5H89RX/V0QP4JGL7YEEVg== - -"@esbuild/openbsd-x64@0.17.15": - version "0.17.15" - resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.17.15.tgz#04a1ec3d4e919714dba68dcf09eeb1228ad0d20c" - integrity sha512-mVD4PGc26b8PI60QaPUltYKeSX0wxuy0AltC+WCTFwvKCq2+OgLP4+fFd+hZXzO2xW1HPKcytZBdjqL6FQFa7w== - -"@esbuild/openbsd-x64@0.17.6": - version "0.17.6" - resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.17.6.tgz#cf4b9fb80ce6d280a673d54a731d9c661f88b083" - integrity sha512-xaxeSunhQRsTNGFanoOkkLtnmMn5QbA0qBhNet/XLVsc+OVkpIWPHcr3zTW2gxVU5YOHFbIHR9ODuaUdNza2Vw== - -"@esbuild/sunos-x64@0.16.3": - version "0.16.3" - resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.16.3.tgz#a838f247867380f0ae25ce1936dc5ab6f57b7734" - integrity sha512-SF9Kch5Ete4reovvRO6yNjMxrvlfT0F0Flm+NPoUw5Z4Q3r1d23LFTgaLwm3Cp0iGbrU/MoUI+ZqwCv5XJijCw== - -"@esbuild/sunos-x64@0.17.15": - version "0.17.15" - resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.17.15.tgz#6694ebe4e16e5cd7dab6505ff7c28f9c1c695ce5" - integrity sha512-U6tYPovOkw3459t2CBwGcFYfFRjivcJJc1WC8Q3funIwX8x4fP+R6xL/QuTPNGOblbq/EUDxj9GU+dWKX0oWlQ== - -"@esbuild/sunos-x64@0.17.6": - version "0.17.6" - resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.17.6.tgz#a6838e246079b24d962b9dcb8d208a3785210a73" - integrity sha512-gnMnMPg5pfMkZvhHee21KbKdc6W3GR8/JuE0Da1kjwpK6oiFU3nqfHuVPgUX2rsOx9N2SadSQTIYV1CIjYG+xw== - -"@esbuild/win32-arm64@0.16.3": - version "0.16.3" - resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.16.3.tgz#bedd9bef5fb41f89ce2599f1761973cf6d6a67b6" - integrity sha512-u5aBonZIyGopAZyOnoPAA6fGsDeHByZ9CnEzyML9NqntK6D/xl5jteZUKm/p6nD09+v3pTM6TuUIqSPcChk5gg== - -"@esbuild/win32-arm64@0.17.15": - version "0.17.15" - resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.17.15.tgz#1f95b2564193c8d1fee8f8129a0609728171d500" - integrity sha512-W+Z5F++wgKAleDABemiyXVnzXgvRFs+GVKThSI+mGgleLWluv0D7Diz4oQpgdpNzh4i2nNDzQtWbjJiqutRp6Q== - -"@esbuild/win32-arm64@0.17.6": - version "0.17.6" - resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.17.6.tgz#ace0186e904d109ea4123317a3ba35befe83ac21" - integrity sha512-G95n7vP1UnGJPsVdKXllAJPtqjMvFYbN20e8RK8LVLhlTiSOH1sd7+Gt7rm70xiG+I5tM58nYgwWrLs6I1jHqg== - -"@esbuild/win32-ia32@0.16.3": - version "0.16.3" - resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.16.3.tgz#49800aa812d8cc35ceef61e8d3b01224684cc0b1" - integrity sha512-GlgVq1WpvOEhNioh74TKelwla9KDuAaLZrdxuuUgsP2vayxeLgVc+rbpIv0IYF4+tlIzq2vRhofV+KGLD+37EQ== - -"@esbuild/win32-ia32@0.17.15": - version "0.17.15" - resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.17.15.tgz#c362b88b3df21916ed7bcf75c6d09c6bf3ae354a" - integrity sha512-Muz/+uGgheShKGqSVS1KsHtCyEzcdOn/W/Xbh6H91Etm+wiIfwZaBn1W58MeGtfI8WA961YMHFYTthBdQs4t+w== - -"@esbuild/win32-ia32@0.17.6": - version "0.17.6" - resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.17.6.tgz#7fb3f6d4143e283a7f7dffc98a6baf31bb365c7e" - integrity sha512-96yEFzLhq5bv9jJo5JhTs1gI+1cKQ83cUpyxHuGqXVwQtY5Eq54ZEsKs8veKtiKwlrNimtckHEkj4mRh4pPjsg== - -"@esbuild/win32-x64@0.16.3": - version "0.16.3" - resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.16.3.tgz#94047dae921949cfb308117d993c4b941291ae10" - integrity sha512-5/JuTd8OWW8UzEtyf19fbrtMJENza+C9JoPIkvItgTBQ1FO2ZLvjbPO6Xs54vk0s5JB5QsfieUEshRQfu7ZHow== - -"@esbuild/win32-x64@0.17.15": - version "0.17.15" - resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.17.15.tgz#c2e737f3a201ebff8e2ac2b8e9f246b397ad19b8" - integrity sha512-DjDa9ywLUUmjhV2Y9wUTIF+1XsmuFGvZoCmOWkli1XcNAh5t25cc7fgsCx4Zi/Uurep3TTLyDiKATgGEg61pkA== - -"@esbuild/win32-x64@0.17.6": - version "0.17.6" - resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.17.6.tgz#563ff4277f1230a006472664fa9278a83dd124da" - integrity sha512-n6d8MOyUrNp6G4VSpRcgjs5xj4A91svJSaiwLIDWVWEsZtpN5FA9NlBbZHDmAJc2e8e6SF4tkBD3HAvPF+7igA== - -"@ethersproject/abi@5.7.0", "@ethersproject/abi@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.7.0.tgz#b3f3e045bbbeed1af3947335c247ad625a44e449" - integrity sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA== - dependencies: +"@emurgo/cardano-serialization-lib-browser@^11.5.0": + version "11.5.0" + resolved "https://registry.yarnpkg.com/@emurgo/cardano-serialization-lib-browser/-/cardano-serialization-lib-browser-11.5.0.tgz#f2d15b538add436e0aa8b67a1d00ca654a680006" + integrity sha512-qchOJ9NYDUz10tzs5r5QhP9hK0p+ZOlRiBwPdTAxqAYLw/8emYBkQQLaS8T1DF6EkeudyrgS00ym5Trw1fo4iA== + +"@emurgo/cardano-serialization-lib-nodejs@11.5.0": + version "11.5.0" + resolved "https://registry.yarnpkg.com/@emurgo/cardano-serialization-lib-nodejs/-/cardano-serialization-lib-nodejs-11.5.0.tgz#0662e2a17d7d1e944f8cdb86396133c8edaec059" + integrity sha512-IlVABlRgo9XaTR1NunwZpWcxnfEv04ba2l1vkUz4S1W7Jt36F4CtffP+jPeqBZGnAe+fnUwo0XjIJC3ZTNToNQ== + +"@esbuild/aix-ppc64@0.20.1": + version "0.20.1" + resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.20.1.tgz#eafa8775019b3650a77e8310ba4dbd17ca7af6d5" + integrity sha512-m55cpeupQ2DbuRGQMMZDzbv9J9PgVelPjlcmM5kxHnrBdBx6REaEd7LamYV7Dm8N7rCyR/XwU6rVP8ploKtIkA== + +"@esbuild/aix-ppc64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz#a70f4ac11c6a1dfc18b8bbb13284155d933b9537" + integrity sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g== + +"@esbuild/aix-ppc64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz#c7184a326533fcdf1b8ee0733e21c713b975575f" + integrity sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ== + +"@esbuild/android-arm64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.17.19.tgz#bafb75234a5d3d1b690e7c2956a599345e84a2fd" + integrity sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA== + +"@esbuild/android-arm64@0.20.1": + version "0.20.1" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.20.1.tgz#68791afa389550736f682c15b963a4f37ec2f5f6" + integrity sha512-hCnXNF0HM6AjowP+Zou0ZJMWWa1VkD77BXe959zERgGJBBxB+sV+J9f/rcjeg2c5bsukD/n17RKWXGFCO5dD5A== + +"@esbuild/android-arm64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz#db1c9202a5bc92ea04c7b6840f1bbe09ebf9e6b9" + integrity sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg== + +"@esbuild/android-arm64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz#09d9b4357780da9ea3a7dfb833a1f1ff439b4052" + integrity sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A== + +"@esbuild/android-arm@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.17.19.tgz#5898f7832c2298bc7d0ab53701c57beb74d78b4d" + integrity sha512-rIKddzqhmav7MSmoFCmDIb6e2W57geRsM94gV2l38fzhXMwq7hZoClug9USI2pFRGL06f4IOPHHpFNOkWieR8A== + +"@esbuild/android-arm@0.20.1": + version "0.20.1" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.20.1.tgz#38c91d8ee8d5196f7fbbdf4f0061415dde3a473a" + integrity sha512-4j0+G27/2ZXGWR5okcJi7pQYhmkVgb4D7UKwxcqrjhvp5TKWx3cUjgB1CGj1mfdmJBQ9VnUGgUhign+FPF2Zgw== + +"@esbuild/android-arm@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.20.2.tgz#3b488c49aee9d491c2c8f98a909b785870d6e995" + integrity sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w== + +"@esbuild/android-arm@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.21.5.tgz#9b04384fb771926dfa6d7ad04324ecb2ab9b2e28" + integrity sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg== + +"@esbuild/android-x64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.17.19.tgz#658368ef92067866d95fb268719f98f363d13ae1" + integrity sha512-uUTTc4xGNDT7YSArp/zbtmbhO0uEEK9/ETW29Wk1thYUJBz3IVnvgEiEwEa9IeLyvnpKrWK64Utw2bgUmDveww== + +"@esbuild/android-x64@0.20.1": + version "0.20.1" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.20.1.tgz#93f6190ce997b313669c20edbf3645fc6c8d8f22" + integrity sha512-MSfZMBoAsnhpS+2yMFYIQUPs8Z19ajwfuaSZx+tSl09xrHZCjbeXXMsUF/0oq7ojxYEpsSo4c0SfjxOYXRbpaA== + +"@esbuild/android-x64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.20.2.tgz#3b1628029e5576249d2b2d766696e50768449f98" + integrity sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg== + +"@esbuild/android-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.21.5.tgz#29918ec2db754cedcb6c1b04de8cd6547af6461e" + integrity sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA== + +"@esbuild/darwin-arm64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.17.19.tgz#584c34c5991b95d4d48d333300b1a4e2ff7be276" + integrity sha512-80wEoCfF/hFKM6WE1FyBHc9SfUblloAWx6FJkFWTWiCoht9Mc0ARGEM47e67W9rI09YoUxJL68WHfDRYEAvOhg== + +"@esbuild/darwin-arm64@0.20.1": + version "0.20.1" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.20.1.tgz#0d391f2e81fda833fe609182cc2fbb65e03a3c46" + integrity sha512-Ylk6rzgMD8klUklGPzS414UQLa5NPXZD5tf8JmQU8GQrj6BrFA/Ic9tb2zRe1kOZyCbGl+e8VMbDRazCEBqPvA== + +"@esbuild/darwin-arm64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz#6e8517a045ddd86ae30c6608c8475ebc0c4000bb" + integrity sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA== + +"@esbuild/darwin-arm64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz#e495b539660e51690f3928af50a76fb0a6ccff2a" + integrity sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ== + +"@esbuild/darwin-x64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.17.19.tgz#7751d236dfe6ce136cce343dce69f52d76b7f6cb" + integrity sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw== + +"@esbuild/darwin-x64@0.20.1": + version "0.20.1" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.20.1.tgz#92504077424584684862f483a2242cfde4055ba2" + integrity sha512-pFIfj7U2w5sMp52wTY1XVOdoxw+GDwy9FsK3OFz4BpMAjvZVs0dT1VXs8aQm22nhwoIWUmIRaE+4xow8xfIDZA== + +"@esbuild/darwin-x64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz#90ed098e1f9dd8a9381695b207e1cff45540a0d0" + integrity sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA== + +"@esbuild/darwin-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz#c13838fa57372839abdddc91d71542ceea2e1e22" + integrity sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw== + +"@esbuild/freebsd-arm64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.19.tgz#cacd171665dd1d500f45c167d50c6b7e539d5fd2" + integrity sha512-pBwbc7DufluUeGdjSU5Si+P3SoMF5DQ/F/UmTSb8HXO80ZEAJmrykPyzo1IfNbAoaqw48YRpv8shwd1NoI0jcQ== + +"@esbuild/freebsd-arm64@0.20.1": + version "0.20.1" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.1.tgz#a1646fa6ba87029c67ac8a102bb34384b9290774" + integrity sha512-UyW1WZvHDuM4xDz0jWun4qtQFauNdXjXOtIy7SYdf7pbxSWWVlqhnR/T2TpX6LX5NI62spt0a3ldIIEkPM6RHw== + +"@esbuild/freebsd-arm64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz#d71502d1ee89a1130327e890364666c760a2a911" + integrity sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw== + +"@esbuild/freebsd-arm64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz#646b989aa20bf89fd071dd5dbfad69a3542e550e" + integrity sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g== + +"@esbuild/freebsd-x64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.17.19.tgz#0769456eee2a08b8d925d7c00b79e861cb3162e4" + integrity sha512-4lu+n8Wk0XlajEhbEffdy2xy53dpR06SlzvhGByyg36qJw6Kpfk7cp45DR/62aPH9mtJRmIyrXAS5UWBrJT6TQ== + +"@esbuild/freebsd-x64@0.20.1": + version "0.20.1" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.20.1.tgz#41c9243ab2b3254ea7fb512f71ffdb341562e951" + integrity sha512-itPwCw5C+Jh/c624vcDd9kRCCZVpzpQn8dtwoYIt2TJF3S9xJLiRohnnNrKwREvcZYx0n8sCSbvGH349XkcQeg== + +"@esbuild/freebsd-x64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz#aa5ea58d9c1dd9af688b8b6f63ef0d3d60cea53c" + integrity sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw== + +"@esbuild/freebsd-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz#aa615cfc80af954d3458906e38ca22c18cf5c261" + integrity sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ== + +"@esbuild/linux-arm64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.17.19.tgz#38e162ecb723862c6be1c27d6389f48960b68edb" + integrity sha512-ct1Tg3WGwd3P+oZYqic+YZF4snNl2bsnMKRkb3ozHmnM0dGWuxcPTTntAF6bOP0Sp4x0PjSF+4uHQ1xvxfRKqg== + +"@esbuild/linux-arm64@0.20.1": + version "0.20.1" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.20.1.tgz#f3c1e1269fbc9eedd9591a5bdd32bf707a883156" + integrity sha512-cX8WdlF6Cnvw/DO9/X7XLH2J6CkBnz7Twjpk56cshk9sjYVcuh4sXQBy5bmTwzBjNVZze2yaV1vtcJS04LbN8w== + +"@esbuild/linux-arm64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz#055b63725df678379b0f6db9d0fa85463755b2e5" + integrity sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A== + +"@esbuild/linux-arm64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz#70ac6fa14f5cb7e1f7f887bcffb680ad09922b5b" + integrity sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q== + +"@esbuild/linux-arm@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.17.19.tgz#1a2cd399c50040184a805174a6d89097d9d1559a" + integrity sha512-cdmT3KxjlOQ/gZ2cjfrQOtmhG4HJs6hhvm3mWSRDPtZ/lP5oe8FWceS10JaSJC13GBd4eH/haHnqf7hhGNLerA== + +"@esbuild/linux-arm@0.20.1": + version "0.20.1" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.20.1.tgz#4503ca7001a8ee99589c072801ce9d7540717a21" + integrity sha512-LojC28v3+IhIbfQ+Vu4Ut5n3wKcgTu6POKIHN9Wpt0HnfgUGlBuyDDQR4jWZUZFyYLiz4RBBBmfU6sNfn6RhLw== + +"@esbuild/linux-arm@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz#76b3b98cb1f87936fbc37f073efabad49dcd889c" + integrity sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg== + +"@esbuild/linux-arm@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz#fc6fd11a8aca56c1f6f3894f2bea0479f8f626b9" + integrity sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA== + +"@esbuild/linux-ia32@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.17.19.tgz#e28c25266b036ce1cabca3c30155222841dc035a" + integrity sha512-w4IRhSy1VbsNxHRQpeGCHEmibqdTUx61Vc38APcsRbuVgK0OPEnQ0YD39Brymn96mOx48Y2laBQGqgZ0j9w6SQ== + +"@esbuild/linux-ia32@0.20.1": + version "0.20.1" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.20.1.tgz#98c474e3e0cbb5bcbdd8561a6e65d18f5767ce48" + integrity sha512-4H/sQCy1mnnGkUt/xszaLlYJVTz3W9ep52xEefGtd6yXDQbz/5fZE5dFLUgsPdbUOQANcVUa5iO6g3nyy5BJiw== + +"@esbuild/linux-ia32@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz#c0e5e787c285264e5dfc7a79f04b8b4eefdad7fa" + integrity sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig== + +"@esbuild/linux-ia32@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz#3271f53b3f93e3d093d518d1649d6d68d346ede2" + integrity sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg== + +"@esbuild/linux-loong64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.17.19.tgz#0f887b8bb3f90658d1a0117283e55dbd4c9dcf72" + integrity sha512-2iAngUbBPMq439a+z//gE+9WBldoMp1s5GWsUSgqHLzLJ9WoZLZhpwWuym0u0u/4XmZ3gpHmzV84PonE+9IIdQ== + +"@esbuild/linux-loong64@0.20.1": + version "0.20.1" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.20.1.tgz#a8097d28d14b9165c725fe58fc438f80decd2f33" + integrity sha512-c0jgtB+sRHCciVXlyjDcWb2FUuzlGVRwGXgI+3WqKOIuoo8AmZAddzeOHeYLtD+dmtHw3B4Xo9wAUdjlfW5yYA== + +"@esbuild/linux-loong64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz#a6184e62bd7cdc63e0c0448b83801001653219c5" + integrity sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ== + +"@esbuild/linux-loong64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz#ed62e04238c57026aea831c5a130b73c0f9f26df" + integrity sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg== + +"@esbuild/linux-mips64el@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.17.19.tgz#f5d2a0b8047ea9a5d9f592a178ea054053a70289" + integrity sha512-LKJltc4LVdMKHsrFe4MGNPp0hqDFA1Wpt3jE1gEyM3nKUvOiO//9PheZZHfYRfYl6AwdTH4aTcXSqBerX0ml4A== + +"@esbuild/linux-mips64el@0.20.1": + version "0.20.1" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.20.1.tgz#c44f6f0d7d017c41ad3bb15bfdb69b690656b5ea" + integrity sha512-TgFyCfIxSujyuqdZKDZ3yTwWiGv+KnlOeXXitCQ+trDODJ+ZtGOzLkSWngynP0HZnTsDyBbPy7GWVXWaEl6lhA== + +"@esbuild/linux-mips64el@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz#d08e39ce86f45ef8fc88549d29c62b8acf5649aa" + integrity sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA== + +"@esbuild/linux-mips64el@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz#e79b8eb48bf3b106fadec1ac8240fb97b4e64cbe" + integrity sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg== + +"@esbuild/linux-ppc64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.17.19.tgz#876590e3acbd9fa7f57a2c7d86f83717dbbac8c7" + integrity sha512-/c/DGybs95WXNS8y3Ti/ytqETiW7EU44MEKuCAcpPto3YjQbyK3IQVKfF6nbghD7EcLUGl0NbiL5Rt5DMhn5tg== + +"@esbuild/linux-ppc64@0.20.1": + version "0.20.1" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.20.1.tgz#0765a55389a99237b3c84227948c6e47eba96f0d" + integrity sha512-b+yuD1IUeL+Y93PmFZDZFIElwbmFfIKLKlYI8M6tRyzE6u7oEP7onGk0vZRh8wfVGC2dZoy0EqX1V8qok4qHaw== + +"@esbuild/linux-ppc64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz#8d252f0b7756ffd6d1cbde5ea67ff8fd20437f20" + integrity sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg== + +"@esbuild/linux-ppc64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz#5f2203860a143b9919d383ef7573521fb154c3e4" + integrity sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w== + +"@esbuild/linux-riscv64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.17.19.tgz#7f49373df463cd9f41dc34f9b2262d771688bf09" + integrity sha512-FC3nUAWhvFoutlhAkgHf8f5HwFWUL6bYdvLc/TTuxKlvLi3+pPzdZiFKSWz/PF30TB1K19SuCxDTI5KcqASJqA== + +"@esbuild/linux-riscv64@0.20.1": + version "0.20.1" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.20.1.tgz#e4153b032288e3095ddf4c8be07893781b309a7e" + integrity sha512-wpDlpE0oRKZwX+GfomcALcouqjjV8MIX8DyTrxfyCfXxoKQSDm45CZr9fanJ4F6ckD4yDEPT98SrjvLwIqUCgg== + +"@esbuild/linux-riscv64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz#19f6dcdb14409dae607f66ca1181dd4e9db81300" + integrity sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg== + +"@esbuild/linux-riscv64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz#07bcafd99322d5af62f618cb9e6a9b7f4bb825dc" + integrity sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA== + +"@esbuild/linux-s390x@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.17.19.tgz#e2afd1afcaf63afe2c7d9ceacd28ec57c77f8829" + integrity sha512-IbFsFbxMWLuKEbH+7sTkKzL6NJmG2vRyy6K7JJo55w+8xDk7RElYn6xvXtDW8HCfoKBFK69f3pgBJSUSQPr+4Q== + +"@esbuild/linux-s390x@0.20.1": + version "0.20.1" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.20.1.tgz#b9ab8af6e4b73b26d63c1c426d7669a5d53eb5a7" + integrity sha512-5BepC2Au80EohQ2dBpyTquqGCES7++p7G+7lXe1bAIvMdXm4YYcEfZtQrP4gaoZ96Wv1Ute61CEHFU7h4FMueQ== + +"@esbuild/linux-s390x@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz#3c830c90f1a5d7dd1473d5595ea4ebb920988685" + integrity sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ== + +"@esbuild/linux-s390x@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz#b7ccf686751d6a3e44b8627ababc8be3ef62d8de" + integrity sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A== + +"@esbuild/linux-x64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.17.19.tgz#8a0e9738b1635f0c53389e515ae83826dec22aa4" + integrity sha512-68ngA9lg2H6zkZcyp22tsVt38mlhWde8l3eJLWkyLrp4HwMUr3c1s/M2t7+kHIhvMjglIBrFpncX1SzMckomGw== + +"@esbuild/linux-x64@0.20.1": + version "0.20.1" + resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.20.1.tgz#0b25da17ac38c3e11cdd06ca3691d4d6bef2755f" + integrity sha512-5gRPk7pKuaIB+tmH+yKd2aQTRpqlf1E4f/mC+tawIm/CGJemZcHZpp2ic8oD83nKgUPMEd0fNanrnFljiruuyA== + +"@esbuild/linux-x64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz#86eca35203afc0d9de0694c64ec0ab0a378f6fff" + integrity sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw== + +"@esbuild/linux-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz#6d8f0c768e070e64309af8004bb94e68ab2bb3b0" + integrity sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ== + +"@esbuild/netbsd-x64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.17.19.tgz#c29fb2453c6b7ddef9a35e2c18b37bda1ae5c462" + integrity sha512-CwFq42rXCR8TYIjIfpXCbRX0rp1jo6cPIUPSaWwzbVI4aOfX96OXY8M6KNmtPcg7QjYeDmN+DD0Wp3LaBOLf4Q== + +"@esbuild/netbsd-x64@0.20.1": + version "0.20.1" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.20.1.tgz#3148e48406cd0d4f7ba1e0bf3f4d77d548c98407" + integrity sha512-4fL68JdrLV2nVW2AaWZBv3XEm3Ae3NZn/7qy2KGAt3dexAgSVT+Hc97JKSZnqezgMlv9x6KV0ZkZY7UO5cNLCg== + +"@esbuild/netbsd-x64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz#e771c8eb0e0f6e1877ffd4220036b98aed5915e6" + integrity sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ== + +"@esbuild/netbsd-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz#bbe430f60d378ecb88decb219c602667387a6047" + integrity sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg== + +"@esbuild/openbsd-x64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.17.19.tgz#95e75a391403cb10297280d524d66ce04c920691" + integrity sha512-cnq5brJYrSZ2CF6c35eCmviIN3k3RczmHz8eYaVlNasVqsNY+JKohZU5MKmaOI+KkllCdzOKKdPs762VCPC20g== + +"@esbuild/openbsd-x64@0.20.1": + version "0.20.1" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.20.1.tgz#7b73e852986a9750192626d377ac96ac2b749b76" + integrity sha512-GhRuXlvRE+twf2ES+8REbeCb/zeikNqwD3+6S5y5/x+DYbAQUNl0HNBs4RQJqrechS4v4MruEr8ZtAin/hK5iw== + +"@esbuild/openbsd-x64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz#9a795ae4b4e37e674f0f4d716f3e226dd7c39baf" + integrity sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ== + +"@esbuild/openbsd-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz#99d1cf2937279560d2104821f5ccce220cb2af70" + integrity sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow== + +"@esbuild/sunos-x64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.17.19.tgz#722eaf057b83c2575937d3ffe5aeb16540da7273" + integrity sha512-vCRT7yP3zX+bKWFeP/zdS6SqdWB8OIpaRq/mbXQxTGHnIxspRtigpkUcDMlSCOejlHowLqII7K2JKevwyRP2rg== + +"@esbuild/sunos-x64@0.20.1": + version "0.20.1" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.20.1.tgz#402a441cdac2eee98d8be378c7bc23e00c1861c5" + integrity sha512-ZnWEyCM0G1Ex6JtsygvC3KUUrlDXqOihw8RicRuQAzw+c4f1D66YlPNNV3rkjVW90zXVsHwZYWbJh3v+oQFM9Q== + +"@esbuild/sunos-x64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz#7df23b61a497b8ac189def6e25a95673caedb03f" + integrity sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w== + +"@esbuild/sunos-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz#08741512c10d529566baba837b4fe052c8f3487b" + integrity sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg== + +"@esbuild/win32-arm64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.17.19.tgz#9aa9dc074399288bdcdd283443e9aeb6b9552b6f" + integrity sha512-yYx+8jwowUstVdorcMdNlzklLYhPxjniHWFKgRqH7IFlUEa0Umu3KuYplf1HUZZ422e3NU9F4LGb+4O0Kdcaag== + +"@esbuild/win32-arm64@0.20.1": + version "0.20.1" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.20.1.tgz#36c4e311085806a6a0c5fc54d1ac4d7b27e94d7b" + integrity sha512-QZ6gXue0vVQY2Oon9WyLFCdSuYbXSoxaZrPuJ4c20j6ICedfsDilNPYfHLlMH7vGfU5DQR0czHLmJvH4Nzis/A== + +"@esbuild/win32-arm64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz#f1ae5abf9ca052ae11c1bc806fb4c0f519bacf90" + integrity sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ== + +"@esbuild/win32-arm64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz#675b7385398411240735016144ab2e99a60fc75d" + integrity sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A== + +"@esbuild/win32-ia32@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.17.19.tgz#95ad43c62ad62485e210f6299c7b2571e48d2b03" + integrity sha512-eggDKanJszUtCdlVs0RB+h35wNlb5v4TWEkq4vZcmVt5u/HiDZrTXe2bWFQUez3RgNHwx/x4sk5++4NSSicKkw== + +"@esbuild/win32-ia32@0.20.1": + version "0.20.1" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.20.1.tgz#0cf933be3fb9dc58b45d149559fe03e9e22b54fe" + integrity sha512-HzcJa1NcSWTAU0MJIxOho8JftNp9YALui3o+Ny7hCh0v5f90nprly1U3Sj1Ldj/CvKKdvvFsCRvDkpsEMp4DNw== + +"@esbuild/win32-ia32@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz#241fe62c34d8e8461cd708277813e1d0ba55ce23" + integrity sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ== + +"@esbuild/win32-ia32@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz#1bfc3ce98aa6ca9a0969e4d2af72144c59c1193b" + integrity sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA== + +"@esbuild/win32-x64@0.17.19": + version "0.17.19" + resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.17.19.tgz#8cfaf2ff603e9aabb910e9c0558c26cf32744061" + integrity sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA== + +"@esbuild/win32-x64@0.20.1": + version "0.20.1" + resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.20.1.tgz#77583b6ea54cee7c1410ebbd54051b6a3fcbd8ba" + integrity sha512-0MBh53o6XtI6ctDnRMeQ+xoCN8kD2qI1rY1KgF/xdWQwoFeKou7puvDfV8/Wv4Ctx2rRpET/gGdz3YlNtNACSA== + +"@esbuild/win32-x64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz#9c907b21e30a52db959ba4f80bb01a0cc403d5cc" + integrity sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ== + +"@esbuild/win32-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz#acad351d582d157bb145535db2a6ff53dd514b5c" + integrity sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw== + +"@eslint-community/eslint-utils@^4.2.0": + version "4.4.0" + resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59" + integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA== + dependencies: + eslint-visitor-keys "^3.3.0" + +"@eslint-community/regexpp@^4.4.0", "@eslint-community/regexpp@^4.6.1": + version "4.10.0" + resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.10.0.tgz#548f6de556857c8bb73bbee70c35dc82a2e74d63" + integrity sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA== + +"@eslint/eslintrc@^2.1.3": + version "2.1.3" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.1.3.tgz#797470a75fe0fbd5a53350ee715e85e87baff22d" + integrity sha512-yZzuIG+jnVu6hNSzFEN07e8BxF3uAzYtQb6uDkaYZLo6oYZDCq454c5kB8zxnzfCYyP4MIuyBn10L0DqwujTmA== + dependencies: + ajv "^6.12.4" + debug "^4.3.2" + espree "^9.6.0" + globals "^13.19.0" + ignore "^5.2.0" + import-fresh "^3.2.1" + js-yaml "^4.1.0" + minimatch "^3.1.2" + strip-json-comments "^3.1.1" + +"@eslint/js@8.54.0": + version "8.54.0" + resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.54.0.tgz#4fab9a2ff7860082c304f750e94acd644cf984cf" + integrity sha512-ut5V+D+fOoWPgGGNj83GGjnntO39xDy6DWxO0wb7Jp3DcMX0TfIqdzHF85VTQkerdyGmuuMD9AKAo5KiNlf/AQ== + +"@ethereumjs/common@^4.2.0", "@ethereumjs/common@^4.3.0": + version "4.3.0" + resolved "https://registry.yarnpkg.com/@ethereumjs/common/-/common-4.3.0.tgz#5b45eec7dcf521fa4ddaf0b383072fbcf9913553" + integrity sha512-shBNJ0ewcPNTUfZduHiczPmqkfJDn0Dh/9BR5fq7xUFTuIq7Fu1Vx00XDwQVIrpVL70oycZocOhBM6nDO+4FEQ== + dependencies: + "@ethereumjs/util" "^9.0.3" + +"@ethereumjs/rlp@^5.0.2": + version "5.0.2" + resolved "https://registry.yarnpkg.com/@ethereumjs/rlp/-/rlp-5.0.2.tgz#c89bd82f2f3bec248ab2d517ae25f5bbc4aac842" + integrity sha512-DziebCdg4JpGlEqEdGgXmjqcFoJi+JGulUXwEjsZGAscAQ7MyD/7LE/GVCP29vEQxKc7AAwjT3A2ywHp2xfoCA== + +"@ethereumjs/tx@^5.2.1": + version "5.3.0" + resolved "https://registry.yarnpkg.com/@ethereumjs/tx/-/tx-5.3.0.tgz#473f351729ef4e30eaa3a3fb5aaccd4405a7ee41" + integrity sha512-uv++XYuIfuqYbvymL3/o14hHuC6zX0nRQ1nI2FHsbkkorLZ2ChEIDqVeeVk7Xc9/jQNU/22sk9qZZkRlsveXxw== + dependencies: + "@ethereumjs/common" "^4.3.0" + "@ethereumjs/rlp" "^5.0.2" + "@ethereumjs/util" "^9.0.3" + ethereum-cryptography "^2.1.3" + +"@ethereumjs/util@^9.0.3": + version "9.0.3" + resolved "https://registry.yarnpkg.com/@ethereumjs/util/-/util-9.0.3.tgz#c2709e6127a85bbe23a71937ac78358ac93e7241" + integrity sha512-PmwzWDflky+7jlZIFqiGsBPap12tk9zK5SVH9YW2OEnDN7OEhCjUOMzbOqwuClrbkSIkM2ERivd7sXZ48Rh/vg== + dependencies: + "@ethereumjs/rlp" "^5.0.2" + ethereum-cryptography "^2.1.3" + +"@ethersproject/abi@5.7.0", "@ethersproject/abi@^5.5.0", "@ethersproject/abi@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.7.0.tgz#b3f3e045bbbeed1af3947335c247ad625a44e449" + integrity sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA== + dependencies: "@ethersproject/address" "^5.7.0" "@ethersproject/bignumber" "^5.7.0" "@ethersproject/bytes" "^5.7.0" @@ -2188,7 +3468,7 @@ "@ethersproject/bytes" "^5.7.0" "@ethersproject/logger" "^5.7.0" -"@ethersproject/rlp@5.7.0", "@ethersproject/rlp@^5.7.0": +"@ethersproject/rlp@5.7.0", "@ethersproject/rlp@^5.5.0", "@ethersproject/rlp@^5.7.0": version "5.7.0" resolved "https://registry.yarnpkg.com/@ethersproject/rlp/-/rlp-5.7.0.tgz#de39e4d5918b9d74d46de93af80b7685a9c21304" integrity sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w== @@ -2305,30 +3585,79 @@ "@ethersproject/properties" "^5.7.0" "@ethersproject/strings" "^5.7.0" -"@floating-ui/core@^0.7.3": - version "0.7.3" - resolved "https://registry.yarnpkg.com/@floating-ui/core/-/core-0.7.3.tgz#d274116678ffae87f6b60e90f88cc4083eefab86" - integrity sha512-buc8BXHmG9l82+OQXOFU3Kr2XQx9ys01U/Q9HMIrZ300iLc8HLMgh7dcCqgYzAzf4BkoQvDcXf5Y+CuEZ5JBYg== +"@faker-js/faker@^8.4.1": + version "8.4.1" + resolved "https://registry.yarnpkg.com/@faker-js/faker/-/faker-8.4.1.tgz#5d5e8aee8fce48f5e189bf730ebd1f758f491451" + integrity sha512-XQ3cU+Q8Uqmrbf2e0cIC/QN43sTBSC8KF12u29Mb47tWrt2hAgBXSgpZMj4Ao8Uk0iJcU99QsOCaIL8934obCg== -"@floating-ui/dom@^0.5.3": - version "0.5.4" - resolved "https://registry.yarnpkg.com/@floating-ui/dom/-/dom-0.5.4.tgz#4eae73f78bcd4bd553ae2ade30e6f1f9c73fe3f1" - integrity sha512-419BMceRLq0RrmTSDxn8hf9R3VCJv2K9PUfugh5JyEFmdjzDo+e8U5EdR8nzKq8Yj1htzLm3b6eQEEam3/rrtg== +"@fal-works/esbuild-plugin-global-externals@^2.1.2": + version "2.1.2" + resolved "https://registry.yarnpkg.com/@fal-works/esbuild-plugin-global-externals/-/esbuild-plugin-global-externals-2.1.2.tgz#c05ed35ad82df8e6ac616c68b92c2282bd083ba4" + integrity sha512-cEee/Z+I12mZcFJshKcCqC8tuX5hG3s+d+9nZ3LabqKF1vKdF41B92pJVCBggjAGORAeOzyyDDKrZwIkLffeOQ== + +"@fastify/busboy@^2.0.0": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@fastify/busboy/-/busboy-2.1.1.tgz#b9da6a878a371829a0502c9b6c1c143ef6663f4d" + integrity sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA== + +"@fivebinaries/coin-selection@2.2.1": + version "2.2.1" + resolved "https://registry.yarnpkg.com/@fivebinaries/coin-selection/-/coin-selection-2.2.1.tgz#f5329909ac8cd1bf87decdcd054c88a8d69399a0" + integrity sha512-iYFsYr7RY7TEvTqP9NKR4p/yf3Iybf9abUDR7lRjzanGsrLwVsREvIuyE05iRYFrvqarlk+gWRPsdR1N2hUBrg== + dependencies: + "@emurgo/cardano-serialization-lib-browser" "^11.5.0" + "@emurgo/cardano-serialization-lib-nodejs" "11.5.0" + +"@floating-ui/core@^1.4.2": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@floating-ui/core/-/core-1.5.0.tgz#5c05c60d5ae2d05101c3021c1a2a350ddc027f8c" + integrity sha512-kK1h4m36DQ0UHGj5Ah4db7R0rHemTqqO0QLvUqi1/mUUp3LuAWbWxdxSIf/XsnH9VS6rRVPLJCncjRzUvyCLXg== dependencies: - "@floating-ui/core" "^0.7.3" + "@floating-ui/utils" "^0.1.3" -"@floating-ui/react-dom@0.7.2": - version "0.7.2" - resolved "https://registry.yarnpkg.com/@floating-ui/react-dom/-/react-dom-0.7.2.tgz#0bf4ceccb777a140fc535c87eb5d6241c8e89864" - integrity sha512-1T0sJcpHgX/u4I1OzIEhlcrvkUN8ln39nz7fMoE/2HDHrPiMFoOGR7++GYyfUmIQHkkrTinaeQsO3XWubjSvGg== +"@floating-ui/dom@^1.5.1": + version "1.5.3" + resolved "https://registry.yarnpkg.com/@floating-ui/dom/-/dom-1.5.3.tgz#54e50efcb432c06c23cd33de2b575102005436fa" + integrity sha512-ClAbQnEqJAKCJOEbbLo5IUlZHkNszqhuxS4fHAVxRPXPya6Ysf2G8KypnYcOTpx6I8xcgF9bbHb6g/2KpbV8qA== dependencies: - "@floating-ui/dom" "^0.5.3" - use-isomorphic-layout-effect "^1.1.1" + "@floating-ui/core" "^1.4.2" + "@floating-ui/utils" "^0.1.3" -"@gar/promisify@^1.0.1": - version "1.1.3" - resolved "https://registry.yarnpkg.com/@gar/promisify/-/promisify-1.1.3.tgz#555193ab2e3bb3b6adc3d551c9c030d9e860daf6" - integrity sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw== +"@floating-ui/react-dom@^2.0.0": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@floating-ui/react-dom/-/react-dom-2.0.4.tgz#b076fafbdfeb881e1d86ae748b7ff95150e9f3ec" + integrity sha512-CF8k2rgKeh/49UrnIBs4BdxPUV6vize/Db1d/YbCLyp9GiVZ0BEwf5AiDSxJRCr6yOkGqTFHtmrULxkEfYZ7dQ== + dependencies: + "@floating-ui/dom" "^1.5.1" + +"@floating-ui/utils@^0.1.3": + version "0.1.6" + resolved "https://registry.yarnpkg.com/@floating-ui/utils/-/utils-0.1.6.tgz#22958c042e10b67463997bd6ea7115fe28cbcaf9" + integrity sha512-OfX7E2oUDYxtBvsuS4e/jSn4Q9Qb6DzgeYtsAdkPZ47znpoNsMgZw0+tVijiv3uGNR6dgNlty6r9rzIzHjtd/A== + +"@humanwhocodes/config-array@^0.11.13": + version "0.11.13" + resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.13.tgz#075dc9684f40a531d9b26b0822153c1e832ee297" + integrity sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ== + dependencies: + "@humanwhocodes/object-schema" "^2.0.1" + debug "^4.1.1" + minimatch "^3.0.5" + +"@humanwhocodes/module-importer@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c" + integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== + +"@humanwhocodes/object-schema@^2.0.1": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz#e5211452df060fa8522b55c7b3c0c4d1981cb044" + integrity sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw== + +"@hutson/parse-repository-url@^3.0.0": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@hutson/parse-repository-url/-/parse-repository-url-3.0.2.tgz#98c23c950a3d9b6c8f0daed06da6c3af06981340" + integrity sha512-H9XAx3hc0BQHY6l+IFSWHDySypcXsvsuLhgYLUGywmJ5pswRVQJUHpOsobnLYp2ZUaUlKiKDrgWWhosOwAEM8Q== "@hypnosphi/create-react-context@^0.3.1": version "0.3.1" @@ -2343,6 +3672,18 @@ resolved "https://registry.yarnpkg.com/@icons/material/-/material-0.2.4.tgz#e90c9f71768b3736e76d7dd6783fc6c2afa88bc8" integrity sha512-QPcGmICAPbGLGb6F/yNf/KzKqvFx8z5qx3D1yFqVAjoFmXK35EgyW+cJ57Te3CNsmzblwtzakLGFqHPqrfb4Tw== +"@improbable-eng/grpc-web@^0.14.1": + version "0.14.1" + resolved "https://registry.yarnpkg.com/@improbable-eng/grpc-web/-/grpc-web-0.14.1.tgz#f4662f64dc89c0f956a94bb8a3b576556c74589c" + integrity sha512-XaIYuunepPxoiGVLLHmlnVminUGzBTnXr8Wv7khzmLWbNw4TCwJKX09GSMJlKhu/TRk6gms0ySFxewaETSBqgw== + dependencies: + browser-headers "^0.4.1" + +"@ioredis/commands@^1.1.1": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@ioredis/commands/-/commands-1.2.0.tgz#6d61b3097470af1fdbbe622795b8921d42018e11" + integrity sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg== + "@iov/crypto@2.1.0": version "2.1.0" resolved "https://registry.yarnpkg.com/@iov/crypto/-/crypto-2.1.0.tgz#10e91b6692e154958c11626dfd096a80e8a481a4" @@ -2385,302 +3726,123 @@ resolved "https://registry.yarnpkg.com/@iov/utils/-/utils-2.0.2.tgz#3527f376d26100e07ac823bf87bebd0f24680d1c" integrity sha512-4D8MEvTcFc/DVy5q25vHxRItmgJyeX85dixMH+MxdKr+yy71h3sYk+sVBEIn70uqGP7VqAJkGOPNFs08/XYELw== -"@istanbuljs/load-nyc-config@^1.0.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced" - integrity sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ== +"@isaacs/cliui@^8.0.2": + version "8.0.2" + resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550" + integrity sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA== dependencies: - camelcase "^5.3.1" - find-up "^4.1.0" - get-package-type "^0.1.0" - js-yaml "^3.13.1" - resolve-from "^5.0.0" + string-width "^5.1.2" + string-width-cjs "npm:string-width@^4.2.0" + strip-ansi "^7.0.1" + strip-ansi-cjs "npm:strip-ansi@^6.0.1" + wrap-ansi "^8.1.0" + wrap-ansi-cjs "npm:wrap-ansi@^7.0.0" -"@istanbuljs/schema@^0.1.2", "@istanbuljs/schema@^0.1.3": +"@istanbuljs/schema@^0.1.2": version "0.1.3" resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== -"@jest/console@^25.5.0": - version "25.5.0" - resolved "https://registry.yarnpkg.com/@jest/console/-/console-25.5.0.tgz#770800799d510f37329c508a9edd0b7b447d9abb" - integrity sha512-T48kZa6MK1Y6k4b89sexwmSF4YLeZS/Udqg3Jj3jG/cHH+N/sLFCEoXEDMOKugJQ9FxPN1osxIknvKkxt6MKyw== +"@jest/schemas@^29.6.3": + version "29.6.3" + resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-29.6.3.tgz#430b5ce8a4e0044a7e3819663305a7b3091c8e03" + integrity sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA== dependencies: - "@jest/types" "^25.5.0" - chalk "^3.0.0" - jest-message-util "^25.5.0" - jest-util "^25.5.0" - slash "^3.0.0" + "@sinclair/typebox" "^0.27.8" -"@jest/core@^25.5.4": - version "25.5.4" - resolved "https://registry.yarnpkg.com/@jest/core/-/core-25.5.4.tgz#3ef7412f7339210f003cdf36646bbca786efe7b4" - integrity sha512-3uSo7laYxF00Dg/DMgbn4xMJKmDdWvZnf89n8Xj/5/AeQ2dOQmn6b6Hkj/MleyzZWXpwv+WSdYWl4cLsy2JsoA== +"@jest/types@^29.6.3": + version "29.6.3" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-29.6.3.tgz#1131f8cf634e7e84c5e77bab12f052af585fba59" + integrity sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw== dependencies: - "@jest/console" "^25.5.0" - "@jest/reporters" "^25.5.1" - "@jest/test-result" "^25.5.0" - "@jest/transform" "^25.5.1" - "@jest/types" "^25.5.0" - ansi-escapes "^4.2.1" - chalk "^3.0.0" - exit "^0.1.2" - graceful-fs "^4.2.4" - jest-changed-files "^25.5.0" - jest-config "^25.5.4" - jest-haste-map "^25.5.1" - jest-message-util "^25.5.0" - jest-regex-util "^25.2.6" - jest-resolve "^25.5.1" - jest-resolve-dependencies "^25.5.4" - jest-runner "^25.5.4" - jest-runtime "^25.5.4" - jest-snapshot "^25.5.1" - jest-util "^25.5.0" - jest-validate "^25.5.0" - jest-watcher "^25.5.0" - micromatch "^4.0.2" - p-each-series "^2.1.0" - realpath-native "^2.0.0" - rimraf "^3.0.0" - slash "^3.0.0" - strip-ansi "^6.0.0" + "@jest/schemas" "^29.6.3" + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/istanbul-reports" "^3.0.0" + "@types/node" "*" + "@types/yargs" "^17.0.8" + chalk "^4.0.0" -"@jest/environment@^25.5.0": - version "25.5.0" - resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-25.5.0.tgz#aa33b0c21a716c65686638e7ef816c0e3a0c7b37" - integrity sha512-U2VXPEqL07E/V7pSZMSQCvV5Ea4lqOlT+0ZFijl/i316cRMHvZ4qC+jBdryd+lmRetjQo0YIQr6cVPNxxK87mA== +"@joshwooding/vite-plugin-react-docgen-typescript@0.3.0": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@joshwooding/vite-plugin-react-docgen-typescript/-/vite-plugin-react-docgen-typescript-0.3.0.tgz#67599fca260c2eafdaf234a944f9d471e6d53b08" + integrity sha512-2D6y7fNvFmsLmRt6UCOFJPvFoPMJGT0Uh1Wg0RaigUp7kdQPs6yYn8Dmx6GZkOH/NW0yMTwRz/p0SRMMRo50vA== dependencies: - "@jest/fake-timers" "^25.5.0" - "@jest/types" "^25.5.0" - jest-mock "^25.5.0" + glob "^7.2.0" + glob-promise "^4.2.0" + magic-string "^0.27.0" + react-docgen-typescript "^2.2.2" -"@jest/fake-timers@^25.5.0": - version "25.5.0" - resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-25.5.0.tgz#46352e00533c024c90c2bc2ad9f2959f7f114185" - integrity sha512-9y2+uGnESw/oyOI3eww9yaxdZyHq7XvprfP/eeoCsjqKYts2yRlsHS/SgjPDV8FyMfn2nbMy8YzUk6nyvdLOpQ== +"@jridgewell/gen-mapping@^0.3.0", "@jridgewell/gen-mapping@^0.3.2": + version "0.3.3" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz#7e02e6eb5df901aaedb08514203b096614024098" + integrity sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ== dependencies: - "@jest/types" "^25.5.0" - jest-message-util "^25.5.0" - jest-mock "^25.5.0" - jest-util "^25.5.0" - lolex "^5.0.0" + "@jridgewell/set-array" "^1.0.1" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/trace-mapping" "^0.3.9" -"@jest/globals@^25.5.2": - version "25.5.2" - resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-25.5.2.tgz#5e45e9de8d228716af3257eeb3991cc2e162ca88" - integrity sha512-AgAS/Ny7Q2RCIj5kZ+0MuKM1wbF0WMLxbCVl/GOMoCNbODRdJ541IxJ98xnZdVSZXivKpJlNPIWa3QmY0l4CXA== +"@jridgewell/gen-mapping@^0.3.5": + version "0.3.5" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz#dcce6aff74bdf6dad1a95802b69b04a2fcb1fb36" + integrity sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg== dependencies: - "@jest/environment" "^25.5.0" - "@jest/types" "^25.5.0" - expect "^25.5.0" + "@jridgewell/set-array" "^1.2.1" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/trace-mapping" "^0.3.24" -"@jest/reporters@^25.5.1": - version "25.5.1" - resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-25.5.1.tgz#cb686bcc680f664c2dbaf7ed873e93aa6811538b" - integrity sha512-3jbd8pPDTuhYJ7vqiHXbSwTJQNavczPs+f1kRprRDxETeE3u6srJ+f0NPuwvOmk+lmunZzPkYWIFZDLHQPkviw== - dependencies: - "@bcoe/v8-coverage" "^0.2.3" - "@jest/console" "^25.5.0" - "@jest/test-result" "^25.5.0" - "@jest/transform" "^25.5.1" - "@jest/types" "^25.5.0" - chalk "^3.0.0" - collect-v8-coverage "^1.0.0" - exit "^0.1.2" - glob "^7.1.2" - graceful-fs "^4.2.4" - istanbul-lib-coverage "^3.0.0" - istanbul-lib-instrument "^4.0.0" - istanbul-lib-report "^3.0.0" - istanbul-lib-source-maps "^4.0.0" - istanbul-reports "^3.0.2" - jest-haste-map "^25.5.1" - jest-resolve "^25.5.1" - jest-util "^25.5.0" - jest-worker "^25.5.0" - slash "^3.0.0" - source-map "^0.6.0" - string-length "^3.1.0" - terminal-link "^2.0.0" - v8-to-istanbul "^4.1.3" - optionalDependencies: - node-notifier "^6.0.0" +"@jridgewell/resolve-uri@^3.1.0": + version "3.1.1" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz#c08679063f279615a3326583ba3a90d1d82cc721" + integrity sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA== -"@jest/source-map@^25.5.0": - version "25.5.0" - resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-25.5.0.tgz#df5c20d6050aa292c2c6d3f0d2c7606af315bd1b" - integrity sha512-eIGx0xN12yVpMcPaVpjXPnn3N30QGJCJQSkEDUt9x1fI1Gdvb07Ml6K5iN2hG7NmMP6FDmtPEssE3z6doOYUwQ== - dependencies: - callsites "^3.0.0" - graceful-fs "^4.2.4" - source-map "^0.6.0" +"@jridgewell/set-array@^1.0.1": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" + integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== -"@jest/test-result@^25.5.0": - version "25.5.0" - resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-25.5.0.tgz#139a043230cdeffe9ba2d8341b27f2efc77ce87c" - integrity sha512-oV+hPJgXN7IQf/fHWkcS99y0smKLU2czLBJ9WA0jHITLst58HpQMtzSYxzaBvYc6U5U6jfoMthqsUlUlbRXs0A== - dependencies: - "@jest/console" "^25.5.0" - "@jest/types" "^25.5.0" - "@types/istanbul-lib-coverage" "^2.0.0" - collect-v8-coverage "^1.0.0" - -"@jest/test-sequencer@^25.5.4": - version "25.5.4" - resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-25.5.4.tgz#9b4e685b36954c38d0f052e596d28161bdc8b737" - integrity sha512-pTJGEkSeg1EkCO2YWq6hbFvKNXk8ejqlxiOg1jBNLnWrgXOkdY6UmqZpwGFXNnRt9B8nO1uWMzLLZ4eCmhkPNA== - dependencies: - "@jest/test-result" "^25.5.0" - graceful-fs "^4.2.4" - jest-haste-map "^25.5.1" - jest-runner "^25.5.4" - jest-runtime "^25.5.4" - -"@jest/transform@^25.5.1": - version "25.5.1" - resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-25.5.1.tgz#0469ddc17699dd2bf985db55fa0fb9309f5c2db3" - integrity sha512-Y8CEoVwXb4QwA6Y/9uDkn0Xfz0finGkieuV0xkdF9UtZGJeLukD5nLkaVrVsODB1ojRWlaoD0AJZpVHCSnJEvg== - dependencies: - "@babel/core" "^7.1.0" - "@jest/types" "^25.5.0" - babel-plugin-istanbul "^6.0.0" - chalk "^3.0.0" - convert-source-map "^1.4.0" - fast-json-stable-stringify "^2.0.0" - graceful-fs "^4.2.4" - jest-haste-map "^25.5.1" - jest-regex-util "^25.2.6" - jest-util "^25.5.0" - micromatch "^4.0.2" - pirates "^4.0.1" - realpath-native "^2.0.0" - slash "^3.0.0" - source-map "^0.6.1" - write-file-atomic "^3.0.0" - -"@jest/transform@^26.6.2": - version "26.6.2" - resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-26.6.2.tgz#5ac57c5fa1ad17b2aae83e73e45813894dcf2e4b" - integrity sha512-E9JjhUgNzvuQ+vVAL21vlyfy12gP0GhazGgJC4h6qUt1jSdUXGWJ1wfu/X7Sd8etSgxV4ovT1pb9v5D6QW4XgA== - dependencies: - "@babel/core" "^7.1.0" - "@jest/types" "^26.6.2" - babel-plugin-istanbul "^6.0.0" - chalk "^4.0.0" - convert-source-map "^1.4.0" - fast-json-stable-stringify "^2.0.0" - graceful-fs "^4.2.4" - jest-haste-map "^26.6.2" - jest-regex-util "^26.0.0" - jest-util "^26.6.2" - micromatch "^4.0.2" - pirates "^4.0.1" - slash "^3.0.0" - source-map "^0.6.1" - write-file-atomic "^3.0.0" - -"@jest/types@^25.5.0": - version "25.5.0" - resolved "https://registry.yarnpkg.com/@jest/types/-/types-25.5.0.tgz#4d6a4793f7b9599fc3680877b856a97dbccf2a9d" - integrity sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw== - dependencies: - "@types/istanbul-lib-coverage" "^2.0.0" - "@types/istanbul-reports" "^1.1.1" - "@types/yargs" "^15.0.0" - chalk "^3.0.0" - -"@jest/types@^26.6.2": - version "26.6.2" - resolved "https://registry.yarnpkg.com/@jest/types/-/types-26.6.2.tgz#bef5a532030e1d88a2f5a6d933f84e97226ed48e" - integrity sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ== - dependencies: - "@types/istanbul-lib-coverage" "^2.0.0" - "@types/istanbul-reports" "^3.0.0" - "@types/node" "*" - "@types/yargs" "^15.0.0" - chalk "^4.0.0" - -"@jridgewell/gen-mapping@^0.1.0": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz#e5d2e450306a9491e3bd77e323e38d7aff315996" - integrity sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w== - dependencies: - "@jridgewell/set-array" "^1.0.0" - "@jridgewell/sourcemap-codec" "^1.4.10" - -"@jridgewell/gen-mapping@^0.3.0", "@jridgewell/gen-mapping@^0.3.2": - version "0.3.2" - resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz#c1aedc61e853f2bb9f5dfe6d4442d3b565b253b9" - integrity sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A== - dependencies: - "@jridgewell/set-array" "^1.0.1" - "@jridgewell/sourcemap-codec" "^1.4.10" - "@jridgewell/trace-mapping" "^0.3.9" - -"@jridgewell/resolve-uri@3.1.0", "@jridgewell/resolve-uri@^3.0.3": - version "3.1.0" - resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78" - integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== - -"@jridgewell/set-array@^1.0.0", "@jridgewell/set-array@^1.0.1": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" - integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== +"@jridgewell/set-array@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.2.1.tgz#558fb6472ed16a4c850b889530e6b36438c49280" + integrity sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A== -"@jridgewell/source-map@^0.3.2": - version "0.3.2" - resolved "https://registry.yarnpkg.com/@jridgewell/source-map/-/source-map-0.3.2.tgz#f45351aaed4527a298512ec72f81040c998580fb" - integrity sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw== +"@jridgewell/source-map@^0.3.3": + version "0.3.5" + resolved "https://registry.yarnpkg.com/@jridgewell/source-map/-/source-map-0.3.5.tgz#a3bb4d5c6825aab0d281268f47f6ad5853431e91" + integrity sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ== dependencies: "@jridgewell/gen-mapping" "^0.3.0" "@jridgewell/trace-mapping" "^0.3.9" -"@jridgewell/sourcemap-codec@1.4.14", "@jridgewell/sourcemap-codec@^1.4.10": - version "1.4.14" - resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" - integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== - -"@jridgewell/trace-mapping@0.3.9": - version "0.3.9" - resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz#6534fd5933a53ba7cbf3a17615e273a0d1273ff9" - integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ== - dependencies: - "@jridgewell/resolve-uri" "^3.0.3" - "@jridgewell/sourcemap-codec" "^1.4.10" +"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.13", "@jridgewell/sourcemap-codec@^1.4.14", "@jridgewell/sourcemap-codec@^1.4.15": + version "1.4.15" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" + integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== -"@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.9": - version "0.3.17" - resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz#793041277af9073b0951a7fe0f0d8c4c98c36985" - integrity sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g== - dependencies: - "@jridgewell/resolve-uri" "3.1.0" - "@jridgewell/sourcemap-codec" "1.4.14" +"@jridgewell/sourcemap-codec@^1.5.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz#3188bcb273a414b0d215fd22a58540b989b9409a" + integrity sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ== -"@json-rpc-tools/provider@^1.5.5": - version "1.7.6" - resolved "https://registry.yarnpkg.com/@json-rpc-tools/provider/-/provider-1.7.6.tgz#8a17c34c493fa892632e278fd9331104e8491ec6" - integrity sha512-z7D3xvJ33UfCGv77n40lbzOYjZKVM3k2+5cV7xS8G6SCvKTzMkhkUYuD/qzQUNT4cG/lv0e9mRToweEEVLVVmA== +"@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.9": + version "0.3.20" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz#72e45707cf240fa6b081d0366f8265b0cd10197f" + integrity sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q== dependencies: - "@json-rpc-tools/utils" "^1.7.6" - axios "^0.21.0" - safe-json-utils "^1.1.1" - ws "^7.4.0" + "@jridgewell/resolve-uri" "^3.1.0" + "@jridgewell/sourcemap-codec" "^1.4.14" -"@json-rpc-tools/types@^1.7.6": - version "1.7.6" - resolved "https://registry.yarnpkg.com/@json-rpc-tools/types/-/types-1.7.6.tgz#5abd5fde01364a130c46093b501715bcce5bdc0e" - integrity sha512-nDSqmyRNEqEK9TZHtM15uNnDljczhCUdBmRhpNZ95bIPKEDQ+nTDmGMFd2lLin3upc5h2VVVd9tkTDdbXUhDIQ== +"@jridgewell/trace-mapping@^0.3.20", "@jridgewell/trace-mapping@^0.3.23", "@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25": + version "0.3.25" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz#15f190e98895f3fc23276ee14bc76b675c2e50f0" + integrity sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ== dependencies: - keyvaluestorage-interface "^1.0.0" + "@jridgewell/resolve-uri" "^3.1.0" + "@jridgewell/sourcemap-codec" "^1.4.14" -"@json-rpc-tools/utils@^1.7.6": - version "1.7.6" - resolved "https://registry.yarnpkg.com/@json-rpc-tools/utils/-/utils-1.7.6.tgz#67f04987dbaa2e7adb6adff1575367b75a9a9ba1" - integrity sha512-HjA8x/U/Q78HRRe19yh8HVKoZ+Iaoo3YZjakJYxR+rw52NHo6jM+VE9b8+7ygkCFXl/EHID5wh/MkXaE/jGyYw== - dependencies: - "@json-rpc-tools/types" "^1.7.6" - "@pedrouid/environment" "^1.0.1" +"@jspm/core@^2.0.1": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@jspm/core/-/core-2.0.1.tgz#3f08c59c60a5f5e994523ed6b0b665ec80adc94e" + integrity sha512-Lg3PnLp0QXpxwLIAuuJboLeRaIhrgJjeuh797QADg3xz8wGLugQOS5DpsE8A6i6Adgzf+bacllkKZG3J0tGfDw== "@keplr-wallet/cosmos@^0.9.12": version "0.9.16" @@ -2709,10 +3871,15 @@ elliptic "^6.5.3" sha.js "^2.4.11" +"@keplr-wallet/simple-fetch@^0.12.14": + version "0.12.44" + resolved "https://registry.yarnpkg.com/@keplr-wallet/simple-fetch/-/simple-fetch-0.12.44.tgz#168c48638f592fe4cc5fe03e57eccc46a06284d7" + integrity sha512-lwTfB6g9XxZR94EBsPFuQida9HLTi67iOQtSw3JUKS6UMUNR9NrvHHrEf6F+CdBpgv5TJ0yKKQGm8+KbUhPSnw== + "@keplr-wallet/types@^0.11.21": - version "0.11.52" - resolved "https://registry.yarnpkg.com/@keplr-wallet/types/-/types-0.11.52.tgz#a4dd652403d2ed5849a58ea7c4595034f7a5a0e3" - integrity sha512-2LyOnaZpyjw5DiyJIG/L73PD/n284GrvhGjAkaTKantx70VGNgH/3x0DwjKpevRRxcuJ+2+A0LkHgkXIpD7YhQ== + version "0.11.64" + resolved "https://registry.yarnpkg.com/@keplr-wallet/types/-/types-0.11.64.tgz#5a308c8c019b4e18f894e0f35f0904b60134d605" + integrity sha512-GgzeLDHHfZFyne3O7UIfFHj/uYqVbxAZI31RbBwt460OBbvwQzjrlZwvJW3vieWRAgxKSITjzEDBl2WneFTQdQ== dependencies: axios "^0.27.2" long "^4.0.0" @@ -2737,189 +3904,393 @@ big-integer "^1.6.48" utility-types "^3.10.0" -"@ledgerhq/devices@^5.51.1": - version "5.51.1" - resolved "https://registry.yarnpkg.com/@ledgerhq/devices/-/devices-5.51.1.tgz#d741a4a5d8f17c2f9d282fd27147e6fe1999edb7" - integrity sha512-4w+P0VkbjzEXC7kv8T1GJ/9AVaP9I6uasMZ/JcdwZBS3qwvKo5A5z9uGhP5c7TvItzcmPb44b5Mw2kT+WjUuAA== +"@ledgerhq/cryptoassets@^12.1.0": + version "12.1.0" + resolved "https://registry.yarnpkg.com/@ledgerhq/cryptoassets/-/cryptoassets-12.1.0.tgz#b123a543e3a00466f5e806eadd0403ee0741393c" + integrity sha512-KF9J0X5qmEpHyAy9FphAmDsuodQN/UA3xmjqBhmBSELt/8tAUHHWNOeEV4TfuJLmk2HzXF730aH+61lvVvIUVw== dependencies: - "@ledgerhq/errors" "^5.50.0" - "@ledgerhq/logs" "^5.50.0" - rxjs "6" + axios "^1.6.0" + bs58check "^2.1.2" + invariant "2" + +"@ledgerhq/devices@^8.3.0": + version "8.3.0" + resolved "https://registry.yarnpkg.com/@ledgerhq/devices/-/devices-8.3.0.tgz#a1e1a21608e162fb3a512f57863bf9842b29493f" + integrity sha512-h5Scr+yIae8yjPOViCHLdMjpqn4oC2Whrsq8LinRxe48LEGMdPqSV1yY7+3Ch827wtzNpMv+/ilKnd8rY+rTlg== + dependencies: + "@ledgerhq/errors" "^6.16.4" + "@ledgerhq/logs" "^6.12.0" + rxjs "^7.8.1" semver "^7.3.5" -"@ledgerhq/errors@^5.34.0", "@ledgerhq/errors@^5.50.0": - version "5.50.0" - resolved "https://registry.yarnpkg.com/@ledgerhq/errors/-/errors-5.50.0.tgz#e3a6834cb8c19346efca214c1af84ed28e69dad9" - integrity sha512-gu6aJ/BHuRlpU7kgVpy2vcYk6atjB4iauP2ymF7Gk0ez0Y/6VSMVSJvubeEQN+IV60+OBK0JgeIZG7OiHaw8ow== - -"@ledgerhq/hw-transport-node-hid-noevents@^5.51.1": - version "5.51.1" - resolved "https://registry.yarnpkg.com/@ledgerhq/hw-transport-node-hid-noevents/-/hw-transport-node-hid-noevents-5.51.1.tgz#71f37f812e448178ad0bcc2258982150d211c1ab" - integrity sha512-9wFf1L8ZQplF7XOY2sQGEeOhpmBRzrn+4X43kghZ7FBDoltrcK+s/D7S+7ffg3j2OySyP6vIIIgloXylao5Scg== - dependencies: - "@ledgerhq/devices" "^5.51.1" - "@ledgerhq/errors" "^5.50.0" - "@ledgerhq/hw-transport" "^5.51.1" - "@ledgerhq/logs" "^5.50.0" - node-hid "2.1.1" - -"@ledgerhq/hw-transport-node-hid@^5.10.0": - version "5.51.1" - resolved "https://registry.yarnpkg.com/@ledgerhq/hw-transport-node-hid/-/hw-transport-node-hid-5.51.1.tgz#fe8eb81e18929663540698c80905952cdbe542d5" - integrity sha512-Y2eVCCdhVs2Lfr7N2x2cNb+ogcZ24ZATO4QxaQ7LogjiPwYmzmvuXFn8zFjMSrKUCn9CtbptXcuiu0NkGsjWlw== - dependencies: - "@ledgerhq/devices" "^5.51.1" - "@ledgerhq/errors" "^5.50.0" - "@ledgerhq/hw-transport" "^5.51.1" - "@ledgerhq/hw-transport-node-hid-noevents" "^5.51.1" - "@ledgerhq/logs" "^5.50.0" - lodash "^4.17.21" - node-hid "2.1.1" - usb "^1.7.0" - -"@ledgerhq/hw-transport-u2f@^5.9.0": - version "5.34.0" - resolved "https://registry.yarnpkg.com/@ledgerhq/hw-transport-u2f/-/hw-transport-u2f-5.34.0.tgz#53466e4f07e177ec29b1ea061b6c56a57439a0cd" - integrity sha512-EM6LcbdD6Xo/msedbAWalBZlv89XAZrAZwL5zN9eKlUcWPjjG8c9+t5NedR/jmIaGuzIUVseUCIRxczqd5byOw== - dependencies: - "@ledgerhq/errors" "^5.34.0" - "@ledgerhq/hw-transport" "^5.34.0" - "@ledgerhq/logs" "^5.30.0" - u2f-api "0.2.7" - -"@ledgerhq/hw-transport-web-ble@^5.9.0": - version "5.51.1" - resolved "https://registry.yarnpkg.com/@ledgerhq/hw-transport-web-ble/-/hw-transport-web-ble-5.51.1.tgz#b8da62f09b82f79fa0969f74364e3b6b1bd0ee87" - integrity sha512-IQmn41C1ohYJKcuEUUrrjhlwaCcqa4cberAfrSICvec9YMFMzKJjvbD42eyyVLNXHMEBKmH5haCUN7fWlPppXw== - dependencies: - "@ledgerhq/devices" "^5.51.1" - "@ledgerhq/errors" "^5.50.0" - "@ledgerhq/hw-transport" "^5.51.1" - "@ledgerhq/logs" "^5.50.0" - rxjs "6" - -"@ledgerhq/hw-transport@^5.34.0", "@ledgerhq/hw-transport@^5.51.1": - version "5.51.1" - resolved "https://registry.yarnpkg.com/@ledgerhq/hw-transport/-/hw-transport-5.51.1.tgz#8dd14a8e58cbee4df0c29eaeef983a79f5f22578" - integrity sha512-6wDYdbWrw9VwHIcoDnqWBaDFyviyjZWv6H9vz9Vyhe4Qd7TIFmbTl/eWs6hZvtZBza9K8y7zD8ChHwRI4s9tSw== - dependencies: - "@ledgerhq/devices" "^5.51.1" - "@ledgerhq/errors" "^5.50.0" +"@ledgerhq/domain-service@^1.1.20": + version "1.1.20" + resolved "https://registry.yarnpkg.com/@ledgerhq/domain-service/-/domain-service-1.1.20.tgz#687cc592eedfd92fbfa68731e0917c46e1c76137" + integrity sha512-+o1cEZj9HkJeIz2eL3r52tzkOiEKMs9w5aXF+Gy4mrmBjQ3Tw0OY9b69b3jz6PjlEHwAZsDRmcvF1/hSW6ITjw== + dependencies: + "@ledgerhq/errors" "^6.16.4" + "@ledgerhq/logs" "^6.12.0" + "@ledgerhq/types-live" "^6.46.0" + axios "^1.3.4" + eip55 "^2.1.1" + react "^18.2.0" + react-dom "^18.2.0" + +"@ledgerhq/errors@^6.16.4": + version "6.16.4" + resolved "https://registry.yarnpkg.com/@ledgerhq/errors/-/errors-6.16.4.tgz#a38baffe8b096d9fff3ad839cadb55704c8d8e7b" + integrity sha512-M57yFaLYSN+fZCX0E0zUqOmrV6eipK+s5RhijHoUNlHUqrsvUz7iRQgpd5gRgHB5VkIjav7KdaZjKiWGcHovaQ== + +"@ledgerhq/evm-tools@^1.0.18": + version "1.0.18" + resolved "https://registry.yarnpkg.com/@ledgerhq/evm-tools/-/evm-tools-1.0.18.tgz#447e9e79d78a396b3c93ad3b7c62fe7e314e96e1" + integrity sha512-jF7H5kjnFp/ju+QvErHyjNtb9G6aaZ1/ne703SO9JwLf/p8fM3uWe5TvS93S8V2sFoO06aoInnwFTJ860ZQKmw== + dependencies: + "@ledgerhq/cryptoassets" "^12.1.0" + "@ledgerhq/live-env" "^2.0.1" + axios "^1.6.5" + crypto-js "4.2.0" + ethers "5.7.2" + +"@ledgerhq/hw-app-eth@^6.36.0": + version "6.36.0" + resolved "https://registry.yarnpkg.com/@ledgerhq/hw-app-eth/-/hw-app-eth-6.36.0.tgz#595f0712d9ae321faba031b728ad68be1461ae4c" + integrity sha512-PnIUicutm3vGtsWMBPXvn24msFhfcxQc7iR+UOVK+h1pYVTkBwOOGvNMtPjrayfDIr+66eLtKBrQrAJpUDHF/A== + dependencies: + "@ethersproject/abi" "^5.5.0" + "@ethersproject/rlp" "^5.5.0" + "@ledgerhq/cryptoassets" "^12.1.0" + "@ledgerhq/domain-service" "^1.1.20" + "@ledgerhq/errors" "^6.16.4" + "@ledgerhq/evm-tools" "^1.0.18" + "@ledgerhq/hw-transport" "^6.30.6" + "@ledgerhq/hw-transport-mocker" "^6.28.6" + "@ledgerhq/logs" "^6.12.0" + "@ledgerhq/types-live" "^6.46.0" + axios "^1.3.4" + bignumber.js "^9.1.2" + +"@ledgerhq/hw-app-solana@^7.1.6": + version "7.1.6" + resolved "https://registry.yarnpkg.com/@ledgerhq/hw-app-solana/-/hw-app-solana-7.1.6.tgz#ebb898a0844bd1810822e9d82eadbbb315504f1c" + integrity sha512-kblNUUZMbujq0AG+6z2Pf5cgp31iE5ybTNAzBBJrpxAj0+wLsM1Cj7OizbNHHU86Lwq1CtxDqCiWEBhrvg9t0w== + dependencies: + "@ledgerhq/errors" "^6.16.4" + "@ledgerhq/hw-transport" "^6.30.6" + bip32-path "^0.4.2" + +"@ledgerhq/hw-transport-mocker@^6.28.6": + version "6.28.6" + resolved "https://registry.yarnpkg.com/@ledgerhq/hw-transport-mocker/-/hw-transport-mocker-6.28.6.tgz#820ff1abe490a1abbf3925f53526f846ee0f470d" + integrity sha512-JDO2kqMOTRCQWNZr1KVlyX1AqE6WBzHjJDS3FnSI8Z/Bj2KSc2/1H/4lW6+Ap64yLtlmOW3GchdafFmLgYAgqw== + dependencies: + "@ledgerhq/hw-transport" "^6.30.6" + "@ledgerhq/logs" "^6.12.0" + rxjs "^7.8.1" + +"@ledgerhq/hw-transport-webhid@^6.28.6": + version "6.28.6" + resolved "https://registry.yarnpkg.com/@ledgerhq/hw-transport-webhid/-/hw-transport-webhid-6.28.6.tgz#94562750136d869774cb56304573a1875ca6375f" + integrity sha512-npU1mgL97KovpTUgcdORoOZ7eVFgwCA7zt0MpgUGUMRNJWDgCFsJslx7KrVXlCGOg87gLfDojreIre502I5pYg== + dependencies: + "@ledgerhq/devices" "^8.3.0" + "@ledgerhq/errors" "^6.16.4" + "@ledgerhq/hw-transport" "^6.30.6" + "@ledgerhq/logs" "^6.12.0" + +"@ledgerhq/hw-transport@^6.30.6": + version "6.30.6" + resolved "https://registry.yarnpkg.com/@ledgerhq/hw-transport/-/hw-transport-6.30.6.tgz#c6d84672ac4828f311831998f4101ea205215a6d" + integrity sha512-fT0Z4IywiuJuZrZE/+W0blkV5UCotDPFTYKLkKCLzYzuE6javva7D/ajRaIeR+hZ4kTmKF4EqnsmDCXwElez+w== + dependencies: + "@ledgerhq/devices" "^8.3.0" + "@ledgerhq/errors" "^6.16.4" + "@ledgerhq/logs" "^6.12.0" events "^3.3.0" -"@ledgerhq/logs@^5.30.0", "@ledgerhq/logs@^5.50.0": - version "5.50.0" - resolved "https://registry.yarnpkg.com/@ledgerhq/logs/-/logs-5.50.0.tgz#29c6419e8379d496ab6d0426eadf3c4d100cd186" - integrity sha512-swKHYCOZUGyVt4ge0u8a7AwNcA//h4nx5wIi0sruGye1IJ5Cva0GyK9L2/WdX+kWVTKp92ZiEo1df31lrWGPgA== +"@ledgerhq/live-env@^2.0.1": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@ledgerhq/live-env/-/live-env-2.0.1.tgz#371a3e72f38c75c0d0a6aba3dbeaa52cbd163c64" + integrity sha512-fs13laLOvREtWb40JhNX9ImFPvPU/+pKhzs51UFXDMujCtk5VCA8s8bKCA4YJ6rD5Ebpg7aJRc423lMxPyVR2A== + dependencies: + rxjs "^7.8.1" + utility-types "^3.10.0" + +"@ledgerhq/logs@^6.12.0": + version "6.12.0" + resolved "https://registry.yarnpkg.com/@ledgerhq/logs/-/logs-6.12.0.tgz#ad903528bf3687a44da435d7b2479d724d374f5d" + integrity sha512-ExDoj1QV5eC6TEbMdLUMMk9cfvNKhhv5gXol4SmULRVCx/3iyCPhJ74nsb3S0Vb+/f+XujBEj3vQn5+cwS0fNA== -"@lezer/common@^0.15.0", "@lezer/common@^0.15.7": - version "0.15.12" - resolved "https://registry.yarnpkg.com/@lezer/common/-/common-0.15.12.tgz#2f21aec551dd5fd7d24eb069f90f54d5bc6ee5e9" - integrity sha512-edfwCxNLnzq5pBA/yaIhwJ3U3Kz8VAUOTRg0hhxaizaI1N+qxV7EXDv/kLCkLeq2RzSFvxexlaj5Mzfn2kY0Ig== +"@ledgerhq/types-cryptoassets@^7.11.0": + version "7.14.0" + resolved "https://registry.yarnpkg.com/@ledgerhq/types-cryptoassets/-/types-cryptoassets-7.14.0.tgz#1114599ba524c78655744c587b13be93cf65ec96" + integrity sha512-lndedmKIoaVOzQO+pGUNKKRCKWD7sdIxOdXz0drVGEBKMUSQKGOX8fhM4lta/qps4yBDjIwSzXAXVBMo+qFaeg== -"@lezer/lr@^0.15.4": - version "0.15.8" - resolved "https://registry.yarnpkg.com/@lezer/lr/-/lr-0.15.8.tgz#1564a911e62b0a0f75ca63794a6aa8c5dc63db21" - integrity sha512-bM6oE6VQZ6hIFxDNKk8bKPa14hqFrV07J/vHGOeiAbJReIaQXmkVb6xQu4MR+JBTLa5arGRyAAjJe1qaQt3Uvg== +"@ledgerhq/types-devices@^6.24.0": + version "6.25.2" + resolved "https://registry.yarnpkg.com/@ledgerhq/types-devices/-/types-devices-6.25.2.tgz#12379d3638b40cd0655c63d657451bf5aec140fe" + integrity sha512-MW7sA8bkBU7JR9hKaPVelQMqNlC5/Z4CJ/rqkWowy0FYJpAoYeXHahtRXC8bI8t5/GkcVvu/dwDU1J64OpwJ6A== + +"@ledgerhq/types-live@^6.46.0": + version "6.46.0" + resolved "https://registry.yarnpkg.com/@ledgerhq/types-live/-/types-live-6.46.0.tgz#85e4c0b59b9e177bc279739a0ab419e24c064785" + integrity sha512-UtI4qm13wJIv9FB/0g6Hi1NijU7PuJEGetqGQxELlKEOmjubXa52EfKVA9IVOngL25m6U8i7jzluwLsHiN2uQQ== dependencies: - "@lezer/common" "^0.15.0" + bignumber.js "^9.1.2" + rxjs "^7.8.1" -"@lmdb/lmdb-darwin-arm64@2.5.2": - version "2.5.2" - resolved "https://registry.yarnpkg.com/@lmdb/lmdb-darwin-arm64/-/lmdb-darwin-arm64-2.5.2.tgz#bc66fa43286b5c082e8fee0eacc17995806b6fbe" - integrity sha512-+F8ioQIUN68B4UFiIBYu0QQvgb9FmlKw2ctQMSBfW2QBrZIxz9vD9jCGqTCPqZBRbPHAS/vG1zSXnKqnS2ch/A== +"@lezer/common@^1.0.0": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@lezer/common/-/common-1.1.1.tgz#4a06a0e1b9214d7eb2ea4a9354d47a63044cee49" + integrity sha512-aAPB9YbvZHqAW+bIwiuuTDGB4DG0sYNRObGLxud8cW7osw1ZQxfDuTZ8KQiqfZ0QJGcR34CvpTMDXEyo/+Htgg== -"@lmdb/lmdb-darwin-x64@2.5.2": - version "2.5.2" - resolved "https://registry.yarnpkg.com/@lmdb/lmdb-darwin-x64/-/lmdb-darwin-x64-2.5.2.tgz#89d8390041bce6bab24a82a20392be22faf54ffc" - integrity sha512-KvPH56KRLLx4KSfKBx0m1r7GGGUMXm0jrKmNE7plbHlesZMuPJICtn07HYgQhj1LNsK7Yqwuvnqh1QxhJnF1EA== +"@lezer/lr@^1.0.0": + version "1.3.14" + resolved "https://registry.yarnpkg.com/@lezer/lr/-/lr-1.3.14.tgz#59d4a3b25698bdac0ef182fa6eadab445fc4f29a" + integrity sha512-z5mY4LStlA3yL7aHT/rqgG614cfcvklS+8oFRFBYrs4YaWLJyKKM4+nN6KopToX0o9Hj6zmH6M5kinOYuy06ug== + dependencies: + "@lezer/common" "^1.0.0" -"@lmdb/lmdb-linux-arm64@2.5.2": - version "2.5.2" - resolved "https://registry.yarnpkg.com/@lmdb/lmdb-linux-arm64/-/lmdb-linux-arm64-2.5.2.tgz#14fe4c96c2bb1285f93797f45915fa35ee047268" - integrity sha512-aLl89VHL/wjhievEOlPocoefUyWdvzVrcQ/MHQYZm2JfV1jUsrbr/ZfkPPUFvZBf+VSE+Q0clWs9l29PCX1hTQ== +"@lingui/babel-plugin-extract-messages@4.5.0": + version "4.5.0" + resolved "https://registry.yarnpkg.com/@lingui/babel-plugin-extract-messages/-/babel-plugin-extract-messages-4.5.0.tgz#71e56cc2eae73890caeea15a00ae4965413430ec" + integrity sha512-jZq3Gbi691jsHyQ4+OPnGgIqZt5eKEGnmI75akYlZpwTPxF7n+hiuKlQS+YB3xfKvcvlAED76ZAMCcwYG5fNrQ== -"@lmdb/lmdb-linux-arm@2.5.2": - version "2.5.2" - resolved "https://registry.yarnpkg.com/@lmdb/lmdb-linux-arm/-/lmdb-linux-arm-2.5.2.tgz#05bde4573ab10cf21827339fe687148f2590cfa1" - integrity sha512-5kQAP21hAkfW5Bl+e0P57dV4dGYnkNIpR7f/GAh6QHlgXx+vp/teVj4PGRZaKAvt0GX6++N6hF8NnGElLDuIDw== +"@lingui/cli@^4.2.1": + version "4.5.0" + resolved "https://registry.yarnpkg.com/@lingui/cli/-/cli-4.5.0.tgz#fb8685cb682cf624b6e5b6d1207f8127b98ed95a" + integrity sha512-MzhxNUNd+YYEmK79TwmneUow5BuLwpOlrUrZq9EyIAWUM4N6kkCVkZ8VIMYCL4TXGQ4kBQjstgDpkF8wdFRtNg== + dependencies: + "@babel/core" "^7.21.0" + "@babel/generator" "^7.21.1" + "@babel/parser" "^7.21.2" + "@babel/runtime" "^7.21.0" + "@babel/types" "^7.21.2" + "@lingui/babel-plugin-extract-messages" "4.5.0" + "@lingui/conf" "4.5.0" + "@lingui/core" "4.5.0" + "@lingui/format-po" "4.5.0" + "@lingui/message-utils" "4.5.0" + babel-plugin-macros "^3.0.1" + chalk "^4.1.0" + chokidar "3.5.1" + cli-table "0.3.6" + commander "^10.0.0" + convert-source-map "^2.0.0" + date-fns "^2.16.1" + esbuild "^0.17.10" + glob "^7.1.4" + inquirer "^7.3.3" + micromatch "4.0.2" + normalize-path "^3.0.0" + ora "^5.1.0" + pathe "^1.1.0" + pkg-up "^3.1.0" + pofile "^1.1.4" + pseudolocale "^2.0.0" + ramda "^0.27.1" + source-map "^0.8.0-beta.0" -"@lmdb/lmdb-linux-x64@2.5.2": - version "2.5.2" - resolved "https://registry.yarnpkg.com/@lmdb/lmdb-linux-x64/-/lmdb-linux-x64-2.5.2.tgz#d2f85afd857d2c33d2caa5b057944574edafcfee" - integrity sha512-xUdUfwDJLGjOUPH3BuPBt0NlIrR7f/QHKgu3GZIXswMMIihAekj2i97oI0iWG5Bok/b+OBjHPfa8IU9velnP/Q== +"@lingui/conf@4.5.0": + version "4.5.0" + resolved "https://registry.yarnpkg.com/@lingui/conf/-/conf-4.5.0.tgz#09b39de3a03a9017cd8299b1d8df923c78447ebf" + integrity sha512-OBm4RQQtbpvmuazLWVpvpaOpt/xvu1PBv8WUX8QoW1vsROe/3P5BpRHRYFyMeZz5mhORJgis9lQtDTq145Ruug== + dependencies: + "@babel/runtime" "^7.20.13" + chalk "^4.1.0" + cosmiconfig "^8.0.0" + jest-validate "^29.4.3" + jiti "^1.17.1" + lodash.get "^4.4.2" -"@lmdb/lmdb-win32-x64@2.5.2": - version "2.5.2" - resolved "https://registry.yarnpkg.com/@lmdb/lmdb-win32-x64/-/lmdb-win32-x64-2.5.2.tgz#28f643fbc0bec30b07fbe95b137879b6b4d1c9c5" - integrity sha512-zrBczSbXKxEyK2ijtbRdICDygRqWSRPpZMN5dD1T8VMEW5RIhIbwFWw2phDRXuBQdVDpSjalCIUMWMV2h3JaZA== +"@lingui/core@4.2.1": + version "4.2.1" + resolved "https://registry.yarnpkg.com/@lingui/core/-/core-4.2.1.tgz#60026b68143b76a25ae1de129c76e6ecb98b037e" + integrity sha512-928PI3fftk/owl1ZPqcK60DgUUktGW5RrMZJdNSxMBpmGtUqOQuj/WW7w69sUFefqsOGOpUY6lR75dwhgqywEA== + dependencies: + "@babel/runtime" "^7.20.13" + "@lingui/message-utils" "4.2.1" + unraw "^2.0.1" -"@mapbox/node-pre-gyp@^1.0.5": - version "1.0.10" - resolved "https://registry.yarnpkg.com/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.10.tgz#8e6735ccebbb1581e5a7e652244cadc8a844d03c" - integrity sha512-4ySo4CjzStuprMwk35H5pPbkymjv1SF3jGLj6rAHp/xT/RF7TL7bd9CTm1xDY49K2qF7jmR/g7k+SkLETP6opA== +"@lingui/core@4.5.0": + version "4.5.0" + resolved "https://registry.yarnpkg.com/@lingui/core/-/core-4.5.0.tgz#8b907238bd0b420b372272d0a757c56bed3aed14" + integrity sha512-8zTuIXJo5Qvjato7LWE6Q4RHiO4LjTBVOoRlqfOGYDp8VZ9w9P7Z7IJgxI7UP5Z1wiuEvnMdVF9I1C4acqXGlQ== dependencies: - detect-libc "^2.0.0" - https-proxy-agent "^5.0.0" - make-dir "^3.1.0" - node-fetch "^2.6.7" - nopt "^5.0.0" - npmlog "^5.0.1" - rimraf "^3.0.2" - semver "^7.3.5" - tar "^6.1.11" - -"@mdx-js/mdx@^1.6.22": - version "1.6.22" - resolved "https://registry.yarnpkg.com/@mdx-js/mdx/-/mdx-1.6.22.tgz#8a723157bf90e78f17dc0f27995398e6c731f1ba" - integrity sha512-AMxuLxPz2j5/6TpF/XSdKpQP1NlG0z11dFOlq+2IP/lSgl11GY8ji6S/rgsViN/L0BDvHvUMruRb7ub+24LUYA== - dependencies: - "@babel/core" "7.12.9" - "@babel/plugin-syntax-jsx" "7.12.1" - "@babel/plugin-syntax-object-rest-spread" "7.8.3" - "@mdx-js/util" "1.6.22" - babel-plugin-apply-mdx-type-prop "1.6.22" - babel-plugin-extract-import-names "1.6.22" - camelcase-css "2.0.1" - detab "2.0.4" - hast-util-raw "6.0.1" - lodash.uniq "4.5.0" - mdast-util-to-hast "10.0.1" - remark-footnotes "2.0.0" - remark-mdx "1.6.22" - remark-parse "8.0.3" - remark-squeeze-paragraphs "4.0.0" - style-to-object "0.3.0" - unified "9.2.0" - unist-builder "2.0.3" - unist-util-visit "2.0.3" - -"@mdx-js/react@^1.6.22": - version "1.6.22" - resolved "https://registry.yarnpkg.com/@mdx-js/react/-/react-1.6.22.tgz#ae09b4744fddc74714ee9f9d6f17a66e77c43573" - integrity sha512-TDoPum4SHdfPiGSAaRBw7ECyI8VaHpK8GJugbJIJuqyh6kzw9ZLJZW3HGL3NNrJGxcAixUvqROm+YuQOo5eXtg== - -"@mdx-js/util@1.6.22": - version "1.6.22" - resolved "https://registry.yarnpkg.com/@mdx-js/util/-/util-1.6.22.tgz#219dfd89ae5b97a8801f015323ffa4b62f45718b" - integrity sha512-H1rQc1ZOHANWBvPcW+JpGwr+juXSxM8Q8YCkm3GhZd8REu1fHR3z99CErO1p9pkcfcxZnMdIZdIsXkOHY0NilA== + "@babel/runtime" "^7.20.13" + "@lingui/message-utils" "4.5.0" + unraw "^3.0.0" + +"@lingui/format-po@4.5.0": + version "4.5.0" + resolved "https://registry.yarnpkg.com/@lingui/format-po/-/format-po-4.5.0.tgz#88dabeaa565ce5e4ff2a1b9865da7759b393af27" + integrity sha512-xQNzZ4RCQfh6TjzjUsyHz3B0R9FJuzhBit9R37NyMn6mL3kBTCUExpPczknm8gWZjtfFO4T8EH5eJhhC5vgJYg== + dependencies: + "@lingui/conf" "4.5.0" + "@lingui/message-utils" "4.5.0" + date-fns "^2.29.3" + pofile "^1.1.4" + +"@lingui/message-utils@4.2.1": + version "4.2.1" + resolved "https://registry.yarnpkg.com/@lingui/message-utils/-/message-utils-4.2.1.tgz#586eb273359ada8c5e9e8816db28913b6218158e" + integrity sha512-131v+j82uS10gBDyjOBdKmQKKO1dc0nYx3MSUu9RK+EnPItRcaME3LBaJ4UJs5Nb1niZOX2yeMKarGAkvwFyPA== + dependencies: + "@messageformat/parser" "^5.0.0" + +"@lingui/message-utils@4.5.0": + version "4.5.0" + resolved "https://registry.yarnpkg.com/@lingui/message-utils/-/message-utils-4.5.0.tgz#7ae9dc6cb65cbb5e2dc1b8cdcc4c8b92d5c7189f" + integrity sha512-iRqh2wvNtzJO3NStB77nEXEfeI53aVVjzD7/mBrEm/P0lC7sqPHk0WBQCfzE0N9xm6a+XHmHu3J+x2nnQ2OjcA== + dependencies: + "@messageformat/parser" "^5.0.0" + +"@lingui/react@4.2.1": + version "4.2.1" + resolved "https://registry.yarnpkg.com/@lingui/react/-/react-4.2.1.tgz#33b6919dfa0330a7bccbd6e385473ff7964670f5" + integrity sha512-6VRKGFzQgEAxChLE5B7Pih7ZqAKS5PWzJtIP6O6amX6uVRxEJBIB/J4BtRNpt25Dz8WXf3C+9sSxskRNWtsZXQ== + dependencies: + "@babel/runtime" "^7.20.13" + "@lingui/core" "4.2.1" + +"@lit-labs/ssr-dom-shim@^1.0.0", "@lit-labs/ssr-dom-shim@^1.1.0": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@lit-labs/ssr-dom-shim/-/ssr-dom-shim-1.1.2.tgz#d693d972974a354034454ec1317eb6afd0b00312" + integrity sha512-jnOD+/+dSrfTWYfSXBXlo5l5f0q1UuJo3tkbMDCYA2lKUYq79jaxqtGEvnRoh049nt1vdo1+45RinipU6FGY2g== + +"@lit/reactive-element@^1.3.0", "@lit/reactive-element@^1.6.0": + version "1.6.3" + resolved "https://registry.yarnpkg.com/@lit/reactive-element/-/reactive-element-1.6.3.tgz#25b4eece2592132845d303e091bad9b04cdcfe03" + integrity sha512-QuTgnG52Poic7uM1AN5yJ09QMe0O28e10XzSvWDz02TJiiKee4stsiownEIadWm8nYzyDAyT+gKzUoZmiWQtsQ== + dependencies: + "@lit-labs/ssr-dom-shim" "^1.0.0" + +"@lmdb/lmdb-darwin-arm64@2.8.5": + version "2.8.5" + resolved "https://registry.yarnpkg.com/@lmdb/lmdb-darwin-arm64/-/lmdb-darwin-arm64-2.8.5.tgz#895d8cb16a9d709ce5fedd8b60022903b875e08e" + integrity sha512-KPDeVScZgA1oq0CiPBcOa3kHIqU+pTOwRFDIhxvmf8CTNvqdZQYp5cCKW0bUk69VygB2PuTiINFWbY78aR2pQw== + +"@lmdb/lmdb-darwin-x64@2.8.5": + version "2.8.5" + resolved "https://registry.yarnpkg.com/@lmdb/lmdb-darwin-x64/-/lmdb-darwin-x64-2.8.5.tgz#ca243534c8b37d5516c557e4624256d18dd63184" + integrity sha512-w/sLhN4T7MW1nB3R/U8WK5BgQLz904wh+/SmA2jD8NnF7BLLoUgflCNxOeSPOWp8geP6nP/+VjWzZVip7rZ1ug== + +"@lmdb/lmdb-linux-arm64@2.8.5": + version "2.8.5" + resolved "https://registry.yarnpkg.com/@lmdb/lmdb-linux-arm64/-/lmdb-linux-arm64-2.8.5.tgz#b44a8023057e21512eefb9f6120096843b531c1e" + integrity sha512-vtbZRHH5UDlL01TT5jB576Zox3+hdyogvpcbvVJlmU5PdL3c5V7cj1EODdh1CHPksRl+cws/58ugEHi8bcj4Ww== + +"@lmdb/lmdb-linux-arm@2.8.5": + version "2.8.5" + resolved "https://registry.yarnpkg.com/@lmdb/lmdb-linux-arm/-/lmdb-linux-arm-2.8.5.tgz#17bd54740779c3e4324e78e8f747c21416a84b3d" + integrity sha512-c0TGMbm2M55pwTDIfkDLB6BpIsgxV4PjYck2HiOX+cy/JWiBXz32lYbarPqejKs9Flm7YVAKSILUducU9g2RVg== + +"@lmdb/lmdb-linux-x64@2.8.5": + version "2.8.5" + resolved "https://registry.yarnpkg.com/@lmdb/lmdb-linux-x64/-/lmdb-linux-x64-2.8.5.tgz#6c61835b6cc58efdf79dbd5e8c72a38300a90302" + integrity sha512-Xkc8IUx9aEhP0zvgeKy7IQ3ReX2N8N1L0WPcQwnZweWmOuKfwpS3GRIYqLtK5za/w3E60zhFfNdS+3pBZPytqQ== + +"@lmdb/lmdb-win32-x64@2.8.5": + version "2.8.5" + resolved "https://registry.yarnpkg.com/@lmdb/lmdb-win32-x64/-/lmdb-win32-x64-2.8.5.tgz#8233e8762440b0f4632c47a09b1b6f23de8b934c" + integrity sha512-4wvrf5BgnR8RpogHhtpCPJMKBmvyZPhhUtEwMJbXh0ni2BucpfF07jlmyM11zRqQ2XIq6PbC2j7W7UCCcm1rRQ== + +"@mdx-js/react@^3.0.0": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@mdx-js/react/-/react-3.0.1.tgz#997a19b3a5b783d936c75ae7c47cfe62f967f746" + integrity sha512-9ZrPIU4MGf6et1m1ov3zKf+q9+deetI51zprKB1D/z3NOb+rUxxtEl3mCjW5wTGh6VhRdwPueh1oRzi6ezkA8A== + dependencies: + "@types/mdx" "^2.0.0" + +"@messageformat/parser@^5.0.0": + version "5.1.0" + resolved "https://registry.yarnpkg.com/@messageformat/parser/-/parser-5.1.0.tgz#05e4851c782d633ad735791dd0a68ee65d2a7201" + integrity sha512-jKlkls3Gewgw6qMjKZ9SFfHUpdzEVdovKFtW1qRhJ3WI4FW5R/NnGDqr8SDGz+krWDO3ki94boMmQvGke1HwUQ== + dependencies: + moo "^0.5.1" "@mischnic/json-sourcemap@^0.1.0": - version "0.1.0" - resolved "https://registry.yarnpkg.com/@mischnic/json-sourcemap/-/json-sourcemap-0.1.0.tgz#38af657be4108140a548638267d02a2ea3336507" - integrity sha512-dQb3QnfNqmQNYA4nFSN/uLaByIic58gOXq4Y4XqLOWmOrw73KmJPt/HLyG0wvn1bnR6mBKs/Uwvkh+Hns1T0XA== + version "0.1.1" + resolved "https://registry.yarnpkg.com/@mischnic/json-sourcemap/-/json-sourcemap-0.1.1.tgz#0ef9b015a8f575dd9a8720d9a6b4dbc988425906" + integrity sha512-iA7+tyVqfrATAIsIRWQG+a7ZLLD0VaOCKV2Wd/v4mqIU3J9c4jx9p7S0nw1XH3gJCKNBOOwACOPYYSUu9pgT+w== dependencies: - "@lezer/common" "^0.15.7" - "@lezer/lr" "^0.15.4" + "@lezer/common" "^1.0.0" + "@lezer/lr" "^1.0.0" json5 "^2.2.1" -"@mrmlnc/readdir-enhanced@^2.2.1": - version "2.2.1" - resolved "https://registry.yarnpkg.com/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz#524af240d1a360527b730475ecfa1344aa540dde" - integrity sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g== - dependencies: - call-me-maybe "^1.0.1" - glob-to-regexp "^0.3.0" +"@mobily/ts-belt@^3.13.1": + version "3.13.1" + resolved "https://registry.yarnpkg.com/@mobily/ts-belt/-/ts-belt-3.13.1.tgz#8f8ce2a2eca41d88c2ca70c84d0f47d0f7f5cd5f" + integrity sha512-K5KqIhPI/EoCTbA6CGbrenM9s41OouyK8A03fGJJcla/zKucsgLbz8HNbeseoLarRPgyWJsUyCYqFhI7t3Ra9Q== + +"@motionone/animation@^10.15.1", "@motionone/animation@^10.16.3": + version "10.16.3" + resolved "https://registry.yarnpkg.com/@motionone/animation/-/animation-10.16.3.tgz#f5b71e27fd8b88b61f983adb0ed6c8e3e89281f9" + integrity sha512-QUGWpLbMFLhyqKlngjZhjtxM8IqiJQjLK0DF+XOF6od9nhSvlaeEpOY/UMCRVcZn/9Tr2rZO22EkuCIjYdI74g== + dependencies: + "@motionone/easing" "^10.16.3" + "@motionone/types" "^10.16.3" + "@motionone/utils" "^10.16.3" + tslib "^2.3.1" + +"@motionone/dom@^10.16.2", "@motionone/dom@^10.16.4": + version "10.16.4" + resolved "https://registry.yarnpkg.com/@motionone/dom/-/dom-10.16.4.tgz#9385716928cc2d5b3208a7dcaf504b69b47fd1ae" + integrity sha512-HPHlVo/030qpRj9R8fgY50KTN4Ko30moWRTA3L3imrsRBmob93cTYmodln49HYFbQm01lFF7X523OkKY0DX6UA== + dependencies: + "@motionone/animation" "^10.16.3" + "@motionone/generators" "^10.16.4" + "@motionone/types" "^10.16.3" + "@motionone/utils" "^10.16.3" + hey-listen "^1.0.8" + tslib "^2.3.1" + +"@motionone/easing@^10.16.3": + version "10.16.3" + resolved "https://registry.yarnpkg.com/@motionone/easing/-/easing-10.16.3.tgz#a62abe0ba2841861f167f286782e287eab8d7466" + integrity sha512-HWTMZbTmZojzwEuKT/xCdvoMPXjYSyQvuVM6jmM0yoGU6BWzsmYMeB4bn38UFf618fJCNtP9XeC/zxtKWfbr0w== + dependencies: + "@motionone/utils" "^10.16.3" + tslib "^2.3.1" + +"@motionone/generators@^10.16.4": + version "10.16.4" + resolved "https://registry.yarnpkg.com/@motionone/generators/-/generators-10.16.4.tgz#4a38708244bce733bfcebd4a26d19f4bbabd36af" + integrity sha512-geFZ3w0Rm0ZXXpctWsSf3REGywmLLujEjxPYpBR0j+ymYwof0xbV6S5kGqqsDKgyWKVWpUInqQYvQfL6fRbXeg== + dependencies: + "@motionone/types" "^10.16.3" + "@motionone/utils" "^10.16.3" + tslib "^2.3.1" + +"@motionone/svelte@^10.16.2": + version "10.16.4" + resolved "https://registry.yarnpkg.com/@motionone/svelte/-/svelte-10.16.4.tgz#5daf117cf5b2576fc6dd487c5e0500938a742470" + integrity sha512-zRVqk20lD1xqe+yEDZhMYgftsuHc25+9JSo+r0a0OWUJFocjSV9D/+UGhX4xgJsuwB9acPzXLr20w40VnY2PQA== + dependencies: + "@motionone/dom" "^10.16.4" + tslib "^2.3.1" + +"@motionone/types@^10.15.1", "@motionone/types@^10.16.3": + version "10.16.3" + resolved "https://registry.yarnpkg.com/@motionone/types/-/types-10.16.3.tgz#9284ea8a52f6b32c51c54b617214f20e43ac6c59" + integrity sha512-W4jkEGFifDq73DlaZs3HUfamV2t1wM35zN/zX7Q79LfZ2sc6C0R1baUHZmqc/K5F3vSw3PavgQ6HyHLd/MXcWg== + +"@motionone/utils@^10.15.1", "@motionone/utils@^10.16.3": + version "10.16.3" + resolved "https://registry.yarnpkg.com/@motionone/utils/-/utils-10.16.3.tgz#ddf07ab6cf3000d89e3bcbdc9a8c3e1fd64f8520" + integrity sha512-WNWDksJIxQkaI9p9Z9z0+K27xdqISGNFy1SsWVGaiedTHq0iaT6iZujby8fT/ZnZxj1EOaxJtSfUPCFNU5CRoA== + dependencies: + "@motionone/types" "^10.16.3" + hey-listen "^1.0.8" + tslib "^2.3.1" + +"@motionone/vue@^10.16.2": + version "10.16.4" + resolved "https://registry.yarnpkg.com/@motionone/vue/-/vue-10.16.4.tgz#07d09e3aa5115ca0bcc0076cb9e5322775277c09" + integrity sha512-z10PF9JV6SbjFq+/rYabM+8CVlMokgl8RFGvieSGNTmrkQanfHn+15XBrhG3BgUfvmTeSeyShfOHpG0i9zEdcg== + dependencies: + "@motionone/dom" "^10.16.4" + tslib "^2.3.1" "@msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.2": version "3.0.2" @@ -2951,20 +4322,43 @@ resolved "https://registry.yarnpkg.com/@msgpackr-extract/msgpackr-extract-win32-x64/-/msgpackr-extract-win32-x64-3.0.2.tgz#0f164b726869f71da3c594171df5ebc1c4b0a407" integrity sha512-O+6Gs8UeDbyFpbSh2CPEz/UOrrdWPTBYNblZK5CxxLisYt4kGX3Sc+czffFonyjiGSq3jWLwJS/CCJc7tBr4sQ== -"@noble/ed25519@^1.7.0": - version "1.7.3" - resolved "https://registry.yarnpkg.com/@noble/ed25519/-/ed25519-1.7.3.tgz#57e1677bf6885354b466c38e2b620c62f45a7123" - integrity sha512-iR8GBkDt0Q3GyaVcIu7mSsVIqnFbkbRzGLWlvhwunacoLwt4J3swfKhfaM6rN6WY+TBGoYT1GtT1mIh2/jGbRQ== +"@ndelangen/get-tarball@^3.0.7": + version "3.0.9" + resolved "https://registry.yarnpkg.com/@ndelangen/get-tarball/-/get-tarball-3.0.9.tgz#727ff4454e65f34707e742a59e5e6b1f525d8964" + integrity sha512-9JKTEik4vq+yGosHYhZ1tiH/3WpUS0Nh0kej4Agndhox8pAdWhEx5knFVRcb/ya9knCRCs1rPxNrSXTDdfVqpA== + dependencies: + gunzip-maybe "^1.4.2" + pump "^3.0.0" + tar-fs "^2.1.1" -"@noble/hashes@^1", "@noble/hashes@^1.0.0", "@noble/hashes@^1.1.2", "@noble/hashes@^1.2.0": - version "1.3.0" - resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.0.tgz#085fd70f6d7d9d109671090ccae1d3bec62554a1" - integrity sha512-ilHEACi9DwqJB0pw7kv+Apvh50jiiSyR/cQ3y4W7lOR5mhvn/50FLUfsnfJz0BDZtl/RR16kXvptiv6q1msYZg== +"@noble/curves@1.2.0", "@noble/curves@^1.2.0", "@noble/curves@~1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.2.0.tgz#92d7e12e4e49b23105a2555c6984d41733d65c35" + integrity sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw== + dependencies: + "@noble/hashes" "1.3.2" + +"@noble/curves@1.4.0", "@noble/curves@^1.4.0", "@noble/curves@~1.4.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.4.0.tgz#f05771ef64da724997f69ee1261b2417a49522d6" + integrity sha512-p+4cb332SFCrReJkCYe8Xzm0OWi4Jji5jVdIZRL/PmacmDkFNw6MrrV+gGpiPxLHbV+zKFRywUWbaseT+tZRXg== + dependencies: + "@noble/hashes" "1.4.0" + +"@noble/hashes@1.3.2", "@noble/hashes@^1", "@noble/hashes@^1.0.0", "@noble/hashes@^1.2.0", "@noble/hashes@~1.3.0", "@noble/hashes@~1.3.2": + version "1.3.2" + resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.2.tgz#6f26dbc8fbc7205873ce3cee2f690eba0d421b39" + integrity sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ== + +"@noble/hashes@1.4.0", "@noble/hashes@^1.3.3", "@noble/hashes@^1.4.0", "@noble/hashes@~1.4.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.4.0.tgz#45814aa329f30e4fe0ba49426f49dfccdd066426" + integrity sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg== -"@noble/secp256k1@^1.6.3": - version "1.7.1" - resolved "https://registry.yarnpkg.com/@noble/secp256k1/-/secp256k1-1.7.1.tgz#b251c70f824ce3ca7f8dc3df08d58f005cc0507c" - integrity sha512-hOUk6AyBFmqVrv7k5WAw/LpszxVbj9gGN4JRkIX52fdFAj1UA61KXmZDvqVEm+pOyec3+fIeZB02LYa/pWOArw== +"@noble/hashes@~1.5.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.5.0.tgz#abadc5ca20332db2b1b2aa3e496e9af1213570b0" + integrity sha512-1j6kQFb7QRru7eKN3ZDvRcP13rugwdxZqCjbiAVZfIJwgj2A65UmT4TgARXGlXgnRkORLTDTrO19ZErt7+QXgA== "@nodelib/fs.scandir@2.1.5": version "2.1.5" @@ -2979,12 +4373,7 @@ resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== -"@nodelib/fs.stat@^1.1.2": - version "1.1.3" - resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz#2b5a3ab3f918cca48a8c754c08168e3f03eba61b" - integrity sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw== - -"@nodelib/fs.walk@^1.2.3": +"@nodelib/fs.walk@^1.2.3", "@nodelib/fs.walk@^1.2.8": version "1.2.8" resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== @@ -2992,105 +4381,89 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" -"@npmcli/fs@^1.0.0": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@npmcli/fs/-/fs-1.1.1.tgz#72f719fe935e687c56a4faecf3c03d06ba593257" - integrity sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ== - dependencies: - "@gar/promisify" "^1.0.1" - semver "^7.3.5" - -"@npmcli/move-file@^1.0.1": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@npmcli/move-file/-/move-file-1.1.2.tgz#1a82c3e372f7cae9253eb66d72543d6b8685c674" - integrity sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg== - dependencies: - mkdirp "^1.0.4" - rimraf "^3.0.2" - -"@npmcli/package-json@^2.0.0": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@npmcli/package-json/-/package-json-2.0.0.tgz#3bbcf4677e21055adbe673d9f08c9f9cde942e4a" - integrity sha512-42jnZ6yl16GzjWSH7vtrmWyJDGVa/LXPdpN2rcUWolFjc9ON2N3uz0qdBbQACfmhuJZ2lbKYtmK5qx68ZPLHMA== - dependencies: - json-parse-even-better-errors "^2.3.1" - -"@nrwl/cli@15.9.2": - version "15.9.2" - resolved "https://registry.yarnpkg.com/@nrwl/cli/-/cli-15.9.2.tgz#82537d3d85410b0143d37a3b4fade09675356084" - integrity sha512-QoCmyrcGakHAYTJaNBbOerRQAmqJHMYGCdqtQidV+aP9p1Dy33XxDELfhd+IYmGqngutXuEWChNpWNhPloLnoA== +"@nrwl/cli@15.9.7": + version "15.9.7" + resolved "https://registry.yarnpkg.com/@nrwl/cli/-/cli-15.9.7.tgz#1db113f5cb1cfe63213097be1ece041eef33da1f" + integrity sha512-1jtHBDuJzA57My5nLzYiM372mJW0NY6rFKxlWt5a0RLsAZdPTHsd8lE3Gs9XinGC1jhXbruWmhhnKyYtZvX/zA== dependencies: - nx "15.9.2" + nx "15.9.7" -"@nrwl/devkit@15.9.2": - version "15.9.2" - resolved "https://registry.yarnpkg.com/@nrwl/devkit/-/devkit-15.9.2.tgz#482b89f1bf88d3600b11f8b7e3e4452c5766eca4" - integrity sha512-2DvTstVZb91m+d4wqUJMBHQ3elxyabdmFE6/3aXmtOGeDxTyXyDzf/1O6JvBBiL8K6XC3ZYchjtxUHgxl/NJ5A== +"@nrwl/devkit@15.9.7": + version "15.9.7" + resolved "https://registry.yarnpkg.com/@nrwl/devkit/-/devkit-15.9.7.tgz#14d19ec82ff4209c12147a97f1cdea05d8f6c087" + integrity sha512-Sb7Am2TMT8AVq8e+vxOlk3AtOA2M0qCmhBzoM1OJbdHaPKc0g0UgSnWRml1kPGg5qfPk72tWclLoZJ5/ut0vTg== dependencies: ejs "^3.1.7" ignore "^5.0.4" - semver "7.3.4" + semver "7.5.4" tmp "~0.2.1" tslib "^2.3.0" -"@nrwl/nx-darwin-arm64@15.9.2": - version "15.9.2" - resolved "https://registry.yarnpkg.com/@nrwl/nx-darwin-arm64/-/nx-darwin-arm64-15.9.2.tgz#612d8d714ec876cafd6f1483bf5565704d1b75be" - integrity sha512-Yv+OVsQt3C/hmWOC+YhJZQlsyph5w1BHfbp4jyCvV1ZXBbb8NdvwxgDHPWXxKPTc1EXuB7aEX3qzxM3/OWEUJg== - -"@nrwl/nx-darwin-x64@15.9.2": - version "15.9.2" - resolved "https://registry.yarnpkg.com/@nrwl/nx-darwin-x64/-/nx-darwin-x64-15.9.2.tgz#3f77bd90dbabf4782d81f773cfb2739a443e595f" - integrity sha512-qHfdluHlPzV0UHOwj1ZJ+qNEhzfLGiBuy1cOth4BSzDlvMnkuqBWoprfaXoztzYcus2NSILY1/7b3Jw4DAWmMw== - -"@nrwl/nx-linux-arm-gnueabihf@15.9.2": - version "15.9.2" - resolved "https://registry.yarnpkg.com/@nrwl/nx-linux-arm-gnueabihf/-/nx-linux-arm-gnueabihf-15.9.2.tgz#3374a5a1692b222ce18f2213a47b4d68fb509e70" - integrity sha512-0GzwbablosnYnnJDCJvAeZv8LlelSrNwUnGhe43saeoZdAew35Ay1E34zBrg/GCGTASuz+knEEYFM+gDD9Mc6A== - -"@nrwl/nx-linux-arm64-gnu@15.9.2": - version "15.9.2" - resolved "https://registry.yarnpkg.com/@nrwl/nx-linux-arm64-gnu/-/nx-linux-arm64-gnu-15.9.2.tgz#e3ec95c6ee3285c77422886cf4cbec1f04804460" - integrity sha512-3mFIY7iUTPG45hSIRaM2DmraCy8W6hNoArAGRrTgYw40BIJHtLrW+Rt7DLyvVXaYCvrKugWOKtxC+jG7kpIZVA== - -"@nrwl/nx-linux-arm64-musl@15.9.2": - version "15.9.2" - resolved "https://registry.yarnpkg.com/@nrwl/nx-linux-arm64-musl/-/nx-linux-arm64-musl-15.9.2.tgz#72ce601d256083ded7380c598f1b3eb4dc2a3472" - integrity sha512-FNBnXEtockwxZa4I3NqggrJp0YIbNokJvt/clrICP+ijOacdUDkv8mJedavobkFsRsNq9gzCbRbUScKymrOLrg== - -"@nrwl/nx-linux-x64-gnu@15.9.2": - version "15.9.2" - resolved "https://registry.yarnpkg.com/@nrwl/nx-linux-x64-gnu/-/nx-linux-x64-gnu-15.9.2.tgz#2da6bb50cd80d699310e91c7331baa6cfc8ce197" - integrity sha512-gHWsP5lbe4FNQCa1Q/VLxIuik+BqAOcSzyPjdUa4gCDcbxPa8xiE57PgXB5E1XUzOWNnDTlXa/Ll07/TIuKuog== - -"@nrwl/nx-linux-x64-musl@15.9.2": - version "15.9.2" - resolved "https://registry.yarnpkg.com/@nrwl/nx-linux-x64-musl/-/nx-linux-x64-musl-15.9.2.tgz#39b3bda5868a53b722f1d42700dce71c5ff3f6b9" - integrity sha512-EaFUukCbmoHsYECX2AS4pxXH933yesBFVvBgD38DkoFDxDoJMVt6JqYwm+d5R7S4R2P9U3l++aurljQTRq567Q== - -"@nrwl/nx-win32-arm64-msvc@15.9.2": - version "15.9.2" - resolved "https://registry.yarnpkg.com/@nrwl/nx-win32-arm64-msvc/-/nx-win32-arm64-msvc-15.9.2.tgz#bc350be5cb7d0bfa6c2c5ced40c5af163a457a2c" - integrity sha512-PGAe7QMr51ivx1X3avvs8daNlvv1wGo3OFrobjlu5rSyjC1Y3qHwT9+wdlwzNZ93FIqWOq09s+rE5gfZRfpdAg== - -"@nrwl/nx-win32-x64-msvc@15.9.2": - version "15.9.2" - resolved "https://registry.yarnpkg.com/@nrwl/nx-win32-x64-msvc/-/nx-win32-x64-msvc-15.9.2.tgz#3e46c3f7af196bdbf0deb336ec4f9448c54e4a9f" - integrity sha512-Q8onNzhuAZ0l9DNkm8D4Z1AEIzJr8JiT4L2fVBLYrV/R75C2HS3q7lzvfo6oqMY6mXge1cFPcrTtg3YXBQaSWA== - -"@nrwl/tao@15.9.2": - version "15.9.2" - resolved "https://registry.yarnpkg.com/@nrwl/tao/-/tao-15.9.2.tgz#e970efa8b3fb828007b02286e9e505247032b5b3" - integrity sha512-+LqNC37w9c6q6Ukdpf0z0tt1PQFNi4gwhHpJvkYQiKRETHjyrrlyqTNEPEyA7PI62RuYC6VrpVw2gzI7ufqZEA== - dependencies: - nx "15.9.2" +"@nrwl/nx-darwin-arm64@15.9.7": + version "15.9.7" + resolved "https://registry.yarnpkg.com/@nrwl/nx-darwin-arm64/-/nx-darwin-arm64-15.9.7.tgz#a2cb7390c782b8acf3bb8806a3002620226a933d" + integrity sha512-aBUgnhlkrgC0vu0fK6eb9Vob7eFnkuknrK+YzTjmLrrZwj7FGNAeyGXSlyo1dVokIzjVKjJg2saZZ0WQbfuCJw== + +"@nrwl/nx-darwin-x64@15.9.7": + version "15.9.7" + resolved "https://registry.yarnpkg.com/@nrwl/nx-darwin-x64/-/nx-darwin-x64-15.9.7.tgz#af0437e726aeb97eb660646bfd9a7da5ba7a0a6f" + integrity sha512-L+elVa34jhGf1cmn38Z0sotQatmLovxoASCIw5r1CBZZeJ5Tg7Y9nOwjRiDixZxNN56hPKXm6xl9EKlVHVeKlg== + +"@nrwl/nx-linux-arm-gnueabihf@15.9.7": + version "15.9.7" + resolved "https://registry.yarnpkg.com/@nrwl/nx-linux-arm-gnueabihf/-/nx-linux-arm-gnueabihf-15.9.7.tgz#e29f4d31afa903bfb4d0fd7421e19be1086eae87" + integrity sha512-pqmfqqEUGFu6PmmHKyXyUw1Al0Ki8PSaR0+ndgCAb1qrekVDGDfznJfaqxN0JSLeolPD6+PFtLyXNr9ZyPFlFg== + +"@nrwl/nx-linux-arm64-gnu@15.9.7": + version "15.9.7" + resolved "https://registry.yarnpkg.com/@nrwl/nx-linux-arm64-gnu/-/nx-linux-arm64-gnu-15.9.7.tgz#eb2880a24d3268dd93583d21a6a0b9ff96bb23b4" + integrity sha512-NYOa/eRrqmM+In5g3M0rrPVIS9Z+q6fvwXJYf/KrjOHqqan/KL+2TOfroA30UhcBrwghZvib7O++7gZ2hzwOnA== + +"@nrwl/nx-linux-arm64-musl@15.9.7": + version "15.9.7" + resolved "https://registry.yarnpkg.com/@nrwl/nx-linux-arm64-musl/-/nx-linux-arm64-musl-15.9.7.tgz#5d04913c4672a96cefa78491824620d8a8bcfd7f" + integrity sha512-zyStqjEcmbvLbejdTOrLUSEdhnxNtdQXlmOuymznCzYUEGRv+4f7OAepD3yRoR0a/57SSORZmmGQB7XHZoYZJA== + +"@nrwl/nx-linux-x64-gnu@15.9.7": + version "15.9.7" + resolved "https://registry.yarnpkg.com/@nrwl/nx-linux-x64-gnu/-/nx-linux-x64-gnu-15.9.7.tgz#cf7f61fd87f35a793e6824952a6eb12242fe43fd" + integrity sha512-saNK5i2A8pKO3Il+Ejk/KStTApUpWgCxjeUz9G+T8A+QHeDloZYH2c7pU/P3jA9QoNeKwjVO9wYQllPL9loeVg== + +"@nrwl/nx-linux-x64-musl@15.9.7": + version "15.9.7" + resolved "https://registry.yarnpkg.com/@nrwl/nx-linux-x64-musl/-/nx-linux-x64-musl-15.9.7.tgz#2bec23c3696780540eb47fa1358dda780c84697f" + integrity sha512-extIUThYN94m4Vj4iZggt6hhMZWQSukBCo8pp91JHnDcryBg7SnYmnikwtY1ZAFyyRiNFBLCKNIDFGkKkSrZ9Q== + +"@nrwl/nx-win32-arm64-msvc@15.9.7": + version "15.9.7" + resolved "https://registry.yarnpkg.com/@nrwl/nx-win32-arm64-msvc/-/nx-win32-arm64-msvc-15.9.7.tgz#21b56ef3ab4190370effea71bd83fdc3e47ec69c" + integrity sha512-GSQ54hJ5AAnKZb4KP4cmBnJ1oC4ILxnrG1mekxeM65c1RtWg9NpBwZ8E0gU3xNrTv8ZNsBeKi/9UhXBxhsIh8A== + +"@nrwl/nx-win32-x64-msvc@15.9.7": + version "15.9.7" + resolved "https://registry.yarnpkg.com/@nrwl/nx-win32-x64-msvc/-/nx-win32-x64-msvc-15.9.7.tgz#1677ab1dcce921706b5677dc2844e3e0027f8bd5" + integrity sha512-x6URof79RPd8AlapVbPefUD3ynJZpmah3tYaYZ9xZRMXojVtEHV8Qh5vysKXQ1rNYJiiB8Ah6evSKWLbAH60tw== + +"@nrwl/tao@15.9.7": + version "15.9.7" + resolved "https://registry.yarnpkg.com/@nrwl/tao/-/tao-15.9.7.tgz#c0e78c99caa6742762f7558f20d8524bc9015e97" + integrity sha512-OBnHNvQf3vBH0qh9YnvBQQWyyFZ+PWguF6dJ8+1vyQYlrLVk/XZ8nJ4ukWFb+QfPv/O8VBmqaofaOI9aFC4yTw== + dependencies: + nx "15.9.7" + +"@nrwl/tao@16.2.1": + version "16.2.1" + resolved "https://registry.yarnpkg.com/@nrwl/tao/-/tao-16.2.1.tgz#08bb3dae81e958777268747c385c32a608452c3e" + integrity sha512-mhLkMxGFbnR4hu9UbjMvzdePDXmUpV33mImt1myewP/cY9YZdzv5ntqT+9U+zzVg7Q2ZGosiGQE+IYRm6yeWog== + dependencies: + nx "16.2.1" "@nrwl/workspace@^15.9.2": - version "15.9.2" - resolved "https://registry.yarnpkg.com/@nrwl/workspace/-/workspace-15.9.2.tgz#258ccbc2e42d4d1cade4652d72c4f7b2a7821f5e" - integrity sha512-4e3p1EtJKvvZfH5ghLT3PtPfdr21WfN1LjctMaFAaqwb7jMos0jQIZlLotDPvc9BD8zzyljniE6BijDSZOWncg== + version "15.9.7" + resolved "https://registry.yarnpkg.com/@nrwl/workspace/-/workspace-15.9.7.tgz#5df09b406f5c639baa6cb57bb4a091b17c5d138b" + integrity sha512-tOYYReTgUtP66mtbl6rGfs83il6ywb99GIsyCGINWNBVuU3WE44Io0MCvfirDwlxwSIWouDr64qhGqqzTo3Z9g== dependencies: - "@nrwl/devkit" "15.9.2" + "@nrwl/devkit" "15.9.7" "@parcel/watcher" "2.0.4" chalk "^4.1.0" chokidar "^3.5.1" @@ -3103,7 +4476,7 @@ ignore "^5.0.4" minimatch "3.0.5" npm-run-path "^4.0.1" - nx "15.9.2" + nx "15.9.7" open "^8.4.0" rxjs "^6.5.4" tmp "~0.2.1" @@ -3111,97 +4484,144 @@ yargs "^17.6.2" yargs-parser "21.1.1" -"@parcel/bundler-default@2.8.3": - version "2.8.3" - resolved "https://registry.yarnpkg.com/@parcel/bundler-default/-/bundler-default-2.8.3.tgz#d64739dbc2dbd59d6629861bf77a8083aced5229" - integrity sha512-yJvRsNWWu5fVydsWk3O2L4yIy3UZiKWO2cPDukGOIWMgp/Vbpp+2Ct5IygVRtE22bnseW/E/oe0PV3d2IkEJGg== - dependencies: - "@parcel/diagnostic" "2.8.3" - "@parcel/graph" "2.8.3" - "@parcel/hash" "2.8.3" - "@parcel/plugin" "2.8.3" - "@parcel/utils" "2.8.3" +"@nx/nx-darwin-arm64@16.2.1": + version "16.2.1" + resolved "https://registry.yarnpkg.com/@nx/nx-darwin-arm64/-/nx-darwin-arm64-16.2.1.tgz#8a144a6fd38a2a7179c583c1fc344b2a0de27996" + integrity sha512-xK/dL5T2R8zrcD8/13PeaYH/LBcYeaELIZkXGdGbtQ8WeFHjPJLBfuWo/7Se7KSWIXLIJEeYrVZwyxuei1dOTA== + +"@nx/nx-darwin-x64@16.2.1": + version "16.2.1" + resolved "https://registry.yarnpkg.com/@nx/nx-darwin-x64/-/nx-darwin-x64-16.2.1.tgz#f878b9257bb5ed939c5095b72f1f37fe01bab950" + integrity sha512-J1ZBqy8FtIhvZopcc96JWZY2InZClQ+XHWHnAmX8S1f79hcLUiatpu90FZhvfXmfOfLlpkKsa8aje/kjpnnWhA== + +"@nx/nx-linux-arm-gnueabihf@16.2.1": + version "16.2.1" + resolved "https://registry.yarnpkg.com/@nx/nx-linux-arm-gnueabihf/-/nx-linux-arm-gnueabihf-16.2.1.tgz#a0f7d2c1f90d78bf30c7beae7c5481a71fb2652a" + integrity sha512-rnujPmWlnkEvzkWARuW85cizVx6uGwQ/gA84tK3cHZQf9ly172WbDtsMtYRS9/CjvysMqDV0zBd7o/YhwpXNZg== + +"@nx/nx-linux-arm64-gnu@16.2.1": + version "16.2.1" + resolved "https://registry.yarnpkg.com/@nx/nx-linux-arm64-gnu/-/nx-linux-arm64-gnu-16.2.1.tgz#30dead7a96437c7cbb041a45e1c0e7292fb2151a" + integrity sha512-ZcuQN8eaxEI+93ut6UrDrZMPsk61LGlS6yaWPgrv3blKMfcU2+DYBDQ3ois7o5t0bnVad5QYSNhIvnMF2iU+hQ== + +"@nx/nx-linux-arm64-musl@16.2.1": + version "16.2.1" + resolved "https://registry.yarnpkg.com/@nx/nx-linux-arm64-musl/-/nx-linux-arm64-musl-16.2.1.tgz#31219ecf98f9fe78b5fc06c9e0102d99e335bc5b" + integrity sha512-mMOvkYyBLU4j+mSHobtrj/pIDYXFGIX3Q9FMWxZ5Xz15m0DsbypZ/8v6NWpJaBY4VX6rJhCc+D/pZH+QBT8+/g== + +"@nx/nx-linux-x64-gnu@16.2.1": + version "16.2.1" + resolved "https://registry.yarnpkg.com/@nx/nx-linux-x64-gnu/-/nx-linux-x64-gnu-16.2.1.tgz#fb89cbbdf852e27093e0296ff7414ccccdf3591a" + integrity sha512-Kyn4dxFTj2PCRv+39tKU8BzDRE6/ru5v435uvodx03GS650F7+OMr4DN57jG4MQWhf//OUX8zPkvbKhsmxjndA== + +"@nx/nx-linux-x64-musl@16.2.1": + version "16.2.1" + resolved "https://registry.yarnpkg.com/@nx/nx-linux-x64-musl/-/nx-linux-x64-musl-16.2.1.tgz#82b1b5ba04ef6e4d49527841239bf9e0fb1456e3" + integrity sha512-q8iFxLosSLiWkRWsbrioXV/qMG8TgsbqcM0VGz2FFLNMJ9DXvav/E/+8YbgEeHOjvA1MDeRaspIpDF7OMgJYGw== + +"@nx/nx-win32-arm64-msvc@16.2.1": + version "16.2.1" + resolved "https://registry.yarnpkg.com/@nx/nx-win32-arm64-msvc/-/nx-win32-arm64-msvc-16.2.1.tgz#8a19a0c2db565f6d07a2d0b4a8b8fc6c8c86fadd" + integrity sha512-PpGiYzrMivDY1i10Zwf5Hmnv6oAQ8ACf6ehDgyQ3tByMMXHgyUZJLykfPaoWjoLh0s8wOvMV74WZO+K1LcIxTA== + +"@nx/nx-win32-x64-msvc@16.2.1": + version "16.2.1" + resolved "https://registry.yarnpkg.com/@nx/nx-win32-x64-msvc/-/nx-win32-x64-msvc-16.2.1.tgz#848b4c5b118f6a6f92f59c1643297e938c439242" + integrity sha512-m5oHCaSKdyydM1n1W9V0m2oxBL8PiF54dZB0+PlKB2fhf1zxiyq8i1hL2hXbKA90IOYcUt5/b7761/BzN5njAw== + +"@parcel/bundler-default@2.12.0": + version "2.12.0" + resolved "https://registry.yarnpkg.com/@parcel/bundler-default/-/bundler-default-2.12.0.tgz#b8f6f3fc3f497714bd54e19882aaa116e97df4a4" + integrity sha512-3ybN74oYNMKyjD6V20c9Gerdbh7teeNvVMwIoHIQMzuIFT6IGX53PyOLlOKRLbjxMc0TMimQQxIt2eQqxR5LsA== + dependencies: + "@parcel/diagnostic" "2.12.0" + "@parcel/graph" "3.2.0" + "@parcel/plugin" "2.12.0" + "@parcel/rust" "2.12.0" + "@parcel/utils" "2.12.0" nullthrows "^1.1.1" -"@parcel/cache@2.8.3": - version "2.8.3" - resolved "https://registry.yarnpkg.com/@parcel/cache/-/cache-2.8.3.tgz#169e130cf59913c0ed9fadce1a450e68f710e16f" - integrity sha512-k7xv5vSQrJLdXuglo+Hv3yF4BCSs1tQ/8Vbd6CHTkOhf7LcGg6CPtLw053R/KdMpd/4GPn0QrAsOLdATm1ELtQ== +"@parcel/cache@2.12.0": + version "2.12.0" + resolved "https://registry.yarnpkg.com/@parcel/cache/-/cache-2.12.0.tgz#b8fd2ea2bc7a2353a9b20344cc191bfb4f8284f3" + integrity sha512-FX5ZpTEkxvq/yvWklRHDESVRz+c7sLTXgFuzz6uEnBcXV38j6dMSikflNpHA6q/L4GKkCqRywm9R6XQwhwIMyw== dependencies: - "@parcel/fs" "2.8.3" - "@parcel/logger" "2.8.3" - "@parcel/utils" "2.8.3" - lmdb "2.5.2" + "@parcel/fs" "2.12.0" + "@parcel/logger" "2.12.0" + "@parcel/utils" "2.12.0" + lmdb "2.8.5" -"@parcel/codeframe@2.8.3": - version "2.8.3" - resolved "https://registry.yarnpkg.com/@parcel/codeframe/-/codeframe-2.8.3.tgz#84fb529ef70def7f5bc64f6c59b18d24826f5fcc" - integrity sha512-FE7sY53D6n/+2Pgg6M9iuEC6F5fvmyBkRE4d9VdnOoxhTXtkEqpqYgX7RJ12FAQwNlxKq4suBJQMgQHMF2Kjeg== +"@parcel/codeframe@2.12.0": + version "2.12.0" + resolved "https://registry.yarnpkg.com/@parcel/codeframe/-/codeframe-2.12.0.tgz#9ea75bd7ae6c5f7fadf42a5e64657cf88fdcb29e" + integrity sha512-v2VmneILFiHZJTxPiR7GEF1wey1/IXPdZMcUlNXBiPZyWDfcuNgGGVQkx/xW561rULLIvDPharOMdxz5oHOKQg== dependencies: chalk "^4.1.0" -"@parcel/compressor-raw@2.8.3": - version "2.8.3" - resolved "https://registry.yarnpkg.com/@parcel/compressor-raw/-/compressor-raw-2.8.3.tgz#301753df8c6de967553149639e8a4179b88f0c95" - integrity sha512-bVDsqleBUxRdKMakWSlWC9ZjOcqDKE60BE+Gh3JSN6WJrycJ02P5wxjTVF4CStNP/G7X17U+nkENxSlMG77ySg== +"@parcel/compressor-raw@2.12.0": + version "2.12.0" + resolved "https://registry.yarnpkg.com/@parcel/compressor-raw/-/compressor-raw-2.12.0.tgz#71012b695c870f1d26bfd8d56983c14bf13fd996" + integrity sha512-h41Q3X7ZAQ9wbQ2csP8QGrwepasLZdXiuEdpUryDce6rF9ZiHoJ97MRpdLxOhOPyASTw/xDgE1xyaPQr0Q3f5A== dependencies: - "@parcel/plugin" "2.8.3" + "@parcel/plugin" "2.12.0" -"@parcel/config-default@2.8.3": - version "2.8.3" - resolved "https://registry.yarnpkg.com/@parcel/config-default/-/config-default-2.8.3.tgz#9a43486e7c702e96c68052c37b79098d7240e35b" - integrity sha512-o/A/mbrO6X/BfGS65Sib8d6SSG45NYrNooNBkH/o7zbOBSRQxwyTlysleK1/3Wa35YpvFyLOwgfakqCtbGy4fw== - dependencies: - "@parcel/bundler-default" "2.8.3" - "@parcel/compressor-raw" "2.8.3" - "@parcel/namer-default" "2.8.3" - "@parcel/optimizer-css" "2.8.3" - "@parcel/optimizer-htmlnano" "2.8.3" - "@parcel/optimizer-image" "2.8.3" - "@parcel/optimizer-svgo" "2.8.3" - "@parcel/optimizer-terser" "2.8.3" - "@parcel/packager-css" "2.8.3" - "@parcel/packager-html" "2.8.3" - "@parcel/packager-js" "2.8.3" - "@parcel/packager-raw" "2.8.3" - "@parcel/packager-svg" "2.8.3" - "@parcel/reporter-dev-server" "2.8.3" - "@parcel/resolver-default" "2.8.3" - "@parcel/runtime-browser-hmr" "2.8.3" - "@parcel/runtime-js" "2.8.3" - "@parcel/runtime-react-refresh" "2.8.3" - "@parcel/runtime-service-worker" "2.8.3" - "@parcel/transformer-babel" "2.8.3" - "@parcel/transformer-css" "2.8.3" - "@parcel/transformer-html" "2.8.3" - "@parcel/transformer-image" "2.8.3" - "@parcel/transformer-js" "2.8.3" - "@parcel/transformer-json" "2.8.3" - "@parcel/transformer-postcss" "2.8.3" - "@parcel/transformer-posthtml" "2.8.3" - "@parcel/transformer-raw" "2.8.3" - "@parcel/transformer-react-refresh-wrap" "2.8.3" - "@parcel/transformer-svg" "2.8.3" - -"@parcel/core@2.8.3": - version "2.8.3" - resolved "https://registry.yarnpkg.com/@parcel/core/-/core-2.8.3.tgz#22a69f36095d53736ab10bf42697d9aa5f4e382b" - integrity sha512-Euf/un4ZAiClnlUXqPB9phQlKbveU+2CotZv7m7i+qkgvFn5nAGnrV4h1OzQU42j9dpgOxWi7AttUDMrvkbhCQ== +"@parcel/config-default@2.12.0": + version "2.12.0" + resolved "https://registry.yarnpkg.com/@parcel/config-default/-/config-default-2.12.0.tgz#7b213348db349c6042a80dfd4a7eab707a1dfbfa" + integrity sha512-dPNe2n9eEsKRc1soWIY0yToMUPirPIa2QhxcCB3Z5RjpDGIXm0pds+BaiqY6uGLEEzsjhRO0ujd4v2Rmm0vuFg== + dependencies: + "@parcel/bundler-default" "2.12.0" + "@parcel/compressor-raw" "2.12.0" + "@parcel/namer-default" "2.12.0" + "@parcel/optimizer-css" "2.12.0" + "@parcel/optimizer-htmlnano" "2.12.0" + "@parcel/optimizer-image" "2.12.0" + "@parcel/optimizer-svgo" "2.12.0" + "@parcel/optimizer-swc" "2.12.0" + "@parcel/packager-css" "2.12.0" + "@parcel/packager-html" "2.12.0" + "@parcel/packager-js" "2.12.0" + "@parcel/packager-raw" "2.12.0" + "@parcel/packager-svg" "2.12.0" + "@parcel/packager-wasm" "2.12.0" + "@parcel/reporter-dev-server" "2.12.0" + "@parcel/resolver-default" "2.12.0" + "@parcel/runtime-browser-hmr" "2.12.0" + "@parcel/runtime-js" "2.12.0" + "@parcel/runtime-react-refresh" "2.12.0" + "@parcel/runtime-service-worker" "2.12.0" + "@parcel/transformer-babel" "2.12.0" + "@parcel/transformer-css" "2.12.0" + "@parcel/transformer-html" "2.12.0" + "@parcel/transformer-image" "2.12.0" + "@parcel/transformer-js" "2.12.0" + "@parcel/transformer-json" "2.12.0" + "@parcel/transformer-postcss" "2.12.0" + "@parcel/transformer-posthtml" "2.12.0" + "@parcel/transformer-raw" "2.12.0" + "@parcel/transformer-react-refresh-wrap" "2.12.0" + "@parcel/transformer-svg" "2.12.0" + +"@parcel/core@2.12.0": + version "2.12.0" + resolved "https://registry.yarnpkg.com/@parcel/core/-/core-2.12.0.tgz#ea5734f008300bc57aaff2ba0f7949724c93b56d" + integrity sha512-s+6pwEj+GfKf7vqGUzN9iSEPueUssCCQrCBUlcAfKrJe0a22hTUCjewpB0I7lNrCIULt8dkndD+sMdOrXsRl6Q== dependencies: "@mischnic/json-sourcemap" "^0.1.0" - "@parcel/cache" "2.8.3" - "@parcel/diagnostic" "2.8.3" - "@parcel/events" "2.8.3" - "@parcel/fs" "2.8.3" - "@parcel/graph" "2.8.3" - "@parcel/hash" "2.8.3" - "@parcel/logger" "2.8.3" - "@parcel/package-manager" "2.8.3" - "@parcel/plugin" "2.8.3" + "@parcel/cache" "2.12.0" + "@parcel/diagnostic" "2.12.0" + "@parcel/events" "2.12.0" + "@parcel/fs" "2.12.0" + "@parcel/graph" "3.2.0" + "@parcel/logger" "2.12.0" + "@parcel/package-manager" "2.12.0" + "@parcel/plugin" "2.12.0" + "@parcel/profiler" "2.12.0" + "@parcel/rust" "2.12.0" "@parcel/source-map" "^2.1.1" - "@parcel/types" "2.8.3" - "@parcel/utils" "2.8.3" - "@parcel/workers" "2.8.3" + "@parcel/types" "2.12.0" + "@parcel/utils" "2.12.0" + "@parcel/workers" "2.12.0" abortcontroller-polyfill "^1.1.9" base-x "^3.0.8" browserslist "^4.6.6" @@ -3209,281 +4629,306 @@ dotenv "^7.0.0" dotenv-expand "^5.1.0" json5 "^2.2.0" - msgpackr "^1.5.4" + msgpackr "^1.9.9" nullthrows "^1.1.1" - semver "^5.7.1" + semver "^7.5.2" -"@parcel/diagnostic@2.8.3": - version "2.8.3" - resolved "https://registry.yarnpkg.com/@parcel/diagnostic/-/diagnostic-2.8.3.tgz#d560276d5d2804b48beafa1feaf3fc6b2ac5e39d" - integrity sha512-u7wSzuMhLGWZjVNYJZq/SOViS3uFG0xwIcqXw12w54Uozd6BH8JlhVtVyAsq9kqnn7YFkw6pXHqAo5Tzh4FqsQ== +"@parcel/diagnostic@2.12.0": + version "2.12.0" + resolved "https://registry.yarnpkg.com/@parcel/diagnostic/-/diagnostic-2.12.0.tgz#b38057d819ea2edc32018a1d51df434f07840be9" + integrity sha512-8f1NOsSFK+F4AwFCKynyIu9Kr/uWHC+SywAv4oS6Bv3Acig0gtwUjugk0C9UaB8ztBZiW5TQZhw+uPZn9T/lJA== dependencies: "@mischnic/json-sourcemap" "^0.1.0" nullthrows "^1.1.1" -"@parcel/events@2.8.3": - version "2.8.3" - resolved "https://registry.yarnpkg.com/@parcel/events/-/events-2.8.3.tgz#205f8d874e6ecc2cbdb941bf8d54bae669e571af" - integrity sha512-hoIS4tAxWp8FJk3628bsgKxEvR7bq2scCVYHSqZ4fTi/s0+VymEATrRCUqf+12e5H47uw1/ZjoqrGtBI02pz4w== - -"@parcel/fs-search@2.8.3": - version "2.8.3" - resolved "https://registry.yarnpkg.com/@parcel/fs-search/-/fs-search-2.8.3.tgz#1c7d812c110b808758f44c56e61dfffdb09e9451" - integrity sha512-DJBT2N8knfN7Na6PP2mett3spQLTqxFrvl0gv+TJRp61T8Ljc4VuUTb0hqBj+belaASIp3Q+e8+SgaFQu7wLiQ== - dependencies: - detect-libc "^1.0.3" +"@parcel/events@2.12.0": + version "2.12.0" + resolved "https://registry.yarnpkg.com/@parcel/events/-/events-2.12.0.tgz#ef67e3fbb96806b3531a37bcf95e8fbb3818ffa2" + integrity sha512-nmAAEIKLjW1kB2cUbCYSmZOGbnGj8wCzhqnK727zCCWaA25ogzAtt657GPOeFyqW77KyosU728Tl63Fc8hphIA== -"@parcel/fs@2.8.3": - version "2.8.3" - resolved "https://registry.yarnpkg.com/@parcel/fs/-/fs-2.8.3.tgz#80536afe877fc8a2bd26be5576b9ba27bb4c5754" - integrity sha512-y+i+oXbT7lP0e0pJZi/YSm1vg0LDsbycFuHZIL80pNwdEppUAtibfJZCp606B7HOjMAlNZOBo48e3hPG3d8jgQ== +"@parcel/fs@2.12.0": + version "2.12.0" + resolved "https://registry.yarnpkg.com/@parcel/fs/-/fs-2.12.0.tgz#8c9029353888311ba2e9e2198dbe6c7c1da635c0" + integrity sha512-NnFkuvou1YBtPOhTdZr44WN7I60cGyly2wpHzqRl62yhObyi1KvW0SjwOMa0QGNcBOIzp4G0CapoZ93hD0RG5Q== dependencies: - "@parcel/fs-search" "2.8.3" - "@parcel/types" "2.8.3" - "@parcel/utils" "2.8.3" + "@parcel/rust" "2.12.0" + "@parcel/types" "2.12.0" + "@parcel/utils" "2.12.0" "@parcel/watcher" "^2.0.7" - "@parcel/workers" "2.8.3" + "@parcel/workers" "2.12.0" -"@parcel/graph@2.8.3": - version "2.8.3" - resolved "https://registry.yarnpkg.com/@parcel/graph/-/graph-2.8.3.tgz#00ffe8ec032e74fee57199e54529f1da7322571d" - integrity sha512-26GL8fYZPdsRhSXCZ0ZWliloK6DHlMJPWh6Z+3VVZ5mnDSbYg/rRKWmrkhnr99ZWmL9rJsv4G74ZwvDEXTMPBg== +"@parcel/graph@3.2.0": + version "3.2.0" + resolved "https://registry.yarnpkg.com/@parcel/graph/-/graph-3.2.0.tgz#309e6e3f19ef4ea7f71b2341ec1bcc08e7c43523" + integrity sha512-xlrmCPqy58D4Fg5umV7bpwDx5Vyt7MlnQPxW68vae5+BA4GSWetfZt+Cs5dtotMG2oCHzZxhIPt7YZ7NRyQzLA== dependencies: nullthrows "^1.1.1" -"@parcel/hash@2.8.3": - version "2.8.3" - resolved "https://registry.yarnpkg.com/@parcel/hash/-/hash-2.8.3.tgz#bc2499a27395169616cad2a99e19e69b9098f6e9" - integrity sha512-FVItqzjWmnyP4ZsVgX+G00+6U2IzOvqDtdwQIWisCcVoXJFCqZJDy6oa2qDDFz96xCCCynjRjPdQx2jYBCpfYw== - dependencies: - detect-libc "^1.0.3" - xxhash-wasm "^0.4.2" - -"@parcel/logger@2.8.3": - version "2.8.3" - resolved "https://registry.yarnpkg.com/@parcel/logger/-/logger-2.8.3.tgz#e14e4debafb3ca9e87c07c06780f9afc38b2712c" - integrity sha512-Kpxd3O/Vs7nYJIzkdmB6Bvp3l/85ydIxaZaPfGSGTYOfaffSOTkhcW9l6WemsxUrlts4za6CaEWcc4DOvaMOPA== +"@parcel/logger@2.12.0": + version "2.12.0" + resolved "https://registry.yarnpkg.com/@parcel/logger/-/logger-2.12.0.tgz#0b866b7aee8a0a462596a80cd46bd8b29c318758" + integrity sha512-cJ7Paqa7/9VJ7C+KwgJlwMqTQBOjjn71FbKk0G07hydUEBISU2aDfmc/52o60ErL9l+vXB26zTrIBanbxS8rVg== dependencies: - "@parcel/diagnostic" "2.8.3" - "@parcel/events" "2.8.3" + "@parcel/diagnostic" "2.12.0" + "@parcel/events" "2.12.0" -"@parcel/markdown-ansi@2.8.3": - version "2.8.3" - resolved "https://registry.yarnpkg.com/@parcel/markdown-ansi/-/markdown-ansi-2.8.3.tgz#1337d421bb1133ad178f386a8e1b746631bba4a1" - integrity sha512-4v+pjyoh9f5zuU/gJlNvNFGEAb6J90sOBwpKJYJhdWXLZMNFCVzSigxrYO+vCsi8G4rl6/B2c0LcwIMjGPHmFQ== +"@parcel/markdown-ansi@2.12.0": + version "2.12.0" + resolved "https://registry.yarnpkg.com/@parcel/markdown-ansi/-/markdown-ansi-2.12.0.tgz#a4301321fa784a28ba817e65e41432fe8b3b3192" + integrity sha512-WZz3rzL8k0H3WR4qTHX6Ic8DlEs17keO9gtD4MNGyMNQbqQEvQ61lWJaIH0nAtgEetu0SOITiVqdZrb8zx/M7w== dependencies: chalk "^4.1.0" -"@parcel/namer-default@2.8.3": - version "2.8.3" - resolved "https://registry.yarnpkg.com/@parcel/namer-default/-/namer-default-2.8.3.tgz#5304bee74beb4b9c1880781bdbe35be0656372f4" - integrity sha512-tJ7JehZviS5QwnxbARd8Uh63rkikZdZs1QOyivUhEvhN+DddSAVEdQLHGPzkl3YRk0tjFhbqo+Jci7TpezuAMw== +"@parcel/namer-default@2.12.0": + version "2.12.0" + resolved "https://registry.yarnpkg.com/@parcel/namer-default/-/namer-default-2.12.0.tgz#f9903da8e4c5c3e33fc8ab70b222be520a46da5d" + integrity sha512-9DNKPDHWgMnMtqqZIMiEj/R9PNWW16lpnlHjwK3ciRlMPgjPJ8+UNc255teZODhX0T17GOzPdGbU/O/xbxVPzA== dependencies: - "@parcel/diagnostic" "2.8.3" - "@parcel/plugin" "2.8.3" + "@parcel/diagnostic" "2.12.0" + "@parcel/plugin" "2.12.0" nullthrows "^1.1.1" -"@parcel/node-resolver-core@2.8.3": - version "2.8.3" - resolved "https://registry.yarnpkg.com/@parcel/node-resolver-core/-/node-resolver-core-2.8.3.tgz#581df074a27646400b3fed9da95297b616a7db8f" - integrity sha512-12YryWcA5Iw2WNoEVr/t2HDjYR1iEzbjEcxfh1vaVDdZ020PiGw67g5hyIE/tsnG7SRJ0xdRx1fQ2hDgED+0Ww== +"@parcel/node-resolver-core@3.3.0": + version "3.3.0" + resolved "https://registry.yarnpkg.com/@parcel/node-resolver-core/-/node-resolver-core-3.3.0.tgz#f40d80de800baa7cf230406b7122c8711ac4cdc8" + integrity sha512-rhPW9DYPEIqQBSlYzz3S0AjXxjN6Ub2yS6tzzsW/4S3Gpsgk/uEq4ZfxPvoPf/6TgZndVxmKwpmxaKtGMmf3cA== dependencies: - "@parcel/diagnostic" "2.8.3" - "@parcel/utils" "2.8.3" + "@mischnic/json-sourcemap" "^0.1.0" + "@parcel/diagnostic" "2.12.0" + "@parcel/fs" "2.12.0" + "@parcel/rust" "2.12.0" + "@parcel/utils" "2.12.0" nullthrows "^1.1.1" - semver "^5.7.1" + semver "^7.5.2" -"@parcel/optimizer-css@2.8.3": - version "2.8.3" - resolved "https://registry.yarnpkg.com/@parcel/optimizer-css/-/optimizer-css-2.8.3.tgz#420a333f4b78f7ff15e69217dfed34421b1143ee" - integrity sha512-JotGAWo8JhuXsQDK0UkzeQB0UR5hDAKvAviXrjqB4KM9wZNLhLleeEAW4Hk8R9smCeQFP6Xg/N/NkLDpqMwT3g== +"@parcel/optimizer-css@2.12.0": + version "2.12.0" + resolved "https://registry.yarnpkg.com/@parcel/optimizer-css/-/optimizer-css-2.12.0.tgz#f44f38dc7136b511a849343eea04714a42e1ba5f" + integrity sha512-ifbcC97fRzpruTjaa8axIFeX4MjjSIlQfem3EJug3L2AVqQUXnM1XO8L0NaXGNLTW2qnh1ZjIJ7vXT/QhsphsA== dependencies: - "@parcel/diagnostic" "2.8.3" - "@parcel/plugin" "2.8.3" + "@parcel/diagnostic" "2.12.0" + "@parcel/plugin" "2.12.0" "@parcel/source-map" "^2.1.1" - "@parcel/utils" "2.8.3" + "@parcel/utils" "2.12.0" browserslist "^4.6.6" - lightningcss "^1.16.1" + lightningcss "^1.22.1" nullthrows "^1.1.1" -"@parcel/optimizer-htmlnano@2.8.3": - version "2.8.3" - resolved "https://registry.yarnpkg.com/@parcel/optimizer-htmlnano/-/optimizer-htmlnano-2.8.3.tgz#a71ab6f0f24160ef9f573266064438eff65e96d0" - integrity sha512-L8/fHbEy8Id2a2E0fwR5eKGlv9VYDjrH9PwdJE9Za9v1O/vEsfl/0T/79/x129l5O0yB6EFQkFa20MiK3b+vOg== +"@parcel/optimizer-htmlnano@2.12.0": + version "2.12.0" + resolved "https://registry.yarnpkg.com/@parcel/optimizer-htmlnano/-/optimizer-htmlnano-2.12.0.tgz#e389d56d3f5cd2f6dd464a756a0704a65e527a9b" + integrity sha512-MfPMeCrT8FYiOrpFHVR+NcZQlXAptK2r4nGJjfT+ndPBhEEZp4yyL7n1y7HfX9geg5altc4WTb4Gug7rCoW8VQ== dependencies: - "@parcel/plugin" "2.8.3" + "@parcel/plugin" "2.12.0" htmlnano "^2.0.0" nullthrows "^1.1.1" posthtml "^0.16.5" svgo "^2.4.0" -"@parcel/optimizer-image@2.8.3": - version "2.8.3" - resolved "https://registry.yarnpkg.com/@parcel/optimizer-image/-/optimizer-image-2.8.3.tgz#ea49b4245b4f7d60b38c7585c6311fb21d341baa" - integrity sha512-SD71sSH27SkCDNUNx9A3jizqB/WIJr3dsfp+JZGZC42tpD/Siim6Rqy9M4To/BpMMQIIiEXa5ofwS+DgTEiEHQ== +"@parcel/optimizer-image@2.12.0": + version "2.12.0" + resolved "https://registry.yarnpkg.com/@parcel/optimizer-image/-/optimizer-image-2.12.0.tgz#46dd3c2a871700076c17376d27f6d46d030a0717" + integrity sha512-bo1O7raeAIbRU5nmNVtx8divLW9Xqn0c57GVNGeAK4mygnQoqHqRZ0mR9uboh64pxv6ijXZHPhKvU9HEpjPjBQ== dependencies: - "@parcel/diagnostic" "2.8.3" - "@parcel/plugin" "2.8.3" - "@parcel/utils" "2.8.3" - "@parcel/workers" "2.8.3" - detect-libc "^1.0.3" + "@parcel/diagnostic" "2.12.0" + "@parcel/plugin" "2.12.0" + "@parcel/rust" "2.12.0" + "@parcel/utils" "2.12.0" + "@parcel/workers" "2.12.0" -"@parcel/optimizer-svgo@2.8.3": - version "2.8.3" - resolved "https://registry.yarnpkg.com/@parcel/optimizer-svgo/-/optimizer-svgo-2.8.3.tgz#04da4efec6b623679539a84961bff6998034ba8a" - integrity sha512-9KQed99NZnQw3/W4qBYVQ7212rzA9EqrQG019TIWJzkA9tjGBMIm2c/nXpK1tc3hQ3e7KkXkFCQ3C+ibVUnHNA== +"@parcel/optimizer-svgo@2.12.0": + version "2.12.0" + resolved "https://registry.yarnpkg.com/@parcel/optimizer-svgo/-/optimizer-svgo-2.12.0.tgz#f1e411cbc3a3c56e05aa5fb2e1edd1ecc7016378" + integrity sha512-Kyli+ZZXnoonnbeRQdoWwee9Bk2jm/49xvnfb+2OO8NN0d41lblBoRhOyFiScRnJrw7eVl1Xrz7NTkXCIO7XFQ== dependencies: - "@parcel/diagnostic" "2.8.3" - "@parcel/plugin" "2.8.3" - "@parcel/utils" "2.8.3" + "@parcel/diagnostic" "2.12.0" + "@parcel/plugin" "2.12.0" + "@parcel/utils" "2.12.0" svgo "^2.4.0" -"@parcel/optimizer-terser@2.8.3": - version "2.8.3" - resolved "https://registry.yarnpkg.com/@parcel/optimizer-terser/-/optimizer-terser-2.8.3.tgz#3a06d98d09386a1a0ae1be85376a8739bfba9618" - integrity sha512-9EeQlN6zIeUWwzrzu6Q2pQSaYsYGah8MtiQ/hog9KEPlYTP60hBv/+utDyYEHSQhL7y5ym08tPX5GzBvwAD/dA== +"@parcel/optimizer-swc@2.12.0": + version "2.12.0" + resolved "https://registry.yarnpkg.com/@parcel/optimizer-swc/-/optimizer-swc-2.12.0.tgz#bacbdb4f6f4a7e0b7086f30b683e3f3f2f980c96" + integrity sha512-iBi6LZB3lm6WmbXfzi8J3DCVPmn4FN2lw7DGXxUXu7MouDPVWfTsM6U/5TkSHJRNRogZ2gqy5q9g34NPxHbJcw== dependencies: - "@parcel/diagnostic" "2.8.3" - "@parcel/plugin" "2.8.3" + "@parcel/diagnostic" "2.12.0" + "@parcel/plugin" "2.12.0" "@parcel/source-map" "^2.1.1" - "@parcel/utils" "2.8.3" + "@parcel/utils" "2.12.0" + "@swc/core" "^1.3.36" nullthrows "^1.1.1" - terser "^5.2.0" -"@parcel/package-manager@2.8.3": - version "2.8.3" - resolved "https://registry.yarnpkg.com/@parcel/package-manager/-/package-manager-2.8.3.tgz#ddd0d62feae3cf0fb6cc0537791b3a16296ad458" - integrity sha512-tIpY5pD2lH53p9hpi++GsODy6V3khSTX4pLEGuMpeSYbHthnOViobqIlFLsjni+QA1pfc8NNNIQwSNdGjYflVA== - dependencies: - "@parcel/diagnostic" "2.8.3" - "@parcel/fs" "2.8.3" - "@parcel/logger" "2.8.3" - "@parcel/types" "2.8.3" - "@parcel/utils" "2.8.3" - "@parcel/workers" "2.8.3" - semver "^5.7.1" - -"@parcel/packager-css@2.8.3": - version "2.8.3" - resolved "https://registry.yarnpkg.com/@parcel/packager-css/-/packager-css-2.8.3.tgz#0eff34268cb4f5dfb53c1bbca85f5567aeb1835a" - integrity sha512-WyvkMmsurlHG8d8oUVm7S+D+cC/T3qGeqogb7sTI52gB6uiywU7lRCizLNqGFyFGIxcVTVHWnSHqItBcLN76lA== +"@parcel/package-manager@2.12.0": + version "2.12.0" + resolved "https://registry.yarnpkg.com/@parcel/package-manager/-/package-manager-2.12.0.tgz#7e1eb5f652544e045f7240fa6cf92e5ff1627624" + integrity sha512-0nvAezcjPx9FT+hIL+LS1jb0aohwLZXct7jAh7i0MLMtehOi0z1Sau+QpgMlA9rfEZZ1LIeFdnZZwqSy7Ccspw== + dependencies: + "@parcel/diagnostic" "2.12.0" + "@parcel/fs" "2.12.0" + "@parcel/logger" "2.12.0" + "@parcel/node-resolver-core" "3.3.0" + "@parcel/types" "2.12.0" + "@parcel/utils" "2.12.0" + "@parcel/workers" "2.12.0" + "@swc/core" "^1.3.36" + semver "^7.5.2" + +"@parcel/packager-css@2.12.0": + version "2.12.0" + resolved "https://registry.yarnpkg.com/@parcel/packager-css/-/packager-css-2.12.0.tgz#bee2908608f306186695c6505c3303548751a7b8" + integrity sha512-j3a/ODciaNKD19IYdWJT+TP+tnhhn5koBGBWWtrKSu0UxWpnezIGZetit3eE+Y9+NTePalMkvpIlit2eDhvfJA== dependencies: - "@parcel/plugin" "2.8.3" + "@parcel/diagnostic" "2.12.0" + "@parcel/plugin" "2.12.0" "@parcel/source-map" "^2.1.1" - "@parcel/utils" "2.8.3" + "@parcel/utils" "2.12.0" + lightningcss "^1.22.1" nullthrows "^1.1.1" -"@parcel/packager-html@2.8.3": - version "2.8.3" - resolved "https://registry.yarnpkg.com/@parcel/packager-html/-/packager-html-2.8.3.tgz#f9263b891aa4dd46c6e2fa2b07025a482132fff1" - integrity sha512-OhPu1Hx1RRKJodpiu86ZqL8el2Aa4uhBHF6RAL1Pcrh2EhRRlPf70Sk0tC22zUpYL7es+iNKZ/n0Rl+OWSHWEw== +"@parcel/packager-html@2.12.0": + version "2.12.0" + resolved "https://registry.yarnpkg.com/@parcel/packager-html/-/packager-html-2.12.0.tgz#dd62a483043982880a63e68ce8d8132f60becd3d" + integrity sha512-PpvGB9hFFe+19NXGz2ApvPrkA9GwEqaDAninT+3pJD57OVBaxB8U+HN4a5LICKxjUppPPqmrLb6YPbD65IX4RA== dependencies: - "@parcel/plugin" "2.8.3" - "@parcel/types" "2.8.3" - "@parcel/utils" "2.8.3" + "@parcel/plugin" "2.12.0" + "@parcel/types" "2.12.0" + "@parcel/utils" "2.12.0" nullthrows "^1.1.1" posthtml "^0.16.5" -"@parcel/packager-js@2.8.3": - version "2.8.3" - resolved "https://registry.yarnpkg.com/@parcel/packager-js/-/packager-js-2.8.3.tgz#3ed11565915d73d12192b6901c75a6b820e4a83a" - integrity sha512-0pGKC3Ax5vFuxuZCRB+nBucRfFRz4ioie19BbDxYnvBxrd4M3FIu45njf6zbBYsI9eXqaDnL1b3DcZJfYqtIzw== +"@parcel/packager-js@2.12.0": + version "2.12.0" + resolved "https://registry.yarnpkg.com/@parcel/packager-js/-/packager-js-2.12.0.tgz#f81f64d16560b97e70bbb4cf568555f990afa2f6" + integrity sha512-viMF+FszITRRr8+2iJyk+4ruGiL27Y6AF7hQ3xbJfzqnmbOhGFtLTQwuwhOLqN/mWR2VKdgbLpZSarWaO3yAMg== dependencies: - "@parcel/diagnostic" "2.8.3" - "@parcel/hash" "2.8.3" - "@parcel/plugin" "2.8.3" + "@parcel/diagnostic" "2.12.0" + "@parcel/plugin" "2.12.0" + "@parcel/rust" "2.12.0" "@parcel/source-map" "^2.1.1" - "@parcel/utils" "2.8.3" + "@parcel/types" "2.12.0" + "@parcel/utils" "2.12.0" globals "^13.2.0" nullthrows "^1.1.1" -"@parcel/packager-raw@2.8.3": - version "2.8.3" - resolved "https://registry.yarnpkg.com/@parcel/packager-raw/-/packager-raw-2.8.3.tgz#bdec826df991e186cb58691cc45d12ad5c06676e" - integrity sha512-BA6enNQo1RCnco9MhkxGrjOk59O71IZ9DPKu3lCtqqYEVd823tXff2clDKHK25i6cChmeHu6oB1Rb73hlPqhUA== +"@parcel/packager-raw@2.12.0": + version "2.12.0" + resolved "https://registry.yarnpkg.com/@parcel/packager-raw/-/packager-raw-2.12.0.tgz#043b704814ff2bcc884cf33e6542f72e246367e0" + integrity sha512-tJZqFbHqP24aq1F+OojFbQIc09P/u8HAW5xfndCrFnXpW4wTgM3p03P0xfw3gnNq+TtxHJ8c3UFE5LnXNNKhYA== dependencies: - "@parcel/plugin" "2.8.3" + "@parcel/plugin" "2.12.0" -"@parcel/packager-svg@2.8.3": - version "2.8.3" - resolved "https://registry.yarnpkg.com/@parcel/packager-svg/-/packager-svg-2.8.3.tgz#7233315296001c531cb55ca96b5f2ef672343630" - integrity sha512-mvIoHpmv5yzl36OjrklTDFShLUfPFTwrmp1eIwiszGdEBuQaX7JVI3Oo2jbVQgcN4W7J6SENzGQ3Q5hPTW3pMw== +"@parcel/packager-svg@2.12.0": + version "2.12.0" + resolved "https://registry.yarnpkg.com/@parcel/packager-svg/-/packager-svg-2.12.0.tgz#2c392243373d60fc834a08d15003f239c34f39a7" + integrity sha512-ldaGiacGb2lLqcXas97k8JiZRbAnNREmcvoY2W2dvW4loVuDT9B9fU777mbV6zODpcgcHWsLL3lYbJ5Lt3y9cg== dependencies: - "@parcel/plugin" "2.8.3" - "@parcel/types" "2.8.3" - "@parcel/utils" "2.8.3" + "@parcel/plugin" "2.12.0" + "@parcel/types" "2.12.0" + "@parcel/utils" "2.12.0" posthtml "^0.16.4" -"@parcel/plugin@2.8.3": - version "2.8.3" - resolved "https://registry.yarnpkg.com/@parcel/plugin/-/plugin-2.8.3.tgz#7bb30a5775eaa6473c27f002a0a3ee7308d6d669" - integrity sha512-jZ6mnsS4D9X9GaNnvrixDQwlUQJCohDX2hGyM0U0bY2NWU8Km97SjtoCpWjq+XBCx/gpC4g58+fk9VQeZq2vlw== +"@parcel/packager-wasm@2.12.0": + version "2.12.0" + resolved "https://registry.yarnpkg.com/@parcel/packager-wasm/-/packager-wasm-2.12.0.tgz#39dbd91e7bf68456dbc9d19a412017e2b513736f" + integrity sha512-fYqZzIqO9fGYveeImzF8ll6KRo2LrOXfD+2Y5U3BiX/wp9wv17dz50QLDQm9hmTcKGWxK4yWqKQh+Evp/fae7A== dependencies: - "@parcel/types" "2.8.3" + "@parcel/plugin" "2.12.0" -"@parcel/reporter-cli@2.8.3": - version "2.8.3" - resolved "https://registry.yarnpkg.com/@parcel/reporter-cli/-/reporter-cli-2.8.3.tgz#12a4743b51b8fe6837f53c20e01bbf1f7336e8e4" - integrity sha512-3sJkS6tFFzgIOz3u3IpD/RsmRxvOKKiQHOTkiiqRt1l44mMDGKS7zANRnJYsQzdCsgwc9SOP30XFgJwtoVlMbw== +"@parcel/plugin@2.12.0": + version "2.12.0" + resolved "https://registry.yarnpkg.com/@parcel/plugin/-/plugin-2.12.0.tgz#3db4237e8977ef5b5378b65eaffb809d2026431a" + integrity sha512-nc/uRA8DiMoe4neBbzV6kDndh/58a4wQuGKw5oEoIwBCHUvE2W8ZFSu7ollSXUGRzfacTt4NdY8TwS73ScWZ+g== + dependencies: + "@parcel/types" "2.12.0" + +"@parcel/profiler@2.12.0": + version "2.12.0" + resolved "https://registry.yarnpkg.com/@parcel/profiler/-/profiler-2.12.0.tgz#8541ca5d27500aebc843b1de081734442e5ee054" + integrity sha512-q53fvl5LDcFYzMUtSusUBZSjQrKjMlLEBgKeQHFwkimwR1mgoseaDBDuNz0XvmzDzF1UelJ02TUKCGacU8W2qA== dependencies: - "@parcel/plugin" "2.8.3" - "@parcel/types" "2.8.3" - "@parcel/utils" "2.8.3" + "@parcel/diagnostic" "2.12.0" + "@parcel/events" "2.12.0" + chrome-trace-event "^1.0.2" + +"@parcel/reporter-cli@2.12.0": + version "2.12.0" + resolved "https://registry.yarnpkg.com/@parcel/reporter-cli/-/reporter-cli-2.12.0.tgz#e067b4eeca49c7120d3455d99810bed5bc825920" + integrity sha512-TqKsH4GVOLPSCanZ6tcTPj+rdVHERnt5y4bwTM82cajM21bCX1Ruwp8xOKU+03091oV2pv5ieB18pJyRF7IpIw== + dependencies: + "@parcel/plugin" "2.12.0" + "@parcel/types" "2.12.0" + "@parcel/utils" "2.12.0" chalk "^4.1.0" term-size "^2.2.1" -"@parcel/reporter-dev-server@2.8.3": - version "2.8.3" - resolved "https://registry.yarnpkg.com/@parcel/reporter-dev-server/-/reporter-dev-server-2.8.3.tgz#a0daa5cc015642684cea561f4e0e7116bbffdc1c" - integrity sha512-Y8C8hzgzTd13IoWTj+COYXEyCkXfmVJs3//GDBsH22pbtSFMuzAZd+8J9qsCo0EWpiDow7V9f1LischvEh3FbQ== +"@parcel/reporter-dev-server@2.12.0": + version "2.12.0" + resolved "https://registry.yarnpkg.com/@parcel/reporter-dev-server/-/reporter-dev-server-2.12.0.tgz#bd4c9e3d6dc8d8b178564a336f46b4f70acf3e79" + integrity sha512-tIcDqRvAPAttRlTV28dHcbWT5K2r/MBFks7nM4nrEDHWtnrCwimkDmZTc1kD8QOCCjGVwRHcQybpHvxfwol6GA== dependencies: - "@parcel/plugin" "2.8.3" - "@parcel/utils" "2.8.3" + "@parcel/plugin" "2.12.0" + "@parcel/utils" "2.12.0" -"@parcel/resolver-default@2.8.3": - version "2.8.3" - resolved "https://registry.yarnpkg.com/@parcel/resolver-default/-/resolver-default-2.8.3.tgz#5ae41e537ae4a793c1abb47f094482b9e2ac3535" - integrity sha512-k0B5M/PJ+3rFbNj4xZSBr6d6HVIe6DH/P3dClLcgBYSXAvElNDfXgtIimbjCyItFkW9/BfcgOVKEEIZOeySH/A== +"@parcel/reporter-tracer@2.12.0": + version "2.12.0" + resolved "https://registry.yarnpkg.com/@parcel/reporter-tracer/-/reporter-tracer-2.12.0.tgz#680e8be677277318c656c1825dbe98a8bfb64e16" + integrity sha512-g8rlu9GxB8Ut/F8WGx4zidIPQ4pcYFjU9bZO+fyRIPrSUFH2bKijCnbZcr4ntqzDGx74hwD6cCG4DBoleq2UlQ== dependencies: - "@parcel/node-resolver-core" "2.8.3" - "@parcel/plugin" "2.8.3" + "@parcel/plugin" "2.12.0" + "@parcel/utils" "2.12.0" + chrome-trace-event "^1.0.3" + nullthrows "^1.1.1" -"@parcel/runtime-browser-hmr@2.8.3": - version "2.8.3" - resolved "https://registry.yarnpkg.com/@parcel/runtime-browser-hmr/-/runtime-browser-hmr-2.8.3.tgz#1fa74e1fbd1030b0a920c58afa3a9eb7dc4bcd1e" - integrity sha512-2O1PYi2j/Q0lTyGNV3JdBYwg4rKo6TEVFlYGdd5wCYU9ZIN9RRuoCnWWH2qCPj3pjIVtBeppYxzfVjPEHINWVg== +"@parcel/resolver-default@2.12.0": + version "2.12.0" + resolved "https://registry.yarnpkg.com/@parcel/resolver-default/-/resolver-default-2.12.0.tgz#005b6bc01de9d166a97d7ef30daf339973c4898a" + integrity sha512-uuhbajTax37TwCxu7V98JtRLiT6hzE4VYSu5B7Qkauy14/WFt2dz6GOUXPgVsED569/hkxebPx3KCMtZW6cHHA== dependencies: - "@parcel/plugin" "2.8.3" - "@parcel/utils" "2.8.3" + "@parcel/node-resolver-core" "3.3.0" + "@parcel/plugin" "2.12.0" -"@parcel/runtime-js@2.8.3": - version "2.8.3" - resolved "https://registry.yarnpkg.com/@parcel/runtime-js/-/runtime-js-2.8.3.tgz#0baa4c8fbf77eabce05d01ccc186614968ffc0cd" - integrity sha512-IRja0vNKwvMtPgIqkBQh0QtRn0XcxNC8HU1jrgWGRckzu10qJWO+5ULgtOeR4pv9krffmMPqywGXw6l/gvJKYQ== +"@parcel/runtime-browser-hmr@2.12.0": + version "2.12.0" + resolved "https://registry.yarnpkg.com/@parcel/runtime-browser-hmr/-/runtime-browser-hmr-2.12.0.tgz#9d045785b83760e305c9efd3d6300a9ff73bcfaf" + integrity sha512-4ZLp2FWyD32r0GlTulO3+jxgsA3oO1P1b5oO2IWuWilfhcJH5LTiazpL5YdusUjtNn9PGN6QLAWfxmzRIfM+Ow== + dependencies: + "@parcel/plugin" "2.12.0" + "@parcel/utils" "2.12.0" + +"@parcel/runtime-js@2.12.0": + version "2.12.0" + resolved "https://registry.yarnpkg.com/@parcel/runtime-js/-/runtime-js-2.12.0.tgz#da6f7da041cb157556822ad60fefcdbc790dda9c" + integrity sha512-sBerP32Z1crX5PfLNGDSXSdqzlllM++GVnVQVeM7DgMKS8JIFG3VLi28YkX+dYYGtPypm01JoIHCkvwiZEcQJg== dependencies: - "@parcel/plugin" "2.8.3" - "@parcel/utils" "2.8.3" + "@parcel/diagnostic" "2.12.0" + "@parcel/plugin" "2.12.0" + "@parcel/utils" "2.12.0" nullthrows "^1.1.1" -"@parcel/runtime-react-refresh@2.8.3": - version "2.8.3" - resolved "https://registry.yarnpkg.com/@parcel/runtime-react-refresh/-/runtime-react-refresh-2.8.3.tgz#381a942fb81e8f5ac6c7e0ee1b91dbf34763c3f8" - integrity sha512-2v/qFKp00MfG0234OdOgQNAo6TLENpFYZMbVbAsPMY9ITiqG73MrEsrGXVoGbYiGTMB/Toer/lSWlJxtacOCuA== +"@parcel/runtime-react-refresh@2.12.0": + version "2.12.0" + resolved "https://registry.yarnpkg.com/@parcel/runtime-react-refresh/-/runtime-react-refresh-2.12.0.tgz#58c17552766492ec2005ffedfa04ecb29386dd8b" + integrity sha512-SCHkcczJIDFTFdLTzrHTkQ0aTrX3xH6jrA4UsCBL6ji61+w+ohy4jEEe9qCgJVXhnJfGLE43HNXek+0MStX+Mw== dependencies: - "@parcel/plugin" "2.8.3" - "@parcel/utils" "2.8.3" + "@parcel/plugin" "2.12.0" + "@parcel/utils" "2.12.0" react-error-overlay "6.0.9" react-refresh "^0.9.0" -"@parcel/runtime-service-worker@2.8.3": - version "2.8.3" - resolved "https://registry.yarnpkg.com/@parcel/runtime-service-worker/-/runtime-service-worker-2.8.3.tgz#54d92da9ff1dfbd27db0e84164a22fa59e99b348" - integrity sha512-/Skkw+EeRiwzOJso5fQtK8c9b452uWLNhQH1ISTodbmlcyB4YalAiSsyHCtMYD0c3/t5Sx4ZS7vxBAtQd0RvOw== +"@parcel/runtime-service-worker@2.12.0": + version "2.12.0" + resolved "https://registry.yarnpkg.com/@parcel/runtime-service-worker/-/runtime-service-worker-2.12.0.tgz#67ee1e6dbc5441651fed04ecb2bd7ebe1e362679" + integrity sha512-BXuMBsfiwpIEnssn+jqfC3jkgbS8oxeo3C7xhSQsuSv+AF2FwY3O3AO1c1RBskEW3XrBLNINOJujroNw80VTKA== dependencies: - "@parcel/plugin" "2.8.3" - "@parcel/utils" "2.8.3" + "@parcel/plugin" "2.12.0" + "@parcel/utils" "2.12.0" nullthrows "^1.1.1" +"@parcel/rust@2.12.0": + version "2.12.0" + resolved "https://registry.yarnpkg.com/@parcel/rust/-/rust-2.12.0.tgz#135df4dd8c63d97720379777c5bb4a2680a201cd" + integrity sha512-005cldMdFZFDPOjbDVEXcINQ3wT4vrxvSavRWI3Az0e3E18exO/x/mW9f648KtXugOXMAqCEqhFHcXECL9nmMw== + "@parcel/source-map@^2.1.1": version "2.1.1" resolved "https://registry.yarnpkg.com/@parcel/source-map/-/source-map-2.1.1.tgz#fb193b82dba6dd62cc7a76b326f57bb35000a782" @@ -3491,165 +4936,235 @@ dependencies: detect-libc "^1.0.3" -"@parcel/transformer-babel@2.8.3": - version "2.8.3" - resolved "https://registry.yarnpkg.com/@parcel/transformer-babel/-/transformer-babel-2.8.3.tgz#286bc6cb9afe4c0259f0b28e0f2f47322a24b130" - integrity sha512-L6lExfpvvC7T/g3pxf3CIJRouQl+sgrSzuWQ0fD4PemUDHvHchSP4SNUVnd6gOytF3Y1KpnEZIunQGi5xVqQCQ== +"@parcel/transformer-babel@2.12.0": + version "2.12.0" + resolved "https://registry.yarnpkg.com/@parcel/transformer-babel/-/transformer-babel-2.12.0.tgz#29be68f2fad4688b33ef3f03ef2b8c3e9928b87f" + integrity sha512-zQaBfOnf/l8rPxYGnsk/ufh/0EuqvmnxafjBIpKZ//j6rGylw5JCqXSb1QvvAqRYruKeccxGv7+HrxpqKU6V4A== dependencies: - "@parcel/diagnostic" "2.8.3" - "@parcel/plugin" "2.8.3" + "@parcel/diagnostic" "2.12.0" + "@parcel/plugin" "2.12.0" "@parcel/source-map" "^2.1.1" - "@parcel/utils" "2.8.3" + "@parcel/utils" "2.12.0" browserslist "^4.6.6" json5 "^2.2.0" nullthrows "^1.1.1" - semver "^5.7.0" + semver "^7.5.2" -"@parcel/transformer-css@2.8.3": - version "2.8.3" - resolved "https://registry.yarnpkg.com/@parcel/transformer-css/-/transformer-css-2.8.3.tgz#d6c44100204e73841ad8e0f90472172ea8b9120c" - integrity sha512-xTqFwlSXtnaYen9ivAgz+xPW7yRl/u4QxtnDyDpz5dr8gSeOpQYRcjkd4RsYzKsWzZcGtB5EofEk8ayUbWKEUg== +"@parcel/transformer-css@2.12.0": + version "2.12.0" + resolved "https://registry.yarnpkg.com/@parcel/transformer-css/-/transformer-css-2.12.0.tgz#218a98948c9410c17287183d80ca9bd9943cc9e9" + integrity sha512-vXhOqoAlQGATYyQ433Z1DXKmiKmzOAUmKysbYH3FD+LKEKLMEl/pA14goqp00TW+A/EjtSKKyeMyHlMIIUqj4Q== dependencies: - "@parcel/diagnostic" "2.8.3" - "@parcel/plugin" "2.8.3" + "@parcel/diagnostic" "2.12.0" + "@parcel/plugin" "2.12.0" "@parcel/source-map" "^2.1.1" - "@parcel/utils" "2.8.3" + "@parcel/utils" "2.12.0" browserslist "^4.6.6" - lightningcss "^1.16.1" + lightningcss "^1.22.1" nullthrows "^1.1.1" -"@parcel/transformer-html@2.8.3": - version "2.8.3" - resolved "https://registry.yarnpkg.com/@parcel/transformer-html/-/transformer-html-2.8.3.tgz#5c68b28ee6b8c7a13b8aee87f7957ad3227bd83f" - integrity sha512-kIZO3qsMYTbSnSpl9cnZog+SwL517ffWH54JeB410OSAYF1ouf4n5v9qBnALZbuCCmPwJRGs4jUtE452hxwN4g== +"@parcel/transformer-html@2.12.0": + version "2.12.0" + resolved "https://registry.yarnpkg.com/@parcel/transformer-html/-/transformer-html-2.12.0.tgz#8681b089e2b20c5fda1c966cefb8de4d8fb2ce80" + integrity sha512-5jW4dFFBlYBvIQk4nrH62rfA/G/KzVzEDa6S+Nne0xXhglLjkm64Ci9b/d4tKZfuGWUbpm2ASAq8skti/nfpXw== dependencies: - "@parcel/diagnostic" "2.8.3" - "@parcel/hash" "2.8.3" - "@parcel/plugin" "2.8.3" + "@parcel/diagnostic" "2.12.0" + "@parcel/plugin" "2.12.0" + "@parcel/rust" "2.12.0" nullthrows "^1.1.1" posthtml "^0.16.5" posthtml-parser "^0.10.1" posthtml-render "^3.0.0" - semver "^5.7.1" + semver "^7.5.2" srcset "4" -"@parcel/transformer-image@2.8.3": - version "2.8.3" - resolved "https://registry.yarnpkg.com/@parcel/transformer-image/-/transformer-image-2.8.3.tgz#73805b2bfc3c8919d7737544e5f8be39e3f303fe" - integrity sha512-cO4uptcCGTi5H6bvTrAWEFUsTNhA4kCo8BSvRSCHA2sf/4C5tGQPHt3JhdO0GQLPwZRCh/R41EkJs5HZ8A8DAg== +"@parcel/transformer-image@2.12.0": + version "2.12.0" + resolved "https://registry.yarnpkg.com/@parcel/transformer-image/-/transformer-image-2.12.0.tgz#8ba2ca3b5d88287bf38c8244b2714158c9d34b2e" + integrity sha512-8hXrGm2IRII49R7lZ0RpmNk27EhcsH+uNKsvxuMpXPuEnWgC/ha/IrjaI29xCng1uGur74bJF43NUSQhR4aTdw== dependencies: - "@parcel/plugin" "2.8.3" - "@parcel/utils" "2.8.3" - "@parcel/workers" "2.8.3" + "@parcel/plugin" "2.12.0" + "@parcel/utils" "2.12.0" + "@parcel/workers" "2.12.0" nullthrows "^1.1.1" -"@parcel/transformer-js@2.8.3": - version "2.8.3" - resolved "https://registry.yarnpkg.com/@parcel/transformer-js/-/transformer-js-2.8.3.tgz#fe400df428394d1e7fe5afb6dea5c7c858e44f03" - integrity sha512-9Qd6bib+sWRcpovvzvxwy/PdFrLUXGfmSW9XcVVG8pvgXsZPFaNjnNT8stzGQj1pQiougCoxMY4aTM5p1lGHEQ== +"@parcel/transformer-js@2.12.0": + version "2.12.0" + resolved "https://registry.yarnpkg.com/@parcel/transformer-js/-/transformer-js-2.12.0.tgz#e6bf0c312f78603faf98ce546086898506e3811f" + integrity sha512-OSZpOu+FGDbC/xivu24v092D9w6EGytB3vidwbdiJ2FaPgfV7rxS0WIUjH4I0OcvHAcitArRXL0a3+HrNTdQQw== dependencies: - "@parcel/diagnostic" "2.8.3" - "@parcel/plugin" "2.8.3" + "@parcel/diagnostic" "2.12.0" + "@parcel/plugin" "2.12.0" + "@parcel/rust" "2.12.0" "@parcel/source-map" "^2.1.1" - "@parcel/utils" "2.8.3" - "@parcel/workers" "2.8.3" - "@swc/helpers" "^0.4.12" + "@parcel/utils" "2.12.0" + "@parcel/workers" "2.12.0" + "@swc/helpers" "^0.5.0" browserslist "^4.6.6" - detect-libc "^1.0.3" nullthrows "^1.1.1" regenerator-runtime "^0.13.7" - semver "^5.7.1" + semver "^7.5.2" -"@parcel/transformer-json@2.8.3": - version "2.8.3" - resolved "https://registry.yarnpkg.com/@parcel/transformer-json/-/transformer-json-2.8.3.tgz#25deb3a5138cc70a83269fc5d39d564609354d36" - integrity sha512-B7LmVq5Q7bZO4ERb6NHtRuUKWGysEeaj9H4zelnyBv+wLgpo4f5FCxSE1/rTNmP9u1qHvQ3scGdK6EdSSokGPg== +"@parcel/transformer-json@2.12.0": + version "2.12.0" + resolved "https://registry.yarnpkg.com/@parcel/transformer-json/-/transformer-json-2.12.0.tgz#16cc0454e4862350b605a5e2009d050c676c6ea5" + integrity sha512-Utv64GLRCQILK5r0KFs4o7I41ixMPllwOLOhkdjJKvf1hZmN6WqfOmB1YLbWS/y5Zb/iB52DU2pWZm96vLFQZQ== dependencies: - "@parcel/plugin" "2.8.3" + "@parcel/plugin" "2.12.0" json5 "^2.2.0" -"@parcel/transformer-postcss@2.8.3": - version "2.8.3" - resolved "https://registry.yarnpkg.com/@parcel/transformer-postcss/-/transformer-postcss-2.8.3.tgz#df4fdc1c90893823445f2a8eb8e2bdd0349ccc58" - integrity sha512-e8luB/poIlz6jBsD1Izms+6ElbyzuoFVa4lFVLZnTAChI3UxPdt9p/uTsIO46HyBps/Bk8ocvt3J4YF84jzmvg== +"@parcel/transformer-postcss@2.12.0": + version "2.12.0" + resolved "https://registry.yarnpkg.com/@parcel/transformer-postcss/-/transformer-postcss-2.12.0.tgz#195f4fb86f36f42b5de82076ea36b9d850f4832e" + integrity sha512-FZqn+oUtiLfPOn67EZxPpBkfdFiTnF4iwiXPqvst3XI8H+iC+yNgzmtJkunOOuylpYY6NOU5jT8d7saqWSDv2Q== dependencies: - "@parcel/diagnostic" "2.8.3" - "@parcel/hash" "2.8.3" - "@parcel/plugin" "2.8.3" - "@parcel/utils" "2.8.3" + "@parcel/diagnostic" "2.12.0" + "@parcel/plugin" "2.12.0" + "@parcel/rust" "2.12.0" + "@parcel/utils" "2.12.0" clone "^2.1.1" nullthrows "^1.1.1" postcss-value-parser "^4.2.0" - semver "^5.7.1" + semver "^7.5.2" -"@parcel/transformer-posthtml@2.8.3": - version "2.8.3" - resolved "https://registry.yarnpkg.com/@parcel/transformer-posthtml/-/transformer-posthtml-2.8.3.tgz#7c3912a5a631cb26485f6464e0d6eeabb6f1e718" - integrity sha512-pkzf9Smyeaw4uaRLsT41RGrPLT5Aip8ZPcntawAfIo+KivBQUV0erY1IvHYjyfFzq1ld/Fo2Ith9He6mxpPifA== +"@parcel/transformer-posthtml@2.12.0": + version "2.12.0" + resolved "https://registry.yarnpkg.com/@parcel/transformer-posthtml/-/transformer-posthtml-2.12.0.tgz#a906c26278e03455f6186b7dbd9f5b63eaa26948" + integrity sha512-z6Z7rav/pcaWdeD+2sDUcd0mmNZRUvtHaUGa50Y2mr+poxrKilpsnFMSiWBT+oOqPt7j71jzDvrdnAF4XkCljg== dependencies: - "@parcel/plugin" "2.8.3" - "@parcel/utils" "2.8.3" + "@parcel/plugin" "2.12.0" + "@parcel/utils" "2.12.0" nullthrows "^1.1.1" posthtml "^0.16.5" posthtml-parser "^0.10.1" posthtml-render "^3.0.0" - semver "^5.7.1" + semver "^7.5.2" -"@parcel/transformer-raw@2.8.3": - version "2.8.3" - resolved "https://registry.yarnpkg.com/@parcel/transformer-raw/-/transformer-raw-2.8.3.tgz#3a22213fe18a5f83fd78889cb49f06e059cfead7" - integrity sha512-G+5cXnd2/1O3nV/pgRxVKZY/HcGSseuhAe71gQdSQftb8uJEURyUHoQ9Eh0JUD3MgWh9V+nIKoyFEZdf9T0sUQ== +"@parcel/transformer-raw@2.12.0": + version "2.12.0" + resolved "https://registry.yarnpkg.com/@parcel/transformer-raw/-/transformer-raw-2.12.0.tgz#1ee7e02214f777cf3a5bf53580ee4dadfaf8a44c" + integrity sha512-Ht1fQvXxix0NncdnmnXZsa6hra20RXYh1VqhBYZLsDfkvGGFnXIgO03Jqn4Z8MkKoa0tiNbDhpKIeTjyclbBxQ== dependencies: - "@parcel/plugin" "2.8.3" + "@parcel/plugin" "2.12.0" -"@parcel/transformer-react-refresh-wrap@2.8.3": - version "2.8.3" - resolved "https://registry.yarnpkg.com/@parcel/transformer-react-refresh-wrap/-/transformer-react-refresh-wrap-2.8.3.tgz#8b0392638405dd470a886002229f7889d5464822" - integrity sha512-q8AAoEvBnCf/nPvgOwFwKZfEl/thwq7c2duxXkhl+tTLDRN2vGmyz4355IxCkavSX+pLWSQ5MexklSEeMkgthg== +"@parcel/transformer-react-refresh-wrap@2.12.0": + version "2.12.0" + resolved "https://registry.yarnpkg.com/@parcel/transformer-react-refresh-wrap/-/transformer-react-refresh-wrap-2.12.0.tgz#cf079353126f2bb820209736a75f868d0df58d92" + integrity sha512-GE8gmP2AZtkpBIV5vSCVhewgOFRhqwdM5Q9jNPOY5PKcM3/Ff0qCqDiTzzGLhk0/VMBrdjssrfZkVx6S/lHdJw== dependencies: - "@parcel/plugin" "2.8.3" - "@parcel/utils" "2.8.3" + "@parcel/plugin" "2.12.0" + "@parcel/utils" "2.12.0" react-refresh "^0.9.0" -"@parcel/transformer-svg@2.8.3": - version "2.8.3" - resolved "https://registry.yarnpkg.com/@parcel/transformer-svg/-/transformer-svg-2.8.3.tgz#4df959cba4ebf45d7aaddd540f752e6e84df38b2" - integrity sha512-3Zr/gBzxi1ZH1fftH/+KsZU7w5GqkmxlB0ZM8ovS5E/Pl1lq1t0xvGJue9m2VuQqP8Mxfpl5qLFmsKlhaZdMIQ== +"@parcel/transformer-svg@2.12.0": + version "2.12.0" + resolved "https://registry.yarnpkg.com/@parcel/transformer-svg/-/transformer-svg-2.12.0.tgz#0281e89bf0f438ec161c19b59a8a8978434a3621" + integrity sha512-cZJqGRJ4JNdYcb+vj94J7PdOuTnwyy45dM9xqbIMH+HSiiIkfrMsdEwYft0GTyFTdsnf+hdHn3tau7Qa5hhX+A== dependencies: - "@parcel/diagnostic" "2.8.3" - "@parcel/hash" "2.8.3" - "@parcel/plugin" "2.8.3" + "@parcel/diagnostic" "2.12.0" + "@parcel/plugin" "2.12.0" + "@parcel/rust" "2.12.0" nullthrows "^1.1.1" posthtml "^0.16.5" posthtml-parser "^0.10.1" posthtml-render "^3.0.0" - semver "^5.7.1" + semver "^7.5.2" -"@parcel/types@2.8.3": - version "2.8.3" - resolved "https://registry.yarnpkg.com/@parcel/types/-/types-2.8.3.tgz#3306bc5391b6913bd619914894b8cd84a24b30fa" - integrity sha512-FECA1FB7+0UpITKU0D6TgGBpGxYpVSMNEENZbSJxFSajNy3wrko+zwBKQmFOLOiPcEtnGikxNs+jkFWbPlUAtw== +"@parcel/types@2.12.0": + version "2.12.0" + resolved "https://registry.yarnpkg.com/@parcel/types/-/types-2.12.0.tgz#caf0af00ee0c7228b350eca5f4d3a5b85ce457ad" + integrity sha512-8zAFiYNCwNTQcglIObyNwKfRYQK5ELlL13GuBOrSMxueUiI5ylgsGbTS1N7J3dAGZixHO8KhHGv5a71FILn9rQ== dependencies: - "@parcel/cache" "2.8.3" - "@parcel/diagnostic" "2.8.3" - "@parcel/fs" "2.8.3" - "@parcel/package-manager" "2.8.3" + "@parcel/cache" "2.12.0" + "@parcel/diagnostic" "2.12.0" + "@parcel/fs" "2.12.0" + "@parcel/package-manager" "2.12.0" "@parcel/source-map" "^2.1.1" - "@parcel/workers" "2.8.3" + "@parcel/workers" "2.12.0" utility-types "^3.10.0" -"@parcel/utils@2.8.3": - version "2.8.3" - resolved "https://registry.yarnpkg.com/@parcel/utils/-/utils-2.8.3.tgz#0d56c9e8e22c119590a5e044a0e01031965da40e" - integrity sha512-IhVrmNiJ+LOKHcCivG5dnuLGjhPYxQ/IzbnF2DKNQXWBTsYlHkJZpmz7THoeLtLliGmSOZ3ZCsbR8/tJJKmxjA== - dependencies: - "@parcel/codeframe" "2.8.3" - "@parcel/diagnostic" "2.8.3" - "@parcel/hash" "2.8.3" - "@parcel/logger" "2.8.3" - "@parcel/markdown-ansi" "2.8.3" +"@parcel/utils@2.12.0": + version "2.12.0" + resolved "https://registry.yarnpkg.com/@parcel/utils/-/utils-2.12.0.tgz#ac900726e7cb12a9e6392081fa05b756183f65fd" + integrity sha512-z1JhLuZ8QmDaYoEIuUCVZlhcFrS7LMfHrb2OCRui5SQFntRWBH2fNM6H/fXXUkT9SkxcuFP2DUA6/m4+Gkz72g== + dependencies: + "@parcel/codeframe" "2.12.0" + "@parcel/diagnostic" "2.12.0" + "@parcel/logger" "2.12.0" + "@parcel/markdown-ansi" "2.12.0" + "@parcel/rust" "2.12.0" "@parcel/source-map" "^2.1.1" chalk "^4.1.0" + nullthrows "^1.1.1" + +"@parcel/watcher-android-arm64@2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.3.0.tgz#d82e74bb564ebd4d8a88791d273a3d2bd61e27ab" + integrity sha512-f4o9eA3dgk0XRT3XhB0UWpWpLnKgrh1IwNJKJ7UJek7eTYccQ8LR7XUWFKqw6aEq5KUNlCcGvSzKqSX/vtWVVA== + +"@parcel/watcher-darwin-arm64@2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.3.0.tgz#c9cd03f8f233d512fcfc873d5b4e23f1569a82ad" + integrity sha512-mKY+oijI4ahBMc/GygVGvEdOq0L4DxhYgwQqYAz/7yPzuGi79oXrZG52WdpGA1wLBPrYb0T8uBaGFo7I6rvSKw== + +"@parcel/watcher-darwin-x64@2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.3.0.tgz#83c902994a2a49b9e1ab5050dba24876fdc2c219" + integrity sha512-20oBj8LcEOnLE3mgpy6zuOq8AplPu9NcSSSfyVKgfOhNAc4eF4ob3ldj0xWjGGbOF7Dcy1Tvm6ytvgdjlfUeow== + +"@parcel/watcher-freebsd-x64@2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.3.0.tgz#7a0f4593a887e2752b706aff2dae509aef430cf6" + integrity sha512-7LftKlaHunueAEiojhCn+Ef2CTXWsLgTl4hq0pkhkTBFI3ssj2bJXmH2L67mKpiAD5dz66JYk4zS66qzdnIOgw== + +"@parcel/watcher-linux-arm-glibc@2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.3.0.tgz#3fc90c3ebe67de3648ed2f138068722f9b1d47da" + integrity sha512-1apPw5cD2xBv1XIHPUlq0cO6iAaEUQ3BcY0ysSyD9Kuyw4MoWm1DV+W9mneWI+1g6OeP6dhikiFE6BlU+AToTQ== + +"@parcel/watcher-linux-arm64-glibc@2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.3.0.tgz#f7bbbf2497d85fd11e4c9e9c26ace8f10ea9bcbc" + integrity sha512-mQ0gBSQEiq1k/MMkgcSB0Ic47UORZBmWoAWlMrTW6nbAGoLZP+h7AtUM7H3oDu34TBFFvjy4JCGP43JlylkTQA== + +"@parcel/watcher-linux-arm64-musl@2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.3.0.tgz#de131a9fcbe1fa0854e9cbf4c55bed3b35bcff43" + integrity sha512-LXZAExpepJew0Gp8ZkJ+xDZaTQjLHv48h0p0Vw2VMFQ8A+RKrAvpFuPVCVwKJCr5SE+zvaG+Etg56qXvTDIedw== + +"@parcel/watcher-linux-x64-glibc@2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.3.0.tgz#193dd1c798003cdb5a1e59470ff26300f418a943" + integrity sha512-P7Wo91lKSeSgMTtG7CnBS6WrA5otr1K7shhSjKHNePVmfBHDoAOHYRXgUmhiNfbcGk0uMCHVcdbfxtuiZCHVow== + +"@parcel/watcher-linux-x64-musl@2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.3.0.tgz#6dbdb86d96e955ab0fe4a4b60734ec0025a689dd" + integrity sha512-+kiRE1JIq8QdxzwoYY+wzBs9YbJ34guBweTK8nlzLKimn5EQ2b2FSC+tAOpq302BuIMjyuUGvBiUhEcLIGMQ5g== + +"@parcel/watcher-wasm@2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@parcel/watcher-wasm/-/watcher-wasm-2.3.0.tgz#73b66c6fbd2a3326ae86a1ec77eab7139d0dd725" + integrity sha512-ejBAX8H0ZGsD8lSICDNyMbSEtPMWgDL0WFCt/0z7hyf5v8Imz4rAM8xY379mBsECkq/Wdqa5WEDLqtjZ+6NxfA== + dependencies: + is-glob "^4.0.3" + micromatch "^4.0.5" + napi-wasm "^1.1.0" + +"@parcel/watcher-win32-arm64@2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.3.0.tgz#59da26a431da946e6c74fa6b0f30b120ea6650b6" + integrity sha512-35gXCnaz1AqIXpG42evcoP2+sNL62gZTMZne3IackM+6QlfMcJLy3DrjuL6Iks7Czpd3j4xRBzez3ADCj1l7Aw== + +"@parcel/watcher-win32-ia32@2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.3.0.tgz#3ee6a18b08929cd3b788e8cc9547fd9a540c013a" + integrity sha512-FJS/IBQHhRpZ6PiCjFt1UAcPr0YmCLHRbTc00IBTrelEjlmmgIVLeOx4MSXzx2HFEy5Jo5YdhGpxCuqCyDJ5ow== + +"@parcel/watcher-win32-x64@2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.3.0.tgz#14e7246289861acc589fd608de39fe5d8b4bb0a7" + integrity sha512-dLx+0XRdMnVI62kU3wbXvbIRhLck4aE28bIGKbRGS7BJNt54IIj9+c/Dkqb+7DJEbHUZAX1bwaoM8PqVlHJmCA== "@parcel/watcher@2.0.4": version "2.0.4" @@ -3659,47 +5174,45 @@ node-addon-api "^3.2.1" node-gyp-build "^4.3.0" -"@parcel/watcher@^2.0.7": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@parcel/watcher/-/watcher-2.1.0.tgz#5f32969362db4893922c526a842d8af7a8538545" - integrity sha512-8s8yYjd19pDSsBpbkOHnT6Z2+UJSuLQx61pCFM0s5wSRvKCEMDjd/cHY3/GI1szHIWbpXpsJdg3V6ISGGx9xDw== +"@parcel/watcher@^2.0.7", "@parcel/watcher@^2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@parcel/watcher/-/watcher-2.3.0.tgz#803517abbc3981a1a1221791d9f59dc0590d50f9" + integrity sha512-pW7QaFiL11O0BphO+bq3MgqeX/INAk9jgBldVDYjlQPO4VddoZnF22TcF9onMhnLVHuNqBJeRf+Fj7eezi/+rQ== dependencies: + detect-libc "^1.0.3" is-glob "^4.0.3" micromatch "^4.0.5" - node-addon-api "^3.2.1" - node-gyp-build "^4.3.0" - -"@parcel/workers@2.8.3": - version "2.8.3" - resolved "https://registry.yarnpkg.com/@parcel/workers/-/workers-2.8.3.tgz#255450ccf4db234082407e4ddda5fd575f08c235" - integrity sha512-+AxBnKgjqVpUHBcHLWIHcjYgKIvHIpZjN33mG5LG9XXvrZiqdWvouEzqEXlVLq5VzzVbKIQQcmsvRy138YErkg== - dependencies: - "@parcel/diagnostic" "2.8.3" - "@parcel/logger" "2.8.3" - "@parcel/types" "2.8.3" - "@parcel/utils" "2.8.3" - chrome-trace-event "^1.0.2" + node-addon-api "^7.0.0" + optionalDependencies: + "@parcel/watcher-android-arm64" "2.3.0" + "@parcel/watcher-darwin-arm64" "2.3.0" + "@parcel/watcher-darwin-x64" "2.3.0" + "@parcel/watcher-freebsd-x64" "2.3.0" + "@parcel/watcher-linux-arm-glibc" "2.3.0" + "@parcel/watcher-linux-arm64-glibc" "2.3.0" + "@parcel/watcher-linux-arm64-musl" "2.3.0" + "@parcel/watcher-linux-x64-glibc" "2.3.0" + "@parcel/watcher-linux-x64-musl" "2.3.0" + "@parcel/watcher-win32-arm64" "2.3.0" + "@parcel/watcher-win32-ia32" "2.3.0" + "@parcel/watcher-win32-x64" "2.3.0" + +"@parcel/workers@2.12.0": + version "2.12.0" + resolved "https://registry.yarnpkg.com/@parcel/workers/-/workers-2.12.0.tgz#773182b5006741102de8ae36d18a5a9e3320ebd1" + integrity sha512-zv5We5Jmb+ZWXlU6A+AufyjY4oZckkxsZ8J4dvyWL0W8IQvGO1JB4FGeryyttzQv3RM3OxcN/BpTGPiDG6keBw== + dependencies: + "@parcel/diagnostic" "2.12.0" + "@parcel/logger" "2.12.0" + "@parcel/profiler" "2.12.0" + "@parcel/types" "2.12.0" + "@parcel/utils" "2.12.0" nullthrows "^1.1.1" -"@pedrouid/environment@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@pedrouid/environment/-/environment-1.0.1.tgz#858f0f8a057340e0b250398b75ead77d6f4342ec" - integrity sha512-HaW78NszGzRZd9SeoI3JD11JqY+lubnaOx7Pewj5pfjqWXOEATpeKIFb9Z4t2WBUK2iryiXX3lzWwmYWgUL0Ug== - -"@pmmmwh/react-refresh-webpack-plugin@^0.5.3": - version "0.5.10" - resolved "https://registry.yarnpkg.com/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.10.tgz#2eba163b8e7dbabb4ce3609ab5e32ab63dda3ef8" - integrity sha512-j0Ya0hCFZPd4x40qLzbhGsh9TMtdb+CJQiso+WxLOPNasohq9cc5SNUcwsZaRH6++Xh91Xkm/xHCkuIiIu0LUA== - dependencies: - ansi-html-community "^0.0.8" - common-path-prefix "^3.0.0" - core-js-pure "^3.23.3" - error-stack-parser "^2.0.6" - find-up "^5.0.0" - html-entities "^2.1.0" - loader-utils "^2.0.4" - schema-utils "^3.0.0" - source-map "^0.7.3" +"@pkgjs/parseargs@^0.11.0": + version "0.11.0" + resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" + integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== "@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2": version "1.1.2" @@ -3754,293 +5267,361 @@ resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570" integrity sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw== -"@radix-ui/primitive@1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@radix-ui/primitive/-/primitive-1.0.0.tgz#e1d8ef30b10ea10e69c76e896f608d9276352253" - integrity sha512-3e7rn8FDMin4CgeL7Z/49smCA3rFYY3Ha2rUQ7HRWFadS5iCRw08ZgVT1LaNTCNqgvrUiyczLflrVrF0SRQtNA== +"@radix-ui/number@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@radix-ui/number/-/number-1.0.1.tgz#644161a3557f46ed38a042acf4a770e826021674" + integrity sha512-T5gIdVO2mmPW3NNhjNgEP3cqMXjXL9UbO0BzWcXfvdBs+BohbQxvd/K5hSVKmn9/lbTdsQVKbUcP5WLCwvUbBg== dependencies: "@babel/runtime" "^7.13.10" -"@radix-ui/react-arrow@1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@radix-ui/react-arrow/-/react-arrow-1.0.2.tgz#93b0ff95f65e2264a05b14ef1031ec798243dd6f" - integrity sha512-fqYwhhI9IarZ0ll2cUSfKuXHlJK0qE4AfnRrPBbRwEH/4mGQn04/QFGomLi8TXWIdv9WJk//KgGm+aDxVIr1wA== +"@radix-ui/primitive@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@radix-ui/primitive/-/primitive-1.0.1.tgz#e46f9958b35d10e9f6dc71c497305c22e3e55dbd" + integrity sha512-yQ8oGX2GVsEYMWGxcovu1uGWPCxV5BFfeeYxqPmuAzUyLT9qmaMXSAhXpb0WrspIeqYzdJpkh2vHModJPgRIaw== + dependencies: + "@babel/runtime" "^7.13.10" + +"@radix-ui/react-arrow@1.0.3": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@radix-ui/react-arrow/-/react-arrow-1.0.3.tgz#c24f7968996ed934d57fe6cde5d6ec7266e1d25d" + integrity sha512-wSP+pHsB/jQRaL6voubsQ/ZlrGBHHrOjmBnr19hxYgtS0WvAFwZhK2WP/YY5yF9uKECCEEDGxuLxq1NBK51wFA== dependencies: "@babel/runtime" "^7.13.10" - "@radix-ui/react-primitive" "1.0.2" + "@radix-ui/react-primitive" "1.0.3" "@radix-ui/react-checkbox@^1.0.1": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@radix-ui/react-checkbox/-/react-checkbox-1.0.4.tgz#98f22c38d5010dd6df4c5744cac74087e3275f4b" + integrity sha512-CBuGQa52aAYnADZVt/KBQzXrwx6TqnlwtcIPGtVt5JkkzQwMOLJjPukimhfKEr4GQNd43C+djUh5Ikopj8pSLg== + dependencies: + "@babel/runtime" "^7.13.10" + "@radix-ui/primitive" "1.0.1" + "@radix-ui/react-compose-refs" "1.0.1" + "@radix-ui/react-context" "1.0.1" + "@radix-ui/react-presence" "1.0.1" + "@radix-ui/react-primitive" "1.0.3" + "@radix-ui/react-use-controllable-state" "1.0.1" + "@radix-ui/react-use-previous" "1.0.1" + "@radix-ui/react-use-size" "1.0.1" + +"@radix-ui/react-collapsible@^1.0.3": version "1.0.3" - resolved "https://registry.yarnpkg.com/@radix-ui/react-checkbox/-/react-checkbox-1.0.3.tgz#bab1916c04b9f66e944e7168be2217cb74c7b94e" - integrity sha512-55B8/vKzTuzxllH5sGJO4zaBf9gYpJuJRRzaOKm+0oAefRnMvbf+Kgww7IOANVN0w3z7agFJgtnXaZl8Uj95AA== + resolved "https://registry.yarnpkg.com/@radix-ui/react-collapsible/-/react-collapsible-1.0.3.tgz#df0e22e7a025439f13f62d4e4a9e92c4a0df5b81" + integrity sha512-UBmVDkmR6IvDsloHVN+3rtx4Mi5TFvylYXpluuv0f37dtaz3H99bp8No0LGXRigVpl3UAT4l9j6bIchh42S/Gg== dependencies: "@babel/runtime" "^7.13.10" - "@radix-ui/primitive" "1.0.0" - "@radix-ui/react-compose-refs" "1.0.0" - "@radix-ui/react-context" "1.0.0" - "@radix-ui/react-presence" "1.0.0" - "@radix-ui/react-primitive" "1.0.2" - "@radix-ui/react-use-controllable-state" "1.0.0" - "@radix-ui/react-use-previous" "1.0.0" - "@radix-ui/react-use-size" "1.0.0" - -"@radix-ui/react-collection@1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@radix-ui/react-collection/-/react-collection-1.0.2.tgz#d50da00bfa2ac14585319efdbbb081d4c5a29a97" - integrity sha512-s8WdQQ6wNXpaxdZ308KSr8fEWGrg4un8i4r/w7fhiS4ElRNjk5rRcl0/C6TANG2LvLOGIxtzo/jAg6Qf73TEBw== + "@radix-ui/primitive" "1.0.1" + "@radix-ui/react-compose-refs" "1.0.1" + "@radix-ui/react-context" "1.0.1" + "@radix-ui/react-id" "1.0.1" + "@radix-ui/react-presence" "1.0.1" + "@radix-ui/react-primitive" "1.0.3" + "@radix-ui/react-use-controllable-state" "1.0.1" + "@radix-ui/react-use-layout-effect" "1.0.1" + +"@radix-ui/react-collection@1.0.3": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@radix-ui/react-collection/-/react-collection-1.0.3.tgz#9595a66e09026187524a36c6e7e9c7d286469159" + integrity sha512-3SzW+0PW7yBBoQlT8wNcGtaxaD0XSu0uLUFgrtHY08Acx05TaHaOmVLR73c0j/cqpDy53KBMO7s0dx2wmOIDIA== dependencies: "@babel/runtime" "^7.13.10" - "@radix-ui/react-compose-refs" "1.0.0" - "@radix-ui/react-context" "1.0.0" - "@radix-ui/react-primitive" "1.0.2" - "@radix-ui/react-slot" "1.0.1" + "@radix-ui/react-compose-refs" "1.0.1" + "@radix-ui/react-context" "1.0.1" + "@radix-ui/react-primitive" "1.0.3" + "@radix-ui/react-slot" "1.0.2" -"@radix-ui/react-compose-refs@1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@radix-ui/react-compose-refs/-/react-compose-refs-1.0.0.tgz#37595b1f16ec7f228d698590e78eeed18ff218ae" - integrity sha512-0KaSv6sx787/hK3eF53iOkiSLwAGlFMx5lotrqD2pTjB18KbybKoEIgkNZTKC60YECDQTKGTRcDBILwZVqVKvA== +"@radix-ui/react-compose-refs@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@radix-ui/react-compose-refs/-/react-compose-refs-1.0.1.tgz#7ed868b66946aa6030e580b1ffca386dd4d21989" + integrity sha512-fDSBgd44FKHa1FRMU59qBMPFcl2PZE+2nmqunj+BWFyYYjnhIDWL2ItDs3rrbJDQOtzt5nIebLCQc4QRfz6LJw== dependencies: "@babel/runtime" "^7.13.10" -"@radix-ui/react-context@1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@radix-ui/react-context/-/react-context-1.0.0.tgz#f38e30c5859a9fb5e9aa9a9da452ee3ed9e0aee0" - integrity sha512-1pVM9RfOQ+n/N5PJK33kRSKsr1glNxomxONs5c49MliinBY6Yw2Q995qfBUUo0/Mbg05B/sGA0gkgPI7kmSHBg== +"@radix-ui/react-context@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@radix-ui/react-context/-/react-context-1.0.1.tgz#fe46e67c96b240de59187dcb7a1a50ce3e2ec00c" + integrity sha512-ebbrdFoYTcuZ0v4wG5tedGnp9tzcV8awzsxYph7gXUyvnNLuTIcCk1q17JEbnVhXAKG9oX3KtchwiMIAYp9NLg== dependencies: "@babel/runtime" "^7.13.10" -"@radix-ui/react-direction@1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@radix-ui/react-direction/-/react-direction-1.0.0.tgz#a2e0b552352459ecf96342c79949dd833c1e6e45" - integrity sha512-2HV05lGUgYcA6xgLQ4BKPDmtL+QbIZYH5fCOTAOOcJ5O0QbWS3i9lKaurLzliYUDhORI2Qr3pyjhJh44lKA3rQ== +"@radix-ui/react-direction@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@radix-ui/react-direction/-/react-direction-1.0.1.tgz#9cb61bf2ccf568f3421422d182637b7f47596c9b" + integrity sha512-RXcvnXgyvYvBEOhCBuddKecVkoMiI10Jcm5cTI7abJRAHYfFxeu+FBQs/DvdxSYucxR5mna0dNsL6QFlds5TMA== dependencies: "@babel/runtime" "^7.13.10" -"@radix-ui/react-dismissable-layer@1.0.3": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.0.3.tgz#63844d8e6bbcd010a513e7176d051c3c4044e09e" - integrity sha512-nXZOvFjOuHS1ovumntGV7NNoLaEp9JEvTht3MBjP44NSW5hUKj/8OnfN3+8WmB+CEhN44XaGhpHoSsUIEl5P7Q== +"@radix-ui/react-dismissable-layer@1.0.5": + version "1.0.5" + resolved "https://registry.yarnpkg.com/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.0.5.tgz#3f98425b82b9068dfbab5db5fff3df6ebf48b9d4" + integrity sha512-aJeDjQhywg9LBu2t/At58hCvr7pEm0o2Ke1x33B+MhjNmmZ17sy4KImo0KPLgsnc/zN7GPdce8Cnn0SWvwZO7g== dependencies: "@babel/runtime" "^7.13.10" - "@radix-ui/primitive" "1.0.0" - "@radix-ui/react-compose-refs" "1.0.0" - "@radix-ui/react-primitive" "1.0.2" - "@radix-ui/react-use-callback-ref" "1.0.0" - "@radix-ui/react-use-escape-keydown" "1.0.2" + "@radix-ui/primitive" "1.0.1" + "@radix-ui/react-compose-refs" "1.0.1" + "@radix-ui/react-primitive" "1.0.3" + "@radix-ui/react-use-callback-ref" "1.0.1" + "@radix-ui/react-use-escape-keydown" "1.0.3" -"@radix-ui/react-id@1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@radix-ui/react-id/-/react-id-1.0.0.tgz#8d43224910741870a45a8c9d092f25887bb6d11e" - integrity sha512-Q6iAB/U7Tq3NTolBBQbHTgclPmGWE3OlktGGqrClPozSw4vkQ1DfQAOtzgRPecKsMdJINE05iaoDUG8tRzCBjw== +"@radix-ui/react-focus-guards@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@radix-ui/react-focus-guards/-/react-focus-guards-1.0.1.tgz#1ea7e32092216b946397866199d892f71f7f98ad" + integrity sha512-Rect2dWbQ8waGzhMavsIbmSVCgYxkXLxxR3ZvCX79JOglzdEy4JXMb98lq4hPxUbLr77nP0UOGf4rcMU+s1pUA== dependencies: "@babel/runtime" "^7.13.10" - "@radix-ui/react-use-layout-effect" "1.0.0" -"@radix-ui/react-popper@1.1.1": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@radix-ui/react-popper/-/react-popper-1.1.1.tgz#54f060941c981e965ff5d6b64e152d6298d2326e" - integrity sha512-keYDcdMPNMjSC8zTsZ8wezUMiWM9Yj14wtF3s0PTIs9srnEPC9Kt2Gny1T3T81mmSeyDjZxsD9N5WCwNNb712w== +"@radix-ui/react-focus-scope@1.0.4": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@radix-ui/react-focus-scope/-/react-focus-scope-1.0.4.tgz#2ac45fce8c5bb33eb18419cdc1905ef4f1906525" + integrity sha512-sL04Mgvf+FmyvZeYfNu1EPAaaxD+aw7cYeIB9L9Fvq8+urhltTRaEo5ysKOpHuKPclsZcSUMKlN05x4u+CINpA== dependencies: "@babel/runtime" "^7.13.10" - "@floating-ui/react-dom" "0.7.2" - "@radix-ui/react-arrow" "1.0.2" - "@radix-ui/react-compose-refs" "1.0.0" - "@radix-ui/react-context" "1.0.0" - "@radix-ui/react-primitive" "1.0.2" - "@radix-ui/react-use-callback-ref" "1.0.0" - "@radix-ui/react-use-layout-effect" "1.0.0" - "@radix-ui/react-use-rect" "1.0.0" - "@radix-ui/react-use-size" "1.0.0" - "@radix-ui/rect" "1.0.0" - -"@radix-ui/react-portal@1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@radix-ui/react-portal/-/react-portal-1.0.2.tgz#102370b1027a767a371cab0243be4bc664f72330" - integrity sha512-swu32idoCW7KA2VEiUZGBSu9nB6qwGdV6k6HYhUoOo3M1FFpD+VgLzUqtt3mwL1ssz7r2x8MggpLSQach2Xy/Q== + "@radix-ui/react-compose-refs" "1.0.1" + "@radix-ui/react-primitive" "1.0.3" + "@radix-ui/react-use-callback-ref" "1.0.1" + +"@radix-ui/react-id@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@radix-ui/react-id/-/react-id-1.0.1.tgz#73cdc181f650e4df24f0b6a5b7aa426b912c88c0" + integrity sha512-tI7sT/kqYp8p96yGWY1OAnLHrqDgzHefRBKQ2YAkBS5ja7QLcZ9Z/uY7bEjPUatf8RomoXM8/1sMj1IJaE5UzQ== dependencies: "@babel/runtime" "^7.13.10" - "@radix-ui/react-primitive" "1.0.2" + "@radix-ui/react-use-layout-effect" "1.0.1" -"@radix-ui/react-presence@1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@radix-ui/react-presence/-/react-presence-1.0.0.tgz#814fe46df11f9a468808a6010e3f3ca7e0b2e84a" - integrity sha512-A+6XEvN01NfVWiKu38ybawfHsBjWum42MRPnEuqPsBZ4eV7e/7K321B5VgYMPv3Xx5An6o1/l9ZuDBgmcmWK3w== +"@radix-ui/react-popover@^1.0.6": + version "1.0.7" + resolved "https://registry.yarnpkg.com/@radix-ui/react-popover/-/react-popover-1.0.7.tgz#23eb7e3327330cb75ec7b4092d685398c1654e3c" + integrity sha512-shtvVnlsxT6faMnK/a7n0wptwBD23xc1Z5mdrtKLwVEfsEMXodS0r5s0/g5P0hX//EKYZS2sxUjqfzlg52ZSnQ== + dependencies: + "@babel/runtime" "^7.13.10" + "@radix-ui/primitive" "1.0.1" + "@radix-ui/react-compose-refs" "1.0.1" + "@radix-ui/react-context" "1.0.1" + "@radix-ui/react-dismissable-layer" "1.0.5" + "@radix-ui/react-focus-guards" "1.0.1" + "@radix-ui/react-focus-scope" "1.0.4" + "@radix-ui/react-id" "1.0.1" + "@radix-ui/react-popper" "1.1.3" + "@radix-ui/react-portal" "1.0.4" + "@radix-ui/react-presence" "1.0.1" + "@radix-ui/react-primitive" "1.0.3" + "@radix-ui/react-slot" "1.0.2" + "@radix-ui/react-use-controllable-state" "1.0.1" + aria-hidden "^1.1.1" + react-remove-scroll "2.5.5" + +"@radix-ui/react-popper@1.1.3": + version "1.1.3" + resolved "https://registry.yarnpkg.com/@radix-ui/react-popper/-/react-popper-1.1.3.tgz#24c03f527e7ac348fabf18c89795d85d21b00b42" + integrity sha512-cKpopj/5RHZWjrbF2846jBNacjQVwkP068DfmgrNJXpvVWrOvlAmE9xSiy5OqeE+Gi8D9fP+oDhUnPqNMY8/5w== + dependencies: + "@babel/runtime" "^7.13.10" + "@floating-ui/react-dom" "^2.0.0" + "@radix-ui/react-arrow" "1.0.3" + "@radix-ui/react-compose-refs" "1.0.1" + "@radix-ui/react-context" "1.0.1" + "@radix-ui/react-primitive" "1.0.3" + "@radix-ui/react-use-callback-ref" "1.0.1" + "@radix-ui/react-use-layout-effect" "1.0.1" + "@radix-ui/react-use-rect" "1.0.1" + "@radix-ui/react-use-size" "1.0.1" + "@radix-ui/rect" "1.0.1" + +"@radix-ui/react-portal@1.0.4": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@radix-ui/react-portal/-/react-portal-1.0.4.tgz#df4bfd353db3b1e84e639e9c63a5f2565fb00e15" + integrity sha512-Qki+C/EuGUVCQTOTD5vzJzJuMUlewbzuKyUy+/iHM2uwGiru9gZeBJtHAPKAEkB5KWGi9mP/CHKcY0wt1aW45Q== dependencies: "@babel/runtime" "^7.13.10" - "@radix-ui/react-compose-refs" "1.0.0" - "@radix-ui/react-use-layout-effect" "1.0.0" + "@radix-ui/react-primitive" "1.0.3" -"@radix-ui/react-primitive@1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@radix-ui/react-primitive/-/react-primitive-1.0.2.tgz#54e22f49ca59ba88d8143090276d50b93f8a7053" - integrity sha512-zY6G5Qq4R8diFPNwtyoLRZBxzu1Z+SXMlfYpChN7Dv8gvmx9X3qhDqiLWvKseKVJMuedFeU/Sa0Sy/Ia+t06Dw== +"@radix-ui/react-presence@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@radix-ui/react-presence/-/react-presence-1.0.1.tgz#491990ba913b8e2a5db1b06b203cb24b5cdef9ba" + integrity sha512-UXLW4UAbIY5ZjcvzjfRFo5gxva8QirC9hF7wRE4U5gz+TP0DbRk+//qyuAQ1McDxBt1xNMBTaciFGvEmJvAZCg== + dependencies: + "@babel/runtime" "^7.13.10" + "@radix-ui/react-compose-refs" "1.0.1" + "@radix-ui/react-use-layout-effect" "1.0.1" + +"@radix-ui/react-primitive@1.0.3": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@radix-ui/react-primitive/-/react-primitive-1.0.3.tgz#d49ea0f3f0b2fe3ab1cb5667eb03e8b843b914d0" + integrity sha512-yi58uVyoAcK/Nq1inRY56ZSjKypBNKTa/1mcL8qdl6oJeEaDbOldlzrGn7P6Q3Id5d+SYNGc5AJgc4vGhjs5+g== dependencies: "@babel/runtime" "^7.13.10" - "@radix-ui/react-slot" "1.0.1" + "@radix-ui/react-slot" "1.0.2" "@radix-ui/react-radio-group@^1.1.1": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@radix-ui/react-radio-group/-/react-radio-group-1.1.2.tgz#9b21ab66a125f60476f272a9c07e9c16e77d4e7b" - integrity sha512-S7K8upMjOkx1fTUzEugbfCYPwI9Yw4m2h2ZfJP+ZWP/Mzc/LE2T6QgiAMaSaC3vZSxU5Kk5Eb377zMklWeaaCQ== + version "1.1.3" + resolved "https://registry.yarnpkg.com/@radix-ui/react-radio-group/-/react-radio-group-1.1.3.tgz#3197f5dcce143bcbf961471bf89320735c0212d3" + integrity sha512-x+yELayyefNeKeTx4fjK6j99Fs6c4qKm3aY38G3swQVTN6xMpsrbigC0uHs2L//g8q4qR7qOcww8430jJmi2ag== dependencies: "@babel/runtime" "^7.13.10" - "@radix-ui/primitive" "1.0.0" - "@radix-ui/react-compose-refs" "1.0.0" - "@radix-ui/react-context" "1.0.0" - "@radix-ui/react-direction" "1.0.0" - "@radix-ui/react-presence" "1.0.0" - "@radix-ui/react-primitive" "1.0.2" - "@radix-ui/react-roving-focus" "1.0.3" - "@radix-ui/react-use-controllable-state" "1.0.0" - "@radix-ui/react-use-previous" "1.0.0" - "@radix-ui/react-use-size" "1.0.0" - -"@radix-ui/react-roving-focus@1.0.3": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@radix-ui/react-roving-focus/-/react-roving-focus-1.0.3.tgz#0b4f4f9bd509f4510079e9e0734a734fd17cdce3" - integrity sha512-stjCkIoMe6h+1fWtXlA6cRfikdBzCLp3SnVk7c48cv/uy3DTGoXhN76YaOYUJuy3aEDvDIKwKR5KSmvrtPvQPQ== + "@radix-ui/primitive" "1.0.1" + "@radix-ui/react-compose-refs" "1.0.1" + "@radix-ui/react-context" "1.0.1" + "@radix-ui/react-direction" "1.0.1" + "@radix-ui/react-presence" "1.0.1" + "@radix-ui/react-primitive" "1.0.3" + "@radix-ui/react-roving-focus" "1.0.4" + "@radix-ui/react-use-controllable-state" "1.0.1" + "@radix-ui/react-use-previous" "1.0.1" + "@radix-ui/react-use-size" "1.0.1" + +"@radix-ui/react-roving-focus@1.0.4": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@radix-ui/react-roving-focus/-/react-roving-focus-1.0.4.tgz#e90c4a6a5f6ac09d3b8c1f5b5e81aab2f0db1974" + integrity sha512-2mUg5Mgcu001VkGy+FfzZyzbmuUWzgWkj3rvv4yu+mLw03+mTzbxZHvfcGyFp2b8EkQeMkpRQ5FiA2Vr2O6TeQ== dependencies: "@babel/runtime" "^7.13.10" - "@radix-ui/primitive" "1.0.0" - "@radix-ui/react-collection" "1.0.2" - "@radix-ui/react-compose-refs" "1.0.0" - "@radix-ui/react-context" "1.0.0" - "@radix-ui/react-direction" "1.0.0" - "@radix-ui/react-id" "1.0.0" - "@radix-ui/react-primitive" "1.0.2" - "@radix-ui/react-use-callback-ref" "1.0.0" - "@radix-ui/react-use-controllable-state" "1.0.0" - -"@radix-ui/react-slot@1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@radix-ui/react-slot/-/react-slot-1.0.1.tgz#e7868c669c974d649070e9ecbec0b367ee0b4d81" - integrity sha512-avutXAFL1ehGvAXtPquu0YK5oz6ctS474iM3vNGQIkswrVhdrS52e3uoMQBzZhNRAIE0jBnUyXWNmSjGHhCFcw== + "@radix-ui/primitive" "1.0.1" + "@radix-ui/react-collection" "1.0.3" + "@radix-ui/react-compose-refs" "1.0.1" + "@radix-ui/react-context" "1.0.1" + "@radix-ui/react-direction" "1.0.1" + "@radix-ui/react-id" "1.0.1" + "@radix-ui/react-primitive" "1.0.3" + "@radix-ui/react-use-callback-ref" "1.0.1" + "@radix-ui/react-use-controllable-state" "1.0.1" + +"@radix-ui/react-select@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@radix-ui/react-select/-/react-select-2.0.0.tgz#a3511792a51a7018d6559357323a7f52e0e38887" + integrity sha512-RH5b7af4oHtkcHS7pG6Sgv5rk5Wxa7XI8W5gvB1N/yiuDGZxko1ynvOiVhFM7Cis2A8zxF9bTOUVbRDzPepe6w== + dependencies: + "@babel/runtime" "^7.13.10" + "@radix-ui/number" "1.0.1" + "@radix-ui/primitive" "1.0.1" + "@radix-ui/react-collection" "1.0.3" + "@radix-ui/react-compose-refs" "1.0.1" + "@radix-ui/react-context" "1.0.1" + "@radix-ui/react-direction" "1.0.1" + "@radix-ui/react-dismissable-layer" "1.0.5" + "@radix-ui/react-focus-guards" "1.0.1" + "@radix-ui/react-focus-scope" "1.0.4" + "@radix-ui/react-id" "1.0.1" + "@radix-ui/react-popper" "1.1.3" + "@radix-ui/react-portal" "1.0.4" + "@radix-ui/react-primitive" "1.0.3" + "@radix-ui/react-slot" "1.0.2" + "@radix-ui/react-use-callback-ref" "1.0.1" + "@radix-ui/react-use-controllable-state" "1.0.1" + "@radix-ui/react-use-layout-effect" "1.0.1" + "@radix-ui/react-use-previous" "1.0.1" + "@radix-ui/react-visually-hidden" "1.0.3" + aria-hidden "^1.1.1" + react-remove-scroll "2.5.5" + +"@radix-ui/react-slot@1.0.2", "@radix-ui/react-slot@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@radix-ui/react-slot/-/react-slot-1.0.2.tgz#a9ff4423eade67f501ffb32ec22064bc9d3099ab" + integrity sha512-YeTpuq4deV+6DusvVUW4ivBgnkHwECUu0BiN43L5UCDFgdhsRUWAghhTF5MbvNTPzmiFOx90asDSUjWuCNapwg== dependencies: "@babel/runtime" "^7.13.10" - "@radix-ui/react-compose-refs" "1.0.0" + "@radix-ui/react-compose-refs" "1.0.1" "@radix-ui/react-switch@^1.0.1": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@radix-ui/react-switch/-/react-switch-1.0.2.tgz#e3d1b9fe18b6b1173aadc8b8e6efdc96a28a70f8" - integrity sha512-BcG/LKehxt36NXG0wPnoCitIfSMtU9Xo7BmythYA1PAMLtsMvW7kALfBzmduQoHTWcKr0AVcFyh0gChBUp9TiQ== + version "1.0.3" + resolved "https://registry.yarnpkg.com/@radix-ui/react-switch/-/react-switch-1.0.3.tgz#6119f16656a9eafb4424c600fdb36efa5ec5837e" + integrity sha512-mxm87F88HyHztsI7N+ZUmEoARGkC22YVW5CaC+Byc+HRpuvCrOBPTAnXgf+tZ/7i0Sg/eOePGdMhUKhPaQEqow== dependencies: "@babel/runtime" "^7.13.10" - "@radix-ui/primitive" "1.0.0" - "@radix-ui/react-compose-refs" "1.0.0" - "@radix-ui/react-context" "1.0.0" - "@radix-ui/react-primitive" "1.0.2" - "@radix-ui/react-use-controllable-state" "1.0.0" - "@radix-ui/react-use-previous" "1.0.0" - "@radix-ui/react-use-size" "1.0.0" + "@radix-ui/primitive" "1.0.1" + "@radix-ui/react-compose-refs" "1.0.1" + "@radix-ui/react-context" "1.0.1" + "@radix-ui/react-primitive" "1.0.3" + "@radix-ui/react-use-controllable-state" "1.0.1" + "@radix-ui/react-use-previous" "1.0.1" + "@radix-ui/react-use-size" "1.0.1" "@radix-ui/react-tooltip@^1.0.2": - version "1.0.5" - resolved "https://registry.yarnpkg.com/@radix-ui/react-tooltip/-/react-tooltip-1.0.5.tgz#fe20274aeac874db643717fc7761d5a8abdd62d1" - integrity sha512-cDKVcfzyO6PpckZekODJZDe5ZxZ2fCZlzKzTmPhe4mX9qTHRfLcKgqb0OKf22xLwDequ2tVleim+ZYx3rabD5w== + version "1.0.7" + resolved "https://registry.yarnpkg.com/@radix-ui/react-tooltip/-/react-tooltip-1.0.7.tgz#8f55070f852e7e7450cc1d9210b793d2e5a7686e" + integrity sha512-lPh5iKNFVQ/jav/j6ZrWq3blfDJ0OH9R6FlNUHPMqdLuQ9vwDgFsRxvl8b7Asuy5c8xmoojHUxKHQSOAvMHxyw== dependencies: "@babel/runtime" "^7.13.10" - "@radix-ui/primitive" "1.0.0" - "@radix-ui/react-compose-refs" "1.0.0" - "@radix-ui/react-context" "1.0.0" - "@radix-ui/react-dismissable-layer" "1.0.3" - "@radix-ui/react-id" "1.0.0" - "@radix-ui/react-popper" "1.1.1" - "@radix-ui/react-portal" "1.0.2" - "@radix-ui/react-presence" "1.0.0" - "@radix-ui/react-primitive" "1.0.2" - "@radix-ui/react-slot" "1.0.1" - "@radix-ui/react-use-controllable-state" "1.0.0" - "@radix-ui/react-visually-hidden" "1.0.2" - -"@radix-ui/react-use-callback-ref@1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.0.0.tgz#9e7b8b6b4946fe3cbe8f748c82a2cce54e7b6a90" - integrity sha512-GZtyzoHz95Rhs6S63D2t/eqvdFCm7I+yHMLVQheKM7nBD8mbZIt+ct1jz4536MDnaOGKIxynJ8eHTkVGVVkoTg== + "@radix-ui/primitive" "1.0.1" + "@radix-ui/react-compose-refs" "1.0.1" + "@radix-ui/react-context" "1.0.1" + "@radix-ui/react-dismissable-layer" "1.0.5" + "@radix-ui/react-id" "1.0.1" + "@radix-ui/react-popper" "1.1.3" + "@radix-ui/react-portal" "1.0.4" + "@radix-ui/react-presence" "1.0.1" + "@radix-ui/react-primitive" "1.0.3" + "@radix-ui/react-slot" "1.0.2" + "@radix-ui/react-use-controllable-state" "1.0.1" + "@radix-ui/react-visually-hidden" "1.0.3" + +"@radix-ui/react-use-callback-ref@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.0.1.tgz#f4bb1f27f2023c984e6534317ebc411fc181107a" + integrity sha512-D94LjX4Sp0xJFVaoQOd3OO9k7tpBYNOXdVhkltUbGv2Qb9OXdrg/CpsjlZv7ia14Sylv398LswWBVVu5nqKzAQ== dependencies: "@babel/runtime" "^7.13.10" -"@radix-ui/react-use-controllable-state@1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.0.0.tgz#a64deaafbbc52d5d407afaa22d493d687c538b7f" - integrity sha512-FohDoZvk3mEXh9AWAVyRTYR4Sq7/gavuofglmiXB2g1aKyboUD4YtgWxKj8O5n+Uak52gXQ4wKz5IFST4vtJHg== +"@radix-ui/react-use-controllable-state@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.0.1.tgz#ecd2ced34e6330caf89a82854aa2f77e07440286" + integrity sha512-Svl5GY5FQeN758fWKrjM6Qb7asvXeiZltlT4U2gVfl8Gx5UAv2sMR0LWo8yhsIZh2oQ0eFdZ59aoOOMV7b47VA== dependencies: "@babel/runtime" "^7.13.10" - "@radix-ui/react-use-callback-ref" "1.0.0" + "@radix-ui/react-use-callback-ref" "1.0.1" -"@radix-ui/react-use-escape-keydown@1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.0.2.tgz#09ab6455ab240b4f0a61faf06d4e5132c4d639f6" - integrity sha512-DXGim3x74WgUv+iMNCF+cAo8xUHHeqvjx8zs7trKf+FkQKPQXLk2sX7Gx1ysH7Q76xCpZuxIJE7HLPxRE+Q+GA== +"@radix-ui/react-use-escape-keydown@1.0.3": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.0.3.tgz#217b840c250541609c66f67ed7bab2b733620755" + integrity sha512-vyL82j40hcFicA+M4Ex7hVkB9vHgSse1ZWomAqV2Je3RleKGO5iM8KMOEtfoSB0PnIelMd2lATjTGMYqN5ylTg== dependencies: "@babel/runtime" "^7.13.10" - "@radix-ui/react-use-callback-ref" "1.0.0" + "@radix-ui/react-use-callback-ref" "1.0.1" -"@radix-ui/react-use-layout-effect@1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.0.0.tgz#2fc19e97223a81de64cd3ba1dc42ceffd82374dc" - integrity sha512-6Tpkq+R6LOlmQb1R5NNETLG0B4YP0wc+klfXafpUCj6JGyaUc8il7/kUZ7m59rGbXGczE9Bs+iz2qloqsZBduQ== +"@radix-ui/react-use-layout-effect@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.0.1.tgz#be8c7bc809b0c8934acf6657b577daf948a75399" + integrity sha512-v/5RegiJWYdoCvMnITBkNNx6bCj20fiaJnWtRkU18yITptraXjffz5Qbn05uOiQnOvi+dbkznkoaMltz1GnszQ== dependencies: "@babel/runtime" "^7.13.10" -"@radix-ui/react-use-previous@1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@radix-ui/react-use-previous/-/react-use-previous-1.0.0.tgz#e48a69c3a7d8078a967084038df66d0d181c56ac" - integrity sha512-RG2K8z/K7InnOKpq6YLDmT49HGjNmrK+fr82UCVKT2sW0GYfVnYp4wZWBooT/EYfQ5faA9uIjvsuMMhH61rheg== +"@radix-ui/react-use-previous@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@radix-ui/react-use-previous/-/react-use-previous-1.0.1.tgz#b595c087b07317a4f143696c6a01de43b0d0ec66" + integrity sha512-cV5La9DPwiQ7S0gf/0qiD6YgNqM5Fk97Kdrlc5yBcrF3jyEZQwm7vYFqMo4IfeHgJXsRaMvLABFtd0OVEmZhDw== dependencies: "@babel/runtime" "^7.13.10" -"@radix-ui/react-use-rect@1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@radix-ui/react-use-rect/-/react-use-rect-1.0.0.tgz#b040cc88a4906b78696cd3a32b075ed5b1423b3e" - integrity sha512-TB7pID8NRMEHxb/qQJpvSt3hQU4sqNPM1VCTjTRjEOa7cEop/QMuq8S6fb/5Tsz64kqSvB9WnwsDHtjnrM9qew== +"@radix-ui/react-use-rect@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@radix-ui/react-use-rect/-/react-use-rect-1.0.1.tgz#fde50b3bb9fd08f4a1cd204572e5943c244fcec2" + integrity sha512-Cq5DLuSiuYVKNU8orzJMbl15TXilTnJKUCltMVQg53BQOF1/C5toAaGrowkgksdBQ9H+SRL23g0HDmg9tvmxXw== dependencies: "@babel/runtime" "^7.13.10" - "@radix-ui/rect" "1.0.0" + "@radix-ui/rect" "1.0.1" -"@radix-ui/react-use-size@1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@radix-ui/react-use-size/-/react-use-size-1.0.0.tgz#a0b455ac826749419f6354dc733e2ca465054771" - integrity sha512-imZ3aYcoYCKhhgNpkNDh/aTiU05qw9hX+HHI1QDBTyIlcFjgeFlKKySNGMwTp7nYFLQg/j0VA2FmCY4WPDDHMg== +"@radix-ui/react-use-size@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@radix-ui/react-use-size/-/react-use-size-1.0.1.tgz#1c5f5fea940a7d7ade77694bb98116fb49f870b2" + integrity sha512-ibay+VqrgcaI6veAojjofPATwledXiSmX+C0KrBk/xgpX9rBzPV3OsfwlhQdUOFbh+LKQorLYT+xTXW9V8yd0g== dependencies: "@babel/runtime" "^7.13.10" - "@radix-ui/react-use-layout-effect" "1.0.0" + "@radix-ui/react-use-layout-effect" "1.0.1" -"@radix-ui/react-visually-hidden@1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.0.2.tgz#29b117a59ef09a984bdad12cb98d81e8350be450" - integrity sha512-qirnJxtYn73HEk1rXL12/mXnu2rwsNHDID10th2JGtdK25T9wX+mxRmGt7iPSahw512GbZOc0syZX1nLQGoEOg== +"@radix-ui/react-visually-hidden@1.0.3": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.0.3.tgz#51aed9dd0fe5abcad7dee2a234ad36106a6984ac" + integrity sha512-D4w41yN5YRKtu464TLnByKzMDG/JlMPHtfZgQAu9v6mNakUqGUI9vUrfQKz8NK41VMm/xbZbh76NUTVtIYqOMA== dependencies: "@babel/runtime" "^7.13.10" - "@radix-ui/react-primitive" "1.0.2" + "@radix-ui/react-primitive" "1.0.3" -"@radix-ui/rect@1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@radix-ui/rect/-/rect-1.0.0.tgz#0dc8e6a829ea2828d53cbc94b81793ba6383bf3c" - integrity sha512-d0O68AYy/9oeEy1DdC07bz1/ZXX+DqCskRd3i4JzLSTXwefzaepQrKjXC7aNM8lTHjFLDO0pDgaEiQ7jEk+HVg== +"@radix-ui/rect@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@radix-ui/rect/-/rect-1.0.1.tgz#bf8e7d947671996da2e30f4904ece343bc4a883f" + integrity sha512-fyrgCaedtvMg9NK3en0pnOYJdtfwxUcNolezkNPUsoX57X8oQk+NkqcvzHXD2uKNij6GXmWU9NDru2IWjrO4BQ== dependencies: "@babel/runtime" "^7.13.10" -"@rango-dev/queue-manager-core@^0.1.12-next.0": - version "0.1.12-next.0" - resolved "https://registry.yarnpkg.com/@rango-dev/queue-manager-core/-/queue-manager-core-0.1.12-next.0.tgz#f2166a003414f9931bf86c51f3af1d32d237b453" - integrity sha512-cUcCgvdUsVQqwaHDgqVdB4bo9+ZLWhZsFXDECF1svQewPaXoxzi/DJteMLdbl27t7v2/dMdM3zEdoe5Z0V2BIg== - dependencies: - idb "^7.1.1" - uuid "^9.0.0" - -"@rango-dev/queue-manager-rango-preset@^0.1.11": - version "0.1.11" - resolved "https://registry.yarnpkg.com/@rango-dev/queue-manager-rango-preset/-/queue-manager-rango-preset-0.1.11.tgz#362f8372c153939859870924806f3b0dfc348706" - integrity sha512-yQORwvIXsz+ZtTZFfjyuqrp1Vg1MLyFpNHqCi72jyz8n1QtuYQKy2Nrh4z/7ALUgXQm4h2i7Y4Q5KDOqIVN/0g== - dependencies: - "@sentry/browser" "^6.12.0" - uuid "^9.0.0" - -"@rango-dev/queue-manager-react@^0.1.11-next.0": - version "0.1.11-next.0" - resolved "https://registry.yarnpkg.com/@rango-dev/queue-manager-react/-/queue-manager-react-0.1.11-next.0.tgz#dd816a77821b0831ac512d394f6f2ee6a7def44e" - integrity sha512-AroeB0IKUCfN1iX8GLSS/Fn6M6Uc5LiUqqg7AxsMGlvWrtOpdQHi6Z7qCIOmD8pJvFh9OjRlN13DgOSLWstgUQ== - "@reach/router@^1.2.1": version "1.3.4" resolved "https://registry.yarnpkg.com/@reach/router/-/router-1.3.4.tgz#d2574b19370a70c80480ed91f3da840136d10f8c" @@ -4051,493 +5632,634 @@ prop-types "^15.6.1" react-lifecycles-compat "^3.0.4" -"@remix-run/dev@npm:@vercel/remix-run-dev@1.14.2": - version "1.14.2" - resolved "https://registry.yarnpkg.com/@vercel/remix-run-dev/-/remix-run-dev-1.14.2.tgz#3899c9b40aea2d4deb3c0e9febcc5398a9c5e162" - integrity sha512-lsJFO2pnQoHYe2gcvj/VY8c0lVHZFnoEfMB3w+CQU8xql2hpneK2XrbKT/mHm+HDeaaJPT+mxAf7jpbFXeZhWA== - dependencies: - "@babel/core" "^7.18.6" - "@babel/generator" "^7.18.6" - "@babel/parser" "^7.18.6" - "@babel/plugin-syntax-jsx" "^7.18.6" - "@babel/plugin-syntax-typescript" "^7.20.0" - "@babel/preset-env" "^7.18.6" - "@babel/preset-typescript" "^7.18.6" - "@babel/traverse" "^7.18.6" - "@babel/types" "^7.20.2" - "@esbuild-plugins/node-modules-polyfill" "^0.1.4" - "@npmcli/package-json" "^2.0.0" - "@remix-run/server-runtime" "1.14.2" - "@vanilla-extract/integration" "^6.0.2" - arg "^5.0.1" - cacache "^15.0.5" - chalk "^4.1.2" - chokidar "^3.5.1" - dotenv "^16.0.0" - esbuild "0.16.3" - execa "5.1.1" - exit-hook "2.2.1" - express "^4.17.1" - fast-glob "3.2.11" - fs-extra "^10.0.0" - get-port "^5.1.1" - gunzip-maybe "^1.4.2" - inquirer "^8.2.1" - jsesc "3.0.2" - json5 "^2.2.1" - lodash "^4.17.21" - lodash.debounce "^4.0.8" - lru-cache "^7.14.1" - minimatch "^3.0.4" - node-fetch "^2.6.7" - ora "^5.4.1" - postcss "^8.4.19" - postcss-discard-duplicates "^5.1.0" - postcss-load-config "^4.0.1" - postcss-modules "^6.0.0" - prettier "2.7.1" - pretty-ms "^7.0.1" - proxy-agent "^5.0.0" - react-refresh "^0.14.0" - recast "^0.21.5" - remark-frontmatter "4.0.1" - remark-mdx-frontmatter "^1.0.1" - semver "^7.3.7" - sort-package-json "^1.55.0" - tar-fs "^2.1.1" - tsconfig-paths "^4.0.0" - ws "^7.4.5" - xdm "^2.0.0" - -"@remix-run/router@1.3.3": - version "1.3.3" - resolved "https://registry.yarnpkg.com/@remix-run/router/-/router-1.3.3.tgz#d6d531d69c0fa3a44fda7dc00b20d49b44549164" - integrity sha512-YRHie1yQEj0kqqCTCJEfHqYSSNlZQ696QJG+MMiW4mxSl9I0ojz/eRhJS4fs88Z5i6D1SmoF9d3K99/QOhI8/w== +"@remix-run/router@1.13.0": + version "1.13.0" + resolved "https://registry.yarnpkg.com/@remix-run/router/-/router-1.13.0.tgz#7e29c4ee85176d9c08cb0f4456bff74d092c5065" + integrity sha512-5dMOnVnefRsl4uRnAdoWjtVTdh8e6aZqgM4puy9nmEADH72ck+uXwzpJLEKE9Q6F8ZljNewLgmTfkxUrBdv4WA== -"@remix-run/router@1.5.0": - version "1.5.0" - resolved "https://registry.yarnpkg.com/@remix-run/router/-/router-1.5.0.tgz#57618e57942a5f0131374a9fdb0167e25a117fdc" - integrity sha512-bkUDCp8o1MvFO+qxkODcbhSqRa6P2GXgrGZVpt0dCXNW2HCSCqYI0ZoAqEOSAjRWmmlKcYgFvN4B4S+zo/f8kg== - -"@remix-run/server-runtime@1.14.2": - version "1.14.2" - resolved "https://registry.yarnpkg.com/@remix-run/server-runtime/-/server-runtime-1.14.2.tgz#aa28d57b0a78c6d2a08806c61b317a0044c8aada" - integrity sha512-/9eer5zWD4t7AeLTdeN9FOlPO1sLnlqQ5DIrDoQVwgDFCOvMycSbLSXhygWl3dVjQyteyzF8OW43qnReyDy/fQ== - dependencies: - "@remix-run/router" "1.3.3" - "@types/cookie" "^0.4.0" - "@types/react" "^18.0.15" - "@web3-storage/multipart-parser" "^1.0.0" - cookie "^0.4.1" - set-cookie-parser "^2.4.8" - source-map "^0.7.3" - -"@rollup/plugin-babel@^5.1.0": - version "5.3.1" - resolved "https://registry.yarnpkg.com/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz#04bc0608f4aa4b2e4b1aebf284344d0f68fda283" - integrity sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q== +"@rollup/pluginutils@^5.0.2": + version "5.1.0" + resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-5.1.0.tgz#7e53eddc8c7f483a4ad0b94afb1f7f5fd3c771e0" + integrity sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g== dependencies: - "@babel/helper-module-imports" "^7.10.4" - "@rollup/pluginutils" "^3.1.0" + "@types/estree" "^1.0.0" + estree-walker "^2.0.2" + picomatch "^2.3.1" -"@rollup/plugin-commonjs@^11.0.0": - version "11.1.0" - resolved "https://registry.yarnpkg.com/@rollup/plugin-commonjs/-/plugin-commonjs-11.1.0.tgz#60636c7a722f54b41e419e1709df05c7234557ef" - integrity sha512-Ycr12N3ZPN96Fw2STurD21jMqzKwL9QuFhms3SD7KKRK7oaXUsBU9Zt0jL/rOPHiPYisI21/rXGO3jr9BnLHUA== - dependencies: - "@rollup/pluginutils" "^3.0.8" - commondir "^1.0.1" - estree-walker "^1.0.1" - glob "^7.1.2" - is-reference "^1.1.2" - magic-string "^0.25.2" - resolve "^1.11.0" +"@rollup/rollup-android-arm-eabi@4.24.0": + version "4.24.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.24.0.tgz#1661ff5ea9beb362795304cb916049aba7ac9c54" + integrity sha512-Q6HJd7Y6xdB48x8ZNVDOqsbh2uByBhgK8PiQgPhwkIw/HC/YX5Ghq2mQY5sRMZWHb3VsFkWooUVOZHKr7DmDIA== + +"@rollup/rollup-android-arm64@4.24.0": + version "4.24.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.24.0.tgz#2ffaa91f1b55a0082b8a722525741aadcbd3971e" + integrity sha512-ijLnS1qFId8xhKjT81uBHuuJp2lU4x2yxa4ctFPtG+MqEE6+C5f/+X/bStmxapgmwLwiL3ih122xv8kVARNAZA== + +"@rollup/rollup-darwin-arm64@4.24.0": + version "4.24.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.24.0.tgz#627007221b24b8cc3063703eee0b9177edf49c1f" + integrity sha512-bIv+X9xeSs1XCk6DVvkO+S/z8/2AMt/2lMqdQbMrmVpgFvXlmde9mLcbQpztXm1tajC3raFDqegsH18HQPMYtA== + +"@rollup/rollup-darwin-x64@4.24.0": + version "4.24.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.24.0.tgz#0605506142b9e796c370d59c5984ae95b9758724" + integrity sha512-X6/nOwoFN7RT2svEQWUsW/5C/fYMBe4fnLK9DQk4SX4mgVBiTA9h64kjUYPvGQ0F/9xwJ5U5UfTbl6BEjaQdBQ== + +"@rollup/rollup-linux-arm-gnueabihf@4.24.0": + version "4.24.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.24.0.tgz#62dfd196d4b10c0c2db833897164d2d319ee0cbb" + integrity sha512-0KXvIJQMOImLCVCz9uvvdPgfyWo93aHHp8ui3FrtOP57svqrF/roSSR5pjqL2hcMp0ljeGlU4q9o/rQaAQ3AYA== + +"@rollup/rollup-linux-arm-musleabihf@4.24.0": + version "4.24.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.24.0.tgz#53ce72aeb982f1f34b58b380baafaf6a240fddb3" + integrity sha512-it2BW6kKFVh8xk/BnHfakEeoLPv8STIISekpoF+nBgWM4d55CZKc7T4Dx1pEbTnYm/xEKMgy1MNtYuoA8RFIWw== + +"@rollup/rollup-linux-arm64-gnu@4.24.0": + version "4.24.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.24.0.tgz#1632990f62a75c74f43e4b14ab3597d7ed416496" + integrity sha512-i0xTLXjqap2eRfulFVlSnM5dEbTVque/3Pi4g2y7cxrs7+a9De42z4XxKLYJ7+OhE3IgxvfQM7vQc43bwTgPwA== + +"@rollup/rollup-linux-arm64-musl@4.24.0": + version "4.24.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.24.0.tgz#8c03a996efb41e257b414b2e0560b7a21f2d9065" + integrity sha512-9E6MKUJhDuDh604Qco5yP/3qn3y7SLXYuiC0Rpr89aMScS2UAmK1wHP2b7KAa1nSjWJc/f/Lc0Wl1L47qjiyQw== + +"@rollup/rollup-linux-powerpc64le-gnu@4.24.0": + version "4.24.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.24.0.tgz#5b98729628d5bcc8f7f37b58b04d6845f85c7b5d" + integrity sha512-2XFFPJ2XMEiF5Zi2EBf4h73oR1V/lycirxZxHZNc93SqDN/IWhYYSYj8I9381ikUFXZrz2v7r2tOVk2NBwxrWw== + +"@rollup/rollup-linux-riscv64-gnu@4.24.0": + version "4.24.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.24.0.tgz#48e42e41f4cabf3573cfefcb448599c512e22983" + integrity sha512-M3Dg4hlwuntUCdzU7KjYqbbd+BLq3JMAOhCKdBE3TcMGMZbKkDdJ5ivNdehOssMCIokNHFOsv7DO4rlEOfyKpg== + +"@rollup/rollup-linux-s390x-gnu@4.24.0": + version "4.24.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.24.0.tgz#e0b4f9a966872cb7d3e21b9e412a4b7efd7f0b58" + integrity sha512-mjBaoo4ocxJppTorZVKWFpy1bfFj9FeCMJqzlMQGjpNPY9JwQi7OuS1axzNIk0nMX6jSgy6ZURDZ2w0QW6D56g== + +"@rollup/rollup-linux-x64-gnu@4.24.0": + version "4.24.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.24.0.tgz#78144741993100f47bd3da72fce215e077ae036b" + integrity sha512-ZXFk7M72R0YYFN5q13niV0B7G8/5dcQ9JDp8keJSfr3GoZeXEoMHP/HlvqROA3OMbMdfr19IjCeNAnPUG93b6A== + +"@rollup/rollup-linux-x64-musl@4.24.0": + version "4.24.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.24.0.tgz#d9fe32971883cd1bd858336bd33a1c3ca6146127" + integrity sha512-w1i+L7kAXZNdYl+vFvzSZy8Y1arS7vMgIy8wusXJzRrPyof5LAb02KGr1PD2EkRcl73kHulIID0M501lN+vobQ== + +"@rollup/rollup-win32-arm64-msvc@4.24.0": + version "4.24.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.24.0.tgz#71fa3ea369316db703a909c790743972e98afae5" + integrity sha512-VXBrnPWgBpVDCVY6XF3LEW0pOU51KbaHhccHw6AS6vBWIC60eqsH19DAeeObl+g8nKAz04QFdl/Cefta0xQtUQ== + +"@rollup/rollup-win32-ia32-msvc@4.24.0": + version "4.24.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.24.0.tgz#653f5989a60658e17d7576a3996deb3902e342e2" + integrity sha512-xrNcGDU0OxVcPTH/8n/ShH4UevZxKIO6HJFK0e15XItZP2UcaiLFd5kiX7hJnqCbSztUF8Qot+JWBC/QXRPYWQ== + +"@rollup/rollup-win32-x64-msvc@4.24.0": + version "4.24.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.24.0.tgz#0574d7e87b44ee8511d08cc7f914bcb802b70818" + integrity sha512-fbMkAF7fufku0N2dE5TBXcNlg0pt0cJue4xBRE2Qc5Vqikxr4VCgKj/ht6SMdFcOacVA9rqF70APJ8RN/4vMJw== + +"@safe-global/safe-apps-provider@^0.17.0": + version "0.17.1" + resolved "https://registry.yarnpkg.com/@safe-global/safe-apps-provider/-/safe-apps-provider-0.17.1.tgz#72df2a66be5343940ed505efe594ed3b0f2f7015" + integrity sha512-lYfRqrbbK1aKU1/UGkYWc/X7PgySYcumXKc5FB2uuwAs2Ghj8uETuW5BrwPqyjBknRxutFbTv+gth/JzjxAhdQ== + dependencies: + "@safe-global/safe-apps-sdk" "8.0.0" + events "^3.3.0" -"@rollup/plugin-json@^4.0.0": - version "4.1.0" - resolved "https://registry.yarnpkg.com/@rollup/plugin-json/-/plugin-json-4.1.0.tgz#54e09867ae6963c593844d8bd7a9c718294496f3" - integrity sha512-yfLbTdNS6amI/2OpmbiBoW12vngr5NW2jCJVZSBEz+H5KfUJZ2M7sDjk0U6GOOdCWFVScShte29o9NezJ53TPw== +"@safe-global/safe-apps-sdk@8.0.0": + version "8.0.0" + resolved "https://registry.yarnpkg.com/@safe-global/safe-apps-sdk/-/safe-apps-sdk-8.0.0.tgz#9bdfe0e0d85e1b2d279bb840f40c4b930aaf8bc1" + integrity sha512-gYw0ki/EAuV1oSyMxpqandHjnthZjYYy+YWpTAzf8BqfXM3ItcZLpjxfg+3+mXW8HIO+3jw6T9iiqEXsqHaMMw== dependencies: - "@rollup/pluginutils" "^3.0.8" + "@safe-global/safe-gateway-typescript-sdk" "^3.5.3" + viem "^1.0.0" -"@rollup/plugin-node-resolve@^9.0.0": - version "9.0.0" - resolved "https://registry.yarnpkg.com/@rollup/plugin-node-resolve/-/plugin-node-resolve-9.0.0.tgz#39bd0034ce9126b39c1699695f440b4b7d2b62e6" - integrity sha512-gPz+utFHLRrd41WMP13Jq5mqqzHL3OXrfj3/MkSyB6UBIcuNt9j60GCbarzMzdf1VHFpOxfQh/ez7wyadLMqkg== +"@safe-global/safe-apps-sdk@^9.1.0": + version "9.1.0" + resolved "https://registry.yarnpkg.com/@safe-global/safe-apps-sdk/-/safe-apps-sdk-9.1.0.tgz#0e65913e0f202e529ed3c846e0f5a98c2d35aa98" + integrity sha512-N5p/ulfnnA2Pi2M3YeWjULeWbjo7ei22JwU/IXnhoHzKq3pYCN6ynL9mJBOlvDVv892EgLPCWCOwQk/uBT2v0Q== dependencies: - "@rollup/pluginutils" "^3.1.0" - "@types/resolve" "1.17.1" - builtin-modules "^3.1.0" - deepmerge "^4.2.2" - is-module "^1.0.0" - resolve "^1.17.0" + "@safe-global/safe-gateway-typescript-sdk" "^3.5.3" + viem "^2.1.1" -"@rollup/plugin-replace@^2.2.1": - version "2.4.2" - resolved "https://registry.yarnpkg.com/@rollup/plugin-replace/-/plugin-replace-2.4.2.tgz#a2d539314fbc77c244858faa523012825068510a" - integrity sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg== - dependencies: - "@rollup/pluginutils" "^3.1.0" - magic-string "^0.25.7" +"@safe-global/safe-gateway-typescript-sdk@^3.5.3": + version "3.13.2" + resolved "https://registry.yarnpkg.com/@safe-global/safe-gateway-typescript-sdk/-/safe-gateway-typescript-sdk-3.13.2.tgz#f03884c7eb766f5508085d95ab96063a28e20920" + integrity sha512-kGlJecJHBzGrGTq/yhLANh56t+Zur6Ubpt+/w03ARX1poDb4TM8vKU3iV8tuYpk359PPWp+Qvjnqb9oW2YQcYw== -"@rollup/pluginutils@^3.0.8", "@rollup/pluginutils@^3.0.9", "@rollup/pluginutils@^3.1.0": - version "3.1.0" - resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-3.1.0.tgz#706b4524ee6dc8b103b3c995533e5ad680c02b9b" - integrity sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg== - dependencies: - "@types/estree" "0.0.39" - estree-walker "^1.0.1" - picomatch "^2.2.2" +"@scure/base@~1.1.0", "@scure/base@~1.1.2": + version "1.1.3" + resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.3.tgz#8584115565228290a6c6c4961973e0903bb3df2f" + integrity sha512-/+SgoRjLq7Xlf0CWuLHq2LUZeL/w65kfzAPG5NH9pcmBhs+nunQTn4gvdwgMTIXnt9b2C/1SeL2XiysZEyIC9Q== -"@rollup/pluginutils@^4.0.0": - version "4.2.1" - resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-4.2.1.tgz#e6c6c3aba0744edce3fb2074922d3776c0af2a6d" - integrity sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ== - dependencies: - estree-walker "^2.0.1" - picomatch "^2.2.2" - -"@sentry/browser@^6.12.0": - version "6.19.7" - resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-6.19.7.tgz#a40b6b72d911b5f1ed70ed3b4e7d4d4e625c0b5f" - integrity sha512-oDbklp4O3MtAM4mtuwyZLrgO1qDVYIujzNJQzXmi9YzymJCuzMLSRDvhY83NNDCRxf0pds4DShgYeZdbSyKraA== - dependencies: - "@sentry/core" "6.19.7" - "@sentry/types" "6.19.7" - "@sentry/utils" "6.19.7" - tslib "^1.9.3" - -"@sentry/core@6.19.7": - version "6.19.7" - resolved "https://registry.yarnpkg.com/@sentry/core/-/core-6.19.7.tgz#156aaa56dd7fad8c89c145be6ad7a4f7209f9785" - integrity sha512-tOfZ/umqB2AcHPGbIrsFLcvApdTm9ggpi/kQZFkej7kMphjT+SGBiQfYtjyg9jcRW+ilAR4JXC9BGKsdEQ+8Vw== - dependencies: - "@sentry/hub" "6.19.7" - "@sentry/minimal" "6.19.7" - "@sentry/types" "6.19.7" - "@sentry/utils" "6.19.7" - tslib "^1.9.3" - -"@sentry/hub@6.19.7": - version "6.19.7" - resolved "https://registry.yarnpkg.com/@sentry/hub/-/hub-6.19.7.tgz#58ad7776bbd31e9596a8ec46365b45cd8b9cfd11" - integrity sha512-y3OtbYFAqKHCWezF0EGGr5lcyI2KbaXW2Ik7Xp8Mu9TxbSTuwTe4rTntwg8ngPjUQU3SUHzgjqVB8qjiGqFXCA== - dependencies: - "@sentry/types" "6.19.7" - "@sentry/utils" "6.19.7" - tslib "^1.9.3" - -"@sentry/minimal@6.19.7": - version "6.19.7" - resolved "https://registry.yarnpkg.com/@sentry/minimal/-/minimal-6.19.7.tgz#b3ee46d6abef9ef3dd4837ebcb6bdfd01b9aa7b4" - integrity sha512-wcYmSJOdvk6VAPx8IcmZgN08XTXRwRtB1aOLZm+MVHjIZIhHoBGZJYTVQS/BWjldsamj2cX3YGbGXNunaCfYJQ== - dependencies: - "@sentry/hub" "6.19.7" - "@sentry/types" "6.19.7" - tslib "^1.9.3" - -"@sentry/types@6.19.7": - version "6.19.7" - resolved "https://registry.yarnpkg.com/@sentry/types/-/types-6.19.7.tgz#c6b337912e588083fc2896eb012526cf7cfec7c7" - integrity sha512-jH84pDYE+hHIbVnab3Hr+ZXr1v8QABfhx39KknxqKWr2l0oEItzepV0URvbEhB446lk/S/59230dlUUIBGsXbg== - -"@sentry/utils@6.19.7": - version "6.19.7" - resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-6.19.7.tgz#6edd739f8185fd71afe49cbe351c1bbf5e7b7c79" - integrity sha512-z95ECmE3i9pbWoXQrD/7PgkBAzJYR+iXtPuTkpBjDKs86O3mT+PXOT3BAn79w2wkn7/i3vOGD2xVr1uiMl26dA== - dependencies: - "@sentry/types" "6.19.7" - tslib "^1.9.3" - -"@sinclair/typebox@0.25.24": - version "0.25.24" - resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.25.24.tgz#8c7688559979f7079aacaf31aa881c3aa410b718" - integrity sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ== - -"@sindresorhus/is@^4.0.0": - version "4.6.0" - resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-4.6.0.tgz#3c7c9c46e678feefe7a2e5bb609d3dbd665ffb3f" - integrity sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw== +"@scure/base@~1.1.6": + version "1.1.7" + resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.7.tgz#fe973311a5c6267846aa131bc72e96c5d40d2b30" + integrity sha512-PPNYBslrLNNUQ/Yad37MHYsNQtK67EhWb6WtSvNLLPo7SdVZgkUjD6Dg+5On7zNwmskf8OX7I7Nx5oN+MIWE0g== + +"@scure/base@~1.1.8": + version "1.1.9" + resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.9.tgz#e5e142fbbfe251091f9c5f1dd4c834ac04c3dbd1" + integrity sha512-8YKhl8GHiNI/pU2VMaofa2Tor7PJRAjwQLBBuilkJ9L5+13yVbC7JO/wS7piioAvPSwR3JKM1IJ/u4xQzbcXKg== -"@sinonjs/commons@^1.7.0": - version "1.8.6" - resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.6.tgz#80c516a4dc264c2a69115e7578d62581ff455ed9" - integrity sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ== +"@scure/bip32@1.3.2": + version "1.3.2" + resolved "https://registry.yarnpkg.com/@scure/bip32/-/bip32-1.3.2.tgz#90e78c027d5e30f0b22c1f8d50ff12f3fb7559f8" + integrity sha512-N1ZhksgwD3OBlwTv3R6KFEcPojl/W4ElJOeCZdi+vuI5QmTFwLq3OFf2zd2ROpKvxFdgZ6hUpb0dx9bVNEwYCA== dependencies: - type-detect "4.0.8" + "@noble/curves" "~1.2.0" + "@noble/hashes" "~1.3.2" + "@scure/base" "~1.1.2" -"@size-limit/esbuild@8.2.4": - version "8.2.4" - resolved "https://registry.yarnpkg.com/@size-limit/esbuild/-/esbuild-8.2.4.tgz#20700c2e4b205c46d32c3a16c8426a219d973eab" - integrity sha512-kPgNfpwUvBD98s5axlf1UciFg4Ki4AYSl/cOmSyyYBuzksHiwW7Myeu0w4mTxtV9nwBFbkrrNXqszE7b+OhFLA== +"@scure/bip32@1.4.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@scure/bip32/-/bip32-1.4.0.tgz#4e1f1e196abedcef395b33b9674a042524e20d67" + integrity sha512-sVUpc0Vq3tXCkDGYVWGIZTRfnvu8LoTDaev7vbwh0omSvVORONr960MQWdKqJDCReIEmTj3PAr73O3aoxz7OPg== dependencies: - esbuild "^0.17.7" - nanoid "^3.3.4" + "@noble/curves" "~1.4.0" + "@noble/hashes" "~1.4.0" + "@scure/base" "~1.1.6" -"@size-limit/file@8.2.4": - version "8.2.4" - resolved "https://registry.yarnpkg.com/@size-limit/file/-/file-8.2.4.tgz#3624527cc9644c700697322d533e157b4a809a2b" - integrity sha512-xLuF97W7m7lxrRJvqXRlxO/4t7cpXtfxOnjml/t4aRVUCMXLdyvebRr9OM4jjoK8Fmiz8jomCbETUCI3jVhLzA== +"@scure/bip39@1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.2.1.tgz#5cee8978656b272a917b7871c981e0541ad6ac2a" + integrity sha512-Z3/Fsz1yr904dduJD0NpiyRHhRYHdcnyh73FZWiV+/qhWi83wNJ3NWolYqCEN+ZWsUz2TWwajJggcRE9r1zUYg== dependencies: - semver "7.3.8" + "@noble/hashes" "~1.3.0" + "@scure/base" "~1.1.0" -"@size-limit/preset-small-lib@^8.1.0": - version "8.2.4" - resolved "https://registry.yarnpkg.com/@size-limit/preset-small-lib/-/preset-small-lib-8.2.4.tgz#66121bc8eb0dadf5b2e3dd72ac7e2708429a2b21" - integrity sha512-AL4384oBgMcDPlNblgWHreqFSSOui0J9NbgyHhegB1h8AgRyHbdVGC3yWLpEESYQXHYnKdbNrYeRE/TclsViog== +"@scure/bip39@1.3.0": + version "1.3.0" + resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.3.0.tgz#0f258c16823ddd00739461ac31398b4e7d6a18c3" + integrity sha512-disdg7gHuTDZtY+ZdkmLpPCk7fxZSu3gBiEGuoC1XYxv9cGx3Z6cpTggCgW6odSOOIXCiDjuGejW+aJKCY/pIQ== dependencies: - "@size-limit/esbuild" "8.2.4" - "@size-limit/file" "8.2.4" + "@noble/hashes" "~1.4.0" + "@scure/base" "~1.1.6" -"@solana/buffer-layout@^4.0.0": +"@scure/bip39@1.4.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.4.0.tgz#664d4f851564e2e1d4bffa0339f9546ea55960a6" + integrity sha512-BEEm6p8IueV/ZTfQLp/0vhw4NPnT9oWf5+28nvmeUICjP99f4vr2d+qc7AVGDDtwRep6ifR43Yed9ERVmiITzw== + dependencies: + "@noble/hashes" "~1.5.0" + "@scure/base" "~1.1.8" + +"@sentry-internal/feedback@7.119.1": + version "7.119.1" + resolved "https://registry.yarnpkg.com/@sentry-internal/feedback/-/feedback-7.119.1.tgz#98285dc9dba0ab62369d758124901b00faf58697" + integrity sha512-EPyW6EKZmhKpw/OQUPRkTynXecZdYl4uhZwdZuGqnGMAzswPOgQvFrkwsOuPYvoMfXqCH7YuRqyJrox3uBOrTA== + dependencies: + "@sentry/core" "7.119.1" + "@sentry/types" "7.119.1" + "@sentry/utils" "7.119.1" + +"@sentry-internal/replay-canvas@7.119.1": + version "7.119.1" + resolved "https://registry.yarnpkg.com/@sentry-internal/replay-canvas/-/replay-canvas-7.119.1.tgz#b1413fb37734d609b0745ac24d49ddf9d63b9c51" + integrity sha512-O/lrzENbMhP/UDr7LwmfOWTjD9PLNmdaCF408Wx8SDuj7Iwc+VasGfHg7fPH4Pdr4nJON6oh+UqoV4IoG05u+A== + dependencies: + "@sentry/core" "7.119.1" + "@sentry/replay" "7.119.1" + "@sentry/types" "7.119.1" + "@sentry/utils" "7.119.1" + +"@sentry-internal/tracing@7.119.1": + version "7.119.1" + resolved "https://registry.yarnpkg.com/@sentry-internal/tracing/-/tracing-7.119.1.tgz#500d50d451bfd0ce6b185e9f112208229739ab03" + integrity sha512-cI0YraPd6qBwvUA3wQdPGTy8PzAoK0NZiaTN1LM3IczdPegehWOaEG5GVTnpGnTsmBAzn1xnBXNBhgiU4dgcrQ== + dependencies: + "@sentry/core" "7.119.1" + "@sentry/types" "7.119.1" + "@sentry/utils" "7.119.1" + +"@sentry/browser@^7.119.1": + version "7.119.1" + resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-7.119.1.tgz#260470dd7fd18de366017c3bf23a252a24d2ff05" + integrity sha512-aMwAnFU4iAPeLyZvqmOQaEDHt/Dkf8rpgYeJ0OEi50dmP6AjG+KIAMCXU7CYCCQDn70ITJo8QD5+KzCoZPYz0A== + dependencies: + "@sentry-internal/feedback" "7.119.1" + "@sentry-internal/replay-canvas" "7.119.1" + "@sentry-internal/tracing" "7.119.1" + "@sentry/core" "7.119.1" + "@sentry/integrations" "7.119.1" + "@sentry/replay" "7.119.1" + "@sentry/types" "7.119.1" + "@sentry/utils" "7.119.1" + +"@sentry/core@7.119.1": + version "7.119.1" + resolved "https://registry.yarnpkg.com/@sentry/core/-/core-7.119.1.tgz#63e949cad167a0ee5e52986c93b96ff1d6a05b57" + integrity sha512-YUNnH7O7paVd+UmpArWCPH4Phlb5LwrkWVqzFWqL3xPyCcTSof2RL8UmvpkTjgYJjJ+NDfq5mPFkqv3aOEn5Sw== + dependencies: + "@sentry/types" "7.119.1" + "@sentry/utils" "7.119.1" + +"@sentry/integrations@7.119.1": + version "7.119.1" + resolved "https://registry.yarnpkg.com/@sentry/integrations/-/integrations-7.119.1.tgz#9fc17aa9fcb942fbd2fc12eecd77a0f316897960" + integrity sha512-CGmLEPnaBqbUleVqrmGYjRjf5/OwjUXo57I9t0KKWViq81mWnYhaUhRZWFNoCNQHns+3+GPCOMvl0zlawt+evw== + dependencies: + "@sentry/core" "7.119.1" + "@sentry/types" "7.119.1" + "@sentry/utils" "7.119.1" + localforage "^1.8.1" + +"@sentry/replay@7.119.1": + version "7.119.1" + resolved "https://registry.yarnpkg.com/@sentry/replay/-/replay-7.119.1.tgz#117cf493a3008a39943b7d571d451c6218542847" + integrity sha512-4da+ruMEipuAZf35Ybt2StBdV1S+oJbSVccGpnl9w6RoeQoloT4ztR6ML3UcFDTXeTPT1FnHWDCyOfST0O7XMw== + dependencies: + "@sentry-internal/tracing" "7.119.1" + "@sentry/core" "7.119.1" + "@sentry/types" "7.119.1" + "@sentry/utils" "7.119.1" + +"@sentry/types@7.119.1": + version "7.119.1" + resolved "https://registry.yarnpkg.com/@sentry/types/-/types-7.119.1.tgz#f9c3c12e217c9078a6d556c92590e42a39b750dd" + integrity sha512-4G2mcZNnYzK3pa2PuTq+M2GcwBRY/yy1rF+HfZU+LAPZr98nzq2X3+mJHNJoobeHRkvVh7YZMPi4ogXiIS5VNQ== + +"@sentry/utils@7.119.1": + version "7.119.1" + resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-7.119.1.tgz#08b28fa8170987a60e149e2102e83395a95e9a89" + integrity sha512-ju/Cvyeu/vkfC5/XBV30UNet5kLEicZmXSyuLwZu95hEbL+foPdxN+re7pCI/eNqfe3B2vz7lvz5afLVOlQ2Hg== + dependencies: + "@sentry/types" "7.119.1" + +"@sinclair/typebox@^0.27.8": + version "0.27.8" + resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.27.8.tgz#6667fac16c436b5434a387a34dedb013198f6e6e" + integrity sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA== + +"@sinclair/typebox@^0.31.28": + version "0.31.28" + resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.31.28.tgz#b68831e7bc7d09daac26968ea32f42bedc968ede" + integrity sha512-/s55Jujywdw/Jpan+vsy6JZs1z2ZTGxTmbZTPiuSL2wz9mfzA2gN1zzaqmvfi4pq+uOt7Du85fkiwv5ymW84aQ== + +"@solana/buffer-layout@^4.0.1": version "4.0.1" resolved "https://registry.yarnpkg.com/@solana/buffer-layout/-/buffer-layout-4.0.1.tgz#b996235eaec15b1e0b5092a8ed6028df77fa6c15" integrity sha512-E1ImOIAD1tBZFRdjeM4/pzTiTApC0AOBGwyAMS4fwIodCWArzJ3DWdoh8cKxeFM2fElkxBh2Aqts1BPC373rHA== dependencies: buffer "~6.0.3" -"@solana/web3.js@^1.67.2": - version "1.74.0" - resolved "https://registry.yarnpkg.com/@solana/web3.js/-/web3.js-1.74.0.tgz#dbcbeabb830dd7cbbcf5e31404ca79c9785cbf2d" - integrity sha512-RKZyPqizPCxmpMGfpu4fuplNZEWCrhRBjjVstv5QnAJvgln1jgOfgui+rjl1ExnqDnWKg9uaZ5jtGROH/cwabg== - dependencies: - "@babel/runtime" "^7.12.5" - "@noble/ed25519" "^1.7.0" - "@noble/hashes" "^1.1.2" - "@noble/secp256k1" "^1.6.3" - "@solana/buffer-layout" "^4.0.0" - agentkeepalive "^4.2.1" +"@solana/wallet-standard-features@^1.1.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@solana/wallet-standard-features/-/wallet-standard-features-1.2.0.tgz#be8b3824abf5ebcfeaa7298445bf53f76a27c935" + integrity sha512-tUd9srDLkRpe1BYg7we+c4UhRQkq+XQWswsr/L1xfGmoRDF47BPSXf4zE7ZU2GRBGvxtGt7lwJVAufQyQYhxTQ== + dependencies: + "@wallet-standard/base" "^1.0.1" + "@wallet-standard/features" "^1.0.3" + +"@solana/web3.js@^1.90.2", "@solana/web3.js@^1.91.6": + version "1.93.0" + resolved "https://registry.yarnpkg.com/@solana/web3.js/-/web3.js-1.93.0.tgz#4b6975020993cec2f6626e4f2bf559ca042df8db" + integrity sha512-suf4VYwWxERz4tKoPpXCRHFRNst7jmcFUaD65kII+zg9urpy5PeeqgLV6G5eWGzcVzA9tZeXOju1A1Y+0ojEVw== + dependencies: + "@babel/runtime" "^7.24.7" + "@noble/curves" "^1.4.0" + "@noble/hashes" "^1.4.0" + "@solana/buffer-layout" "^4.0.1" + agentkeepalive "^4.5.0" bigint-buffer "^1.1.5" - bn.js "^5.0.0" + bn.js "^5.2.1" + borsh "^0.7.0" + bs58 "^4.0.1" + buffer "6.0.3" + fast-stable-stringify "^1.0.0" + jayson "^4.1.0" + node-fetch "^2.7.0" + rpc-websockets "^9.0.0" + superstruct "^1.0.4" + +"@solana/web3.js@^1.91.4": + version "1.91.4" + resolved "https://registry.yarnpkg.com/@solana/web3.js/-/web3.js-1.91.4.tgz#b80295ce72aa125930dfc5b41b4b4e3f85fd87fa" + integrity sha512-zconqecIcBqEF6JiM4xYF865Xc4aas+iWK5qnu7nwKPq9ilRYcn+2GiwpYXqUqqBUe0XCO17w18KO0F8h+QATg== + dependencies: + "@babel/runtime" "^7.23.4" + "@noble/curves" "^1.2.0" + "@noble/hashes" "^1.3.3" + "@solana/buffer-layout" "^4.0.1" + agentkeepalive "^4.5.0" + bigint-buffer "^1.1.5" + bn.js "^5.2.1" borsh "^0.7.0" bs58 "^4.0.1" - buffer "6.0.1" + buffer "6.0.3" fast-stable-stringify "^1.0.0" - jayson "^3.4.4" - node-fetch "^2.6.7" + jayson "^4.1.0" + node-fetch "^2.7.0" rpc-websockets "^7.5.1" superstruct "^0.14.2" -"@stitches/react@^1.2.8": - version "1.2.8" - resolved "https://registry.yarnpkg.com/@stitches/react/-/react-1.2.8.tgz#954f8008be8d9c65c4e58efa0937f32388ce3a38" - integrity sha512-9g9dWI4gsSVe8bNLlb+lMkBYsnIKCZTmvqvDG+Avnn69XfmHZKiaMrx7cgTaddq7aTPPmXiTsbFcUy0xgI4+wA== +"@solflare-wallet/metamask-sdk@^1.0.3": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@solflare-wallet/metamask-sdk/-/metamask-sdk-1.0.3.tgz#3baaa22de2c86515e6ba6025285cd1f5d74b04e5" + integrity sha512-os5Px5PTMYKGS5tzOoyjDxtOtj0jZKnbI1Uwt8+Jsw1HHIA+Ib2UACCGNhQ/un2f8sIbTfLD1WuucNMOy8KZpQ== + dependencies: + "@solana/wallet-standard-features" "^1.1.0" + "@wallet-standard/base" "^1.0.1" + bs58 "^5.0.0" + eventemitter3 "^5.0.1" + uuid "^9.0.0" -"@storybook/addon-actions@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/addon-actions/-/addon-actions-6.5.16.tgz#2d7679f64899bef165a338582cb928102a09e364" - integrity sha512-aADjilFmuD6TNGz2CRPSupnyiA/IGkPJHDBTqMpsDXTUr8xnuD122xkIhg6UxmCM2y1c+ncwYXy3WPK2xXK57g== - dependencies: - "@storybook/addons" "6.5.16" - "@storybook/api" "6.5.16" - "@storybook/client-logger" "6.5.16" - "@storybook/components" "6.5.16" - "@storybook/core-events" "6.5.16" - "@storybook/csf" "0.0.2--canary.4566f4d.1" - "@storybook/theming" "6.5.16" - core-js "^3.8.2" - fast-deep-equal "^3.1.3" - global "^4.4.0" - lodash "^4.17.21" - polished "^4.2.2" - prop-types "^15.7.2" - react-inspector "^5.1.0" - regenerator-runtime "^0.13.7" - telejson "^6.0.8" - ts-dedent "^2.0.0" - util-deprecate "^1.0.2" - uuid-browser "^3.1.0" - -"@storybook/addon-backgrounds@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/addon-backgrounds/-/addon-backgrounds-6.5.16.tgz#a93ea53955f714b4a4432dda1b88942cc87dd390" - integrity sha512-t7qooZ892BruhilFmzYPbysFwpULt/q4zYXNSmKVbAYta8UVvitjcU4F18p8FpWd9WvhiTr0SDlyhNZuzvDfug== - dependencies: - "@storybook/addons" "6.5.16" - "@storybook/api" "6.5.16" - "@storybook/client-logger" "6.5.16" - "@storybook/components" "6.5.16" - "@storybook/core-events" "6.5.16" - "@storybook/csf" "0.0.2--canary.4566f4d.1" - "@storybook/theming" "6.5.16" - core-js "^3.8.2" - global "^4.4.0" - memoizerific "^1.11.3" - regenerator-runtime "^0.13.7" - ts-dedent "^2.0.0" - util-deprecate "^1.0.2" +"@solflare-wallet/sdk@^1.4.2": + version "1.4.2" + resolved "https://registry.yarnpkg.com/@solflare-wallet/sdk/-/sdk-1.4.2.tgz#630b9a26f7bca255ee4a7088f287ae8c8335e345" + integrity sha512-jrseNWipwl9xXZgrzwZF3hhL0eIVxuEtoZOSLmuPuef7FgHjstuTtNJAeT4icA7pzdDV4hZvu54pI2r2f7SmrQ== + dependencies: + bs58 "^5.0.0" + eventemitter3 "^5.0.1" + uuid "^9.0.0" -"@storybook/addon-controls@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/addon-controls/-/addon-controls-6.5.16.tgz#5017805b8ca413edf6e9d87b90a9436e79eb5e59" - integrity sha512-kShSGjq1MjmmyL3l8i+uPz6yddtf82mzys0l82VKtcuyjrr5944wYFJ5NTXMfZxrO/U6FeFsfuFZE/k6ex3EMg== - dependencies: - "@storybook/addons" "6.5.16" - "@storybook/api" "6.5.16" - "@storybook/client-logger" "6.5.16" - "@storybook/components" "6.5.16" - "@storybook/core-common" "6.5.16" - "@storybook/csf" "0.0.2--canary.4566f4d.1" - "@storybook/node-logger" "6.5.16" - "@storybook/store" "6.5.16" - "@storybook/theming" "6.5.16" - core-js "^3.8.2" - lodash "^4.17.21" - ts-dedent "^2.0.0" +"@stablelib/aead@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@stablelib/aead/-/aead-1.0.1.tgz#c4b1106df9c23d1b867eb9b276d8f42d5fc4c0c3" + integrity sha512-q39ik6sxGHewqtO0nP4BuSe3db5G1fEJE8ukvngS2gLkBXyy6E7pLubhbYgnkDFv6V8cWaxcE4Xn0t6LWcJkyg== -"@storybook/addon-docs@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/addon-docs/-/addon-docs-6.5.16.tgz#3de912f51fb8e48b9a53b11a5b1cede067acbe70" - integrity sha512-QM9WDZG9P02UvbzLu947a8ZngOrQeAKAT8jCibQFM/+RJ39xBlfm8rm+cQy3dm94wgtjmVkA3mKGOV/yrrsddg== - dependencies: - "@babel/plugin-transform-react-jsx" "^7.12.12" - "@babel/preset-env" "^7.12.11" - "@jest/transform" "^26.6.2" - "@mdx-js/react" "^1.6.22" - "@storybook/addons" "6.5.16" - "@storybook/api" "6.5.16" - "@storybook/components" "6.5.16" - "@storybook/core-common" "6.5.16" - "@storybook/core-events" "6.5.16" - "@storybook/csf" "0.0.2--canary.4566f4d.1" - "@storybook/docs-tools" "6.5.16" - "@storybook/mdx1-csf" "^0.0.1" - "@storybook/node-logger" "6.5.16" - "@storybook/postinstall" "6.5.16" - "@storybook/preview-web" "6.5.16" - "@storybook/source-loader" "6.5.16" - "@storybook/store" "6.5.16" - "@storybook/theming" "6.5.16" - babel-loader "^8.0.0" - core-js "^3.8.2" - fast-deep-equal "^3.1.3" - global "^4.4.0" - lodash "^4.17.21" - regenerator-runtime "^0.13.7" - remark-external-links "^8.0.0" - remark-slug "^6.0.0" - ts-dedent "^2.0.0" - util-deprecate "^1.0.2" +"@stablelib/binary@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@stablelib/binary/-/binary-1.0.1.tgz#c5900b94368baf00f811da5bdb1610963dfddf7f" + integrity sha512-ClJWvmL6UBM/wjkvv/7m5VP3GMr9t0osr4yVgLZsLCOz4hGN9gIAFEqnJ0TsSMAN+n840nf2cHZnA5/KFqHC7Q== + dependencies: + "@stablelib/int" "^1.0.1" -"@storybook/addon-essentials@^6.5.13": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/addon-essentials/-/addon-essentials-6.5.16.tgz#815991366a4a90b60bf0aa4022eb0bb0c2bb536d" - integrity sha512-TeoMr6tEit4Pe91GH6f8g/oar1P4M0JL9S6oMcFxxrhhtOGO7XkWD5EnfyCx272Ok2VYfE58FNBTGPNBVIqYKQ== - dependencies: - "@storybook/addon-actions" "6.5.16" - "@storybook/addon-backgrounds" "6.5.16" - "@storybook/addon-controls" "6.5.16" - "@storybook/addon-docs" "6.5.16" - "@storybook/addon-measure" "6.5.16" - "@storybook/addon-outline" "6.5.16" - "@storybook/addon-toolbars" "6.5.16" - "@storybook/addon-viewport" "6.5.16" - "@storybook/addons" "6.5.16" - "@storybook/api" "6.5.16" - "@storybook/core-common" "6.5.16" - "@storybook/node-logger" "6.5.16" - core-js "^3.8.2" - regenerator-runtime "^0.13.7" - ts-dedent "^2.0.0" +"@stablelib/bytes@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@stablelib/bytes/-/bytes-1.0.1.tgz#0f4aa7b03df3080b878c7dea927d01f42d6a20d8" + integrity sha512-Kre4Y4kdwuqL8BR2E9hV/R5sOrUj6NanZaZis0V6lX5yzqC3hBuVSDXUIBqQv/sCpmuWRiHLwqiT1pqqjuBXoQ== -"@storybook/addon-info@^5.3.21": - version "5.3.21" - resolved "https://registry.yarnpkg.com/@storybook/addon-info/-/addon-info-5.3.21.tgz#fc8fd61d0471f4743b32f5ae8e5b7c84b52ff112" - integrity sha512-A/K9HzmoXMuOUxH3AozTvjNZwTlYVHob2OaDRfMza0gYMzG0tOrxqcdNTigeAWAjS//Z0G3enue6rHulQZK/+g== +"@stablelib/chacha20poly1305@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@stablelib/chacha20poly1305/-/chacha20poly1305-1.0.1.tgz#de6b18e283a9cb9b7530d8767f99cde1fec4c2ee" + integrity sha512-MmViqnqHd1ymwjOQfghRKw2R/jMIGT3wySN7cthjXCBdO+qErNPUBnRzqNpnvIwg7JBCg3LdeCZZO4de/yEhVA== dependencies: - "@storybook/addons" "5.3.21" - "@storybook/client-logger" "5.3.21" - "@storybook/components" "5.3.21" - "@storybook/theming" "5.3.21" - core-js "^3.0.1" - global "^4.3.2" - marksy "^8.0.0" - nested-object-assign "^1.0.3" - prop-types "^15.7.2" - react "^16.8.3" - react-addons-create-fragment "^15.6.2" - react-element-to-jsx-string "^14.0.2" - react-is "^16.8.3" - react-lifecycles-compat "^3.0.4" - util-deprecate "^1.0.2" + "@stablelib/aead" "^1.0.1" + "@stablelib/binary" "^1.0.1" + "@stablelib/chacha" "^1.0.1" + "@stablelib/constant-time" "^1.0.1" + "@stablelib/poly1305" "^1.0.1" + "@stablelib/wipe" "^1.0.1" -"@storybook/addon-links@^6.5.13": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/addon-links/-/addon-links-6.5.16.tgz#cacb20cd0656f0681a874709d428d3f3577828c3" - integrity sha512-P/mmqK57NGXnR0i3d/T5B0rIt0Lg8Yq+qionRr3LK3AwG/4yGnYt4GNomLEknn/eEwABYq1Q/Z1aOpgIhNdq5A== +"@stablelib/chacha@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@stablelib/chacha/-/chacha-1.0.1.tgz#deccfac95083e30600c3f92803a3a1a4fa761371" + integrity sha512-Pmlrswzr0pBzDofdFuVe1q7KdsHKhhU24e8gkEwnTGOmlC7PADzLVxGdn2PoNVBBabdg0l/IfLKg6sHAbTQugg== dependencies: - "@storybook/addons" "6.5.16" - "@storybook/client-logger" "6.5.16" - "@storybook/core-events" "6.5.16" - "@storybook/csf" "0.0.2--canary.4566f4d.1" - "@storybook/router" "6.5.16" - "@types/qs" "^6.9.5" - core-js "^3.8.2" - global "^4.4.0" - prop-types "^15.7.2" - qs "^6.10.0" - regenerator-runtime "^0.13.7" - ts-dedent "^2.0.0" + "@stablelib/binary" "^1.0.1" + "@stablelib/wipe" "^1.0.1" -"@storybook/addon-measure@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/addon-measure/-/addon-measure-6.5.16.tgz#7f7bfdc0b624fbf18386b20a5e460027bf87115c" - integrity sha512-DMwnXkmM2L6POTh4KaOWvOAtQ2p9Tr1UUNxz6VXiN5cKFohpCs6x0txdLU5WN8eWIq0VFsO7u5ZX34CGCc6gCg== - dependencies: - "@storybook/addons" "6.5.16" - "@storybook/api" "6.5.16" - "@storybook/client-logger" "6.5.16" - "@storybook/components" "6.5.16" - "@storybook/core-events" "6.5.16" - "@storybook/csf" "0.0.2--canary.4566f4d.1" - core-js "^3.8.2" - global "^4.4.0" +"@stablelib/constant-time@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@stablelib/constant-time/-/constant-time-1.0.1.tgz#bde361465e1cf7b9753061b77e376b0ca4c77e35" + integrity sha512-tNOs3uD0vSJcK6z1fvef4Y+buN7DXhzHDPqRLSXUel1UfqMB1PWNsnnAezrKfEwTLpN0cGH2p9NNjs6IqeD0eg== -"@storybook/addon-outline@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/addon-outline/-/addon-outline-6.5.16.tgz#6985b6a0b0122db36561c81dde2aa851604657b7" - integrity sha512-0du96nha4qltexO0Xq1xB7LeRSbqjC9XqtZLflXG7/X3ABoPD2cXgOV97eeaXUodIyb2qYBbHUfftBeA75x0+w== - dependencies: - "@storybook/addons" "6.5.16" - "@storybook/api" "6.5.16" - "@storybook/client-logger" "6.5.16" - "@storybook/components" "6.5.16" - "@storybook/core-events" "6.5.16" - "@storybook/csf" "0.0.2--canary.4566f4d.1" - core-js "^3.8.2" - global "^4.4.0" - regenerator-runtime "^0.13.7" - ts-dedent "^2.0.0" +"@stablelib/ed25519@^1.0.2": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@stablelib/ed25519/-/ed25519-1.0.3.tgz#f8fdeb6f77114897c887bb6a3138d659d3f35996" + integrity sha512-puIMWaX9QlRsbhxfDc5i+mNPMY+0TmQEskunY1rZEBPi1acBCVQAhnsk/1Hk50DGPtVsZtAWQg4NHGlVaO9Hqg== + dependencies: + "@stablelib/random" "^1.0.2" + "@stablelib/sha512" "^1.0.1" + "@stablelib/wipe" "^1.0.1" -"@storybook/addon-toolbars@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/addon-toolbars/-/addon-toolbars-6.5.16.tgz#9de04f9cc64b68d6cb680aa1c4fbf874e11afa32" - integrity sha512-y3PuUKiwOWrAvqx1YdUvArg0UaAwmboXFeR2bkrowk1xcT+xnRO3rML4npFeUl26OQ1FzwxX/cw6nknREBBLEA== - dependencies: - "@storybook/addons" "6.5.16" - "@storybook/api" "6.5.16" - "@storybook/client-logger" "6.5.16" - "@storybook/components" "6.5.16" - "@storybook/theming" "6.5.16" - core-js "^3.8.2" - regenerator-runtime "^0.13.7" +"@stablelib/hash@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@stablelib/hash/-/hash-1.0.1.tgz#3c944403ff2239fad8ebb9015e33e98444058bc5" + integrity sha512-eTPJc/stDkdtOcrNMZ6mcMK1e6yBbqRBaNW55XA1jU8w/7QdnCF0CmMmOD1m7VSkBR44PWrMHU2l6r8YEQHMgg== -"@storybook/addon-viewport@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/addon-viewport/-/addon-viewport-6.5.16.tgz#226aa0ab93df68264269eb31adb104e7e48f6c68" - integrity sha512-1Vyqf1U6Qng6TXlf4SdqUKyizlw1Wn6+qW8YeA2q1lbkJqn3UlnHXIp8Q0t/5q1dK5BFtREox3+jkGwbJrzkmA== - dependencies: - "@storybook/addons" "6.5.16" - "@storybook/api" "6.5.16" - "@storybook/client-logger" "6.5.16" - "@storybook/components" "6.5.16" - "@storybook/core-events" "6.5.16" - "@storybook/theming" "6.5.16" - core-js "^3.8.2" - global "^4.4.0" +"@stablelib/hkdf@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@stablelib/hkdf/-/hkdf-1.0.1.tgz#b4efd47fd56fb43c6a13e8775a54b354f028d98d" + integrity sha512-SBEHYE16ZXlHuaW5RcGk533YlBj4grMeg5TooN80W3NpcHRtLZLLXvKyX0qcRFxf+BGDobJLnwkvgEwHIDBR6g== + dependencies: + "@stablelib/hash" "^1.0.1" + "@stablelib/hmac" "^1.0.1" + "@stablelib/wipe" "^1.0.1" + +"@stablelib/hmac@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@stablelib/hmac/-/hmac-1.0.1.tgz#3d4c1b8cf194cb05d28155f0eed8a299620a07ec" + integrity sha512-V2APD9NSnhVpV/QMYgCVMIYKiYG6LSqw1S65wxVoirhU/51ACio6D4yDVSwMzuTJXWZoVHbDdINioBwKy5kVmA== + dependencies: + "@stablelib/constant-time" "^1.0.1" + "@stablelib/hash" "^1.0.1" + "@stablelib/wipe" "^1.0.1" + +"@stablelib/int@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@stablelib/int/-/int-1.0.1.tgz#75928cc25d59d73d75ae361f02128588c15fd008" + integrity sha512-byr69X/sDtDiIjIV6m4roLVWnNNlRGzsvxw+agj8CIEazqWGOQp2dTYgQhtyVXV9wpO6WyXRQUzLV/JRNumT2w== + +"@stablelib/keyagreement@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@stablelib/keyagreement/-/keyagreement-1.0.1.tgz#4612efb0a30989deb437cd352cee637ca41fc50f" + integrity sha512-VKL6xBwgJnI6l1jKrBAfn265cspaWBPAPEc62VBQrWHLqVgNRE09gQ/AnOEyKUWrrqfD+xSQ3u42gJjLDdMDQg== + dependencies: + "@stablelib/bytes" "^1.0.1" + +"@stablelib/poly1305@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@stablelib/poly1305/-/poly1305-1.0.1.tgz#93bfb836c9384685d33d70080718deae4ddef1dc" + integrity sha512-1HlG3oTSuQDOhSnLwJRKeTRSAdFNVB/1djy2ZbS35rBSJ/PFqx9cf9qatinWghC2UbfOYD8AcrtbUQl8WoxabA== + dependencies: + "@stablelib/constant-time" "^1.0.1" + "@stablelib/wipe" "^1.0.1" + +"@stablelib/random@^1.0.1", "@stablelib/random@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@stablelib/random/-/random-1.0.2.tgz#2dece393636489bf7e19c51229dd7900eddf742c" + integrity sha512-rIsE83Xpb7clHPVRlBj8qNe5L8ISQOzjghYQm/dZ7VaM2KHYwMW5adjQjrzTZCchFnNCNhkwtnOBa9HTMJCI8w== + dependencies: + "@stablelib/binary" "^1.0.1" + "@stablelib/wipe" "^1.0.1" + +"@stablelib/sha256@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@stablelib/sha256/-/sha256-1.0.1.tgz#77b6675b67f9b0ea081d2e31bda4866297a3ae4f" + integrity sha512-GIIH3e6KH+91FqGV42Kcj71Uefd/QEe7Dy42sBTeqppXV95ggCcxLTk39bEr+lZfJmp+ghsR07J++ORkRELsBQ== + dependencies: + "@stablelib/binary" "^1.0.1" + "@stablelib/hash" "^1.0.1" + "@stablelib/wipe" "^1.0.1" + +"@stablelib/sha512@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@stablelib/sha512/-/sha512-1.0.1.tgz#6da700c901c2c0ceacbd3ae122a38ac57c72145f" + integrity sha512-13gl/iawHV9zvDKciLo1fQ8Bgn2Pvf7OV6amaRVKiq3pjQ3UmEpXxWiAfV8tYjUpeZroBxtyrwtdooQT/i3hzw== + dependencies: + "@stablelib/binary" "^1.0.1" + "@stablelib/hash" "^1.0.1" + "@stablelib/wipe" "^1.0.1" + +"@stablelib/wipe@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@stablelib/wipe/-/wipe-1.0.1.tgz#d21401f1d59ade56a62e139462a97f104ed19a36" + integrity sha512-WfqfX/eXGiAd3RJe4VU2snh/ZPwtSjLG4ynQ/vYzvghTh7dHFcI1wl+nrkWG6lGhukOxOsUHfv8dUXr58D0ayg== + +"@stablelib/x25519@^1.0.3": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@stablelib/x25519/-/x25519-1.0.3.tgz#13c8174f774ea9f3e5e42213cbf9fc68a3c7b7fd" + integrity sha512-KnTbKmUhPhHavzobclVJQG5kuivH+qDLpe84iRqX3CLrKp881cF160JvXJ+hjn1aMyCwYOKeIZefIH/P5cJoRw== + dependencies: + "@stablelib/keyagreement" "^1.0.1" + "@stablelib/random" "^1.0.2" + "@stablelib/wipe" "^1.0.1" + +"@stitches/react@^1.2.8": + version "1.2.8" + resolved "https://registry.yarnpkg.com/@stitches/react/-/react-1.2.8.tgz#954f8008be8d9c65c4e58efa0937f32388ce3a38" + integrity sha512-9g9dWI4gsSVe8bNLlb+lMkBYsnIKCZTmvqvDG+Avnn69XfmHZKiaMrx7cgTaddq7aTPPmXiTsbFcUy0xgI4+wA== + +"@storybook/addon-actions@8.0.8": + version "8.0.8" + resolved "https://registry.yarnpkg.com/@storybook/addon-actions/-/addon-actions-8.0.8.tgz#0b625b36e738a3b02c25d7b0b0b9f28c4e68c918" + integrity sha512-F3qpN0n53d058EroW1A2IlzrsFNR5p2srLY4FmXB80nxAKV8oqoDI4jp15zYlf8ThcJoQl36plT8gx3r1BpANA== + dependencies: + "@storybook/core-events" "8.0.8" + "@storybook/global" "^5.0.0" + "@types/uuid" "^9.0.1" + dequal "^2.0.2" + polished "^4.2.2" + uuid "^9.0.0" + +"@storybook/addon-backgrounds@8.0.8": + version "8.0.8" + resolved "https://registry.yarnpkg.com/@storybook/addon-backgrounds/-/addon-backgrounds-8.0.8.tgz#da119e0fa0f0c6d44c2c44c34b9861953fedd653" + integrity sha512-lrAJjVxDeXSK116rDajb56TureZiT76ygraP22/IvU3IcWCEcRiKYwlay8WgCTbJHtFmdBpelLBapoT46+IR9Q== + dependencies: + "@storybook/global" "^5.0.0" memoizerific "^1.11.3" + ts-dedent "^2.0.0" + +"@storybook/addon-controls@8.0.8": + version "8.0.8" + resolved "https://registry.yarnpkg.com/@storybook/addon-controls/-/addon-controls-8.0.8.tgz#1c8e39ee9ac71704c60da79b363977006d587d75" + integrity sha512-7xANN18CLYsVthuSXwxKezqpelEKJlT9xaYLtw5vvD00btW5g3vxq+Z/A31OkS2OuaH2bE0GfRCoG2OLR8yQQA== + dependencies: + "@storybook/blocks" "8.0.8" + lodash "^4.17.21" + ts-dedent "^2.0.0" + +"@storybook/addon-docs@8.0.8": + version "8.0.8" + resolved "https://registry.yarnpkg.com/@storybook/addon-docs/-/addon-docs-8.0.8.tgz#0b5a7e60e32d955f42f3fcae9197e2de06946af4" + integrity sha512-HNiY4ESH9WxGS6QpIpURzdSbyDxbRh7VIgbvUrePSKajlsL4RFN/gdnn5TnSL00tOP/w+Cy/fXcbljMUKy7Ivg== + dependencies: + "@babel/core" "^7.12.3" + "@mdx-js/react" "^3.0.0" + "@storybook/blocks" "8.0.8" + "@storybook/client-logger" "8.0.8" + "@storybook/components" "8.0.8" + "@storybook/csf-plugin" "8.0.8" + "@storybook/csf-tools" "8.0.8" + "@storybook/global" "^5.0.0" + "@storybook/node-logger" "8.0.8" + "@storybook/preview-api" "8.0.8" + "@storybook/react-dom-shim" "8.0.8" + "@storybook/theming" "8.0.8" + "@storybook/types" "8.0.8" + "@types/react" "^16.8.0 || ^17.0.0 || ^18.0.0" + fs-extra "^11.1.0" + react "^16.8.0 || ^17.0.0 || ^18.0.0" + react-dom "^16.8.0 || ^17.0.0 || ^18.0.0" + rehype-external-links "^3.0.0" + rehype-slug "^6.0.0" + ts-dedent "^2.0.0" + +"@storybook/addon-essentials@^8.0.8": + version "8.0.8" + resolved "https://registry.yarnpkg.com/@storybook/addon-essentials/-/addon-essentials-8.0.8.tgz#b3e07dbce5fd8d903597b94a1ec99c4c08cd5472" + integrity sha512-bc9KJk7SPM2I5CCJEAP8R5leP+74IYxhWPiTN8Y1YFmf3MA1lpDJbwy+RfuRZ2ZKnSKszCXCVzU/T10HKUHLZw== + dependencies: + "@storybook/addon-actions" "8.0.8" + "@storybook/addon-backgrounds" "8.0.8" + "@storybook/addon-controls" "8.0.8" + "@storybook/addon-docs" "8.0.8" + "@storybook/addon-highlight" "8.0.8" + "@storybook/addon-measure" "8.0.8" + "@storybook/addon-outline" "8.0.8" + "@storybook/addon-toolbars" "8.0.8" + "@storybook/addon-viewport" "8.0.8" + "@storybook/core-common" "8.0.8" + "@storybook/manager-api" "8.0.8" + "@storybook/node-logger" "8.0.8" + "@storybook/preview-api" "8.0.8" + ts-dedent "^2.0.0" + +"@storybook/addon-highlight@8.0.8": + version "8.0.8" + resolved "https://registry.yarnpkg.com/@storybook/addon-highlight/-/addon-highlight-8.0.8.tgz#e4c1d2df7d4b4e325a007e4a7de5042cc5101625" + integrity sha512-KKD7xiNhxZQM4fdDidtcla6jSzgN1f9qe1AwFSHLXwIW22+4c97Vgf+AookN7cJvB77HxRUnvQH//zV1CJEDug== + dependencies: + "@storybook/global" "^5.0.0" + +"@storybook/addon-info@^5.3.21": + version "5.3.21" + resolved "https://registry.yarnpkg.com/@storybook/addon-info/-/addon-info-5.3.21.tgz#fc8fd61d0471f4743b32f5ae8e5b7c84b52ff112" + integrity sha512-A/K9HzmoXMuOUxH3AozTvjNZwTlYVHob2OaDRfMza0gYMzG0tOrxqcdNTigeAWAjS//Z0G3enue6rHulQZK/+g== + dependencies: + "@storybook/addons" "5.3.21" + "@storybook/client-logger" "5.3.21" + "@storybook/components" "5.3.21" + "@storybook/theming" "5.3.21" + core-js "^3.0.1" + global "^4.3.2" + marksy "^8.0.0" + nested-object-assign "^1.0.3" prop-types "^15.7.2" - regenerator-runtime "^0.13.7" + react "^16.8.3" + react-addons-create-fragment "^15.6.2" + react-element-to-jsx-string "^14.0.2" + react-is "^16.8.3" + react-lifecycles-compat "^3.0.4" + util-deprecate "^1.0.2" + +"@storybook/addon-links@^8.0.8": + version "8.0.8" + resolved "https://registry.yarnpkg.com/@storybook/addon-links/-/addon-links-8.0.8.tgz#9121b3b96e9aa696792596622582061c0320452b" + integrity sha512-iRI/W9I6fOom5zfZvsu53gfJtuhBSMmhgI/u5uZbAbfEoNL5D1PqpDXD4ygM8Vvlx90AZNZ2W5slEe7gCZOMyA== + dependencies: + "@storybook/csf" "^0.1.2" + "@storybook/global" "^5.0.0" + ts-dedent "^2.0.0" + +"@storybook/addon-measure@8.0.8": + version "8.0.8" + resolved "https://registry.yarnpkg.com/@storybook/addon-measure/-/addon-measure-8.0.8.tgz#297834f54331bcfd50b28cc935844ff13ba3aff9" + integrity sha512-akyoa+1F2ripV6ELF2UbxiSHv791LWSAVK7gsD/a5eJfKZMm5yoHjcY7Icdkc/ctE+pyjAQNhkXTixUngge09w== + dependencies: + "@storybook/global" "^5.0.0" + tiny-invariant "^1.3.1" + +"@storybook/addon-outline@8.0.8": + version "8.0.8" + resolved "https://registry.yarnpkg.com/@storybook/addon-outline/-/addon-outline-8.0.8.tgz#3441617f7f9246be1958ae3ce421bb4f691860ec" + integrity sha512-8Gxs095ekpa5YZolLSs5cWbWK94GZTevEUX8GFeLGIz9sf1KO3kmEO3eC5ogzDoB0cloqvbmVAJvYJ3FWiUx8w== + dependencies: + "@storybook/global" "^5.0.0" + ts-dedent "^2.0.0" + +"@storybook/addon-toolbars@8.0.8": + version "8.0.8" + resolved "https://registry.yarnpkg.com/@storybook/addon-toolbars/-/addon-toolbars-8.0.8.tgz#64d54974941633aef1814d557275127de1a7da9d" + integrity sha512-PZxlK+/Fwk2xcrpr5kkXYjCbBaEjAWcEHWq7mhQReMFaAs5AJE8dvmeQ7rmPDOHnlg4+YsARDFKz5FJtthRIgg== + +"@storybook/addon-viewport@8.0.8": + version "8.0.8" + resolved "https://registry.yarnpkg.com/@storybook/addon-viewport/-/addon-viewport-8.0.8.tgz#ed7a7fa0a9b89cc27130a549c3bea9a91404472c" + integrity sha512-nOuc6DquGvm24c/A0HFTgeEN/opd58ebs1KLaEEq1f6iYV0hT2Gpnk0Usg/seOiFtJnj3NyAM46HSkZz06T8Sw== + dependencies: + memoizerific "^1.11.3" "@storybook/addons@5.3.21": version "5.3.21" @@ -4552,22 +6274,14 @@ global "^4.3.2" util-deprecate "^1.0.2" -"@storybook/addons@6.5.16", "@storybook/addons@^6.5.13": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/addons/-/addons-6.5.16.tgz#07e8f2205f86fa4c9dada719e3e096cb468e3cdd" - integrity sha512-p3DqQi+8QRL5k7jXhXmJZLsE/GqHqyY6PcoA1oNTJr0try48uhTGUOYkgzmqtDaa/qPFO5LP+xCPzZXckGtquQ== - dependencies: - "@storybook/api" "6.5.16" - "@storybook/channels" "6.5.16" - "@storybook/client-logger" "6.5.16" - "@storybook/core-events" "6.5.16" - "@storybook/csf" "0.0.2--canary.4566f4d.1" - "@storybook/router" "6.5.16" - "@storybook/theming" "6.5.16" - "@types/webpack-env" "^1.16.0" - core-js "^3.8.2" - global "^4.4.0" - regenerator-runtime "^0.13.7" +"@storybook/addons@^7.1.1": + version "7.5.3" + resolved "https://registry.yarnpkg.com/@storybook/addons/-/addons-7.5.3.tgz#1a96c290a171ea97b255d9892e86f0e7c3517cd2" + integrity sha512-1JDndMZ/Pju4YJ4aXegeF0O6BVT19c+Gu7WOlsD0aHbmAsPK5qH9QvcpR04nby6VrVZYtBOEJhGsWtAytzLVZw== + dependencies: + "@storybook/manager-api" "7.5.3" + "@storybook/preview-api" "7.5.3" + "@storybook/types" "7.5.3" "@storybook/api@5.3.21": version "5.3.21" @@ -4595,105 +6309,118 @@ telejson "^3.2.0" util-deprecate "^1.0.2" -"@storybook/api@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/api/-/api-6.5.16.tgz#897915b76de05587fd702951d5d836f708043662" - integrity sha512-HOsuT8iomqeTMQJrRx5U8nsC7lJTwRr1DhdD0SzlqL4c80S/7uuCy4IZvOt4sYQjOzW5fOo/kamcoBXyLproTA== - dependencies: - "@storybook/channels" "6.5.16" - "@storybook/client-logger" "6.5.16" - "@storybook/core-events" "6.5.16" - "@storybook/csf" "0.0.2--canary.4566f4d.1" - "@storybook/router" "6.5.16" - "@storybook/semver" "^7.3.2" - "@storybook/theming" "6.5.16" - core-js "^3.8.2" - fast-deep-equal "^3.1.3" - global "^4.4.0" +"@storybook/blocks@8.0.8": + version "8.0.8" + resolved "https://registry.yarnpkg.com/@storybook/blocks/-/blocks-8.0.8.tgz#b31e01f53d534eed5380917ffce2a4a213496f9e" + integrity sha512-kwsjhvnmFEaIl51QHJt/83G7mZ5YbzFKnWCwy8WUpi0xvVcyoFQSGGgwR3XRrzGfUEPK8P2FDHeKw1bLzyIejA== + dependencies: + "@storybook/channels" "8.0.8" + "@storybook/client-logger" "8.0.8" + "@storybook/components" "8.0.8" + "@storybook/core-events" "8.0.8" + "@storybook/csf" "^0.1.2" + "@storybook/docs-tools" "8.0.8" + "@storybook/global" "^5.0.0" + "@storybook/icons" "^1.2.5" + "@storybook/manager-api" "8.0.8" + "@storybook/preview-api" "8.0.8" + "@storybook/theming" "8.0.8" + "@storybook/types" "8.0.8" + "@types/lodash" "^4.14.167" + color-convert "^2.0.1" + dequal "^2.0.2" lodash "^4.17.21" + markdown-to-jsx "7.3.2" memoizerific "^1.11.3" - regenerator-runtime "^0.13.7" - store2 "^2.12.0" - telejson "^6.0.8" + polished "^4.2.2" + react-colorful "^5.1.2" + telejson "^7.2.0" + tocbot "^4.20.1" ts-dedent "^2.0.0" util-deprecate "^1.0.2" -"@storybook/builder-webpack4@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/builder-webpack4/-/builder-webpack4-6.5.16.tgz#ac468d244835a7f3bd01936398fee47244da35c1" - integrity sha512-YqDIrVNsUo8r9xc6AxsYDLxVYtMgl5Bxk+8/h1adsOko+jAFhdg6hOcAVxEmoSI0TMASOOVMFlT2hr23ppN2rQ== - dependencies: - "@babel/core" "^7.12.10" - "@storybook/addons" "6.5.16" - "@storybook/api" "6.5.16" - "@storybook/channel-postmessage" "6.5.16" - "@storybook/channels" "6.5.16" - "@storybook/client-api" "6.5.16" - "@storybook/client-logger" "6.5.16" - "@storybook/components" "6.5.16" - "@storybook/core-common" "6.5.16" - "@storybook/core-events" "6.5.16" - "@storybook/node-logger" "6.5.16" - "@storybook/preview-web" "6.5.16" - "@storybook/router" "6.5.16" - "@storybook/semver" "^7.3.2" - "@storybook/store" "6.5.16" - "@storybook/theming" "6.5.16" - "@storybook/ui" "6.5.16" - "@types/node" "^14.0.10 || ^16.0.0" - "@types/webpack" "^4.41.26" - autoprefixer "^9.8.6" - babel-loader "^8.0.0" - case-sensitive-paths-webpack-plugin "^2.3.0" - core-js "^3.8.2" - css-loader "^3.6.0" - file-loader "^6.2.0" - find-up "^5.0.0" - fork-ts-checker-webpack-plugin "^4.1.6" - glob "^7.1.6" - glob-promise "^3.4.0" - global "^4.4.0" - html-webpack-plugin "^4.0.0" - pnp-webpack-plugin "1.6.4" - postcss "^7.0.36" - postcss-flexbugs-fixes "^4.2.1" - postcss-loader "^4.2.0" - raw-loader "^4.0.2" - stable "^0.1.8" - style-loader "^1.3.0" - terser-webpack-plugin "^4.2.3" +"@storybook/builder-manager@8.0.8": + version "8.0.8" + resolved "https://registry.yarnpkg.com/@storybook/builder-manager/-/builder-manager-8.0.8.tgz#23ed7b13aa98662ccc6bd1fb5525246a4469bd33" + integrity sha512-0uihNTpTou0RFMM6PQLlfCxDxse9nIDEb83AmWE/OUnpKDDY9+WFupVWGaZc9HfH9h4Yqre2fiuK1b7KNYe7AQ== + dependencies: + "@fal-works/esbuild-plugin-global-externals" "^2.1.2" + "@storybook/core-common" "8.0.8" + "@storybook/manager" "8.0.8" + "@storybook/node-logger" "8.0.8" + "@types/ejs" "^3.1.1" + "@yarnpkg/esbuild-plugin-pnp" "^3.0.0-rc.10" + browser-assert "^1.2.1" + ejs "^3.1.8" + esbuild "^0.18.0 || ^0.19.0 || ^0.20.0" + esbuild-plugin-alias "^0.2.1" + express "^4.17.3" + fs-extra "^11.1.0" + process "^0.11.10" + util "^0.12.4" + +"@storybook/builder-vite@8.0.8": + version "8.0.8" + resolved "https://registry.yarnpkg.com/@storybook/builder-vite/-/builder-vite-8.0.8.tgz#55b2af2fde1bce9c1647294938462d9ea50fe68b" + integrity sha512-ibWOxoHczCc6ttMQqiSXv29m/e44sKVoc1BJluApQcjCXl9g6QXyN45zV70odjCxMfNy7EQgUjCA0mgAgMHSIw== + dependencies: + "@storybook/channels" "8.0.8" + "@storybook/client-logger" "8.0.8" + "@storybook/core-common" "8.0.8" + "@storybook/core-events" "8.0.8" + "@storybook/csf-plugin" "8.0.8" + "@storybook/node-logger" "8.0.8" + "@storybook/preview" "8.0.8" + "@storybook/preview-api" "8.0.8" + "@storybook/types" "8.0.8" + "@types/find-cache-dir" "^3.2.1" + browser-assert "^1.2.1" + es-module-lexer "^0.9.3" + express "^4.17.3" + find-cache-dir "^3.0.0" + fs-extra "^11.1.0" + magic-string "^0.30.0" + ts-dedent "^2.0.0" + +"@storybook/builder-webpack5@8.0.8": + version "8.0.8" + resolved "https://registry.yarnpkg.com/@storybook/builder-webpack5/-/builder-webpack5-8.0.8.tgz#78649eeae401eaae4d9d76f6197d0211242b096e" + integrity sha512-NG7XHNSZ0+1DtHYhE36vDtXlZHVUUjC0TqqYQ3+On6Ormih80MndbmPjL6XhfleES8YzG28MhNePdOY867rehg== + dependencies: + "@storybook/channels" "8.0.8" + "@storybook/client-logger" "8.0.8" + "@storybook/core-common" "8.0.8" + "@storybook/core-events" "8.0.8" + "@storybook/core-webpack" "8.0.8" + "@storybook/node-logger" "8.0.8" + "@storybook/preview" "8.0.8" + "@storybook/preview-api" "8.0.8" + "@types/node" "^18.0.0" + "@types/semver" "^7.3.4" + browser-assert "^1.2.1" + case-sensitive-paths-webpack-plugin "^2.4.0" + cjs-module-lexer "^1.2.3" + constants-browserify "^1.0.0" + css-loader "^6.7.1" + es-module-lexer "^1.4.1" + express "^4.17.3" + fork-ts-checker-webpack-plugin "^8.0.0" + fs-extra "^11.1.0" + html-webpack-plugin "^5.5.0" + magic-string "^0.30.5" + path-browserify "^1.0.1" + process "^0.11.10" + semver "^7.3.7" + style-loader "^3.3.1" + terser-webpack-plugin "^5.3.1" ts-dedent "^2.0.0" - url-loader "^4.1.1" + url "^0.11.0" + util "^0.12.4" util-deprecate "^1.0.2" - webpack "4" - webpack-dev-middleware "^3.7.3" - webpack-filter-warnings-plugin "^1.2.1" + webpack "5" + webpack-dev-middleware "^6.1.2" webpack-hot-middleware "^2.25.1" - webpack-virtual-modules "^0.2.2" - -"@storybook/channel-postmessage@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/channel-postmessage/-/channel-postmessage-6.5.16.tgz#06167c0a66c06b2b5f8ff01d1dd436fff8119a15" - integrity sha512-fZZSN29dsUArWOx7e7lTdMA9+7zijVwCwbvi2Fo4fqhRLh1DsTb/VXfz1FKMCWAjNlcX7QQvV25tnxbqsD6lyw== - dependencies: - "@storybook/channels" "6.5.16" - "@storybook/client-logger" "6.5.16" - "@storybook/core-events" "6.5.16" - core-js "^3.8.2" - global "^4.4.0" - qs "^6.10.0" - telejson "^6.0.8" - -"@storybook/channel-websocket@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/channel-websocket/-/channel-websocket-6.5.16.tgz#41f69ca9444a4dfbf72580b4696900c5b1d2b817" - integrity sha512-wJg2lpBjmRC2GJFzmhB9kxlh109VE58r/0WhFtLbwKvPqsvGf82xkBEl6BtBCvIQ4stzYnj/XijjA8qSi2zpOg== - dependencies: - "@storybook/channels" "6.5.16" - "@storybook/client-logger" "6.5.16" - core-js "^3.8.2" - global "^4.4.0" - telejson "^6.0.8" + webpack-virtual-modules "^0.5.0" "@storybook/channels@5.3.21": version "5.3.21" @@ -4702,40 +6429,70 @@ dependencies: core-js "^3.0.1" -"@storybook/channels@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/channels/-/channels-6.5.16.tgz#3fb9a3b5666ecb951a2d0cf8b0699b084ef2d3c6" - integrity sha512-VylzaWQZaMozEwZPJdyJoz+0jpDa8GRyaqu9TGG6QGv+KU5POoZaGLDkRE7TzWkyyP0KQLo80K99MssZCpgSeg== +"@storybook/channels@7.5.3": + version "7.5.3" + resolved "https://registry.yarnpkg.com/@storybook/channels/-/channels-7.5.3.tgz#cbd178b0778f3484b970d0fd0edd294db6969e0f" + integrity sha512-dhWuV2o2lmxH0RKuzND8jxYzvSQTSmpE13P0IT/k8+I1up/rSNYOBQJT6SalakcNWXFAMXguo/8E7ApmnKKcEw== dependencies: - core-js "^3.8.2" - ts-dedent "^2.0.0" - util-deprecate "^1.0.2" - -"@storybook/client-api@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/client-api/-/client-api-6.5.16.tgz#13e5a7c3d1f0f951ec4ef51cfcf2c5aafb560e12" - integrity sha512-i3UwkzzUFw8I+E6fOcgB5sc4oU2fhvaKnqC1mpd9IYGJ9JN9MnGIaVl3Ko28DtFItu/QabC9JsLIJVripFLktQ== - dependencies: - "@storybook/addons" "6.5.16" - "@storybook/channel-postmessage" "6.5.16" - "@storybook/channels" "6.5.16" - "@storybook/client-logger" "6.5.16" - "@storybook/core-events" "6.5.16" - "@storybook/csf" "0.0.2--canary.4566f4d.1" - "@storybook/store" "6.5.16" - "@types/qs" "^6.9.5" - "@types/webpack-env" "^1.16.0" - core-js "^3.8.2" - fast-deep-equal "^3.1.3" - global "^4.4.0" - lodash "^4.17.21" - memoizerific "^1.11.3" + "@storybook/client-logger" "7.5.3" + "@storybook/core-events" "7.5.3" + "@storybook/global" "^5.0.0" qs "^6.10.0" - regenerator-runtime "^0.13.7" - store2 "^2.12.0" - synchronous-promise "^2.0.15" + telejson "^7.2.0" + tiny-invariant "^1.3.1" + +"@storybook/channels@8.0.8": + version "8.0.8" + resolved "https://registry.yarnpkg.com/@storybook/channels/-/channels-8.0.8.tgz#571b1ff9a58ae01a2172c877d87b1398d95c5579" + integrity sha512-L3EGVkabv3fweXnykD/GlNUDO5HtwlIfSovC7BF4MmP7662j2/eqlZrJxDojGtbv11XHjWp/UJHUIfKpcHXYjQ== + dependencies: + "@storybook/client-logger" "8.0.8" + "@storybook/core-events" "8.0.8" + "@storybook/global" "^5.0.0" + telejson "^7.2.0" + tiny-invariant "^1.3.1" + +"@storybook/cli@8.0.8": + version "8.0.8" + resolved "https://registry.yarnpkg.com/@storybook/cli/-/cli-8.0.8.tgz#e1c73a9c009823fdda795f3c3cf074a7fef8ea91" + integrity sha512-RnSdgykh2i7es1rQ7CNGpDrKK/PN1f0xjwpkAHXCEB6T9KpHBmqDquzZp+N127a1HBHHXy018yi4wT8mSQyEoA== + dependencies: + "@babel/core" "^7.23.0" + "@babel/types" "^7.23.0" + "@ndelangen/get-tarball" "^3.0.7" + "@storybook/codemod" "8.0.8" + "@storybook/core-common" "8.0.8" + "@storybook/core-events" "8.0.8" + "@storybook/core-server" "8.0.8" + "@storybook/csf-tools" "8.0.8" + "@storybook/node-logger" "8.0.8" + "@storybook/telemetry" "8.0.8" + "@storybook/types" "8.0.8" + "@types/semver" "^7.3.4" + "@yarnpkg/fslib" "2.10.3" + "@yarnpkg/libzip" "2.3.0" + chalk "^4.1.0" + commander "^6.2.1" + cross-spawn "^7.0.3" + detect-indent "^6.1.0" + envinfo "^7.7.3" + execa "^5.0.0" + find-up "^5.0.0" + fs-extra "^11.1.0" + get-npm-tarball-url "^2.0.3" + giget "^1.0.0" + globby "^11.0.2" + jscodeshift "^0.15.1" + leven "^3.1.0" + ora "^5.4.1" + prettier "^3.1.1" + prompts "^2.4.0" + read-pkg-up "^7.0.1" + semver "^7.3.7" + strip-json-comments "^3.0.1" + tempy "^1.0.1" + tiny-invariant "^1.3.1" ts-dedent "^2.0.0" - util-deprecate "^1.0.2" "@storybook/client-logger@5.3.21": version "5.3.21" @@ -4744,13 +6501,40 @@ dependencies: core-js "^3.0.1" -"@storybook/client-logger@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/client-logger/-/client-logger-6.5.16.tgz#955cc46b389e7151c9eb1585a75e6a0605af61a1" - integrity sha512-pxcNaCj3ItDdicPTXTtmYJE3YC1SjxFrBmHcyrN+nffeNyiMuViJdOOZzzzucTUG0wcOOX8jaSyak+nnHg5H1Q== - dependencies: - core-js "^3.8.2" - global "^4.4.0" +"@storybook/client-logger@7.5.3": + version "7.5.3" + resolved "https://registry.yarnpkg.com/@storybook/client-logger/-/client-logger-7.5.3.tgz#5a33a8a1785dbe6beff60654bc8947724c0cd62e" + integrity sha512-vUFYALypjix5FoJ5M/XUP6KmyTnQJNW1poHdW7WXUVSg+lBM6E5eAtjTm0hdxNNDH8KSrdy24nCLra5h0X0BWg== + dependencies: + "@storybook/global" "^5.0.0" + +"@storybook/client-logger@8.0.8": + version "8.0.8" + resolved "https://registry.yarnpkg.com/@storybook/client-logger/-/client-logger-8.0.8.tgz#351cc47629e91f188c6862038bf3a13cabb7d034" + integrity sha512-a4BKwl9NLFcuRgMyI7S4SsJeLFK0LCQxIy76V6YyrE1DigoXz4nA4eQxdjLf7JVvU0EZFmNSfbVL/bXzzWKNXA== + dependencies: + "@storybook/global" "^5.0.0" + +"@storybook/codemod@8.0.8": + version "8.0.8" + resolved "https://registry.yarnpkg.com/@storybook/codemod/-/codemod-8.0.8.tgz#1480bfc7c005ade0ec3181158103c82e70ffdf3f" + integrity sha512-ufEBLciLmLlAh+L6lGgBObTiny6odXMKqiJOewQ9XfIN0wdWdyRUf5QdZIPOdfgHhWF2Q2HeswiulsoHm8Z/hA== + dependencies: + "@babel/core" "^7.23.2" + "@babel/preset-env" "^7.23.2" + "@babel/types" "^7.23.0" + "@storybook/csf" "^0.1.2" + "@storybook/csf-tools" "8.0.8" + "@storybook/node-logger" "8.0.8" + "@storybook/types" "8.0.8" + "@types/cross-spawn" "^6.0.2" + cross-spawn "^7.0.3" + globby "^11.0.2" + jscodeshift "^0.15.1" + lodash "^4.17.21" + prettier "^3.1.1" + recast "^0.23.5" + tiny-invariant "^1.3.1" "@storybook/components@5.3.21": version "5.3.21" @@ -4779,101 +6563,54 @@ simplebar-react "^1.0.0-alpha.6" ts-dedent "^1.1.0" -"@storybook/components@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/components/-/components-6.5.16.tgz#f8dc51213bc08fe32154be964e1e8b0e2f670ed6" - integrity sha512-LzBOFJKITLtDcbW9jXl0/PaG+4xAz25PK8JxPZpIALbmOpYWOAPcO6V9C2heX6e6NgWFMUxjplkULEk9RCQMNA== - dependencies: - "@storybook/client-logger" "6.5.16" - "@storybook/csf" "0.0.2--canary.4566f4d.1" - "@storybook/theming" "6.5.16" - core-js "^3.8.2" +"@storybook/components@8.0.8": + version "8.0.8" + resolved "https://registry.yarnpkg.com/@storybook/components/-/components-8.0.8.tgz#e189a9eb2891e0677317d8e016c217ff35a8565e" + integrity sha512-EpBExH4kHWQJSfA8QXJJ5AsLRUGi5X/zWY7ffiYW8rtnBmEnk3T9FpmnyJlY1A8sdd3b1wQ07JGBDHfL1mdELw== + dependencies: + "@radix-ui/react-slot" "^1.0.2" + "@storybook/client-logger" "8.0.8" + "@storybook/csf" "^0.1.2" + "@storybook/global" "^5.0.0" + "@storybook/icons" "^1.2.5" + "@storybook/theming" "8.0.8" + "@storybook/types" "8.0.8" memoizerific "^1.11.3" - qs "^6.10.0" - regenerator-runtime "^0.13.7" - util-deprecate "^1.0.2" - -"@storybook/core-client@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/core-client/-/core-client-6.5.16.tgz#ed2328fd38c6111fe887f6a91b28d9dc2b17092a" - integrity sha512-14IRaDrVtKrQ+gNWC0wPwkCNfkZOKghYV/swCUnQX3rP99defsZK8Hc7xHIYoAiOP5+sc3sweRAxgmFiJeQ1Ig== - dependencies: - "@storybook/addons" "6.5.16" - "@storybook/channel-postmessage" "6.5.16" - "@storybook/channel-websocket" "6.5.16" - "@storybook/client-api" "6.5.16" - "@storybook/client-logger" "6.5.16" - "@storybook/core-events" "6.5.16" - "@storybook/csf" "0.0.2--canary.4566f4d.1" - "@storybook/preview-web" "6.5.16" - "@storybook/store" "6.5.16" - "@storybook/ui" "6.5.16" - airbnb-js-shims "^2.2.1" - ansi-to-html "^0.6.11" - core-js "^3.8.2" - global "^4.4.0" - lodash "^4.17.21" - qs "^6.10.0" - regenerator-runtime "^0.13.7" - ts-dedent "^2.0.0" - unfetch "^4.2.0" util-deprecate "^1.0.2" -"@storybook/core-common@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/core-common/-/core-common-6.5.16.tgz#db80aa6f220a576a83db821f720e103190a914ae" - integrity sha512-2qtnKP3TTOzt2cp6LXKRTh7XrI9z5VanMnMTgeoFcA5ebnndD4V6BExQUdYPClE/QooLx6blUWNgS9dFEpjSqQ== - dependencies: - "@babel/core" "^7.12.10" - "@babel/plugin-proposal-class-properties" "^7.12.1" - "@babel/plugin-proposal-decorators" "^7.12.12" - "@babel/plugin-proposal-export-default-from" "^7.12.1" - "@babel/plugin-proposal-nullish-coalescing-operator" "^7.12.1" - "@babel/plugin-proposal-object-rest-spread" "^7.12.1" - "@babel/plugin-proposal-optional-chaining" "^7.12.7" - "@babel/plugin-proposal-private-methods" "^7.12.1" - "@babel/plugin-proposal-private-property-in-object" "^7.12.1" - "@babel/plugin-syntax-dynamic-import" "^7.8.3" - "@babel/plugin-transform-arrow-functions" "^7.12.1" - "@babel/plugin-transform-block-scoping" "^7.12.12" - "@babel/plugin-transform-classes" "^7.12.1" - "@babel/plugin-transform-destructuring" "^7.12.1" - "@babel/plugin-transform-for-of" "^7.12.1" - "@babel/plugin-transform-parameters" "^7.12.1" - "@babel/plugin-transform-shorthand-properties" "^7.12.1" - "@babel/plugin-transform-spread" "^7.12.1" - "@babel/preset-env" "^7.12.11" - "@babel/preset-react" "^7.12.10" - "@babel/preset-typescript" "^7.12.7" - "@babel/register" "^7.12.1" - "@storybook/node-logger" "6.5.16" - "@storybook/semver" "^7.3.2" - "@types/node" "^14.0.10 || ^16.0.0" - "@types/pretty-hrtime" "^1.0.0" - babel-loader "^8.0.0" - babel-plugin-macros "^3.0.1" - babel-plugin-polyfill-corejs3 "^0.1.0" +"@storybook/core-common@8.0.8": + version "8.0.8" + resolved "https://registry.yarnpkg.com/@storybook/core-common/-/core-common-8.0.8.tgz#3a6136097559bcfa581a372516f67f13ace85655" + integrity sha512-CL15M2oeQW+Rb1l7ciunLDI2Re+ojL2lX1ZFAiDedcOU+JHsdq43zAuXoZVzp8icUi2AUSwEjZIxGCSingj+JQ== + dependencies: + "@storybook/core-events" "8.0.8" + "@storybook/csf-tools" "8.0.8" + "@storybook/node-logger" "8.0.8" + "@storybook/types" "8.0.8" + "@yarnpkg/fslib" "2.10.3" + "@yarnpkg/libzip" "2.3.0" chalk "^4.1.0" - core-js "^3.8.2" - express "^4.17.1" - file-system-cache "^1.0.5" + cross-spawn "^7.0.3" + esbuild "^0.18.0 || ^0.19.0 || ^0.20.0" + esbuild-register "^3.5.0" + execa "^5.0.0" + file-system-cache "2.3.0" + find-cache-dir "^3.0.0" find-up "^5.0.0" - fork-ts-checker-webpack-plugin "^6.0.4" - fs-extra "^9.0.1" - glob "^7.1.6" + fs-extra "^11.1.0" + glob "^10.0.0" handlebars "^4.7.7" - interpret "^2.2.0" - json5 "^2.2.3" - lazy-universal-dotenv "^3.0.1" + lazy-universal-dotenv "^4.0.0" + node-fetch "^2.0.0" picomatch "^2.3.0" pkg-dir "^5.0.0" pretty-hrtime "^1.0.3" resolve-from "^5.0.0" - slash "^3.0.0" - telejson "^6.0.8" + semver "^7.3.7" + tempy "^1.0.1" + tiny-invariant "^1.3.1" ts-dedent "^2.0.0" - util-deprecate "^1.0.2" - webpack "4" + util "^0.12.4" "@storybook/core-events@5.3.21": version "5.3.21" @@ -4882,90 +6619,101 @@ dependencies: core-js "^3.0.1" -"@storybook/core-events@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/core-events/-/core-events-6.5.16.tgz#b1c265dac755007dae172d9d4b72656c9e5d7bb3" - integrity sha512-qMZQwmvzpH5F2uwNUllTPg6eZXr2OaYZQRRN8VZJiuorZzDNdAFmiVWMWdkThwmyLEJuQKXxqCL8lMj/7PPM+g== +"@storybook/core-events@7.5.3": + version "7.5.3" + resolved "https://registry.yarnpkg.com/@storybook/core-events/-/core-events-7.5.3.tgz#210089576844569a914cc0cd1e07119bac6eb0e4" + integrity sha512-DFOpyQ22JD5C1oeOFzL8wlqSWZzrqgDfDbUGP8xdO4wJu+FVTxnnWN6ZYLdTPB1u27DOhd7TzjQMfLDHLu7kbQ== + dependencies: + ts-dedent "^2.0.0" + +"@storybook/core-events@8.0.8": + version "8.0.8" + resolved "https://registry.yarnpkg.com/@storybook/core-events/-/core-events-8.0.8.tgz#70b606bdcfd153b0e94ded4414069aac89e38419" + integrity sha512-PtuvR7vS4glDEdCfKB4f1k3Vs1C3rTWP2DNbF+IjjPhNLMBznCdzTAPcz+NUIBvpjjGnhKwWikJ0yj931YjSVg== dependencies: - core-js "^3.8.2" + ts-dedent "^2.0.0" -"@storybook/core-server@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/core-server/-/core-server-6.5.16.tgz#f40de3413de49388129d29c74e5e48321af03f12" - integrity sha512-/3NPfmNyply395Dm0zaVZ8P9aruwO+tPx4D6/jpw8aqrRSwvAMndPMpoMCm0NXcpSm5rdX+Je4S3JW6JcggFkA== +"@storybook/core-server@8.0.8": + version "8.0.8" + resolved "https://registry.yarnpkg.com/@storybook/core-server/-/core-server-8.0.8.tgz#2cb60f2ca58720f6257cb70327b93aea8f0df074" + integrity sha512-tSEueEBttbSohzhZVN2bFNlFx3eoqQ7p57cjQLKXXwKygS2qKxISKnFy+Y0nj20APz68Wj51kx0rN0nGALeegw== dependencies: + "@aw-web-design/x-default-browser" "1.4.126" + "@babel/core" "^7.23.9" "@discoveryjs/json-ext" "^0.5.3" - "@storybook/builder-webpack4" "6.5.16" - "@storybook/core-client" "6.5.16" - "@storybook/core-common" "6.5.16" - "@storybook/core-events" "6.5.16" - "@storybook/csf" "0.0.2--canary.4566f4d.1" - "@storybook/csf-tools" "6.5.16" - "@storybook/manager-webpack4" "6.5.16" - "@storybook/node-logger" "6.5.16" - "@storybook/semver" "^7.3.2" - "@storybook/store" "6.5.16" - "@storybook/telemetry" "6.5.16" - "@types/node" "^14.0.10 || ^16.0.0" - "@types/node-fetch" "^2.5.7" + "@storybook/builder-manager" "8.0.8" + "@storybook/channels" "8.0.8" + "@storybook/core-common" "8.0.8" + "@storybook/core-events" "8.0.8" + "@storybook/csf" "^0.1.2" + "@storybook/csf-tools" "8.0.8" + "@storybook/docs-mdx" "3.0.0" + "@storybook/global" "^5.0.0" + "@storybook/manager" "8.0.8" + "@storybook/manager-api" "8.0.8" + "@storybook/node-logger" "8.0.8" + "@storybook/preview-api" "8.0.8" + "@storybook/telemetry" "8.0.8" + "@storybook/types" "8.0.8" + "@types/detect-port" "^1.3.0" + "@types/node" "^18.0.0" "@types/pretty-hrtime" "^1.0.0" - "@types/webpack" "^4.41.26" - better-opn "^2.1.1" - boxen "^5.1.2" + "@types/semver" "^7.3.4" + better-opn "^3.0.2" chalk "^4.1.0" cli-table3 "^0.6.1" - commander "^6.2.1" compression "^1.7.4" - core-js "^3.8.2" - cpy "^8.1.2" detect-port "^1.3.0" - express "^4.17.1" - fs-extra "^9.0.1" - global "^4.4.0" + express "^4.17.3" + fs-extra "^11.1.0" globby "^11.0.2" - ip "^2.0.0" + ip "^2.0.1" lodash "^4.17.21" - node-fetch "^2.6.7" open "^8.4.0" pretty-hrtime "^1.0.3" prompts "^2.4.0" - regenerator-runtime "^0.13.7" - serve-favicon "^2.5.0" - slash "^3.0.0" - telejson "^6.0.8" + read-pkg-up "^7.0.1" + semver "^7.3.7" + telejson "^7.2.0" + tiny-invariant "^1.3.1" ts-dedent "^2.0.0" + util "^0.12.4" util-deprecate "^1.0.2" watchpack "^2.2.0" - webpack "4" ws "^8.2.3" - x-default-browser "^0.4.0" - -"@storybook/core@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/core/-/core-6.5.16.tgz#ae994f01327fe81b6e652963c35bac7a74f0da06" - integrity sha512-CEF3QFTsm/VMnMKtRNr4rRdLeIkIG0g1t26WcmxTdSThNPBd8CsWzQJ7Jqu7CKiut+MU4A1LMOwbwCE5F2gmyA== - dependencies: - "@storybook/core-client" "6.5.16" - "@storybook/core-server" "6.5.16" - -"@storybook/csf-tools@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/csf-tools/-/csf-tools-6.5.16.tgz#367889a3ddb33c93261129104ec2958215ec5459" - integrity sha512-+WD4sH/OwAfXZX3IN6/LOZ9D9iGEFcN+Vvgv9wOsLRgsAZ10DG/NK6c1unXKDM/ogJtJYccNI8Hd+qNE/GFV6A== - dependencies: - "@babel/core" "^7.12.10" - "@babel/generator" "^7.12.11" - "@babel/parser" "^7.12.11" - "@babel/plugin-transform-react-jsx" "^7.12.12" - "@babel/preset-env" "^7.12.11" - "@babel/traverse" "^7.12.11" - "@babel/types" "^7.12.11" - "@storybook/csf" "0.0.2--canary.4566f4d.1" - "@storybook/mdx1-csf" "^0.0.1" - core-js "^3.8.2" - fs-extra "^9.0.1" - global "^4.4.0" - regenerator-runtime "^0.13.7" + +"@storybook/core-webpack@8.0.8": + version "8.0.8" + resolved "https://registry.yarnpkg.com/@storybook/core-webpack/-/core-webpack-8.0.8.tgz#bbf4bb37eae32e0ea7bd1faf51a40a281e749b6b" + integrity sha512-wt7Ty2/aVAWSYbtXkpJ/oCi+NKc2SVrZVqqsasdt9IjAS4LTATZ89Ku0u1FKI61OhZbckVXBW5bPXJYibCK24Q== + dependencies: + "@storybook/core-common" "8.0.8" + "@storybook/node-logger" "8.0.8" + "@storybook/types" "8.0.8" + "@types/node" "^18.0.0" + ts-dedent "^2.0.0" + +"@storybook/csf-plugin@8.0.8": + version "8.0.8" + resolved "https://registry.yarnpkg.com/@storybook/csf-plugin/-/csf-plugin-8.0.8.tgz#91d5ad52236b7977f193f36c536a460aeae297e9" + integrity sha512-x9WspjZGcqXENj/Vn4Qmn0oTW93KN2V9wqpflWwCUJTByl2MugQsh5xRuDbs2yM7dD6zKcqRyPaTY+GFZBW+Vg== + dependencies: + "@storybook/csf-tools" "8.0.8" + unplugin "^1.3.1" + +"@storybook/csf-tools@8.0.8": + version "8.0.8" + resolved "https://registry.yarnpkg.com/@storybook/csf-tools/-/csf-tools-8.0.8.tgz#04f843bfc3961271adbb3e64be7e5e32396c51f8" + integrity sha512-Ji5fpoGym/MSyHJ6ALghVUUecwhEbN0On+jOZ2VPkrkATi9UDtryHQPdF60HKR63Iv53xRuWRzudB6zm43RTzw== + dependencies: + "@babel/generator" "^7.23.0" + "@babel/parser" "^7.23.0" + "@babel/traverse" "^7.23.2" + "@babel/types" "^7.23.0" + "@storybook/csf" "^0.1.2" + "@storybook/types" "8.0.8" + fs-extra "^11.1.0" + recast "^0.23.5" ts-dedent "^2.0.0" "@storybook/csf@0.0.1": @@ -4975,177 +6723,236 @@ dependencies: lodash "^4.17.15" -"@storybook/csf@0.0.2--canary.4566f4d.1": - version "0.0.2--canary.4566f4d.1" - resolved "https://registry.yarnpkg.com/@storybook/csf/-/csf-0.0.2--canary.4566f4d.1.tgz#dac52a21c40ef198554e71fe4d20d61e17f65327" - integrity sha512-9OVvMVh3t9znYZwb0Svf/YQoxX2gVOeQTGe2bses2yj+a3+OJnCrUF3/hGv6Em7KujtOdL2LL+JnG49oMVGFgQ== +"@storybook/csf@^0.1.0": + version "0.1.2" + resolved "https://registry.yarnpkg.com/@storybook/csf/-/csf-0.1.2.tgz#8e7452f0097507f5841b5ade3f5da1525bc9afb2" + integrity sha512-ePrvE/pS1vsKR9Xr+o+YwdqNgHUyXvg+1Xjx0h9LrVx7Zq4zNe06pd63F5EvzTbCbJsHj7GHr9tkiaqm7U8WRA== dependencies: - lodash "^4.17.15" + type-fest "^2.19.0" -"@storybook/docs-tools@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/docs-tools/-/docs-tools-6.5.16.tgz#1ec5433eeab63a214d37ffc4660cdaec9704ac39" - integrity sha512-o+rAWPRGifjBF5xZzTKOqnHN3XQWkl0QFJYVDIiJYJrVll7ExCkpEq/PahOGzIBBV+tpMstJgmKM3lr/lu/jmg== +"@storybook/csf@^0.1.2": + version "0.1.4" + resolved "https://registry.yarnpkg.com/@storybook/csf/-/csf-0.1.4.tgz#18224bcd571fa834ccc4bebda8a0ca4cedbc4d91" + integrity sha512-B9UI/lsQMjF+oEfZCI6YXNoeuBcGZoOP5x8yKbe2tIEmsMjSztFKkpPzi5nLCnBk/MBtl6QJeI3ksJnbsWPkOw== dependencies: - "@babel/core" "^7.12.10" - "@storybook/csf" "0.0.2--canary.4566f4d.1" - "@storybook/store" "6.5.16" - core-js "^3.8.2" + type-fest "^2.19.0" + +"@storybook/docs-mdx@3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@storybook/docs-mdx/-/docs-mdx-3.0.0.tgz#5c9b5ce35dcb00ad8aa5dddbabf52ad09fab3974" + integrity sha512-NmiGXl2HU33zpwTv1XORe9XG9H+dRUC1Jl11u92L4xr062pZtrShLmD4VKIsOQujxhhOrbxpwhNOt+6TdhyIdQ== + +"@storybook/docs-tools@8.0.8": + version "8.0.8" + resolved "https://registry.yarnpkg.com/@storybook/docs-tools/-/docs-tools-8.0.8.tgz#4a46a474dec06ea1f87ea577de5cbfb57f3ce71f" + integrity sha512-p/MIrDshXMl/fiCRlfG9StkRYI1QlUyUSQQ/YDBFlBfWcJYARIt3TIvQyvs3Q/apnQNcDXIW663W57s7WHTO2w== + dependencies: + "@storybook/core-common" "8.0.8" + "@storybook/preview-api" "8.0.8" + "@storybook/types" "8.0.8" + "@types/doctrine" "^0.0.3" + assert "^2.1.0" doctrine "^3.0.0" lodash "^4.17.21" - regenerator-runtime "^0.13.7" -"@storybook/manager-webpack4@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/manager-webpack4/-/manager-webpack4-6.5.16.tgz#7033228d38f048ceff3d403ba918d7f206b926a5" - integrity sha512-5VJZwmQU6AgdsBPsYdu886UKBHQ9SJEnFMaeUxKEclXk+iRsmbzlL4GHKyVd6oGX/ZaecZtcHPR6xrzmA4Ziew== - dependencies: - "@babel/core" "^7.12.10" - "@babel/plugin-transform-template-literals" "^7.12.1" - "@babel/preset-react" "^7.12.10" - "@storybook/addons" "6.5.16" - "@storybook/core-client" "6.5.16" - "@storybook/core-common" "6.5.16" - "@storybook/node-logger" "6.5.16" - "@storybook/theming" "6.5.16" - "@storybook/ui" "6.5.16" - "@types/node" "^14.0.10 || ^16.0.0" - "@types/webpack" "^4.41.26" - babel-loader "^8.0.0" - case-sensitive-paths-webpack-plugin "^2.3.0" - chalk "^4.1.0" - core-js "^3.8.2" - css-loader "^3.6.0" - express "^4.17.1" - file-loader "^6.2.0" - find-up "^5.0.0" - fs-extra "^9.0.1" - html-webpack-plugin "^4.0.0" - node-fetch "^2.6.7" - pnp-webpack-plugin "1.6.4" - read-pkg-up "^7.0.1" - regenerator-runtime "^0.13.7" - resolve-from "^5.0.0" - style-loader "^1.3.0" - telejson "^6.0.8" - terser-webpack-plugin "^4.2.3" +"@storybook/global@^5.0.0": + version "5.0.0" + resolved "https://registry.yarnpkg.com/@storybook/global/-/global-5.0.0.tgz#b793d34b94f572c1d7d9e0f44fac4e0dbc9572ed" + integrity sha512-FcOqPAXACP0I3oJ/ws6/rrPT9WGhu915Cg8D02a9YxLo0DE9zI+a9A5gRGvmQ09fiWPukqI8ZAEoQEdWUKMQdQ== + +"@storybook/icons@^1.2.5": + version "1.2.9" + resolved "https://registry.yarnpkg.com/@storybook/icons/-/icons-1.2.9.tgz#bb4a51a79e186b62e2dd0e04928b8617ac573838" + integrity sha512-cOmylsz25SYXaJL/gvTk/dl3pyk7yBFRfeXTsHvTA3dfhoU/LWSq0NKL9nM7WBasJyn6XPSGnLS4RtKXLw5EUg== + +"@storybook/manager-api@7.5.3": + version "7.5.3" + resolved "https://registry.yarnpkg.com/@storybook/manager-api/-/manager-api-7.5.3.tgz#6e9e791a8996631dc77f3a0cecc34ce4f4869647" + integrity sha512-d8mVLr/5BEG4bAS2ZeqYTy/aX4jPEpZHdcLaWoB4mAM+PAL9wcWsirUyApKtDVYLITJf/hd8bb2Dm2ok6E45gA== + dependencies: + "@storybook/channels" "7.5.3" + "@storybook/client-logger" "7.5.3" + "@storybook/core-events" "7.5.3" + "@storybook/csf" "^0.1.0" + "@storybook/global" "^5.0.0" + "@storybook/router" "7.5.3" + "@storybook/theming" "7.5.3" + "@storybook/types" "7.5.3" + dequal "^2.0.2" + lodash "^4.17.21" + memoizerific "^1.11.3" + semver "^7.3.7" + store2 "^2.14.2" + telejson "^7.2.0" ts-dedent "^2.0.0" - url-loader "^4.1.1" - util-deprecate "^1.0.2" - webpack "4" - webpack-dev-middleware "^3.7.3" - webpack-virtual-modules "^0.2.2" -"@storybook/mdx1-csf@^0.0.1": - version "0.0.1" - resolved "https://registry.yarnpkg.com/@storybook/mdx1-csf/-/mdx1-csf-0.0.1.tgz#d4184e3f6486fade9f7a6bfaf934d9bc07718d5b" - integrity sha512-4biZIWWzoWlCarMZmTpqcJNgo/RBesYZwGFbQeXiGYsswuvfWARZnW9RE9aUEMZ4XPn7B1N3EKkWcdcWe/K2tg== - dependencies: - "@babel/generator" "^7.12.11" - "@babel/parser" "^7.12.11" - "@babel/preset-env" "^7.12.11" - "@babel/types" "^7.12.11" - "@mdx-js/mdx" "^1.6.22" - "@types/lodash" "^4.14.167" - js-string-escape "^1.0.1" - loader-utils "^2.0.0" +"@storybook/manager-api@8.0.8": + version "8.0.8" + resolved "https://registry.yarnpkg.com/@storybook/manager-api/-/manager-api-8.0.8.tgz#e9c2661a8b2fe060076e9bb02fcdc7d498f6caed" + integrity sha512-1HU4nfLRi0sD2uw229gb8EQyufNWrLvMNpg013kBsBXRd+Dj4dqF3v+KrYFNtteY7riC4mAJ6YcQ4tBUNYZDug== + dependencies: + "@storybook/channels" "8.0.8" + "@storybook/client-logger" "8.0.8" + "@storybook/core-events" "8.0.8" + "@storybook/csf" "^0.1.2" + "@storybook/global" "^5.0.0" + "@storybook/icons" "^1.2.5" + "@storybook/router" "8.0.8" + "@storybook/theming" "8.0.8" + "@storybook/types" "8.0.8" + dequal "^2.0.2" lodash "^4.17.21" - prettier ">=2.2.1 <=2.3.0" + memoizerific "^1.11.3" + store2 "^2.14.2" + telejson "^7.2.0" ts-dedent "^2.0.0" -"@storybook/node-logger@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/node-logger/-/node-logger-6.5.16.tgz#d57fd6204c2abfbc297551d98ad5475dd73207cc" - integrity sha512-YjhBKrclQtjhqFNSO+BZK+RXOx6EQypAELJKoLFaawg331e8VUfvUuRCNB3fcEWp8G9oH13PQQte0OTjLyyOYg== - dependencies: - "@types/npmlog" "^4.1.2" - chalk "^4.1.0" - core-js "^3.8.2" - npmlog "^5.0.1" - pretty-hrtime "^1.0.3" +"@storybook/manager@8.0.8": + version "8.0.8" + resolved "https://registry.yarnpkg.com/@storybook/manager/-/manager-8.0.8.tgz#a90dd62b64348698308738d8a5986f02fb5671e8" + integrity sha512-pWYHSDmgT8p/XbQMKuDPdgB6KzjePI6dU5KQ5MERYfch1UiuGPVm1HHDlxxSfHW0IIXw9Qnwq4L0Awe4qhvJKQ== + +"@storybook/node-logger@8.0.8": + version "8.0.8" + resolved "https://registry.yarnpkg.com/@storybook/node-logger/-/node-logger-8.0.8.tgz#12d29cac99ef439aba0050f2fb03894ed4c52c86" + integrity sha512-ymps3MMTxtMWq0eDiXk1iO7iv0Eg0PuUvOpPPohEJauGzU9THv81xx01aaHKSprFFJYD2LMQr1aFuUplItO12g== + +"@storybook/preset-react-webpack@8.0.8": + version "8.0.8" + resolved "https://registry.yarnpkg.com/@storybook/preset-react-webpack/-/preset-react-webpack-8.0.8.tgz#ccf766d5cc8cd8b8bca5ac96a8c7e0342b67984c" + integrity sha512-ucdSQWE3VzleDprd5pmVbUbPPfkU9yLYvJ9pOO4XZngPY4fZdL3vWMsjhBL/PPs2tQ+pC3s6rWnrOqkSMmJ+7w== + dependencies: + "@storybook/core-webpack" "8.0.8" + "@storybook/docs-tools" "8.0.8" + "@storybook/node-logger" "8.0.8" + "@storybook/react" "8.0.8" + "@storybook/react-docgen-typescript-plugin" "1.0.6--canary.9.0c3f3b7.0" + "@types/node" "^18.0.0" + "@types/semver" "^7.3.4" + find-up "^5.0.0" + fs-extra "^11.1.0" + magic-string "^0.30.5" + react-docgen "^7.0.0" + resolve "^1.22.8" + semver "^7.3.7" + tsconfig-paths "^4.2.0" + webpack "5" -"@storybook/postinstall@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/postinstall/-/postinstall-6.5.16.tgz#20aa02fd4513fa0b60ed838b413c46f351f64f60" - integrity sha512-08K2q+qN6pqyPW7PHLCZ5G5Xa6Wosd6t0F16PQ4abX2ItlJLabVoJN5mZ0gm/aeLTjD8QYr8IDvacu4eXh0SVA== - dependencies: - core-js "^3.8.2" - -"@storybook/preview-web@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/preview-web/-/preview-web-6.5.16.tgz#1d32a72be25776f9597e33ffc1914f3430fae689" - integrity sha512-IJnvfe2sKCfk7apN9Fu9U8qibbarrPX5JB55ZzK1amSHVmSDuYk5MIMc/U3NnSQNnvd1DO5v/zMcGgj563hrtg== - dependencies: - "@storybook/addons" "6.5.16" - "@storybook/channel-postmessage" "6.5.16" - "@storybook/client-logger" "6.5.16" - "@storybook/core-events" "6.5.16" - "@storybook/csf" "0.0.2--canary.4566f4d.1" - "@storybook/store" "6.5.16" - ansi-to-html "^0.6.11" - core-js "^3.8.2" - global "^4.4.0" +"@storybook/preview-api@7.5.3": + version "7.5.3" + resolved "https://registry.yarnpkg.com/@storybook/preview-api/-/preview-api-7.5.3.tgz#eaf70f9b6888d0dac42ce39a296afd6acacf6156" + integrity sha512-LNmEf7oBRnZ1wG3bQ+P+TO29+NN5pSDJiAA6FabZBrtIVm+psc2lxBCDQvFYyAFzQSlt60toGKNW8+RfFNdR5Q== + dependencies: + "@storybook/channels" "7.5.3" + "@storybook/client-logger" "7.5.3" + "@storybook/core-events" "7.5.3" + "@storybook/csf" "^0.1.0" + "@storybook/global" "^5.0.0" + "@storybook/types" "7.5.3" + "@types/qs" "^6.9.5" + dequal "^2.0.2" lodash "^4.17.21" + memoizerific "^1.11.3" qs "^6.10.0" - regenerator-runtime "^0.13.7" synchronous-promise "^2.0.15" ts-dedent "^2.0.0" - unfetch "^4.2.0" util-deprecate "^1.0.2" -"@storybook/react-docgen-typescript-plugin@1.0.2-canary.6.9d540b91e815f8fc2f8829189deb00553559ff63.0": - version "1.0.2-canary.6.9d540b91e815f8fc2f8829189deb00553559ff63.0" - resolved "https://registry.yarnpkg.com/@storybook/react-docgen-typescript-plugin/-/react-docgen-typescript-plugin-1.0.2-canary.6.9d540b91e815f8fc2f8829189deb00553559ff63.0.tgz#3103532ff494fb7dc3cf835f10740ecf6a26c0f9" - integrity sha512-eVg3BxlOm2P+chijHBTByr90IZVUtgRW56qEOLX7xlww2NBuKrcavBlcmn+HH7GIUktquWkMPtvy6e0W0NgA5w== +"@storybook/preview-api@8.0.8": + version "8.0.8" + resolved "https://registry.yarnpkg.com/@storybook/preview-api/-/preview-api-8.0.8.tgz#0684226cd822b9266cceced26ce288b91ea6aa02" + integrity sha512-khgw2mNiBrSZS3KNGQPzjneL3Csh3BOq0yLAtJpT7CRSrI/YjlE7jjcTkKzoxW+UCgvNTnLvsowcuzu82e69fA== + dependencies: + "@storybook/channels" "8.0.8" + "@storybook/client-logger" "8.0.8" + "@storybook/core-events" "8.0.8" + "@storybook/csf" "^0.1.2" + "@storybook/global" "^5.0.0" + "@storybook/types" "8.0.8" + "@types/qs" "^6.9.5" + dequal "^2.0.2" + lodash "^4.17.21" + memoizerific "^1.11.3" + qs "^6.10.0" + tiny-invariant "^1.3.1" + ts-dedent "^2.0.0" + util-deprecate "^1.0.2" + +"@storybook/preview@8.0.8": + version "8.0.8" + resolved "https://registry.yarnpkg.com/@storybook/preview/-/preview-8.0.8.tgz#4a914fa1a512d664c77a43395453ddc4a229989a" + integrity sha512-J/ooKcvDV1s7ROH7lF/0vOyWDOgDB7bN6vS67J1WK0HLvMGaqUzU+q3ndakGzu0LU/jvUBqEFSZd1ALWyZINDQ== + +"@storybook/react-docgen-typescript-plugin@1.0.6--canary.9.0c3f3b7.0": + version "1.0.6--canary.9.0c3f3b7.0" + resolved "https://registry.yarnpkg.com/@storybook/react-docgen-typescript-plugin/-/react-docgen-typescript-plugin-1.0.6--canary.9.0c3f3b7.0.tgz#7f10f3c641f32e4513a8b6ffb5036933e7059534" + integrity sha512-KUqXC3oa9JuQ0kZJLBhVdS4lOneKTOopnNBK4tUAgoxWQ3u/IjzdueZjFr7gyBrXMoU6duutk3RQR9u8ZpYJ4Q== dependencies: debug "^4.1.1" endent "^2.0.1" find-cache-dir "^3.3.1" flat-cache "^3.0.4" micromatch "^4.0.2" - react-docgen-typescript "^2.1.1" + react-docgen-typescript "^2.2.2" tslib "^2.0.0" -"@storybook/react@^6.5.13": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/react/-/react-6.5.16.tgz#f7b82ba87f5bb73b4e4e83cce298a98710a88398" - integrity sha512-cBtNlOzf/MySpNLBK22lJ8wFU22HnfTB2xJyBk7W7Zi71Lm7Uxkhv1Pz8HdiQndJ0SlsAAQOWjQYsSZsGkZIaA== - dependencies: - "@babel/preset-flow" "^7.12.1" - "@babel/preset-react" "^7.12.10" - "@pmmmwh/react-refresh-webpack-plugin" "^0.5.3" - "@storybook/addons" "6.5.16" - "@storybook/client-logger" "6.5.16" - "@storybook/core" "6.5.16" - "@storybook/core-common" "6.5.16" - "@storybook/csf" "0.0.2--canary.4566f4d.1" - "@storybook/docs-tools" "6.5.16" - "@storybook/node-logger" "6.5.16" - "@storybook/react-docgen-typescript-plugin" "1.0.2-canary.6.9d540b91e815f8fc2f8829189deb00553559ff63.0" - "@storybook/semver" "^7.3.2" - "@storybook/store" "6.5.16" +"@storybook/react-dom-shim@8.0.8": + version "8.0.8" + resolved "https://registry.yarnpkg.com/@storybook/react-dom-shim/-/react-dom-shim-8.0.8.tgz#28370b050be3e5ebea296efa6bde01a792ac96fd" + integrity sha512-vOMlAz2HH/xfgZmSO28fCEmp5/tPxINDEdBDVLdZeYG6R1j5jlMRyaNcXt4cPNDkyc///PkB/K767hg4goca/Q== + +"@storybook/react-vite@^8.0.8": + version "8.0.8" + resolved "https://registry.yarnpkg.com/@storybook/react-vite/-/react-vite-8.0.8.tgz#2584d64ca1a8871da47a6e0cb5054c30248dc641" + integrity sha512-3xN+/KgcjEAKJ0cM8yFYk8+T59kgKSMlQaavoIgQudbEErSubr9l7jDWXH44afQIEBVs++ayYWrbEN2wyMGoug== + dependencies: + "@joshwooding/vite-plugin-react-docgen-typescript" "0.3.0" + "@rollup/pluginutils" "^5.0.2" + "@storybook/builder-vite" "8.0.8" + "@storybook/node-logger" "8.0.8" + "@storybook/react" "8.0.8" + find-up "^5.0.0" + magic-string "^0.30.0" + react-docgen "^7.0.0" + resolve "^1.22.8" + tsconfig-paths "^4.2.0" + +"@storybook/react-webpack5@^8.0.8": + version "8.0.8" + resolved "https://registry.yarnpkg.com/@storybook/react-webpack5/-/react-webpack5-8.0.8.tgz#f89010ee0fc0d5393bd1ce4d591f3bb89be6f06b" + integrity sha512-7K2hsT2H9B746bxrcFzIfbbaRajWkeZfeL7W8coSODpTUjC78Dno2bZO5FE3O0HdnbhJe2jJhDpJKVhFR0MKiQ== + dependencies: + "@storybook/builder-webpack5" "8.0.8" + "@storybook/preset-react-webpack" "8.0.8" + "@storybook/react" "8.0.8" + "@types/node" "^18.0.0" + +"@storybook/react@8.0.8", "@storybook/react@^8.0.8": + version "8.0.8" + resolved "https://registry.yarnpkg.com/@storybook/react/-/react-8.0.8.tgz#04374fd813e87763678c0c34eb1f2b91b01525e4" + integrity sha512-pPTlQntl09kv7qkAFYsxUq6qCLeeZC/K3yGFBGMy2Dc+PFjBYdT6mt2I8GB3twK0Cq5gJESlLj48QnYLQ/9PbA== + dependencies: + "@storybook/client-logger" "8.0.8" + "@storybook/docs-tools" "8.0.8" + "@storybook/global" "^5.0.0" + "@storybook/preview-api" "8.0.8" + "@storybook/react-dom-shim" "8.0.8" + "@storybook/types" "8.0.8" + "@types/escodegen" "^0.0.6" "@types/estree" "^0.0.51" - "@types/node" "^14.14.20 || ^16.0.0" - "@types/webpack-env" "^1.16.0" + "@types/node" "^18.0.0" acorn "^7.4.1" acorn-jsx "^5.3.1" acorn-walk "^7.2.0" - babel-plugin-add-react-displayname "^0.0.5" - babel-plugin-react-docgen "^4.2.1" - core-js "^3.8.2" - escodegen "^2.0.0" - fs-extra "^9.0.1" - global "^4.4.0" + escodegen "^2.1.0" html-tags "^3.1.0" lodash "^4.17.21" prop-types "^15.7.2" - react-element-to-jsx-string "^14.3.4" - react-refresh "^0.11.0" - read-pkg-up "^7.0.1" - regenerator-runtime "^0.13.7" + react-element-to-jsx-string "^15.0.0" + semver "^7.3.7" ts-dedent "^2.0.0" + type-fest "~2.19" util-deprecate "^1.0.2" - webpack ">=4.43.0 <6.0.0" "@storybook/router@5.3.21": version "5.3.21" @@ -5162,79 +6969,37 @@ qs "^6.6.0" util-deprecate "^1.0.2" -"@storybook/router@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/router/-/router-6.5.16.tgz#28fb4d34e8219351a40bee1fc94dcacda6e1bd8b" - integrity sha512-ZgeP8a5YV/iuKbv31V8DjPxlV4AzorRiR8OuSt/KqaiYXNXlOoQDz/qMmiNcrshrfLpmkzoq7fSo4T8lWo2UwQ== +"@storybook/router@7.5.3": + version "7.5.3" + resolved "https://registry.yarnpkg.com/@storybook/router/-/router-7.5.3.tgz#e024ad96bc4bbf7250239921a251e828729e4747" + integrity sha512-/iNYCFore7R5n6eFHbBYoB0P2/sybTVpA+uXTNUd3UEt7Ro6CEslTaFTEiH2RVQwOkceBp/NpyWon74xZuXhMg== dependencies: - "@storybook/client-logger" "6.5.16" - core-js "^3.8.2" + "@storybook/client-logger" "7.5.3" memoizerific "^1.11.3" qs "^6.10.0" - regenerator-runtime "^0.13.7" - -"@storybook/semver@^7.3.2": - version "7.3.2" - resolved "https://registry.yarnpkg.com/@storybook/semver/-/semver-7.3.2.tgz#f3b9c44a1c9a0b933c04e66d0048fcf2fa10dac0" - integrity sha512-SWeszlsiPsMI0Ps0jVNtH64cI5c0UF3f7KgjVKJoNP30crQ6wUSddY2hsdeczZXEKVJGEn50Q60flcGsQGIcrg== - dependencies: - core-js "^3.6.5" - find-up "^4.1.0" -"@storybook/source-loader@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/source-loader/-/source-loader-6.5.16.tgz#b691a024e6ff36bbd1144ecb4a65986f0e149741" - integrity sha512-fyVl4jrM/5JLrb48aqXPu7sTsmySQaVGFp1zfeqvPPlJRFMastDrePm5XGPN7Qjv1wsKmpuBvuweFKOT1pru3g== +"@storybook/router@8.0.8": + version "8.0.8" + resolved "https://registry.yarnpkg.com/@storybook/router/-/router-8.0.8.tgz#9688ff51590b303725e4db065483ec134dffe571" + integrity sha512-wdFdNsEKweigU9VkGZtpb7GhBJLWzbABcwOuEy2h0d5m7egB97hy9BxhANdqkC+PbAHrabxC99Ca3wTj50MoDg== dependencies: - "@storybook/addons" "6.5.16" - "@storybook/client-logger" "6.5.16" - "@storybook/csf" "0.0.2--canary.4566f4d.1" - core-js "^3.8.2" - estraverse "^5.2.0" - global "^4.4.0" - loader-utils "^2.0.4" - lodash "^4.17.21" - prettier ">=2.2.1 <=2.3.0" - regenerator-runtime "^0.13.7" + "@storybook/client-logger" "8.0.8" + memoizerific "^1.11.3" + qs "^6.10.0" -"@storybook/store@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/store/-/store-6.5.16.tgz#b308701293a3a11bfcc766770584495874fd17da" - integrity sha512-g+bVL5hmMq/9cM51K04e37OviUPHT0rHHrRm5wj/hrf18Kd9120b3sxdQ5Dc+HZ292yuME0n+cyrQPTYx9Epmw== +"@storybook/telemetry@8.0.8": + version "8.0.8" + resolved "https://registry.yarnpkg.com/@storybook/telemetry/-/telemetry-8.0.8.tgz#d477d9fcdc5d7a50692d39ba1e061c1e5e500d46" + integrity sha512-Uvj4nN01vQgjXZYKF/GKTFE85//Qm4ZTlJxTFWid+oYWc8NpAyJvlsJkj/dsEn4cLrgnJx2e4xvnx0Umr2ck+A== dependencies: - "@storybook/addons" "6.5.16" - "@storybook/client-logger" "6.5.16" - "@storybook/core-events" "6.5.16" - "@storybook/csf" "0.0.2--canary.4566f4d.1" - core-js "^3.8.2" - fast-deep-equal "^3.1.3" - global "^4.4.0" - lodash "^4.17.21" - memoizerific "^1.11.3" - regenerator-runtime "^0.13.7" - slash "^3.0.0" - stable "^0.1.8" - synchronous-promise "^2.0.15" - ts-dedent "^2.0.0" - util-deprecate "^1.0.2" - -"@storybook/telemetry@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/telemetry/-/telemetry-6.5.16.tgz#b13c8133e02c28e37b7716c987e7414b1ddc5363" - integrity sha512-CWr5Uko1l9jJW88yTXsZTj/3GTabPvw0o7pDPOXPp8JRZiJTxv1JFaFCafhK9UzYbgcRuGfCC8kEWPZims7iKA== - dependencies: - "@storybook/client-logger" "6.5.16" - "@storybook/core-common" "6.5.16" + "@storybook/client-logger" "8.0.8" + "@storybook/core-common" "8.0.8" + "@storybook/csf-tools" "8.0.8" chalk "^4.1.0" - core-js "^3.8.2" detect-package-manager "^2.0.1" fetch-retry "^5.0.2" - fs-extra "^9.0.1" - global "^4.4.0" - isomorphic-unfetch "^3.1.0" - nanoid "^3.3.1" + fs-extra "^11.1.0" read-pkg-up "^7.0.1" - regenerator-runtime "^0.13.7" "@storybook/theming@5.3.21": version "5.3.21" @@ -5254,101 +7019,591 @@ resolve-from "^5.0.0" ts-dedent "^1.1.0" -"@storybook/theming@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/theming/-/theming-6.5.16.tgz#b999bdb98945b605b93b9dfdf7408535b701e2aa" - integrity sha512-hNLctkjaYLRdk1+xYTkC1mg4dYz2wSv6SqbLpcKMbkPHTE0ElhddGPHQqB362md/w9emYXNkt1LSMD8Xk9JzVQ== +"@storybook/theming@7.5.3": + version "7.5.3" + resolved "https://registry.yarnpkg.com/@storybook/theming/-/theming-7.5.3.tgz#bbcf547c8b3ec1e59e641c58155a44781d5f310d" + integrity sha512-Cjmthe1MAk0z4RKCZ7m72gAD8YD0zTAH97z5ryM1Qv84QXjiCQ143fGOmYz1xEQdNFpOThPcwW6FEccLHTkVcg== dependencies: - "@storybook/client-logger" "6.5.16" - core-js "^3.8.2" + "@emotion/use-insertion-effect-with-fallbacks" "^1.0.0" + "@storybook/client-logger" "7.5.3" + "@storybook/global" "^5.0.0" memoizerific "^1.11.3" - regenerator-runtime "^0.13.7" -"@storybook/ui@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/ui/-/ui-6.5.16.tgz#c73bf456e672ecf2370b4365070088487fc0ce57" - integrity sha512-rHn/n12WM8BaXtZ3IApNZCiS+C4Oc5+Lkl4MoctX8V7QSml0SxZBB5hsJ/AiWkgbRxjQpa/L/Nt7/Qw0FjTH/A== - dependencies: - "@storybook/addons" "6.5.16" - "@storybook/api" "6.5.16" - "@storybook/channels" "6.5.16" - "@storybook/client-logger" "6.5.16" - "@storybook/components" "6.5.16" - "@storybook/core-events" "6.5.16" - "@storybook/router" "6.5.16" - "@storybook/semver" "^7.3.2" - "@storybook/theming" "6.5.16" - core-js "^3.8.2" +"@storybook/theming@8.0.8": + version "8.0.8" + resolved "https://registry.yarnpkg.com/@storybook/theming/-/theming-8.0.8.tgz#ef72edf6b7f37c0e7e2d6134eccfdff54618d8c6" + integrity sha512-43hkNz7yo8Bl97AO2WbxIGprUqMhUZyK9g8383bd30gSxy9nfND/bdSdcgmA8IokDn8qp37Q4QmxtUZdhjMzZQ== + dependencies: + "@emotion/use-insertion-effect-with-fallbacks" "^1.0.1" + "@storybook/client-logger" "8.0.8" + "@storybook/global" "^5.0.0" memoizerific "^1.11.3" - qs "^6.10.0" - regenerator-runtime "^0.13.7" - resolve-from "^5.0.0" -"@swc/helpers@^0.4.12": - version "0.4.14" - resolved "https://registry.yarnpkg.com/@swc/helpers/-/helpers-0.4.14.tgz#1352ac6d95e3617ccb7c1498ff019654f1e12a74" - integrity sha512-4C7nX/dvpzB7za4Ql9K81xK3HPxCpHMgwTZVyf+9JQ6VUbn9jjZVN7/Nkdz/Ugzs2CSjqnL/UPXroiVBVHUWUw== +"@storybook/types@7.5.3": + version "7.5.3" + resolved "https://registry.yarnpkg.com/@storybook/types/-/types-7.5.3.tgz#be956805dafc09fa9a7a3dd4e0e5097ef08e4fd4" + integrity sha512-iu5W0Kdd6nysN5CPkY4GRl+0BpxRTdSfBIJak7mb6xCIHSB5t1tw4BOuqMQ5EgpikRY3MWJ4gY647QkWBX3MNQ== + dependencies: + "@storybook/channels" "7.5.3" + "@types/babel__core" "^7.0.0" + "@types/express" "^4.7.0" + file-system-cache "2.3.0" + +"@storybook/types@8.0.8": + version "8.0.8" + resolved "https://registry.yarnpkg.com/@storybook/types/-/types-8.0.8.tgz#bf226aad7a3036490359e261607e6f7f234f6c9c" + integrity sha512-NGsgCsXnWlaZmHenHDgHGs21zhweZACkqTNsEQ7hvsiF08QeiKAdgJLQg3YeGK73h9mFDRP9djprUtJYab6vnQ== + dependencies: + "@storybook/channels" "8.0.8" + "@types/express" "^4.7.0" + file-system-cache "2.3.0" + +"@svgr/babel-plugin-add-jsx-attribute@8.0.0": + version "8.0.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-8.0.0.tgz#4001f5d5dd87fa13303e36ee106e3ff3a7eb8b22" + integrity sha512-b9MIk7yhdS1pMCZM8VeNfUlSKVRhsHZNMl5O9SfaX0l0t5wjdgu4IDzGB8bpnGBBOjGST3rRFVsaaEtI4W6f7g== + +"@svgr/babel-plugin-remove-jsx-attribute@8.0.0": + version "8.0.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-8.0.0.tgz#69177f7937233caca3a1afb051906698f2f59186" + integrity sha512-BcCkm/STipKvbCl6b7QFrMh/vx00vIP63k2eM66MfHJzPr6O2U0jYEViXkHJWqXqQYjdeA9cuCl5KWmlwjDvbA== + +"@svgr/babel-plugin-remove-jsx-empty-expression@8.0.0": + version "8.0.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-8.0.0.tgz#c2c48104cfd7dcd557f373b70a56e9e3bdae1d44" + integrity sha512-5BcGCBfBxB5+XSDSWnhTThfI9jcO5f0Ai2V24gZpG+wXF14BzwxxdDb4g6trdOux0rhibGs385BeFMSmxtS3uA== + +"@svgr/babel-plugin-replace-jsx-attribute-value@8.0.0": + version "8.0.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-8.0.0.tgz#8fbb6b2e91fa26ac5d4aa25c6b6e4f20f9c0ae27" + integrity sha512-KVQ+PtIjb1BuYT3ht8M5KbzWBhdAjjUPdlMtpuw/VjT8coTrItWX6Qafl9+ji831JaJcu6PJNKCV0bp01lBNzQ== + +"@svgr/babel-plugin-svg-dynamic-title@8.0.0": + version "8.0.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-8.0.0.tgz#1d5ba1d281363fc0f2f29a60d6d936f9bbc657b0" + integrity sha512-omNiKqwjNmOQJ2v6ge4SErBbkooV2aAWwaPFs2vUY7p7GhVkzRkJ00kILXQvRhA6miHnNpXv7MRnnSjdRjK8og== + +"@svgr/babel-plugin-svg-em-dimensions@8.0.0": + version "8.0.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-8.0.0.tgz#35e08df300ea8b1d41cb8f62309c241b0369e501" + integrity sha512-mURHYnu6Iw3UBTbhGwE/vsngtCIbHE43xCRK7kCw4t01xyGqb2Pd+WXekRRoFOBIY29ZoOhUCTEweDMdrjfi9g== + +"@svgr/babel-plugin-transform-react-native-svg@8.1.0": + version "8.1.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-8.1.0.tgz#90a8b63998b688b284f255c6a5248abd5b28d754" + integrity sha512-Tx8T58CHo+7nwJ+EhUwx3LfdNSG9R2OKfaIXXs5soiy5HtgoAEkDay9LIimLOcG8dJQH1wPZp/cnAv6S9CrR1Q== + +"@svgr/babel-plugin-transform-svg-component@8.0.0": + version "8.0.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-8.0.0.tgz#013b4bfca88779711f0ed2739f3f7efcefcf4f7e" + integrity sha512-DFx8xa3cZXTdb/k3kfPeaixecQLgKh5NVBMwD0AQxOzcZawK4oo1Jh9LbrcACUivsCA7TLG8eeWgrDXjTMhRmw== + +"@svgr/babel-preset@8.1.0": + version "8.1.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-preset/-/babel-preset-8.1.0.tgz#0e87119aecdf1c424840b9d4565b7137cabf9ece" + integrity sha512-7EYDbHE7MxHpv4sxvnVPngw5fuR6pw79SkcrILHJ/iMpuKySNCl5W1qcwPEpU+LgyRXOaAFgH0KhwD18wwg6ug== + dependencies: + "@svgr/babel-plugin-add-jsx-attribute" "8.0.0" + "@svgr/babel-plugin-remove-jsx-attribute" "8.0.0" + "@svgr/babel-plugin-remove-jsx-empty-expression" "8.0.0" + "@svgr/babel-plugin-replace-jsx-attribute-value" "8.0.0" + "@svgr/babel-plugin-svg-dynamic-title" "8.0.0" + "@svgr/babel-plugin-svg-em-dimensions" "8.0.0" + "@svgr/babel-plugin-transform-react-native-svg" "8.1.0" + "@svgr/babel-plugin-transform-svg-component" "8.0.0" + +"@svgr/cli@^8.0.1": + version "8.1.0" + resolved "https://registry.yarnpkg.com/@svgr/cli/-/cli-8.1.0.tgz#dd7fcf42a144eb681bb9923c5d806bf6cafd7512" + integrity sha512-SnlaLspB610XFXvs3PmhzViHErsXp0yIy4ERyZlHDlO1ro2iYtHMWYk2mztdLD/lBjiA4ZXe4RePON3qU/Tc4A== + dependencies: + "@svgr/core" "8.1.0" + "@svgr/plugin-jsx" "8.1.0" + "@svgr/plugin-prettier" "8.1.0" + "@svgr/plugin-svgo" "8.1.0" + camelcase "^6.2.0" + chalk "^4.1.2" + commander "^9.4.1" + dashify "^2.0.0" + glob "^8.0.3" + snake-case "^3.0.4" + +"@svgr/core@8.1.0": + version "8.1.0" + resolved "https://registry.yarnpkg.com/@svgr/core/-/core-8.1.0.tgz#41146f9b40b1a10beaf5cc4f361a16a3c1885e88" + integrity sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA== + dependencies: + "@babel/core" "^7.21.3" + "@svgr/babel-preset" "8.1.0" + camelcase "^6.2.0" + cosmiconfig "^8.1.3" + snake-case "^3.0.4" + +"@svgr/hast-util-to-babel-ast@8.0.0": + version "8.0.0" + resolved "https://registry.yarnpkg.com/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-8.0.0.tgz#6952fd9ce0f470e1aded293b792a2705faf4ffd4" + integrity sha512-EbDKwO9GpfWP4jN9sGdYwPBU0kdomaPIL2Eu4YwmgP+sJeXT+L7bMwJUBnhzfH8Q2qMBqZ4fJwpCyYsAN3mt2Q== + dependencies: + "@babel/types" "^7.21.3" + entities "^4.4.0" + +"@svgr/plugin-jsx@8.1.0": + version "8.1.0" + resolved "https://registry.yarnpkg.com/@svgr/plugin-jsx/-/plugin-jsx-8.1.0.tgz#96969f04a24b58b174ee4cd974c60475acbd6928" + integrity sha512-0xiIyBsLlr8quN+WyuxooNW9RJ0Dpr8uOnH/xrCVO8GLUcwHISwj1AG0k+LFzteTkAA0GbX0kj9q6Dk70PTiPA== + dependencies: + "@babel/core" "^7.21.3" + "@svgr/babel-preset" "8.1.0" + "@svgr/hast-util-to-babel-ast" "8.0.0" + svg-parser "^2.0.4" + +"@svgr/plugin-prettier@8.1.0": + version "8.1.0" + resolved "https://registry.yarnpkg.com/@svgr/plugin-prettier/-/plugin-prettier-8.1.0.tgz#71bf0d0b0ae4c2234a2deb0e5bad21c2cfe31364" + integrity sha512-o4/uFI8G64tAjBZ4E7gJfH+VP7Qi3T0+M4WnIsP91iFnGPqs5WvPDkpZALXPiyWEtzfYs1Rmwy1Zdfu8qoZuKw== + dependencies: + deepmerge "^4.3.1" + prettier "^2.8.7" + +"@svgr/plugin-svgo@8.1.0": + version "8.1.0" + resolved "https://registry.yarnpkg.com/@svgr/plugin-svgo/-/plugin-svgo-8.1.0.tgz#b115b7b967b564f89ac58feae89b88c3decd0f00" + integrity sha512-Ywtl837OGO9pTLIN/onoWLmDQ4zFUycI1g76vuKGEz6evR/ZTJlJuz3G/fIkb6OVBJ2g0o6CGJzaEjfmEo3AHA== + dependencies: + cosmiconfig "^8.1.3" + deepmerge "^4.3.1" + svgo "^3.0.2" + +"@swc/core-darwin-arm64@1.3.99": + version "1.3.99" + resolved "https://registry.yarnpkg.com/@swc/core-darwin-arm64/-/core-darwin-arm64-1.3.99.tgz#def204349ac645b8de21a800fa784907642a6c91" + integrity sha512-Qj7Jct68q3ZKeuJrjPx7k8SxzWN6PqLh+VFxzA+KwLDpQDPzOlKRZwkIMzuFjLhITO4RHgSnXoDk/Syz0ZeN+Q== + +"@swc/core-darwin-x64@1.3.99": + version "1.3.99" + resolved "https://registry.yarnpkg.com/@swc/core-darwin-x64/-/core-darwin-x64-1.3.99.tgz#2633f1ac1668ec569f34f86eb5250d56fcacd952" + integrity sha512-wR7m9QVJjgiBu1PSOHy7s66uJPa45Kf9bZExXUL+JAa9OQxt5y+XVzr+n+F045VXQOwdGWplgPnWjgbUUHEVyw== + +"@swc/core-linux-arm64-gnu@1.3.99": + version "1.3.99" + resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.3.99.tgz#871c2f049a3a5d88bcc7317ac004230517a08ba4" + integrity sha512-gcGv1l5t0DScEONmw5OhdVmEI/o49HCe9Ik38zzH0NtDkc+PDYaCcXU5rvfZP2qJFaAAr8cua8iJcOunOSLmnA== + +"@swc/core-linux-arm64-musl@1.3.99": + version "1.3.99" + resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.3.99.tgz#28ed1622e92bc13aab4b650f2af695af8695289b" + integrity sha512-XL1/eUsTO8BiKsWq9i3iWh7H99iPO61+9HYiWVKhSavknfj4Plbn+XyajDpxsauln5o8t+BRGitymtnAWJM4UQ== + +"@swc/core-linux-x64-gnu@1.3.99": + version "1.3.99" + resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.3.99.tgz#8e07add9cc8b76d542959e3240340effa6c6e446" + integrity sha512-fGrXYE6DbTfGNIGQmBefYxSk3rp/1lgbD0nVg4rl4mfFRQPi7CgGhrrqSuqZ/ezXInUIgoCyvYGWFSwjLXt/Qg== + +"@swc/core-linux-x64-musl@1.3.99": + version "1.3.99" + resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.3.99.tgz#677eb82d6862605cb0a81ec5b732bef2a9861b16" + integrity sha512-kvgZp/mqf3IJ806gUOL6gN6VU15+DfzM1Zv4Udn8GqgXiUAvbQehrtruid4Snn5pZTLj4PEpSCBbxgxK1jbssA== + +"@swc/core-win32-arm64-msvc@1.3.99": + version "1.3.99" + resolved "https://registry.yarnpkg.com/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.3.99.tgz#6c9bf96dd4cb81b5960884906766dc47a49efb0d" + integrity sha512-yt8RtZ4W/QgFF+JUemOUQAkVW58cCST7mbfKFZ1v16w3pl3NcWd9OrtppFIXpbjU1rrUX2zp2R7HZZzZ2Zk/aQ== + +"@swc/core-win32-ia32-msvc@1.3.99": + version "1.3.99" + resolved "https://registry.yarnpkg.com/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.3.99.tgz#6940a602b65137eee30f09ced7cd9fcb6e162b88" + integrity sha512-62p5fWnOJR/rlbmbUIpQEVRconICy5KDScWVuJg1v3GPLBrmacjphyHiJC1mp6dYvvoEWCk/77c/jcQwlXrDXw== + +"@swc/core-win32-x64-msvc@1.3.99": + version "1.3.99" + resolved "https://registry.yarnpkg.com/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.3.99.tgz#7fcdfe6577f015604f7e69f71dda99822e946385" + integrity sha512-PdppWhkoS45VGdMBxvClVgF1hVjqamtvYd82Gab1i4IV45OSym2KinoDCKE1b6j3LwBLOn2J9fvChGSgGfDCHQ== + +"@swc/core@^1.3.36": + version "1.3.99" + resolved "https://registry.yarnpkg.com/@swc/core/-/core-1.3.99.tgz#24a2ff0aaa1096b31046c8099b043936db0c4ca6" + integrity sha512-8O996RfuPC4ieb4zbYMfbyCU9k4gSOpyCNnr7qBQ+o7IEmh8JCV6B8wwu+fT/Om/6Lp34KJe1IpJ/24axKS6TQ== + dependencies: + "@swc/counter" "^0.1.1" + "@swc/types" "^0.1.5" + optionalDependencies: + "@swc/core-darwin-arm64" "1.3.99" + "@swc/core-darwin-x64" "1.3.99" + "@swc/core-linux-arm64-gnu" "1.3.99" + "@swc/core-linux-arm64-musl" "1.3.99" + "@swc/core-linux-x64-gnu" "1.3.99" + "@swc/core-linux-x64-musl" "1.3.99" + "@swc/core-win32-arm64-msvc" "1.3.99" + "@swc/core-win32-ia32-msvc" "1.3.99" + "@swc/core-win32-x64-msvc" "1.3.99" + +"@swc/counter@^0.1.1": + version "0.1.2" + resolved "https://registry.yarnpkg.com/@swc/counter/-/counter-0.1.2.tgz#bf06d0770e47c6f1102270b744e17b934586985e" + integrity sha512-9F4ys4C74eSTEUNndnER3VJ15oru2NumfQxS8geE+f3eB5xvfxpWyqE5XlVnxb/R14uoXi6SLbBwwiDSkv+XEw== + +"@swc/helpers@^0.5.0": + version "0.5.3" + resolved "https://registry.yarnpkg.com/@swc/helpers/-/helpers-0.5.3.tgz#98c6da1e196f5f08f977658b80d6bd941b5f294f" + integrity sha512-FaruWX6KdudYloq1AHD/4nU+UsMTdNE8CKyrseXWEcgjDAbvkwJg2QGPAnfIJLIWsjZOSPLOAykK6fuYp4vp4A== dependencies: tslib "^2.4.0" -"@szmarczak/http-timer@^4.0.5": - version "4.0.6" - resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-4.0.6.tgz#b4a914bb62e7c272d4e5989fe4440f812ab1d807" - integrity sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w== +"@swc/helpers@^0.5.11": + version "0.5.11" + resolved "https://registry.yarnpkg.com/@swc/helpers/-/helpers-0.5.11.tgz#5bab8c660a6e23c13b2d23fcd1ee44a2db1b0cb7" + integrity sha512-YNlnKRWF2sVojTpIyzwou9XoTNbzbzONwRhOoniEioF1AtaitTvVZblaQRrAzChWQ1bLYyYSWzM18y4WwgzJ+A== dependencies: - defer-to-connect "^2.0.0" + tslib "^2.4.0" -"@tootallnate/once@1": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" - integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw== +"@swc/types@^0.1.5": + version "0.1.5" + resolved "https://registry.yarnpkg.com/@swc/types/-/types-0.1.5.tgz#043b731d4f56a79b4897a3de1af35e75d56bc63a" + integrity sha512-myfUej5naTBWnqOCc/MdVOLVjXUXtIA+NpDrDBKJtLLg2shUjBu3cZmB/85RyitKc55+lUUyl7oRfLOvkr2hsw== -"@trysound/sax@0.2.0": - version "0.2.0" - resolved "https://registry.yarnpkg.com/@trysound/sax/-/sax-0.2.0.tgz#cccaab758af56761eb7bf37af6f03f326dd798ad" - integrity sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA== +"@terra-money/terra.js@^3.1.7": + version "3.1.10" + resolved "https://registry.yarnpkg.com/@terra-money/terra.js/-/terra.js-3.1.10.tgz#5707c8da2b8735d1b2a43fee0b1bf0da51c5a8f8" + integrity sha512-MqR16LjTUyVD4HnEavP1iBW0c1roCoRHH/E1x9P44pXzgtv2wsMeP+2un4Bnck4Nkv/46Xvy/BSKiY90ll3BKA== + dependencies: + "@classic-terra/terra.proto" "^1.1.0" + "@terra-money/terra.proto" "^2.1.0" + axios "^0.27.2" + bech32 "^2.0.0" + bip32 "^2.0.6" + bip39 "^3.0.3" + bufferutil "^4.0.3" + decimal.js "^10.2.1" + jscrypto "^1.0.1" + readable-stream "^3.6.0" + secp256k1 "^4.0.2" + tmp "^0.2.1" + utf-8-validate "^5.0.5" + ws "^7.5.9" -"@ts-morph/common@~0.11.0": - version "0.11.1" - resolved "https://registry.yarnpkg.com/@ts-morph/common/-/common-0.11.1.tgz#281af2a0642b19354d8aa07a0d50dfdb4aa8164e" - integrity sha512-7hWZS0NRpEsNV8vWJzg7FEz6V8MaLNeJOmwmghqUXTpzk16V1LLZhdo+4QvE/+zv4cVci0OviuJFnqhEfoV3+g== +"@terra-money/terra.proto@^2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@terra-money/terra.proto/-/terra.proto-2.1.0.tgz#5a2ed85fc8146a346d6095adfc5d205b6fb6d387" + integrity sha512-rhaMslv3Rkr+QsTQEZs64FKA4QlfO0DfQHaR6yct/EovenMkibDEQ63dEL6yJA6LCaEQGYhyVB9JO9pTUA8ybw== dependencies: - fast-glob "^3.2.7" - minimatch "^3.0.4" - mkdirp "^1.0.4" - path-browserify "^1.0.1" + "@improbable-eng/grpc-web" "^0.14.1" + google-protobuf "^3.17.3" + long "^4.0.0" + protobufjs "~6.11.2" -"@tsconfig/node10@^1.0.7": - version "1.0.9" - resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.9.tgz#df4907fc07a886922637b15e02d4cebc4c0021b2" - integrity sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA== +"@terra-money/wallet-controller@^3.11.2": + version "3.11.2" + resolved "https://registry.yarnpkg.com/@terra-money/wallet-controller/-/wallet-controller-3.11.2.tgz#6541f897790a4091b11154a57fa7c61e2df8a3b6" + integrity sha512-tnjBjXZoqL9Ar8LW0K5A3QRrZfO6Rt58sU2RsVWXSWtYiqpycHr0Px6ugfVGVkOgqhgawtNwoiO64kq2oOiXrA== + dependencies: + "@terra-money/wallet-types" "^3.11.2" + "@terra-money/web-extension-interface" "^3.11.2" + "@walletconnect/core" "^1.6.6" + "@walletconnect/iso-crypto" "^1.6.6" + "@walletconnect/types" "^1.6.6" + "@walletconnect/utils" "^1.6.6" + bowser "^2.11.0" + fast-deep-equal "^3.1.3" + jscrypto "^1.0.0" + mobile-detect "^1.4.5" + qrcode "^1.5.0" + rxjs "^7.0.0" + secp256k1 "^4.0.0" + ws "^7.5.5" + +"@terra-money/wallet-types@^3.11.2": + version "3.11.2" + resolved "https://registry.yarnpkg.com/@terra-money/wallet-types/-/wallet-types-3.11.2.tgz#5be7016abcd249b4839b1aadb837a6aa043dfaf2" + integrity sha512-vIHCqL4gtiAlvhnxDSnh6bTXIIZGNOIEfH/lWEgwCHXp4cGh0MeZixcnd4UvpW2ynirwtWkppAz9N4qX9zTtAA== + +"@terra-money/web-extension-interface@^3.11.2": + version "3.11.2" + resolved "https://registry.yarnpkg.com/@terra-money/web-extension-interface/-/web-extension-interface-3.11.2.tgz#7a3379238013dbb71adec4efc6051e1715f71e97" + integrity sha512-nnmhTbBkoTQ+XFmQ/0hPDnCCp/0x2EsZvTp/Md6KVGBWtWQg0gHCTwZVC8G5q48mD1WSS9ocRw3wBFSiVRPKoA== + dependencies: + rxjs "^7.0.0" + +"@testing-library/dom@^10.1.0": + version "10.4.0" + resolved "https://registry.yarnpkg.com/@testing-library/dom/-/dom-10.4.0.tgz#82a9d9462f11d240ecadbf406607c6ceeeff43a8" + integrity sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ== + dependencies: + "@babel/code-frame" "^7.10.4" + "@babel/runtime" "^7.12.5" + "@types/aria-query" "^5.0.1" + aria-query "5.3.0" + chalk "^4.1.0" + dom-accessibility-api "^0.5.9" + lz-string "^1.5.0" + pretty-format "^27.0.2" -"@tsconfig/node12@^1.0.7": - version "1.0.11" - resolved "https://registry.yarnpkg.com/@tsconfig/node12/-/node12-1.0.11.tgz#ee3def1f27d9ed66dac6e46a295cffb0152e058d" - integrity sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag== +"@testing-library/react-hooks@^8.0.1": + version "8.0.1" + resolved "https://registry.yarnpkg.com/@testing-library/react-hooks/-/react-hooks-8.0.1.tgz#0924bbd5b55e0c0c0502d1754657ada66947ca12" + integrity sha512-Aqhl2IVmLt8IovEVarNDFuJDVWVvhnr9/GCU6UUnrYXwgDFF9h2L2o2P9KBni1AST5sT6riAyoukFLyjQUgD/g== + dependencies: + "@babel/runtime" "^7.12.5" + react-error-boundary "^3.1.0" -"@tsconfig/node14@^1.0.0": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@tsconfig/node14/-/node14-1.0.3.tgz#e4386316284f00b98435bf40f72f75a09dabf6c1" - integrity sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow== +"@testing-library/react@^16.0.0": + version "16.1.0" + resolved "https://registry.yarnpkg.com/@testing-library/react/-/react-16.1.0.tgz#aa0c61398bac82eaf89776967e97de41ac742d71" + integrity sha512-Q2ToPvg0KsVL0ohND9A3zLJWcOXXcO8IDu3fj11KhNt0UlCWyFyvnCIBkd12tidB2lkiVRG8VFqdhcqhqnAQtg== + dependencies: + "@babel/runtime" "^7.12.5" -"@tsconfig/node16@^1.0.2": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.3.tgz#472eaab5f15c1ffdd7f8628bd4c4f753995ec79e" - integrity sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ== +"@ton/core@^0.59.0": + version "0.59.0" + resolved "https://registry.yarnpkg.com/@ton/core/-/core-0.59.0.tgz#58da9fcaa58e5a0c705b63baf1e86cab6e196689" + integrity sha512-LSIkGst7BoY7fMWshejzcH0UJnoW21JGlRrW0ch+6A7Xb/7EuekxgdKym7fHxcry6OIf6FoeFg97lJ960N/Ghg== + dependencies: + symbol.inspect "1.0.1" -"@types/acorn@^4.0.0": - version "4.0.6" - resolved "https://registry.yarnpkg.com/@types/acorn/-/acorn-4.0.6.tgz#d61ca5480300ac41a7d973dd5b84d0a591154a22" - integrity sha512-veQTnWP+1D/xbxVrPC3zHnCZRjSrKfhbMUlEA43iMZLu7EsnTtkJklIuwrCPbOi8YkvDQAiW05VQQFvvz9oieQ== +"@ton/crypto-primitives@2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@ton/crypto-primitives/-/crypto-primitives-2.1.0.tgz#8c9277c250b59aae3c819e0d6bd61e44d998e9ca" + integrity sha512-PQesoyPgqyI6vzYtCXw4/ZzevePc4VGcJtFwf08v10OevVJHVfW238KBdpj1kEDQkxWLeuNHEpTECNFKnP6tow== + dependencies: + jssha "3.2.0" + +"@ton/crypto@^3.3.0": + version "3.3.0" + resolved "https://registry.yarnpkg.com/@ton/crypto/-/crypto-3.3.0.tgz#019103df6540fbc1d8102979b4587bc85ff9779e" + integrity sha512-/A6CYGgA/H36OZ9BbTaGerKtzWp50rg67ZCH2oIjV1NcrBaCK9Z343M+CxedvM7Haf3f/Ee9EhxyeTp0GKMUpA== + dependencies: + "@ton/crypto-primitives" "2.1.0" + jssha "3.2.0" + tweetnacl "1.0.3" + +"@tonconnect/isomorphic-eventsource@^0.0.2": + version "0.0.2" + resolved "https://registry.yarnpkg.com/@tonconnect/isomorphic-eventsource/-/isomorphic-eventsource-0.0.2.tgz#e58c44cf9953e090f2c35da9a638946ddb614be5" + integrity sha512-B4UoIjPi0QkvIzZH5fV3BQLWrqSYABdrzZQSI9sJA9aA+iC0ohOzFwVVGXanlxeDAy1bcvPbb29f6sVUk0UnnQ== + dependencies: + eventsource "^2.0.2" + +"@tonconnect/isomorphic-fetch@^0.0.3": + version "0.0.3" + resolved "https://registry.yarnpkg.com/@tonconnect/isomorphic-fetch/-/isomorphic-fetch-0.0.3.tgz#31978e04ddc4428eff532c23d20229ed5ddb6417" + integrity sha512-jIg5nTrDwnite4fXao3dD83eCpTvInTjZon/rZZrIftIegh4XxyVb5G2mpMqXrVGk1e8SVXm3Kj5OtfMplQs0w== + dependencies: + node-fetch "^2.6.9" + +"@tonconnect/protocol@^2.2.6": + version "2.2.6" + resolved "https://registry.yarnpkg.com/@tonconnect/protocol/-/protocol-2.2.6.tgz#24b3fbcde6003e65fb5840a190072db5378699db" + integrity sha512-kyoDz5EqgsycYP+A+JbVsAUYHNT059BCrK+m0pqxykMODwpziuSAXfwAZmHcg8v7NB9VKYbdFY55xKeXOuEd0w== + dependencies: + tweetnacl "^1.0.3" + tweetnacl-util "^0.15.1" + +"@tonconnect/sdk@3.0.5": + version "3.0.5" + resolved "https://registry.yarnpkg.com/@tonconnect/sdk/-/sdk-3.0.5.tgz#08a202bdc8ea897c37221fd69925c35cd2106323" + integrity sha512-ow0qnN4s3iQ/r2uXobZ7YzdQBtan/36CgCT9IP35G07g38UxsUXwzw8ANmJTDj/JPiQcIKuYBMfIwIX9zLM0wg== + dependencies: + "@tonconnect/isomorphic-eventsource" "^0.0.2" + "@tonconnect/isomorphic-fetch" "^0.0.3" + "@tonconnect/protocol" "^2.2.6" + +"@tonconnect/ui@^2.0.9": + version "2.0.9" + resolved "https://registry.yarnpkg.com/@tonconnect/ui/-/ui-2.0.9.tgz#589285c9b8f4b0d94c10b3feadfae266bf086503" + integrity sha512-ZxofTBf81NqrxyD0ybI8AuFHN11uKVg/00xTDFhP5FoPB8rYC7En9qE2VJ6IvwvtTpmh8jspi2ancOHUMBoCQA== + dependencies: + "@tonconnect/sdk" "3.0.5" + classnames "^2.3.2" + deepmerge "^4.2.2" + ua-parser-js "^1.0.35" + +"@trezor/analytics@1.0.17": + version "1.0.17" + resolved "https://registry.yarnpkg.com/@trezor/analytics/-/analytics-1.0.17.tgz#5835fe8201498367104d9fa63a2cb6094ad2cbdc" + integrity sha512-FbMzdutD9OVbkhKaIqRJcEvqf7PeBkS3iqmQIKKVC1kL9R2w33D07pPNFMqgUqhV3CrOkjNkQOJpC8AxKxaIQw== + dependencies: + "@trezor/env-utils" "1.0.17" + "@trezor/utils" "9.0.24" + +"@trezor/blockchain-link-types@1.0.17": + version "1.0.17" + resolved "https://registry.yarnpkg.com/@trezor/blockchain-link-types/-/blockchain-link-types-1.0.17.tgz#92727159b6709fccc0710428f25ef422376c41bc" + integrity sha512-N37+dK/FtEaRhhQYpqQxmb041V83pXzHtXfUFvbQ3DAfXG1eBSg/q2UvIpDgQldL3r8uSUEh/Frh5OpR3KURfw== + dependencies: + "@solana/web3.js" "^1.91.6" + "@trezor/type-utils" "1.0.5" + "@trezor/utxo-lib" "2.0.10" + socks-proxy-agent "6.1.1" + +"@trezor/blockchain-link-utils@1.0.18": + version "1.0.18" + resolved "https://registry.yarnpkg.com/@trezor/blockchain-link-utils/-/blockchain-link-utils-1.0.18.tgz#ae1f2f1ab1b47901ce4265485917ae0cdf9d172c" + integrity sha512-kHjZX5GN7AIC+BU111wu6lTomaJiEEwehVgKG0g8rMsE5TWY1m4BazcH1jp5iUV7jR0B67Pd1jRMbgua59GsVQ== + dependencies: + "@mobily/ts-belt" "^3.13.1" + "@solana/web3.js" "^1.91.6" + "@trezor/env-utils" "1.0.17" + "@trezor/utils" "9.0.24" + +"@trezor/blockchain-link@2.1.30": + version "2.1.30" + resolved "https://registry.yarnpkg.com/@trezor/blockchain-link/-/blockchain-link-2.1.30.tgz#d995a7d8c008db57dc08d8690f964bbba26cbbae" + integrity sha512-OVo/j1pP4o4CzwnSVn2RLi5xO4RyqIxHUywYq/t6aBLM3+sAoHi1vtZM9DBAtrYnoXSsz+w9Uaj2DwSlKJ93bA== + dependencies: + "@solana/buffer-layout" "^4.0.1" + "@solana/web3.js" "^1.90.2" + "@trezor/blockchain-link-types" "1.0.17" + "@trezor/blockchain-link-utils" "1.0.18" + "@trezor/utils" "9.0.24" + "@trezor/utxo-lib" "2.0.10" + "@types/web" "^0.0.138" + events "^3.3.0" + ripple-lib "^1.10.1" + socks-proxy-agent "6.1.1" + ws "^8.16.0" + +"@trezor/connect-analytics@1.0.15": + version "1.0.15" + resolved "https://registry.yarnpkg.com/@trezor/connect-analytics/-/connect-analytics-1.0.15.tgz#489784e5b617f0ac6bb1d8626f37d794c1b2810d" + integrity sha512-LAf//pBuogLFBNuS47s3MFs1SfeyT+7Mh959wJTOXTC+DSmHUCLIrcahf6odGxR8moqVXUXgWoWPBQpc9WvKDA== + dependencies: + "@trezor/analytics" "1.0.17" + +"@trezor/connect-common@0.0.33": + version "0.0.33" + resolved "https://registry.yarnpkg.com/@trezor/connect-common/-/connect-common-0.0.33.tgz#2a36bf322615e9908502367ede93da0ba3b20719" + integrity sha512-OCGTjs1M4kmkiICQxz1QP52d31szWnO4EA3YkcLWPSGRNHjMV5c+DxoYU8FM6g1JSz9YW8SxjkGPAvHqowy0ZQ== + dependencies: + "@trezor/env-utils" "1.0.17" + "@trezor/utils" "9.0.24" + +"@trezor/connect-web@^9.2.4": + version "9.2.4" + resolved "https://registry.yarnpkg.com/@trezor/connect-web/-/connect-web-9.2.4.tgz#3d79ec291aa5317bdd132da0b0ab91b3f2d50f61" + integrity sha512-BatNwWzkg7hYLYhkJIuAbV74Uw1l0Lee0Xp+2XdR7muuXPBVs5GbqlFfI0DE6SM8oVvzvvAFufXW/zfYd0iTGA== + dependencies: + "@trezor/connect" "9.2.4" + "@trezor/connect-common" "0.0.33" + "@trezor/utils" "9.0.24" + events "^3.3.0" + +"@trezor/connect@9.2.4": + version "9.2.4" + resolved "https://registry.yarnpkg.com/@trezor/connect/-/connect-9.2.4.tgz#9ee90f26ea91bf5bba7d94e0b67b2fb1e0b52d61" + integrity sha512-uAmdIQrJA2I+1MMe1bYNZqZgsgYx5K4TGJx/10cU5U5uNifN83QBaRekmqQufyTkmXzArvWsbG2UK3oXHLd1OA== + dependencies: + "@babel/preset-typescript" "^7.23.3" + "@ethereumjs/common" "^4.2.0" + "@ethereumjs/tx" "^5.2.1" + "@fivebinaries/coin-selection" "2.2.1" + "@trezor/blockchain-link" "2.1.30" + "@trezor/blockchain-link-types" "1.0.17" + "@trezor/connect-analytics" "1.0.15" + "@trezor/connect-common" "0.0.33" + "@trezor/protobuf" "1.0.13" + "@trezor/protocol" "1.0.9" + "@trezor/schema-utils" "1.0.4" + "@trezor/transport" "1.1.29" + "@trezor/utils" "9.0.24" + "@trezor/utxo-lib" "2.0.10" + blakejs "^1.2.1" + bs58 "^5.0.0" + bs58check "^3.0.1" + cross-fetch "^4.0.0" + events "^3.3.0" + +"@trezor/env-utils@1.0.17": + version "1.0.17" + resolved "https://registry.yarnpkg.com/@trezor/env-utils/-/env-utils-1.0.17.tgz#ea1f28e95113af8fbbfa49ebba060b6fc5d2a3f5" + integrity sha512-S6pY5VqmIdhQaXFOvfXJtxLkZs3WYeL1ZES9ZMmvCeP/mu0uBByxUoywFNu2bLaLYNitMYgCVFMCmo7jWfss0Q== + dependencies: + ua-parser-js "^1.0.37" + +"@trezor/protobuf@1.0.13": + version "1.0.13" + resolved "https://registry.yarnpkg.com/@trezor/protobuf/-/protobuf-1.0.13.tgz#90257e665d253661dd8da3206f18e08b8db19678" + integrity sha512-RqQsqEbwfJGYjzu/CG47v17fiABEZvlCvdLMWlfCB+LB5hzamTLEE3pMRrnsC5iJIPaA+ZSnhAIWznqVf8NOhw== dependencies: - "@types/estree" "*" + "@trezor/schema-utils" "1.0.4" + long "^4.0.0" + protobufjs "7.2.6" + +"@trezor/protocol@1.0.9": + version "1.0.9" + resolved "https://registry.yarnpkg.com/@trezor/protocol/-/protocol-1.0.9.tgz#bbd679b9e1b8463db2cbaa9bd8d2252da712ba2b" + integrity sha512-BlSVmHL9tYWZ3HvXHD9H4JFkzZM5LXXVwS10SFHDftpj7CcVqXumxKLcHhSV8LKEw0rVYUXgER7+lQ8n2UdrLQ== + +"@trezor/schema-utils@1.0.4": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@trezor/schema-utils/-/schema-utils-1.0.4.tgz#0d87fd12821c0c47e70ca9a1c4b114fd239151f9" + integrity sha512-wDcGD1ErjrDNc8afGihHRwGvfdKZzOOt3iJcrKkgKZAmVazYi8GpWwpIHDhY2yI0oqewAVNNhE9B26t9uWNFng== + dependencies: + "@sinclair/typebox" "^0.31.28" + ts-mixer "^6.0.3" + +"@trezor/transport@1.1.29": + version "1.1.29" + resolved "https://registry.yarnpkg.com/@trezor/transport/-/transport-1.1.29.tgz#fb6f47a7108bef6abb331718fccb7fb1af7fb6a7" + integrity sha512-odGOuXnF43BRkS0jZmf59SHKMDG8SwyasxYss+lItRVCsia5S3bMBFGVRez0PHAIQ+GsS7j6QOc95tEC5at4Bg== + dependencies: + "@trezor/protobuf" "1.0.13" + "@trezor/protocol" "1.0.9" + "@trezor/utils" "9.0.24" + cross-fetch "^4.0.0" + json-stable-stringify "^1.1.1" + long "^4.0.0" + protobufjs "7.2.6" + usb "^2.11.0" + +"@trezor/type-utils@1.0.5": + version "1.0.5" + resolved "https://registry.yarnpkg.com/@trezor/type-utils/-/type-utils-1.0.5.tgz#5efdd6ab1ebd5086878d9123cfe4eb70440072e6" + integrity sha512-AK8Gg5yoPAMvxqK49LXr8yoop1oxIXRxkOhCuWGV51fDM02/L1dhGNKC04UyCTyG7jZ+H1f5ywuna81BVT/ptQ== + +"@trezor/utils@9.0.24": + version "9.0.24" + resolved "https://registry.yarnpkg.com/@trezor/utils/-/utils-9.0.24.tgz#a2811bec78b37d70542e5bfe8d43c60ca98cb513" + integrity sha512-U03PQChHODjmlMrN7XVR46PnV3F6XlO6ynGSgXdgQffhE/EmMq5U4mA9lqtnPf56xWaU+lQVLmF6/LN2GNQIAg== + dependencies: + bignumber.js "^9.1.2" + +"@trezor/utxo-lib@2.0.10": + version "2.0.10" + resolved "https://registry.yarnpkg.com/@trezor/utxo-lib/-/utxo-lib-2.0.10.tgz#48b1a39c10fd21a3e43b2d5bfafddf6af7b5bd78" + integrity sha512-UIU8JWXnx0ykSYKWWv5MQV08sMdr0kRXG9rlVXkSi7y73FT3O76GTqiDz8iRo5If0gZUNEnk261W1oEnha1tTw== + dependencies: + "@trezor/utils" "9.0.24" + bchaddrjs "^0.5.2" + bech32 "^2.0.0" + bip66 "^1.1.5" + bitcoin-ops "^1.4.1" + blake-hash "^2.0.0" + blakejs "^1.2.1" + bn.js "^5.2.1" + bs58 "^5.0.0" + bs58check "^3.0.1" + create-hash "^1.2.0" + create-hmac "^1.1.7" + int64-buffer "^1.0.1" + pushdata-bitcoin "^1.0.1" + tiny-secp256k1 "^1.1.6" + typeforce "^1.18.0" + varuint-bitcoin "^1.1.2" + wif "^4.0.0" + +"@trysound/sax@0.2.0": + version "0.2.0" + resolved "https://registry.yarnpkg.com/@trysound/sax/-/sax-0.2.0.tgz#cccaab758af56761eb7bf37af6f03f326dd798ad" + integrity sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA== + +"@types/aria-query@^5.0.1": + version "5.0.4" + resolved "https://registry.yarnpkg.com/@types/aria-query/-/aria-query-5.0.4.tgz#1a31c3d378850d2778dabb6374d036dcba4ba708" + integrity sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw== -"@types/babel__core@^7.1.7": - version "7.20.0" - resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.20.0.tgz#61bc5a4cae505ce98e1e36c5445e4bee060d8891" - integrity sha512-+n8dL/9GWblDO0iU6eZAwEIJVr5DWigtle+Q6HLOrh/pdbXOhOtqzq8VPPE2zvNJzSKY4vH/z3iT3tn0A3ypiQ== +"@types/babel__core@^7.0.0", "@types/babel__core@^7.18.0": + version "7.20.5" + resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.20.5.tgz#3df15f27ba85319caa07ba08d0721889bb39c017" + integrity sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA== dependencies: "@babel/parser" "^7.20.7" "@babel/types" "^7.20.7" @@ -5357,160 +7612,163 @@ "@types/babel__traverse" "*" "@types/babel__generator@*": - version "7.6.4" - resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.4.tgz#1f20ce4c5b1990b37900b63f050182d28c2439b7" - integrity sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg== + version "7.6.7" + resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.7.tgz#a7aebf15c7bc0eb9abd638bdb5c0b8700399c9d0" + integrity sha512-6Sfsq+EaaLrw4RmdFWE9Onp63TOUue71AWb4Gpa6JxzgTYtimbM086WnYTy2U67AofR++QKCo08ZP6pwx8YFHQ== dependencies: "@babel/types" "^7.0.0" "@types/babel__template@*": - version "7.4.1" - resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.4.1.tgz#3d1a48fd9d6c0edfd56f2ff578daed48f36c8969" - integrity sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g== + version "7.4.4" + resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.4.4.tgz#5672513701c1b2199bc6dad636a9d7491586766f" + integrity sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A== dependencies: "@babel/parser" "^7.1.0" "@babel/types" "^7.0.0" -"@types/babel__traverse@*", "@types/babel__traverse@^7.0.6": - version "7.18.3" - resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.18.3.tgz#dfc508a85781e5698d5b33443416b6268c4b3e8d" - integrity sha512-1kbcJ40lLB7MHsj39U4Sh1uTd2E7rLEa79kmDpI6cy+XiXsteB3POdQomoq4FxszMrO3ZYchkhYJw7A2862b3w== +"@types/babel__traverse@*": + version "7.20.4" + resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.20.4.tgz#ec2c06fed6549df8bc0eb4615b683749a4a92e1b" + integrity sha512-mSM/iKUk5fDDrEV/e83qY+Cr3I1+Q3qqTuEn++HAWYjEa1+NxZr6CNrcJGf2ZTnq4HoFGC3zaTPZTobCzCFukA== dependencies: - "@babel/types" "^7.3.0" + "@babel/types" "^7.20.7" -"@types/bech32@^1.1.2": - version "1.1.4" - resolved "https://registry.yarnpkg.com/@types/bech32/-/bech32-1.1.4.tgz#501590d41c81a5f1802e39d6be450e89ec6d75d6" - integrity sha512-LWSo7sw6NFc9u7HpMK6aPRa7lNw3NKYAEEQCvdFFLkMCgwzv+0/CySQeqdL9hUIsirThQJ4u6ax/0uKEN63Z2g== +"@types/babel__traverse@^7.18.0": + version "7.20.5" + resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.20.5.tgz#7b7502be0aa80cc4ef22978846b983edaafcd4dd" + integrity sha512-WXCyOcRtH37HAUkpXhUduaxdm82b4GSlyTqajXviN4EfiuPgNYR109xMCKvpl6zPIpua0DGlMEDCq+g8EdoheQ== dependencies: - bech32 "*" - -"@types/big.js@^4.0.5": - version "4.0.5" - resolved "https://registry.yarnpkg.com/@types/big.js/-/big.js-4.0.5.tgz#62c61697646269e39191f24e55e8272f05f21fc0" - integrity sha512-D9KFrAt05FDSqLo7PU9TDHfDgkarlwdkuwFsg7Zm4xl62tTNaz+zN+Tkcdx2wGLBbSMf8BnoMhOVeUGUaJfLKg== + "@babel/types" "^7.20.7" -"@types/bn.js@*": - version "5.1.1" - resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-5.1.1.tgz#b51e1b55920a4ca26e9285ff79936bbdec910682" - integrity sha512-qNrYbZqMx0uJAfKnKclPh+dTwK33KfLHYqtyODwd5HnXOjnkhc4qgn3BrK6RWyGZm5+sIFE7Q7Vz6QQtJB7w7g== +"@types/body-parser@*": + version "1.19.5" + resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.5.tgz#04ce9a3b677dc8bd681a17da1ab9835dc9d3ede4" + integrity sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg== dependencies: + "@types/connect" "*" "@types/node" "*" -"@types/bn.js@^4.11.6": - version "4.11.6" - resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-4.11.6.tgz#c306c70d9358aaea33cd4eda092a742b9505967c" - integrity sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg== +"@types/connect@*", "@types/connect@^3.4.33": + version "3.4.38" + resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.38.tgz#5ba7f3bc4fbbdeaff8dded952e5ff2cc53f8d858" + integrity sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug== dependencies: "@types/node" "*" -"@types/cacheable-request@^6.0.1": - version "6.0.3" - resolved "https://registry.yarnpkg.com/@types/cacheable-request/-/cacheable-request-6.0.3.tgz#a430b3260466ca7b5ca5bfd735693b36e7a9d183" - integrity sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw== +"@types/cross-spawn@^6.0.2": + version "6.0.6" + resolved "https://registry.yarnpkg.com/@types/cross-spawn/-/cross-spawn-6.0.6.tgz#0163d0b79a6f85409e0decb8dcca17147f81fd22" + integrity sha512-fXRhhUkG4H3TQk5dBhQ7m/JDdSNHKwR2BBia62lhwEIq9xGiQKLxd6LymNhn47SjXhsUEPmxi+PKw2OkW4LLjA== dependencies: - "@types/http-cache-semantics" "*" - "@types/keyv" "^3.1.4" "@types/node" "*" - "@types/responselike" "^1.0.0" -"@types/connect@^3.4.33": - version "3.4.35" - resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.35.tgz#5fcf6ae445e4021d1fc2219a4873cc73a3bb2ad1" - integrity sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ== - dependencies: - "@types/node" "*" +"@types/d3-color@^1": + version "1.4.5" + resolved "https://registry.yarnpkg.com/@types/d3-color/-/d3-color-1.4.5.tgz#23bb1afda325549c6314ab60aa2aa28c4c6b1c37" + integrity sha512-5sNP3DmtSnSozxcjqmzQKsDOuVJXZkceo1KJScDc1982kk/TS9mTPc6lpli1gTu1MIBF1YWutpHpjucNWcIj5g== -"@types/cookie@^0.4.0": - version "0.4.1" - resolved "https://registry.yarnpkg.com/@types/cookie/-/cookie-0.4.1.tgz#bfd02c1f2224567676c1545199f87c3a861d878d" - integrity sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q== +"@types/d3-interpolate@^1.3.1": + version "1.4.5" + resolved "https://registry.yarnpkg.com/@types/d3-interpolate/-/d3-interpolate-1.4.5.tgz#7964699575ec9c594a9a7aaea411a812ce6cd674" + integrity sha512-k9L18hXXv7OvK4PqW1kSFYIzasGOvfhPUWmHFkoZ8/ci99EAmY4HoF6zMefrHl0SGV7XYc7Qq2MNh8dK3edg5A== + dependencies: + "@types/d3-color" "^1" -"@types/crypto-js@^3.1.43": - version "3.1.47" - resolved "https://registry.yarnpkg.com/@types/crypto-js/-/crypto-js-3.1.47.tgz#36e549dd3f1322742a3a738e7c113ebe48221860" - integrity sha512-eI6gvpcGHLk3dAuHYnRCAjX+41gMv1nz/VP55wAe5HtmAKDOoPSfr3f6vkMc08ov1S0NsjvUBxDtHHxqQY1LGA== +"@types/d3-path@^1", "@types/d3-path@^1.0.8": + version "1.0.11" + resolved "https://registry.yarnpkg.com/@types/d3-path/-/d3-path-1.0.11.tgz#45420fee2d93387083b34eae4fe6d996edf482bc" + integrity sha512-4pQMp8ldf7UaB/gR8Fvvy69psNHkTpD/pVw3vmEi8iZAB9EPMBruB1JvHO4BIq9QkUUd2lV1F5YXpMNj7JPBpw== -"@types/debug@^4.0.0": - version "4.1.7" - resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.7.tgz#7cc0ea761509124709b8b2d1090d8f6c17aadb82" - integrity sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg== +"@types/d3-scale@^3.3.0": + version "3.3.5" + resolved "https://registry.yarnpkg.com/@types/d3-scale/-/d3-scale-3.3.5.tgz#c89ff1550a4246f717e3c2e35deb35e183a338ba" + integrity sha512-YOpKj0kIEusRf7ofeJcSZQsvKbnTwpe1DUF+P2qsotqG53kEsjm7EzzliqQxMkAWdkZcHrg5rRhB4JiDOQPX+A== dependencies: - "@types/ms" "*" + "@types/d3-time" "^2" -"@types/duplexify@*": - version "3.6.1" - resolved "https://registry.yarnpkg.com/@types/duplexify/-/duplexify-3.6.1.tgz#5685721cf7dc4a21b6f0e8a8efbec6b4d2fbafad" - integrity sha512-n0zoEj/fMdMOvqbHxmqnza/kXyoGgJmEpsXjpP+gEqE1Ye4yNqc7xWipKnUoMpWhMuzJQSfK2gMrwlElly7OGQ== +"@types/d3-shape@^1.3.1": + version "1.3.12" + resolved "https://registry.yarnpkg.com/@types/d3-shape/-/d3-shape-1.3.12.tgz#8f2f9f7a12e631ce6700d6d55b84795ce2c8b259" + integrity sha512-8oMzcd4+poSLGgV0R1Q1rOlx/xdmozS4Xab7np0eamFFUYq71AU9pOCJEFnkXW2aI/oXdVYJzw6pssbSut7Z9Q== dependencies: - "@types/node" "*" + "@types/d3-path" "^1" -"@types/elliptic@^6.4.12": - version "6.4.14" - resolved "https://registry.yarnpkg.com/@types/elliptic/-/elliptic-6.4.14.tgz#7bbaad60567a588c1f08b10893453e6b9b4de48e" - integrity sha512-z4OBcDAU0GVwDTuwJzQCiL6188QvZMkvoERgcVjq0/mPM8jCfdwZ3x5zQEVoL9WCAru3aG5wl3Z5Ww5wBWn7ZQ== - dependencies: - "@types/bn.js" "*" +"@types/d3-time@^2", "@types/d3-time@^2.0.0": + version "2.1.4" + resolved "https://registry.yarnpkg.com/@types/d3-time/-/d3-time-2.1.4.tgz#43587aa57d565ab60a1d2201edeebc497d5c1252" + integrity sha512-BTfLsxTeo7yFxI/haOOf1ZwJ6xKgQLT9dCp+EcmQv87Gox6X+oKl4mLKfO6fnWm3P22+A6DknMNEZany8ql2Rw== -"@types/eslint-scope@^3.7.3": - version "3.7.4" - resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.4.tgz#37fc1223f0786c39627068a12e94d6e6fc61de16" - integrity sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA== - dependencies: - "@types/eslint" "*" - "@types/estree" "*" +"@types/detect-port@^1.3.0": + version "1.3.5" + resolved "https://registry.yarnpkg.com/@types/detect-port/-/detect-port-1.3.5.tgz#deecde143245989dee0e82115f3caba5ee0ea747" + integrity sha512-Rf3/lB9WkDfIL9eEKaSYKc+1L/rNVYBjThk22JTqQw0YozXarX8YljFAz+HCoC6h4B4KwCMsBPZHaFezwT4BNA== -"@types/eslint-visitor-keys@^1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#1ee30d79544ca84d68d4b3cdb0af4f205663dd2d" - integrity sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag== +"@types/doctrine@^0.0.3": + version "0.0.3" + resolved "https://registry.yarnpkg.com/@types/doctrine/-/doctrine-0.0.3.tgz#e892d293c92c9c1d3f9af72c15a554fbc7e0895a" + integrity sha512-w5jZ0ee+HaPOaX25X2/2oGR/7rgAQSYII7X7pp0m9KgBfMP7uKfMfTvcpl5Dj+eDBbpxKGiqE+flqDr6XTd2RA== -"@types/eslint@*": - version "8.37.0" - resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.37.0.tgz#29cebc6c2a3ac7fea7113207bf5a828fdf4d7ef1" - integrity sha512-Piet7dG2JBuDIfohBngQ3rCt7MgO9xCO4xIMKxBThCq5PNRB91IjlJ10eJVwfoNtvTErmxLzwBZ7rHZtbOMmFQ== - dependencies: - "@types/estree" "*" - "@types/json-schema" "*" +"@types/doctrine@^0.0.9": + version "0.0.9" + resolved "https://registry.yarnpkg.com/@types/doctrine/-/doctrine-0.0.9.tgz#d86a5f452a15e3e3113b99e39616a9baa0f9863f" + integrity sha512-eOIHzCUSH7SMfonMG1LsC2f8vxBFtho6NGBznK41R84YzPuvSBzrhEps33IsQiOW9+VL6NQ9DbjQJznk/S4uRA== -"@types/estree-jsx@^0.0.1": - version "0.0.1" - resolved "https://registry.yarnpkg.com/@types/estree-jsx/-/estree-jsx-0.0.1.tgz#c36d7a1afeb47a95a8ee0b7bc8bc705db38f919d" - integrity sha512-gcLAYiMfQklDCPjQegGn0TBAn9it05ISEsEhlKQUddIk7o2XDokOcTN7HBO8tznM0D9dGezvHEfRZBfZf6me0A== - dependencies: - "@types/estree" "*" +"@types/ejs@^3.1.1": + version "3.1.5" + resolved "https://registry.yarnpkg.com/@types/ejs/-/ejs-3.1.5.tgz#49d738257cc73bafe45c13cb8ff240683b4d5117" + integrity sha512-nv+GSx77ZtXiJzwKdsASqi+YQ5Z7vwHsTP0JY2SiQgjGckkBRKZnk8nIM+7oUZ1VCtuTz0+By4qVR7fqzp/Dfg== -"@types/estree-jsx@^1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@types/estree-jsx/-/estree-jsx-1.0.0.tgz#7bfc979ab9f692b492017df42520f7f765e98df1" - integrity sha512-3qvGd0z8F2ENTGr/GG1yViqfiKmRfrXVx5sJyHGFu3z7m5g5utCQtGp/g29JnjflhtQJBv1WDQukHiT58xPcYQ== - dependencies: - "@types/estree" "*" +"@types/emscripten@^1.39.6": + version "1.39.10" + resolved "https://registry.yarnpkg.com/@types/emscripten/-/emscripten-1.39.10.tgz#da6e58a6171b46a41d3694f812d845d515c77e18" + integrity sha512-TB/6hBkYQJxsZHSqyeuO1Jt0AB/bW6G7rHt9g7lML7SOF6lbgcHvw/Lr+69iqN0qxgXLhWKScAon73JNnptuDw== -"@types/estree@*", "@types/estree@^1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.0.tgz#5fb2e536c1ae9bf35366eed879e827fa59ca41c2" - integrity sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ== +"@types/escodegen@^0.0.6": + version "0.0.6" + resolved "https://registry.yarnpkg.com/@types/escodegen/-/escodegen-0.0.6.tgz#5230a9ce796e042cda6f086dbf19f22ea330659c" + integrity sha512-AjwI4MvWx3HAOaZqYsjKWyEObT9lcVV0Y0V8nXo6cXzN8ZiMxVhf6F3d/UNvXVGKrEzL/Dluc5p+y9GkzlTWig== -"@types/estree@0.0.39": - version "0.0.39" - resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.39.tgz#e177e699ee1b8c22d23174caaa7422644389509f" - integrity sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw== +"@types/estree@1.0.6", "@types/estree@^1.0.5": + version "1.0.6" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.6.tgz#628effeeae2064a1b4e79f78e81d87b7e5fc7b50" + integrity sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw== "@types/estree@^0.0.51": version "0.0.51" resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.51.tgz#cfd70924a25a3fd32b218e5e420e6897e1ac4f40" integrity sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ== -"@types/glob@*": - version "8.1.0" - resolved "https://registry.yarnpkg.com/@types/glob/-/glob-8.1.0.tgz#b63e70155391b0584dce44e7ea25190bbc38f2fc" - integrity sha512-IO+MJPVhoqz+28h1qLAcBEH2+xHMK6MTyHJc7MTnnYb6wsoLR29POVGJ7LycmVXIqyy/4/2ShP5sUwTXuOwb/w== +"@types/estree@^1.0.0": + version "1.0.5" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.5.tgz#a6ce3e556e00fd9895dd872dd172ad0d4bd687f4" + integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw== + +"@types/express-serve-static-core@^4.17.33": + version "4.17.41" + resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.41.tgz#5077defa630c2e8d28aa9ffc2c01c157c305bef6" + integrity sha512-OaJ7XLaelTgrvlZD8/aa0vvvxZdUmlCn6MtWeB7TkiKW70BQLc9XEPpDLPdbo52ZhXUCrznlWdCHWxJWtdyajA== dependencies: - "@types/minimatch" "^5.1.2" "@types/node" "*" + "@types/qs" "*" + "@types/range-parser" "*" + "@types/send" "*" -"@types/glob@^7.1.1": +"@types/express@^4.7.0": + version "4.17.21" + resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.21.tgz#c26d4a151e60efe0084b23dc3369ebc631ed192d" + integrity sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ== + dependencies: + "@types/body-parser" "*" + "@types/express-serve-static-core" "^4.17.33" + "@types/qs" "*" + "@types/serve-static" "*" + +"@types/find-cache-dir@^3.2.1": + version "3.2.1" + resolved "https://registry.yarnpkg.com/@types/find-cache-dir/-/find-cache-dir-3.2.1.tgz#7b959a4b9643a1e6a1a5fe49032693cc36773501" + integrity sha512-frsJrz2t/CeGifcu/6uRo4b+SzAwT4NYCVPu1GN8IB9XTzrpPkGuV0tmh9mN+/L0PklAlsC3u5Fxt0ju00LXIw== + +"@types/glob@^7.1.3": version "7.2.0" resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.2.0.tgz#bc1b5bf3aa92f25bd5dd39f35c57361bdce5b2eb" integrity sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA== @@ -5518,239 +7776,209 @@ "@types/minimatch" "*" "@types/node" "*" -"@types/graceful-fs@^4.1.2": - version "4.1.6" - resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.6.tgz#e14b2576a1c25026b7f02ede1de3b84c3a1efeae" - integrity sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw== +"@types/hast@^2.0.0": + version "2.3.8" + resolved "https://registry.yarnpkg.com/@types/hast/-/hast-2.3.8.tgz#4ac5caf38b262b7bd5ca3202dda71f0271635660" + integrity sha512-aMIqAlFd2wTIDZuvLbhUT+TGvMxrNC8ECUIVtH6xxy0sQLs3iu6NO8Kp/VT5je7i5ufnebXzdV1dNDMnvaH6IQ== dependencies: - "@types/node" "*" + "@types/unist" "^2" -"@types/hast@^2.0.0": - version "2.3.4" - resolved "https://registry.yarnpkg.com/@types/hast/-/hast-2.3.4.tgz#8aa5ef92c117d20d974a82bdfb6a648b08c0bafc" - integrity sha512-wLEm0QvaoawEDoTRwzTXp4b4jpwiJDvR5KMnFnVodm3scufTlBOWRD6N1OBf9TZMhjlNsSfcO5V+7AF4+Vy+9g== +"@types/hast@^3.0.0": + version "3.0.4" + resolved "https://registry.yarnpkg.com/@types/hast/-/hast-3.0.4.tgz#1d6b39993b82cea6ad783945b0508c25903e15aa" + integrity sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ== dependencies: "@types/unist" "*" -"@types/html-minifier-terser@^5.0.0": - version "5.1.2" - resolved "https://registry.yarnpkg.com/@types/html-minifier-terser/-/html-minifier-terser-5.1.2.tgz#693b316ad323ea97eed6b38ed1a3cc02b1672b57" - integrity sha512-h4lTMgMJctJybDp8CQrxTUiiYmedihHWkjnF/8Pxseu2S6Nlfcy8kwboQ8yejh456rP2yWoEVm1sS/FVsfM48w== +"@types/html-minifier-terser@^6.0.0": + version "6.1.0" + resolved "https://registry.yarnpkg.com/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz#4fc33a00c1d0c16987b1a20cf92d20614c55ac35" + integrity sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg== -"@types/http-cache-semantics@*": - version "4.0.1" - resolved "https://registry.yarnpkg.com/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz#0ea7b61496902b95890dc4c3a116b60cb8dae812" - integrity sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ== +"@types/http-errors@*": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@types/http-errors/-/http-errors-2.0.4.tgz#7eb47726c391b7345a6ec35ad7f4de469cf5ba4f" + integrity sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA== "@types/is-function@^1.0.0": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@types/is-function/-/is-function-1.0.1.tgz#2d024eace950c836d9e3335a66b97960ae41d022" - integrity sha512-A79HEEiwXTFtfY+Bcbo58M2GRYzCr9itHWzbzHVFNEYCcoU/MMGwYYf721gBrnhpj1s6RGVVha/IgNFnR0Iw/Q== + version "1.0.3" + resolved "https://registry.yarnpkg.com/@types/is-function/-/is-function-1.0.3.tgz#548f851db5d30a12abeea2569ba75890dbf89425" + integrity sha512-/CLhCW79JUeLKznI6mbVieGbl4QU5Hfn+6udw1YHZoofASjbQ5zaP5LzAUZYDpRYEjS4/P+DhEgyJ/PQmGGTWw== -"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1": - version "2.0.4" - resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz#8467d4b3c087805d63580480890791277ce35c44" - integrity sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g== +"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0": + version "2.0.6" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz#7739c232a1fee9b4d3ce8985f314c0c6d33549d7" + integrity sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w== "@types/istanbul-lib-report@*": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#c14c24f18ea8190c118ee7562b7ff99a36552686" - integrity sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg== - dependencies: - "@types/istanbul-lib-coverage" "*" - -"@types/istanbul-reports@^1.1.1": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz#e875cc689e47bce549ec81f3df5e6f6f11cfaeb2" - integrity sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw== + version "3.0.3" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz#53047614ae72e19fc0401d872de3ae2b4ce350bf" + integrity sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA== dependencies: "@types/istanbul-lib-coverage" "*" - "@types/istanbul-lib-report" "*" "@types/istanbul-reports@^3.0.0": - version "3.0.1" - resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz#9153fe98bba2bd565a63add9436d6f0d7f8468ff" - integrity sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw== + version "3.0.4" + resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz#0f03e3d2f670fbdac586e34b433783070cc16f54" + integrity sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ== dependencies: "@types/istanbul-lib-report" "*" -"@types/jest@^25.1.4", "@types/jest@^25.2.1": - version "25.2.3" - resolved "https://registry.yarnpkg.com/@types/jest/-/jest-25.2.3.tgz#33d27e4c4716caae4eced355097a47ad363fdcaf" - integrity sha512-JXc1nK/tXHiDhV55dvfzqtmP4S3sy3T3ouV2tkViZgxY/zeUkcpQcQPGRlgF4KmWzWW5oiWYSZwtCB+2RsE4Fw== - dependencies: - jest-diff "^25.2.1" - pretty-format "^25.2.1" - -"@types/json-schema@*", "@types/json-schema@^7.0.3", "@types/json-schema@^7.0.4", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.6", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": - version "7.0.11" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.11.tgz#d421b6c527a3037f7c84433fd2c4229e016863d3" - integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ== +"@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": + version "7.0.15" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" + integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== "@types/json5@^0.0.29": version "0.0.29" resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== -"@types/keyv@^3.1.4": - version "3.1.4" - resolved "https://registry.yarnpkg.com/@types/keyv/-/keyv-3.1.4.tgz#3ccdb1c6751b0c7e52300bcdacd5bcbf8faa75b6" - integrity sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg== - dependencies: - "@types/node" "*" +"@types/lodash@^4.14.136": + version "4.17.5" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.17.5.tgz#e6c29b58e66995d57cd170ce3e2a61926d55ee04" + integrity sha512-MBIOHVZqVqgfro1euRDWX7OO0fBVUUMrN6Pwm8LQsz8cWhEpihlvR70ENj3f40j58TNxZaWv2ndSkInykNBBJw== -"@types/ledgerhq__hw-transport@^4.21.2": - version "4.21.4" - resolved "https://registry.yarnpkg.com/@types/ledgerhq__hw-transport/-/ledgerhq__hw-transport-4.21.4.tgz#3a78a02d2b51d2b0dd8099412d5567d21118225c" - integrity sha512-vep+6yZnGv6owAthIY0w3f72w4dJIb4+yE5PCHveInTlZE9wukvU6Wc5Eig0OUUxcdhTazzeZx1xUaNVLqyQSg== - dependencies: - "@types/node" "*" +"@types/lodash@^4.14.167": + version "4.14.202" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.202.tgz#f09dbd2fb082d507178b2f2a5c7e74bd72ff98f8" + integrity sha512-OvlIYQK9tNneDlS0VN54LLd5uiPCBOp7gS5Z0f1mjoJYBrtStzgmJBxONW3U6OZqdtNzZPmn9BS/7WI7BFFcFQ== -"@types/lodash@^4.14.149", "@types/lodash@^4.14.167": - version "4.14.192" - resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.192.tgz#5790406361a2852d332d41635d927f1600811285" - integrity sha512-km+Vyn3BYm5ytMO13k9KTp27O75rbQ0NFw+U//g+PX7VZyjCioXaRFisqSIJRECljcTv73G3i6BpglNGHgUQ5A== +"@types/lodash@^4.14.172": + version "4.17.7" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.17.7.tgz#2f776bcb53adc9e13b2c0dfd493dfcbd7de43612" + integrity sha512-8wTvZawATi/lsmNu10/j2hk1KEP0IvjubqPE3cu1Xz7xfXXt5oCq3SNUz4fMIP4XGF9Ky+Ue2tBA3hcS7LSBlA== "@types/long@^4.0.1": version "4.0.2" resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.2.tgz#b74129719fc8d11c01868010082d483b7545591a" integrity sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA== -"@types/mdast@^3.0.0": - version "3.0.11" - resolved "https://registry.yarnpkg.com/@types/mdast/-/mdast-3.0.11.tgz#dc130f7e7d9306124286f6d6cee40cf4d14a3dc0" - integrity sha512-Y/uImid8aAwrEA24/1tcRZwpxX3pIFTSilcNDKSPn+Y2iDywSEachzRuvgAYYLR3wpGXAsMbv5lvKLDZLeYPAw== - dependencies: - "@types/unist" "*" +"@types/mdx@^2.0.0": + version "2.0.10" + resolved "https://registry.yarnpkg.com/@types/mdx/-/mdx-2.0.10.tgz#0d7b57fb1d83e27656156e4ee0dfba96532930e4" + integrity sha512-Rllzc5KHk0Al5/WANwgSPl1/CwjqCy+AZrGd78zuK+jO9aDM6ffblZ+zIjgPNAaEBmlO0RYDvLNh7wD0zKVgEg== -"@types/mdurl@^1.0.0": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@types/mdurl/-/mdurl-1.0.2.tgz#e2ce9d83a613bacf284c7be7d491945e39e1f8e9" - integrity sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA== +"@types/mime@*": + version "3.0.4" + resolved "https://registry.yarnpkg.com/@types/mime/-/mime-3.0.4.tgz#2198ac274de6017b44d941e00261d5bc6a0e0a45" + integrity sha512-iJt33IQnVRkqeqC7PzBHPTC6fDlRNRW8vjrgqtScAhrmMwe8c4Eo7+fUGTa+XdWrpEgpyKWMYmi2dIwMAYRzPw== + +"@types/mime@^1": + version "1.3.5" + resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.5.tgz#1ef302e01cf7d2b5a0fa526790c9123bf1d06690" + integrity sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w== -"@types/minimatch@*", "@types/minimatch@^5.1.2": +"@types/minimatch@*": version "5.1.2" resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-5.1.2.tgz#07508b45797cb81ec3f273011b054cd0755eddca" integrity sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA== "@types/minimist@^1.2.0": - version "1.2.2" - resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.2.tgz#ee771e2ba4b3dc5b372935d549fd9617bf345b8c" - integrity sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ== - -"@types/ms@*": - version "0.7.31" - resolved "https://registry.yarnpkg.com/@types/ms/-/ms-0.7.31.tgz#31b7ca6407128a3d2bbc27fe2d21b345397f6197" - integrity sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA== - -"@types/node-fetch@^2.5.7": - version "2.6.3" - resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.6.3.tgz#175d977f5e24d93ad0f57602693c435c57ad7e80" - integrity sha512-ETTL1mOEdq/sxUtgtOhKjyB2Irra4cjxksvcMUR5Zr4n+PxVhsCD9WS46oPbHL3et9Zde7CNRr+WUNlcHvsX+w== - dependencies: - "@types/node" "*" - form-data "^3.0.0" + version "1.2.5" + resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.5.tgz#ec10755e871497bcd83efe927e43ec46e8c0747e" + integrity sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag== "@types/node@*", "@types/node@>=13.7.0": - version "18.15.11" - resolved "https://registry.yarnpkg.com/@types/node/-/node-18.15.11.tgz#b3b790f09cb1696cffcec605de025b088fa4225f" - integrity sha512-E5Kwq2n4SbMzQOn6wnmBjuK9ouqlURrcZDVfbo9ftDDTFt3nk7ZKK4GMOzoYgnpQJKcxwQw+lGaBvvlMo0qN/Q== + version "20.10.0" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.10.0.tgz#16ddf9c0a72b832ec4fcce35b8249cf149214617" + integrity sha512-D0WfRmU9TQ8I9PFx9Yc+EBHw+vSpIub4IDvQivcp26PtPrdMGAq5SDcpXEo/epqa/DXotVpekHiLNTg3iaKXBQ== + dependencies: + undici-types "~5.26.4" "@types/node@10.12.18": version "10.12.18" resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.18.tgz#1d3ca764718915584fcd9f6344621b7672665c67" integrity sha512-fh+pAqt4xRzPfqA6eh3Z2y6fyZavRIumvjhaCL753+TVkGKGhpPeyrJG2JftD0T9q4GF00KjefsQ+PQNDdWQaQ== -"@types/node@14.18.33": - version "14.18.33" - resolved "https://registry.yarnpkg.com/@types/node/-/node-14.18.33.tgz#8c29a0036771569662e4635790ffa9e057db379b" - integrity sha512-qelS/Ra6sacc4loe/3MSjXNL1dNQ/GjxNHVzuChwMfmk7HuycRLVQN2qNY3XahK+fZc5E2szqQSKUyAF0E+2bg== +"@types/node@18.15.13": + version "18.15.13" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.15.13.tgz#f64277c341150c979e42b00e4ac289290c9df469" + integrity sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q== "@types/node@^12.12.54": version "12.20.55" resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.55.tgz#c329cbd434c42164f846b909bd6f85b5537f6240" integrity sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ== -"@types/node@^13.7.0", "@types/node@^13.9.0": - version "13.13.52" - resolved "https://registry.yarnpkg.com/@types/node/-/node-13.13.52.tgz#03c13be70b9031baaed79481c0c0cfb0045e53f7" - integrity sha512-s3nugnZumCC//n4moGGe6tkNMyYEdaDBitVjwPxXmR5lnMG5dHePinH2EdxkG3Rh1ghFHHixAG4NJhpJW1rthQ== - -"@types/node@^14.0.10 || ^16.0.0", "@types/node@^14.14.20 || ^16.0.0": - version "16.18.23" - resolved "https://registry.yarnpkg.com/@types/node/-/node-16.18.23.tgz#b6e934fe427eb7081d0015aad070acb3373c3c90" - integrity sha512-XAMpaw1s1+6zM+jn2tmw8MyaRDIJfXxqmIQIS0HfoGYPuf7dUWeiUKopwq13KFX9lEp1+THGtlaaYx39Nxr58g== +"@types/node@^18.0.0": + version "18.18.13" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.18.13.tgz#ae0f76c0bfe79d8fad0f910b78ae3e59b333c6e8" + integrity sha512-vXYZGRrSCreZmq1rEjMRLXJhiy8MrIeVasx+PCVlP414N7CJLHnMf+juVvjdprHyH+XRy3zKZLHeNueOpJCn0g== + dependencies: + undici-types "~5.26.4" "@types/normalize-package-data@^2.4.0": - version "2.4.1" - resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz#d3357479a0fdfdd5907fe67e17e0a85c906e1301" - integrity sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw== - -"@types/npmlog@^4.1.2": - version "4.1.4" - resolved "https://registry.yarnpkg.com/@types/npmlog/-/npmlog-4.1.4.tgz#30eb872153c7ead3e8688c476054ddca004115f6" - integrity sha512-WKG4gTr8przEZBiJ5r3s8ZIAoMXNbOgQ+j/d5O4X3x6kZJRLNvyUJuUK/KoG3+8BaOHPhp2m7WC6JKKeovDSzQ== + version "2.4.4" + resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz#56e2cc26c397c038fab0e3a917a12d5c5909e901" + integrity sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA== "@types/parse-json@^4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0" - integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA== - -"@types/parse5@^5.0.0": - version "5.0.3" - resolved "https://registry.yarnpkg.com/@types/parse5/-/parse5-5.0.3.tgz#e7b5aebbac150f8b5fdd4a46e7f0bd8e65e19109" - integrity sha512-kUNnecmtkunAoQ3CnjmMkzNU/gtxG8guhi+Fk2U/kOpIKjIMKnXGp4IJCgQJrXSgMsWYimYG4TGjz/UzbGEBTw== - -"@types/prettier@^1.19.0": - version "1.19.1" - resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-1.19.1.tgz#33509849f8e679e4add158959fdb086440e9553f" - integrity sha512-5qOlnZscTn4xxM5MeGXAMOsIOIKIbh9e85zJWfBRVPlRMEVawzoPhINYbRGkBZCI8LxvBe7tJCdWiarA99OZfQ== + version "4.0.2" + resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.2.tgz#5950e50960793055845e956c427fc2b0d70c5239" + integrity sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw== "@types/pretty-hrtime@^1.0.0": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@types/pretty-hrtime/-/pretty-hrtime-1.0.1.tgz#72a26101dc567b0d68fd956cf42314556e42d601" - integrity sha512-VjID5MJb1eGKthz2qUerWT8+R4b9N+CHvGCzg9fn4kWZgaF9AhdYikQio3R7wV8YY1NsQKPaCwKz1Yff+aHNUQ== + version "1.0.3" + resolved "https://registry.yarnpkg.com/@types/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz#ee1bd8c9f7a01b3445786aad0ef23aba5f511a44" + integrity sha512-nj39q0wAIdhwn7DGUyT9irmsKK1tV0bd5WFEhgpqNTMFZ8cE+jieuTphCW0tfdm47S2zVT5mr09B28b1chmQMA== + +"@types/promise-retry@^1.1.6": + version "1.1.6" + resolved "https://registry.yarnpkg.com/@types/promise-retry/-/promise-retry-1.1.6.tgz#3c48826d8a27f68f9d4900fc7448f08a1532db44" + integrity sha512-EC1+OMXV0PZb0pf+cmyxc43MEP2CDumZe4AfuxWboxxEixztIebknpJPZAX5XlodGF1OY+C1E/RAeNGzxf+bJA== + dependencies: + "@types/retry" "*" "@types/prop-types@*": - version "15.7.5" - resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.5.tgz#5f19d2b85a98e9558036f6a3cacc8819420f05cf" - integrity sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w== + version "15.7.11" + resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.11.tgz#2596fb352ee96a1379c657734d4b913a613ad563" + integrity sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng== -"@types/pumpify@^1.4.1": - version "1.4.1" - resolved "https://registry.yarnpkg.com/@types/pumpify/-/pumpify-1.4.1.tgz#5a0650f39a3f8f077c7e544d0c5ae2899b28394c" - integrity sha512-l7u/Dnh1OG9T7VH6TvulR0g8oE8hgIW5409mSUKi8Vxw2+JV18aTa06Sv5bvNjrD0zbsB/cuZ/iTFQgFNfzIuw== - dependencies: - "@types/duplexify" "*" - "@types/node" "*" +"@types/qs@*", "@types/qs@^6.9.5": + version "6.9.10" + resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.10.tgz#0af26845b5067e1c9a622658a51f60a3934d51e8" + integrity sha512-3Gnx08Ns1sEoCrWssEgTSJs/rsT2vhGP+Ja9cnnk9k4ALxinORlQneLXFeFKOTJMOeZUFD1s7w+w2AphTpvzZw== -"@types/qs@^6.9.5": - version "6.9.7" - resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.7.tgz#63bb7d067db107cc1e457c303bc25d511febf6cb" - integrity sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw== +"@types/range-parser@*": + version "1.2.7" + resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.7.tgz#50ae4353eaaddc04044279812f52c8c65857dbcb" + integrity sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ== "@types/reach__router@^1.2.3": - version "1.3.11" - resolved "https://registry.yarnpkg.com/@types/reach__router/-/reach__router-1.3.11.tgz#528af5d73f76b42cf7de5664cdd1b728dee78e31" - integrity sha512-j23ChnIEiW8aAP4KT8OVyTXOFr+Ri65BDnwzmfHFO9WHypXYevHFjeil1Cj7YH3emfCE924BwAmgW4hOv7Wg3g== + version "1.3.14" + resolved "https://registry.yarnpkg.com/@types/reach__router/-/reach__router-1.3.14.tgz#0979270997253ebdf43052a65c5f0419c77774cb" + integrity sha512-2iOQZbwfw1ZYwYK+dRp7D1b8kU6GlFPJ/iEt33zDYxfId5CAKT7vX3lN/XmJ+FaMZ3FyB99tPgfajcmZnTqdtg== dependencies: "@types/react" "*" "@types/react-color@^3.0.6": - version "3.0.6" - resolved "https://registry.yarnpkg.com/@types/react-color/-/react-color-3.0.6.tgz#602fed023802b2424e7cd6ff3594ccd3d5055f9a" - integrity sha512-OzPIO5AyRmLA7PlOyISlgabpYUa3En74LP8mTMa0veCA719SvYQov4WLMsHvCgXP+L+KI9yGhYnqZafVGG0P4w== + version "3.0.10" + resolved "https://registry.yarnpkg.com/@types/react-color/-/react-color-3.0.10.tgz#f869ab3a46938fb97a5c2ee568bc6469f82b14dd" + integrity sha512-6K5BAn3zyd8lW8UbckIAVeXGxR82Za9jyGD2DBEynsa7fKaguLDVtjfypzs7fgEV7bULgs7uhds8A8v1wABTvQ== dependencies: "@types/react" "*" "@types/reactcss" "*" +"@types/react-dom@*": + version "18.3.0" + resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.3.0.tgz#0cbc818755d87066ab6ca74fbedb2547d74a82b0" + integrity sha512-EhwApuTmMBmXuFOikhQLIBUn6uFg81SwLMOAUgodJF14SOBOCMdU04gDoYi0WOJJHD144TL32z4yDqCW3dnkQg== + dependencies: + "@types/react" "*" + "@types/react-dom@^18.0.10", "@types/react-dom@^18.0.8": - version "18.0.11" - resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.0.11.tgz#321351c1459bc9ca3d216aefc8a167beec334e33" - integrity sha512-O38bPbI2CWtgw/OoQoY+BRelw7uysmXbWvw3nLWO21H1HSh+GOlqPuXshJfjmpNlKiiSDG9cc1JZAaMmVdcTlw== + version "18.2.17" + resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.2.17.tgz#375c55fab4ae671bd98448dcfa153268d01d6f64" + integrity sha512-rvrT/M7Df5eykWFxn6MYt5Pem/Dbyc1N8Y0S9Mrkw2WFCRiqUgw9P7ul2NpwsXCSM1DVdENzdG9J5SreqfAIWg== dependencies: "@types/react" "*" +"@types/react-dom@^18.0.25": + version "18.3.5" + resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.3.5.tgz#45f9f87398c5dcea085b715c58ddcf1faf65f716" + integrity sha512-P4t6saawp+b/dFrUr2cvkVsfvPguwsxtH6dNIYRllMsefqFzkZk5UIjzyDOv5g1dXIPdG4Sp1yCR4Z6RCUsG/Q== + "@types/react-syntax-highlighter@11.0.4": version "11.0.4" resolved "https://registry.yarnpkg.com/@types/react-syntax-highlighter/-/react-syntax-highlighter-11.0.4.tgz#d86d17697db62f98046874f62fdb3e53a0bbc4cd" @@ -5765,380 +7993,436 @@ dependencies: "@types/react" "*" -"@types/react-virtualized-auto-sizer@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@types/react-virtualized-auto-sizer/-/react-virtualized-auto-sizer-1.0.1.tgz#b3187dae1dfc4c15880c9cfc5b45f2719ea6ebd4" - integrity sha512-GH8sAnBEM5GV9LTeiz56r4ZhMOUSrP43tAQNSRVxNexDjcNKLCEtnxusAItg1owFUFE6k0NslV26gqVClVvong== - dependencies: - "@types/react" "*" - -"@types/react-window-infinite-loader@^1.0.6": - version "1.0.6" - resolved "https://registry.yarnpkg.com/@types/react-window-infinite-loader/-/react-window-infinite-loader-1.0.6.tgz#d7b23b4afaa1e0e2050876b766c3ea19f748f549" - integrity sha512-V8g8sBDLVeJJAfEENJS7VXZK+DRJ+jzPNtk8jpj2G+obhf+iqGNUDGwNWCbBhLiD+KpHhf3kWQlKBRi0tAeU4Q== - dependencies: - "@types/react" "*" - "@types/react-window" "*" - -"@types/react-window@*", "@types/react-window@^1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@types/react-window/-/react-window-1.8.5.tgz#285fcc5cea703eef78d90f499e1457e9b5c02fc1" - integrity sha512-V9q3CvhC9Jk9bWBOysPGaWy/Z0lxYcTXLtLipkt2cnRj1JOSFNF7wqGpkScSXMgBwC+fnVRg/7shwgddBG5ICw== +"@types/react@*", "@types/react@^18.0.25", "@types/react@^18.0.26": + version "18.2.38" + resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.38.tgz#3605ca41d3daff2c434e0b98d79a2469d4c2dd52" + integrity sha512-cBBXHzuPtQK6wNthuVMV6IjHAFkdl/FOPFIlkd81/Cd1+IqkHu/A+w4g43kaQQoYHik/ruaQBDL72HyCy1vuMw== dependencies: - "@types/react" "*" + "@types/prop-types" "*" + "@types/scheduler" "*" + csstype "^3.0.2" -"@types/react@*", "@types/react@^18.0.15", "@types/react@^18.0.25", "@types/react@^18.0.26": - version "18.0.33" - resolved "https://registry.yarnpkg.com/@types/react/-/react-18.0.33.tgz#a1575160cb4376787c2f5fe0312302f824baa61e" - integrity sha512-sHxzVxeanvQyQ1lr8NSHaj0kDzcNiGpILEVt69g9S31/7PfMvNCKLKcsHw4lYKjs3cGNJjXSP4mYzX43QlnjNA== +"@types/react@^16.8.0 || ^17.0.0 || ^18.0.0": + version "18.2.79" + resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.79.tgz#c40efb4f255711f554d47b449f796d1c7756d865" + integrity sha512-RwGAGXPl9kSXwdNTafkOEuFrTBD5SA2B3iEB96xi8+xu5ddUa/cpvyVCSNn+asgLCTHkb5ZxN8gbuibYJi4s1w== dependencies: "@types/prop-types" "*" - "@types/scheduler" "*" csstype "^3.0.2" "@types/reactcss@*": - version "1.2.6" - resolved "https://registry.yarnpkg.com/@types/reactcss/-/reactcss-1.2.6.tgz#133c1e7e896f2726370d1d5a26bf06a30a038bcc" - integrity sha512-qaIzpCuXNWomGR1Xq8SCFTtF4v8V27Y6f+b9+bzHiv087MylI/nTCqqdChNeWS7tslgROmYB7yeiruWX7WnqNg== + version "1.2.10" + resolved "https://registry.yarnpkg.com/@types/reactcss/-/reactcss-1.2.10.tgz#89feb81e913ccf68ff599dbabcc823e1b49c4f7c" + integrity sha512-gf5qJ1wOYP8N5q9H8/5c3QZHQzu8ltPClhM0vEWuBu9SGg4KSzgpJd2TShEsQDwsYn+mtnJ1xHUdJyzj/r9WrA== dependencies: "@types/react" "*" -"@types/resolve@1.17.1": - version "1.17.1" - resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-1.17.1.tgz#3afd6ad8967c77e4376c598a82ddd58f46ec45d6" - integrity sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw== +"@types/resolve@^1.20.2": + version "1.20.6" + resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-1.20.6.tgz#e6e60dad29c2c8c206c026e6dd8d6d1bdda850b8" + integrity sha512-A4STmOXPhMUtHH+S6ymgE2GiBSMqf4oTvcQZMcHzokuTLVYzXTB8ttjcgxOVaAp2lGwEdzZ0J+cRbbeevQj1UQ== + +"@types/retry@*": + version "0.12.5" + resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.5.tgz#f090ff4bd8d2e5b940ff270ab39fd5ca1834a07e" + integrity sha512-3xSjTp3v03X/lSQLkczaN9UIEwJMoMCA1+Nb5HfbJEQWogdeQIyVtTvxPXDQjZ5zws8rFQfVfRdz03ARihPJgw== + +"@types/scheduler@*": + version "0.16.8" + resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.8.tgz#ce5ace04cfeabe7ef87c0091e50752e36707deff" + integrity sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A== + +"@types/semver@^7.3.12", "@types/semver@^7.3.4": + version "7.5.6" + resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.6.tgz#c65b2bfce1bec346582c07724e3f8c1017a20339" + integrity sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A== + +"@types/send@*": + version "0.17.4" + resolved "https://registry.yarnpkg.com/@types/send/-/send-0.17.4.tgz#6619cd24e7270793702e4e6a4b958a9010cfc57a" + integrity sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA== dependencies: + "@types/mime" "^1" "@types/node" "*" -"@types/responselike@^1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@types/responselike/-/responselike-1.0.0.tgz#251f4fe7d154d2bad125abe1b429b23afd262e29" - integrity sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA== +"@types/serve-static@*": + version "1.15.5" + resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.15.5.tgz#15e67500ec40789a1e8c9defc2d32a896f05b033" + integrity sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ== dependencies: + "@types/http-errors" "*" + "@types/mime" "*" "@types/node" "*" -"@types/scheduler@*": - version "0.16.3" - resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.3.tgz#cef09e3ec9af1d63d2a6cc5b383a737e24e6dcf5" - integrity sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ== +"@types/stringify-object@^4.0.2": + version "4.0.5" + resolved "https://registry.yarnpkg.com/@types/stringify-object/-/stringify-object-4.0.5.tgz#c66c041c46f66c931a67f8e3569a66b8c92c95ba" + integrity sha512-TzX5V+njkbJ8iJ0mrj+Vqveep/1JBH4SSA3J2wYrE1eUrOhdsjTBCb0kao4EquSQ8KgPpqY4zSVP2vCPWKBElg== -"@types/source-list-map@*": - version "0.1.2" - resolved "https://registry.yarnpkg.com/@types/source-list-map/-/source-list-map-0.1.2.tgz#0078836063ffaf17412349bba364087e0ac02ec9" - integrity sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA== +"@types/trusted-types@^2.0.2": + version "2.0.7" + resolved "https://registry.yarnpkg.com/@types/trusted-types/-/trusted-types-2.0.7.tgz#baccb07a970b91707df3a3e8ba6896c57ead2d11" + integrity sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw== -"@types/stack-utils@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-1.0.1.tgz#0a851d3bd96498fa25c33ab7278ed3bd65f06c3e" - integrity sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw== +"@types/unist@*", "@types/unist@^3.0.0": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@types/unist/-/unist-3.0.2.tgz#6dd61e43ef60b34086287f83683a5c1b2dc53d20" + integrity sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ== -"@types/tapable@^1", "@types/tapable@^1.0.5": - version "1.0.8" - resolved "https://registry.yarnpkg.com/@types/tapable/-/tapable-1.0.8.tgz#b94a4391c85666c7b73299fd3ad79d4faa435310" - integrity sha512-ipixuVrh2OdNmauvtT51o3d8z12p6LtFW9in7U79der/kwejjdNchQC5UMn5u/KxNoM7VHHOs/l8KS8uHxhODQ== +"@types/unist@^2": + version "2.0.10" + resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.10.tgz#04ffa7f406ab628f7f7e97ca23e290cd8ab15efc" + integrity sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA== -"@types/tiny-secp256k1@^1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@types/tiny-secp256k1/-/tiny-secp256k1-1.0.0.tgz#0c8fde0dfd320c9d089907e37805d67a346ad991" - integrity sha512-IW3dFGNyVkVLC1MCMogVWQaKH/ZtjPQdOW9c3X128o5lVpFYNsq/l3Qo1pV7sfTmvDzWEXR3QTxg1TMy1pyaAQ== +"@types/uuid@^8.3.4": + version "8.3.4" + resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-8.3.4.tgz#bd86a43617df0594787d38b735f55c805becf1bc" + integrity sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw== + +"@types/uuid@^9.0.1": + version "9.0.8" + resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-9.0.8.tgz#7545ba4fc3c003d6c756f651f3bf163d8f0f29ba" + integrity sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA== + +"@types/w3c-web-hid@^1.0.2": + version "1.0.6" + resolved "https://registry.yarnpkg.com/@types/w3c-web-hid/-/w3c-web-hid-1.0.6.tgz#45435513f34544d8c9d650699cf5050a3a4fd104" + integrity sha512-IWyssXmRDo6K7s31dxf+U+x/XUWuVsl9qUIYbJmpUHPcTv/COfBCKw/F0smI45+gPV34brjyP30BFcIsHgYWLA== + +"@types/w3c-web-usb@^1.0.6": + version "1.0.10" + resolved "https://registry.yarnpkg.com/@types/w3c-web-usb/-/w3c-web-usb-1.0.10.tgz#cf89cccd2d93b6245e784c19afe0a9f5038d4528" + integrity sha512-CHgUI5kTc/QLMP8hODUHhge0D4vx+9UiAwIGiT0sTy/B2XpdX1U5rJt6JSISgr6ikRT7vxV9EVAFeYZqUnl1gQ== + +"@types/web@^0.0.138": + version "0.0.138" + resolved "https://registry.yarnpkg.com/@types/web/-/web-0.0.138.tgz#52ca1e688275a0b82a5522a7accaaa182aa029b1" + integrity sha512-oQD74hl+cNCZdSWIupJCXZ2azTuB3MJ/mrWlgYt+v4pD7/Dr78gl5hKAdieZNf9NrAqwUez79bHtnFVSNSscWA== + +"@types/ws@^7.2.0", "@types/ws@^7.4.4": + version "7.4.7" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-7.4.7.tgz#f7c390a36f7a0679aa69de2d501319f4f8d9b702" + integrity sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww== dependencies: "@types/node" "*" -"@types/uglify-js@*": - version "3.17.1" - resolved "https://registry.yarnpkg.com/@types/uglify-js/-/uglify-js-3.17.1.tgz#e0ffcef756476410e5bce2cb01384ed878a195b5" - integrity sha512-GkewRA4i5oXacU/n4MA9+bLgt5/L3F1mKrYvFGm7r2ouLXhRKjuWwo9XHNnbx6WF3vlGW21S3fCvgqxvxXXc5g== +"@types/ws@^8.2.2": + version "8.5.10" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.10.tgz#4acfb517970853fa6574a3a6886791d04a396787" + integrity sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A== dependencies: - source-map "^0.6.1" + "@types/node" "*" -"@types/unist@*", "@types/unist@^2.0.0", "@types/unist@^2.0.2", "@types/unist@^2.0.3": - version "2.0.6" - resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.6.tgz#250a7b16c3b91f672a24552ec64678eeb1d3a08d" - integrity sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ== +"@types/yargs-parser@*": + version "21.0.3" + resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.3.tgz#815e30b786d2e8f0dcd85fd5bcf5e1a04d008f15" + integrity sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ== -"@types/uuid@^7.0.0": - version "7.0.5" - resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-7.0.5.tgz#b1d2f772142a301538fae9bdf9cf15b9f2573a29" - integrity sha512-hKB88y3YHL8oPOs/CNlaXtjWn93+Bs48sDQR37ZUqG2tLeCS7EA1cmnkKsuQsub9OKEB/y/Rw9zqJqqNSbqVlQ== +"@types/yargs@^17.0.8": + version "17.0.32" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.32.tgz#030774723a2f7faafebf645f4e5a48371dca6229" + integrity sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog== + dependencies: + "@types/yargs-parser" "*" -"@types/uuid@^8.3.4": - version "8.3.4" - resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-8.3.4.tgz#bd86a43617df0594787d38b735f55c805becf1bc" - integrity sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw== +"@typescript-eslint/eslint-plugin@^5.59.7": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz#aeef0328d172b9e37d9bab6dbc13b87ed88977db" + integrity sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag== + dependencies: + "@eslint-community/regexpp" "^4.4.0" + "@typescript-eslint/scope-manager" "5.62.0" + "@typescript-eslint/type-utils" "5.62.0" + "@typescript-eslint/utils" "5.62.0" + debug "^4.3.4" + graphemer "^1.4.0" + ignore "^5.2.0" + natural-compare-lite "^1.4.0" + semver "^7.3.7" + tsutils "^3.21.0" -"@types/webpack-env@^1.16.0": - version "1.18.0" - resolved "https://registry.yarnpkg.com/@types/webpack-env/-/webpack-env-1.18.0.tgz#ed6ecaa8e5ed5dfe8b2b3d00181702c9925f13fb" - integrity sha512-56/MAlX5WMsPVbOg7tAxnYvNYMMWr/QJiIp6BxVSW3JJXUVzzOn64qW8TzQyMSqSUFM2+PVI4aUHcHOzIz/1tg== +"@typescript-eslint/parser@^5.59.7": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.62.0.tgz#1b63d082d849a2fcae8a569248fbe2ee1b8a56c7" + integrity sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA== + dependencies: + "@typescript-eslint/scope-manager" "5.62.0" + "@typescript-eslint/types" "5.62.0" + "@typescript-eslint/typescript-estree" "5.62.0" + debug "^4.3.4" -"@types/webpack-sources@*": - version "3.2.0" - resolved "https://registry.yarnpkg.com/@types/webpack-sources/-/webpack-sources-3.2.0.tgz#16d759ba096c289034b26553d2df1bf45248d38b" - integrity sha512-Ft7YH3lEVRQ6ls8k4Ff1oB4jN6oy/XmU6tQISKdhfh+1mR+viZFphS6WL0IrtDOzvefmJg5a0s7ZQoRXwqTEFg== +"@typescript-eslint/scope-manager@5.62.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz#d9457ccc6a0b8d6b37d0eb252a23022478c5460c" + integrity sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w== + dependencies: + "@typescript-eslint/types" "5.62.0" + "@typescript-eslint/visitor-keys" "5.62.0" + +"@typescript-eslint/type-utils@5.62.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.62.0.tgz#286f0389c41681376cdad96b309cedd17d70346a" + integrity sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew== + dependencies: + "@typescript-eslint/typescript-estree" "5.62.0" + "@typescript-eslint/utils" "5.62.0" + debug "^4.3.4" + tsutils "^3.21.0" + +"@typescript-eslint/types@5.62.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.62.0.tgz#258607e60effa309f067608931c3df6fed41fd2f" + integrity sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ== + +"@typescript-eslint/typescript-estree@5.62.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz#7d17794b77fabcac615d6a48fb143330d962eb9b" + integrity sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA== + dependencies: + "@typescript-eslint/types" "5.62.0" + "@typescript-eslint/visitor-keys" "5.62.0" + debug "^4.3.4" + globby "^11.1.0" + is-glob "^4.0.3" + semver "^7.3.7" + tsutils "^3.21.0" + +"@typescript-eslint/utils@5.62.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.62.0.tgz#141e809c71636e4a75daa39faed2fb5f4b10df86" + integrity sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ== + dependencies: + "@eslint-community/eslint-utils" "^4.2.0" + "@types/json-schema" "^7.0.9" + "@types/semver" "^7.3.12" + "@typescript-eslint/scope-manager" "5.62.0" + "@typescript-eslint/types" "5.62.0" + "@typescript-eslint/typescript-estree" "5.62.0" + eslint-scope "^5.1.1" + semver "^7.3.7" + +"@typescript-eslint/visitor-keys@5.62.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz#2174011917ce582875954ffe2f6912d5931e353e" + integrity sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw== + dependencies: + "@typescript-eslint/types" "5.62.0" + eslint-visitor-keys "^3.3.0" + +"@ungap/structured-clone@^1.0.0", "@ungap/structured-clone@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.2.0.tgz#756641adb587851b5ccb3e095daf27ae581c8406" + integrity sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ== + +"@vercel/routing-utils@^3.1.0": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@vercel/routing-utils/-/routing-utils-3.1.0.tgz#6a71903f4106006b2cb52add9d3b708b59acaaaf" + integrity sha512-Ci5xTjVTJY/JLZXpCXpLehMft97i9fH34nu9PGav6DtwkVUF6TOPX86U0W0niQjMZ5n6/ZP0BwcJK2LOozKaGw== dependencies: - "@types/node" "*" - "@types/source-list-map" "*" - source-map "^0.7.3" + path-to-regexp "6.1.0" + optionalDependencies: + ajv "^6.0.0" -"@types/webpack@^4.41.26", "@types/webpack@^4.41.8": - version "4.41.33" - resolved "https://registry.yarnpkg.com/@types/webpack/-/webpack-4.41.33.tgz#16164845a5be6a306bcbe554a8e67f9cac215ffc" - integrity sha512-PPajH64Ft2vWevkerISMtnZ8rTs4YmRbs+23c402J0INmxDKCrhZNvwZYtzx96gY2wAtXdrK1BS2fiC8MlLr3g== +"@visx/axis@2.18.0": + version "2.18.0" + resolved "https://registry.yarnpkg.com/@visx/axis/-/axis-2.18.0.tgz#9175e9d969df420592082b1ea64c16422377b389" + integrity sha512-iBMObSKHOHDZbuVXsdVLmAjLE5jCN1Ls3XI57v3yuf+qZ327mdPSliSOyOxhvRdaNDYPLSQj+P1nKan+04wJiQ== dependencies: - "@types/node" "*" - "@types/tapable" "^1" - "@types/uglify-js" "*" - "@types/webpack-sources" "*" - anymatch "^3.0.0" - source-map "^0.6.0" + "@types/react" "*" + "@visx/group" "2.17.0" + "@visx/point" "2.17.0" + "@visx/scale" "2.18.0" + "@visx/shape" "2.18.0" + "@visx/text" "2.17.0" + classnames "^2.3.1" + prop-types "^15.6.0" -"@types/ws@^7.4.4": - version "7.4.7" - resolved "https://registry.yarnpkg.com/@types/ws/-/ws-7.4.7.tgz#f7c390a36f7a0679aa69de2d501319f4f8d9b702" - integrity sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww== +"@visx/bounds@2.17.0": + version "2.17.0" + resolved "https://registry.yarnpkg.com/@visx/bounds/-/bounds-2.17.0.tgz#2585be71bc82032ad3e1456b34b2f2c17ad34e69" + integrity sha512-XsoyTAyCm+DZbrPgP3IZFZAcNqBmXFBLSep04TqnrEA3hf16GxIzcpaGe+hAVhPg5yzBdjc7tLk6s0h5F44niA== dependencies: - "@types/node" "*" + "@types/react" "*" + "@types/react-dom" "*" + prop-types "^15.5.10" -"@types/yargs-parser@*": - version "21.0.0" - resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.0.tgz#0c60e537fa790f5f9472ed2776c2b71ec117351b" - integrity sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA== +"@visx/curve@2.17.0": + version "2.17.0" + resolved "https://registry.yarnpkg.com/@visx/curve/-/curve-2.17.0.tgz#9b4c87dd0d10a62a0f85d5a72e4c0400316df9bf" + integrity sha512-8Fw2ZalgYbpeoelLqTOmMs/wD8maSKsKS9rRIwmHZ0O0XxY8iG9oVYbD4CLWzf/uFWCY6+qofk4J1g9BWQSXJQ== + dependencies: + "@types/d3-shape" "^1.3.1" + d3-shape "^1.0.6" -"@types/yargs@^15.0.0": - version "15.0.15" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-15.0.15.tgz#e609a2b1ef9e05d90489c2f5f45bbfb2be092158" - integrity sha512-IziEYMU9XoVj8hWg7k+UJrXALkGFjWJhn5QFEv9q4p+v40oZhSuC135M38st8XPjICL7Ey4TV64ferBGUoJhBg== +"@visx/event@2.17.0": + version "2.17.0" + resolved "https://registry.yarnpkg.com/@visx/event/-/event-2.17.0.tgz#220c7674505e0d7a55f36bce9575482a7fa7dc23" + integrity sha512-fg2UWo89RgKgWWnnqI+i7EF8Ry+3CdMHTND4lo4DyJvcZZUCOwhxCHMQ4/PHW0EAUfxI51nGadcE1BcEVR5zWw== dependencies: - "@types/yargs-parser" "*" + "@types/react" "*" + "@visx/point" "2.17.0" -"@typescript-eslint/eslint-plugin@^2.12.0": - version "2.34.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.34.0.tgz#6f8ce8a46c7dea4a6f1d171d2bb8fbae6dac2be9" - integrity sha512-4zY3Z88rEE99+CNvTbXSyovv2z9PNOVffTWD2W8QF5s2prBQtwN2zadqERcrHpcR7O/+KMI3fcTAmUUhK/iQcQ== - dependencies: - "@typescript-eslint/experimental-utils" "2.34.0" - functional-red-black-tree "^1.0.1" - regexpp "^3.0.0" - tsutils "^3.17.1" - -"@typescript-eslint/experimental-utils@2.34.0": - version "2.34.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-2.34.0.tgz#d3524b644cdb40eebceca67f8cf3e4cc9c8f980f" - integrity sha512-eS6FTkq+wuMJ+sgtuNTtcqavWXqsflWcfBnlYhg/nS4aZ1leewkXGbvBhaapn1q6qf4M71bsR1tez5JTRMuqwA== - dependencies: - "@types/json-schema" "^7.0.3" - "@typescript-eslint/typescript-estree" "2.34.0" - eslint-scope "^5.0.0" - eslint-utils "^2.0.0" - -"@typescript-eslint/parser@^2.12.0": - version "2.34.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-2.34.0.tgz#50252630ca319685420e9a39ca05fe185a256bc8" - integrity sha512-03ilO0ucSD0EPTw2X4PntSIRFtDPWjrVq7C3/Z3VQHRC7+13YB55rcJI3Jt+YgeHbjUdJPcPa7b23rXCBokuyA== - dependencies: - "@types/eslint-visitor-keys" "^1.0.0" - "@typescript-eslint/experimental-utils" "2.34.0" - "@typescript-eslint/typescript-estree" "2.34.0" - eslint-visitor-keys "^1.1.0" - -"@typescript-eslint/typescript-estree@2.34.0": - version "2.34.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-2.34.0.tgz#14aeb6353b39ef0732cc7f1b8285294937cf37d5" - integrity sha512-OMAr+nJWKdlVM9LOqCqh3pQQPwxHAN7Du8DR6dmwCrAmxtiXQnhHJ6tBNtf+cggqfo51SG/FCwnKhXCIM7hnVg== +"@visx/grid@2.18.0": + version "2.18.0" + resolved "https://registry.yarnpkg.com/@visx/grid/-/grid-2.18.0.tgz#ae68e975d4b203a626ddba3a39d67a135816d6be" + integrity sha512-bmOowI5QA0R1KgNKxj5y+Belj5MbUz+RRW2BxTsXa7NbDV6IsA7H4l+kj3DDldRi7Q5SVm9zpfwWXNIBAhiFdA== dependencies: - debug "^4.1.1" - eslint-visitor-keys "^1.1.0" - glob "^7.1.6" - is-glob "^4.0.1" - lodash "^4.17.15" - semver "^7.3.2" - tsutils "^3.17.1" + "@types/react" "*" + "@visx/curve" "2.17.0" + "@visx/group" "2.17.0" + "@visx/point" "2.17.0" + "@visx/scale" "2.18.0" + "@visx/shape" "2.18.0" + classnames "^2.3.1" + prop-types "^15.6.2" -"@vanilla-extract/babel-plugin-debug-ids@^1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@vanilla-extract/babel-plugin-debug-ids/-/babel-plugin-debug-ids-1.0.2.tgz#24674b4d09e98236c883d23aef6f37d1a326af28" - integrity sha512-LjnbQWGeMwaydmovx8jWUR8BxLtLiPyq0xz5C8G5OvFhsuJxvavLdrBHNNizvr1dq7/3qZGlPv0znsvU4P44YA== +"@visx/group@2.17.0": + version "2.17.0" + resolved "https://registry.yarnpkg.com/@visx/group/-/group-2.17.0.tgz#b349fd6507e56fcb43d0b067d728df4ab329ca2e" + integrity sha512-60Y2dIKRh3cp/Drpq//wM067ZNrnCcvFCXufPgIihv0Ix8O7oMsYxu3ch4XUMjks+U2IAZQr5Dnc+C9sTQFkhw== dependencies: - "@babel/core" "^7.20.7" + "@types/react" "*" + classnames "^2.3.1" + prop-types "^15.6.2" -"@vanilla-extract/css@^1.10.0": - version "1.11.0" - resolved "https://registry.yarnpkg.com/@vanilla-extract/css/-/css-1.11.0.tgz#ad285f31e0b0dff0d7a02cab6a2e5c39e5f2ddf3" - integrity sha512-uohj+8cGWbnrVzTfrjlJeXqdGjH3d3TcscdQxKe3h5bb5QQXTpPSq+c+SeWADIGiZybzcW0CBvZV8jsy1ywY9w== - dependencies: - "@emotion/hash" "^0.9.0" - "@vanilla-extract/private" "^1.0.3" - ahocorasick "1.0.2" - chalk "^4.1.1" - css-what "^5.0.1" - cssesc "^3.0.0" - csstype "^3.0.7" - deep-object-diff "^1.1.9" - deepmerge "^4.2.2" - media-query-parser "^2.0.2" - outdent "^0.8.0" +"@visx/point@2.17.0": + version "2.17.0" + resolved "https://registry.yarnpkg.com/@visx/point/-/point-2.17.0.tgz#c11f1efee5241bcd612a29f3b3099cb435c9604e" + integrity sha512-fUdGQBLGaSVbFTbQ6k+1nPisbqYjTjAdo9FhlwLd3W3uyXN/39Sx2z3N2579sVNBDzmCKdYNQIU0HC+/3Vqo6w== + +"@visx/scale@2.18.0": + version "2.18.0" + resolved "https://registry.yarnpkg.com/@visx/scale/-/scale-2.18.0.tgz#b78054e68ac8de49f0abeea0c60bb0bd14dec492" + integrity sha512-clH8HFblMlCuHvUjGRwenvbY1w9YXHU9fPl91Vbtd5bdM9xAN0Lo2+cgV46cvaX3YpnyVb4oNhlbPCBu3h6Rhw== + dependencies: + "@types/d3-interpolate" "^1.3.1" + "@types/d3-scale" "^3.3.0" + "@types/d3-time" "^2.0.0" + d3-interpolate "^1.4.0" + d3-scale "^3.3.0" + d3-time "^2.1.1" + +"@visx/shape@2.18.0": + version "2.18.0" + resolved "https://registry.yarnpkg.com/@visx/shape/-/shape-2.18.0.tgz#0d7202ca9e722ed9360e1b76f6de7b2748511d2a" + integrity sha512-kVSEjnzswQMyFDa/IXE7K+WsAkl91xK6A4W6MbGfcUhfQn+AP0GorvotW7HZGjkIlbmuLl14+vRktDo5jqS/og== + dependencies: + "@types/d3-path" "^1.0.8" + "@types/d3-shape" "^1.3.1" + "@types/lodash" "^4.14.172" + "@types/react" "*" + "@visx/curve" "2.17.0" + "@visx/group" "2.17.0" + "@visx/scale" "2.18.0" + classnames "^2.3.1" + d3-path "^1.0.5" + d3-shape "^1.2.0" + lodash "^4.17.21" + prop-types "^15.5.10" -"@vanilla-extract/integration@^6.0.2": - version "6.2.1" - resolved "https://registry.yarnpkg.com/@vanilla-extract/integration/-/integration-6.2.1.tgz#e87849ed3d8e9ddd2703b8b8597fdbff08cf62ad" - integrity sha512-+xYJz07G7TFAMZGrOqArOsURG+xcYvqctujEkANjw2McCBvGEK505RxQqOuNiA9Mi9hgGdNp2JedSa94f3eoLg== - dependencies: - "@babel/core" "^7.20.7" - "@babel/plugin-syntax-typescript" "^7.20.0" - "@vanilla-extract/babel-plugin-debug-ids" "^1.0.2" - "@vanilla-extract/css" "^1.10.0" - esbuild "0.17.6" - eval "0.1.6" - find-up "^5.0.0" - javascript-stringify "^2.0.1" +"@visx/text@2.17.0": + version "2.17.0" + resolved "https://registry.yarnpkg.com/@visx/text/-/text-2.17.0.tgz#e65aa8a202ce9cfdcbd898bb0afd6253ccea6a40" + integrity sha512-Eu6b8SMI+LU4O6H4l/QhCa7c4GtDTQO6jhSYuU70pdTST1Bm74nImPGekG2xDW3uxaLlkb8fDpvXag0Z7v+vlQ== + dependencies: + "@types/lodash" "^4.14.172" + "@types/react" "*" + classnames "^2.3.1" lodash "^4.17.21" - mlly "^1.1.0" - outdent "^0.8.0" - vite "^4.1.4" - vite-node "^0.28.5" + prop-types "^15.7.2" + reduce-css-calc "^1.3.0" -"@vanilla-extract/private@^1.0.3": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@vanilla-extract/private/-/private-1.0.3.tgz#7ec72bc2ff6fe51f9d650f962e8d1989b073690f" - integrity sha512-17kVyLq3ePTKOkveHxXuIJZtGYs+cSoev7BlP+Lf4916qfDhk/HBjvlYDe8egrea7LNPHKwSZJK/bzZC+Q6AwQ== +"@visx/tooltip@2.17.0": + version "2.17.0" + resolved "https://registry.yarnpkg.com/@visx/tooltip/-/tooltip-2.17.0.tgz#e5e39a62795d2f6c7d2a1472e7af092005374106" + integrity sha512-+dMHURP9NqSFZLomMUnoVYjRs+I2qcOw1yYvLtTp/4GUAFRMSUJoSJeuLwng1VBIgCEB95xuQ95NgGID4qzPxA== + dependencies: + "@types/react" "*" + "@visx/bounds" "2.17.0" + classnames "^2.3.1" + prop-types "^15.5.10" + react-use-measure "^2.0.4" -"@vercel/build-utils@6.7.0": - version "6.7.0" - resolved "https://registry.yarnpkg.com/@vercel/build-utils/-/build-utils-6.7.0.tgz#f0915b0a36dd3b56f188c7e477995aa910c151c0" - integrity sha512-1cHgu0AzETSMLo1ugeHOT2pcrXNoZb1bwgxBP7yTIlJAKWLIEqPHbJWFvKQXZl2FV3kzzTctTrw/YNUWmntYiA== +"@vitest/coverage-v8@^2.0.5": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@vitest/coverage-v8/-/coverage-v8-2.0.5.tgz#411961ce4fd1177a32b4dd74ab576ed3b859155e" + integrity sha512-qeFcySCg5FLO2bHHSa0tAZAOnAUbp4L6/A5JDuj9+bt53JREl8hpLjLHEWF0e/gWc8INVpJaqA7+Ene2rclpZg== + dependencies: + "@ampproject/remapping" "^2.3.0" + "@bcoe/v8-coverage" "^0.2.3" + debug "^4.3.5" + istanbul-lib-coverage "^3.2.2" + istanbul-lib-report "^3.0.1" + istanbul-lib-source-maps "^5.0.6" + istanbul-reports "^3.1.7" + magic-string "^0.30.10" + magicast "^0.3.4" + std-env "^3.7.0" + test-exclude "^7.0.1" + tinyrainbow "^1.2.0" + +"@vitest/expect@2.0.5": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@vitest/expect/-/expect-2.0.5.tgz#f3745a6a2c18acbea4d39f5935e913f40d26fa86" + integrity sha512-yHZtwuP7JZivj65Gxoi8upUN2OzHTi3zVfjwdpu2WrvCZPLwsJ2Ey5ILIPccoW23dd/zQBlJ4/dhi7DWNyXCpA== + dependencies: + "@vitest/spy" "2.0.5" + "@vitest/utils" "2.0.5" + chai "^5.1.1" + tinyrainbow "^1.2.0" -"@vercel/gatsby-plugin-vercel-analytics@1.0.8": - version "1.0.8" - resolved "https://registry.yarnpkg.com/@vercel/gatsby-plugin-vercel-analytics/-/gatsby-plugin-vercel-analytics-1.0.8.tgz#3779132cf1eb8d4ef00806a913249b65c4b5edf5" - integrity sha512-EL5xH3KOtAwzLc50NA2Df5BQwIV9tu8QBIG0unSTUtOpIaqqnOMBZT86DxadsAniUs7xYRcaeXOkQog/PbpWDw== +"@vitest/pretty-format@2.0.5", "@vitest/pretty-format@^2.0.5": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@vitest/pretty-format/-/pretty-format-2.0.5.tgz#91d2e6d3a7235c742e1a6cc50e7786e2f2979b1e" + integrity sha512-h8k+1oWHfwTkyTkb9egzwNMfJAEx4veaPSnMeKbVSjp4euqGSbQlm5+6VHwTr7u4FJslVVsUG5nopCaAYdOmSQ== dependencies: - "@babel/runtime" "7.12.1" - web-vitals "0.2.4" + tinyrainbow "^1.2.0" -"@vercel/gatsby-plugin-vercel-builder@1.2.6": - version "1.2.6" - resolved "https://registry.yarnpkg.com/@vercel/gatsby-plugin-vercel-builder/-/gatsby-plugin-vercel-builder-1.2.6.tgz#1daa8e0f951c6c766d17b1874afaacdd99de604a" - integrity sha512-mBxdsDQCIp10CuDFsAS3+6K8r6pQVtljb8Abey601g96oVSM6+8zlsuDgWsqQRaJducBi7kdHivvVoqzjVA6uA== - dependencies: - "@sinclair/typebox" "0.25.24" - "@vercel/build-utils" "6.7.0" - "@vercel/node" "2.10.2" - "@vercel/routing-utils" "2.1.11" - esbuild "0.14.47" - etag "1.8.1" - fs-extra "11.1.0" - -"@vercel/go@2.4.3": - version "2.4.3" - resolved "https://registry.yarnpkg.com/@vercel/go/-/go-2.4.3.tgz#0ae947ea6c1e934671bf06a6d73195fb07262446" - integrity sha512-EklaqH9pHCiu6XhmVYji1CvEy5LOS+hilJ64ncPBAQhXzjD5RuJ8u4Af1AFe46Zl7dpAEg5rYfCrz2hqsMo1Pw== - -"@vercel/hydrogen@0.0.61": - version "0.0.61" - resolved "https://registry.yarnpkg.com/@vercel/hydrogen/-/hydrogen-0.0.61.tgz#947175c897e714de0f79149d85546c2f1d7c1dc2" - integrity sha512-g9WB5tImyto697coEMOtbtT8F+9geHGW0DDCNMBlERjEtE4e1ILJ1P5u9lhM6i1nXvRJlQZZ8w2IbQuCZmNH2w== - -"@vercel/next@3.7.3": - version "3.7.3" - resolved "https://registry.yarnpkg.com/@vercel/next/-/next-3.7.3.tgz#6ae4b2fd4077ad1dd96804a47f1d6fdfa012223a" - integrity sha512-lNqn1j8B3IJCh0VEc3/d/1H8/z11Sou1nz1Rp4yBYYXJeiihFU7OLsDPxGFF/a5QfcSVlsMZVRRMaciWOFG2Ow== - -"@vercel/nft@0.22.5": - version "0.22.5" - resolved "https://registry.yarnpkg.com/@vercel/nft/-/nft-0.22.5.tgz#951bd7589ceebdd3e280afcf3a13bdacf83f6b7e" - integrity sha512-mug57Wd1BL7GMj9gXMgMeKUjdqO0e4u+0QLPYMFE1rwdJ+55oPy6lp3nIBCS8gOvigT62UI4QKUL2sGqcoW4Hw== - dependencies: - "@mapbox/node-pre-gyp" "^1.0.5" - "@rollup/pluginutils" "^4.0.0" - acorn "^8.6.0" - async-sema "^3.1.1" - bindings "^1.4.0" - estree-walker "2.0.2" - glob "^7.1.3" - graceful-fs "^4.2.9" - micromatch "^4.0.2" - node-gyp-build "^4.2.2" - resolve-from "^5.0.0" +"@vitest/runner@2.0.5": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@vitest/runner/-/runner-2.0.5.tgz#89197e712bb93513537d6876995a4843392b2a84" + integrity sha512-TfRfZa6Bkk9ky4tW0z20WKXFEwwvWhRY+84CnSEtq4+3ZvDlJyY32oNTJtM7AW9ihW90tX/1Q78cb6FjoAs+ig== + dependencies: + "@vitest/utils" "2.0.5" + pathe "^1.1.2" -"@vercel/node-bridge@4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@vercel/node-bridge/-/node-bridge-4.0.0.tgz#3214ff14c9388cb9bc3e78023ff618d3410b605d" - integrity sha512-617HSGelTGR68s0kqsPV0R2UiSvcw3Zf5Yv32S5NN4AH5TZGRr5DQJ3ATr4C/HrK7CHK5B7FDVrv2JebdVpPYQ== - -"@vercel/node@2.10.2": - version "2.10.2" - resolved "https://registry.yarnpkg.com/@vercel/node/-/node-2.10.2.tgz#9d09574b99ba59cef4865187acc829d5a2503f98" - integrity sha512-rsxVEosHUtSBswZfZWxWgV4v5x8COB9kTp4lhaxZXC9cHFgXT5ydV7m4R2NOPwcRGUbQSyy9ushX1RnsOan0qw== - dependencies: - "@edge-runtime/vm" "2.0.0" - "@types/node" "14.18.33" - "@vercel/build-utils" "6.7.0" - "@vercel/node-bridge" "4.0.0" - "@vercel/static-config" "2.0.14" - edge-runtime "2.0.0" - esbuild "0.14.47" - exit-hook "2.2.1" - node-fetch "2.6.7" - ts-node "10.9.1" - typescript "4.3.4" - -"@vercel/python@3.1.57": - version "3.1.57" - resolved "https://registry.yarnpkg.com/@vercel/python/-/python-3.1.57.tgz#952053cfb6ae8f95337e5c9bfc30523c5bc161f0" - integrity sha512-q/cy6dWBAYvhlm9ortub9IJMxXoHQ2UcJzhIl3//26OOuWoroJUWWgk7/uDFagxXrdxOt1hSfHZ3kDUbwGBe/w== - -"@vercel/redwood@1.1.13": - version "1.1.13" - resolved "https://registry.yarnpkg.com/@vercel/redwood/-/redwood-1.1.13.tgz#f9aa2941fa3401d0875c9cab11f4733fcbdc1bf8" - integrity sha512-4PmEaPl7+1Cnr7GLBBg+pldKPOmsZpafnrtgLQyX3I87KFfDScvf+ELJYFDk4TdbRXT2iXdryL7NfNC/LT39xw== - dependencies: - "@vercel/nft" "0.22.5" - "@vercel/routing-utils" "2.1.11" - semver "6.1.1" - -"@vercel/remix-builder@1.8.3": - version "1.8.3" - resolved "https://registry.yarnpkg.com/@vercel/remix-builder/-/remix-builder-1.8.3.tgz#7e1a0e27aaa983d7abd5f991c69908c975b3a544" - integrity sha512-H0yzb+DTzCB8ALgLhXZeJfHlOWhz7j9pXeVGL21RnTzX8lvG2AUHtotYjIadLjR0SuYzB0NvYKPG5mrHmFrFNg== - dependencies: - "@remix-run/dev" "npm:@vercel/remix-run-dev@1.14.2" - "@vercel/build-utils" "6.7.0" - "@vercel/nft" "0.22.5" - "@vercel/static-config" "2.0.14" - path-to-regexp "6.2.1" - semver "7.3.8" - ts-morph "12.0.0" - -"@vercel/routing-utils@2.1.11": - version "2.1.11" - resolved "https://registry.yarnpkg.com/@vercel/routing-utils/-/routing-utils-2.1.11.tgz#5d479f6ea41e3f9b00546df7d1d5cadd6a0fe5ee" - integrity sha512-3cr0c41tylYvC6JMmzxC2kEf5iqFT0Kz1sqTs1koRVeiAEsf6soKi0FwW+ASbT3+9rBiJDkG2E1y4J3mZn6DZQ== +"@vitest/snapshot@2.0.5": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@vitest/snapshot/-/snapshot-2.0.5.tgz#a2346bc5013b73c44670c277c430e0334690a162" + integrity sha512-SgCPUeDFLaM0mIUHfaArq8fD2WbaXG/zVXjRupthYfYGzc8ztbFbu6dUNOblBG7XLMR1kEhS/DNnfCZ2IhdDew== dependencies: - path-to-regexp "6.1.0" - optionalDependencies: - ajv "^6.0.0" + "@vitest/pretty-format" "2.0.5" + magic-string "^0.30.10" + pathe "^1.1.2" -"@vercel/ruby@1.3.74": - version "1.3.74" - resolved "https://registry.yarnpkg.com/@vercel/ruby/-/ruby-1.3.74.tgz#a06e6c7a584143a6307f3e5e3c2e07c3605b8f41" - integrity sha512-LexN8Tlr+oaveInWOZhHVLXjvz4AWlGDvgKavKZQHZokPpXXn2gQPuRaf26B+ZAYfqCEsOnoH/Uwea9fjc5vQw== +"@vitest/spy@2.0.5": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@vitest/spy/-/spy-2.0.5.tgz#590fc07df84a78b8e9dd976ec2090920084a2b9f" + integrity sha512-c/jdthAhvJdpfVuaexSrnawxZz6pywlTPe84LUB2m/4t3rl2fTo9NFGBG4oWgaD+FTgDDV8hJ/nibT7IfH3JfA== + dependencies: + tinyspy "^3.0.0" -"@vercel/static-build@1.3.21": - version "1.3.21" - resolved "https://registry.yarnpkg.com/@vercel/static-build/-/static-build-1.3.21.tgz#1175baed3ed2ffa3eb021b1d6b5adc8e39b13697" - integrity sha512-4KSs4kG+jfoFnrQaX0e7zIkkaz9QPEKh+SAcpZ8H4roVeBo1rdin7A3wze0iC7pTObpEAHXHme2zylpBcUGYOQ== +"@vitest/utils@2.0.5": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@vitest/utils/-/utils-2.0.5.tgz#6f8307a4b6bc6ceb9270007f73c67c915944e926" + integrity sha512-d8HKbqIcya+GR67mkZbrzhS5kKhtp8dQLcmRZLGTscGVg7yImT82cIrhtn2L8+VujWcy6KZweApgNmPsTAO/UQ== dependencies: - "@vercel/gatsby-plugin-vercel-analytics" "1.0.8" - "@vercel/gatsby-plugin-vercel-builder" "1.2.6" + "@vitest/pretty-format" "2.0.5" + estree-walker "^3.0.3" + loupe "^3.1.1" + tinyrainbow "^1.2.0" -"@vercel/static-config@2.0.14": - version "2.0.14" - resolved "https://registry.yarnpkg.com/@vercel/static-config/-/static-config-2.0.14.tgz#8097516c94360ea7914d8b89cdb4b7da72e29841" - integrity sha512-Ih0H/V8geRjsNpvD73dphV+y0Pe21RXIJEUW/XI0y7ZrYzLbYQt4AAIvsgfDqcQNm4xEizh3sEXArPWEp18bdQ== +"@wallet-standard/base@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@wallet-standard/base/-/base-1.0.1.tgz#860dd94d47c9e3c5c43b79d91c6afdbd7a36264e" + integrity sha512-1To3ekMfzhYxe0Yhkpri+Fedq0SYcfrOfJi3vbLjMwF2qiKPjTGLwZkf2C9ftdQmxES+hmxhBzTwF4KgcOwf8w== + +"@wallet-standard/features@^1.0.3": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@wallet-standard/features/-/features-1.0.3.tgz#c992876c5e4f7a0672f8869c4146c87e0dfe48c8" + integrity sha512-m8475I6W5LTatTZuUz5JJNK42wFRgkJTB0I9tkruMwfqBF2UN2eomkYNVf9RbrsROelCRzSFmugqjKZBFaubsA== dependencies: - ajv "8.6.3" - json-schema-to-ts "1.6.4" - ts-morph "12.0.0" + "@wallet-standard/base" "^1.0.1" "@walletconnect/browser-utils@^1.8.0": version "1.8.0" @@ -6151,17 +8435,30 @@ "@walletconnect/window-metadata" "1.0.0" detect-browser "5.2.0" -"@walletconnect/client@^1.8.0": - version "1.8.0" - resolved "https://registry.yarnpkg.com/@walletconnect/client/-/client-1.8.0.tgz#6f46b5499c7c861c651ff1ebe5da5b66225ca696" - integrity sha512-svyBQ14NHx6Cs2j4TpkQaBI/2AF4+LXz64FojTjMtV4VMMhl81jSO1vNeg+yYhQzvjcGH/GpSwixjyCW0xFBOQ== - dependencies: - "@walletconnect/core" "^1.8.0" - "@walletconnect/iso-crypto" "^1.8.0" - "@walletconnect/types" "^1.8.0" - "@walletconnect/utils" "^1.8.0" +"@walletconnect/core@2.11.2": + version "2.11.2" + resolved "https://registry.yarnpkg.com/@walletconnect/core/-/core-2.11.2.tgz#35286be92c645fa461fecc0dfe25de9f076fca8f" + integrity sha512-bB4SiXX8hX3/hyBfVPC5gwZCXCl+OPj+/EDVM71iAO3TDsh78KPbrVAbDnnsbHzZVHlsMohtXX3j5XVsheN3+g== + dependencies: + "@walletconnect/heartbeat" "1.2.1" + "@walletconnect/jsonrpc-provider" "1.0.13" + "@walletconnect/jsonrpc-types" "1.0.3" + "@walletconnect/jsonrpc-utils" "1.0.8" + "@walletconnect/jsonrpc-ws-connection" "1.0.14" + "@walletconnect/keyvaluestorage" "^1.1.1" + "@walletconnect/logger" "^2.0.1" + "@walletconnect/relay-api" "^1.0.9" + "@walletconnect/relay-auth" "^1.0.4" + "@walletconnect/safe-json" "^1.0.2" + "@walletconnect/time" "^1.0.2" + "@walletconnect/types" "2.11.2" + "@walletconnect/utils" "2.11.2" + events "^3.3.0" + isomorphic-unfetch "3.1.0" + lodash.isequal "4.5.0" + uint8arrays "^3.1.0" -"@walletconnect/core@^1.8.0": +"@walletconnect/core@^1.6.6": version "1.8.0" resolved "https://registry.yarnpkg.com/@walletconnect/core/-/core-1.8.0.tgz#6b2748b90c999d9d6a70e52e26a8d5e8bfeaa81e" integrity sha512-aFTHvEEbXcZ8XdWBw6rpQDte41Rxwnuk3SgTD8/iKGSRTni50gI9S3YEzMj05jozSiOBxQci4pJDMVhIUMtarw== @@ -6198,21 +8495,24 @@ dependencies: tslib "1.14.1" -"@walletconnect/ethereum-provider@1.8.0": - version "1.8.0" - resolved "https://registry.yarnpkg.com/@walletconnect/ethereum-provider/-/ethereum-provider-1.8.0.tgz#ed1dbf9cecc3b818758a060d2f9017c50bde1d32" - integrity sha512-Nq9m+oo5P0F+njsROHw9KMWdoc/8iGHYzQdkjJN/1C7DtsqFRg5k5a3hd9rzCLpbPsOC1q8Z5lRs6JQgDvPm6Q== +"@walletconnect/events@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@walletconnect/events/-/events-1.0.1.tgz#2b5f9c7202019e229d7ccae1369a9e86bda7816c" + integrity sha512-NPTqaoi0oPBVNuLv7qPaJazmGHs5JGyO8eEAk5VGKmJzDR7AHzD4k6ilox5kxk1iwiOnFopBOOMLs86Oa76HpQ== dependencies: - "@walletconnect/client" "^1.8.0" - "@walletconnect/jsonrpc-http-connection" "^1.0.2" - "@walletconnect/jsonrpc-provider" "^1.0.5" - "@walletconnect/signer-connection" "^1.8.0" - "@walletconnect/types" "^1.8.0" - "@walletconnect/utils" "^1.8.0" - eip1193-provider "1.0.1" - eventemitter3 "4.0.7" + keyvaluestorage-interface "^1.0.0" + tslib "1.14.1" + +"@walletconnect/heartbeat@1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@walletconnect/heartbeat/-/heartbeat-1.2.1.tgz#afaa3a53232ae182d7c9cff41c1084472d8f32e9" + integrity sha512-yVzws616xsDLJxuG/28FqtZ5rzrTA4gUjdEMTbWB5Y8V1XHRmqq4efAxCw5ie7WjbXFSUyBHaWlMR+2/CpQC5Q== + dependencies: + "@walletconnect/events" "^1.0.1" + "@walletconnect/time" "^1.0.2" + tslib "1.14.1" -"@walletconnect/iso-crypto@^1.8.0": +"@walletconnect/iso-crypto@^1.6.6": version "1.8.0" resolved "https://registry.yarnpkg.com/@walletconnect/iso-crypto/-/iso-crypto-1.8.0.tgz#44ddf337c4f02837c062dbe33fa7ab36789df451" integrity sha512-pWy19KCyitpfXb70hA73r9FcvklS+FvO9QUIttp3c2mfW8frxgYeRXfxLRCIQTkaYueRKvdqPjbyhPLam508XQ== @@ -6221,58 +8521,83 @@ "@walletconnect/types" "^1.8.0" "@walletconnect/utils" "^1.8.0" -"@walletconnect/jsonrpc-http-connection@^1.0.2": - version "1.0.6" - resolved "https://registry.yarnpkg.com/@walletconnect/jsonrpc-http-connection/-/jsonrpc-http-connection-1.0.6.tgz#48c41cf3e5ac9add9425420b345615dc438594cd" - integrity sha512-/3zSqDi7JDN06E4qm0NmVYMitngXfh21UWwy8zeJcBeJc+Jcs094EbLsIxtziIIKTCCbT88lWuTjl1ZujxN7cw== +"@walletconnect/jsonrpc-provider@1.0.13": + version "1.0.13" + resolved "https://registry.yarnpkg.com/@walletconnect/jsonrpc-provider/-/jsonrpc-provider-1.0.13.tgz#9a74da648d015e1fffc745f0c7d629457f53648b" + integrity sha512-K73EpThqHnSR26gOyNEL+acEex3P7VWZe6KE12ZwKzAt2H4e5gldZHbjsu2QR9cLeJ8AXuO7kEMOIcRv1QEc7g== dependencies: - "@walletconnect/jsonrpc-utils" "^1.0.6" - "@walletconnect/safe-json" "^1.0.1" - cross-fetch "^3.1.4" + "@walletconnect/jsonrpc-utils" "^1.0.8" + "@walletconnect/safe-json" "^1.0.2" tslib "1.14.1" -"@walletconnect/jsonrpc-provider@^1.0.5": - version "1.0.10" - resolved "https://registry.yarnpkg.com/@walletconnect/jsonrpc-provider/-/jsonrpc-provider-1.0.10.tgz#8351a06b70faa8f8c0e77dc2c6d9b0190d17d407" - integrity sha512-g0ffPSpY3P6GqGjWGHsr3yqvQUhj7q2k6pAikoXv5XTXWaJRzFvrlbFkSgxziXsBrwrMZn0qvPufvpN4mMZ5FA== +"@walletconnect/jsonrpc-types@1.0.3", "@walletconnect/jsonrpc-types@^1.0.2", "@walletconnect/jsonrpc-types@^1.0.3": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@walletconnect/jsonrpc-types/-/jsonrpc-types-1.0.3.tgz#65e3b77046f1a7fa8347ae02bc1b841abe6f290c" + integrity sha512-iIQ8hboBl3o5ufmJ8cuduGad0CQm3ZlsHtujv9Eu16xq89q+BG7Nh5VLxxUgmtpnrePgFkTwXirCTkwJH1v+Yw== dependencies: - "@walletconnect/jsonrpc-utils" "^1.0.6" - "@walletconnect/safe-json" "^1.0.1" + keyvaluestorage-interface "^1.0.0" tslib "1.14.1" -"@walletconnect/jsonrpc-types@^1.0.1", "@walletconnect/jsonrpc-types@^1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@walletconnect/jsonrpc-types/-/jsonrpc-types-1.0.2.tgz#b79519f679cd6a5fa4a1bea888f27c1916689a20" - integrity sha512-CZe8tjJX73OWdHjrBHy7HtAapJ2tT0Q3TYhPBhRxi3643lwPIQWC9En45ldY14TZwgSewkbZ0FtGBZK0G7Bbyg== +"@walletconnect/jsonrpc-utils@1.0.8", "@walletconnect/jsonrpc-utils@^1.0.3", "@walletconnect/jsonrpc-utils@^1.0.6", "@walletconnect/jsonrpc-utils@^1.0.8": + version "1.0.8" + resolved "https://registry.yarnpkg.com/@walletconnect/jsonrpc-utils/-/jsonrpc-utils-1.0.8.tgz#82d0cc6a5d6ff0ecc277cb35f71402c91ad48d72" + integrity sha512-vdeb03bD8VzJUL6ZtzRYsFMq1eZQcM3EAzT0a3st59dyLfJ0wq+tKMpmGH7HlB7waD858UWgfIcudbPFsbzVdw== dependencies: - keyvaluestorage-interface "^1.0.0" + "@walletconnect/environment" "^1.0.1" + "@walletconnect/jsonrpc-types" "^1.0.3" tslib "1.14.1" -"@walletconnect/jsonrpc-utils@^1.0.3", "@walletconnect/jsonrpc-utils@^1.0.4", "@walletconnect/jsonrpc-utils@^1.0.6": - version "1.0.6" - resolved "https://registry.yarnpkg.com/@walletconnect/jsonrpc-utils/-/jsonrpc-utils-1.0.6.tgz#7fa58e6671247e64e189828103282e6258f5330f" - integrity sha512-snp0tfkjPiDLQp/jrBewI+9SM33GPV4+Gjgldod6XQ7rFyQ5FZjnBxUkY4xWH0+arNxzQSi6v5iDXjCjSaorpg== +"@walletconnect/jsonrpc-ws-connection@1.0.14": + version "1.0.14" + resolved "https://registry.yarnpkg.com/@walletconnect/jsonrpc-ws-connection/-/jsonrpc-ws-connection-1.0.14.tgz#eec700e74766c7887de2bd76c91a0206628732aa" + integrity sha512-Jsl6fC55AYcbkNVkwNM6Jo+ufsuCQRqViOQ8ZBPH9pRREHH9welbBiszuTLqEJiQcO/6XfFDl6bzCJIkrEi8XA== dependencies: - "@walletconnect/environment" "^1.0.1" - "@walletconnect/jsonrpc-types" "^1.0.2" + "@walletconnect/jsonrpc-utils" "^1.0.6" + "@walletconnect/safe-json" "^1.0.2" + events "^3.3.0" + ws "^7.5.1" + +"@walletconnect/keyvaluestorage@^1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@walletconnect/keyvaluestorage/-/keyvaluestorage-1.1.1.tgz#dd2caddabfbaf80f6b8993a0704d8b83115a1842" + integrity sha512-V7ZQq2+mSxAq7MrRqDxanTzu2RcElfK1PfNYiaVnJgJ7Q7G7hTVwF8voIBx92qsRyGHZihrwNPHuZd1aKkd0rA== + dependencies: + "@walletconnect/safe-json" "^1.0.1" + idb-keyval "^6.2.1" + unstorage "^1.9.0" + +"@walletconnect/logger@^2.0.1": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@walletconnect/logger/-/logger-2.0.1.tgz#7f489b96e9a1ff6bf3e58f0fbd6d69718bf844a8" + integrity sha512-SsTKdsgWm+oDTBeNE/zHxxr5eJfZmE9/5yp/Ku+zJtcTAjELb3DXueWkDXmE9h8uHIbJzIb5wj5lPdzyrjT6hQ== + dependencies: + pino "7.11.0" tslib "1.14.1" -"@walletconnect/mobile-registry@^1.4.0": - version "1.4.0" - resolved "https://registry.yarnpkg.com/@walletconnect/mobile-registry/-/mobile-registry-1.4.0.tgz#502cf8ab87330841d794819081e748ebdef7aee5" - integrity sha512-ZtKRio4uCZ1JUF7LIdecmZt7FOLnX72RPSY7aUVu7mj7CSfxDwUn6gBuK6WGtH+NZCldBqDl5DenI5fFSvkKYw== +"@walletconnect/modal-core@2.6.2": + version "2.6.2" + resolved "https://registry.yarnpkg.com/@walletconnect/modal-core/-/modal-core-2.6.2.tgz#d73e45d96668764e0c8668ea07a45bb8b81119e9" + integrity sha512-cv8ibvdOJQv2B+nyxP9IIFdxvQznMz8OOr/oR/AaUZym4hjXNL/l1a2UlSQBXrVjo3xxbouMxLb3kBsHoYP2CA== + dependencies: + valtio "1.11.2" -"@walletconnect/qrcode-modal@^1.8.0": - version "1.8.0" - resolved "https://registry.yarnpkg.com/@walletconnect/qrcode-modal/-/qrcode-modal-1.8.0.tgz#ddd6f5c9b7ee52c16adf9aacec2a3eac4994caea" - integrity sha512-BueaFefaAi8mawE45eUtztg3ZFbsAH4DDXh1UNwdUlsvFMjqcYzLUG0xZvDd6z2eOpbgDg2N3bl6gF0KONj1dg== +"@walletconnect/modal-ui@2.6.2": + version "2.6.2" + resolved "https://registry.yarnpkg.com/@walletconnect/modal-ui/-/modal-ui-2.6.2.tgz#fa57c087c57b7f76aaae93deab0f84bb68b59cf9" + integrity sha512-rbdstM1HPGvr7jprQkyPggX7rP4XiCG85ZA+zWBEX0dVQg8PpAgRUqpeub4xQKDgY7pY/xLRXSiCVdWGqvG2HA== dependencies: - "@walletconnect/browser-utils" "^1.8.0" - "@walletconnect/mobile-registry" "^1.4.0" - "@walletconnect/types" "^1.8.0" - copy-to-clipboard "^3.3.1" - preact "10.4.1" - qrcode "1.4.4" + "@walletconnect/modal-core" "2.6.2" + lit "2.8.0" + motion "10.16.2" + qrcode "1.5.3" + +"@walletconnect/modal@^2.6.2": + version "2.6.2" + resolved "https://registry.yarnpkg.com/@walletconnect/modal/-/modal-2.6.2.tgz#4b534a836f5039eeb3268b80be7217a94dd12651" + integrity sha512-eFopgKi8AjKf/0U4SemvcYw9zlLpx9njVN8sf6DAkowC2Md0gPU/UNEbH1Wwj407pEKnEds98pKWib1NN1ACoA== + dependencies: + "@walletconnect/modal-core" "2.6.2" + "@walletconnect/modal-ui" "2.6.2" "@walletconnect/randombytes@^1.0.3": version "1.0.3" @@ -6284,29 +8609,52 @@ randombytes "^2.1.0" tslib "1.14.1" +"@walletconnect/relay-api@^1.0.9": + version "1.0.9" + resolved "https://registry.yarnpkg.com/@walletconnect/relay-api/-/relay-api-1.0.9.tgz#f8c2c3993dddaa9f33ed42197fc9bfebd790ecaf" + integrity sha512-Q3+rylJOqRkO1D9Su0DPE3mmznbAalYapJ9qmzDgK28mYF9alcP3UwG/og5V7l7CFOqzCLi7B8BvcBUrpDj0Rg== + dependencies: + "@walletconnect/jsonrpc-types" "^1.0.2" + tslib "1.14.1" + +"@walletconnect/relay-auth@^1.0.4": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@walletconnect/relay-auth/-/relay-auth-1.0.4.tgz#0b5c55c9aa3b0ef61f526ce679f3ff8a5c4c2c7c" + integrity sha512-kKJcS6+WxYq5kshpPaxGHdwf5y98ZwbfuS4EE/NkQzqrDFm5Cj+dP8LofzWvjrrLkZq7Afy7WrQMXdLy8Sx7HQ== + dependencies: + "@stablelib/ed25519" "^1.0.2" + "@stablelib/random" "^1.0.1" + "@walletconnect/safe-json" "^1.0.1" + "@walletconnect/time" "^1.0.2" + tslib "1.14.1" + uint8arrays "^3.0.0" + "@walletconnect/safe-json@1.0.0": version "1.0.0" resolved "https://registry.yarnpkg.com/@walletconnect/safe-json/-/safe-json-1.0.0.tgz#12eeb11d43795199c045fafde97e3c91646683b2" integrity sha512-QJzp/S/86sUAgWY6eh5MKYmSfZaRpIlmCJdi5uG4DJlKkZrHEF7ye7gA+VtbVzvTtpM/gRwO2plQuiooIeXjfg== -"@walletconnect/safe-json@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@walletconnect/safe-json/-/safe-json-1.0.1.tgz#9813fa0a7a544b16468730c2d7bed046ed160957" - integrity sha512-Fm7e31oSYY15NQr8SsLJheKAy5L744udZf2lJKcz6wFmPJEzf7hOF0866o/rrldRzJnjZ4H2GJ45pFudsnLW5A== +"@walletconnect/safe-json@^1.0.1", "@walletconnect/safe-json@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@walletconnect/safe-json/-/safe-json-1.0.2.tgz#7237e5ca48046e4476154e503c6d3c914126fa77" + integrity sha512-Ogb7I27kZ3LPC3ibn8ldyUr5544t3/STow9+lzz7Sfo808YD7SBWk7SAsdBFlYgP2zDRy2hS3sKRcuSRM0OTmA== dependencies: tslib "1.14.1" -"@walletconnect/signer-connection@^1.8.0": - version "1.8.0" - resolved "https://registry.yarnpkg.com/@walletconnect/signer-connection/-/signer-connection-1.8.0.tgz#6cdf490df770e504cc1a550bdb5bac7696b130bc" - integrity sha512-+YAaTAP52MWZJ2wWnqKClKCPlPHBo6reURFe0cWidLADh9mi/kPWGALZ5AENK22zpem1bbKV466rF5Rzvu0ehA== - dependencies: - "@walletconnect/client" "^1.8.0" - "@walletconnect/jsonrpc-types" "^1.0.1" - "@walletconnect/jsonrpc-utils" "^1.0.3" - "@walletconnect/qrcode-modal" "^1.8.0" - "@walletconnect/types" "^1.8.0" - eventemitter3 "4.0.7" +"@walletconnect/sign-client@^2.11.2": + version "2.11.2" + resolved "https://registry.yarnpkg.com/@walletconnect/sign-client/-/sign-client-2.11.2.tgz#855609653855f0d23b0502cdbdcf43402e34c459" + integrity sha512-MfBcuSz2GmMH+P7MrCP46mVE5qhP0ZyWA0FyIH6/WuxQ6G+MgKsGfaITqakpRPsykWOJq8tXMs3XvUPDU413OQ== + dependencies: + "@walletconnect/core" "2.11.2" + "@walletconnect/events" "^1.0.1" + "@walletconnect/heartbeat" "1.2.1" + "@walletconnect/jsonrpc-utils" "1.0.8" + "@walletconnect/logger" "^2.0.1" + "@walletconnect/time" "^1.0.2" + "@walletconnect/types" "2.11.2" + "@walletconnect/utils" "2.11.2" + events "^3.3.0" "@walletconnect/socket-transport@^1.8.0": version "1.8.0" @@ -6317,12 +8665,51 @@ "@walletconnect/utils" "^1.8.0" ws "7.5.3" -"@walletconnect/types@^1.8.0": +"@walletconnect/time@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@walletconnect/time/-/time-1.0.2.tgz#6c5888b835750ecb4299d28eecc5e72c6d336523" + integrity sha512-uzdd9woDcJ1AaBZRhqy5rNC9laqWGErfc4dxA9a87mPdKOgWMD85mcFo9dIYIts/Jwocfwn07EC6EzclKubk/g== + dependencies: + tslib "1.14.1" + +"@walletconnect/types@2.11.2", "@walletconnect/types@^2.11.2": + version "2.11.2" + resolved "https://registry.yarnpkg.com/@walletconnect/types/-/types-2.11.2.tgz#d0359dd4106fcaa1634241a00428d3ea08d0d3c7" + integrity sha512-p632MFB+lJbip2cvtXPBQslpUdiw1sDtQ5y855bOlAGquay+6fZ4h1DcDePeKQDQM3P77ax2a9aNPZxV6y/h1Q== + dependencies: + "@walletconnect/events" "^1.0.1" + "@walletconnect/heartbeat" "1.2.1" + "@walletconnect/jsonrpc-types" "1.0.3" + "@walletconnect/keyvaluestorage" "^1.1.1" + "@walletconnect/logger" "^2.0.1" + events "^3.3.0" + +"@walletconnect/types@^1.6.6", "@walletconnect/types@^1.8.0": version "1.8.0" resolved "https://registry.yarnpkg.com/@walletconnect/types/-/types-1.8.0.tgz#3f5e85b2d6b149337f727ab8a71b8471d8d9a195" integrity sha512-Cn+3I0V0vT9ghMuzh1KzZvCkiAxTq+1TR2eSqw5E5AVWfmCtECFkVZBP6uUJZ8YjwLqXheI+rnjqPy7sVM4Fyg== -"@walletconnect/utils@^1.8.0": +"@walletconnect/utils@2.11.2", "@walletconnect/utils@^2.11.2": + version "2.11.2" + resolved "https://registry.yarnpkg.com/@walletconnect/utils/-/utils-2.11.2.tgz#dee0f19adf5e38543612cbe9fa4de7ed28eb7e85" + integrity sha512-LyfdmrnZY6dWqlF4eDrx5jpUwsB2bEPjoqR5Z6rXPiHJKUOdJt7az+mNOn5KTSOlRpd1DmozrBrWr+G9fFLYVw== + dependencies: + "@stablelib/chacha20poly1305" "1.0.1" + "@stablelib/hkdf" "1.0.1" + "@stablelib/random" "^1.0.2" + "@stablelib/sha256" "1.0.1" + "@stablelib/x25519" "^1.0.3" + "@walletconnect/relay-api" "^1.0.9" + "@walletconnect/safe-json" "^1.0.2" + "@walletconnect/time" "^1.0.2" + "@walletconnect/types" "2.11.2" + "@walletconnect/window-getters" "^1.0.1" + "@walletconnect/window-metadata" "^1.0.1" + detect-browser "5.3.0" + query-string "7.1.3" + uint8arrays "^3.1.0" + +"@walletconnect/utils@^1.6.6", "@walletconnect/utils@^1.8.0": version "1.8.0" resolved "https://registry.yarnpkg.com/@walletconnect/utils/-/utils-1.8.0.tgz#2591a197c1fa7429941fe428876088fda6632060" integrity sha512-zExzp8Mj1YiAIBfKNm5u622oNw44WOESzo6hj+Q3apSMIb0Jph9X3GDIdbZmvVZsNPxWDL7uodKgZcCInZv2vA== @@ -6340,7 +8727,7 @@ resolved "https://registry.yarnpkg.com/@walletconnect/window-getters/-/window-getters-1.0.0.tgz#1053224f77e725dfd611c83931b5f6c98c32bfc8" integrity sha512-xB0SQsLaleIYIkSsl43vm8EwETpBzJ2gnzk7e0wMF3ktqiTGS6TFHxcprMl5R44KKh4tCcHCJwolMCaDSwtAaA== -"@walletconnect/window-getters@^1.0.0": +"@walletconnect/window-getters@^1.0.0", "@walletconnect/window-getters@^1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@walletconnect/window-getters/-/window-getters-1.0.1.tgz#f36d1c72558a7f6b87ecc4451fc8bd44f63cbbdc" integrity sha512-vHp+HqzGxORPAN8gY03qnbTMnhqIwjeRJNOMOAzePRg4xVEEE2WvYsI9G2NMjOknA8hnuYbU3/hwLcKbjhc8+Q== @@ -6354,275 +8741,133 @@ dependencies: "@walletconnect/window-getters" "^1.0.0" -"@web3-storage/multipart-parser@^1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@web3-storage/multipart-parser/-/multipart-parser-1.0.0.tgz#6b69dc2a32a5b207ba43e556c25cc136a56659c4" - integrity sha512-BEO6al7BYqcnfX15W2cnGR+Q566ACXAT9UQykORCWW80lmkpWsnEob6zJS1ZVBKsSJC8+7vJkHwlp+lXG1UCdw== - -"@webassemblyjs/ast@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.1.tgz#2bfd767eae1a6996f432ff7e8d7fc75679c0b6a7" - integrity sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw== +"@walletconnect/window-metadata@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@walletconnect/window-metadata/-/window-metadata-1.0.1.tgz#2124f75447b7e989e4e4e1581d55d25bc75f7be5" + integrity sha512-9koTqyGrM2cqFRW517BPY/iEtUDx2r1+Pwwu5m7sJ7ka79wi3EyqhqcICk/yDmv6jAS1rjKgTKXlEhanYjijcA== dependencies: - "@webassemblyjs/helper-numbers" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + "@walletconnect/window-getters" "^1.0.1" + tslib "1.14.1" -"@webassemblyjs/ast@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.9.0.tgz#bd850604b4042459a5a41cd7d338cbed695ed964" - integrity sha512-C6wW5L+b7ogSDVqymbkkvuW9kruN//YisMED04xzeBBqjHa2FYnmvOlS6Xj68xWQRgWvI9cIglsjFowH/RJyEA== +"@webassemblyjs/ast@1.12.1", "@webassemblyjs/ast@^1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.12.1.tgz#bb16a0e8b1914f979f45864c23819cc3e3f0d4bb" + integrity sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg== dependencies: - "@webassemblyjs/helper-module-context" "1.9.0" - "@webassemblyjs/helper-wasm-bytecode" "1.9.0" - "@webassemblyjs/wast-parser" "1.9.0" - -"@webassemblyjs/floating-point-hex-parser@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz#f6c61a705f0fd7a6aecaa4e8198f23d9dc179e4f" - integrity sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ== - -"@webassemblyjs/floating-point-hex-parser@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.9.0.tgz#3c3d3b271bddfc84deb00f71344438311d52ffb4" - integrity sha512-TG5qcFsS8QB4g4MhrxK5TqfdNe7Ey/7YL/xN+36rRjl/BlGE/NcBvJcqsRgCP6Z92mRE+7N50pRIi8SmKUbcQA== - -"@webassemblyjs/helper-api-error@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz#1a63192d8788e5c012800ba6a7a46c705288fd16" - integrity sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg== - -"@webassemblyjs/helper-api-error@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.9.0.tgz#203f676e333b96c9da2eeab3ccef33c45928b6a2" - integrity sha512-NcMLjoFMXpsASZFxJ5h2HZRcEhDkvnNFOAKneP5RbKRzaWJN36NC4jqQHKwStIhGXu5mUWlUUk7ygdtrO8lbmw== - -"@webassemblyjs/helper-buffer@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz#832a900eb444884cde9a7cad467f81500f5e5ab5" - integrity sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA== - -"@webassemblyjs/helper-buffer@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.9.0.tgz#a1442d269c5feb23fcbc9ef759dac3547f29de00" - integrity sha512-qZol43oqhq6yBPx7YM3m9Bv7WMV9Eevj6kMi6InKOuZxhw+q9hOkvq5e/PpKSiLfyetpaBnogSbNCfBwyB00CA== + "@webassemblyjs/helper-numbers" "1.11.6" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" -"@webassemblyjs/helper-code-frame@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.9.0.tgz#647f8892cd2043a82ac0c8c5e75c36f1d9159f27" - integrity sha512-ERCYdJBkD9Vu4vtjUYe8LZruWuNIToYq/ME22igL+2vj2dQ2OOujIZr3MEFvfEaqKoVqpsFKAGsRdBSBjrIvZA== - dependencies: - "@webassemblyjs/wast-printer" "1.9.0" +"@webassemblyjs/floating-point-hex-parser@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz#dacbcb95aff135c8260f77fa3b4c5fea600a6431" + integrity sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw== -"@webassemblyjs/helper-fsm@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-fsm/-/helper-fsm-1.9.0.tgz#c05256b71244214671f4b08ec108ad63b70eddb8" - integrity sha512-OPRowhGbshCb5PxJ8LocpdX9Kl0uB4XsAjl6jH/dWKlk/mzsANvhwbiULsaiqT5GZGT9qinTICdj6PLuM5gslw== +"@webassemblyjs/helper-api-error@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz#6132f68c4acd59dcd141c44b18cbebbd9f2fa768" + integrity sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q== -"@webassemblyjs/helper-module-context@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-module-context/-/helper-module-context-1.9.0.tgz#25d8884b76839871a08a6c6f806c3979ef712f07" - integrity sha512-MJCW8iGC08tMk2enck1aPW+BE5Cw8/7ph/VGZxwyvGbJwjktKkDK7vy7gAmMDx88D7mhDTCNKAW5tED+gZ0W8g== - dependencies: - "@webassemblyjs/ast" "1.9.0" +"@webassemblyjs/helper-buffer@1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz#6df20d272ea5439bf20ab3492b7fb70e9bfcb3f6" + integrity sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw== -"@webassemblyjs/helper-numbers@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz#64d81da219fbbba1e3bd1bfc74f6e8c4e10a62ae" - integrity sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ== +"@webassemblyjs/helper-numbers@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz#cbce5e7e0c1bd32cf4905ae444ef64cea919f1b5" + integrity sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g== dependencies: - "@webassemblyjs/floating-point-hex-parser" "1.11.1" - "@webassemblyjs/helper-api-error" "1.11.1" + "@webassemblyjs/floating-point-hex-parser" "1.11.6" + "@webassemblyjs/helper-api-error" "1.11.6" "@xtuc/long" "4.2.2" -"@webassemblyjs/helper-wasm-bytecode@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz#f328241e41e7b199d0b20c18e88429c4433295e1" - integrity sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q== - -"@webassemblyjs/helper-wasm-bytecode@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.9.0.tgz#4fed8beac9b8c14f8c58b70d124d549dd1fe5790" - integrity sha512-R7FStIzyNcd7xKxCZH5lE0Bqy+hGTwS3LJjuv1ZVxd9O7eHCedSdrId/hMOd20I+v8wDXEn+bjfKDLzTepoaUw== - -"@webassemblyjs/helper-wasm-section@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz#21ee065a7b635f319e738f0dd73bfbda281c097a" - integrity sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg== - dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-buffer" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" - "@webassemblyjs/wasm-gen" "1.11.1" - -"@webassemblyjs/helper-wasm-section@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.9.0.tgz#5a4138d5a6292ba18b04c5ae49717e4167965346" - integrity sha512-XnMB8l3ek4tvrKUUku+IVaXNHz2YsJyOOmz+MMkZvh8h1uSJpSen6vYnw3IoQ7WwEuAhL8Efjms1ZWjqh2agvw== - dependencies: - "@webassemblyjs/ast" "1.9.0" - "@webassemblyjs/helper-buffer" "1.9.0" - "@webassemblyjs/helper-wasm-bytecode" "1.9.0" - "@webassemblyjs/wasm-gen" "1.9.0" +"@webassemblyjs/helper-wasm-bytecode@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz#bb2ebdb3b83aa26d9baad4c46d4315283acd51e9" + integrity sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA== -"@webassemblyjs/ieee754@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz#963929e9bbd05709e7e12243a099180812992614" - integrity sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ== +"@webassemblyjs/helper-wasm-section@1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz#3da623233ae1a60409b509a52ade9bc22a37f7bf" + integrity sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g== dependencies: - "@xtuc/ieee754" "^1.2.0" + "@webassemblyjs/ast" "1.12.1" + "@webassemblyjs/helper-buffer" "1.12.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + "@webassemblyjs/wasm-gen" "1.12.1" -"@webassemblyjs/ieee754@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.9.0.tgz#15c7a0fbaae83fb26143bbacf6d6df1702ad39e4" - integrity sha512-dcX8JuYU/gvymzIHc9DgxTzUUTLexWwt8uCTWP3otys596io0L5aW02Gb1RjYpx2+0Jus1h4ZFqjla7umFniTg== +"@webassemblyjs/ieee754@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz#bb665c91d0b14fffceb0e38298c329af043c6e3a" + integrity sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg== dependencies: "@xtuc/ieee754" "^1.2.0" -"@webassemblyjs/leb128@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.11.1.tgz#ce814b45574e93d76bae1fb2644ab9cdd9527aa5" - integrity sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw== - dependencies: - "@xtuc/long" "4.2.2" - -"@webassemblyjs/leb128@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.9.0.tgz#f19ca0b76a6dc55623a09cffa769e838fa1e1c95" - integrity sha512-ENVzM5VwV1ojs9jam6vPys97B/S65YQtv/aanqnU7D8aSoHFX8GyhGg0CMfyKNIHBuAVjy3tlzd5QMMINa7wpw== - dependencies: - "@xtuc/long" "4.2.2" - -"@webassemblyjs/utf8@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.11.1.tgz#d1f8b764369e7c6e6bae350e854dec9a59f0a3ff" - integrity sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ== - -"@webassemblyjs/utf8@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.9.0.tgz#04d33b636f78e6a6813227e82402f7637b6229ab" - integrity sha512-GZbQlWtopBTP0u7cHrEx+73yZKrQoBMpwkGEIqlacljhXCkVM1kMQge/Mf+csMJAjEdSwhOyLAS0AoR3AG5P8w== - -"@webassemblyjs/wasm-edit@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz#ad206ebf4bf95a058ce9880a8c092c5dec8193d6" - integrity sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA== - dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-buffer" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" - "@webassemblyjs/helper-wasm-section" "1.11.1" - "@webassemblyjs/wasm-gen" "1.11.1" - "@webassemblyjs/wasm-opt" "1.11.1" - "@webassemblyjs/wasm-parser" "1.11.1" - "@webassemblyjs/wast-printer" "1.11.1" - -"@webassemblyjs/wasm-edit@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.9.0.tgz#3fe6d79d3f0f922183aa86002c42dd256cfee9cf" - integrity sha512-FgHzBm80uwz5M8WKnMTn6j/sVbqilPdQXTWraSjBwFXSYGirpkSWE2R9Qvz9tNiTKQvoKILpCuTjBKzOIm0nxw== - dependencies: - "@webassemblyjs/ast" "1.9.0" - "@webassemblyjs/helper-buffer" "1.9.0" - "@webassemblyjs/helper-wasm-bytecode" "1.9.0" - "@webassemblyjs/helper-wasm-section" "1.9.0" - "@webassemblyjs/wasm-gen" "1.9.0" - "@webassemblyjs/wasm-opt" "1.9.0" - "@webassemblyjs/wasm-parser" "1.9.0" - "@webassemblyjs/wast-printer" "1.9.0" - -"@webassemblyjs/wasm-gen@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz#86c5ea304849759b7d88c47a32f4f039ae3c8f76" - integrity sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA== - dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" - "@webassemblyjs/ieee754" "1.11.1" - "@webassemblyjs/leb128" "1.11.1" - "@webassemblyjs/utf8" "1.11.1" - -"@webassemblyjs/wasm-gen@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.9.0.tgz#50bc70ec68ded8e2763b01a1418bf43491a7a49c" - integrity sha512-cPE3o44YzOOHvlsb4+E9qSqjc9Qf9Na1OO/BHFy4OI91XDE14MjFN4lTMezzaIWdPqHnsTodGGNP+iRSYfGkjA== - dependencies: - "@webassemblyjs/ast" "1.9.0" - "@webassemblyjs/helper-wasm-bytecode" "1.9.0" - "@webassemblyjs/ieee754" "1.9.0" - "@webassemblyjs/leb128" "1.9.0" - "@webassemblyjs/utf8" "1.9.0" - -"@webassemblyjs/wasm-opt@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz#657b4c2202f4cf3b345f8a4c6461c8c2418985f2" - integrity sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw== - dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-buffer" "1.11.1" - "@webassemblyjs/wasm-gen" "1.11.1" - "@webassemblyjs/wasm-parser" "1.11.1" - -"@webassemblyjs/wasm-opt@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.9.0.tgz#2211181e5b31326443cc8112eb9f0b9028721a61" - integrity sha512-Qkjgm6Anhm+OMbIL0iokO7meajkzQD71ioelnfPEj6r4eOFuqm4YC3VBPqXjFyyNwowzbMD+hizmprP/Fwkl2A== - dependencies: - "@webassemblyjs/ast" "1.9.0" - "@webassemblyjs/helper-buffer" "1.9.0" - "@webassemblyjs/wasm-gen" "1.9.0" - "@webassemblyjs/wasm-parser" "1.9.0" - -"@webassemblyjs/wasm-parser@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz#86ca734534f417e9bd3c67c7a1c75d8be41fb199" - integrity sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA== - dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-api-error" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" - "@webassemblyjs/ieee754" "1.11.1" - "@webassemblyjs/leb128" "1.11.1" - "@webassemblyjs/utf8" "1.11.1" - -"@webassemblyjs/wasm-parser@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.9.0.tgz#9d48e44826df4a6598294aa6c87469d642fff65e" - integrity sha512-9+wkMowR2AmdSWQzsPEjFU7njh8HTO5MqO8vjwEHuM+AMHioNqSBONRdr0NQQ3dVQrzp0s8lTcYqzUdb7YgELA== - dependencies: - "@webassemblyjs/ast" "1.9.0" - "@webassemblyjs/helper-api-error" "1.9.0" - "@webassemblyjs/helper-wasm-bytecode" "1.9.0" - "@webassemblyjs/ieee754" "1.9.0" - "@webassemblyjs/leb128" "1.9.0" - "@webassemblyjs/utf8" "1.9.0" - -"@webassemblyjs/wast-parser@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-parser/-/wast-parser-1.9.0.tgz#3031115d79ac5bd261556cecc3fa90a3ef451914" - integrity sha512-qsqSAP3QQ3LyZjNC/0jBJ/ToSxfYJ8kYyuiGvtn/8MK89VrNEfwj7BPQzJVHi0jGTRK2dGdJ5PRqhtjzoww+bw== - dependencies: - "@webassemblyjs/ast" "1.9.0" - "@webassemblyjs/floating-point-hex-parser" "1.9.0" - "@webassemblyjs/helper-api-error" "1.9.0" - "@webassemblyjs/helper-code-frame" "1.9.0" - "@webassemblyjs/helper-fsm" "1.9.0" - "@xtuc/long" "4.2.2" - -"@webassemblyjs/wast-printer@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz#d0c73beda8eec5426f10ae8ef55cee5e7084c2f0" - integrity sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg== +"@webassemblyjs/leb128@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.11.6.tgz#70e60e5e82f9ac81118bc25381a0b283893240d7" + integrity sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ== dependencies: - "@webassemblyjs/ast" "1.11.1" "@xtuc/long" "4.2.2" -"@webassemblyjs/wast-printer@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.9.0.tgz#4935d54c85fef637b00ce9f52377451d00d47899" - integrity sha512-2J0nE95rHXHyQ24cWjMKJ1tqB/ds8z/cyeOZxJhcb+rW+SQASVjuznUSmdz5GpVJTzU8JkhYut0D3siFDD6wsA== - dependencies: - "@webassemblyjs/ast" "1.9.0" - "@webassemblyjs/wast-parser" "1.9.0" +"@webassemblyjs/utf8@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.11.6.tgz#90f8bc34c561595fe156603be7253cdbcd0fab5a" + integrity sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA== + +"@webassemblyjs/wasm-edit@^1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz#9f9f3ff52a14c980939be0ef9d5df9ebc678ae3b" + integrity sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g== + dependencies: + "@webassemblyjs/ast" "1.12.1" + "@webassemblyjs/helper-buffer" "1.12.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + "@webassemblyjs/helper-wasm-section" "1.12.1" + "@webassemblyjs/wasm-gen" "1.12.1" + "@webassemblyjs/wasm-opt" "1.12.1" + "@webassemblyjs/wasm-parser" "1.12.1" + "@webassemblyjs/wast-printer" "1.12.1" + +"@webassemblyjs/wasm-gen@1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz#a6520601da1b5700448273666a71ad0a45d78547" + integrity sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w== + dependencies: + "@webassemblyjs/ast" "1.12.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + "@webassemblyjs/ieee754" "1.11.6" + "@webassemblyjs/leb128" "1.11.6" + "@webassemblyjs/utf8" "1.11.6" + +"@webassemblyjs/wasm-opt@1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz#9e6e81475dfcfb62dab574ac2dda38226c232bc5" + integrity sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg== + dependencies: + "@webassemblyjs/ast" "1.12.1" + "@webassemblyjs/helper-buffer" "1.12.1" + "@webassemblyjs/wasm-gen" "1.12.1" + "@webassemblyjs/wasm-parser" "1.12.1" + +"@webassemblyjs/wasm-parser@1.12.1", "@webassemblyjs/wasm-parser@^1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz#c47acb90e6f083391e3fa61d113650eea1e95937" + integrity sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ== + dependencies: + "@webassemblyjs/ast" "1.12.1" + "@webassemblyjs/helper-api-error" "1.11.6" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + "@webassemblyjs/ieee754" "1.11.6" + "@webassemblyjs/leb128" "1.11.6" + "@webassemblyjs/utf8" "1.11.6" + +"@webassemblyjs/wast-printer@1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz#bcecf661d7d1abdaf989d8341a4833e33e2b31ac" + integrity sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA== + dependencies: + "@webassemblyjs/ast" "1.12.1" "@xtuc/long" "4.2.2" "@xtuc/ieee754@^1.2.0": @@ -6635,15 +8880,46 @@ resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== +"@yarnpkg/esbuild-plugin-pnp@^3.0.0-rc.10": + version "3.0.0-rc.15" + resolved "https://registry.yarnpkg.com/@yarnpkg/esbuild-plugin-pnp/-/esbuild-plugin-pnp-3.0.0-rc.15.tgz#4e40e7d2eb28825c9a35ab9d04c363931d7c0e67" + integrity sha512-kYzDJO5CA9sy+on/s2aIW0411AklfCi8Ck/4QDivOqsMKpStZA2SsR+X27VTggGwpStWaLrjJcDcdDMowtG8MA== + dependencies: + tslib "^2.4.0" + +"@yarnpkg/fslib@2.10.3": + version "2.10.3" + resolved "https://registry.yarnpkg.com/@yarnpkg/fslib/-/fslib-2.10.3.tgz#a8c9893df5d183cf6362680b9f1c6d7504dd5717" + integrity sha512-41H+Ga78xT9sHvWLlFOZLIhtU6mTGZ20pZ29EiZa97vnxdohJD2AF42rCoAoWfqUz486xY6fhjMH+DYEM9r14A== + dependencies: + "@yarnpkg/libzip" "^2.3.0" + tslib "^1.13.0" + +"@yarnpkg/libzip@2.3.0", "@yarnpkg/libzip@^2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@yarnpkg/libzip/-/libzip-2.3.0.tgz#fe1e762e47669f6e2c960fc118436608d834e3be" + integrity sha512-6xm38yGVIa6mKm/DUCF2zFFJhERh/QWp1ufm4cNUvxsONBmfPg8uZ9pZBdOmF6qFGr/HlT6ABBkCSx/dlEtvWg== + dependencies: + "@types/emscripten" "^1.39.6" + tslib "^1.13.0" + "@yarnpkg/lockfile@^1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz#e77a97fbd345b76d83245edcd17d393b1b41fb31" integrity sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ== +"@yarnpkg/parsers@3.0.0-rc.46": + version "3.0.0-rc.46" + resolved "https://registry.yarnpkg.com/@yarnpkg/parsers/-/parsers-3.0.0-rc.46.tgz#03f8363111efc0ea670e53b0282cd3ef62de4e01" + integrity sha512-aiATs7pSutzda/rq8fnuPwTglyVwjM22bNnK2ZgjrpAjQHSSl3lztd2f9evst1W/qnC58DRz7T7QndUDumAR4Q== + dependencies: + js-yaml "^3.10.0" + tslib "^2.4.0" + "@yarnpkg/parsers@^3.0.0-rc.18": - version "3.0.0-rc.42" - resolved "https://registry.yarnpkg.com/@yarnpkg/parsers/-/parsers-3.0.0-rc.42.tgz#3814e90a81bb1f9c06cc83c6a009139c55efe94d" - integrity sha512-eW9Mbegmb5bJjwawJM9ghjUjUqciNMhC6L7XrQPF/clXS5bbP66MstsgCT5hy9VlfUh/CfBT+0Wucf531dMjHA== + version "3.0.0" + resolved "https://registry.yarnpkg.com/@yarnpkg/parsers/-/parsers-3.0.0.tgz#a43136f094bca5dcc1ae784c296446a85211cc62" + integrity sha512-jVZa3njBv6tcOUw34nlUdUM/40wwtm/gnVF8rtk0tA6vNcokqYI8CFU1BZjlpFwUSZaXxYkrtuPE/f2MMFlTxQ== dependencies: js-yaml "^3.10.0" tslib "^2.4.0" @@ -6663,15 +8939,15 @@ JSONStream@^1.0.4, JSONStream@^1.3.5: jsonparse "^1.2.0" through ">=2.2.7 <3" -abab@^2.0.0: - version "2.0.6" - resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.6.tgz#41b80f2c871d19686216b82309231cfd3cb3d291" - integrity sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA== +abitype@0.9.8: + version "0.9.8" + resolved "https://registry.yarnpkg.com/abitype/-/abitype-0.9.8.tgz#1f120b6b717459deafd213dfbf3a3dd1bf10ae8c" + integrity sha512-puLifILdm+8sjyss4S+fsUN09obiT1g2YW6CtcQF+QDzxR0euzgEB29MZujC6zMk2a6SVmtttq1fc6+YFA7WYQ== -abbrev@1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" - integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== +abitype@1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/abitype/-/abitype-1.0.5.tgz#29d0daa3eea867ca90f7e4123144c1d1270774b6" + integrity sha512-YzDhti7cjlfaBhHutMaboYB21Ha3rXR9QTkNJFzYC4kC8YclaiwPBBBJY8ejFdu2wnJeZCVZSMlQJ7fi8S6hsw== abortcontroller-polyfill@^1.1.9: version "1.7.5" @@ -6686,53 +8962,35 @@ accepts@~1.3.5, accepts@~1.3.8: mime-types "~2.1.34" negotiator "0.6.3" -acorn-globals@^4.3.2: - version "4.3.4" - resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-4.3.4.tgz#9fa1926addc11c97308c4e66d7add0d40c3272e7" - integrity sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A== - dependencies: - acorn "^6.0.1" - acorn-walk "^6.0.1" - -acorn-import-assertions@^1.7.6: - version "1.8.0" - resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz#ba2b5939ce62c238db6d93d81c9b111b29b855e9" - integrity sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw== +acorn-import-attributes@^1.9.5: + version "1.9.5" + resolved "https://registry.yarnpkg.com/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz#7eb1557b1ba05ef18b5ed0ec67591bfab04688ef" + integrity sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ== -acorn-jsx@^5.0.0, acorn-jsx@^5.2.0, acorn-jsx@^5.3.1: +acorn-jsx@^5.3.1, acorn-jsx@^5.3.2: version "5.3.2" resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== -acorn-walk@^6.0.1: - version "6.2.0" - resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-6.2.0.tgz#123cb8f3b84c2171f1f7fb252615b1c78a6b1a8c" - integrity sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA== - acorn-walk@^7.2.0: version "7.2.0" resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-7.2.0.tgz#0de889a601203909b0fbe07b8938dc21d2e967bc" integrity sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA== -acorn-walk@^8.1.1, acorn-walk@^8.2.0: - version "8.2.0" - resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1" - integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== - -acorn@^6.0.1, acorn@^6.4.1: - version "6.4.2" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.2.tgz#35866fd710528e92de10cf06016498e47e39e1e6" - integrity sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ== - -acorn@^7.1.0, acorn@^7.1.1, acorn@^7.4.1: +acorn@^7.4.1: version "7.4.1" resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== -acorn@^8.0.0, acorn@^8.4.1, acorn@^8.5.0, acorn@^8.6.0, acorn@^8.7.0, acorn@^8.7.1, acorn@^8.8.2: - version "8.8.2" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.2.tgz#1b2f25db02af965399b9776b0c2c391276d37c4a" - integrity sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw== +acorn@^8.10.0, acorn@^8.11.2, acorn@^8.7.1, acorn@^8.8.2, acorn@^8.9.0: + version "8.11.2" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.11.2.tgz#ca0d78b51895be5390a5903c5b3bdcdaf78ae40b" + integrity sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w== + +add-stream@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/add-stream/-/add-stream-1.0.0.tgz#6a7990437ca736d5e1288db92bd3266d5f5cb2aa" + integrity sha512-qQLMr+8o0WC4FZGQTcJiKBVC59JylcPSrTtk6usvmIDFUOCKegapy1VHQwRbFMOFyb/inzUVqHs+eMYKDM1YeQ== address@^1.0.1: version "1.2.2" @@ -6744,25 +9002,35 @@ aes-js@3.0.0: resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-3.0.0.tgz#e21df10ad6c2053295bcbb8dab40b09dbea87e4d" integrity sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw== +aes-js@4.0.0-beta.5: + version "4.0.0-beta.5" + resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-4.0.0-beta.5.tgz#8d2452c52adedebc3a3e28465d858c11ca315873" + integrity sha512-G965FqalsNyrPqgEGON7nIx1e/OVENSgiEIzyC63haUMuvNnwIgIjMs52hlTCKhkBny7A2ORNlfY9Zu+jmGk1Q== + aes-js@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-3.1.2.tgz#db9aabde85d5caabbfc0d4f2a4446960f627146a" integrity sha512-e5pEa2kBnBOgR4Y/p20pskXI74UEz7de8ZGVo58asOtvSVG5YAbJeELPZxOmt+Bnz3rX753YKhfIn4X4l1PPRQ== -agent-base@6, agent-base@^6.0.0, agent-base@^6.0.2: +agent-base@6, agent-base@^6.0.2: version "6.0.2" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== dependencies: debug "4" -agentkeepalive@^4.2.1: - version "4.3.0" - resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-4.3.0.tgz#bb999ff07412653c1803b3ced35e50729830a255" - integrity sha512-7Epl1Blf4Sy37j4v9f9FjICCh4+KAQOyXgHEwlyBiAQLbhKdq/i2QQU3amQalS/wPhdPzDXPL5DMR5bkn+YeWg== +agent-base@^7.0.2: + version "7.1.0" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-7.1.0.tgz#536802b76bc0b34aa50195eb2442276d613e3434" + integrity sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg== + dependencies: + debug "^4.3.4" + +agentkeepalive@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-4.5.0.tgz#2673ad1389b3c418c5a20c5d7364f93ca04be923" + integrity sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew== dependencies: - debug "^4.1.0" - depd "^2.0.0" humanize-ms "^1.2.1" aggregate-error@^3.0.0: @@ -6773,39 +9041,6 @@ aggregate-error@^3.0.0: clean-stack "^2.0.0" indent-string "^4.0.0" -ahocorasick@1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/ahocorasick/-/ahocorasick-1.0.2.tgz#9eee93aef9d02bfb476d9b648d9b7a40ef2fd500" - integrity sha512-hCOfMzbFx5IDutmWLAt6MZwOUjIfSM9G9FyVxytmE4Rs/5YDPWQrD/+IR1w+FweD9H2oOZEnv36TmkjhNURBVA== - -airbnb-js-shims@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/airbnb-js-shims/-/airbnb-js-shims-2.2.1.tgz#db481102d682b98ed1daa4c5baa697a05ce5c040" - integrity sha512-wJNXPH66U2xjgo1Zwyjf9EydvJ2Si94+vSdk6EERcBfB2VZkeltpqIats0cqIZMLCXP3zcyaUKGYQeIBT6XjsQ== - dependencies: - array-includes "^3.0.3" - array.prototype.flat "^1.2.1" - array.prototype.flatmap "^1.2.1" - es5-shim "^4.5.13" - es6-shim "^0.35.5" - function.prototype.name "^1.1.0" - globalthis "^1.0.0" - object.entries "^1.1.0" - object.fromentries "^2.0.0 || ^1.0.0" - object.getownpropertydescriptors "^2.0.3" - object.values "^1.1.0" - promise.allsettled "^1.0.0" - promise.prototype.finally "^3.1.0" - string.prototype.matchall "^4.0.0 || ^3.0.1" - string.prototype.padend "^3.0.0" - string.prototype.padstart "^3.0.0" - symbol.prototype.description "^1.0.0" - -ajv-errors@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/ajv-errors/-/ajv-errors-1.0.1.tgz#f35986aceb91afadec4102fbd85014950cefa64d" - integrity sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ== - ajv-formats@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/ajv-formats/-/ajv-formats-2.1.1.tgz#6e669400659eb74973bbf2e33327180a0996b520" @@ -6813,29 +9048,19 @@ ajv-formats@^2.1.1: dependencies: ajv "^8.0.0" -ajv-keywords@^3.1.0, ajv-keywords@^3.4.1, ajv-keywords@^3.5.2: +ajv-keywords@^3.5.2: version "3.5.2" resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== -ajv-keywords@^5.0.0: +ajv-keywords@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-5.1.0.tgz#69d4d385a4733cdbeab44964a1170a88f87f0e16" integrity sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw== dependencies: fast-deep-equal "^3.1.3" -ajv@8.6.3: - version "8.6.3" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.6.3.tgz#11a66527761dc3e9a3845ea775d2d3c0414e8764" - integrity sha512-SMJOdDP6LqTkD0Uq8qLi+gMwSt0imXLSV080qFVwJCpH9U6Mb+SUGHAXM0KNbcBPguytWyvFxcHgMLe2D2XSpw== - dependencies: - fast-deep-equal "^3.1.1" - json-schema-traverse "^1.0.0" - require-from-string "^2.0.2" - uri-js "^4.2.2" - -ajv@^6.0.0, ajv@^6.1.0, ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.2, ajv@^6.12.3, ajv@^6.12.4, ajv@^6.12.5: +ajv@^6.0.0, ajv@^6.12.4, ajv@^6.12.5: version "6.12.6" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== @@ -6845,7 +9070,7 @@ ajv@^6.0.0, ajv@^6.1.0, ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.2, ajv@^6.12.3, ajv@ json-schema-traverse "^0.4.1" uri-js "^4.2.2" -ajv@^8.0.0, ajv@^8.8.0: +ajv@^8.0.0, ajv@^8.11.0, ajv@^8.9.0: version "8.12.0" resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.12.0.tgz#d1a0527323e22f53562c567c00991577dfbe19d1" integrity sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA== @@ -6855,28 +9080,11 @@ ajv@^8.0.0, ajv@^8.8.0: require-from-string "^2.0.2" uri-js "^4.2.2" -ansi-align@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-3.0.1.tgz#0cdf12e111ace773a86e9a1fad1225c43cb19a59" - integrity sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w== - dependencies: - string-width "^4.1.0" - -ansi-colors@^3.0.0: - version "3.2.4" - resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-3.2.4.tgz#e3a3da4bfbae6c86a9c285625de124a234026fbf" - integrity sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA== - ansi-colors@^4.1.1: version "4.1.3" resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.3.tgz#37611340eb2243e70cc604cad35d63270d48781b" integrity sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw== -ansi-escapes@^3.0.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b" - integrity sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ== - ansi-escapes@^4.2.1: version "4.3.2" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" @@ -6884,32 +9092,29 @@ ansi-escapes@^4.2.1: dependencies: type-fest "^0.21.3" -ansi-html-community@0.0.8, ansi-html-community@^0.0.8: +ansi-escapes@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-5.0.0.tgz#b6a0caf0eef0c41af190e9a749e0c00ec04bb2a6" + integrity sha512-5GFMVX8HqE/TB+FuBJGuO5XG0WrsA6ptUqoODaT/n9mmUaZFkqnBueB4leqGBCmrUHnCnC4PCZTCd0E7QQ83bA== + dependencies: + type-fest "^1.0.2" + +ansi-html-community@0.0.8: version "0.0.8" resolved "https://registry.yarnpkg.com/ansi-html-community/-/ansi-html-community-0.0.8.tgz#69fbc4d6ccbe383f9736934ae34c3f8290f1bf41" integrity sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw== -ansi-regex@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" - integrity sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA== - -ansi-regex@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.1.tgz#123d6479e92ad45ad897d4054e3c7ca7db4944e1" - integrity sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw== - -ansi-regex@^4.1.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.1.tgz#164daac87ab2d6f6db3a29875e2d1766582dabed" - integrity sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g== - -ansi-regex@^5.0.0, ansi-regex@^5.0.1: +ansi-regex@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== -ansi-styles@^3.2.0, ansi-styles@^3.2.1: +ansi-regex@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.0.1.tgz#3183e38fae9a65d7cb5e53945cd5897d0260a06a" + integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== + +ansi-styles@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== @@ -6923,22 +9128,17 @@ ansi-styles@^4.0.0, ansi-styles@^4.1.0: dependencies: color-convert "^2.0.1" -ansi-to-html@^0.6.11: - version "0.6.15" - resolved "https://registry.yarnpkg.com/ansi-to-html/-/ansi-to-html-0.6.15.tgz#ac6ad4798a00f6aa045535d7f6a9cb9294eebea7" - integrity sha512-28ijx2aHJGdzbs+O5SNQF65r6rrKYnkuwTYm8lZlChuoJ9P1vVzIpWO20sQTqTPDXYp6NFwk326vApTtLVFXpQ== - dependencies: - entities "^2.0.0" +ansi-styles@^5.0.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b" + integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== -anymatch@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" - integrity sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw== - dependencies: - micromatch "^3.1.4" - normalize-path "^2.1.1" +ansi-styles@^6.0.0, ansi-styles@^6.1.0: + version "6.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5" + integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug== -anymatch@^3.0.0, anymatch@^3.0.3, anymatch@~3.1.2: +anymatch@^3.1.3, anymatch@~3.1.1, anymatch@~3.1.2: version "3.1.3" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== @@ -6951,41 +9151,10 @@ app-root-dir@^1.0.2: resolved "https://registry.yarnpkg.com/app-root-dir/-/app-root-dir-1.0.2.tgz#38187ec2dea7577fff033ffcb12172692ff6e118" integrity sha512-jlpIfsOoNoafl92Sz//64uQHGSyMrD2vYG5d8o2a4qGvyNCvXur7bzIsWtAC/6flI2RYAp3kv8rsfBtaLm7w0g== -aproba@^1.0.3, aproba@^1.1.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" - integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== - -"aproba@^1.0.3 || ^2.0.0": - version "2.0.0" - resolved "https://registry.yarnpkg.com/aproba/-/aproba-2.0.0.tgz#52520b8ae5b569215b354efc0caa3fe1e45a8adc" - integrity sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ== - -are-we-there-yet@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz#372e0e7bd279d8e94c653aaa1f67200884bf3e1c" - integrity sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw== - dependencies: - delegates "^1.0.0" - readable-stream "^3.6.0" - -are-we-there-yet@~1.1.2: - version "1.1.7" - resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz#b15474a932adab4ff8a50d9adfa7e4e926f21146" - integrity sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g== - dependencies: - delegates "^1.0.0" - readable-stream "^2.0.6" - -arg@^4.1.0: - version "4.1.3" - resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" - integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== - -arg@^5.0.1: - version "5.0.2" - resolved "https://registry.yarnpkg.com/arg/-/arg-5.0.2.tgz#c81433cc427c92c4dcf4865142dbca6f15acd59c" - integrity sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg== +arch@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/arch/-/arch-2.2.0.tgz#1bc47818f305764f23ab3306b0bfc086c5a29d11" + integrity sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ== argparse@^1.0.7: version "1.0.10" @@ -6999,27 +9168,19 @@ argparse@^2.0.1: resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== -aria-query@^5.1.3: - version "5.1.3" - resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-5.1.3.tgz#19db27cd101152773631396f7a95a3b58c22c35e" - integrity sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ== +aria-hidden@^1.1.1: + version "1.2.3" + resolved "https://registry.yarnpkg.com/aria-hidden/-/aria-hidden-1.2.3.tgz#14aeb7fb692bbb72d69bebfa47279c1fd725e954" + integrity sha512-xcLxITLe2HYa1cnYnwCjkOO1PqUHQpozB8x9AR0OgWN2woOBi5kSDVxKfd0b7sb1hw5qFeJhXm9H1nu3xSfLeQ== dependencies: - deep-equal "^2.0.5" - -arr-diff@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" - integrity sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA== - -arr-flatten@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" - integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== + tslib "^2.0.0" -arr-union@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" - integrity sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q== +aria-query@5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-5.3.0.tgz#650c569e41ad90b51b3d7df5e5eed1c7549c103e" + integrity sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A== + dependencies: + dequal "^2.0.3" array-back@^3.0.1, array-back@^3.1.0: version "3.1.0" @@ -7034,16 +9195,6 @@ array-buffer-byte-length@^1.0.0: call-bind "^1.0.2" is-array-buffer "^3.0.1" -array-equal@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/array-equal/-/array-equal-1.0.0.tgz#8c2a5ef2472fd9ea742b04c77a75093ba2757c93" - integrity sha512-H3LU5RLiSsGXPhN+Nipar0iR0IofH+8r89G2y1tBKxQ/agagKyAjhkAFDRBfodP2caPrNKHpAWNIM/c9yeL7uA== - -array-find-index@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1" - integrity sha512-M1HQyIXcBGtVywBt8WVdim+lrNaK7VHp99Qt5pSNziXznKHViIBbXWtfRTpEFpF/c4FdfxNAsCCwPp5phBYJtw== - array-flatten@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" @@ -7054,102 +9205,82 @@ array-ify@^1.0.0: resolved "https://registry.yarnpkg.com/array-ify/-/array-ify-1.0.0.tgz#9e528762b4a9066ad163a6962a364418e9626ece" integrity sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng== -array-includes@^3.0.3, array-includes@^3.1.5, array-includes@^3.1.6: - version "3.1.6" - resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.6.tgz#9e9e720e194f198266ba9e18c29e6a9b0e4b225f" - integrity sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw== +array-includes@^3.1.6, array-includes@^3.1.7: + version "3.1.7" + resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.7.tgz#8cd2e01b26f7a3086cbc87271593fe921c62abda" + integrity sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ== dependencies: call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.4" - get-intrinsic "^1.1.3" + define-properties "^1.2.0" + es-abstract "^1.22.1" + get-intrinsic "^1.2.1" is-string "^1.0.7" -array-union@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" - integrity sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng== - dependencies: - array-uniq "^1.0.1" - array-union@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== -array-uniq@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" - integrity sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q== - -array-unique@^0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" - integrity sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ== - -array.prototype.flat@^1.2.1, array.prototype.flat@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.3.1.tgz#ffc6576a7ca3efc2f46a143b9d1dda9b4b3cf5e2" - integrity sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA== +array.prototype.findlastindex@^1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.3.tgz#b37598438f97b579166940814e2c0493a4f50207" + integrity sha512-LzLoiOMAxvy+Gd3BAq3B7VeIgPdo+Q8hthvKtXybMvRV0jrXfJM/t8mw7nNlpEcVlVUnCnM2KSX4XU5HmpodOA== dependencies: call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.4" + define-properties "^1.2.0" + es-abstract "^1.22.1" es-shim-unscopables "^1.0.0" + get-intrinsic "^1.2.1" -array.prototype.flatmap@^1.2.1, array.prototype.flatmap@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.3.1.tgz#1aae7903c2100433cb8261cd4ed310aab5c4a183" - integrity sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ== +array.prototype.flat@^1.3.1, array.prototype.flat@^1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz#1476217df8cff17d72ee8f3ba06738db5b387d18" + integrity sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA== dependencies: call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.4" + define-properties "^1.2.0" + es-abstract "^1.22.1" es-shim-unscopables "^1.0.0" -array.prototype.map@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/array.prototype.map/-/array.prototype.map-1.0.5.tgz#6e43c2fee6c0fb5e4806da2dc92eb00970809e55" - integrity sha512-gfaKntvwqYIuC7mLLyv2wzZIJqrRhn5PZ9EfFejSx6a78sV7iDsGpG9P+3oUPtm1Rerqm6nrKS4FYuTIvWfo3g== +array.prototype.flatmap@^1.3.1, array.prototype.flatmap@^1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz#c9a7c6831db8e719d6ce639190146c24bbd3e527" + integrity sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ== dependencies: call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.4" - es-array-method-boxes-properly "^1.0.0" - is-string "^1.0.7" + define-properties "^1.2.0" + es-abstract "^1.22.1" + es-shim-unscopables "^1.0.0" -array.prototype.reduce@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/array.prototype.reduce/-/array.prototype.reduce-1.0.5.tgz#6b20b0daa9d9734dd6bc7ea66b5bbce395471eac" - integrity sha512-kDdugMl7id9COE8R7MHF5jWk7Dqt/fs4Pv+JXoICnYwqpjjjbUurz6w5fT5IG6brLdJhv6/VoHB0H7oyIBXd+Q== +array.prototype.tosorted@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/array.prototype.tosorted/-/array.prototype.tosorted-1.1.2.tgz#620eff7442503d66c799d95503f82b475745cefd" + integrity sha512-HuQCHOlk1Weat5jzStICBCd83NxiIMwqDg/dHEsoefabn/hJRj5pVdWcPUSpRrwhwxZOsQassMpgN/xRYFBMIg== dependencies: call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.4" - es-array-method-boxes-properly "^1.0.0" - is-string "^1.0.7" + define-properties "^1.2.0" + es-abstract "^1.22.1" + es-shim-unscopables "^1.0.0" + get-intrinsic "^1.2.1" -array.prototype.tosorted@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/array.prototype.tosorted/-/array.prototype.tosorted-1.1.1.tgz#ccf44738aa2b5ac56578ffda97c03fd3e23dd532" - integrity sha512-pZYPXPRl2PqWcsUs6LOMn+1f1532nEoPTYowBtqLwAW+W8vSVhkIGnmOX1t/UQjD6YGI0vcD2B1U7ZFGQH9jnQ== +arraybuffer.prototype.slice@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.2.tgz#98bd561953e3e74bb34938e77647179dfe6e9f12" + integrity sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw== dependencies: + array-buffer-byte-length "^1.0.0" call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.4" - es-shim-unscopables "^1.0.0" - get-intrinsic "^1.1.3" + define-properties "^1.2.0" + es-abstract "^1.22.1" + get-intrinsic "^1.2.1" + is-array-buffer "^3.0.2" + is-shared-array-buffer "^1.0.2" arrify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" integrity sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA== -arrify@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/arrify/-/arrify-2.0.1.tgz#c9655e9331e0abcd588d2a7cad7e9956f66701fa" - integrity sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug== - asap@~2.0.3: version "2.0.6" resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" @@ -7165,140 +9296,61 @@ asn1.js@^5.2.0: minimalistic-assert "^1.0.0" safer-buffer "^2.1.0" -asn1@~0.2.3: - version "0.2.6" - resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.6.tgz#0d3a7bb6e64e02a90c0303b31f292868ea09a08d" - integrity sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ== - dependencies: - safer-buffer "~2.1.0" - -assert-plus@1.0.0, assert-plus@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" - integrity sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw== - -assert@^1.1.1: - version "1.5.0" - resolved "https://registry.yarnpkg.com/assert/-/assert-1.5.0.tgz#55c109aaf6e0aefdb3dc4b71240c70bf574b18eb" - integrity sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA== +assert@^2.0.0, assert@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/assert/-/assert-2.1.0.tgz#6d92a238d05dc02e7427c881fb8be81c8448b2dd" + integrity sha512-eLHpSK/Y4nhMJ07gDaAzoX/XAKS8PSaojml3M0DM4JpV1LAi5JOJ/p6H/XWrl8L+DzVEvVCW1z3vWAaB9oTsQw== dependencies: - object-assign "^4.1.1" - util "0.10.3" - -assign-symbols@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" - integrity sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw== - -ast-types-flow@^0.0.7: - version "0.0.7" - resolved "https://registry.yarnpkg.com/ast-types-flow/-/ast-types-flow-0.0.7.tgz#f70b735c6bca1a5c9c22d982c3e39e7feba3bdad" - integrity sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag== + call-bind "^1.0.2" + is-nan "^1.3.2" + object-is "^1.1.5" + object.assign "^4.1.4" + util "^0.12.5" -ast-types@0.15.2: - version "0.15.2" - resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.15.2.tgz#39ae4809393c4b16df751ee563411423e85fb49d" - integrity sha512-c27loCv9QkZinsa5ProX751khO9DJl/AcB5c2KNtA6NRvHKS0PgLfcftz72KVq504vB0Gku5s2kUZzDBvQWvHg== - dependencies: - tslib "^2.0.1" +assertion-error@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-2.0.1.tgz#f641a196b335690b1070bf00b6e7593fec190bf7" + integrity sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA== -ast-types@^0.13.2: - version "0.13.4" - resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.13.4.tgz#ee0d77b343263965ecc3fb62da16e7222b2b6782" - integrity sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w== +ast-types@^0.16.1: + version "0.16.1" + resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.16.1.tgz#7a9da1617c9081bc121faafe91711b4c8bb81da2" + integrity sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg== dependencies: tslib "^2.0.1" -ast-types@^0.14.2: - version "0.14.2" - resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.14.2.tgz#600b882df8583e3cd4f2df5fa20fa83759d4bdfd" - integrity sha512-O0yuUDnZeQDL+ncNGlJ78BiO4jnYI3bvMsD5prT0/nsgijG/LpNBIr63gTjVTNsiGkgQhiyCShTgxt8oXOrklA== - dependencies: - tslib "^2.0.1" +async@^3.2.3: + version "3.2.5" + resolved "https://registry.yarnpkg.com/async/-/async-3.2.5.tgz#ebd52a8fdaf7a2289a24df399f8d8485c8a46b66" + integrity sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg== -astral-regex@^1.0.0: +asynciterator.prototype@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" - integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg== - -astring@^1.6.0: - version "1.8.4" - resolved "https://registry.yarnpkg.com/astring/-/astring-1.8.4.tgz#6d4c5d8de7be2ead9e4a3cc0e2efb8d759378904" - integrity sha512-97a+l2LBU3Op3bBQEff79i/E4jMD2ZLFD8rHx9B6mXyB2uQwhJQYfiDqUwtfjF4QA1F2qs//N6Cw8LetMbQjcw== - -async-each@^1.0.1: - version "1.0.6" - resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.6.tgz#52f1d9403818c179b7561e11a5d1b77eb2160e77" - integrity sha512-c646jH1avxr+aVpndVMeAfYw7wAa6idufrlN3LPA4PmKS0QEGp6PIC9nwz0WQkkvBGAMEki3pFdtxaF39J9vvg== - -async-limiter@~1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" - integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ== - -async-sema@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/async-sema/-/async-sema-3.1.1.tgz#e527c08758a0f8f6f9f15f799a173ff3c40ea808" - integrity sha512-tLRNUXati5MFePdAk8dw7Qt7DpxPB60ofAgn8WRhW6a2rcimZnYBP9oxHiv0OHy+Wz7kPMG+t4LGdt31+4EmGg== - -async@^3.2.3: - version "3.2.4" - resolved "https://registry.yarnpkg.com/async/-/async-3.2.4.tgz#2d22e00f8cddeb5fde5dd33522b56d1cf569a81c" - integrity sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ== + resolved "https://registry.yarnpkg.com/asynciterator.prototype/-/asynciterator.prototype-1.0.0.tgz#8c5df0514936cdd133604dfcc9d3fb93f09b2b62" + integrity sha512-wwHYEIS0Q80f5mosx3L/dfG5t5rjEa9Ft51GTaNt862EnpyGHpgz2RkZvLPp1oF5TnAiTohkEKVEu8pQPJI7Vg== + dependencies: + has-symbols "^1.0.3" asynckit@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== -asyncro@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/asyncro/-/asyncro-3.0.0.tgz#3c7a732e263bc4a42499042f48d7d858e9c0134e" - integrity sha512-nEnWYfrBmA3taTiuiOoZYmgJ/CNrSoQLeLs29SeLcPu60yaw/mHDBHV0iOZ051fTvsTHxpCY+gXibqT9wbQYfg== - at-least-node@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2" integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg== -atob@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" - integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== - -autoprefixer@^9.8.6: - version "9.8.8" - resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.8.8.tgz#fd4bd4595385fa6f06599de749a4d5f7a474957a" - integrity sha512-eM9d/swFopRt5gdJ7jrpCwgvEMIayITpojhkkSMRsFHYuH5bkSQ4p/9qTEHtmNudUZh22Tehu7I6CxAW0IXTKA== - dependencies: - browserslist "^4.12.0" - caniuse-lite "^1.0.30001109" - normalize-range "^0.1.2" - num2fraction "^1.2.2" - picocolors "^0.2.1" - postcss "^7.0.32" - postcss-value-parser "^4.1.0" +atomic-sleep@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/atomic-sleep/-/atomic-sleep-1.0.0.tgz#eb85b77a601fc932cfe432c5acd364a9e2c9075b" + integrity sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ== available-typed-arrays@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7" integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== -aws-sign2@~0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" - integrity sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA== - -aws4@^1.8.0: - version "1.12.0" - resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.12.0.tgz#ce1c9d143389679e253b314241ea9aa5cec980d3" - integrity sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg== - -axe-core@^4.6.2: - version "4.6.3" - resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.6.3.tgz#fc0db6fdb65cc7a80ccf85286d91d64ababa3ece" - integrity sha512-/BQzOX780JhsxDnPpH4ZiyrJAzcd8AfzFPkv+89veFSr1rcMjuq2JDCwypKaPeB6ljHp9KjXhPpjgCvQlWYuqg== - axios@0.21.1: version "0.21.1" resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.1.tgz#22563481962f4d6bde9a76d516ef0e5d3c09b2b8" @@ -7306,27 +9358,13 @@ axios@0.21.1: dependencies: follow-redirects "^1.10.0" -axios@^0.19.0: - version "0.19.2" - resolved "https://registry.yarnpkg.com/axios/-/axios-0.19.2.tgz#3ea36c5d8818d0d5f8a8a97a6d36b86cdc00cb27" - integrity sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA== - dependencies: - follow-redirects "1.5.10" - -axios@^0.21.0, axios@^0.21.1, axios@^0.21.2, axios@^0.21.4: +axios@^0.21.1, axios@^0.21.2, axios@^0.21.4: version "0.21.4" resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.4.tgz#c67b90dc0568e5c1cf2b0b858c43ba28e2eda575" integrity sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg== dependencies: follow-redirects "^1.14.0" -axios@^0.24.0: - version "0.24.0" - resolved "https://registry.yarnpkg.com/axios/-/axios-0.24.0.tgz#804e6fa1e4b9c5288501dd9dff56a7a0940d20d6" - integrity sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA== - dependencies: - follow-redirects "^1.14.4" - axios@^0.27.2: version "0.27.2" resolved "https://registry.yarnpkg.com/axios/-/axios-0.27.2.tgz#207658cc8621606e586c85db4b41a750e756d972" @@ -7335,94 +9373,46 @@ axios@^0.27.2: follow-redirects "^1.14.9" form-data "^4.0.0" -axios@^1.0.0, axios@^1.2.6: - version "1.3.4" - resolved "https://registry.yarnpkg.com/axios/-/axios-1.3.4.tgz#f5760cefd9cfb51fd2481acf88c05f67c4523024" - integrity sha512-toYm+Bsyl6VC5wSkfkbbNB6ROv7KY93PEBBL6xyDczaIHasAiv4wPqQ/c4RjoQzipxRD2W5g21cOqQulZ7rHwQ== +axios@^1.0.0: + version "1.6.2" + resolved "https://registry.yarnpkg.com/axios/-/axios-1.6.2.tgz#de67d42c755b571d3e698df1b6504cde9b0ee9f2" + integrity sha512-7i24Ri4pmDRfJTR7LDBhsOTtcm+9kjX5WiY1X3wIisx6G9So3pfMkEiU7emUBe46oceVImccTEM3k6C5dbVW8A== dependencies: follow-redirects "^1.15.0" form-data "^4.0.0" proxy-from-env "^1.1.0" -axobject-query@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-3.1.1.tgz#3b6e5c6d4e43ca7ba51c5babf99d22a9c68485e1" - integrity sha512-goKlv8DZrK9hUh975fnHzhNIO4jUnFCfv/dszV5VwUGDFjI6vQ2VwoyjYjYNEbBE8AH87TduWP5uyDR1D+Iteg== +axios@^1.3.4, axios@^1.6.0, axios@^1.6.5: + version "1.6.8" + resolved "https://registry.yarnpkg.com/axios/-/axios-1.6.8.tgz#66d294951f5d988a00e87a0ffb955316a619ea66" + integrity sha512-v/ZHtJDU39mDpyBoFVkETcd/uNdxrWRrg3bKpOKzXFA6Bvqopts6ALSMU3y6ijYxbw2B+wPrIv46egTzJXCLGQ== dependencies: - deep-equal "^2.0.5" - -b4a@^1.6.0: - version "1.6.3" - resolved "https://registry.yarnpkg.com/b4a/-/b4a-1.6.3.tgz#cce6e8a2f0d0774e5fe8062086827e979970266d" - integrity sha512-aX6/FqpWQve8VN9kyTExy7GlmwNShvxcCWWD5QVR3ZbRlyBGtCrG5Autu95xxSPH4CRs+5PSV4d7PRnWpmqFlA== + follow-redirects "^1.15.6" + form-data "^4.0.0" + proxy-from-env "^1.1.0" -babel-eslint@^10.0.3: - version "10.1.0" - resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-10.1.0.tgz#6968e568a910b78fb3779cdd8b6ac2f479943232" - integrity sha512-ifWaTHQ0ce+448CYop8AdrQiBsGrnC+bMgfyKFdi6EsPLTAWG+QfyDeM6OH+FmWnKvEq5NnBMLvlBUPKQZoDSg== +axios@^1.7.4: + version "1.7.7" + resolved "https://registry.yarnpkg.com/axios/-/axios-1.7.7.tgz#2f554296f9892a72ac8d8e4c5b79c14a91d0a47f" + integrity sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q== dependencies: - "@babel/code-frame" "^7.0.0" - "@babel/parser" "^7.7.0" - "@babel/traverse" "^7.7.0" - "@babel/types" "^7.7.0" - eslint-visitor-keys "^1.0.0" - resolve "^1.12.0" - -babel-jest@^25.5.1: - version "25.5.1" - resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-25.5.1.tgz#bc2e6101f849d6f6aec09720ffc7bc5332e62853" - integrity sha512-9dA9+GmMjIzgPnYtkhBg73gOo/RHqPmLruP3BaGL4KEX3Dwz6pI8auSN8G8+iuEG90+GSswyKvslN+JYSaacaQ== - dependencies: - "@jest/transform" "^25.5.1" - "@jest/types" "^25.5.0" - "@types/babel__core" "^7.1.7" - babel-plugin-istanbul "^6.0.0" - babel-preset-jest "^25.5.0" - chalk "^3.0.0" - graceful-fs "^4.2.4" - slash "^3.0.0" + follow-redirects "^1.15.6" + form-data "^4.0.0" + proxy-from-env "^1.1.0" -babel-loader@^8.0.0: - version "8.3.0" - resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.3.0.tgz#124936e841ba4fe8176786d6ff28add1f134d6a8" - integrity sha512-H8SvsMF+m9t15HNLMipppzkC+Y2Yq+v3SonZyU70RBL/h1gxPkH08Ot8pEE9Z4Kd+czyWJClmFS8qzIP9OZ04Q== - dependencies: - find-cache-dir "^3.3.1" - loader-utils "^2.0.0" - make-dir "^3.1.0" - schema-utils "^2.6.5" +babel-core@^7.0.0-bridge.0: + version "7.0.0-bridge.0" + resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-7.0.0-bridge.0.tgz#95a492ddd90f9b4e9a4a1da14eb335b87b634ece" + integrity sha512-poPX9mZH/5CSanm50Q+1toVci6pv5KSRv/5TWCwtzQS5XEwn40BcCrgIeMFWP9CKKIniKXNxoIOnOq4VVlGXhg== babel-loader@^9.1.0: - version "9.1.2" - resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-9.1.2.tgz#a16a080de52d08854ee14570469905a5fc00d39c" - integrity sha512-mN14niXW43tddohGl8HPu5yfQq70iUThvFL/4QzESA7GcZoC0eVOhvWdQ8+3UlSjaDE9MVtsW9mxDY07W7VpVA== + version "9.1.3" + resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-9.1.3.tgz#3d0e01b4e69760cc694ee306fe16d358aa1c6f9a" + integrity sha512-xG3ST4DglodGf8qSwv0MdeWLhrDsw/32QMdTO5T1ZIp9gQur0HkCyFs7Awskr10JKXFXwpAhiCuYX5oGXnRGbw== dependencies: - find-cache-dir "^3.3.2" + find-cache-dir "^4.0.0" schema-utils "^4.0.0" -babel-plugin-add-react-displayname@^0.0.5: - version "0.0.5" - resolved "https://registry.yarnpkg.com/babel-plugin-add-react-displayname/-/babel-plugin-add-react-displayname-0.0.5.tgz#339d4cddb7b65fd62d1df9db9fe04de134122bd5" - integrity sha512-LY3+Y0XVDYcShHHorshrDbt4KFWL4bSeniCtl4SYZbask+Syngk1uMPCeN9+nSiZo6zX5s0RTq/J9Pnaaf/KHw== - -babel-plugin-annotate-pure-calls@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/babel-plugin-annotate-pure-calls/-/babel-plugin-annotate-pure-calls-0.4.0.tgz#78aa00fd878c4fcde4d49f3da397fcf5defbcce8" - integrity sha512-oi4M/PWUJOU9ZyRGoPTfPMqdyMp06jbJAomd3RcyYuzUtBOddv98BqLm96Lucpi2QFoQHkdGQt0ACvw7VzVEQA== - -babel-plugin-apply-mdx-type-prop@1.6.22: - version "1.6.22" - resolved "https://registry.yarnpkg.com/babel-plugin-apply-mdx-type-prop/-/babel-plugin-apply-mdx-type-prop-1.6.22.tgz#d216e8fd0de91de3f1478ef3231e05446bc8705b" - integrity sha512-VefL+8o+F/DfK24lPZMtJctrCVOfgbqLAGZSkxwhazQv4VxPg3Za/i40fu22KR2m8eEda+IfSOlPLUSIiLcnCQ== - dependencies: - "@babel/helper-plugin-utils" "7.10.4" - "@mdx-js/util" "1.6.22" - -babel-plugin-dev-expression@^0.2.1: - version "0.2.3" - resolved "https://registry.yarnpkg.com/babel-plugin-dev-expression/-/babel-plugin-dev-expression-0.2.3.tgz#8aaf52155dfb063ed4ddec6280456fbc256fead4" - integrity sha512-rP5LK9QQTzCW61nVVzw88En1oK8t8gTsIeC6E61oelxNsU842yMjF0G1MxhvUpCkxCEIj7sE8/e5ieTheT//uw== - babel-plugin-emotion@^10.0.27: version "10.2.2" resolved "https://registry.yarnpkg.com/babel-plugin-emotion/-/babel-plugin-emotion-10.2.2.tgz#a1fe3503cff80abfd0bdda14abd2e8e57a79d17d" @@ -7439,34 +9429,7 @@ babel-plugin-emotion@^10.0.27: find-root "^1.1.0" source-map "^0.5.7" -babel-plugin-extract-import-names@1.6.22: - version "1.6.22" - resolved "https://registry.yarnpkg.com/babel-plugin-extract-import-names/-/babel-plugin-extract-import-names-1.6.22.tgz#de5f9a28eb12f3eb2578bf74472204e66d1a13dc" - integrity sha512-yJ9BsJaISua7d8zNT7oRG1ZLBJCIdZ4PZqmH8qa9N5AK01ifk3fnkc98AXhtzE7UkfCsEumvoQWgoYLhOnJ7jQ== - dependencies: - "@babel/helper-plugin-utils" "7.10.4" - -babel-plugin-istanbul@^6.0.0: - version "6.1.1" - resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz#fa88ec59232fd9b4e36dbbc540a8ec9a9b47da73" - integrity sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@istanbuljs/load-nyc-config" "^1.0.0" - "@istanbuljs/schema" "^0.1.2" - istanbul-lib-instrument "^5.0.4" - test-exclude "^6.0.0" - -babel-plugin-jest-hoist@^25.5.0: - version "25.5.0" - resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-25.5.0.tgz#129c80ba5c7fc75baf3a45b93e2e372d57ca2677" - integrity sha512-u+/W+WAjMlvoocYGTwthAiQSxDcJAyHpQ6oWlHdFZaaN+Rlk8Q7iiwDPg2lN/FyJtAYnKjFxbn7xus4HCFkg5g== - dependencies: - "@babel/template" "^7.3.3" - "@babel/types" "^7.3.3" - "@types/babel__traverse" "^7.0.6" - -babel-plugin-macros@^2.0.0, babel-plugin-macros@^2.6.1: +babel-plugin-macros@^2.0.0: version "2.8.0" resolved "https://registry.yarnpkg.com/babel-plugin-macros/-/babel-plugin-macros-2.8.0.tgz#0f958a7cc6556b1e65344465d99111a1e5e10138" integrity sha512-SEP5kJpfGYqYKpBrj5XU3ahw5p5GOHJ0U5ssOSQ/WBVdwkD2Dzlce95exQTs3jOVWPPKLBN2rlEWkCK7dSmLvg== @@ -7484,105 +9447,70 @@ babel-plugin-macros@^3.0.1: cosmiconfig "^7.0.0" resolve "^1.19.0" -babel-plugin-polyfill-corejs2@^0.3.3: - version "0.3.3" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.3.tgz#5d1bd3836d0a19e1b84bbf2d9640ccb6f951c122" - integrity sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q== +babel-plugin-polyfill-corejs2@^0.4.10: + version "0.4.10" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.10.tgz#276f41710b03a64f6467433cab72cbc2653c38b1" + integrity sha512-rpIuu//y5OX6jVU+a5BCn1R5RSZYWAl2Nar76iwaOdycqb6JPxediskWFMMl7stfwNJR4b7eiQvh5fB5TEQJTQ== dependencies: - "@babel/compat-data" "^7.17.7" - "@babel/helper-define-polyfill-provider" "^0.3.3" - semver "^6.1.1" + "@babel/compat-data" "^7.22.6" + "@babel/helper-define-polyfill-provider" "^0.6.1" + semver "^6.3.1" -babel-plugin-polyfill-corejs3@^0.1.0: - version "0.1.7" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.1.7.tgz#80449d9d6f2274912e05d9e182b54816904befd0" - integrity sha512-u+gbS9bbPhZWEeyy1oR/YaaSpod/KDT07arZHb80aTpl8H5ZBq+uN1nN9/xtX7jQyfLdPfoqI4Rue/MQSWJquw== +babel-plugin-polyfill-corejs2@^0.4.6: + version "0.4.6" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.6.tgz#b2df0251d8e99f229a8e60fc4efa9a68b41c8313" + integrity sha512-jhHiWVZIlnPbEUKSSNb9YoWcQGdlTLq7z1GHL4AjFxaoOUMuuEVJ+Y4pAaQUGOGk93YsVCKPbqbfw3m0SM6H8Q== dependencies: - "@babel/helper-define-polyfill-provider" "^0.1.5" - core-js-compat "^3.8.1" + "@babel/compat-data" "^7.22.6" + "@babel/helper-define-polyfill-provider" "^0.4.3" + semver "^6.3.1" -babel-plugin-polyfill-corejs3@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.6.0.tgz#56ad88237137eade485a71b52f72dbed57c6230a" - integrity sha512-+eHqR6OPcBhJOGgsIar7xoAB1GcSwVUA3XjAd7HJNzOXT4wv6/H7KIdA/Nc60cvUlDbKApmqNvD1B1bzOt4nyA== +babel-plugin-polyfill-corejs3@^0.10.4: + version "0.10.4" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.4.tgz#789ac82405ad664c20476d0233b485281deb9c77" + integrity sha512-25J6I8NGfa5YkCDogHRID3fVCadIR8/pGl1/spvCkzb6lVn6SR3ojpx9nOn9iEBcUsjY24AmdKm5khcfKdylcg== dependencies: - "@babel/helper-define-polyfill-provider" "^0.3.3" - core-js-compat "^3.25.1" + "@babel/helper-define-polyfill-provider" "^0.6.1" + core-js-compat "^3.36.1" -babel-plugin-polyfill-regenerator@^0.0.4: - version "0.0.4" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.0.4.tgz#588641af9a2cb4e299b1400c47672a4a104d2459" - integrity sha512-+/uCzO9JTYVZVGCpZpVAQkgPGt2zkR0VYiZvJ4aVoCe4ccgpKvNQqcjzAgQzSsjK64Jhc5hvrCR3l0087BevkA== +babel-plugin-polyfill-corejs3@^0.8.5: + version "0.8.6" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.8.6.tgz#25c2d20002da91fe328ff89095c85a391d6856cf" + integrity sha512-leDIc4l4tUgU7str5BWLS2h8q2N4Nf6lGZP6UrNDxdtfF2g69eJ5L0H7S8A5Ln/arfFAfHor5InAdZuIOwZdgQ== dependencies: - "@babel/helper-define-polyfill-provider" "^0.0.3" + "@babel/helper-define-polyfill-provider" "^0.4.3" + core-js-compat "^3.33.1" -babel-plugin-polyfill-regenerator@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.4.1.tgz#390f91c38d90473592ed43351e801a9d3e0fd747" - integrity sha512-NtQGmyQDXjQqQ+IzRkBVwEOz9lQ4zxAQZgoAYEtU9dJjnl1Oc98qnN7jcp+bE7O7aYzVpavXE3/VKXNzUbh7aw== +babel-plugin-polyfill-regenerator@^0.5.3: + version "0.5.3" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.3.tgz#d4c49e4b44614607c13fb769bcd85c72bb26a4a5" + integrity sha512-8sHeDOmXC8csczMrYEOf0UTNa4yE2SxV5JGeT/LP1n0OYVDUUFPxG9vdk2AlDlIit4t+Kf0xCtpgXPBwnn/9pw== dependencies: - "@babel/helper-define-polyfill-provider" "^0.3.3" + "@babel/helper-define-polyfill-provider" "^0.4.3" -babel-plugin-react-docgen@^4.2.1: - version "4.2.1" - resolved "https://registry.yarnpkg.com/babel-plugin-react-docgen/-/babel-plugin-react-docgen-4.2.1.tgz#7cc8e2f94e8dc057a06e953162f0810e4e72257b" - integrity sha512-UQ0NmGHj/HAqi5Bew8WvNfCk8wSsmdgNd8ZdMjBCICtyCJCq9LiqgqvjCYe570/Wg7AQArSq1VQ60Dd/CHN7mQ== +babel-plugin-polyfill-regenerator@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.1.tgz#4f08ef4c62c7a7f66a35ed4c0d75e30506acc6be" + integrity sha512-JfTApdE++cgcTWjsiCQlLyFBMbTUft9ja17saCc93lgV33h4tuCVj7tlvu//qpLwaG+3yEz7/KhahGrUMkVq9g== dependencies: - ast-types "^0.14.2" - lodash "^4.17.15" - react-docgen "^5.0.0" + "@babel/helper-define-polyfill-provider" "^0.6.1" babel-plugin-syntax-jsx@^6.18.0: version "6.18.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz#0af32a9a6e13ca7a3fd5069e62d7b0f58d0d8946" integrity sha512-qrPaCSo9c8RHNRHIotaufGbuOBN8rtdC4QrrFFc43vyWCCz7Kl7GL1PGaXtMGQZUXrkCjNEgxDfmAuAabr/rlw== -babel-plugin-transform-rename-import@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-rename-import/-/babel-plugin-transform-rename-import-2.3.0.tgz#5d9d645f937b0ca5c26a24b2510a06277b6ffd9b" - integrity sha512-dPgJoT57XC0PqSnLgl2FwNvxFrWlspatX2dkk7yjKQj5HHGw071vAcOf+hqW8ClqcBDMvEbm6mevn5yHAD8mlQ== - -babel-preset-current-node-syntax@^0.1.2: - version "0.1.4" - resolved "https://registry.yarnpkg.com/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-0.1.4.tgz#826f1f8e7245ad534714ba001f84f7e906c3b615" - integrity sha512-5/INNCYhUGqw7VbVjT/hb3ucjgkVHKXY7lX3ZjlN4gm565VyFmJUrJ/h+h16ECVB38R/9SF6aACydpKMLZ/c9w== - dependencies: - "@babel/plugin-syntax-async-generators" "^7.8.4" - "@babel/plugin-syntax-bigint" "^7.8.3" - "@babel/plugin-syntax-class-properties" "^7.8.3" - "@babel/plugin-syntax-import-meta" "^7.8.3" - "@babel/plugin-syntax-json-strings" "^7.8.3" - "@babel/plugin-syntax-logical-assignment-operators" "^7.8.3" - "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" - "@babel/plugin-syntax-numeric-separator" "^7.8.3" - "@babel/plugin-syntax-object-rest-spread" "^7.8.3" - "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" - "@babel/plugin-syntax-optional-chaining" "^7.8.3" - -babel-preset-jest@^25.5.0: - version "25.5.0" - resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-25.5.0.tgz#c1d7f191829487a907764c65307faa0e66590b49" - integrity sha512-8ZczygctQkBU+63DtSOKGh7tFL0CeCuz+1ieud9lJ1WPQ9O6A1a/r+LGn6Y705PA6whHQ3T1XuB/PmpfNYf8Fw== - dependencies: - babel-plugin-jest-hoist "^25.5.0" - babel-preset-current-node-syntax "^0.1.2" - -bail@^1.0.0: - version "1.0.5" - resolved "https://registry.yarnpkg.com/bail/-/bail-1.0.5.tgz#b6fa133404a392cbc1f8c4bf63f5953351e7a776" - integrity sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ== - -bail@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/bail/-/bail-2.0.2.tgz#d26f5cd8fe5d6f832a31517b9f7c356040ba6d5d" - integrity sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw== +balanced-match@^0.4.2: + version "0.4.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-0.4.2.tgz#cb3f3e3c732dc0f01ee70b403f302e61d7709838" + integrity sha512-STw03mQKnGUYtoNjmowo4F2cRmIIxYEGiMsjjwla/u5P1lxadj/05WkNaFjNiKTgJkj8KiXbgAiRTmcQRwQNtg== balanced-match@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== -base-x@^3.0.2, base-x@^3.0.8: +base-x@^3.0.2, base-x@^3.0.8, base-x@^3.0.9: version "3.0.9" resolved "https://registry.yarnpkg.com/base-x/-/base-x-3.0.9.tgz#6349aaabb58526332de9f60995e548a53fe21320" integrity sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ== @@ -7599,52 +9527,42 @@ base64-js@^1.0.2, base64-js@^1.3.0, base64-js@^1.3.1: resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== -base@^0.11.1: - version "0.11.2" - resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" - integrity sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg== - dependencies: - cache-base "^1.0.1" - class-utils "^0.3.5" - component-emitter "^1.2.1" - define-property "^1.0.0" - isobject "^3.0.1" - mixin-deep "^1.2.0" - pascalcase "^0.1.1" - -bcrypt-pbkdf@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" - integrity sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w== +bchaddrjs@^0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/bchaddrjs/-/bchaddrjs-0.5.2.tgz#1f52b5077329774e7c82d4882964628106bb11a0" + integrity sha512-OO7gIn3m7ea4FVx4cT8gdlWQR2+++EquhdpWQJH9BQjK63tJJ6ngB3QMZDO6DiBoXiIGUsTPHjlrHVxPGcGxLQ== dependencies: - tweetnacl "^0.14.3" - -bech32@*: - version "2.0.0" - resolved "https://registry.yarnpkg.com/bech32/-/bech32-2.0.0.tgz#078d3686535075c8c79709f054b1b226a133b355" - integrity sha512-LcknSilhIGatDAsY1ak2I8VtGaHNhgMSYVxFrGLXv+xLHytaKZKcaUJJUE7qmBr7h33o5YQwP55pMI0xmkpJwg== + bs58check "2.1.2" + buffer "^6.0.3" + cashaddrjs "0.4.4" + stream-browserify "^3.0.0" bech32@1.1.4, bech32@^1.1.3, bech32@^1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/bech32/-/bech32-1.1.4.tgz#e38c9f37bf179b8eb16ae3a772b40c356d4832e9" integrity sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ== -better-opn@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/better-opn/-/better-opn-2.1.1.tgz#94a55b4695dc79288f31d7d0e5f658320759f7c6" - integrity sha512-kIPXZS5qwyKiX/HcRvDYfmBQUa8XP17I0mYZZ0y4UhpYOSvtsLHDYqmomS+Mj20aDvD3knEiQ0ecQy2nhio3yA== +bech32@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/bech32/-/bech32-2.0.0.tgz#078d3686535075c8c79709f054b1b226a133b355" + integrity sha512-LcknSilhIGatDAsY1ak2I8VtGaHNhgMSYVxFrGLXv+xLHytaKZKcaUJJUE7qmBr7h33o5YQwP55pMI0xmkpJwg== + +better-opn@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/better-opn/-/better-opn-3.0.2.tgz#f96f35deaaf8f34144a4102651babcf00d1d8817" + integrity sha512-aVNobHnJqLiUelTaHat9DZ1qM2w0C0Eym4LPI/3JxOnSokGVdsl1T1kN7TFvsEAD8G47A6VKQ0TVHqbBnYMJlQ== dependencies: - open "^7.0.3" + open "^8.0.4" -big-integer@^1.6.48, big-integer@^1.6.7: - version "1.6.51" - resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.51.tgz#0df92a5d9880560d3ff2d5fd20245c889d130686" - integrity sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg== +big-integer@1.6.36: + version "1.6.36" + resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.36.tgz#78631076265d4ae3555c04f85e7d9d2f3a071a36" + integrity sha512-t70bfa7HYEA1D9idDbmuv7YbsbVkQ+Hp+8KFSul4aE5e/i1bjCNIRYJZlA8Q8p0r9T8cF/RVvwUgRA//FydEyg== -big.js@^5.2.2: - version "5.2.2" - resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" - integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== +big-integer@^1.6.44, big-integer@^1.6.48: + version "1.6.52" + resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.52.tgz#60a887f3047614a8e1bffe5d7173490a97dc8c85" + integrity sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg== bigint-buffer@^1.1.5: version "1.1.5" @@ -7653,29 +9571,29 @@ bigint-buffer@^1.1.5: dependencies: bindings "^1.3.0" -bignumber.js@^9.0.2, bignumber.js@^9.1.1: - version "9.1.1" - resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.1.1.tgz#c4df7dc496bd849d4c9464344c1aa74228b4dac6" - integrity sha512-pHm4LsMJ6lzgNGVfZHjMoO8sdoRhOzOH4MLmY65Jg70bpxCKu5iOHNJyfF6OyvYw7t8Fpf35RuzUyqnQsj8Vig== - -binary-extensions@^1.0.0: - version "1.13.1" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.13.1.tgz#598afe54755b2868a5330d2aff9d4ebb53209b65" - integrity sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw== +bignumber.js@^9.0.0, bignumber.js@^9.1.1, bignumber.js@^9.1.2: + version "9.1.2" + resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.1.2.tgz#b7c4242259c008903b13707983b5f4bbd31eda0c" + integrity sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug== binary-extensions@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== -bindings@^1.3.0, bindings@^1.4.0, bindings@^1.5.0: +bindings@^1.3.0: version "1.5.0" resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== dependencies: file-uri-to-path "1.0.0" -bip32@^2.0.5, bip32@^2.0.6: +bip32-path@^0.4.2: + version "0.4.2" + resolved "https://registry.yarnpkg.com/bip32-path/-/bip32-path-0.4.2.tgz#5db0416ad6822712f077836e2557b8697c0c7c99" + integrity sha512-ZBMCELjJfcNMkz5bDuJ1WrYvjlhEF5k6mQ8vUr4N7MbVRsXei7ZOg8VhhwMfNiW68NWmLkgkc6WvTickrLGprQ== + +bip32@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/bip32/-/bip32-2.0.6.tgz#6a81d9f98c4cd57d05150c60d8f9e75121635134" integrity sha512-HpV5OMLLGTjSVblmrtYRfFFKuQB+GArM0+XP8HGWfJ5vxYBqo+DesvJwOdC2WJ3bCkZShGf0QIfoIpeomVzVdA== @@ -7695,6 +9613,18 @@ bip39@^3.0.2, bip39@^3.0.3: dependencies: "@noble/hashes" "^1.2.0" +bip66@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/bip66/-/bip66-1.1.5.tgz#01fa8748785ca70955d5011217d1b3139969ca22" + integrity sha512-nemMHz95EmS38a26XbbdxIYj5csHd3RMP3H5bwQknX0WYHF01qhpufP42mLOwVICuH2JmhIhXiWs89MfUGL7Xw== + dependencies: + safe-buffer "^5.0.1" + +bitcoin-ops@^1.3.0, bitcoin-ops@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/bitcoin-ops/-/bitcoin-ops-1.4.1.tgz#e45de620398e22fd4ca6023de43974ff42240278" + integrity sha512-pef6gxZFztEhaE9RY9HmWVmiIHqCb2OyS4HPKkpc6CIiiOa3Qmuoylxc5P2EkU3w+5eTSifI9SEZC88idAIGow== + bl@^4.0.3, bl@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a" @@ -7704,10 +9634,19 @@ bl@^4.0.3, bl@^4.1.0: inherits "^2.0.4" readable-stream "^3.4.0" -bluebird@^3.5.5: - version "3.7.2" - resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" - integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== +blake-hash@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/blake-hash/-/blake-hash-2.0.0.tgz#af184dce641951126d05b7d1c3de3224f538d66e" + integrity sha512-Igj8YowDu1PRkRsxZA7NVkdFNxH5rKv5cpLxQ0CVXSIA77pVYwCPRQJ2sMew/oneUpfuYRyjG6r8SmmmnbZb1w== + dependencies: + node-addon-api "^3.0.0" + node-gyp-build "^4.2.2" + readable-stream "^3.6.0" + +blakejs@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/blakejs/-/blakejs-1.2.1.tgz#5057e4206eadb4a97f7c0b6e197a505042fc3814" + integrity sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ== bn.js@4.11.8: version "4.11.8" @@ -7724,21 +9663,21 @@ bn.js@^5.0.0, bn.js@^5.1.1, bn.js@^5.2.0, bn.js@^5.2.1: resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.1.tgz#0bc527a6a0d18d0aa8d5b0538ce4a77dccfa7b70" integrity sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ== -body-parser@1.20.1: - version "1.20.1" - resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.1.tgz#b1812a8912c195cd371a3ee5e66faa2338a5c668" - integrity sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw== +body-parser@1.20.3: + version "1.20.3" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.3.tgz#1953431221c6fb5cd63c4b36d53fab0928e548c6" + integrity sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g== dependencies: bytes "3.1.2" - content-type "~1.0.4" + content-type "~1.0.5" debug "2.6.9" depd "2.0.0" destroy "1.2.0" http-errors "2.0.0" iconv-lite "0.4.24" on-finished "2.4.1" - qs "6.11.0" - raw-body "2.5.1" + qs "6.13.0" + raw-body "2.5.2" type-is "~1.6.18" unpipe "1.0.0" @@ -7754,28 +9693,19 @@ borsh@^0.7.0: dependencies: bn.js "^5.2.0" bs58 "^4.0.0" - text-encoding-utf-8 "^1.0.2" - -boxen@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/boxen/-/boxen-5.1.2.tgz#788cb686fc83c1f486dfa8a40c68fc2b831d2b50" - integrity sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ== - dependencies: - ansi-align "^3.0.0" - camelcase "^6.2.0" - chalk "^4.1.0" - cli-boxes "^2.2.1" - string-width "^4.2.2" - type-fest "^0.20.2" - widest-line "^3.1.0" - wrap-ansi "^7.0.0" + text-encoding-utf-8 "^1.0.2" -bplist-parser@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/bplist-parser/-/bplist-parser-0.1.1.tgz#d60d5dcc20cba6dc7e1f299b35d3e1f95dafbae6" - integrity sha512-2AEM0FXy8ZxVLBuqX0hqt1gDwcnz2zygEkQ6zaD5Wko/sB9paUNwlpawrFtKeHUAQUOzjVy9AO4oeonqIHKA9Q== +bowser@^2.11.0: + version "2.11.0" + resolved "https://registry.yarnpkg.com/bowser/-/bowser-2.11.0.tgz#5ca3c35757a7aa5771500c70a73a9f91ef420a8f" + integrity sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA== + +bplist-parser@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/bplist-parser/-/bplist-parser-0.2.0.tgz#43a9d183e5bf9d545200ceac3e712f79ebbe8d0e" + integrity sha512-z0M+byMThzQmD9NILRniCUXYsYpjwnlO8N5uCFaCqIOpqRsJCrQL9NK3JsD67CN5a08nF5oIL2bD6loTdHOuKw== dependencies: - big-integer "^1.6.7" + big-integer "^1.6.44" brace-expansion@^1.1.7: version "1.1.11" @@ -7792,45 +9722,27 @@ brace-expansion@^2.0.1: dependencies: balanced-match "^1.0.0" -braces@^2.3.1, braces@^2.3.2: - version "2.3.2" - resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" - integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== - dependencies: - arr-flatten "^1.1.0" - array-unique "^0.3.2" - extend-shallow "^2.0.1" - fill-range "^4.0.0" - isobject "^3.0.1" - repeat-element "^1.1.2" - snapdragon "^0.8.1" - snapdragon-node "^2.0.1" - split-string "^3.0.2" - to-regex "^3.0.1" - -braces@^3.0.2, braces@~3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" - integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== +braces@^3.0.1, braces@^3.0.2, braces@~3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.3.tgz#490332f40919452272d55a8480adc0c441358789" + integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA== dependencies: - fill-range "^7.0.1" + fill-range "^7.1.1" -brorand@^1.0.1, brorand@^1.1.0: +brorand@^1.0.1, brorand@^1.0.5, brorand@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" integrity sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w== -browser-process-hrtime@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz#3c9b4b7d782c8121e56f10106d84c0d0ffc94626" - integrity sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow== +browser-assert@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/browser-assert/-/browser-assert-1.2.1.tgz#9aaa5a2a8c74685c2ae05bfe46efd606f068c200" + integrity sha512-nfulgvOR6S4gt9UKCeGJOuSGBPGiFT6oQ/2UBnvTY/5aQ1PnksW72fhZkM30DzoRRv2WpwZf1vHHEr3mtuXIWQ== -browser-resolve@^1.11.3: - version "1.11.3" - resolved "https://registry.yarnpkg.com/browser-resolve/-/browser-resolve-1.11.3.tgz#9b7cbb3d0f510e4cb86bdbd796124d28b5890af6" - integrity sha512-exDi1BYWB/6raKHmDTCicQfTkqwN5fioMFV4j8BsfMU4R2DK/QfZfK7kOVkmWCNANf0snkBzqGqAJBao9gZMdQ== - dependencies: - resolve "1.1.7" +browser-headers@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/browser-headers/-/browser-headers-0.4.1.tgz#4308a7ad3b240f4203dbb45acedb38dc2d65dd02" + integrity sha512-CA9hsySZVo9371qEHjHZtYxV2cFtVj5Wj/ZHi8ooEsrtm4vOnl9Y9HmyYWk9q+05d7K3rdoAE0j3MVEFVvtQtg== browserify-aes@^1.0.0, browserify-aes@^1.0.4: version "1.2.0" @@ -7863,7 +9775,7 @@ browserify-des@^1.0.0: inherits "^2.0.1" safe-buffer "^5.1.2" -browserify-rsa@^4.0.0, browserify-rsa@^4.0.1: +browserify-rsa@^4.0.0, browserify-rsa@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.1.0.tgz#b2fd06b5b75ae297f7ce2dc651f918f5be158c8d" integrity sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog== @@ -7872,19 +9784,19 @@ browserify-rsa@^4.0.0, browserify-rsa@^4.0.1: randombytes "^2.0.1" browserify-sign@^4.0.0: - version "4.2.1" - resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.2.1.tgz#eaf4add46dd54be3bb3b36c0cf15abbeba7956c3" - integrity sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg== + version "4.2.2" + resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.2.2.tgz#e78d4b69816d6e3dd1c747e64e9947f9ad79bc7e" + integrity sha512-1rudGyeYY42Dk6texmv7c4VcQ0EsvVbLwZkA+AQB7SxvXxmcD93jcHie8bzecJ+ChDlmAm2Qyu0+Ccg5uhZXCg== dependencies: - bn.js "^5.1.1" - browserify-rsa "^4.0.1" + bn.js "^5.2.1" + browserify-rsa "^4.1.0" create-hash "^1.2.0" create-hmac "^1.1.7" - elliptic "^6.5.3" + elliptic "^6.5.4" inherits "^2.0.4" - parse-asn1 "^5.1.5" - readable-stream "^3.6.0" - safe-buffer "^5.2.0" + parse-asn1 "^5.1.6" + readable-stream "^3.6.2" + safe-buffer "^5.2.1" browserify-zlib@^0.1.4: version "0.1.4" @@ -7893,29 +9805,35 @@ browserify-zlib@^0.1.4: dependencies: pako "~0.2.0" -browserify-zlib@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.2.0.tgz#2869459d9aa3be245fe8fe2ca1f46e2e7f54d73f" - integrity sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA== +browserslist@^4.21.10: + version "4.23.3" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.23.3.tgz#debb029d3c93ebc97ffbc8d9cbb03403e227c800" + integrity sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA== dependencies: - pako "~1.0.5" + caniuse-lite "^1.0.30001646" + electron-to-chromium "^1.5.4" + node-releases "^2.0.18" + update-browserslist-db "^1.1.0" -browserslist@^4.12.0, browserslist@^4.14.5, browserslist@^4.21.3, browserslist@^4.21.5, browserslist@^4.6.6: - version "4.21.5" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.5.tgz#75c5dae60063ee641f977e00edd3cfb2fb7af6a7" - integrity sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w== +browserslist@^4.21.9, browserslist@^4.22.1, browserslist@^4.6.6: + version "4.22.1" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.22.1.tgz#ba91958d1a59b87dab6fed8dfbcb3da5e2e9c619" + integrity sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ== dependencies: - caniuse-lite "^1.0.30001449" - electron-to-chromium "^1.4.284" - node-releases "^2.0.8" - update-browserslist-db "^1.0.10" + caniuse-lite "^1.0.30001541" + electron-to-chromium "^1.4.535" + node-releases "^2.0.13" + update-browserslist-db "^1.0.13" -bs-logger@0.x: - version "0.2.6" - resolved "https://registry.yarnpkg.com/bs-logger/-/bs-logger-0.2.6.tgz#eb7d365307a72cf974cc6cda76b68354ad336bd8" - integrity sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog== +browserslist@^4.22.2, browserslist@^4.23.0: + version "4.23.0" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.23.0.tgz#8f3acc2bbe73af7213399430890f86c63a5674ab" + integrity sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ== dependencies: - fast-json-stable-stringify "2.x" + caniuse-lite "^1.0.30001587" + electron-to-chromium "^1.4.668" + node-releases "^2.0.14" + update-browserslist-db "^1.0.13" bs58@^4.0.0, bs58@^4.0.1: version "4.0.1" @@ -7931,7 +9849,7 @@ bs58@^5.0.0: dependencies: base-x "^4.0.0" -bs58check@<3.0.0, bs58check@^2.1.1: +bs58check@2.1.2, bs58check@<3.0.0, bs58check@^2.1.1, bs58check@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/bs58check/-/bs58check-2.1.2.tgz#53b018291228d82a5aa08e7d796fdafda54aebfc" integrity sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA== @@ -7940,32 +9858,15 @@ bs58check@<3.0.0, bs58check@^2.1.1: create-hash "^1.1.0" safe-buffer "^5.1.2" -bser@2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/bser/-/bser-2.1.1.tgz#e6787da20ece9d07998533cfd9de6f5c38f4bc05" - integrity sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ== - dependencies: - node-int64 "^0.4.0" - -buffer-alloc-unsafe@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0" - integrity sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg== - -buffer-alloc@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/buffer-alloc/-/buffer-alloc-1.2.0.tgz#890dd90d923a873e08e10e5fd51a57e5b7cce0ec" - integrity sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow== +bs58check@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/bs58check/-/bs58check-3.0.1.tgz#2094d13720a28593de1cba1d8c4e48602fdd841c" + integrity sha512-hjuuJvoWEybo7Hn/0xOrczQKKEKD63WguEjlhLExYs2wUBcebDC1jDNK17eEAD2lYfw82d5ASC1d7K3SWszjaQ== dependencies: - buffer-alloc-unsafe "^1.1.0" - buffer-fill "^1.0.0" - -buffer-fill@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/buffer-fill/-/buffer-fill-1.0.0.tgz#f8f78b76789888ef39f205cd637f68e702122b2c" - integrity sha512-T7zexNBwiiaCOGDg9xNX9PBmjrubblRkENuptryuI64URkXDFum9il/JGL8Lm8wYfAXpredVXXZz7eMHilimiQ== + "@noble/hashes" "^1.2.0" + bs58 "^5.0.0" -buffer-from@1.x, buffer-from@^1.0.0, buffer-from@^1.1.1: +buffer-from@^1.0.0: version "1.1.2" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== @@ -7975,14 +9876,6 @@ buffer-xor@^1.0.3: resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" integrity sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ== -buffer@6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.1.tgz#3cbea8c1463e5a0779e30b66d4c88c6ffa182ac2" - integrity sha512-rVAXBwEcEoYtxnHSO5iWyhzV/O1WMtkUYWlfdLS7FjU4PnSJJHEfHXi/uHPI5EwltmOA794gN3bm3/pzuctWjQ== - dependencies: - base64-js "^1.3.1" - ieee754 "^1.2.1" - buffer@6.0.3, buffer@^6.0.3, buffer@~6.0.3: version "6.0.3" resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6" @@ -7991,16 +9884,7 @@ buffer@6.0.3, buffer@^6.0.3, buffer@~6.0.3: base64-js "^1.3.1" ieee754 "^1.2.1" -buffer@^4.3.0: - version "4.9.2" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.2.tgz#230ead344002988644841ab0244af8c44bbe3ef8" - integrity sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg== - dependencies: - base64-js "^1.0.2" - ieee754 "^1.1.4" - isarray "^1.0.0" - -buffer@^5.4.3, buffer@^5.5.0: +buffer@^5.5.0: version "5.7.1" resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== @@ -8016,28 +9900,13 @@ buffer@~5.4.3: base64-js "^1.0.2" ieee754 "^1.1.4" -bufferutil@^4.0.1: - version "4.0.7" - resolved "https://registry.yarnpkg.com/bufferutil/-/bufferutil-4.0.7.tgz#60c0d19ba2c992dd8273d3f73772ffc894c153ad" - integrity sha512-kukuqc39WOHtdxtw4UScxF/WVnMFVSQVKhtx3AjZJzhd0RGZZldcrfSEbVsWWe6KNH253574cq5F+wpv0G9pJw== +bufferutil@^4.0.1, bufferutil@^4.0.3: + version "4.0.8" + resolved "https://registry.yarnpkg.com/bufferutil/-/bufferutil-4.0.8.tgz#1de6a71092d65d7766c4d8a522b261a6e787e8ea" + integrity sha512-4T53u4PdgsXqKaIctwF8ifXlRTTmEPJ8iEPWFdGZvcf7sbwYo6FKFEX9eNNAnzFZ7EzJAQ3CJeOtCRA4rDp7Pw== dependencies: node-gyp-build "^4.3.0" -builtin-modules@^3.1.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-3.3.0.tgz#cae62812b89801e9656336e46223e030386be7b6" - integrity sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw== - -builtin-status-codes@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" - integrity sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ== - -bytes-iec@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/bytes-iec/-/bytes-iec-3.1.1.tgz#94cd36bf95c2c22a82002c247df8772d1d591083" - integrity sha512-fey6+4jDK7TFtFg/klGSvNKJctyU7n2aQdnM+CO0ruLPbqqMOM8Tio0Pc+deqUeVKX1tL5DQep1zQ7+37aTAsA== - bytes@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" @@ -8048,126 +9917,42 @@ bytes@3.1.2: resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== -c8@^7.6.0: - version "7.13.0" - resolved "https://registry.yarnpkg.com/c8/-/c8-7.13.0.tgz#a2a70a851278709df5a9247d62d7f3d4bcb5f2e4" - integrity sha512-/NL4hQTv1gBL6J6ei80zu3IiTrmePDKXKXOTLpHvcIWZTVYQlDhVWjjWvkhICylE8EwwnMVzDZugCvdx0/DIIA== - dependencies: - "@bcoe/v8-coverage" "^0.2.3" - "@istanbuljs/schema" "^0.1.3" - find-up "^5.0.0" - foreground-child "^2.0.0" - istanbul-lib-coverage "^3.2.0" - istanbul-lib-report "^3.0.0" - istanbul-reports "^3.1.4" - rimraf "^3.0.2" - test-exclude "^6.0.0" - v8-to-istanbul "^9.0.0" - yargs "^16.2.0" - yargs-parser "^20.2.9" - cac@^6.7.14: version "6.7.14" resolved "https://registry.yarnpkg.com/cac/-/cac-6.7.14.tgz#804e1e6f506ee363cb0e3ccbb09cad5dd9870959" integrity sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ== -cacache@^12.0.2: - version "12.0.4" - resolved "https://registry.yarnpkg.com/cacache/-/cacache-12.0.4.tgz#668bcbd105aeb5f1d92fe25570ec9525c8faa40c" - integrity sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ== - dependencies: - bluebird "^3.5.5" - chownr "^1.1.1" - figgy-pudding "^3.5.1" - glob "^7.1.4" - graceful-fs "^4.1.15" - infer-owner "^1.0.3" - lru-cache "^5.1.1" - mississippi "^3.0.0" - mkdirp "^0.5.1" - move-concurrently "^1.0.1" - promise-inflight "^1.0.1" - rimraf "^2.6.3" - ssri "^6.0.1" - unique-filename "^1.1.1" - y18n "^4.0.0" - -cacache@^15.0.5: - version "15.3.0" - resolved "https://registry.yarnpkg.com/cacache/-/cacache-15.3.0.tgz#dc85380fb2f556fe3dda4c719bfa0ec875a7f1eb" - integrity sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ== - dependencies: - "@npmcli/fs" "^1.0.0" - "@npmcli/move-file" "^1.0.1" - chownr "^2.0.0" - fs-minipass "^2.0.0" - glob "^7.1.4" - infer-owner "^1.0.4" - lru-cache "^6.0.0" - minipass "^3.1.1" - minipass-collect "^1.0.2" - minipass-flush "^1.0.5" - minipass-pipeline "^1.2.2" - mkdirp "^1.0.3" - p-map "^4.0.0" - promise-inflight "^1.0.1" - rimraf "^3.0.2" - ssri "^8.0.1" - tar "^6.0.2" - unique-filename "^1.1.1" +caip@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/caip/-/caip-1.1.1.tgz#c2c2b598b5e052d72c35c8d81b31f864e19c61e3" + integrity sha512-a3v5lteUUOoyRI0U6qe5ayCCGkF2mCmJ5zQMDnOD2vRjgRg6sm9p8TsRC2h4D4beyqRN9RYniphAPnj/+jQC6g== -cache-base@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" - integrity sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ== +call-bind@^1.0.0, call-bind@^1.0.2, call-bind@^1.0.4, call-bind@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.5.tgz#6fa2b7845ce0ea49bf4d8b9ef64727a2c2e2e513" + integrity sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ== dependencies: - collection-visit "^1.0.0" - component-emitter "^1.2.1" - get-value "^2.0.6" - has-value "^1.0.0" - isobject "^3.0.1" - set-value "^2.0.0" - to-object-path "^0.3.0" - union-value "^1.0.0" - unset-value "^1.0.0" - -cacheable-lookup@^5.0.3: - version "5.0.4" - resolved "https://registry.yarnpkg.com/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz#5a6b865b2c44357be3d5ebc2a467b032719a7005" - integrity sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA== + function-bind "^1.1.2" + get-intrinsic "^1.2.1" + set-function-length "^1.1.1" -cacheable-request@^7.0.2: - version "7.0.2" - resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-7.0.2.tgz#ea0d0b889364a25854757301ca12b2da77f91d27" - integrity sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew== - dependencies: - clone-response "^1.0.2" - get-stream "^5.1.0" - http-cache-semantics "^4.0.0" - keyv "^4.0.0" - lowercase-keys "^2.0.0" - normalize-url "^6.0.1" - responselike "^2.0.0" - -call-bind@^1.0.0, call-bind@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" - integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== +call-bind@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.7.tgz#06016599c40c56498c18769d2730be242b6fa3b9" + integrity sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w== dependencies: - function-bind "^1.1.1" - get-intrinsic "^1.0.2" - -call-me-maybe@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/call-me-maybe/-/call-me-maybe-1.0.2.tgz#03f964f19522ba643b1b0693acb9152fe2074baa" - integrity sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ== + es-define-property "^1.0.0" + es-errors "^1.3.0" + function-bind "^1.1.2" + get-intrinsic "^1.2.4" + set-function-length "^1.2.1" callsites@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== -camel-case@^4.1.1: +camel-case@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-4.1.2.tgz#9728072a954f805228225a6deea6b38461e1bd5a" integrity sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw== @@ -8175,19 +9960,6 @@ camel-case@^4.1.1: pascal-case "^3.1.2" tslib "^2.0.3" -camelcase-css@2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/camelcase-css/-/camelcase-css-2.0.1.tgz#ee978f6947914cc30c6b44741b6ed1df7f043fd5" - integrity sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA== - -camelcase-keys@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7" - integrity sha512-bA/Z/DERHKqoEOrp+qeGKw1QlvEQkGZSc0XaY6VnTxZr+Kv1G5zFwttpjv8qxZ/sBPT4nthwZaAcsAZTJlSKXQ== - dependencies: - camelcase "^2.0.0" - map-obj "^1.0.0" - camelcase-keys@^6.2.2: version "6.2.2" resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-6.2.2.tgz#5e755d6ba51aa223ec7d3d52f25778210f9dc3c0" @@ -8197,17 +9969,12 @@ camelcase-keys@^6.2.2: map-obj "^4.0.0" quick-lru "^4.0.1" -camelcase@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f" - integrity sha512-DLIsRzJVBQu72meAKPkWQOLcujdXT32hwdfnkI1frSiSRMK1MofjKHf+MEx0SB6fjEFXL8fBDv1dKymBlOp4Qw== - camelcase@^5.0.0, camelcase@^5.3.1: version "5.3.1" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== -camelcase@^6.0.0, camelcase@^6.2.0: +camelcase@^6.2.0: version "6.3.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== @@ -8217,34 +9984,45 @@ can-use-dom@^0.1.0: resolved "https://registry.yarnpkg.com/can-use-dom/-/can-use-dom-0.1.0.tgz#22cc4a34a0abc43950f42c6411024a3f6366b45a" integrity sha512-ceOhN1DL7Y4O6M0j9ICgmTYziV89WMd96SvSl0REd8PMgrY0B/WBOPoed5S1KUmJqXgUXh8gzSe6E3ae27upsQ== -caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001449: - version "1.0.30001474" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001474.tgz#13b6fe301a831fe666cce8ca4ef89352334133d5" - integrity sha512-iaIZ8gVrWfemh5DG3T9/YqarVZoYf0r188IjaGwx68j4Pf0SGY6CQkmJUIE+NZHkkecQGohzXmBGEwWDr9aM3Q== +caniuse-lite@^1.0.30001541, caniuse-lite@^1.0.30001587: + version "1.0.30001638" + resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001638.tgz" + integrity sha512-5SuJUJ7cZnhPpeLHaH0c/HPAnAHZvS6ElWyHK9GSIbVOQABLzowiI2pjmpvZ1WEbkyz46iFd4UXlOHR5SqgfMQ== -capture-exit@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/capture-exit/-/capture-exit-2.0.0.tgz#fb953bfaebeb781f62898239dabb426d08a509a4" - integrity sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g== - dependencies: - rsvp "^4.8.4" +caniuse-lite@^1.0.30001646: + version "1.0.30001660" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001660.tgz#31218de3463fabb44d0b7607b652e56edf2e2355" + integrity sha512-GacvNTTuATm26qC74pt+ad1fW15mlQ/zuTzzY1ZoIzECTP8HURDfF43kNxPgf7H1jmelCBQTTbBNxdSXOA7Bqg== -case-sensitive-paths-webpack-plugin@^2.3.0: +case-sensitive-paths-webpack-plugin@^2.4.0: version "2.4.0" resolved "https://registry.yarnpkg.com/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.4.0.tgz#db64066c6422eed2e08cc14b986ca43796dbc6d4" integrity sha512-roIFONhcxog0JSSWbvVAh3OocukmSgpqOH6YpMkCvav/ySIV3JKg4Dc8vYtQjYi/UxpNE36r/9v+VqTQqgkYmw== -caseless@~0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" - integrity sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw== +cashaddrjs@0.4.4: + version "0.4.4" + resolved "https://registry.yarnpkg.com/cashaddrjs/-/cashaddrjs-0.4.4.tgz#169f1ae620d325db77700273d972282adeeee331" + integrity sha512-xZkuWdNOh0uq/mxJIng6vYWfTowZLd9F4GMAlp2DwFHlcCqCm91NtuAc47RuV4L7r4PYcY5p6Cr2OKNb4hnkWA== + dependencies: + big-integer "1.6.36" -ccount@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/ccount/-/ccount-1.1.0.tgz#246687debb6014735131be8abab2d93898f8d043" - integrity sha512-vlNK021QdI7PNeiUh/lKkC/mNHHfV0m/Ad5JoI0TYtlBnJAslM/JIkm/tGC88bkLIwO6OQ5uV6ztS6kVAtCDlg== +chai@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/chai/-/chai-5.1.1.tgz#f035d9792a22b481ead1c65908d14bb62ec1c82c" + integrity sha512-pT1ZgP8rPNqUgieVaEY+ryQr6Q4HXNg8Ei9UnLUrjN4IA7dvQC5JB+/kxVcPNDHyBcc/26CXPkbNzq3qwrOEKA== + dependencies: + assertion-error "^2.0.1" + check-error "^2.1.1" + deep-eql "^5.0.1" + loupe "^3.1.0" + pathval "^2.0.0" + +chalk@5.3.0, chalk@^5.2.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-5.3.0.tgz#67c20a7ebef70e7f3970a01f90fa210cb6860385" + integrity sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w== -chalk@^2.0.0, chalk@^2.1.0, chalk@^2.4.1, chalk@^2.4.2: +chalk@^2.4.1, chalk@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== @@ -8253,15 +10031,7 @@ chalk@^2.0.0, chalk@^2.1.0, chalk@^2.4.1, chalk@^2.4.2: escape-string-regexp "^1.0.5" supports-color "^5.3.0" -chalk@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-3.0.0.tgz#3f73c2bf526591f574cc492c51e2456349f844e4" - integrity sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - -chalk@^4.0.0, chalk@^4.0.2, chalk@^4.1.0, chalk@^4.1.1, chalk@^4.1.2: +chalk@^4.0.0, chalk@^4.0.2, chalk@^4.1.0, chalk@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== @@ -8269,46 +10039,21 @@ chalk@^4.0.0, chalk@^4.0.2, chalk@^4.1.0, chalk@^4.1.1, chalk@^4.1.2: ansi-styles "^4.1.0" supports-color "^7.1.0" -chalk@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-5.2.0.tgz#249623b7d66869c673699fb66d65723e54dfcfb3" - integrity sha512-ree3Gqw/nazQAPuJJEy+avdl7QfZMcUvmHIKgEZkGL+xOBzRvup5Hxo6LHuMceSxOabuJLJm5Yp/92R9eMmMvA== - -character-entities-html4@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/character-entities-html4/-/character-entities-html4-2.1.0.tgz#1f1adb940c971a4b22ba39ddca6b618dc6e56b2b" - integrity sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA== - character-entities-legacy@^1.0.0: version "1.1.4" resolved "https://registry.yarnpkg.com/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz#94bc1845dce70a5bb9d2ecc748725661293d8fc1" integrity sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA== -character-entities-legacy@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz#76bc83a90738901d7bc223a9e93759fdd560125b" - integrity sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ== - character-entities@^1.0.0: version "1.2.4" resolved "https://registry.yarnpkg.com/character-entities/-/character-entities-1.2.4.tgz#e12c3939b7eaf4e5b15e7ad4c5e28e1d48c5b16b" integrity sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw== -character-entities@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/character-entities/-/character-entities-2.0.2.tgz#2d09c2e72cd9523076ccb21157dff66ad43fcc22" - integrity sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ== - character-reference-invalid@^1.0.0: version "1.1.4" resolved "https://registry.yarnpkg.com/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz#083329cda0eae272ab3dbbf37e9a382c13af1560" integrity sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg== -character-reference-invalid@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz#85c66b041e43b47210faf401278abf808ac45cb9" - integrity sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw== - chardet@^0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" @@ -8319,26 +10064,27 @@ charenc@~0.0.1: resolved "https://registry.yarnpkg.com/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667" integrity sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA== -chokidar@^2.1.8: - version "2.1.8" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.8.tgz#804b3a7b6a99358c3c5c61e71d8728f041cff917" - integrity sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg== +check-error@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/check-error/-/check-error-2.1.1.tgz#87eb876ae71ee388fa0471fe423f494be1d96ccc" + integrity sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw== + +chokidar@3.5.1: + version "3.5.1" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.1.tgz#ee9ce7bbebd2b79f49f304799d5468e31e14e68a" + integrity sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw== dependencies: - anymatch "^2.0.0" - async-each "^1.0.1" - braces "^2.3.2" - glob-parent "^3.1.0" - inherits "^2.0.3" - is-binary-path "^1.0.0" - is-glob "^4.0.0" - normalize-path "^3.0.0" - path-is-absolute "^1.0.0" - readdirp "^2.2.1" - upath "^1.1.1" + anymatch "~3.1.1" + braces "~3.0.2" + glob-parent "~5.1.0" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.5.0" optionalDependencies: - fsevents "^1.2.7" + fsevents "~2.3.1" -chokidar@^3.4.1, chokidar@^3.4.2, chokidar@^3.5.1, chokidar@^3.5.3: +chokidar@^3.5.1, chokidar@^3.5.3: version "3.5.3" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== @@ -8363,15 +10109,20 @@ chownr@^2.0.0: resolved "https://registry.yarnpkg.com/chownr/-/chownr-2.0.0.tgz#15bfbe53d2eab4cf70f18a8cd68ebe5b3cb1dece" integrity sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ== -chrome-trace-event@^1.0.2: +chromatic@^11.3.0: + version "11.3.0" + resolved "https://registry.yarnpkg.com/chromatic/-/chromatic-11.3.0.tgz#d46b7aac1a0eaed29a765645eaf93c484220174c" + integrity sha512-q1ZtJDJrjLGnz60ivpC16gmd7KFzcaA4eTb7gcytCqbaKqlHhCFr1xQmcUDsm14CK7JsqdkFU6S+JQdOd2ZNJg== + +chrome-trace-event@^1.0.2, chrome-trace-event@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz#1015eced4741e15d06664a957dbbf50d041e26ac" integrity sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg== -ci-info@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" - integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== +ci-info@^3.7.0: + version "3.9.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.9.0.tgz#4279a62028a7b1f262f3473fc9605f5e218c59b4" + integrity sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ== cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: version "1.0.4" @@ -8381,20 +10132,27 @@ cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: inherits "^2.0.1" safe-buffer "^5.0.1" -class-utils@^0.3.5: - version "0.3.6" - resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" - integrity sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg== +citty@^0.1.3, citty@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/citty/-/citty-0.1.5.tgz#fe37ceae5dc764af75eb2fece99d2bf527ea4e50" + integrity sha512-AS7n5NSc0OQVMV9v6wt3ByujNIrne0/cTjiC2MYqhvao57VNfiuVksTSr2p17nVOhEr2KtqiAkGwHcgMC/qUuQ== dependencies: - arr-union "^3.1.0" - define-property "^0.2.5" - isobject "^3.0.0" - static-extend "^0.1.1" + consola "^3.2.3" -clean-css@^4.2.3: - version "4.2.4" - resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.2.4.tgz#733bf46eba4e607c6891ea57c24a989356831178" - integrity sha512-EJUDT7nDVFDvaQgAo2G/PJvxmp1o/c6iXLbswsBbUFXi1Nr+AjA2cKmfbKDMjMvzEe75g3P6JkaDDAKk96A85A== +cjs-module-lexer@^1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz#6c370ab19f8a3394e318fe682686ec0ac684d107" + integrity sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ== + +classnames@^2.3.1, classnames@^2.3.2: + version "2.5.1" + resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.5.1.tgz#ba774c614be0f016da105c858e7159eae8e7687b" + integrity sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow== + +clean-css@^5.2.2: + version "5.3.2" + resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-5.3.2.tgz#70ecc7d4d4114921f5d298349ff86a31a9975224" + integrity sha512-JVJbM+f3d3Q704rF4bqQ5UUyTtuJ0JRKNbTKVEeujCCBoMdkEi+V+e8oktO9qGQNSvHrFTM6JZRXrUvGR1czww== dependencies: source-map "~0.6.0" @@ -8403,11 +10161,6 @@ clean-stack@^2.0.0: resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== -cli-boxes@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-2.2.1.tgz#ddd5035d25094fce220e9cab40a45840a440318f" - integrity sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw== - cli-cursor@3.1.0, cli-cursor@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" @@ -8415,27 +10168,22 @@ cli-cursor@3.1.0, cli-cursor@^3.1.0: dependencies: restore-cursor "^3.1.0" -cli-cursor@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" - integrity sha512-8lgKz8LmCRYZZQDpRyT2m5rKJ08TnU4tR9FFFW2rxpxR1FzWi4PQ/NfyODchAatHaUgnSPVcx/R5w6NuTBzFiw== +cli-cursor@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-4.0.0.tgz#3cecfe3734bf4fe02a8361cbdc0f6fe28c6a57ea" + integrity sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg== dependencies: - restore-cursor "^2.0.0" + restore-cursor "^4.0.0" cli-spinners@2.6.1: version "2.6.1" resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.6.1.tgz#adc954ebe281c37a6319bfa401e6dd2488ffb70d" integrity sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g== -cli-spinners@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-1.3.1.tgz#002c1990912d0d59580c93bd36c056de99e4259a" - integrity sha512-1QL4544moEsDVH9T/l6Cemov/37iv1RtoKf7NJ04A60+4MREXNfx/QvavbH6QoGdsD4N4Mwy49cmaINR/o2mdg== - -cli-spinners@^2.2.0, cli-spinners@^2.5.0: - version "2.7.0" - resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.7.0.tgz#f815fd30b5f9eaac02db604c7a231ed7cb2f797a" - integrity sha512-qu3pN8Y3qHNgE2AFweciB1IfMnmZ/fsNTEE+NOFjmGB2F/7rLhnhzppvpCnN4FovtP26k8lHyy9ptEbNwWFLzw== +cli-spinners@^2.5.0: + version "2.9.2" + resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.9.2.tgz#1773a8f4b9c4d6ac31563df53b3fc1d79462fe41" + integrity sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg== cli-table3@^0.6.1: version "0.6.3" @@ -8446,6 +10194,21 @@ cli-table3@^0.6.1: optionalDependencies: "@colors/colors" "1.5.0" +cli-table@0.3.6: + version "0.3.6" + resolved "https://registry.yarnpkg.com/cli-table/-/cli-table-0.3.6.tgz#e9d6aa859c7fe636981fd3787378c2a20bce92fc" + integrity sha512-ZkNZbnZjKERTY5NwC2SeMeLeifSPq/pubeRoTpdr3WchLlnZg6hEgvHkK5zL7KNFdd9PmHN8lxrENUwI3cE8vQ== + dependencies: + colors "1.0.3" + +cli-truncate@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-3.1.0.tgz#3f23ab12535e3d73e839bb43e73c9de487db1389" + integrity sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA== + dependencies: + slice-ansi "^5.0.0" + string-width "^5.0.0" + cli-width@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-3.0.0.tgz#a2f48437a2caa9a22436e794bf071ec9e61cedf6" @@ -8460,14 +10223,14 @@ clipboard@^2.0.0: select "^1.1.2" tiny-emitter "^2.0.0" -cliui@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-5.0.0.tgz#deefcfdb2e800784aa34f46fa08e06851c7bbbc5" - integrity sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA== +clipboardy@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/clipboardy/-/clipboardy-3.0.0.tgz#f3876247404d334c9ed01b6f269c11d09a5e3092" + integrity sha512-Su+uU5sr1jkUy1sGRpLKjKrvEOVXgSgiSInwa/qeID6aJ07yh+5NWc3h2QfjHjBnfX4LhtFcuAWKUsJ3r+fjbg== dependencies: - string-width "^3.1.0" - strip-ansi "^5.2.0" - wrap-ansi "^5.1.0" + arch "^2.2.0" + execa "^5.1.1" + is-wsl "^2.2.0" cliui@^6.0.0: version "6.0.0" @@ -8505,13 +10268,6 @@ clone-deep@^4.0.1: kind-of "^6.0.2" shallow-clone "^3.0.0" -clone-response@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.3.tgz#af2032aa47816399cf5f0a1d0db902f517abb8c3" - integrity sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA== - dependencies: - mimic-response "^1.0.0" - clone@^1.0.2: version "1.0.4" resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" @@ -8522,38 +10278,10 @@ clone@^2.1.1: resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f" integrity sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w== -co@^4.6.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" - integrity sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ== - -code-block-writer@^10.1.1: - version "10.1.1" - resolved "https://registry.yarnpkg.com/code-block-writer/-/code-block-writer-10.1.1.tgz#ad5684ed4bfb2b0783c8b131281ae84ee640a42f" - integrity sha512-67ueh2IRGst/51p0n6FvPrnRjAGHY5F8xdjkgrYE7DDzpJe6qA07RYQ9VcoUeo5ATOjSOiWpSL3SWBRRbempMw== - -code-point-at@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" - integrity sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA== - -collapse-white-space@^1.0.2: - version "1.0.6" - resolved "https://registry.yarnpkg.com/collapse-white-space/-/collapse-white-space-1.0.6.tgz#e63629c0016665792060dbbeb79c42239d2c5287" - integrity sha512-jEovNnrhMuqyCcjfEJA56v0Xq8SkIoPKDyaHahwo3POf4qcSXqMYuwNcOTzp74vTsR9Tn08z4MxWqAhcekogkQ== - -collect-v8-coverage@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz#cc2c8e94fc18bbdffe64d6534570c8a673b27f59" - integrity sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg== - -collection-visit@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" - integrity sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw== - dependencies: - map-visit "^1.0.0" - object-visit "^1.0.0" +cluster-key-slot@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz#88ddaa46906e303b5de30d3153b7d9fe0a0c19ac" + integrity sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA== color-convert@^1.9.0: version "1.9.3" @@ -8574,17 +10302,22 @@ color-name@1.1.3: resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== -color-name@~1.1.4: +color-name@^1.1.4, color-name@~1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== -color-support@^1.1.2: - version "1.1.3" - resolved "https://registry.yarnpkg.com/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2" - integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg== +colorette@^2.0.10, colorette@^2.0.20: + version "2.0.20" + resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.20.tgz#9eb793e6833067f7235902fcd3b09917a000a95a" + integrity sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w== + +colors@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.0.3.tgz#0433f44d809680fdeb60ed260f1b0c262e82a40b" + integrity sha512-pFGrxThWcWQ2MsAz6RtgeWe4NK2kUE1WfsrvvlctdII745EW9I0yflqhe7++M5LEc7bV2c/9/5zc8sFcpL0Drw== -combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6: +combined-stream@^1.0.8: version "1.0.8" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== @@ -8596,11 +10329,6 @@ comma-separated-tokens@^1.0.0: resolved "https://registry.yarnpkg.com/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz#632b80b6117867a158f1080ad498b2fbe7e3f5ea" integrity sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw== -comma-separated-tokens@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz#4e89c9458acb61bc8fef19f4529973b2392839ee" - integrity sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg== - command-line-args@^5.2.1: version "5.2.1" resolved "https://registry.yarnpkg.com/command-line-args/-/command-line-args-5.2.1.tgz#c44c32e437a57d7c51157696893c5909e9cec42e" @@ -8611,16 +10339,21 @@ command-line-args@^5.2.1: lodash.camelcase "^4.3.0" typical "^4.0.0" -commander@^2.19.0, commander@^2.20.0, commander@^2.20.3: +commander@11.0.0: + version "11.0.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-11.0.0.tgz#43e19c25dbedc8256203538e8d7e9346877a6f67" + integrity sha512-9HMlXtt/BNoYr8ooyjjNRdIilOTkVJXB+GhxMTtOKwk0R4j4lS4NpjuqmRxroBfnfTSHQIHQB7wryHhXarNjmQ== + +commander@^10.0.0: + version "10.0.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-10.0.1.tgz#881ee46b4f77d1c1dccc5823433aa39b022cbe06" + integrity sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug== + +commander@^2.20.0, commander@^2.20.3: version "2.20.3" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== -commander@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068" - integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA== - commander@^6.2.1: version "6.2.1" resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c" @@ -8631,6 +10364,16 @@ commander@^7.0.0, commander@^7.2.0: resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== +commander@^8.3.0: + version "8.3.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66" + integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww== + +commander@^9.4.1: + version "9.5.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-9.5.0.tgz#bc08d1eb5cedf7ccb797a96199d41c7bc3e60d30" + integrity sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ== + common-path-prefix@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/common-path-prefix/-/common-path-prefix-3.0.0.tgz#7d007a7e07c58c4b4d5f433131a19141b29f11e0" @@ -8649,11 +10392,6 @@ compare-func@^2.0.0: array-ify "^1.0.0" dot-prop "^5.1.0" -component-emitter@^1.2.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" - integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== - compressible@~2.0.16: version "2.0.18" resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.18.tgz#af53cca6b070d4c3c0750fbd77286a6d7cc46fba" @@ -8679,16 +10417,6 @@ concat-map@0.0.1: resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== -concat-stream@^1.5.0: - version "1.6.2" - resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" - integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== - dependencies: - buffer-from "^1.0.0" - inherits "^2.0.3" - readable-stream "^2.2.2" - typedarray "^0.0.6" - concat-stream@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-2.0.0.tgz#414cf5af790a48c60ab9be4527d56d5e41133cb1" @@ -8699,42 +10427,136 @@ concat-stream@^2.0.0: readable-stream "^3.0.2" typedarray "^0.0.6" -confusing-browser-globals@^1.0.9: - version "1.0.11" - resolved "https://registry.yarnpkg.com/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz#ae40e9b57cdd3915408a2805ebd3a5585608dc81" - integrity sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA== +consola@^3.2.3: + version "3.2.3" + resolved "https://registry.yarnpkg.com/consola/-/consola-3.2.3.tgz#0741857aa88cfa0d6fd53f1cff0375136e98502f" + integrity sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ== -console-browserify@^1.1.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.2.0.tgz#67063cef57ceb6cf4993a2ab3a55840ae8c49336" - integrity sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA== +constants-browserify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" + integrity sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ== -console-control-strings@^1.0.0, console-control-strings@^1.1.0, console-control-strings@~1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" - integrity sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ== +content-disposition@0.5.4: + version "0.5.4" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" + integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== + dependencies: + safe-buffer "5.2.1" + +content-type@~1.0.4, content-type@~1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918" + integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== + +conventional-changelog-angular@^5.0.12, conventional-changelog-angular@^5.0.13: + version "5.0.13" + resolved "https://registry.yarnpkg.com/conventional-changelog-angular/-/conventional-changelog-angular-5.0.13.tgz#896885d63b914a70d4934b59d2fe7bde1832b28c" + integrity sha512-i/gipMxs7s8L/QeuavPF2hLnJgH6pEZAttySB6aiQLWcX3puWDL3ACVmvBhJGxnAy52Qc15ua26BufY6KpmrVA== + dependencies: + compare-func "^2.0.0" + q "^1.5.1" + +conventional-changelog-angular@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/conventional-changelog-angular/-/conventional-changelog-angular-7.0.0.tgz#5eec8edbff15aa9b1680a8dcfbd53e2d7eb2ba7a" + integrity sha512-ROjNchA9LgfNMTTFSIWPzebCwOGFdgkEq45EnvvrmSLvCtAw0HSmrCs7/ty+wAeYUZyNay0YMUNYFTRL72PkBQ== + dependencies: + compare-func "^2.0.0" + +conventional-changelog-atom@^2.0.8: + version "2.0.8" + resolved "https://registry.yarnpkg.com/conventional-changelog-atom/-/conventional-changelog-atom-2.0.8.tgz#a759ec61c22d1c1196925fca88fe3ae89fd7d8de" + integrity sha512-xo6v46icsFTK3bb7dY/8m2qvc8sZemRgdqLb/bjpBsH2UyOS8rKNTgcb5025Hri6IpANPApbXMg15QLb1LJpBw== + dependencies: + q "^1.5.1" + +conventional-changelog-cli@^2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/conventional-changelog-cli/-/conventional-changelog-cli-2.2.2.tgz#9a7746cede92c6a8f27dc46692efaadfbed60daa" + integrity sha512-8grMV5Jo8S0kP3yoMeJxV2P5R6VJOqK72IiSV9t/4H5r/HiRqEBQ83bYGuz4Yzfdj4bjaAEhZN/FFbsFXr5bOA== + dependencies: + add-stream "^1.0.0" + conventional-changelog "^3.1.24" + lodash "^4.17.15" + meow "^8.0.0" + tempfile "^3.0.0" + +conventional-changelog-codemirror@^2.0.8: + version "2.0.8" + resolved "https://registry.yarnpkg.com/conventional-changelog-codemirror/-/conventional-changelog-codemirror-2.0.8.tgz#398e9530f08ce34ec4640af98eeaf3022eb1f7dc" + integrity sha512-z5DAsn3uj1Vfp7po3gpt2Boc+Bdwmw2++ZHa5Ak9k0UKsYAO5mH1UBTN0qSCuJZREIhX6WU4E1p3IW2oRCNzQw== + dependencies: + q "^1.5.1" + +conventional-changelog-conventionalcommits@^4.5.0: + version "4.6.3" + resolved "https://registry.yarnpkg.com/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-4.6.3.tgz#0765490f56424b46f6cb4db9135902d6e5a36dc2" + integrity sha512-LTTQV4fwOM4oLPad317V/QNQ1FY4Hju5qeBIM1uTHbrnCE+Eg4CdRZ3gO2pUeR+tzWdp80M2j3qFFEDWVqOV4g== + dependencies: + compare-func "^2.0.0" + lodash "^4.17.15" + q "^1.5.1" + +conventional-changelog-conventionalcommits@^7.0.2: + version "7.0.2" + resolved "https://registry.yarnpkg.com/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-7.0.2.tgz#aa5da0f1b2543094889e8cf7616ebe1a8f5c70d5" + integrity sha512-NKXYmMR/Hr1DevQegFB4MwfM5Vv0m4UIxKZTTYuD98lpTknaZlSRrDOG4X7wIXpGkfsYxZTghUN+Qq+T0YQI7w== + dependencies: + compare-func "^2.0.0" + +conventional-changelog-core@^4.2.1: + version "4.2.4" + resolved "https://registry.yarnpkg.com/conventional-changelog-core/-/conventional-changelog-core-4.2.4.tgz#e50d047e8ebacf63fac3dc67bf918177001e1e9f" + integrity sha512-gDVS+zVJHE2v4SLc6B0sLsPiloR0ygU7HaDW14aNJE1v4SlqJPILPl/aJC7YdtRE4CybBf8gDwObBvKha8Xlyg== + dependencies: + add-stream "^1.0.0" + conventional-changelog-writer "^5.0.0" + conventional-commits-parser "^3.2.0" + dateformat "^3.0.0" + get-pkg-repo "^4.0.0" + git-raw-commits "^2.0.8" + git-remote-origin-url "^2.0.0" + git-semver-tags "^4.1.1" + lodash "^4.17.15" + normalize-package-data "^3.0.0" + q "^1.5.1" + read-pkg "^3.0.0" + read-pkg-up "^3.0.0" + through2 "^4.0.0" + +conventional-changelog-ember@^2.0.9: + version "2.0.9" + resolved "https://registry.yarnpkg.com/conventional-changelog-ember/-/conventional-changelog-ember-2.0.9.tgz#619b37ec708be9e74a220f4dcf79212ae1c92962" + integrity sha512-ulzIReoZEvZCBDhcNYfDIsLTHzYHc7awh+eI44ZtV5cx6LVxLlVtEmcO+2/kGIHGtw+qVabJYjdI5cJOQgXh1A== + dependencies: + q "^1.5.1" -constants-browserify@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" - integrity sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ== +conventional-changelog-eslint@^3.0.9: + version "3.0.9" + resolved "https://registry.yarnpkg.com/conventional-changelog-eslint/-/conventional-changelog-eslint-3.0.9.tgz#689bd0a470e02f7baafe21a495880deea18b7cdb" + integrity sha512-6NpUCMgU8qmWmyAMSZO5NrRd7rTgErjrm4VASam2u5jrZS0n38V7Y9CzTtLT2qwz5xEChDR4BduoWIr8TfwvXA== + dependencies: + q "^1.5.1" -content-disposition@0.5.4: - version "0.5.4" - resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" - integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== +conventional-changelog-express@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/conventional-changelog-express/-/conventional-changelog-express-2.0.6.tgz#420c9d92a347b72a91544750bffa9387665a6ee8" + integrity sha512-SDez2f3iVJw6V563O3pRtNwXtQaSmEfTCaTBPCqn0oG0mfkq0rX4hHBq5P7De2MncoRixrALj3u3oQsNK+Q0pQ== dependencies: - safe-buffer "5.2.1" + q "^1.5.1" -content-type@~1.0.4: - version "1.0.5" - resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918" - integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== +conventional-changelog-jquery@^3.0.11: + version "3.0.11" + resolved "https://registry.yarnpkg.com/conventional-changelog-jquery/-/conventional-changelog-jquery-3.0.11.tgz#d142207400f51c9e5bb588596598e24bba8994bf" + integrity sha512-x8AWz5/Td55F7+o/9LQ6cQIPwrCjfJQ5Zmfqi8thwUEKHstEn4kTIofXub7plf1xvFA2TqhZlq7fy5OmV6BOMw== + dependencies: + q "^1.5.1" -conventional-changelog-angular@^5.0.13: - version "5.0.13" - resolved "https://registry.yarnpkg.com/conventional-changelog-angular/-/conventional-changelog-angular-5.0.13.tgz#896885d63b914a70d4934b59d2fe7bde1832b28c" - integrity sha512-i/gipMxs7s8L/QeuavPF2hLnJgH6pEZAttySB6aiQLWcX3puWDL3ACVmvBhJGxnAy52Qc15ua26BufY6KpmrVA== +conventional-changelog-jshint@^2.0.9: + version "2.0.9" + resolved "https://registry.yarnpkg.com/conventional-changelog-jshint/-/conventional-changelog-jshint-2.0.9.tgz#f2d7f23e6acd4927a238555d92c09b50fe3852ff" + integrity sha512-wMLdaIzq6TNnMHMy31hql02OEQ8nCQfExw1SE0hYL5KvU+JCTuPaDO+7JiogGT2gJAxiUGATdtYYfh+nT+6riA== dependencies: compare-func "^2.0.0" q "^1.5.1" @@ -8744,6 +10566,38 @@ conventional-changelog-preset-loader@^2.3.4: resolved "https://registry.yarnpkg.com/conventional-changelog-preset-loader/-/conventional-changelog-preset-loader-2.3.4.tgz#14a855abbffd59027fd602581f1f34d9862ea44c" integrity sha512-GEKRWkrSAZeTq5+YjUZOYxdHq+ci4dNwHvpaBC3+ENalzFWuCWa9EZXSuZBpkr72sMdKB+1fyDV4takK1Lf58g== +conventional-changelog-writer@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/conventional-changelog-writer/-/conventional-changelog-writer-5.0.1.tgz#e0757072f045fe03d91da6343c843029e702f359" + integrity sha512-5WsuKUfxW7suLblAbFnxAcrvf6r+0b7GvNaWUwUIk0bXMnENP/PEieGKVUQrjPqwPT4o3EPAASBXiY6iHooLOQ== + dependencies: + conventional-commits-filter "^2.0.7" + dateformat "^3.0.0" + handlebars "^4.7.7" + json-stringify-safe "^5.0.1" + lodash "^4.17.15" + meow "^8.0.0" + semver "^6.0.0" + split "^1.0.0" + through2 "^4.0.0" + +conventional-changelog@^3.1.24: + version "3.1.25" + resolved "https://registry.yarnpkg.com/conventional-changelog/-/conventional-changelog-3.1.25.tgz#3e227a37d15684f5aa1fb52222a6e9e2536ccaff" + integrity sha512-ryhi3fd1mKf3fSjbLXOfK2D06YwKNic1nC9mWqybBHdObPd8KJ2vjaXZfYj1U23t+V8T8n0d7gwnc9XbIdFbyQ== + dependencies: + conventional-changelog-angular "^5.0.12" + conventional-changelog-atom "^2.0.8" + conventional-changelog-codemirror "^2.0.8" + conventional-changelog-conventionalcommits "^4.5.0" + conventional-changelog-core "^4.2.1" + conventional-changelog-ember "^2.0.9" + conventional-changelog-eslint "^3.0.9" + conventional-changelog-express "^2.0.6" + conventional-changelog-jquery "^3.0.11" + conventional-changelog-jshint "^2.0.9" + conventional-changelog-preset-loader "^2.3.4" + conventional-commits-filter@^2.0.7: version "2.0.7" resolved "https://registry.yarnpkg.com/conventional-commits-filter/-/conventional-commits-filter-2.0.7.tgz#f8d9b4f182fce00c9af7139da49365b136c8a0b3" @@ -8752,7 +10606,7 @@ conventional-commits-filter@^2.0.7: lodash.ismatch "^4.4.0" modify-values "^1.0.0" -conventional-commits-parser@^3.2.0: +conventional-commits-parser@^3.2.0, conventional-commits-parser@^3.2.4: version "3.2.4" resolved "https://registry.yarnpkg.com/conventional-commits-parser/-/conventional-commits-parser-3.2.4.tgz#a7d3b77758a202a9b2293d2112a8d8052c740972" integrity sha512-nK7sAtfi+QXbxHCYfhpZsfRtaitZLIA6889kFIouLvz6repszQDgxBu7wf2WbU+Dco7sAnNCJYERCwt54WPC2Q== @@ -8764,6 +10618,16 @@ conventional-commits-parser@^3.2.0: split2 "^3.0.0" through2 "^4.0.0" +conventional-commits-parser@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/conventional-commits-parser/-/conventional-commits-parser-5.0.0.tgz#57f3594b81ad54d40c1b4280f04554df28627d9a" + integrity sha512-ZPMl0ZJbw74iS9LuX9YIAiW8pfM5p3yh2o/NbXHbkFuZzY5jvdi5jFycEOkmBW5H5I7nA+D6f3UcsCLP2vvSEA== + dependencies: + JSONStream "^1.3.5" + is-text-path "^2.0.0" + meow "^12.0.1" + split2 "^4.0.0" + conventional-recommended-bump@^6.1.0: version "6.1.0" resolved "https://registry.yarnpkg.com/conventional-recommended-bump/-/conventional-recommended-bump-6.1.0.tgz#cfa623285d1de554012f2ffde70d9c8a22231f55" @@ -8778,87 +10642,74 @@ conventional-recommended-bump@^6.1.0: meow "^8.0.0" q "^1.5.1" -convert-hrtime@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/convert-hrtime/-/convert-hrtime-3.0.0.tgz#62c7593f5809ca10be8da858a6d2f702bcda00aa" - integrity sha512-7V+KqSvMiHp8yWDuwfww06XleMWVVB9b9tURBx+G7UTADuo5hYPuowKloz4OzOqbPezxgo+fdQ1522WzPG4OeA== - -convert-source-map@^1.4.0, convert-source-map@^1.5.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0: +convert-source-map@^1.5.0: version "1.9.0" resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.9.0.tgz#7faae62353fb4213366d0ca98358d22e8368b05f" integrity sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A== +convert-source-map@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-2.0.0.tgz#4b560f649fc4e918dd0ab75cf4961e8bc882d82a" + integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg== + +cookie-es@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/cookie-es/-/cookie-es-1.0.0.tgz#4759684af168dfc54365b2c2dda0a8d7ee1e4865" + integrity sha512-mWYvfOLrfEc996hlKcdABeIiPHUPC6DM2QYZdGGOvhOTbA3tjm2eBwqlJpoFdjC89NI4Qt6h0Pu06Mp+1Pj5OQ== + cookie-signature@1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== -cookie@0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b" - integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== - -cookie@^0.4.1: - version "0.4.2" - resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.2.tgz#0e41f24de5ecf317947c82fc789e06a884824432" - integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA== - -copy-concurrently@^1.0.0: - version "1.0.5" - resolved "https://registry.yarnpkg.com/copy-concurrently/-/copy-concurrently-1.0.5.tgz#92297398cae34937fcafd6ec8139c18051f0b5e0" - integrity sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A== - dependencies: - aproba "^1.1.1" - fs-write-stream-atomic "^1.0.8" - iferr "^0.1.5" - mkdirp "^0.5.1" - rimraf "^2.5.4" - run-queue "^1.0.0" - -copy-descriptor@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" - integrity sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw== +cookie@0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.6.0.tgz#2798b04b071b0ecbff0dbb62a505a8efa4e19051" + integrity sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw== -copy-to-clipboard@^3.3.1, copy-to-clipboard@^3.3.3: +copy-to-clipboard@^3.3.3: version "3.3.3" resolved "https://registry.yarnpkg.com/copy-to-clipboard/-/copy-to-clipboard-3.3.3.tgz#55ac43a1db8ae639a4bd99511c148cdd1b83a1b0" integrity sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA== dependencies: toggle-selection "^1.0.6" -core-js-compat@^3.25.1, core-js-compat@^3.8.1: - version "3.30.0" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.30.0.tgz#99aa2789f6ed2debfa1df3232784126ee97f4d80" - integrity sha512-P5A2h/9mRYZFIAP+5Ab8ns6083IyVpSclU74UNvbGVQ8VM7n3n3/g2yF3AkKQ9NXz2O+ioxLbEWKnDtgsFamhg== +core-js-compat@^3.31.0, core-js-compat@^3.33.1: + version "3.33.3" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.33.3.tgz#ec678b772c5a2d8a7c60a91c3a81869aa704ae01" + integrity sha512-cNzGqFsh3Ot+529GIXacjTJ7kegdt5fPXxCBVS1G0iaZpuo/tBz399ymceLJveQhFFZ8qThHiP3fzuoQjKN2ow== dependencies: - browserslist "^4.21.5" + browserslist "^4.22.1" -core-js-pure@^3.23.3: - version "3.30.0" - resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.30.0.tgz#41b6c42e5f363bd53d79999bd35093b17e42e1bf" - integrity sha512-+2KbMFGeBU0ln/csoPqTe0i/yfHbrd2EUhNMObsGtXMKS/RTtlkYyi+/3twLcevbgNR0yM/r0Psa3TEoQRpFMQ== +core-js-compat@^3.36.1: + version "3.36.1" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.36.1.tgz#1818695d72c99c25d621dca94e6883e190cea3c8" + integrity sha512-Dk997v9ZCt3X/npqzyGdTlq6t7lDBhZwGvV94PKzDArjp7BTRm7WlDAXYd/OWdeFHO8OChQYRJNJvUCqCbrtKA== + dependencies: + browserslist "^4.23.0" core-js@^1.0.0: version "1.2.7" resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636" integrity sha512-ZiPp9pZlgxpWRu0M+YWbm6+aQ84XEfH1JRXvfOc/fILWI0VKhLC2LX13X1NYq4fULzLMq7Hfh43CSo2/aIaUPA== -core-js@^3.0.1, core-js@^3.0.4, core-js@^3.6.5, core-js@^3.8.2: - version "3.30.0" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.30.0.tgz#64ac6f83bc7a49fd42807327051701d4b1478dea" - integrity sha512-hQotSSARoNh1mYPi9O2YaWeiq/cEB95kOrFb4NCrO4RIFt1qqNpKsaE+vy/L3oiqvND5cThqXzUU3r9F7Efztg== - -core-util-is@1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" - integrity sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ== +core-js@^3.0.1: + version "3.33.3" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.33.3.tgz#3c644a323f0f533a0d360e9191e37f7fc059088d" + integrity sha512-lo0kOocUlLKmm6kv/FswQL8zbkH7mVsLJ/FULClOhv8WRVmKLVcs6XPNQAzstfeJTCHMyButEwG+z1kHxHoDZw== core-util-is@~1.0.0: version "1.0.3" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== +cosmiconfig-typescript-loader@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-5.0.0.tgz#0d3becfe022a871f7275ceb2397d692e06045dc8" + integrity sha512-+8cK7jRAReYkMwMiG+bxhcNKiHJDM6bR9FD/nGBXOWdMLuYawjF5cGrtLilJ+LGd3ZjCXnJjR5DkfWPoIVlqJA== + dependencies: + jiti "^1.19.1" + cosmiconfig@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-6.0.0.tgz#da4fee853c52f6b1e6935f41c1a2fc50bd4a9982" @@ -8881,6 +10732,16 @@ cosmiconfig@^7.0.0, cosmiconfig@^7.0.1: path-type "^4.0.0" yaml "^1.10.0" +cosmiconfig@^8.0.0, cosmiconfig@^8.1.3, cosmiconfig@^8.3.6: + version "8.3.6" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-8.3.6.tgz#060a2b871d66dba6c8538ea1118ba1ac16f5fae3" + integrity sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA== + dependencies: + import-fresh "^3.3.0" + js-yaml "^4.1.0" + parse-json "^5.2.0" + path-type "^4.0.0" + cosmjs-types@^0.5.2: version "0.5.2" resolved "https://registry.yarnpkg.com/cosmjs-types/-/cosmjs-types-0.5.2.tgz#2d42b354946f330dfb5c90a87fdc2a36f97b965d" @@ -8889,30 +10750,21 @@ cosmjs-types@^0.5.2: long "^4.0.0" protobufjs "~6.11.2" -cp-file@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/cp-file/-/cp-file-7.0.0.tgz#b9454cfd07fe3b974ab9ea0e5f29655791a9b8cd" - integrity sha512-0Cbj7gyvFVApzpK/uhCtQ/9kE9UnYpxMzaq5nQQC/Dh4iaj5fxp7iEFIullrYwzj8nf0qnsI1Qsx34hAeAebvw== +cosmjs-types@^0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/cosmjs-types/-/cosmjs-types-0.8.0.tgz#2ed78f3e990f770229726f95f3ef5bf9e2b6859b" + integrity sha512-Q2Mj95Fl0PYMWEhA2LuGEIhipF7mQwd9gTQ85DdP9jjjopeoGaDxvmPa5nakNzsq7FnO1DMTatXTAx6bxMH7Lg== dependencies: - graceful-fs "^4.1.2" - make-dir "^3.0.0" - nested-error-stacks "^2.0.0" - p-event "^4.1.0" + long "^4.0.0" + protobufjs "~6.11.2" -cpy@^8.1.2: - version "8.1.2" - resolved "https://registry.yarnpkg.com/cpy/-/cpy-8.1.2.tgz#e339ea54797ad23f8e3919a5cffd37bfc3f25935" - integrity sha512-dmC4mUesv0OYH2kNFEidtf/skUwv4zePmGeepjyyJ0qTo5+8KhA1o99oIAwVVLzQMAeDJml74d6wPPKb6EZUTg== - dependencies: - arrify "^2.0.1" - cp-file "^7.0.0" - globby "^9.2.0" - has-glob "^1.0.0" - junk "^3.1.0" - nested-error-stacks "^2.1.0" - p-all "^2.1.0" - p-filter "^2.1.0" - p-map "^3.0.0" +cosmos-wallet@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/cosmos-wallet/-/cosmos-wallet-1.2.0.tgz#1243066fe933cf5482de1aec0b96169cebe867c6" + integrity sha512-lMEpNhjN6FHU6c8l/lYi1hWU/74bOlTmo3pz0mwVpCHjNSe5u7sZCO7j0dndd3oV0tM8tj/u3eJa4NgZxG9a0Q== + dependencies: + "@cosmjs/amino" "^0.25.4" + "@cosmjs/proto-signing" "^0.25.4" create-ecdh@^4.0.0: version "4.0.4" @@ -8953,19 +10805,14 @@ create-react-context@0.3.0: gud "^1.0.0" warning "^4.0.3" -create-require@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" - integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== - -cross-fetch@3.1.5, cross-fetch@^3.1.4: - version "3.1.5" - resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.5.tgz#e1389f44d9e7ba767907f7af8454787952ab534f" - integrity sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw== +cross-fetch@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-4.0.0.tgz#f037aef1580bb3a1a35164ea2a848ba81b445983" + integrity sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g== dependencies: - node-fetch "2.6.7" + node-fetch "^2.6.12" -cross-spawn@^6.0.0, cross-spawn@^6.0.5: +cross-spawn@^6.0.5: version "6.0.5" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== @@ -8976,7 +10823,7 @@ cross-spawn@^6.0.0, cross-spawn@^6.0.5: shebang-command "^1.2.0" which "^1.2.9" -cross-spawn@^7.0.0, cross-spawn@^7.0.3: +cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3: version "7.0.3" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== @@ -8990,7 +10837,7 @@ crypt@~0.0.1: resolved "https://registry.yarnpkg.com/crypt/-/crypt-0.0.2.tgz#88d7ff7ec0dfb86f713dc87bbb42d044d3e6c41b" integrity sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow== -crypto-browserify@^3.11.0, crypto-browserify@^3.12.0: +crypto-browserify@^3.12.0: version "3.12.0" resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" integrity sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg== @@ -9007,34 +10854,29 @@ crypto-browserify@^3.11.0, crypto-browserify@^3.12.0: randombytes "^2.0.0" randomfill "^1.0.3" -crypto-js@^3.1.9-1: - version "3.3.0" - resolved "https://registry.yarnpkg.com/crypto-js/-/crypto-js-3.3.0.tgz#846dd1cce2f68aacfa156c8578f926a609b7976b" - integrity sha512-DIT51nX0dCfKltpRiXV+/TVZq+Qq2NgF4644+K7Ttnla7zEzqc+kjJyiB96BHNyUTBxyjzRcZYpUdZa+QAqi6Q== +crypto-js@4.2.0, crypto-js@^4.0.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/crypto-js/-/crypto-js-4.2.0.tgz#4d931639ecdfd12ff80e8186dba6af2c2e856631" + integrity sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q== -crypto-js@^4.0.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/crypto-js/-/crypto-js-4.1.1.tgz#9e485bcf03521041bd85844786b83fb7619736cf" - integrity sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw== +crypto-random-string@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-2.0.0.tgz#ef2a7a966ec11083388369baa02ebead229b30d5" + integrity sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA== -css-loader@^3.6.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-3.6.0.tgz#2e4b2c7e6e2d27f8c8f28f61bffcd2e6c91ef645" - integrity sha512-M5lSukoWi1If8dhQAUCvj4H8vUt3vOnwbQBH9DdTm/s4Ym2B/3dPMtYZeJmq7Q3S3Pa+I94DcZ7pc9bP14cWIQ== +css-loader@^6.7.1: + version "6.8.1" + resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-6.8.1.tgz#0f8f52699f60f5e679eab4ec0fcd68b8e8a50a88" + integrity sha512-xDAXtEVGlD0gJ07iclwWVkLoZOpEvAWaSyf6W18S2pOC//K8+qUDIx8IIT3D+HjnmkJPQeesOPv5aiUaJsCM2g== dependencies: - camelcase "^5.3.1" - cssesc "^3.0.0" - icss-utils "^4.1.1" - loader-utils "^1.2.3" - normalize-path "^3.0.0" - postcss "^7.0.32" - postcss-modules-extract-imports "^2.0.0" - postcss-modules-local-by-default "^3.0.2" - postcss-modules-scope "^2.2.0" - postcss-modules-values "^3.0.0" - postcss-value-parser "^4.1.0" - schema-utils "^2.7.0" - semver "^6.3.0" + icss-utils "^5.1.0" + postcss "^8.4.21" + postcss-modules-extract-imports "^3.0.0" + postcss-modules-local-by-default "^4.0.3" + postcss-modules-scope "^3.0.0" + postcss-modules-values "^4.0.0" + postcss-value-parser "^4.2.0" + semver "^7.3.8" css-select@^4.1.3: version "4.3.0" @@ -9047,6 +10889,17 @@ css-select@^4.1.3: domutils "^2.8.0" nth-check "^2.0.1" +css-select@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/css-select/-/css-select-5.1.0.tgz#b8ebd6554c3637ccc76688804ad3f6a6fdaea8a6" + integrity sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg== + dependencies: + boolbase "^1.0.0" + css-what "^6.1.0" + domhandler "^5.0.2" + domutils "^3.0.1" + nth-check "^2.0.1" + css-tree@^1.1.2, css-tree@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.1.3.tgz#eb4870fb6fd7707327ec95c2ff2ab09b5e8db91d" @@ -9055,12 +10908,23 @@ css-tree@^1.1.2, css-tree@^1.1.3: mdn-data "2.0.14" source-map "^0.6.1" -css-what@^5.0.1: - version "5.1.0" - resolved "https://registry.yarnpkg.com/css-what/-/css-what-5.1.0.tgz#3f7b707aadf633baf62c2ceb8579b545bb40f7fe" - integrity sha512-arSMRWIIFY0hV8pIxZMEfmMI47Wj3R/aWpZDDxWYCPEiOMv6tfOrnpDtgxBYPEQD4V0Y/958+1TdC3iWTFcUPw== +css-tree@^2.2.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-2.3.1.tgz#10264ce1e5442e8572fc82fbe490644ff54b5c20" + integrity sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw== + dependencies: + mdn-data "2.0.30" + source-map-js "^1.0.1" -css-what@^6.0.1: +css-tree@~2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-2.2.1.tgz#36115d382d60afd271e377f9c5f67d02bd48c032" + integrity sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA== + dependencies: + mdn-data "2.0.28" + source-map-js "^1.0.1" + +css-what@^6.0.1, css-what@^6.1.0: version "6.1.0" resolved "https://registry.yarnpkg.com/css-what/-/css-what-6.1.0.tgz#fb5effcf76f1ddea2c81bdfaa4de44e79bac70f4" integrity sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw== @@ -9070,6 +10934,13 @@ cssesc@^3.0.0: resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== +csso@5.0.5: + version "5.0.5" + resolved "https://registry.yarnpkg.com/csso/-/csso-5.0.5.tgz#f9b7fe6cc6ac0b7d90781bb16d5e9874303e2ca6" + integrity sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ== + dependencies: + css-tree "~2.2.0" + csso@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/csso/-/csso-4.2.0.tgz#ea3a561346e8dc9f546d6febedd50187cf389529" @@ -9077,122 +10948,159 @@ csso@^4.2.0: dependencies: css-tree "^1.1.2" -cssom@^0.4.1: - version "0.4.4" - resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.4.4.tgz#5a66cf93d2d0b661d80bf6a44fb65f5c2e4e0a10" - integrity sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw== - -cssom@~0.3.6: - version "0.3.8" - resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.8.tgz#9f1276f5b2b463f2114d3f2c75250af8c1a36f4a" - integrity sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg== - -cssstyle@^2.0.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-2.3.0.tgz#ff665a0ddbdc31864b09647f34163443d90b0852" - integrity sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A== - dependencies: - cssom "~0.3.6" - csstype@^2.5.7: version "2.6.21" resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.21.tgz#2efb85b7cc55c80017c66a5ad7cbd931fda3a90e" integrity sha512-Z1PhmomIfypOpoMjRQB70jfvy/wxT50qW08YXO5lMIJkrdq4yOTR+AW7FqutScmB9NkLwxo+jU+kZLbofZZq/w== -csstype@^3.0.2, csstype@^3.0.7: +csstype@^3.0.2: version "3.1.2" resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.2.tgz#1d4bf9d572f11c14031f0436e1c10bc1f571f50b" integrity sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ== -currently-unhandled@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" - integrity sha512-/fITjgjGU50vjQ4FH6eUoYu+iUoUKIXws2hL15JJpIR+BbTxaXQsMuuyjtNh2WqsSBS5nsaZHFsFecyw5CCAng== - dependencies: - array-find-index "^1.0.1" - curve25519-js@0.0.4: version "0.0.4" resolved "https://registry.yarnpkg.com/curve25519-js/-/curve25519-js-0.0.4.tgz#e6ad967e8cd284590d657bbfc90d8b50e49ba060" integrity sha512-axn2UMEnkhyDUPWOwVKBMVIzSQy2ejH2xRGy1wq81dqRwApXfIzfbE3hIX0ZRFBIihf/KDqK158DLwESu4AK1w== -cyclist@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-1.0.1.tgz#596e9698fd0c80e12038c2b82d6eb1b35b6224d9" - integrity sha512-NJGVKPS81XejHcLhaLJS7plab0fK3slPh11mESeeDq2W4ZI5kUKK/LRRdVDvjJseojbPB7ZwjnyOybg3Igea/A== +d3-array@2, d3-array@^2.3.0: + version "2.12.1" + resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-2.12.1.tgz#e20b41aafcdffdf5d50928004ececf815a465e81" + integrity sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ== + dependencies: + internmap "^1.0.0" -damerau-levenshtein@^1.0.8: - version "1.0.8" - resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz#b43d286ccbd36bc5b2f7ed41caf2d0aba1f8a6e7" - integrity sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA== +d3-color@1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/d3-color/-/d3-color-1.4.1.tgz#c52002bf8846ada4424d55d97982fef26eb3bc8a" + integrity sha512-p2sTHSLCJI2QKunbGb7ocOh7DgTAn8IrLx21QRc/BSnodXM4sv6aLQlnfpvehFMLZEfBc6g9pH9SWQccFYfJ9Q== + +"d3-color@1 - 2": + version "2.0.0" + resolved "https://registry.yarnpkg.com/d3-color/-/d3-color-2.0.0.tgz#8d625cab42ed9b8f601a1760a389f7ea9189d62e" + integrity sha512-SPXi0TSKPD4g9tw0NMZFnR95XVgUZiBH+uUTqQuDu1OsE2zomHU7ho0FISciaPvosimixwHFl3WHLGabv6dDgQ== + +"d3-format@1 - 2": + version "2.0.0" + resolved "https://registry.yarnpkg.com/d3-format/-/d3-format-2.0.0.tgz#a10bcc0f986c372b729ba447382413aabf5b0767" + integrity sha512-Ab3S6XuE/Q+flY96HXT0jOXcM4EAClYFnRGY5zsjRGNy6qCYrQsMffs7cV5Q9xejb35zxW5hf/guKw34kvIKsA== + +"d3-interpolate@1.2.0 - 2": + version "2.0.1" + resolved "https://registry.yarnpkg.com/d3-interpolate/-/d3-interpolate-2.0.1.tgz#98be499cfb8a3b94d4ff616900501a64abc91163" + integrity sha512-c5UhwwTs/yybcmTpAVqwSFl6vrQ8JZJoT5F7xNFK9pymv5C0Ymcc9/LIJHtYIggg/yS9YHw8i8O8tgb9pupjeQ== + dependencies: + d3-color "1 - 2" + +d3-interpolate@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/d3-interpolate/-/d3-interpolate-1.4.0.tgz#526e79e2d80daa383f9e0c1c1c7dcc0f0583e987" + integrity sha512-V9znK0zc3jOPV4VD2zZn0sDhZU3WAE2bmlxdIwwQPPzPjvyLkd8B3JUVdS1IDUFDkWZ72c9qnv1GK2ZagTZ8EA== + dependencies: + d3-color "1" + +d3-path@1, d3-path@^1.0.5: + version "1.0.9" + resolved "https://registry.yarnpkg.com/d3-path/-/d3-path-1.0.9.tgz#48c050bb1fe8c262493a8caf5524e3e9591701cf" + integrity sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg== + +d3-scale@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/d3-scale/-/d3-scale-3.3.0.tgz#28c600b29f47e5b9cd2df9749c206727966203f3" + integrity sha512-1JGp44NQCt5d1g+Yy+GeOnZP7xHo0ii8zsQp6PGzd+C1/dl0KGsp9A7Mxwp+1D1o4unbTTxVdU/ZOIEBoeZPbQ== + dependencies: + d3-array "^2.3.0" + d3-format "1 - 2" + d3-interpolate "1.2.0 - 2" + d3-time "^2.1.1" + d3-time-format "2 - 3" + +d3-shape@^1.0.6, d3-shape@^1.2.0: + version "1.3.7" + resolved "https://registry.yarnpkg.com/d3-shape/-/d3-shape-1.3.7.tgz#df63801be07bc986bc54f63789b4fe502992b5d7" + integrity sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw== + dependencies: + d3-path "1" + +"d3-time-format@2 - 3": + version "3.0.0" + resolved "https://registry.yarnpkg.com/d3-time-format/-/d3-time-format-3.0.0.tgz#df8056c83659e01f20ac5da5fdeae7c08d5f1bb6" + integrity sha512-UXJh6EKsHBTjopVqZBhFysQcoXSv/5yLONZvkQ5Kk3qbwiUYkdX17Xa1PT6U1ZWXGGfB1ey5L8dKMlFq2DO0Ag== + dependencies: + d3-time "1 - 2" + +"d3-time@1 - 2", d3-time@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/d3-time/-/d3-time-2.1.1.tgz#e9d8a8a88691f4548e68ca085e5ff956724a6682" + integrity sha512-/eIQe/eR4kCQwq7yxi7z4c6qEXf2IYGcjoWB5OOQy4Tq9Uv39/947qlDcN2TLkiTzQWzvnsuYPB9TrWaNfipKQ== + dependencies: + d3-array "2" dargs@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/dargs/-/dargs-7.0.0.tgz#04015c41de0bcb69ec84050f3d9be0caf8d6d5cc" integrity sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg== -dashdash@^1.12.0: - version "1.14.1" - resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" - integrity sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g== +dashify@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/dashify/-/dashify-2.0.0.tgz#fff270ca2868ca427fee571de35691d6e437a648" + integrity sha512-hpA5C/YrPjucXypHPPc0oJ1l9Hf6wWbiOL7Ik42cxnsUOhWiCB/fylKbKqqJalW9FgkNQCw16YO8uW9Hs0Iy1A== + +date-fns@^2.16.1, date-fns@^2.29.3: + version "2.30.0" + resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.30.0.tgz#f367e644839ff57894ec6ac480de40cae4b0f4d0" + integrity sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw== dependencies: - assert-plus "^1.0.0" + "@babel/runtime" "^7.21.0" -data-uri-to-buffer@3: - version "3.0.1" - resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-3.0.1.tgz#594b8973938c5bc2c33046535785341abc4f3636" - integrity sha512-WboRycPNsVw3B3TL559F7kuBUM4d8CgMEvk6xEJlOp7OBPjt6G7z8WMWlD2rOFZLk6OYfFIUGsCOWzcQH9K2og== +dateformat@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-3.0.3.tgz#a6e37499a4d9a9cf85ef5872044d62901c9889ae" + integrity sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q== -data-urls@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-1.1.0.tgz#15ee0582baa5e22bb59c77140da8f9c76963bbfe" - integrity sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ== - dependencies: - abab "^2.0.0" - whatwg-mimetype "^2.2.0" - whatwg-url "^7.0.0" +dayjs@^1.11.6: + version "1.11.13" + resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.13.tgz#92430b0139055c3ebb60150aa13e860a4b5a366c" + integrity sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg== dayjs@^1.11.7: - version "1.11.7" - resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.7.tgz#4b296922642f70999544d1144a2c25730fce63e2" - integrity sha512-+Yw9U6YO5TQohxLcIkrXBeY73WP3ejHWVvx8XCk3gxvQDCTEmS48ZrSZCKciI7Bhl/uCMyxYtE9UqRILmFphkQ== + version "1.11.10" + resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.10.tgz#68acea85317a6e164457d6d6947564029a6a16a0" + integrity sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ== -deasync@^0.1.0: - version "0.1.28" - resolved "https://registry.yarnpkg.com/deasync/-/deasync-0.1.28.tgz#9b447b79b3f822432f0ab6a8614c0062808b5ad2" - integrity sha512-QqLF6inIDwiATrfROIyQtwOQxjZuek13WRYZ7donU5wJPLoP67MnYxA6QtqdvdBy2mMqv5m3UefBVdJjvevOYg== - dependencies: - bindings "^1.5.0" - node-addon-api "^1.7.1" +debounce@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/debounce/-/debounce-1.2.1.tgz#38881d8f4166a5c5848020c11827b834bcb3e0a5" + integrity sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug== -debug@2.6.9, debug@^2.2.0, debug@^2.3.3: +debug@2.6.9: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== dependencies: ms "2.0.0" -debug@4, debug@^4.0.0, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.4: +debug@4, debug@4.3.4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== dependencies: ms "2.1.2" -debug@=3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" - integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== - dependencies: - ms "2.0.0" - -debug@^3.0.0, debug@^3.2.7: +debug@^3.2.7: version "3.2.7" resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== dependencies: ms "^2.1.1" +debug@^4.3.5: + version "4.3.6" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.6.tgz#2ab2c38fbaffebf8aa95fdfe6d88438c7a13c52b" + integrity sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg== + dependencies: + ms "2.1.2" + decamelize-keys@^1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/decamelize-keys/-/decamelize-keys-1.1.1.tgz#04a2d523b2f18d80d0158a43b895d56dff8d19d8" @@ -9201,105 +11109,65 @@ decamelize-keys@^1.1.0: decamelize "^1.1.0" map-obj "^1.0.0" -decamelize@^1.1.0, decamelize@^1.1.2, decamelize@^1.2.0: +decamelize@^1.1.0, decamelize@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" integrity sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA== -decode-named-character-reference@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz#daabac9690874c394c81e4162a0304b35d824f0e" - integrity sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg== - dependencies: - character-entities "^2.0.0" +decimal.js@^10.2.0, decimal.js@^10.2.1: + version "10.4.3" + resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.4.3.tgz#1044092884d245d1b7f65725fa4ad4c6f781cc23" + integrity sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA== -decode-uri-component@^0.2.0: +decode-uri-component@^0.2.0, decode-uri-component@^0.2.2: version "0.2.2" resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.2.tgz#e69dbe25d37941171dd540e024c444cd5188e1e9" integrity sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ== -decompress-response@^4.2.0: - version "4.2.1" - resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-4.2.1.tgz#414023cc7a302da25ce2ec82d0d5238ccafd8986" - integrity sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw== - dependencies: - mimic-response "^2.0.0" - -decompress-response@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc" - integrity sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ== - dependencies: - mimic-response "^3.1.0" - dedent@^0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" integrity sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA== -deep-equal@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.1.1.tgz#b5c98c942ceffaf7cb051e24e1434a25a2e6076a" - integrity sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g== - dependencies: - is-arguments "^1.0.4" - is-date-object "^1.0.1" - is-regex "^1.0.4" - object-is "^1.0.1" - object-keys "^1.1.1" - regexp.prototype.flags "^1.2.0" +deep-eql@^5.0.1: + version "5.0.2" + resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-5.0.2.tgz#4b756d8d770a9257300825d52a2c2cff99c3a341" + integrity sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q== -deep-equal@^2.0.5: - version "2.2.0" - resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-2.2.0.tgz#5caeace9c781028b9ff459f33b779346637c43e6" - integrity sha512-RdpzE0Hv4lhowpIUKKMJfeH6C1pXdtT1/it80ubgWqwI3qpuxUBpC1S4hnHg+zjnuOoDkzUtUCEEkG+XG5l3Mw== +deep-equal@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.1.2.tgz#78a561b7830eef3134c7f6f3a3d6af272a678761" + integrity sha512-5tdhKF6DbU7iIzrIOa1AOUt39ZRm13cmL1cGEh//aqR8x9+tNfbywRf0n5FD/18OKMdo7DNEtrX2t22ZAkI+eg== dependencies: - call-bind "^1.0.2" - es-get-iterator "^1.1.2" - get-intrinsic "^1.1.3" is-arguments "^1.1.1" - is-array-buffer "^3.0.1" is-date-object "^1.0.5" is-regex "^1.1.4" - is-shared-array-buffer "^1.0.2" - isarray "^2.0.5" object-is "^1.1.5" object-keys "^1.1.1" - object.assign "^4.1.4" - regexp.prototype.flags "^1.4.3" - side-channel "^1.0.4" - which-boxed-primitive "^1.0.2" - which-collection "^1.0.1" - which-typed-array "^1.1.9" + regexp.prototype.flags "^1.5.1" -deep-extend@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" - integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== - -deep-is@~0.1.3: +deep-is@^0.1.3: version "0.1.4" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== -deep-object-diff@^1.1.0, deep-object-diff@^1.1.9: +deep-object-diff@^1.1.0: version "1.1.9" resolved "https://registry.yarnpkg.com/deep-object-diff/-/deep-object-diff-1.1.9.tgz#6df7ef035ad6a0caa44479c536ed7b02570f4595" integrity sha512-Rn+RuwkmkDwCi2/oXOFS9Gsr5lJZu/yTGpK7wAaAIE75CC+LCGEZHpY6VQJa/RoJcrmaA/docWJZvYohlNkWPA== -deepmerge@^4.2.2: +deepmerge@^4.2.2, deepmerge@^4.3.1: version "4.3.1" resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.3.1.tgz#44b5f2147cd3b00d4b56137685966f26fd25dd4a" integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A== -default-browser-id@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/default-browser-id/-/default-browser-id-1.0.4.tgz#e59d09a5d157b828b876c26816e61c3d2a2c203a" - integrity sha512-qPy925qewwul9Hifs+3sx1ZYn14obHxpkX+mPD369w4Rzg+YkJBgi3SOvwUq81nWSjqGUegIgEPwD8u+HUnxlw== +default-browser-id@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/default-browser-id/-/default-browser-id-3.0.0.tgz#bee7bbbef1f4e75d31f98f4d3f1556a14cea790c" + integrity sha512-OZ1y3y0SqSICtE8DE4S8YOE9UZOJ8wO16fKWVP5J1Qz42kV9jcnMVFrEE/noXb/ss3Q4pZIH79kxofzyNNtUNA== dependencies: - bplist-parser "^0.1.0" - meow "^3.1.0" - untildify "^2.0.0" + bplist-parser "^0.2.0" + untildify "^4.0.0" defaults@^1.0.3: version "1.0.4" @@ -9308,55 +11176,56 @@ defaults@^1.0.3: dependencies: clone "^1.0.2" -defer-to-connect@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-2.0.1.tgz#8016bdb4143e4632b77a3449c6236277de520587" - integrity sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg== +define-data-property@^1.0.1, define-data-property@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.1.tgz#c35f7cd0ab09883480d12ac5cb213715587800b3" + integrity sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ== + dependencies: + get-intrinsic "^1.2.1" + gopd "^1.0.1" + has-property-descriptors "^1.0.0" + +define-data-property@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.4.tgz#894dc141bb7d3060ae4366f6a0107e68fbe48c5e" + integrity sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A== + dependencies: + es-define-property "^1.0.0" + es-errors "^1.3.0" + gopd "^1.0.1" define-lazy-prop@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f" integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og== -define-properties@^1.1.2, define-properties@^1.1.3, define-properties@^1.1.4: - version "1.2.0" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.2.0.tgz#52988570670c9eacedd8064f4a990f2405849bd5" - integrity sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA== +define-properties@^1.1.3, define-properties@^1.1.4, define-properties@^1.2.0, define-properties@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.2.1.tgz#10781cc616eb951a80a034bafcaa7377f6af2b6c" + integrity sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg== dependencies: + define-data-property "^1.0.1" has-property-descriptors "^1.0.0" object-keys "^1.1.1" -define-property@^0.2.5: - version "0.2.5" - resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" - integrity sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA== - dependencies: - is-descriptor "^0.1.0" - -define-property@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" - integrity sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA== - dependencies: - is-descriptor "^1.0.0" - -define-property@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" - integrity sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ== - dependencies: - is-descriptor "^1.0.2" - isobject "^3.0.1" +defu@^6.1.2, defu@^6.1.3: + version "6.1.3" + resolved "https://registry.yarnpkg.com/defu/-/defu-6.1.3.tgz#6d7f56bc61668e844f9f593ace66fd67ef1205fd" + integrity sha512-Vy2wmG3NTkmHNg/kzpuvHhkqeIx3ODWqasgCRbKtbXEN0G+HpEEv9BtJLp7ZG1CZloFaC41Ah3ZFbq7aqCqMeQ== -degenerator@^3.0.2: - version "3.0.3" - resolved "https://registry.yarnpkg.com/degenerator/-/degenerator-3.0.3.tgz#a081ac30052ca84e1d1c6e86c972ae8dabbc4079" - integrity sha512-FTq/qYMeBJACu1gHcXJvzsRBTK6aw5zWCYbEnIOyamOt5UJufWJRQ5XfDb6OuayfJWvmWAHgcZyt43vm/hbj7g== +del@^6.0.0: + version "6.1.1" + resolved "https://registry.yarnpkg.com/del/-/del-6.1.1.tgz#3b70314f1ec0aa325c6b14eb36b95786671edb7a" + integrity sha512-ua8BhapfP0JUJKC/zV9yHHDW/rDoDxP4Zhn3AkA6/xT6gY7jYXJiaeyBZznYVujhZZET+UgcbZiQ7sN3WqcImg== dependencies: - ast-types "^0.13.2" - escodegen "^1.8.1" - esprima "^4.0.0" - vm2 "^3.9.11" + globby "^11.0.1" + graceful-fs "^4.2.4" + is-glob "^4.0.1" + is-path-cwd "^2.2.0" + is-path-inside "^3.0.2" + p-map "^4.0.0" + rimraf "^3.0.2" + slash "^3.0.0" delay@^5.0.0: version "5.0.0" @@ -9373,47 +11242,50 @@ delegate@^3.1.2: resolved "https://registry.yarnpkg.com/delegate/-/delegate-3.2.0.tgz#b66b71c3158522e8ab5744f720d8ca0c2af59166" integrity sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw== -delegates@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" - integrity sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ== +denque@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/denque/-/denque-2.1.0.tgz#e93e1a6569fb5e66f16a3c2a2964617d349d6ab1" + integrity sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw== -depd@2.0.0, depd@^2.0.0: +depd@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== -dequal@^2.0.0: +dequal@^2.0.2, dequal@^2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/dequal/-/dequal-2.0.3.tgz#2644214f1997d39ed0ee0ece72335490a7ac67be" integrity sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA== des.js@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.1.tgz#5382142e1bdc53f85d86d53e5f4aa7deb91e0843" - integrity sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA== + version "1.1.0" + resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.1.0.tgz#1d37f5766f3bbff4ee9638e871a8768c173b81da" + integrity sha512-r17GxjhUCjSRy8aiJpr8/UadFIzMzJGexI3Nmz4ADi9LYSFx4gTBp80+NaX/YsXWWLhpZ7v/v/ubEc/bCNfKwg== dependencies: inherits "^2.0.1" minimalistic-assert "^1.0.0" +destr@^2.0.1, destr@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/destr/-/destr-2.0.2.tgz#8d3c0ee4ec0a76df54bc8b819bca215592a8c218" + integrity sha512-65AlobnZMiCET00KaFFjUefxDX0khFA/E4myqZ7a6Sq1yZtR8+FVIvilVX66vF2uobSumxooYZChiRPCKNqhmg== + destroy@1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== -detab@2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/detab/-/detab-2.0.4.tgz#b927892069aff405fbb9a186fe97a44a92a94b43" - integrity sha512-8zdsQA5bIkoRECvCrNKPla84lyoR7DSAyf7p0YgXzBO9PDJx8KntPUay7NS6yp+KdxdVtiE5SpHKtbp2ZQyA9g== - dependencies: - repeat-string "^1.5.4" - detect-browser@5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/detect-browser/-/detect-browser-5.2.0.tgz#c9cd5afa96a6a19fda0bbe9e9be48a6b6e1e9c97" integrity sha512-tr7XntDAu50BVENgQfajMLzacmSe34D+qZc4zjnniz0ZVuw/TZcLcyxHQjYpJTM36sGEkZZlYLnIM1hH7alTMA== -detect-indent@^6.0.0: +detect-browser@5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/detect-browser/-/detect-browser-5.3.0.tgz#9705ef2bddf46072d0f7265a1fe300e36fe7ceca" + integrity sha512-53rsFbGdwMwlF7qvCt0ypLM5V5/Mbl0szB7GPN8y9NCcbknYOeVVXdrXEq+90IwAfrrzt6Hd+u2E2ntakICU8w== + +detect-indent@^6.1.0: version "6.1.0" resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-6.1.0.tgz#592485ebbbf6b3b1ab2be175c8393d04ca0d57e6" integrity sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA== @@ -9423,15 +11295,10 @@ detect-libc@^1.0.3: resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" integrity sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg== -detect-libc@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.0.1.tgz#e1897aa88fa6ad197862937fbc0441ef352ee0cd" - integrity sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w== - -detect-newline@3.1.0, detect-newline@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" - integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA== +detect-libc@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.0.2.tgz#8ccf2ba9315350e1241b88d0ac3b0e1fbd99605d" + integrity sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw== detect-node-es@^1.1.0: version "1.1.0" @@ -9453,21 +11320,6 @@ detect-port@^1.3.0: address "^1.0.1" debug "4" -diff-sequences@^25.2.6: - version "25.2.6" - resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-25.2.6.tgz#5f467c00edd35352b7bca46d7927d60e687a76dd" - integrity sha512-Hq8o7+6GaZeoFjtpgvRBUknSXNeJiCx7V9Fr94ZMljNiCr9n9L8H8aJqgWOQiDDGdyn29fRNcDdRVJ5fdyihfg== - -diff@^4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" - integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== - -diff@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/diff/-/diff-5.1.0.tgz#bc52d298c5ea8df9194800224445ed43ffc87e40" - integrity sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw== - diffie-hellman@^5.0.0: version "5.0.3" resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875" @@ -9478,16 +11330,9 @@ diffie-hellman@^5.0.0: randombytes "^2.0.0" dijkstrajs@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/dijkstrajs/-/dijkstrajs-1.0.2.tgz#2e48c0d3b825462afe75ab4ad5e829c8ece36257" - integrity sha512-QV6PMaHTCNmKSeP6QoXhVTw9snc9VD8MulTT0Bd99Pacp4SS1cjcrYPgBPmibqKVtMJJfqC6XvOXgPMEEPH/fg== - -dir-glob@^2.2.2: - version "2.2.2" - resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-2.2.2.tgz#fa09f0694153c8918b18ba0deafae94769fc50c4" - integrity sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw== - dependencies: - path-type "^3.0.0" + version "1.0.3" + resolved "https://registry.yarnpkg.com/dijkstrajs/-/dijkstrajs-1.0.3.tgz#4c8dbdea1f0f6478bff94d9c49c784d623e4fc23" + integrity sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA== dir-glob@^3.0.1: version "3.0.1" @@ -9510,6 +11355,11 @@ doctrine@^3.0.0: dependencies: esutils "^2.0.2" +dom-accessibility-api@^0.5.9: + version "0.5.16" + resolved "https://registry.yarnpkg.com/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz#5a7429e6066eb3664d911e33fb0e45de8eb08453" + integrity sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg== + dom-converter@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/dom-converter/-/dom-converter-0.2.0.tgz#6721a9daee2e293682955b6afe416771627bb768" @@ -9526,28 +11376,25 @@ dom-serializer@^1.0.1: domhandler "^4.2.0" entities "^2.0.0" +dom-serializer@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-2.0.0.tgz#e41b802e1eedf9f6cae183ce5e622d789d7d8e53" + integrity sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg== + dependencies: + domelementtype "^2.3.0" + domhandler "^5.0.2" + entities "^4.2.0" + dom-walk@^0.1.0: version "0.1.2" resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.2.tgz#0c548bef048f4d1f2a97249002236060daa3fd84" integrity sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w== -domain-browser@^1.1.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" - integrity sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA== - -domelementtype@^2.0.1, domelementtype@^2.2.0: +domelementtype@^2.0.1, domelementtype@^2.2.0, domelementtype@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.3.0.tgz#5c45e8e869952626331d7aab326d01daf65d589d" integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw== -domexception@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/domexception/-/domexception-1.0.1.tgz#937442644ca6a31261ef36e3ec677fe805582c90" - integrity sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug== - dependencies: - webidl-conversions "^4.0.2" - domhandler@^4.0.0, domhandler@^4.2.0, domhandler@^4.2.2, domhandler@^4.3.1: version "4.3.1" resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.3.1.tgz#8d792033416f59d68bc03a5aa7b018c1ca89279c" @@ -9555,6 +11402,13 @@ domhandler@^4.0.0, domhandler@^4.2.0, domhandler@^4.2.2, domhandler@^4.3.1: dependencies: domelementtype "^2.2.0" +domhandler@^5.0.2, domhandler@^5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-5.0.3.tgz#cc385f7f751f1d1fc650c21374804254538c7d31" + integrity sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w== + dependencies: + domelementtype "^2.3.0" + domutils@^2.5.2, domutils@^2.8.0: version "2.8.0" resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.8.0.tgz#4437def5db6e2d1f5d6ee859bd95ca7d02048135" @@ -9564,6 +11418,15 @@ domutils@^2.5.2, domutils@^2.8.0: domelementtype "^2.2.0" domhandler "^4.2.0" +domutils@^3.0.1: + version "3.1.0" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-3.1.0.tgz#c47f551278d3dc4b0b1ab8cbb42d751a6f0d824e" + integrity sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA== + dependencies: + dom-serializer "^2.0.0" + domelementtype "^2.3.0" + domhandler "^5.0.3" + dot-case@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/dot-case/-/dot-case-3.0.4.tgz#9b2b670d00a431667a8a75ba29cd1b98809ce751" @@ -9579,26 +11442,26 @@ dot-prop@^5.1.0: dependencies: is-obj "^2.0.0" +dotenv-expand@^10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/dotenv-expand/-/dotenv-expand-10.0.0.tgz#12605d00fb0af6d0a592e6558585784032e4ef37" + integrity sha512-GopVGCpVS1UKH75VKHGuQFqS1Gusej0z4FyQkPdwjil2gNIv+LNsqBlboOzpJFZKVT95GkCyWJbBSdFEFUWI2A== + dotenv-expand@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/dotenv-expand/-/dotenv-expand-5.1.0.tgz#3fbaf020bfd794884072ea26b1e9791d45a629f0" integrity sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA== dotenv@^16.0.0: - version "16.0.3" - resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.0.3.tgz#115aec42bac5053db3c456db30cc243a5a836a07" - integrity sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ== + version "16.3.1" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.3.1.tgz#369034de7d7e5b120972693352a3bf112172cc3e" + integrity sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ== dotenv@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-7.0.0.tgz#a2be3cd52736673206e8a85fb5210eea29628e7c" integrity sha512-M3NhsLbV1i6HuGzBUH8vXrtxOk+tWmzWKDMbAVSUp3Zsjm7ywFeuwrUXhmhQyRK1q5B5GGy7hcXPbj3bnfZg2g== -dotenv@^8.0.0: - version "8.6.0" - resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.6.0.tgz#061af664d19f7f4d8fc6e4ff9b584ce237adcb8b" - integrity sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g== - dotenv@~10.0.0: version "10.0.0" resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-10.0.0.tgz#3d4227b8fb95f81096cdd2b66653fb2c7085ba81" @@ -9609,7 +11472,7 @@ duplexer@^0.1.1: resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.2.tgz#3abe43aef3835f8ae077d136ddce0f276b0400e6" integrity sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg== -duplexify@^3.4.2, duplexify@^3.5.0, duplexify@^3.5.1, duplexify@^3.6.0: +duplexify@^3.5.0, duplexify@^3.6.0: version "3.7.1" resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.7.1.tgz#2a4df5317f6ccfd91f86d6fd25d8d8a103b88309" integrity sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g== @@ -9619,7 +11482,7 @@ duplexify@^3.4.2, duplexify@^3.5.0, duplexify@^3.5.1, duplexify@^3.6.0: readable-stream "^2.0.0" stream-shift "^1.0.0" -duplexify@^4.1.1: +duplexify@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-4.1.2.tgz#18b4f8d28289132fa0b9573c898d9f903f81c7b0" integrity sha512-fz3OjcNCHmRP12MJoZMPglx8m4rrFP8rovnk4vT8Fs+aonZoCwGg10dSsQsfP/E62eZcPTMSMP6686fu9Qlqtw== @@ -9629,54 +11492,46 @@ duplexify@^4.1.1: readable-stream "^3.1.1" stream-shift "^1.0.0" -ecc-jsbn@~0.1.1: - version "0.1.2" - resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" - integrity sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw== - dependencies: - jsbn "~0.1.0" - safer-buffer "^2.1.0" - -edge-runtime@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/edge-runtime/-/edge-runtime-2.0.0.tgz#4739e1c8f4237db8ad8a16db5f0e28cc6de16aab" - integrity sha512-TmRJhKi4mlM1e+zgF4CSzVU5gJ1sWj7ia+XhVgZ8PYyYUxk4PPjJU8qScpSLsAbdSxoBghLxdMuwuCzdYLd1sQ== - dependencies: - "@edge-runtime/format" "1.1.0" - "@edge-runtime/vm" "2.0.0" - exit-hook "2.2.1" - http-status "1.5.3" - mri "1.2.0" - picocolors "1.0.0" - pretty-bytes "5.6.0" - pretty-ms "7.0.1" - time-span "4.0.0" +eastasianwidth@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" + integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== ee-first@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== -eip1193-provider@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/eip1193-provider/-/eip1193-provider-1.0.1.tgz#420d29cf4f6c443e3f32e718fb16fafb250637c3" - integrity sha512-kSuqwQ26d7CzuS/t3yRXo2Su2cVH0QfvyKbr2H7Be7O5YDyIq4hQGCNTo5wRdP07bt+E2R/8nPCzey4ojBHf7g== +eip55@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/eip55/-/eip55-2.1.1.tgz#28b743c4701ac3c811b1e9fe67e39cf1d0781b96" + integrity sha512-WcagVAmNu2Ww2cDUfzuWVntYwFxbvZ5MvIyLZpMjTTkjD6sCvkGOiS86jTppzu9/gWsc8isLHAeMBWK02OnZmA== dependencies: - "@json-rpc-tools/provider" "^1.5.5" + keccak "^3.0.3" -ejs@^3.1.7: - version "3.1.9" - resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.9.tgz#03c9e8777fe12686a9effcef22303ca3d8eeb361" - integrity sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ== +ejs@^3.1.7, ejs@^3.1.8: + version "3.1.10" + resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.10.tgz#69ab8358b14e896f80cc39e62087b88500c3ac3b" + integrity sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA== dependencies: jake "^10.8.5" -electron-to-chromium@^1.4.284: - version "1.4.349" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.349.tgz#c65a4378cea805accfe6f585730ce2a3afe07f1d" - integrity sha512-34LBfVDiL6byWorSmQOPwq4gD5wpN8Mhh5yPGQr67FbcxsfUS0BDJP9y6RykSgeWVUfSkN/2dChywnsrmKVyUg== +electron-to-chromium@^1.4.535: + version "1.4.594" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.594.tgz#f69f207fba80735a44a988df42f3f439115d0515" + integrity sha512-xT1HVAu5xFn7bDfkjGQi9dNpMqGchUkebwf1GL7cZN32NSwwlHRPMSDJ1KN6HkS0bWUtndbSQZqvpQftKG2uFQ== + +electron-to-chromium@^1.4.668: + version "1.4.737" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.737.tgz#3a774a58e04980741f65d440f5fdf57af18b6dde" + integrity sha512-QvLTxaLHKdy5YxvixAw/FfHq2eWLUL9KvsPjp0aHK1gI5d3EDuDgITkvj0nFO2c6zUY3ZqVAJQiBYyQP9tQpfw== + +electron-to-chromium@^1.5.4: + version "1.5.25" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.25.tgz#492ade1cde401332b9b75aa0c55fd5e1550ca66c" + integrity sha512-kMb204zvK3PsSlgvvwzI3wBIcAw15tRkYk+NQdsjdDtcQWTp2RABbMQ9rUBy8KNEOM+/E6ep+XC3AykiWZld4g== -elliptic@6.5.4, elliptic@^6.0.0, elliptic@^6.4.0, elliptic@^6.5.3, elliptic@^6.5.4: +elliptic@6.5.4, elliptic@^6.4.0, elliptic@^6.5.3, elliptic@^6.5.4: version "6.5.4" resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb" integrity sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ== @@ -9689,10 +11544,18 @@ elliptic@6.5.4, elliptic@^6.0.0, elliptic@^6.4.0, elliptic@^6.5.3, elliptic@^6.5 minimalistic-assert "^1.0.1" minimalistic-crypto-utils "^1.0.1" -emoji-regex@^7.0.1: - version "7.0.3" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" - integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== +elliptic@^6.5.7: + version "6.5.7" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.7.tgz#8ec4da2cb2939926a1b9a73619d768207e647c8b" + integrity sha512-ESVCtTwiA+XhY3wyh24QqRGBoP3rEdDUl3EDUUo9tft074fi19IrdpH7hLCMMP3CIj7jb3W96rn8lt/BqIlt5Q== + dependencies: + bn.js "^4.11.9" + brorand "^1.1.0" + hash.js "^1.0.0" + hmac-drbg "^1.0.1" + inherits "^2.0.4" + minimalistic-assert "^1.0.1" + minimalistic-crypto-utils "^1.0.1" emoji-regex@^8.0.0: version "8.0.0" @@ -9704,11 +11567,6 @@ emoji-regex@^9.2.2: resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== -emojis-list@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78" - integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q== - emotion-theming@^10.0.19: version "10.3.0" resolved "https://registry.yarnpkg.com/emotion-theming/-/emotion-theming-10.3.0.tgz#7f84d7099581d7ffe808aab5cd870e30843db72a" @@ -9718,11 +11576,21 @@ emotion-theming@^10.0.19: "@emotion/weak-memoize" "0.2.5" hoist-non-react-statics "^3.3.0" +encode-utf8@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/encode-utf8/-/encode-utf8-1.0.3.tgz#f30fdd31da07fb596f281beb2f6b027851994cda" + integrity sha512-ucAnuBEhUK4boH2HjVYG5Q2mQyPorvv0u/ocS+zhdw0S8AlHYY+GOFhP1Gio5z4icpP2ivFSvhtFjQi8+T9ppw== + encodeurl@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== +encodeurl@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-2.0.0.tgz#7b8ea898077d7e409d3ac45474ea38eaf0857a58" + integrity sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg== + encoding@^0.1.11: version "0.1.13" resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9" @@ -9746,24 +11614,15 @@ endent@^2.0.1: fast-json-parse "^1.0.3" objectorarray "^1.0.5" -enhanced-resolve@^4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.5.0.tgz#2f3cfd84dbe3b487f18f2db2ef1e064a571ca5ec" - integrity sha512-Nv9m36S/vxpsI+Hc4/ZGRs0n9mXqSWGGq49zxb/cJfPAQMbUtttJAlNPS4AQzaBdw/pKskw5bMbekT/Y7W/Wlg== - dependencies: - graceful-fs "^4.1.2" - memory-fs "^0.5.0" - tapable "^1.0.0" - -enhanced-resolve@^5.10.0: - version "5.12.0" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.12.0.tgz#300e1c90228f5b570c4d35babf263f6da7155634" - integrity sha512-QHTXI/sZQmko1cbDoNAa3mJ5qhWUUNAq3vR0/YiD379fWQrcfuoX1+HW2S0MTt7XmoPLapdaDKUtelUSPic7hQ== +enhanced-resolve@^5.17.1: + version "5.17.1" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz#67bfbbcc2f81d511be77d686a90267ef7f898a15" + integrity sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg== dependencies: graceful-fs "^4.2.4" tapable "^2.2.0" -enquirer@^2.3.4, enquirer@~2.3.6: +enquirer@~2.3.6: version "2.3.6" resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg== @@ -9780,46 +11639,48 @@ entities@^3.0.1: resolved "https://registry.yarnpkg.com/entities/-/entities-3.0.1.tgz#2b887ca62585e96db3903482d336c1006c3001d4" integrity sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q== -errno@^0.1.3, errno@~0.1.7: - version "0.1.8" - resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.8.tgz#8bb3e9c7d463be4976ff888f76b4809ebc2e811f" - integrity sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A== - dependencies: - prr "~1.0.1" +entities@^4.2.0, entities@^4.4.0, entities@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/entities/-/entities-4.5.0.tgz#5d268ea5e7113ec74c4d033b79ea5a35a488fb48" + integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw== + +envinfo@^7.7.3: + version "7.11.0" + resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.11.0.tgz#c3793f44284a55ff8c82faf1ffd91bc6478ea01f" + integrity sha512-G9/6xF1FPbIw0TtalAMaVPpiq2aDEuKLXM314jPVAO9r2fo2a4BLqMNkmRS7O/xPPZ+COAhGIz3ETvHEV3eUcg== + +err-code@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/err-code/-/err-code-2.0.3.tgz#23c2f3b756ffdfc608d30e27c9a941024807e7f9" + integrity sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA== -error-ex@^1.2.0, error-ex@^1.3.1: +error-ex@^1.3.1: version "1.3.2" resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== dependencies: is-arrayish "^0.2.1" -error-stack-parser@^2.0.6: - version "2.1.4" - resolved "https://registry.yarnpkg.com/error-stack-parser/-/error-stack-parser-2.1.4.tgz#229cb01cdbfa84440bfa91876285b94680188286" - integrity sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ== - dependencies: - stackframe "^1.3.4" - -es-abstract@^1.19.0, es-abstract@^1.20.4: - version "1.21.2" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.21.2.tgz#a56b9695322c8a185dc25975aa3b8ec31d0e7eff" - integrity sha512-y/B5POM2iBnIxCiernH1G7rC9qQoM77lLIMQLuob0zhp8C56Po81+2Nj0WFKnd0pNReDTnkYryc+zhOzpEIROg== +es-abstract@^1.22.1: + version "1.22.3" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.22.3.tgz#48e79f5573198de6dee3589195727f4f74bc4f32" + integrity sha512-eiiY8HQeYfYH2Con2berK+To6GrK2RxbPawDkGq4UiCQQfZHb6wX9qQqkbpPqaxQFcl8d9QzZqo0tGE0VcrdwA== dependencies: array-buffer-byte-length "^1.0.0" + arraybuffer.prototype.slice "^1.0.2" available-typed-arrays "^1.0.5" - call-bind "^1.0.2" + call-bind "^1.0.5" es-set-tostringtag "^2.0.1" es-to-primitive "^1.2.1" - function.prototype.name "^1.1.5" - get-intrinsic "^1.2.0" + function.prototype.name "^1.1.6" + get-intrinsic "^1.2.2" get-symbol-description "^1.0.0" globalthis "^1.0.3" gopd "^1.0.1" - has "^1.0.3" has-property-descriptors "^1.0.0" has-proto "^1.0.1" has-symbols "^1.0.3" + hasown "^2.0.0" internal-slot "^1.0.5" is-array-buffer "^3.0.2" is-callable "^1.2.7" @@ -9827,60 +11688,86 @@ es-abstract@^1.19.0, es-abstract@^1.20.4: is-regex "^1.1.4" is-shared-array-buffer "^1.0.2" is-string "^1.0.7" - is-typed-array "^1.1.10" + is-typed-array "^1.1.12" is-weakref "^1.0.2" - object-inspect "^1.12.3" + object-inspect "^1.13.1" object-keys "^1.1.1" object.assign "^4.1.4" - regexp.prototype.flags "^1.4.3" + regexp.prototype.flags "^1.5.1" + safe-array-concat "^1.0.1" safe-regex-test "^1.0.0" - string.prototype.trim "^1.2.7" - string.prototype.trimend "^1.0.6" - string.prototype.trimstart "^1.0.6" + string.prototype.trim "^1.2.8" + string.prototype.trimend "^1.0.7" + string.prototype.trimstart "^1.0.7" + typed-array-buffer "^1.0.0" + typed-array-byte-length "^1.0.0" + typed-array-byte-offset "^1.0.0" typed-array-length "^1.0.4" unbox-primitive "^1.0.2" - which-typed-array "^1.1.9" + which-typed-array "^1.1.13" -es-array-method-boxes-properly@^1.0.0: +es-define-property@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz#873f3e84418de4ee19c5be752990b2e44718d09e" - integrity sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA== + resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.0.tgz#c7faefbdff8b2696cf5f46921edfb77cc4ba3845" + integrity sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ== + dependencies: + get-intrinsic "^1.2.4" -es-get-iterator@^1.0.2, es-get-iterator@^1.1.2: - version "1.1.3" - resolved "https://registry.yarnpkg.com/es-get-iterator/-/es-get-iterator-1.1.3.tgz#3ef87523c5d464d41084b2c3c9c214f1199763d6" - integrity sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw== +es-errors@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f" + integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw== + +es-iterator-helpers@^1.0.12: + version "1.0.15" + resolved "https://registry.yarnpkg.com/es-iterator-helpers/-/es-iterator-helpers-1.0.15.tgz#bd81d275ac766431d19305923707c3efd9f1ae40" + integrity sha512-GhoY8uYqd6iwUl2kgjTm4CZAf6oo5mHK7BPqx3rKgx893YSsy0LGHV6gfqqQvZt/8xM8xeOnfXBCfqclMKkJ5g== dependencies: + asynciterator.prototype "^1.0.0" call-bind "^1.0.2" - get-intrinsic "^1.1.3" + define-properties "^1.2.1" + es-abstract "^1.22.1" + es-set-tostringtag "^2.0.1" + function-bind "^1.1.1" + get-intrinsic "^1.2.1" + globalthis "^1.0.3" + has-property-descriptors "^1.0.0" + has-proto "^1.0.1" has-symbols "^1.0.3" - is-arguments "^1.1.1" - is-map "^2.0.2" - is-set "^2.0.2" - is-string "^1.0.7" - isarray "^2.0.5" - stop-iteration-iterator "^1.0.0" + internal-slot "^1.0.5" + iterator.prototype "^1.1.2" + safe-array-concat "^1.0.1" -es-module-lexer@^0.9.0: +es-module-lexer@^0.9.3: version "0.9.3" resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-0.9.3.tgz#6f13db00cc38417137daf74366f535c8eb438f19" integrity sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ== +es-module-lexer@^1.2.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-1.4.1.tgz#41ea21b43908fe6a287ffcbe4300f790555331f5" + integrity sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w== + +es-module-lexer@^1.4.1: + version "1.5.0" + resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-1.5.0.tgz#4878fee3789ad99e065f975fdd3c645529ff0236" + integrity sha512-pqrTKmwEIgafsYZAGw9kszYzmagcE/n4dbgwGWLEXg7J4QFJVQRBld8j3Q3GNez79jzxZshq0bcT962QHOghjw== + es-set-tostringtag@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz#338d502f6f674301d710b80c8592de8a15f09cd8" - integrity sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg== + version "2.0.2" + resolved "https://registry.yarnpkg.com/es-set-tostringtag/-/es-set-tostringtag-2.0.2.tgz#11f7cc9f63376930a5f20be4915834f4bc74f9c9" + integrity sha512-BuDyupZt65P9D2D2vA/zqcI3G5xRsklm5N3xCwuiy+/vKy8i0ifdsQP1sLgO4tZDSCaQUSnmC48khknGMV3D2Q== dependencies: - get-intrinsic "^1.1.3" - has "^1.0.3" + get-intrinsic "^1.2.2" has-tostringtag "^1.0.0" + hasown "^2.0.0" es-shim-unscopables@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz#702e632193201e3edf8713635d083d378e510241" - integrity sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w== + version "1.0.2" + resolved "https://registry.yarnpkg.com/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz#1f6942e71ecc7835ed1c8a83006d8771a63a3763" + integrity sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw== dependencies: - has "^1.0.3" + hasown "^2.0.0" es-to-primitive@^1.2.1: version "1.2.1" @@ -9891,11 +11778,6 @@ es-to-primitive@^1.2.1: is-date-object "^1.0.1" is-symbol "^1.0.2" -es5-shim@^4.5.13: - version "4.6.7" - resolved "https://registry.yarnpkg.com/es5-shim/-/es5-shim-4.6.7.tgz#bc67ae0fc3dd520636e0a1601cc73b450ad3e955" - integrity sha512-jg21/dmlrNQI7JyyA2w7n+yifSxBng0ZralnSfVZjoCawgNTCnS+yBCyVM9DL5itm7SUnDGgv7hcq2XCZX4iRQ== - es6-promise@^4.0.3: version "4.2.8" resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a" @@ -9908,226 +11790,152 @@ es6-promisify@^5.0.0: dependencies: es6-promise "^4.0.3" -es6-shim@^0.35.5: - version "0.35.8" - resolved "https://registry.yarnpkg.com/es6-shim/-/es6-shim-0.35.8.tgz#89216f6fbf8bacba3f897c8c0e814d2a41c05fb7" - integrity sha512-Twf7I2v4/1tLoIXMT8HlqaBSS5H2wQTs2wx3MNYCI8K1R1/clXyCazrcVCPm/FuO9cyV8+leEaZOWD5C253NDg== - -esbuild-android-64@0.14.47: - version "0.14.47" - resolved "https://registry.yarnpkg.com/esbuild-android-64/-/esbuild-android-64-0.14.47.tgz#ef95b42c67bcf4268c869153fa3ad1466c4cea6b" - integrity sha512-R13Bd9+tqLVFndncMHssZrPWe6/0Kpv2/dt4aA69soX4PRxlzsVpCvoJeFE8sOEoeVEiBkI0myjlkDodXlHa0g== - -esbuild-android-arm64@0.14.47: - version "0.14.47" - resolved "https://registry.yarnpkg.com/esbuild-android-arm64/-/esbuild-android-arm64-0.14.47.tgz#4ebd7ce9fb250b4695faa3ee46fd3b0754ecd9e6" - integrity sha512-OkwOjj7ts4lBp/TL6hdd8HftIzOy/pdtbrNA4+0oVWgGG64HrdVzAF5gxtJufAPOsEjkyh1oIYvKAUinKKQRSQ== - -esbuild-darwin-64@0.14.47: - version "0.14.47" - resolved "https://registry.yarnpkg.com/esbuild-darwin-64/-/esbuild-darwin-64-0.14.47.tgz#e0da6c244f497192f951807f003f6a423ed23188" - integrity sha512-R6oaW0y5/u6Eccti/TS6c/2c1xYTb1izwK3gajJwi4vIfNs1s8B1dQzI1UiC9T61YovOQVuePDcfqHLT3mUZJA== - -esbuild-darwin-arm64@0.14.47: - version "0.14.47" - resolved "https://registry.yarnpkg.com/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.47.tgz#cd40fd49a672fca581ed202834239dfe540a9028" - integrity sha512-seCmearlQyvdvM/noz1L9+qblC5vcBrhUaOoLEDDoLInF/VQ9IkobGiLlyTPYP5dW1YD4LXhtBgOyevoIHGGnw== - -esbuild-freebsd-64@0.14.47: - version "0.14.47" - resolved "https://registry.yarnpkg.com/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.47.tgz#8da6a14c095b29c01fc8087a16cb7906debc2d67" - integrity sha512-ZH8K2Q8/Ux5kXXvQMDsJcxvkIwut69KVrYQhza/ptkW50DC089bCVrJZZ3sKzIoOx+YPTrmsZvqeZERjyYrlvQ== - -esbuild-freebsd-arm64@0.14.47: - version "0.14.47" - resolved "https://registry.yarnpkg.com/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.47.tgz#ad31f9c92817ff8f33fd253af7ab5122dc1b83f6" - integrity sha512-ZJMQAJQsIOhn3XTm7MPQfCzEu5b9STNC+s90zMWe2afy9EwnHV7Ov7ohEMv2lyWlc2pjqLW8QJnz2r0KZmeAEQ== - -esbuild-linux-32@0.14.47: - version "0.14.47" - resolved "https://registry.yarnpkg.com/esbuild-linux-32/-/esbuild-linux-32-0.14.47.tgz#de085e4db2e692ea30c71208ccc23fdcf5196c58" - integrity sha512-FxZOCKoEDPRYvq300lsWCTv1kcHgiiZfNrPtEhFAiqD7QZaXrad8LxyJ8fXGcWzIFzRiYZVtB3ttvITBvAFhKw== - -esbuild-linux-64@0.14.47: - version "0.14.47" - resolved "https://registry.yarnpkg.com/esbuild-linux-64/-/esbuild-linux-64-0.14.47.tgz#2a9321bbccb01f01b04cebfcfccbabeba3658ba1" - integrity sha512-nFNOk9vWVfvWYF9YNYksZptgQAdstnDCMtR6m42l5Wfugbzu11VpMCY9XrD4yFxvPo9zmzcoUL/88y0lfJZJJw== - -esbuild-linux-arm64@0.14.47: - version "0.14.47" - resolved "https://registry.yarnpkg.com/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.47.tgz#b9da7b6fc4b0ca7a13363a0c5b7bb927e4bc535a" - integrity sha512-ywfme6HVrhWcevzmsufjd4iT3PxTfCX9HOdxA7Hd+/ZM23Y9nXeb+vG6AyA6jgq/JovkcqRHcL9XwRNpWG6XRw== - -esbuild-linux-arm@0.14.47: - version "0.14.47" - resolved "https://registry.yarnpkg.com/esbuild-linux-arm/-/esbuild-linux-arm-0.14.47.tgz#56fec2a09b9561c337059d4af53625142aded853" - integrity sha512-ZGE1Bqg/gPRXrBpgpvH81tQHpiaGxa8c9Rx/XOylkIl2ypLuOcawXEAo8ls+5DFCcRGt/o3sV+PzpAFZobOsmA== - -esbuild-linux-mips64le@0.14.47: - version "0.14.47" - resolved "https://registry.yarnpkg.com/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.47.tgz#9db21561f8f22ed79ef2aedb7bbef082b46cf823" - integrity sha512-mg3D8YndZ1LvUiEdDYR3OsmeyAew4MA/dvaEJxvyygahWmpv1SlEEnhEZlhPokjsUMfRagzsEF/d/2XF+kTQGg== - -esbuild-linux-ppc64le@0.14.47: - version "0.14.47" - resolved "https://registry.yarnpkg.com/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.47.tgz#dc3a3da321222b11e96e50efafec9d2de408198b" - integrity sha512-WER+f3+szmnZiWoK6AsrTKGoJoErG2LlauSmk73LEZFQ/iWC+KhhDsOkn1xBUpzXWsxN9THmQFltLoaFEH8F8w== - -esbuild-linux-riscv64@0.14.47: - version "0.14.47" - resolved "https://registry.yarnpkg.com/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.47.tgz#9bd6dcd3dca6c0357084ecd06e1d2d4bf105335f" - integrity sha512-1fI6bP3A3rvI9BsaaXbMoaOjLE3lVkJtLxsgLHqlBhLlBVY7UqffWBvkrX/9zfPhhVMd9ZRFiaqXnB1T7BsL2g== - -esbuild-linux-s390x@0.14.47: - version "0.14.47" - resolved "https://registry.yarnpkg.com/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.47.tgz#a458af939b52f2cd32fc561410d441a51f69d41f" - integrity sha512-eZrWzy0xFAhki1CWRGnhsHVz7IlSKX6yT2tj2Eg8lhAwlRE5E96Hsb0M1mPSE1dHGpt1QVwwVivXIAacF/G6mw== - -esbuild-netbsd-64@0.14.47: - version "0.14.47" - resolved "https://registry.yarnpkg.com/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.47.tgz#6388e785d7e7e4420cb01348d7483ab511b16aa8" - integrity sha512-Qjdjr+KQQVH5Q2Q1r6HBYswFTToPpss3gqCiSw2Fpq/ua8+eXSQyAMG+UvULPqXceOwpnPo4smyZyHdlkcPppQ== - -esbuild-openbsd-64@0.14.47: - version "0.14.47" - resolved "https://registry.yarnpkg.com/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.47.tgz#309af806db561aa886c445344d1aacab850dbdc5" - integrity sha512-QpgN8ofL7B9z8g5zZqJE+eFvD1LehRlxr25PBkjyyasakm4599iroUpaj96rdqRlO2ShuyqwJdr+oNqWwTUmQw== - -esbuild-sunos-64@0.14.47: - version "0.14.47" - resolved "https://registry.yarnpkg.com/esbuild-sunos-64/-/esbuild-sunos-64-0.14.47.tgz#3f19612dcdb89ba6c65283a7ff6e16f8afbf8aaa" - integrity sha512-uOeSgLUwukLioAJOiGYm3kNl+1wJjgJA8R671GYgcPgCx7QR73zfvYqXFFcIO93/nBdIbt5hd8RItqbbf3HtAQ== - -esbuild-windows-32@0.14.47: - version "0.14.47" - resolved "https://registry.yarnpkg.com/esbuild-windows-32/-/esbuild-windows-32-0.14.47.tgz#a92d279c8458d5dc319abcfeb30aa49e8f2e6f7f" - integrity sha512-H0fWsLTp2WBfKLBgwYT4OTfFly4Im/8B5f3ojDv1Kx//kiubVY0IQunP2Koc/fr/0wI7hj3IiBDbSrmKlrNgLQ== - -esbuild-windows-64@0.14.47: - version "0.14.47" - resolved "https://registry.yarnpkg.com/esbuild-windows-64/-/esbuild-windows-64-0.14.47.tgz#2564c3fcf0c23d701edb71af8c52d3be4cec5f8a" - integrity sha512-/Pk5jIEH34T68r8PweKRi77W49KwanZ8X6lr3vDAtOlH5EumPE4pBHqkCUdELanvsT14yMXLQ/C/8XPi1pAtkQ== - -esbuild-windows-arm64@0.14.47: - version "0.14.47" - resolved "https://registry.yarnpkg.com/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.47.tgz#86d9db1a22d83360f726ac5fba41c2f625db6878" - integrity sha512-HFSW2lnp62fl86/qPQlqw6asIwCnEsEoNIL1h2uVMgakddf+vUuMcCbtUY1i8sst7KkgHrVKCJQB33YhhOweCQ== - -esbuild@0.14.47: - version "0.14.47" - resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.14.47.tgz#0d6415f6bd8eb9e73a58f7f9ae04c5276cda0e4d" - integrity sha512-wI4ZiIfFxpkuxB8ju4MHrGwGLyp1+awEHAHVpx6w7a+1pmYIq8T9FGEVVwFo0iFierDoMj++Xq69GXWYn2EiwA== +esbuild-plugin-alias@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/esbuild-plugin-alias/-/esbuild-plugin-alias-0.2.1.tgz#45a86cb941e20e7c2bc68a2bea53562172494fcb" + integrity sha512-jyfL/pwPqaFXyKnj8lP8iLk6Z0m099uXR45aSN8Av1XD4vhvQutxxPzgA2bTcAwQpa1zCXDcWOlhFgyP3GKqhQ== + +esbuild-plugins-node-modules-polyfill@^1.6.6: + version "1.6.6" + resolved "https://registry.yarnpkg.com/esbuild-plugins-node-modules-polyfill/-/esbuild-plugins-node-modules-polyfill-1.6.6.tgz#acdfbd32443a1667a029b930b15a5ae767a7ed25" + integrity sha512-0wDvliv65SCaaGtmoITnmXqqiUzU+ggFupnOgkEo2B9cQ+CUt58ql2+EY6dYoEsoqiHRu2NuTrFUJGMJEgMmLw== + dependencies: + "@jspm/core" "^2.0.1" + local-pkg "^0.5.0" + resolve.exports "^2.0.2" + +esbuild-register@^3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/esbuild-register/-/esbuild-register-3.5.0.tgz#449613fb29ab94325c722f560f800dd946dc8ea8" + integrity sha512-+4G/XmakeBAsvJuDugJvtyF1x+XJT4FMocynNpxrvEBViirpfUn2PgNpCHedfWhF4WokNsO/OvMKrmJOIJsI5A== + dependencies: + debug "^4.3.4" + +esbuild@^0.17.10: + version "0.17.19" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.17.19.tgz#087a727e98299f0462a3d0bcdd9cd7ff100bd955" + integrity sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw== optionalDependencies: - esbuild-android-64 "0.14.47" - esbuild-android-arm64 "0.14.47" - esbuild-darwin-64 "0.14.47" - esbuild-darwin-arm64 "0.14.47" - esbuild-freebsd-64 "0.14.47" - esbuild-freebsd-arm64 "0.14.47" - esbuild-linux-32 "0.14.47" - esbuild-linux-64 "0.14.47" - esbuild-linux-arm "0.14.47" - esbuild-linux-arm64 "0.14.47" - esbuild-linux-mips64le "0.14.47" - esbuild-linux-ppc64le "0.14.47" - esbuild-linux-riscv64 "0.14.47" - esbuild-linux-s390x "0.14.47" - esbuild-netbsd-64 "0.14.47" - esbuild-openbsd-64 "0.14.47" - esbuild-sunos-64 "0.14.47" - esbuild-windows-32 "0.14.47" - esbuild-windows-64 "0.14.47" - esbuild-windows-arm64 "0.14.47" - -esbuild@0.16.3: - version "0.16.3" - resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.16.3.tgz#5868632fa23f7a8547f2a4ea359c44e946515c94" - integrity sha512-71f7EjPWTiSguen8X/kxEpkAS7BFHwtQKisCDDV3Y4GLGWBaoSCyD5uXkaUew6JDzA9FEN1W23mdnSwW9kqCeg== + "@esbuild/android-arm" "0.17.19" + "@esbuild/android-arm64" "0.17.19" + "@esbuild/android-x64" "0.17.19" + "@esbuild/darwin-arm64" "0.17.19" + "@esbuild/darwin-x64" "0.17.19" + "@esbuild/freebsd-arm64" "0.17.19" + "@esbuild/freebsd-x64" "0.17.19" + "@esbuild/linux-arm" "0.17.19" + "@esbuild/linux-arm64" "0.17.19" + "@esbuild/linux-ia32" "0.17.19" + "@esbuild/linux-loong64" "0.17.19" + "@esbuild/linux-mips64el" "0.17.19" + "@esbuild/linux-ppc64" "0.17.19" + "@esbuild/linux-riscv64" "0.17.19" + "@esbuild/linux-s390x" "0.17.19" + "@esbuild/linux-x64" "0.17.19" + "@esbuild/netbsd-x64" "0.17.19" + "@esbuild/openbsd-x64" "0.17.19" + "@esbuild/sunos-x64" "0.17.19" + "@esbuild/win32-arm64" "0.17.19" + "@esbuild/win32-ia32" "0.17.19" + "@esbuild/win32-x64" "0.17.19" + +"esbuild@^0.18.0 || ^0.19.0 || ^0.20.0": + version "0.20.2" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.20.2.tgz#9d6b2386561766ee6b5a55196c6d766d28c87ea1" + integrity sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g== optionalDependencies: - "@esbuild/android-arm" "0.16.3" - "@esbuild/android-arm64" "0.16.3" - "@esbuild/android-x64" "0.16.3" - "@esbuild/darwin-arm64" "0.16.3" - "@esbuild/darwin-x64" "0.16.3" - "@esbuild/freebsd-arm64" "0.16.3" - "@esbuild/freebsd-x64" "0.16.3" - "@esbuild/linux-arm" "0.16.3" - "@esbuild/linux-arm64" "0.16.3" - "@esbuild/linux-ia32" "0.16.3" - "@esbuild/linux-loong64" "0.16.3" - "@esbuild/linux-mips64el" "0.16.3" - "@esbuild/linux-ppc64" "0.16.3" - "@esbuild/linux-riscv64" "0.16.3" - "@esbuild/linux-s390x" "0.16.3" - "@esbuild/linux-x64" "0.16.3" - "@esbuild/netbsd-x64" "0.16.3" - "@esbuild/openbsd-x64" "0.16.3" - "@esbuild/sunos-x64" "0.16.3" - "@esbuild/win32-arm64" "0.16.3" - "@esbuild/win32-ia32" "0.16.3" - "@esbuild/win32-x64" "0.16.3" - -esbuild@0.17.6: - version "0.17.6" - resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.17.6.tgz#bbccd4433629deb6e0a83860b3b61da120ba4e01" - integrity sha512-TKFRp9TxrJDdRWfSsSERKEovm6v30iHnrjlcGhLBOtReE28Yp1VSBRfO3GTaOFMoxsNerx4TjrhzSuma9ha83Q== + "@esbuild/aix-ppc64" "0.20.2" + "@esbuild/android-arm" "0.20.2" + "@esbuild/android-arm64" "0.20.2" + "@esbuild/android-x64" "0.20.2" + "@esbuild/darwin-arm64" "0.20.2" + "@esbuild/darwin-x64" "0.20.2" + "@esbuild/freebsd-arm64" "0.20.2" + "@esbuild/freebsd-x64" "0.20.2" + "@esbuild/linux-arm" "0.20.2" + "@esbuild/linux-arm64" "0.20.2" + "@esbuild/linux-ia32" "0.20.2" + "@esbuild/linux-loong64" "0.20.2" + "@esbuild/linux-mips64el" "0.20.2" + "@esbuild/linux-ppc64" "0.20.2" + "@esbuild/linux-riscv64" "0.20.2" + "@esbuild/linux-s390x" "0.20.2" + "@esbuild/linux-x64" "0.20.2" + "@esbuild/netbsd-x64" "0.20.2" + "@esbuild/openbsd-x64" "0.20.2" + "@esbuild/sunos-x64" "0.20.2" + "@esbuild/win32-arm64" "0.20.2" + "@esbuild/win32-ia32" "0.20.2" + "@esbuild/win32-x64" "0.20.2" + +esbuild@^0.20.1: + version "0.20.1" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.20.1.tgz#1e4cbb380ad1959db7609cb9573ee77257724a3e" + integrity sha512-OJwEgrpWm/PCMsLVWXKqvcjme3bHNpOgN7Tb6cQnR5n0TPbQx1/Xrn7rqM+wn17bYeT6MGB5sn1Bh5YiGi70nA== optionalDependencies: - "@esbuild/android-arm" "0.17.6" - "@esbuild/android-arm64" "0.17.6" - "@esbuild/android-x64" "0.17.6" - "@esbuild/darwin-arm64" "0.17.6" - "@esbuild/darwin-x64" "0.17.6" - "@esbuild/freebsd-arm64" "0.17.6" - "@esbuild/freebsd-x64" "0.17.6" - "@esbuild/linux-arm" "0.17.6" - "@esbuild/linux-arm64" "0.17.6" - "@esbuild/linux-ia32" "0.17.6" - "@esbuild/linux-loong64" "0.17.6" - "@esbuild/linux-mips64el" "0.17.6" - "@esbuild/linux-ppc64" "0.17.6" - "@esbuild/linux-riscv64" "0.17.6" - "@esbuild/linux-s390x" "0.17.6" - "@esbuild/linux-x64" "0.17.6" - "@esbuild/netbsd-x64" "0.17.6" - "@esbuild/openbsd-x64" "0.17.6" - "@esbuild/sunos-x64" "0.17.6" - "@esbuild/win32-arm64" "0.17.6" - "@esbuild/win32-ia32" "0.17.6" - "@esbuild/win32-x64" "0.17.6" - -esbuild@^0.17.5, esbuild@^0.17.7: - version "0.17.15" - resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.17.15.tgz#209ebc87cb671ffb79574db93494b10ffaf43cbc" - integrity sha512-LBUV2VsUIc/iD9ME75qhT4aJj0r75abCVS0jakhFzOtR7TQsqQA5w0tZ+KTKnwl3kXE0MhskNdHDh/I5aCR1Zw== + "@esbuild/aix-ppc64" "0.20.1" + "@esbuild/android-arm" "0.20.1" + "@esbuild/android-arm64" "0.20.1" + "@esbuild/android-x64" "0.20.1" + "@esbuild/darwin-arm64" "0.20.1" + "@esbuild/darwin-x64" "0.20.1" + "@esbuild/freebsd-arm64" "0.20.1" + "@esbuild/freebsd-x64" "0.20.1" + "@esbuild/linux-arm" "0.20.1" + "@esbuild/linux-arm64" "0.20.1" + "@esbuild/linux-ia32" "0.20.1" + "@esbuild/linux-loong64" "0.20.1" + "@esbuild/linux-mips64el" "0.20.1" + "@esbuild/linux-ppc64" "0.20.1" + "@esbuild/linux-riscv64" "0.20.1" + "@esbuild/linux-s390x" "0.20.1" + "@esbuild/linux-x64" "0.20.1" + "@esbuild/netbsd-x64" "0.20.1" + "@esbuild/openbsd-x64" "0.20.1" + "@esbuild/sunos-x64" "0.20.1" + "@esbuild/win32-arm64" "0.20.1" + "@esbuild/win32-ia32" "0.20.1" + "@esbuild/win32-x64" "0.20.1" + +esbuild@^0.21.3: + version "0.21.5" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.21.5.tgz#9ca301b120922959b766360d8ac830da0d02997d" + integrity sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw== optionalDependencies: - "@esbuild/android-arm" "0.17.15" - "@esbuild/android-arm64" "0.17.15" - "@esbuild/android-x64" "0.17.15" - "@esbuild/darwin-arm64" "0.17.15" - "@esbuild/darwin-x64" "0.17.15" - "@esbuild/freebsd-arm64" "0.17.15" - "@esbuild/freebsd-x64" "0.17.15" - "@esbuild/linux-arm" "0.17.15" - "@esbuild/linux-arm64" "0.17.15" - "@esbuild/linux-ia32" "0.17.15" - "@esbuild/linux-loong64" "0.17.15" - "@esbuild/linux-mips64el" "0.17.15" - "@esbuild/linux-ppc64" "0.17.15" - "@esbuild/linux-riscv64" "0.17.15" - "@esbuild/linux-s390x" "0.17.15" - "@esbuild/linux-x64" "0.17.15" - "@esbuild/netbsd-x64" "0.17.15" - "@esbuild/openbsd-x64" "0.17.15" - "@esbuild/sunos-x64" "0.17.15" - "@esbuild/win32-arm64" "0.17.15" - "@esbuild/win32-ia32" "0.17.15" - "@esbuild/win32-x64" "0.17.15" + "@esbuild/aix-ppc64" "0.21.5" + "@esbuild/android-arm" "0.21.5" + "@esbuild/android-arm64" "0.21.5" + "@esbuild/android-x64" "0.21.5" + "@esbuild/darwin-arm64" "0.21.5" + "@esbuild/darwin-x64" "0.21.5" + "@esbuild/freebsd-arm64" "0.21.5" + "@esbuild/freebsd-x64" "0.21.5" + "@esbuild/linux-arm" "0.21.5" + "@esbuild/linux-arm64" "0.21.5" + "@esbuild/linux-ia32" "0.21.5" + "@esbuild/linux-loong64" "0.21.5" + "@esbuild/linux-mips64el" "0.21.5" + "@esbuild/linux-ppc64" "0.21.5" + "@esbuild/linux-riscv64" "0.21.5" + "@esbuild/linux-s390x" "0.21.5" + "@esbuild/linux-x64" "0.21.5" + "@esbuild/netbsd-x64" "0.21.5" + "@esbuild/openbsd-x64" "0.21.5" + "@esbuild/sunos-x64" "0.21.5" + "@esbuild/win32-arm64" "0.21.5" + "@esbuild/win32-ia32" "0.21.5" + "@esbuild/win32-x64" "0.21.5" escalade@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== +escalade@^3.1.2: + version "3.2.0" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.2.0.tgz#011a3f69856ba189dffa7dc8fcce99d2a87903e5" + integrity sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA== + escape-html@~1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" @@ -10138,141 +11946,102 @@ escape-string-regexp@^1.0.5: resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== -escape-string-regexp@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" - integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== - escape-string-regexp@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== -escodegen@^1.11.1, escodegen@^1.8.1: - version "1.14.3" - resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.14.3.tgz#4e7b81fba61581dc97582ed78cab7f0e8d63f503" - integrity sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw== - dependencies: - esprima "^4.0.1" - estraverse "^4.2.0" - esutils "^2.0.2" - optionator "^0.8.1" - optionalDependencies: - source-map "~0.6.1" - -escodegen@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-2.0.0.tgz#5e32b12833e8aa8fa35e1bf0befa89380484c7dd" - integrity sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw== +escodegen@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-2.1.0.tgz#ba93bbb7a43986d29d6041f99f5262da773e2e17" + integrity sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w== dependencies: esprima "^4.0.1" estraverse "^5.2.0" esutils "^2.0.2" - optionator "^0.8.1" optionalDependencies: source-map "~0.6.1" -eslint-config-prettier@^6.0.0: - version "6.15.0" - resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-6.15.0.tgz#7f93f6cb7d45a92f1537a70ecc06366e1ac6fed9" - integrity sha512-a1+kOYLR8wMGustcgAjdydMsQ2A/2ipRPwRKUmfYaSxc9ZPcrku080Ctl6zrZzZNs/U82MjSv+qKREkoq3bJaw== - dependencies: - get-stdin "^6.0.0" - -eslint-config-react-app@^5.2.1: - version "5.2.1" - resolved "https://registry.yarnpkg.com/eslint-config-react-app/-/eslint-config-react-app-5.2.1.tgz#698bf7aeee27f0cea0139eaef261c7bf7dd623df" - integrity sha512-pGIZ8t0mFLcV+6ZirRgYK6RVqUIKRIi9MmgzUEmrIknsn3AdO0I32asO86dJgloHq+9ZPl8UIg8mYrvgP5u2wQ== - dependencies: - confusing-browser-globals "^1.0.9" +eslint-config-prettier@^8.8.0: + version "8.10.0" + resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-8.10.0.tgz#3a06a662130807e2502fc3ff8b4143d8a0658e11" + integrity sha512-SM8AMJdeQqRYT9O9zguiruQZaN7+z+E4eAP9oiLNGKMtomwaB1E9dcgUD6ZAn/eQAb52USbvezbiljfZUhbJcg== -eslint-import-resolver-node@^0.3.7: - version "0.3.7" - resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.7.tgz#83b375187d412324a1963d84fa664377a23eb4d7" - integrity sha512-gozW2blMLJCeFpBwugLTGyvVjNoeo1knonXAcatC6bjPBZitotxdWf7Gimr25N4c0AAOo4eOUfaG82IJPDpqCA== +eslint-import-resolver-node@^0.3.9: + version "0.3.9" + resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz#d4eaac52b8a2e7c3cd1903eb00f7e053356118ac" + integrity sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g== dependencies: debug "^3.2.7" - is-core-module "^2.11.0" - resolve "^1.22.1" + is-core-module "^2.13.0" + resolve "^1.22.4" -eslint-module-utils@^2.7.4: - version "2.7.4" - resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.7.4.tgz#4f3e41116aaf13a20792261e61d3a2e7e0583974" - integrity sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA== +eslint-module-utils@^2.8.0: + version "2.8.0" + resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz#e439fee65fc33f6bba630ff621efc38ec0375c49" + integrity sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw== dependencies: debug "^3.2.7" -eslint-plugin-flowtype@^3.13.0: - version "3.13.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-flowtype/-/eslint-plugin-flowtype-3.13.0.tgz#e241ebd39c0ce519345a3f074ec1ebde4cf80f2c" - integrity sha512-bhewp36P+t7cEV0b6OdmoRWJCBYRiHFlqPZAG1oS3SF+Y0LQkeDvFSM4oxoxvczD1OdONCXMlJfQFiWLcV9urw== +eslint-plugin-destructuring@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-destructuring/-/eslint-plugin-destructuring-2.2.1.tgz#7c0681174699af03fd9fab4c9619fcad45156fbe" + integrity sha512-I/jbm7E3xamiFqn8NLwyhZkDjCb0lTFIykNxIWwDwHsTlU+8hR4gDQmrXTWdyDHG9k1i2uFeHMhoMAtERNWp4w== dependencies: - lodash "^4.17.15" + lodash.zipobject "^4.1.3" -eslint-plugin-import@^2.18.2: - version "2.27.5" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.27.5.tgz#876a6d03f52608a3e5bb439c2550588e51dd6c65" - integrity sha512-LmEt3GVofgiGuiE+ORpnvP+kAm3h6MLZJ4Q5HCyHADofsb4VzXFsRiWj3c0OFiV+3DWFh0qg3v9gcPlfc3zRow== +eslint-plugin-import@^2.27.5: + version "2.29.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.29.0.tgz#8133232e4329ee344f2f612885ac3073b0b7e155" + integrity sha512-QPOO5NO6Odv5lpoTkddtutccQjysJuFxoPS7fAHO+9m9udNHvTCPSAMW9zGAYj8lAIdr40I8yPCdUYrncXtrwg== dependencies: - array-includes "^3.1.6" - array.prototype.flat "^1.3.1" - array.prototype.flatmap "^1.3.1" + array-includes "^3.1.7" + array.prototype.findlastindex "^1.2.3" + array.prototype.flat "^1.3.2" + array.prototype.flatmap "^1.3.2" debug "^3.2.7" doctrine "^2.1.0" - eslint-import-resolver-node "^0.3.7" - eslint-module-utils "^2.7.4" - has "^1.0.3" - is-core-module "^2.11.0" + eslint-import-resolver-node "^0.3.9" + eslint-module-utils "^2.8.0" + hasown "^2.0.0" + is-core-module "^2.13.1" is-glob "^4.0.3" minimatch "^3.1.2" - object.values "^1.1.6" - resolve "^1.22.1" - semver "^6.3.0" - tsconfig-paths "^3.14.1" + object.fromentries "^2.0.7" + object.groupby "^1.0.1" + object.values "^1.1.7" + semver "^6.3.1" + tsconfig-paths "^3.14.2" -eslint-plugin-jsx-a11y@^6.2.3: - version "6.7.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.7.1.tgz#fca5e02d115f48c9a597a6894d5bcec2f7a76976" - integrity sha512-63Bog4iIethyo8smBklORknVjB0T2dwB8Mr/hIC+fBS0uyHdYYpzM/Ed+YC8VxTjlXHEWFOdmgwcDn1U2L9VCA== +eslint-plugin-jsx-id-attribute-enforcement@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-id-attribute-enforcement/-/eslint-plugin-jsx-id-attribute-enforcement-1.0.2.tgz#eb72009ef1c2d150bf7466be2b1d0008fe6de61b" + integrity sha512-xWg5lJ+z1/+WByCdtIAepKRx8J8GAeYGw4MmlAkEfdyCpj/UMEb+FVCmEVOJbXdyvTPq8xNfhIW/43eInykHPg== dependencies: - "@babel/runtime" "^7.20.7" - aria-query "^5.1.3" - array-includes "^3.1.6" - array.prototype.flatmap "^1.3.1" - ast-types-flow "^0.0.7" - axe-core "^4.6.2" - axobject-query "^3.1.1" - damerau-levenshtein "^1.0.8" - emoji-regex "^9.2.2" - has "^1.0.3" - jsx-ast-utils "^3.3.3" - language-tags "=1.0.5" - minimatch "^3.1.2" - object.entries "^1.1.6" - object.fromentries "^2.0.6" - semver "^6.3.0" + requireindex "~1.1.0" -eslint-plugin-prettier@^3.1.0: - version "3.4.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-3.4.1.tgz#e9ddb200efb6f3d05ffe83b1665a716af4a387e5" - integrity sha512-htg25EUYUeIhKHXjOinK4BgCcDwtLHjqaxCDsMy5nbnUMkKFvIhMVCp+5GFUXQ4Nr8lBsPqtGAqBenbpFqAA2g== +eslint-plugin-prettier@^4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-4.2.1.tgz#651cbb88b1dab98bfd42f017a12fa6b2d993f94b" + integrity sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ== dependencies: prettier-linter-helpers "^1.0.0" -eslint-plugin-react-hooks@^2.2.0: - version "2.5.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-2.5.1.tgz#4ef5930592588ce171abeb26f400c7fbcbc23cd0" - integrity sha512-Y2c4b55R+6ZzwtTppKwSmK/Kar8AdLiC2f9NADCuxbcTgPPg41Gyqa6b9GppgXSvCtkRw43ZE86CT5sejKC6/g== +eslint-plugin-react-hooks@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz#4c3e697ad95b77e93f8646aaa1630c1ba607edd3" + integrity sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g== -eslint-plugin-react@^7.14.3: - version "7.32.2" - resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.32.2.tgz#e71f21c7c265ebce01bcbc9d0955170c55571f10" - integrity sha512-t2fBMa+XzonrrNkyVirzKlvn5RXzzPwRHtMvLAtVZrt8oxgnTQaYbU6SXTOO1mwQgp1y5+toMSKInnzGr0Knqg== +eslint-plugin-react@^7.32.2: + version "7.33.2" + resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.33.2.tgz#69ee09443ffc583927eafe86ffebb470ee737608" + integrity sha512-73QQMKALArI8/7xGLNI/3LylrEYrlKZSb5C9+q3OtOewTnMQi5cT+aE9E41sLCmli3I9PGGmD1yiZydyo4FEPw== dependencies: array-includes "^3.1.6" array.prototype.flatmap "^1.3.1" array.prototype.tosorted "^1.1.1" doctrine "^2.1.0" + es-iterator-helpers "^1.0.12" estraverse "^5.3.0" jsx-ast-utils "^2.4.1 || ^3.0.0" minimatch "^3.1.2" @@ -10282,10 +12051,10 @@ eslint-plugin-react@^7.14.3: object.values "^1.1.6" prop-types "^15.8.1" resolve "^2.0.0-next.4" - semver "^6.3.0" + semver "^6.3.1" string.prototype.matchall "^4.0.8" -eslint-scope@5.1.1, eslint-scope@^5.0.0: +eslint-scope@5.1.1, eslint-scope@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== @@ -10293,105 +12062,92 @@ eslint-scope@5.1.1, eslint-scope@^5.0.0: esrecurse "^4.3.0" estraverse "^4.1.1" -eslint-scope@^4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.3.tgz#ca03833310f6889a3264781aa82e63eb9cfe7848" - integrity sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg== - dependencies: - esrecurse "^4.1.0" - estraverse "^4.1.1" - -eslint-utils@^1.4.2, eslint-utils@^1.4.3: - version "1.4.3" - resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.4.3.tgz#74fec7c54d0776b6f67e0251040b5806564e981f" - integrity sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q== - dependencies: - eslint-visitor-keys "^1.1.0" - -eslint-utils@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.1.0.tgz#d2de5e03424e707dc10c74068ddedae708741b27" - integrity sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg== +eslint-scope@^7.2.2: + version "7.2.2" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.2.2.tgz#deb4f92563390f32006894af62a22dba1c46423f" + integrity sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg== dependencies: - eslint-visitor-keys "^1.1.0" - -eslint-visitor-keys@^1.0.0, eslint-visitor-keys@^1.1.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e" - integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== + esrecurse "^4.3.0" + estraverse "^5.2.0" -eslint@^6.1.0: - version "6.8.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.8.0.tgz#62262d6729739f9275723824302fb227c8c93ffb" - integrity sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig== - dependencies: - "@babel/code-frame" "^7.0.0" - ajv "^6.10.0" - chalk "^2.1.0" - cross-spawn "^6.0.5" - debug "^4.0.1" +eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4.3: + version "3.4.3" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz#0cd72fe8550e3c2eae156a96a4dddcd1c8ac5800" + integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== + +eslint@^8.41.0: + version "8.54.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.54.0.tgz#588e0dd4388af91a2e8fa37ea64924074c783537" + integrity sha512-NY0DfAkM8BIZDVl6PgSa1ttZbx3xHgJzSNJKYcQglem6CppHyMhRIQkBVSSMaSRnLhig3jsDbEzOjwCVt4AmmA== + dependencies: + "@eslint-community/eslint-utils" "^4.2.0" + "@eslint-community/regexpp" "^4.6.1" + "@eslint/eslintrc" "^2.1.3" + "@eslint/js" "8.54.0" + "@humanwhocodes/config-array" "^0.11.13" + "@humanwhocodes/module-importer" "^1.0.1" + "@nodelib/fs.walk" "^1.2.8" + "@ungap/structured-clone" "^1.2.0" + ajv "^6.12.4" + chalk "^4.0.0" + cross-spawn "^7.0.2" + debug "^4.3.2" doctrine "^3.0.0" - eslint-scope "^5.0.0" - eslint-utils "^1.4.3" - eslint-visitor-keys "^1.1.0" - espree "^6.1.2" - esquery "^1.0.1" + escape-string-regexp "^4.0.0" + eslint-scope "^7.2.2" + eslint-visitor-keys "^3.4.3" + espree "^9.6.1" + esquery "^1.4.2" esutils "^2.0.2" - file-entry-cache "^5.0.1" - functional-red-black-tree "^1.0.1" - glob-parent "^5.0.0" - globals "^12.1.0" - ignore "^4.0.6" - import-fresh "^3.0.0" + fast-deep-equal "^3.1.3" + file-entry-cache "^6.0.1" + find-up "^5.0.0" + glob-parent "^6.0.2" + globals "^13.19.0" + graphemer "^1.4.0" + ignore "^5.2.0" imurmurhash "^0.1.4" - inquirer "^7.0.0" is-glob "^4.0.0" - js-yaml "^3.13.1" + is-path-inside "^3.0.3" + js-yaml "^4.1.0" json-stable-stringify-without-jsonify "^1.0.1" - levn "^0.3.0" - lodash "^4.17.14" - minimatch "^3.0.4" - mkdirp "^0.5.1" + levn "^0.4.1" + lodash.merge "^4.6.2" + minimatch "^3.1.2" natural-compare "^1.4.0" - optionator "^0.8.3" - progress "^2.0.0" - regexpp "^2.0.1" - semver "^6.1.2" - strip-ansi "^5.2.0" - strip-json-comments "^3.0.1" - table "^5.2.3" + optionator "^0.9.3" + strip-ansi "^6.0.1" text-table "^0.2.0" - v8-compile-cache "^2.0.3" -espree@^6.1.2: - version "6.2.1" - resolved "https://registry.yarnpkg.com/espree/-/espree-6.2.1.tgz#77fc72e1fd744a2052c20f38a5b575832e82734a" - integrity sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw== +espree@^9.6.0, espree@^9.6.1: + version "9.6.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-9.6.1.tgz#a2a17b8e434690a5432f2f8018ce71d331a48c6f" + integrity sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ== dependencies: - acorn "^7.1.1" - acorn-jsx "^5.2.0" - eslint-visitor-keys "^1.1.0" + acorn "^8.9.0" + acorn-jsx "^5.3.2" + eslint-visitor-keys "^3.4.1" esprima@^4.0.0, esprima@^4.0.1, esprima@~4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== -esquery@^1.0.1: +esquery@^1.4.2: version "1.5.0" resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.5.0.tgz#6ce17738de8577694edd7361c57182ac8cb0db0b" integrity sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg== dependencies: estraverse "^5.1.0" -esrecurse@^4.1.0, esrecurse@^4.3.0: +esrecurse@^4.3.0: version "4.3.0" resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== dependencies: estraverse "^5.2.0" -estraverse@^4.1.1, estraverse@^4.2.0: +estraverse@^4.1.1: version "4.3.0" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== @@ -10401,72 +12157,12 @@ estraverse@^5.1.0, estraverse@^5.2.0, estraverse@^5.3.0: resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== -estree-to-babel@^3.1.0: - version "3.2.1" - resolved "https://registry.yarnpkg.com/estree-to-babel/-/estree-to-babel-3.2.1.tgz#82e78315275c3ca74475fdc8ac1a5103c8a75bf5" - integrity sha512-YNF+mZ/Wu2FU/gvmzuWtYc8rloubL7wfXCTgouFrnjGVXPA/EeYYA7pupXWrb3Iv1cTBeSSxxJIbK23l4MRNqg== - dependencies: - "@babel/traverse" "^7.1.6" - "@babel/types" "^7.2.0" - c8 "^7.6.0" - -estree-util-attach-comments@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/estree-util-attach-comments/-/estree-util-attach-comments-2.1.1.tgz#ee44f4ff6890ee7dfb3237ac7810154c94c63f84" - integrity sha512-+5Ba/xGGS6mnwFbXIuQiDPTbuTxuMCooq3arVv7gPZtYpjp+VXH/NkHAP35OOefPhNG/UGqU3vt/LTABwcHX0w== - dependencies: - "@types/estree" "^1.0.0" - -estree-util-build-jsx@^2.0.0: - version "2.2.2" - resolved "https://registry.yarnpkg.com/estree-util-build-jsx/-/estree-util-build-jsx-2.2.2.tgz#32f8a239fb40dc3f3dca75bb5dcf77a831e4e47b" - integrity sha512-m56vOXcOBuaF+Igpb9OPAy7f9w9OIkb5yhjsZuaPm7HoGi4oTOQi0h2+yZ+AtKklYFZ+rPC4n0wYCJCEU1ONqg== - dependencies: - "@types/estree-jsx" "^1.0.0" - estree-util-is-identifier-name "^2.0.0" - estree-walker "^3.0.0" - -estree-util-is-identifier-name@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/estree-util-is-identifier-name/-/estree-util-is-identifier-name-1.1.0.tgz#2e3488ea06d9ea2face116058864f6370b37456d" - integrity sha512-OVJZ3fGGt9By77Ix9NhaRbzfbDV/2rx9EP7YIDJTmsZSEc5kYn2vWcNccYyahJL2uAQZK2a5Or2i0wtIKTPoRQ== - -estree-util-is-identifier-name@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/estree-util-is-identifier-name/-/estree-util-is-identifier-name-2.1.0.tgz#fb70a432dcb19045e77b05c8e732f1364b4b49b2" - integrity sha512-bEN9VHRyXAUOjkKVQVvArFym08BTWB0aJPppZZr0UNyAqWsLaVfAqP7hbaTJjzHifmB5ebnR8Wm7r7yGN/HonQ== - -estree-util-value-to-estree@^1.0.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/estree-util-value-to-estree/-/estree-util-value-to-estree-1.3.0.tgz#1d3125594b4d6680f666644491e7ac1745a3df49" - integrity sha512-Y+ughcF9jSUJvncXwqRageavjrNPAI+1M/L3BI3PyLp1nmgYTGUXU6t5z1Y7OWuThoDdhPME07bQU+d5LxdJqw== - dependencies: - is-plain-obj "^3.0.0" - -estree-util-visit@^1.0.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/estree-util-visit/-/estree-util-visit-1.2.1.tgz#8bc2bc09f25b00827294703835aabee1cc9ec69d" - integrity sha512-xbgqcrkIVbIG+lI/gzbvd9SGTJL4zqJKBFttUl5pP27KhAjtMKbX/mQXJ7qgyXpMgVy/zvpm0xoQQaGL8OloOw== - dependencies: - "@types/estree-jsx" "^1.0.0" - "@types/unist" "^2.0.0" - -estree-walker@2.0.2, estree-walker@^2.0.1: +estree-walker@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac" integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w== -estree-walker@^0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-0.6.1.tgz#53049143f40c6eb918b23671d1fe3219f3a1b362" - integrity sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w== - -estree-walker@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-1.0.1.tgz#31bc5d612c96b704106b477e6dd5d8aa138cb700" - integrity sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg== - -estree-walker@^3.0.0: +estree-walker@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-3.0.3.tgz#67c3e549ec402a487b4fc193d1953a524752340d" integrity sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g== @@ -10478,12 +12174,22 @@ esutils@^2.0.2: resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== -etag@1.8.1, etag@~1.8.1: +etag@~1.8.1: version "1.8.1" resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== -ethers@^5.7.2: +ethereum-cryptography@^2.1.3: + version "2.2.0" + resolved "https://registry.yarnpkg.com/ethereum-cryptography/-/ethereum-cryptography-2.2.0.tgz#06e2d9c0d89f98ffc6a83818f55bf85afecd50dc" + integrity sha512-hsm9JhfytIf8QME/3B7j4bc8V+VdTU+Vas1aJlvIS96ffoNAosudXvGoEvWmc7QZYdkC8mrMJz9r0fcbw7GyCA== + dependencies: + "@noble/curves" "1.4.0" + "@noble/hashes" "1.4.0" + "@scure/bip32" "1.4.0" + "@scure/bip39" "1.3.0" + +ethers@5.7.2: version "5.7.2" resolved "https://registry.yarnpkg.com/ethers/-/ethers-5.7.2.tgz#3a7deeabbb8c030d4126b24f84e525466145872e" integrity sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg== @@ -10519,23 +12225,39 @@ ethers@^5.7.2: "@ethersproject/web" "5.7.1" "@ethersproject/wordlists" "5.7.0" -eval@0.1.6: - version "0.1.6" - resolved "https://registry.yarnpkg.com/eval/-/eval-0.1.6.tgz#9620d7d8c85515e97e6b47c5814f46ae381cb3cc" - integrity sha512-o0XUw+5OGkXw4pJZzQoXUk+H87DHuC+7ZE//oSrRGtatTmr12oTnLfg6QOq9DyTt0c/p4TwzgmkKrBzWTSizyQ== +ethers@^6.13.2: + version "6.13.2" + resolved "https://registry.yarnpkg.com/ethers/-/ethers-6.13.2.tgz#4b67d4b49e69b59893931a032560999e5e4419fe" + integrity sha512-9VkriTTed+/27BGuY1s0hf441kqwHJ1wtN2edksEtiRvXx+soxRX3iSXTfFqq2+YwrOqbDoTHjIhQnjJRlzKmg== dependencies: - require-like ">= 0.1.1" + "@adraffy/ens-normalize" "1.10.1" + "@noble/curves" "1.2.0" + "@noble/hashes" "1.3.2" + "@types/node" "18.15.13" + aes-js "4.0.0-beta.5" + tslib "2.4.0" + ws "8.17.1" -eventemitter3@4.0.7, eventemitter3@^4.0.7: +eventemitter3@^4.0.7: version "4.0.7" resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== -events@^3.0.0, events@^3.2.0, events@^3.3.0: +eventemitter3@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-5.0.1.tgz#53f5ffd0a492ac800721bb42c66b841de96423c4" + integrity sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA== + +events@^3.2.0, events@^3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== +eventsource@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/eventsource/-/eventsource-2.0.2.tgz#76dfcc02930fb2ff339520b6d290da573a9e8508" + integrity sha512-IzUmBGPR3+oUG9dUeXynyNmf91/3zUSJg1lCktzKw47OXuhco54U3r9B7O4XX+Rb1Itm9OZ2b0RkTs10bICOxA== + evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" @@ -10544,12 +12266,22 @@ evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: md5.js "^1.3.4" safe-buffer "^5.1.1" -exec-sh@^0.3.2: - version "0.3.6" - resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.3.6.tgz#ff264f9e325519a60cb5e273692943483cca63bc" - integrity sha512-nQn+hI3yp+oD0huYhKwvYI32+JFeq+XkNcD1GAo3Y/MjxsfVGmrrzrnzjWiNY6f+pUCP440fThsFh5gZrRAU/w== +execa@7.2.0, execa@^7.1.1: + version "7.2.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-7.2.0.tgz#657e75ba984f42a70f38928cedc87d6f2d4fe4e9" + integrity sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA== + dependencies: + cross-spawn "^7.0.3" + get-stream "^6.0.1" + human-signals "^4.3.0" + is-stream "^3.0.0" + merge-stream "^2.0.0" + npm-run-path "^5.1.0" + onetime "^6.0.0" + signal-exit "^3.0.7" + strip-final-newline "^3.0.0" -execa@5.1.1, execa@^5.1.1: +execa@^5.0.0, execa@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== @@ -10564,162 +12296,58 @@ execa@5.1.1, execa@^5.1.1: signal-exit "^3.0.3" strip-final-newline "^2.0.0" -execa@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" - integrity sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA== - dependencies: - cross-spawn "^6.0.0" - get-stream "^4.0.0" - is-stream "^1.1.0" - npm-run-path "^2.0.0" - p-finally "^1.0.0" - signal-exit "^3.0.0" - strip-eof "^1.0.0" - -execa@^3.2.0: - version "3.4.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-3.4.0.tgz#c08ed4550ef65d858fac269ffc8572446f37eb89" - integrity sha512-r9vdGQk4bmCuK1yKQu1KTwcT2zwfWdbdaXfCtAh+5nU/4fSX+JAb7vZGvI5naJrQlvONrEB20jeruESI69530g== - dependencies: - cross-spawn "^7.0.0" - get-stream "^5.0.0" - human-signals "^1.1.1" - is-stream "^2.0.0" - merge-stream "^2.0.0" - npm-run-path "^4.0.0" - onetime "^5.1.0" - p-finally "^2.0.0" - signal-exit "^3.0.2" - strip-final-newline "^2.0.0" - -execa@^4.0.3: - version "4.1.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-4.1.0.tgz#4e5491ad1572f2f17a77d388c6c857135b22847a" - integrity sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA== - dependencies: - cross-spawn "^7.0.0" - get-stream "^5.0.0" - human-signals "^1.1.1" - is-stream "^2.0.0" - merge-stream "^2.0.0" - npm-run-path "^4.0.0" - onetime "^5.1.0" - signal-exit "^3.0.2" - strip-final-newline "^2.0.0" - -execa@^7.1.1: - version "7.1.1" - resolved "https://registry.yarnpkg.com/execa/-/execa-7.1.1.tgz#3eb3c83d239488e7b409d48e8813b76bb55c9c43" - integrity sha512-wH0eMf/UXckdUYnO21+HDztteVv05rq2GXksxT4fCGeHkBhw1DROXh40wcjMcRqDOWE7iPJ4n3M7e2+YFP+76Q== +execa@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/execa/-/execa-8.0.1.tgz#51f6a5943b580f963c3ca9c6321796db8cc39b8c" + integrity sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg== dependencies: cross-spawn "^7.0.3" - get-stream "^6.0.1" - human-signals "^4.3.0" + get-stream "^8.0.1" + human-signals "^5.0.0" is-stream "^3.0.0" merge-stream "^2.0.0" npm-run-path "^5.1.0" onetime "^6.0.0" - signal-exit "^3.0.7" + signal-exit "^4.1.0" strip-final-newline "^3.0.0" -exit-hook@2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/exit-hook/-/exit-hook-2.2.1.tgz#007b2d92c6428eda2b76e7016a34351586934593" - integrity sha512-eNTPlAD67BmP31LDINZ3U7HSF8l57TxOY2PmBJ1shpCvpnxBF93mWCE8YHBnXs8qiUZJc9WDcWIeC3a2HIAMfw== - -exit@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" - integrity sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ== - -expand-brackets@^2.1.4: - version "2.1.4" - resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" - integrity sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA== - dependencies: - debug "^2.3.3" - define-property "^0.2.5" - extend-shallow "^2.0.1" - posix-character-classes "^0.1.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" - -expand-template@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/expand-template/-/expand-template-2.0.3.tgz#6e14b3fcee0f3a6340ecb57d2e8918692052a47c" - integrity sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg== - -expect@^25.5.0: - version "25.5.0" - resolved "https://registry.yarnpkg.com/expect/-/expect-25.5.0.tgz#f07f848712a2813bb59167da3fb828ca21f58bba" - integrity sha512-w7KAXo0+6qqZZhovCaBVPSIqQp7/UTcx4M9uKt2m6pd2VB1voyC8JizLRqeEqud3AAVP02g+hbErDu5gu64tlA== - dependencies: - "@jest/types" "^25.5.0" - ansi-styles "^4.0.0" - jest-get-type "^25.2.6" - jest-matcher-utils "^25.5.0" - jest-message-util "^25.5.0" - jest-regex-util "^25.2.6" - -express@^4.17.1: - version "4.18.2" - resolved "https://registry.yarnpkg.com/express/-/express-4.18.2.tgz#3fabe08296e930c796c19e3c516979386ba9fd59" - integrity sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ== +express@^4.17.3: + version "4.21.0" + resolved "https://registry.yarnpkg.com/express/-/express-4.21.0.tgz#d57cb706d49623d4ac27833f1cbc466b668eb915" + integrity sha512-VqcNGcj/Id5ZT1LZ/cfihi3ttTn+NJmkli2eZADigjq29qTlWi/hAQ43t/VLPq8+UX06FCEx3ByOYet6ZFblng== dependencies: accepts "~1.3.8" array-flatten "1.1.1" - body-parser "1.20.1" + body-parser "1.20.3" content-disposition "0.5.4" content-type "~1.0.4" - cookie "0.5.0" + cookie "0.6.0" cookie-signature "1.0.6" debug "2.6.9" depd "2.0.0" - encodeurl "~1.0.2" + encodeurl "~2.0.0" escape-html "~1.0.3" etag "~1.8.1" - finalhandler "1.2.0" + finalhandler "1.3.1" fresh "0.5.2" http-errors "2.0.0" - merge-descriptors "1.0.1" + merge-descriptors "1.0.3" methods "~1.1.2" on-finished "2.4.1" parseurl "~1.3.3" - path-to-regexp "0.1.7" + path-to-regexp "0.1.10" proxy-addr "~2.0.7" - qs "6.11.0" + qs "6.13.0" range-parser "~1.2.1" safe-buffer "5.2.1" - send "0.18.0" - serve-static "1.15.0" + send "0.19.0" + serve-static "1.16.2" setprototypeof "1.2.0" statuses "2.0.1" type-is "~1.6.18" utils-merge "1.0.1" vary "~1.1.2" -extend-shallow@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" - integrity sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug== - dependencies: - is-extendable "^0.1.0" - -extend-shallow@^3.0.0, extend-shallow@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" - integrity sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q== - dependencies: - assign-symbols "^1.0.0" - is-extendable "^1.0.1" - -extend@^3.0.0, extend@~3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" - integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== - external-editor@^3.0.3: version "3.1.0" resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495" @@ -10729,30 +12357,6 @@ external-editor@^3.0.3: iconv-lite "^0.4.24" tmp "^0.0.33" -extglob@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" - integrity sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw== - dependencies: - array-unique "^0.3.2" - define-property "^1.0.0" - expand-brackets "^2.1.4" - extend-shallow "^2.0.1" - fragment-cache "^0.2.1" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" - -extsprintf@1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" - integrity sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g== - -extsprintf@^1.2.0: - version "1.4.1" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.1.tgz#8d172c064867f235c0c84a596806d279bf4bcc07" - integrity sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA== - eyes@^0.1.8: version "0.1.8" resolved "https://registry.yarnpkg.com/eyes/-/eyes-0.1.8.tgz#62cf120234c683785d902348a800ef3e0cc20bc0" @@ -10768,26 +12372,15 @@ fast-deep-equal@^2.0.1: resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49" integrity sha512-bCK/2Z4zLidyB4ReuIsvALH6w31YfAQDmXMqMx6FyfHqvBxtjC0eRumeSu4Bs3XtXwpyIywtSTrVT99BxY1f9w== -fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: - version "3.1.3" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" - integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== - -fast-diff@^1.1.2: - version "1.2.0" - resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.2.0.tgz#73ee11982d86caaf7959828d519cfe927fac5f03" - integrity sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w== - -fast-glob@3.2.11: - version "3.2.11" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.11.tgz#a1172ad95ceb8a16e20caa5c5e56480e5129c1d9" - integrity sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew== - dependencies: - "@nodelib/fs.stat" "^2.0.2" - "@nodelib/fs.walk" "^1.2.3" - glob-parent "^5.1.2" - merge2 "^1.3.0" - micromatch "^4.0.4" +fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== + +fast-diff@^1.1.2: + version "1.3.0" + resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.3.0.tgz#ece407fa550a64d638536cd727e129c61616e0f0" + integrity sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw== fast-glob@3.2.7: version "3.2.7" @@ -10800,22 +12393,10 @@ fast-glob@3.2.7: merge2 "^1.3.0" micromatch "^4.0.4" -fast-glob@^2.2.6: - version "2.2.7" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-2.2.7.tgz#6953857c3afa475fff92ee6015d52da70a4cd39d" - integrity sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw== - dependencies: - "@mrmlnc/readdir-enhanced" "^2.2.1" - "@nodelib/fs.stat" "^1.1.2" - glob-parent "^3.1.0" - is-glob "^4.0.0" - merge2 "^1.2.3" - micromatch "^3.1.10" - -fast-glob@^3.0.3, fast-glob@^3.2.7, fast-glob@^3.2.9: - version "3.2.12" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.12.tgz#7f39ec99c2e6ab030337142da9e0c18f37afae80" - integrity sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w== +fast-glob@^3.2.9: + version "3.3.2" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.2.tgz#a904501e57cfdd2ffcded45e99a54fef55e46129" + integrity sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow== dependencies: "@nodelib/fs.stat" "^2.0.2" "@nodelib/fs.walk" "^1.2.3" @@ -10828,16 +12409,21 @@ fast-json-parse@^1.0.3: resolved "https://registry.yarnpkg.com/fast-json-parse/-/fast-json-parse-1.0.3.tgz#43e5c61ee4efa9265633046b770fb682a7577c4d" integrity sha512-FRWsaZRWEJ1ESVNbDWmsAlqDk96gPQezzLghafp5J4GUKjbCz3OkAHuZs5TuPEtkbVQERysLp9xv6c24fBm8Aw== -fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0: +fast-json-stable-stringify@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== -fast-levenshtein@~2.0.6: +fast-levenshtein@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== +fast-redact@^3.0.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/fast-redact/-/fast-redact-3.3.0.tgz#7c83ce3a7be4898241a46560d51de10f653f7634" + integrity sha512-6T5V1QK1u4oF+ATxs1lWUmlEk6P2T9HqJG3e2DnHOdVgZy2rFJBoEnrIedcTXlkAHU/zKC+7KETJ+KGGKwxgMQ== + fast-stable-stringify@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fast-stable-stringify/-/fast-stable-stringify-1.0.0.tgz#5c5543462b22aeeefd36d05b34e51c78cb86d313" @@ -10850,27 +12436,13 @@ fastq@^1.6.0: dependencies: reusify "^1.0.4" -fault@^1.0.2: +fault@^1.0.0, fault@^1.0.2: version "1.0.4" resolved "https://registry.yarnpkg.com/fault/-/fault-1.0.4.tgz#eafcfc0a6d214fc94601e170df29954a4f842f13" integrity sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA== dependencies: format "^0.2.0" -fault@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/fault/-/fault-2.0.1.tgz#d47ca9f37ca26e4bd38374a7c500b5a384755b6c" - integrity sha512-WtySTkS4OKev5JtpHXnib4Gxiurzh5NCGvWrFaZ34m6JehfTUhKZvn9njTfw48t6JumVQOmrKqpmGcdwxnhqBQ== - dependencies: - format "^0.2.0" - -fb-watchman@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.2.tgz#e9524ee6b5c77e9e5001af0f85f3adbb8623255c" - integrity sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA== - dependencies: - bser "2.1.1" - fbjs@^0.8.4: version "0.8.18" resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.18.tgz#9835e0addb9aca2eff53295cd79ca1cfc7c9662a" @@ -10885,14 +12457,9 @@ fbjs@^0.8.4: ua-parser-js "^0.7.30" fetch-retry@^5.0.2: - version "5.0.4" - resolved "https://registry.yarnpkg.com/fetch-retry/-/fetch-retry-5.0.4.tgz#06e8e4533030bf6faa00ffbb9450cb9264c23c12" - integrity sha512-LXcdgpdcVedccGg0AZqg+S8lX/FCdwXD92WNZ5k5qsb0irRhSFsBOpcJt7oevyqT2/C2nEE0zSFNdBEpj3YOSw== - -figgy-pudding@^3.5.1: - version "3.5.2" - resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.2.tgz#b4eee8148abb01dcf1d1ac34367d59e12fa61d6e" - integrity sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw== + version "5.0.6" + resolved "https://registry.yarnpkg.com/fetch-retry/-/fetch-retry-5.0.6.tgz#17d0bc90423405b7a88b74355bf364acd2a7fa56" + integrity sha512-3yurQZ2hD9VISAhJJP9bpYFNQrHHBXE2JxxjY5aLEcDi46RmAzJE2OC9FAde0yis5ElW0jTTzs0zfg/Cca4XqQ== figures@3.2.0, figures@^3.0.0: version "3.2.0" @@ -10901,77 +12468,69 @@ figures@3.2.0, figures@^3.0.0: dependencies: escape-string-regexp "^1.0.5" -file-entry-cache@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-5.0.1.tgz#ca0f6efa6dd3d561333fb14515065c2fafdf439c" - integrity sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g== - dependencies: - flat-cache "^2.0.1" - -file-loader@^6.2.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-6.2.0.tgz#baef7cf8e1840df325e4390b4484879480eebe4d" - integrity sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw== +file-entry-cache@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" + integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== dependencies: - loader-utils "^2.0.0" - schema-utils "^3.0.0" + flat-cache "^3.0.4" -file-system-cache@^1.0.5: - version "1.1.0" - resolved "https://registry.yarnpkg.com/file-system-cache/-/file-system-cache-1.1.0.tgz#984de17b976b75a77a27e08d6828137c1aa80fa1" - integrity sha512-IzF5MBq+5CR0jXx5RxPe4BICl/oEhBSXKaL9fLhAXrIfIUS77Hr4vzrYyqYMHN6uTt+BOqi3fDCTjjEBCjERKw== +file-system-cache@2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/file-system-cache/-/file-system-cache-2.3.0.tgz#201feaf4c8cd97b9d0d608e96861bb6005f46fe6" + integrity sha512-l4DMNdsIPsVnKrgEXbJwDJsA5mB8rGwHYERMgqQx/xAUtChPJMre1bXBzDEqqVbWv9AIbFezXMxeEkZDSrXUOQ== dependencies: - fs-extra "^10.1.0" - ramda "^0.28.0" + fs-extra "11.1.1" + ramda "0.29.0" file-uri-to-path@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== -file-uri-to-path@2: - version "2.0.0" - resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-2.0.0.tgz#7b415aeba227d575851e0a5b0c640d7656403fba" - integrity sha512-hjPFI8oE/2iQPVe4gbrJ73Pp+Xfub2+WI2LlXDbsaJBwT5wuMh35WNWVYYTpnz895shtwfyutMFLFywpQAFdLg== - -filelist@^1.0.1: +filelist@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/filelist/-/filelist-1.0.4.tgz#f78978a1e944775ff9e62e744424f215e58352b5" integrity sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q== dependencies: minimatch "^5.0.1" -fill-range@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" - integrity sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ== - dependencies: - extend-shallow "^2.0.1" - is-number "^3.0.0" - repeat-string "^1.6.1" - to-regex-range "^2.1.0" +filesize@^10.0.12: + version "10.1.1" + resolved "https://registry.yarnpkg.com/filesize/-/filesize-10.1.1.tgz#eb98ce885aa73741199748e70e5b7339cc22c5ff" + integrity sha512-L0cdwZrKlwZQkMSFnCflJ6J2Y+5egO/p3vgRSDQGxQt++QbUZe5gMbRO6kg6gzwQDPvq2Fk9AmoxUNfZ5gdqaQ== -fill-range@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" - integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== +filesize@^10.1.2: + version "10.1.2" + resolved "https://registry.yarnpkg.com/filesize/-/filesize-10.1.2.tgz#33bb71c5c134102499f1bc36e6f2863137f6cb0c" + integrity sha512-Dx770ai81ohflojxhU+oG+Z2QGvKdYxgEr9OSA8UVrqhwNHjfH9A8f5NKfg83fEH8ZFA5N5llJo5T3PIoZ4CRA== + +fill-range@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.1.1.tgz#44265d3cac07e3ea7dc247516380643754a05292" + integrity sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg== dependencies: to-regex-range "^5.0.1" -finalhandler@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.2.0.tgz#7d23fe5731b207b4640e4fcd00aec1f9207a7b32" - integrity sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg== +filter-obj@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/filter-obj/-/filter-obj-1.1.0.tgz#9b311112bc6c6127a16e016c6c5d7f19e0805c5b" + integrity sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ== + +finalhandler@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.3.1.tgz#0c575f1d1d324ddd1da35ad7ece3df7d19088019" + integrity sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ== dependencies: debug "2.6.9" - encodeurl "~1.0.2" + encodeurl "~2.0.0" escape-html "~1.0.3" on-finished "2.4.1" parseurl "~1.3.3" statuses "2.0.1" unpipe "~1.0.0" -find-cache-dir@^2.0.0, find-cache-dir@^2.1.0: +find-cache-dir@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-2.1.0.tgz#8d0f94cd13fe43c6c7c261a0d86115ca918c05f7" integrity sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ== @@ -10980,7 +12539,7 @@ find-cache-dir@^2.0.0, find-cache-dir@^2.1.0: make-dir "^2.0.0" pkg-dir "^3.0.0" -find-cache-dir@^3.3.1, find-cache-dir@^3.3.2: +find-cache-dir@^3.0.0, find-cache-dir@^3.3.1: version "3.3.2" resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-3.3.2.tgz#b30c5b6eff0730731aea9bbd9dbecbd80256d64b" integrity sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig== @@ -10989,6 +12548,14 @@ find-cache-dir@^3.3.1, find-cache-dir@^3.3.2: make-dir "^3.0.2" pkg-dir "^4.1.0" +find-cache-dir@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-4.0.0.tgz#a30ee0448f81a3990708f6453633c733e2f6eec2" + integrity sha512-9ZonPT4ZAK4a+1pUPVPZJapbi7O5qbbJPdYw/NOQWZZbVLdDTYM3A4R9z/DpAM08IDaFGsvPgiGZ82WEwUDWjg== + dependencies: + common-path-prefix "^3.0.0" + pkg-dir "^7.0.0" + find-replace@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/find-replace/-/find-replace-3.0.0.tgz#3e7e23d3b05167a76f770c9fbd5258b0def68c38" @@ -11001,13 +12568,12 @@ find-root@^1.1.0: resolved "https://registry.yarnpkg.com/find-root/-/find-root-1.1.0.tgz#abcfc8ba76f708c42a97b3d685b7e9450bfb9ce4" integrity sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng== -find-up@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" - integrity sha512-jvElSjyuo4EMQGoTwo1uJU5pQMwTW5lS1x05zzfJuTIyLR3zwO27LYrxNg+dlvKpGOuGy/MzBdXh80g0ve5+HA== +find-up@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" + integrity sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ== dependencies: - path-exists "^2.0.0" - pinkie-promise "^2.0.0" + locate-path "^2.0.0" find-up@^3.0.0: version "3.0.0" @@ -11032,21 +12598,28 @@ find-up@^5.0.0: locate-path "^6.0.0" path-exists "^4.0.0" -flat-cache@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-2.0.1.tgz#5d296d6f04bda44a4630a301413bdbc2ec085ec0" - integrity sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA== +find-up@^6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-6.3.0.tgz#2abab3d3280b2dc7ac10199ef324c4e002c8c790" + integrity sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw== + dependencies: + locate-path "^7.1.0" + path-exists "^5.0.0" + +find-yarn-workspace-root@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/find-yarn-workspace-root/-/find-yarn-workspace-root-2.0.0.tgz#f47fb8d239c900eb78179aa81b66673eac88f7bd" + integrity sha512-1IMnbjt4KzsQfnhnzNd8wUEgXZ44IzZaZmnLYx7D5FZlaHt2gW20Cri8Q+E/t5tIj4+epTBub+2Zxu/vNILzqQ== dependencies: - flatted "^2.0.0" - rimraf "2.6.3" - write "1.0.3" + micromatch "^4.0.2" flat-cache@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11" - integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== + version "3.2.0" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.2.0.tgz#2c0c2d5040c99b1632771a9d105725c0115363ee" + integrity sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw== dependencies: - flatted "^3.1.0" + flatted "^3.2.9" + keyv "^4.5.3" rimraf "^3.0.2" flat@^5.0.2: @@ -11054,42 +12627,27 @@ flat@^5.0.2: resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== -flatted@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.2.tgz#4575b21e2bcee7434aa9be662f4b7b5f9c2b5138" - integrity sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA== - -flatted@^3.1.0: - version "3.2.7" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.7.tgz#609f39207cb614b89d0765b477cb2d437fbf9787" - integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ== +flatted@^3.2.9: + version "3.2.9" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.9.tgz#7eb4c67ca1ba34232ca9d2d93e9886e611ad7daf" + integrity sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ== -flush-write-stream@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.1.1.tgz#8dd7d873a1babc207d94ead0c2e0e44276ebf2e8" - integrity sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w== - dependencies: - inherits "^2.0.3" - readable-stream "^2.3.6" +flow-parser@0.*: + version "0.222.0" + resolved "https://registry.yarnpkg.com/flow-parser/-/flow-parser-0.222.0.tgz#88decc0e35bc11c011af66dbc2f669589d69a6b2" + integrity sha512-Fq5OkFlFRSMV2EOZW+4qUYMTE0uj8pcLsYJMxXYriSBDpHAF7Ofx3PibCTy3cs5P6vbsry7eYj7Z7xFD49GIOQ== -focus-lock@^0.11.6: - version "0.11.6" - resolved "https://registry.yarnpkg.com/focus-lock/-/focus-lock-0.11.6.tgz#e8821e21d218f03e100f7dc27b733f9c4f61e683" - integrity sha512-KSuV3ur4gf2KqMNoZx3nXNVhqCkn42GuTYCX4tXPEwf0MjpFQmNMiN6m7dXaUXgIoivL6/65agoUMg4RLS0Vbg== +focus-lock@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/focus-lock/-/focus-lock-1.0.0.tgz#2c50d8ce59d3d6608cda2672be9e65812459206c" + integrity sha512-a8Ge6cdKh9za/GZR/qtigTAk7SrGore56EFcoMshClsh7FLk1zwszc/ltuMfKhx56qeuyL/jWQ4J4axou0iJ9w== dependencies: tslib "^2.0.3" -follow-redirects@1.5.10: - version "1.5.10" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.5.10.tgz#7b7a9f9aea2fdff36786a94ff643ed07f4ff5e2a" - integrity sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ== - dependencies: - debug "=3.1.0" - -follow-redirects@^1.10.0, follow-redirects@^1.14.0, follow-redirects@^1.14.4, follow-redirects@^1.14.9, follow-redirects@^1.15.0: - version "1.15.2" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13" - integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA== +follow-redirects@^1.10.0, follow-redirects@^1.14.0, follow-redirects@^1.14.9, follow-redirects@^1.15.0, follow-redirects@^1.15.6: + version "1.15.6" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.6.tgz#7f815c0cda4249c74ff09e95ef97c23b5fd0399b" + integrity sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA== for-each@^0.3.3: version "0.3.3" @@ -11098,64 +12656,31 @@ for-each@^0.3.3: dependencies: is-callable "^1.1.3" -for-in@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" - integrity sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ== - -foreground-child@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-2.0.0.tgz#71b32800c9f15aa8f2f83f4a6bd9bff35d861a53" - integrity sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA== +foreground-child@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-3.1.1.tgz#1d173e776d75d2772fed08efe4a0de1ea1b12d0d" + integrity sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg== dependencies: cross-spawn "^7.0.0" - signal-exit "^3.0.2" - -forever-agent@~0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" - integrity sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw== - -fork-ts-checker-webpack-plugin@^4.1.6: - version "4.1.6" - resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-4.1.6.tgz#5055c703febcf37fa06405d400c122b905167fc5" - integrity sha512-DUxuQaKoqfNne8iikd14SAkh5uw4+8vNifp6gmA73yYNS6ywLIWSLD/n/mBzHQRpW3J7rbATEakmiA8JvkTyZw== - dependencies: - "@babel/code-frame" "^7.5.5" - chalk "^2.4.1" - micromatch "^3.1.10" - minimatch "^3.0.4" - semver "^5.6.0" - tapable "^1.0.0" - worker-rpc "^0.1.0" + signal-exit "^4.0.1" -fork-ts-checker-webpack-plugin@^6.0.4: - version "6.5.3" - resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.5.3.tgz#eda2eff6e22476a2688d10661688c47f611b37f3" - integrity sha512-SbH/l9ikmMWycd5puHJKTkZJKddF4iRLyW3DeZ08HTI7NGyLS38MXd/KGgeWumQO7YNQbW2u/NtPT2YowbPaGQ== +fork-ts-checker-webpack-plugin@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-8.0.0.tgz#dae45dfe7298aa5d553e2580096ced79b6179504" + integrity sha512-mX3qW3idpueT2klaQXBzrIM/pHw+T0B/V9KHEvNrqijTq9NFnMZU6oreVxDYcf33P8a5cW+67PjodNHthGnNVg== dependencies: - "@babel/code-frame" "^7.8.3" - "@types/json-schema" "^7.0.5" - chalk "^4.1.0" - chokidar "^3.4.2" - cosmiconfig "^6.0.0" + "@babel/code-frame" "^7.16.7" + chalk "^4.1.2" + chokidar "^3.5.3" + cosmiconfig "^7.0.1" deepmerge "^4.2.2" - fs-extra "^9.0.0" - glob "^7.1.6" - memfs "^3.1.2" + fs-extra "^10.0.0" + memfs "^3.4.1" minimatch "^3.0.4" - schema-utils "2.7.0" - semver "^7.3.2" - tapable "^1.0.0" - -form-data@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.1.tgz#ebd53791b78356a99af9a300d4282c4d5eb9755f" - integrity sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg== - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.8" - mime-types "^2.1.12" + node-abort-controller "^3.0.1" + schema-utils "^3.1.1" + semver "^7.3.5" + tapable "^2.2.1" form-data@^4.0.0: version "4.0.0" @@ -11166,15 +12691,6 @@ form-data@^4.0.0: combined-stream "^1.0.8" mime-types "^2.1.12" -form-data@~2.3.2: - version "2.3.3" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" - integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.6" - mime-types "^2.1.12" - format@^0.2.0: version "0.2.2" resolved "https://registry.yarnpkg.com/format/-/format-0.2.2.tgz#d6170107e9efdc4ed30c9dc39016df942b5cb58b" @@ -11185,50 +12701,26 @@ forwarded@0.2.0: resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== -fragment-cache@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" - integrity sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA== - dependencies: - map-cache "^0.2.2" - fresh@0.5.2: version "0.5.2" resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== -from2@^2.1.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" - integrity sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g== - dependencies: - inherits "^2.0.1" - readable-stream "^2.0.0" - fs-constants@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== -fs-extra@11.1.0: - version "11.1.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-11.1.0.tgz#5784b102104433bb0e090f48bfc4a30742c357ed" - integrity sha512-0rcTq621PD5jM/e0a3EJoGC/1TC5ZBCERW82LQuwfGnCa1V8w7dpYH1yNu+SLb6E5dkeCBzKEyLGlFrnr+dUyw== +fs-extra@11.1.1, fs-extra@^11.1.0: + version "11.1.1" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-11.1.1.tgz#da69f7c39f3b002378b0954bb6ae7efdc0876e2d" + integrity sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ== dependencies: graceful-fs "^4.2.0" jsonfile "^6.0.1" universalify "^2.0.0" -fs-extra@8.1.0, fs-extra@^8.1.0: - version "8.1.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" - integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g== - dependencies: - graceful-fs "^4.2.0" - jsonfile "^4.0.0" - universalify "^0.1.0" - -fs-extra@^10.0.0, fs-extra@^10.1.0: +fs-extra@^10.0.0: version "10.1.0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.1.0.tgz#02873cfbc4084dde127eaa5f9905eef2325d1abf" integrity sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ== @@ -11237,16 +12729,7 @@ fs-extra@^10.0.0, fs-extra@^10.1.0: jsonfile "^6.0.1" universalify "^2.0.0" -fs-extra@^11.1.0: - version "11.1.1" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-11.1.1.tgz#da69f7c39f3b002378b0954bb6ae7efdc0876e2d" - integrity sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ== - dependencies: - graceful-fs "^4.2.0" - jsonfile "^6.0.1" - universalify "^2.0.0" - -fs-extra@^9.0.0, fs-extra@^9.0.1: +fs-extra@^9.0.0: version "9.1.0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d" integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ== @@ -11263,109 +12746,42 @@ fs-minipass@^2.0.0: dependencies: minipass "^3.0.0" -fs-monkey@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/fs-monkey/-/fs-monkey-1.0.3.tgz#ae3ac92d53bb328efe0e9a1d9541f6ad8d48e2d3" - integrity sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q== - -fs-write-stream-atomic@^1.0.8: - version "1.0.10" - resolved "https://registry.yarnpkg.com/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz#b47df53493ef911df75731e70a9ded0189db40c9" - integrity sha512-gehEzmPn2nAwr39eay+x3X34Ra+M2QlVUTLhkXPjWdeO8RF9kszk116avgBJM3ZyNHgHXBNx+VmPaFC36k0PzA== - dependencies: - graceful-fs "^4.1.2" - iferr "^0.1.5" - imurmurhash "^0.1.4" - readable-stream "1 || 2" +fs-monkey@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/fs-monkey/-/fs-monkey-1.0.5.tgz#fe450175f0db0d7ea758102e1d84096acb925788" + integrity sha512-8uMbBjrhzW76TYgEV27Y5E//W2f/lTFmx78P2w19FZSxarhI/798APGQyuGCwmkNxgwGRhrLfvWyLBvNtuOmew== fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== -fsevents@^1.2.7: - version "1.2.13" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.13.tgz#f325cb0455592428bcf11b383370ef70e3bfcc38" - integrity sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw== - dependencies: - bindings "^1.5.0" - nan "^2.12.1" - -fsevents@^2.1.2, fsevents@~2.3.2: - version "2.3.2" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" - integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== - -ftp@^0.3.10: - version "0.3.10" - resolved "https://registry.yarnpkg.com/ftp/-/ftp-0.3.10.tgz#9197d861ad8142f3e63d5a83bfe4c59f7330885d" - integrity sha512-faFVML1aBx2UoDStmLwv2Wptt4vw5x03xxX172nhA5Y5HBshW5JweqQ2W4xL4dezQTG8inJsuYcpPHHU3X5OTQ== - dependencies: - readable-stream "1.1.x" - xregexp "2.0.0" +fsevents@~2.3.1, fsevents@~2.3.2, fsevents@~2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" + integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== -function-bind@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" - integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== +function-bind@^1.1.1, function-bind@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" + integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== -function.prototype.name@^1.1.0, function.prototype.name@^1.1.5: - version "1.1.5" - resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.5.tgz#cce0505fe1ffb80503e6f9e46cc64e46a12a9621" - integrity sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA== +function.prototype.name@^1.1.5, function.prototype.name@^1.1.6: + version "1.1.6" + resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.6.tgz#cdf315b7d90ee77a4c6ee216c3c3362da07533fd" + integrity sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg== dependencies: call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.19.0" - functions-have-names "^1.2.2" - -functional-red-black-tree@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" - integrity sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g== + define-properties "^1.2.0" + es-abstract "^1.22.1" + functions-have-names "^1.2.3" -functions-have-names@^1.2.2: +functions-have-names@^1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== -gauge@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/gauge/-/gauge-3.0.2.tgz#03bf4441c044383908bcfa0656ad91803259b395" - integrity sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q== - dependencies: - aproba "^1.0.3 || ^2.0.0" - color-support "^1.1.2" - console-control-strings "^1.0.0" - has-unicode "^2.0.1" - object-assign "^4.1.1" - signal-exit "^3.0.0" - string-width "^4.2.3" - strip-ansi "^6.0.1" - wide-align "^1.1.2" - -gauge@~2.7.3: - version "2.7.4" - resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" - integrity sha512-14x4kjc6lkD3ltw589k0NrPD6cCNTD6CWoVUNpB85+DrtONoZn+Rug6xZU5RvSC4+TZPxA5AnBibQYAvZn41Hg== - dependencies: - aproba "^1.0.3" - console-control-strings "^1.0.0" - has-unicode "^2.0.0" - object-assign "^4.1.0" - signal-exit "^3.0.0" - string-width "^1.0.1" - strip-ansi "^3.0.1" - wide-align "^1.1.0" - -generic-names@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/generic-names/-/generic-names-4.0.0.tgz#0bd8a2fd23fe8ea16cbd0a279acd69c06933d9a3" - integrity sha512-ySFolZQfw9FoDb3ed9d80Cm9f0+r7qj+HJkWjeD9RBfpxEVTlVhol+gvaQB/78WbwYfbnNh8nWHHBSlg072y6A== - dependencies: - loader-utils "^3.2.0" - -gensync@^1.0.0-beta.1, gensync@^1.0.0-beta.2: +gensync@^1.0.0-beta.2: version "1.0.0-beta.2" resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== @@ -11375,59 +12791,77 @@ get-caller-file@^2.0.1, get-caller-file@^2.0.5: resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== -get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.0.tgz#7ad1dc0535f3a2904bba075772763e5051f6d05f" - integrity sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q== +get-func-name@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.2.tgz#0d7cf20cd13fda808669ffa88f4ffc7a3943fc41" + integrity sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ== + +get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@^1.2.0, get-intrinsic@^1.2.1, get-intrinsic@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.2.tgz#281b7622971123e1ef4b3c90fd7539306da93f3b" + integrity sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA== dependencies: - function-bind "^1.1.1" - has "^1.0.3" + function-bind "^1.1.2" + has-proto "^1.0.1" has-symbols "^1.0.3" + hasown "^2.0.0" -get-package-type@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" - integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q== - -get-port@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/get-port/-/get-port-4.2.0.tgz#e37368b1e863b7629c43c5a323625f95cf24b119" - integrity sha512-/b3jarXkH8KJoOMQc3uVGHASwGLPq3gSFJ7tgJm2diza+bydJPTGOibin2steecKeOylE8oY2JERlVWkAJO6yw== +get-intrinsic@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.4.tgz#e385f5a4b5227d449c3eabbad05494ef0abbeadd" + integrity sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ== + dependencies: + es-errors "^1.3.0" + function-bind "^1.1.2" + has-proto "^1.0.1" + has-symbols "^1.0.3" + hasown "^2.0.0" -get-port@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/get-port/-/get-port-5.1.1.tgz#0469ed07563479de6efb986baf053dcd7d4e3193" - integrity sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ== +get-nonce@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/get-nonce/-/get-nonce-1.0.1.tgz#fdf3f0278073820d2ce9426c18f07481b1e0cdf3" + integrity sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q== -get-stdin@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe" - integrity sha512-F5aQMywwJ2n85s4hJPTT9RPxGmubonuB10MNYo17/xph174n2MIR33HRguhzVag10O/npM7SPk73LMZNP+FaWw== +get-npm-tarball-url@^2.0.3: + version "2.1.0" + resolved "https://registry.yarnpkg.com/get-npm-tarball-url/-/get-npm-tarball-url-2.1.0.tgz#cbd6bb25884622bc3191c761466c93ac83343213" + integrity sha512-ro+DiMu5DXgRBabqXupW38h7WPZ9+Ad8UjwhvsmmN8w1sU7ab0nzAXvVZ4kqYg57OrqomRtJvepX5/xvFKNtjA== -get-stdin@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-6.0.0.tgz#9e09bf712b360ab9225e812048f71fde9c89657b" - integrity sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g== +get-own-enumerable-keys@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/get-own-enumerable-keys/-/get-own-enumerable-keys-1.0.0.tgz#59bbda0f7e7469c8c74086e08f79f1381b203899" + integrity sha512-PKsK2FSrQCyxcGHsGrLDcK0lx+0Ke+6e8KFFozA9/fIQLhQzPaRvJFdcz7+Axg3jUH/Mq+NI4xa5u/UT2tQskA== -get-stream@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" - integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== +get-pkg-repo@^4.0.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/get-pkg-repo/-/get-pkg-repo-4.2.1.tgz#75973e1c8050c73f48190c52047c4cee3acbf385" + integrity sha512-2+QbHjFRfGB74v/pYWjd5OhU3TDIC2Gv/YKUTk/tCvAz0pkn/Mz6P3uByuBimLOcPvN2jYdScl3xGFSrx0jEcA== dependencies: - pump "^3.0.0" + "@hutson/parse-repository-url" "^3.0.0" + hosted-git-info "^4.0.0" + through2 "^2.0.0" + yargs "^16.2.0" -get-stream@^5.0.0, get-stream@^5.1.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" - integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== - dependencies: - pump "^3.0.0" +get-port-please@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/get-port-please/-/get-port-please-3.1.1.tgz#2556623cddb4801d823c0a6a15eec038abb483be" + integrity sha512-3UBAyM3u4ZBVYDsxOQfJDxEa6XTbpBDrOjp4mf7ExFRt5BKs/QywQQiJsh2B+hxcZLSapWqCRvElUe8DnKcFHA== + +get-port@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/get-port/-/get-port-4.2.0.tgz#e37368b1e863b7629c43c5a323625f95cf24b119" + integrity sha512-/b3jarXkH8KJoOMQc3uVGHASwGLPq3gSFJ7tgJm2diza+bydJPTGOibin2steecKeOylE8oY2JERlVWkAJO6yw== get-stream@^6.0.0, get-stream@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== +get-stream@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-8.0.1.tgz#def9dfd71742cd7754a7761ed43749a27d02eca2" + integrity sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA== + get-symbol-description@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.0.tgz#7fdb81c900101fbd564dd5f1a30af5aadc1e58d6" @@ -11436,36 +12870,20 @@ get-symbol-description@^1.0.0: call-bind "^1.0.2" get-intrinsic "^1.1.1" -get-uri@3: - version "3.0.2" - resolved "https://registry.yarnpkg.com/get-uri/-/get-uri-3.0.2.tgz#f0ef1356faabc70e1f9404fa3b66b2ba9bfc725c" - integrity sha512-+5s0SJbGoyiJTZZ2JTpFPLMPSch72KEqGOTvQsBqg0RBWvwhWUSYZFAtz3TPW0GXJuLBJPts1E241iHg+VRfhg== - dependencies: - "@tootallnate/once" "1" - data-uri-to-buffer "3" - debug "4" - file-uri-to-path "2" - fs-extra "^8.1.0" - ftp "^0.3.10" - -get-value@^2.0.3, get-value@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" - integrity sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA== - -getpass@^0.1.1: - version "0.1.7" - resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" - integrity sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng== - dependencies: - assert-plus "^1.0.0" - -git-hooks-list@1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/git-hooks-list/-/git-hooks-list-1.0.3.tgz#be5baaf78203ce342f2f844a9d2b03dba1b45156" - integrity sha512-Y7wLWcrLUXwk2noSka166byGCvhMtDRpgHdzCno1UQv/n/Hegp++a2xBWJL1lJarnKD3SWaljD+0z1ztqxuKyQ== - -git-raw-commits@^2.0.8: +giget@^1.0.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/giget/-/giget-1.1.3.tgz#574ed901031eafa732347a7990d84bfa6484c51a" + integrity sha512-zHuCeqtfgqgDwvXlR84UNgnJDuUHQcNI5OqWqFxxuk2BshuKbYhJWdxBsEo4PvKqoGh23lUAIvBNpChMLv7/9Q== + dependencies: + colorette "^2.0.20" + defu "^6.1.2" + https-proxy-agent "^7.0.2" + mri "^1.2.0" + node-fetch-native "^1.4.0" + pathe "^1.1.1" + tar "^6.2.0" + +git-raw-commits@^2.0.11, git-raw-commits@^2.0.8: version "2.0.11" resolved "https://registry.yarnpkg.com/git-raw-commits/-/git-raw-commits-2.0.11.tgz#bc3576638071d18655e1cc60d7f524920008d723" integrity sha512-VnctFhw+xfj8Va1xtfEqCUD2XDrbAPSJx+hSrE5K7fGdjZruW7XV+QOrN7LF/RJyvspRiD2I0asWsxFp0ya26A== @@ -11476,6 +12894,14 @@ git-raw-commits@^2.0.8: split2 "^3.0.0" through2 "^4.0.0" +git-remote-origin-url@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/git-remote-origin-url/-/git-remote-origin-url-2.0.0.tgz#5282659dae2107145a11126112ad3216ec5fa65f" + integrity sha512-eU+GGrZgccNJcsDH5LkXR3PB9M958hxc7sbA8DFJjrv9j4L2P/eZfKhM+QD6wyzpiv+b1BpK0XrYCxkovtjSLw== + dependencies: + gitconfiglocal "^1.0.0" + pify "^2.3.0" + git-semver-tags@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/git-semver-tags/-/git-semver-tags-4.1.1.tgz#63191bcd809b0ec3e151ba4751c16c444e5b5780" @@ -11484,42 +12910,38 @@ git-semver-tags@^4.1.1: meow "^8.0.0" semver "^6.0.0" -github-from-package@0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/github-from-package/-/github-from-package-0.0.0.tgz#97fb5d96bfde8973313f20e8288ef9a167fa64ce" - integrity sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw== - -github-slugger@^1.0.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/github-slugger/-/github-slugger-1.5.0.tgz#17891bbc73232051474d68bd867a34625c955f7d" - integrity sha512-wIh+gKBI9Nshz2o46B0B3f5k/W+WI9ZAv6y5Dn5WJ5SK1t0TnDimB4WE5rmTD05ZAIn8HALCZVmCsvj0w0v0lw== - -glob-parent@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" - integrity sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA== +gitconfiglocal@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/gitconfiglocal/-/gitconfiglocal-1.0.0.tgz#41d045f3851a5ea88f03f24ca1c6178114464b9b" + integrity sha512-spLUXeTAVHxDtKsJc8FkFVgFtMdEN9qPGpL23VfSHx4fP4+Ds097IXLvymbnDH8FnmxX5Nr9bPw3A+AQ6mWEaQ== dependencies: - is-glob "^3.1.0" - path-dirname "^1.0.0" + ini "^1.3.2" + +github-slugger@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/github-slugger/-/github-slugger-2.0.0.tgz#52cf2f9279a21eb6c59dd385b410f0c0adda8f1a" + integrity sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw== -glob-parent@^5.0.0, glob-parent@^5.1.2, glob-parent@~5.1.2: +glob-parent@^5.1.2, glob-parent@~5.1.0, glob-parent@~5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== dependencies: is-glob "^4.0.1" -glob-promise@^3.4.0: - version "3.4.0" - resolved "https://registry.yarnpkg.com/glob-promise/-/glob-promise-3.4.0.tgz#b6b8f084504216f702dc2ce8c9bc9ac8866fdb20" - integrity sha512-q08RJ6O+eJn+dVanerAndJwIcumgbDdYiUT7zFQl3Wm1xD6fBKtah7H8ZJChj4wP+8C+QfeVy8xautR7rdmKEw== +glob-parent@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" + integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== dependencies: - "@types/glob" "*" + is-glob "^4.0.3" -glob-to-regexp@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz#8c5a1494d2066c570cc3bfe4496175acc4d502ab" - integrity sha512-Iozmtbqv0noj0uDDqoL0zNq0VBEfK2YFoMAZoxJe4cwphvLR+JskfF30QhXHOR4m3KrE6NLRYw+U9MRXvifyig== +glob-promise@^4.2.0: + version "4.2.2" + resolved "https://registry.yarnpkg.com/glob-promise/-/glob-promise-4.2.2.tgz#15f44bcba0e14219cd93af36da6bb905ff007877" + integrity sha512-xcUzJ8NWN5bktoTIX7eOclO1Npxd/dyVqUJxlLIDasT4C7KZyqlPIwkdJ0Ypiy3p2ZKahTjK4M9uC3sNSfNMzw== + dependencies: + "@types/glob" "^7.1.3" glob-to-regexp@^0.4.1: version "0.4.1" @@ -11538,7 +12960,30 @@ glob@7.1.4: once "^1.3.0" path-is-absolute "^1.0.0" -glob@^7.0.0, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: +glob@^10.0.0, glob@^10.3.7: + version "10.3.10" + resolved "https://registry.yarnpkg.com/glob/-/glob-10.3.10.tgz#0351ebb809fd187fe421ab96af83d3a70715df4b" + integrity sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g== + dependencies: + foreground-child "^3.1.0" + jackspeak "^2.3.5" + minimatch "^9.0.1" + minipass "^5.0.0 || ^6.0.2 || ^7.0.0" + path-scurry "^1.10.1" + +glob@^10.4.1: + version "10.4.5" + resolved "https://registry.yarnpkg.com/glob/-/glob-10.4.5.tgz#f4d9f0b90ffdbab09c9d77f5f29b4262517b0956" + integrity sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg== + dependencies: + foreground-child "^3.1.0" + jackspeak "^3.1.2" + minimatch "^9.0.4" + minipass "^7.1.2" + package-json-from-dist "^1.0.0" + path-scurry "^1.11.1" + +glob@^7.1.3, glob@^7.1.4, glob@^7.2.0: version "7.2.3" resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== @@ -11550,6 +12995,24 @@ glob@^7.0.0, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: once "^1.3.0" path-is-absolute "^1.0.0" +glob@^8.0.3: + version "8.1.0" + resolved "https://registry.yarnpkg.com/glob/-/glob-8.1.0.tgz#d388f656593ef708ee3e34640fdfb99a9fd1c33e" + integrity sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^5.0.1" + once "^1.3.0" + +global-dirs@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-0.1.1.tgz#b319c0dd4607f353f3be9cca4c72fc148c49f445" + integrity sha512-NknMLn7F2J7aflwFOlGdNIuCDpN3VGoSoB+aap3KABFWbHVn1TCgFC+np23J8W2BiZbjfEw3BFBycSMv1AFblg== + dependencies: + ini "^1.3.4" + global@^4.3.2, global@^4.4.0: version "4.4.0" resolved "https://registry.yarnpkg.com/global/-/global-4.4.0.tgz#3e7b105179006a323ed71aafca3e9c57a5cc6406" @@ -11563,47 +13026,21 @@ globals@^11.1.0: resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== -globals@^12.1.0: - version "12.4.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-12.4.0.tgz#a18813576a41b00a24a97e7f815918c2e19925f8" - integrity sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg== - dependencies: - type-fest "^0.8.1" - -globals@^13.2.0: - version "13.20.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-13.20.0.tgz#ea276a1e508ffd4f1612888f9d1bad1e2717bf82" - integrity sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ== +globals@^13.19.0, globals@^13.2.0: + version "13.23.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-13.23.0.tgz#ef31673c926a0976e1f61dab4dca57e0c0a8af02" + integrity sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA== dependencies: type-fest "^0.20.2" -globalthis@^1.0.0, globalthis@^1.0.1, globalthis@^1.0.3: +globalthis@^1.0.1, globalthis@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.3.tgz#5852882a52b80dc301b0660273e1ed082f0b6ccf" integrity sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA== dependencies: define-properties "^1.1.3" -globalyzer@0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/globalyzer/-/globalyzer-0.1.0.tgz#cb76da79555669a1519d5a8edf093afaa0bf1465" - integrity sha512-40oNTM9UfG6aBmuKxk/giHn5nQ8RVz/SS4Ir6zgzOv9/qC3kKZ9v4etGTcJbEl/NyVQH7FGU7d+X1egr57Md2Q== - -globby@10.0.0: - version "10.0.0" - resolved "https://registry.yarnpkg.com/globby/-/globby-10.0.0.tgz#abfcd0630037ae174a88590132c2f6804e291072" - integrity sha512-3LifW9M4joGZasyYPz2A1U74zbC/45fvpXUvO/9KbSa+VV0aGZarWkfdgKyR9sExNP0t0x0ss/UMJpNpcaTspw== - dependencies: - "@types/glob" "^7.1.1" - array-union "^2.1.0" - dir-glob "^3.0.1" - fast-glob "^3.0.3" - glob "^7.1.3" - ignore "^5.1.1" - merge2 "^1.2.3" - slash "^3.0.0" - -globby@^11.0.2, globby@^11.1.0: +globby@^11.0.1, globby@^11.0.2, globby@^11.1.0: version "11.1.0" resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== @@ -11615,25 +13052,6 @@ globby@^11.0.2, globby@^11.1.0: merge2 "^1.4.1" slash "^3.0.0" -globby@^9.2.0: - version "9.2.0" - resolved "https://registry.yarnpkg.com/globby/-/globby-9.2.0.tgz#fd029a706c703d29bdd170f4b6db3a3f7a7cb63d" - integrity sha512-ollPHROa5mcxDEkwg6bPt3QbEf4pDQSNtd6JPL1YvOvAo/7/0VAm9TccUeoTmarjPw4pfUthSCqcyfNB1I3ZSg== - dependencies: - "@types/glob" "^7.1.1" - array-union "^1.0.2" - dir-glob "^2.2.2" - fast-glob "^2.2.6" - glob "^7.1.3" - ignore "^4.0.3" - pify "^4.0.1" - slash "^2.0.0" - -globrex@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/globrex/-/globrex-0.1.2.tgz#dd5d9ec826232730cd6793a5e33a9302985e6098" - integrity sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg== - good-listener@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/good-listener/-/good-listener-1.2.2.tgz#d53b30cdf9313dffb7dc9a0d477096aa6d145c50" @@ -11641,6 +13059,11 @@ good-listener@^1.2.2: dependencies: delegate "^3.1.2" +google-protobuf@^3.17.3: + version "3.21.2" + resolved "https://registry.yarnpkg.com/google-protobuf/-/google-protobuf-3.21.2.tgz#4580a2bea8bbb291ee579d1fefb14d6fa3070ea4" + integrity sha512-3MSOYFO5U9mPGikIYCzK0SaThypfGgS6bHqrUGXG3DPHCrb+txNqeEcns1W0lkGfk0rCyNXm7xB9rMxnCiZOoA== + gopd@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c" @@ -11648,32 +13071,15 @@ gopd@^1.0.1: dependencies: get-intrinsic "^1.1.3" -got@^11.0.0: - version "11.8.6" - resolved "https://registry.yarnpkg.com/got/-/got-11.8.6.tgz#276e827ead8772eddbcfc97170590b841823233a" - integrity sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g== - dependencies: - "@sindresorhus/is" "^4.0.0" - "@szmarczak/http-timer" "^4.0.5" - "@types/cacheable-request" "^6.0.1" - "@types/responselike" "^1.0.0" - cacheable-lookup "^5.0.3" - cacheable-request "^7.0.2" - decompress-response "^6.0.0" - http2-wrapper "^1.0.0-beta.5.2" - lowercase-keys "^2.0.0" - p-cancelable "^2.0.0" - responselike "^2.0.0" - -graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4, graceful-fs@^4.2.9: +graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.11, graceful-fs@^4.2.4: version "4.2.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== -growly@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081" - integrity sha512-+xGQY0YyAWCnqy7Cd++hc2JqMYzlm0dG30Jd0beaA64sROr8C4nt8Yc9V5Ro3avlSUDTN0ulqP/VBKi1/lLygw== +graphemer@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6" + integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== gud@^1.0.0: version "1.0.0" @@ -11692,30 +13098,40 @@ gunzip-maybe@^1.4.2: pumpify "^1.3.3" through2 "^2.0.3" +h3@^1.8.1, h3@^1.8.2: + version "1.9.0" + resolved "https://registry.yarnpkg.com/h3/-/h3-1.9.0.tgz#c5f512a93026df9837db6f30c9ef51135dd46752" + integrity sha512-+F3ZqrNV/CFXXfZ2lXBINHi+rM4Xw3CDC5z2CDK3NMPocjonKipGLLDSkrqY9DOrioZNPTIdDMWfQKm//3X2DA== + dependencies: + cookie-es "^1.0.0" + defu "^6.1.3" + destr "^2.0.2" + iron-webcrypto "^1.0.0" + radix3 "^1.1.0" + ufo "^1.3.2" + uncrypto "^0.1.3" + unenv "^1.7.4" + handlebars@^4.7.7: - version "4.7.7" - resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.7.tgz#9ce33416aad02dbd6c8fafa8240d5d98004945a1" - integrity sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA== + version "4.7.8" + resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.8.tgz#41c42c18b1be2365439188c77c6afae71c0cd9e9" + integrity sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ== dependencies: minimist "^1.2.5" - neo-async "^2.6.0" + neo-async "^2.6.2" source-map "^0.6.1" wordwrap "^1.0.0" optionalDependencies: uglify-js "^3.1.4" -har-schema@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" - integrity sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q== - -har-validator@~5.1.3: - version "5.1.5" - resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.5.tgz#1f0803b9f8cb20c0fa13822df1ecddb36bde1efd" - integrity sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w== +happy-dom@^14.12.0: + version "14.12.3" + resolved "https://registry.yarnpkg.com/happy-dom/-/happy-dom-14.12.3.tgz#1b5892c670461fd1db041bee690981c22d3d521f" + integrity sha512-vsYlEs3E9gLwA1Hp+w3qzu+RUDFf4VTT8cyKqVICoZ2k7WM++Qyd2LwzyTi5bqMJFiIC/vNpTDYuxdreENRK/g== dependencies: - ajv "^6.12.3" - har-schema "^2.0.0" + entities "^4.5.0" + webidl-conversions "^7.0.0" + whatwg-mimetype "^3.0.0" hard-rejection@^2.1.0: version "2.1.0" @@ -11737,19 +13153,19 @@ has-flag@^4.0.0: resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== -has-glob@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-glob/-/has-glob-1.0.0.tgz#9aaa9eedbffb1ba3990a7b0010fb678ee0081207" - integrity sha512-D+8A457fBShSEI3tFCj65PAbT++5sKiFtdCdOam0gnfBgw9D277OERk+HM9qYJXmdVLZ/znez10SqHN0BBQ50g== +has-property-descriptors@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz#52ba30b6c5ec87fd89fa574bc1c39125c6f65340" + integrity sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg== dependencies: - is-glob "^3.0.0" + get-intrinsic "^1.2.2" -has-property-descriptors@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz#610708600606d36961ed04c196193b6a607fa861" - integrity sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ== +has-property-descriptors@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz#963ed7d071dc7bf5f084c5bfbe0d1b6222586854" + integrity sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg== dependencies: - get-intrinsic "^1.1.1" + es-define-property "^1.0.0" has-proto@^1.0.1: version "1.0.1" @@ -11768,49 +13184,6 @@ has-tostringtag@^1.0.0: dependencies: has-symbols "^1.0.2" -has-unicode@^2.0.0, has-unicode@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" - integrity sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ== - -has-value@^0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" - integrity sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q== - dependencies: - get-value "^2.0.3" - has-values "^0.1.4" - isobject "^2.0.0" - -has-value@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" - integrity sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw== - dependencies: - get-value "^2.0.6" - has-values "^1.0.0" - isobject "^3.0.0" - -has-values@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" - integrity sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ== - -has-values@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" - integrity sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ== - dependencies: - is-number "^3.0.0" - kind-of "^4.0.0" - -has@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" - integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== - dependencies: - function-bind "^1.1.1" - hash-base@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.1.0.tgz#55c381d9e06e1d2997a883b4a3fddfe7f0d3af33" @@ -11828,88 +13201,38 @@ hash.js@1.1.7, hash.js@^1.0.0, hash.js@^1.0.3, hash.js@^1.1.7, hash.js@~1.1.7: inherits "^2.0.3" minimalistic-assert "^1.0.1" -hast-to-hyperscript@^9.0.0: - version "9.0.1" - resolved "https://registry.yarnpkg.com/hast-to-hyperscript/-/hast-to-hyperscript-9.0.1.tgz#9b67fd188e4c81e8ad66f803855334173920218d" - integrity sha512-zQgLKqF+O2F72S1aa4y2ivxzSlko3MAvxkwG8ehGmNiqd98BIN3JM1rAJPmplEyLmGLO2QZYJtIneOSZ2YbJuA== +hasown@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.0.tgz#f4c513d454a57b7c7e1650778de226b11700546c" + integrity sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA== dependencies: - "@types/unist" "^2.0.3" - comma-separated-tokens "^1.0.0" - property-information "^5.3.0" - space-separated-tokens "^1.0.0" - style-to-object "^0.3.0" - unist-util-is "^4.0.0" - web-namespaces "^1.0.0" + function-bind "^1.1.2" -hast-util-from-parse5@^6.0.0: - version "6.0.1" - resolved "https://registry.yarnpkg.com/hast-util-from-parse5/-/hast-util-from-parse5-6.0.1.tgz#554e34abdeea25ac76f5bd950a1f0180e0b3bc2a" - integrity sha512-jeJUWiN5pSxW12Rh01smtVkZgZr33wBokLzKLwinYOUfSzm1Nl/c3GUGebDyOKjdsRgMvoVbV0VpAcpjF4NrJA== +hast-util-heading-rank@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/hast-util-heading-rank/-/hast-util-heading-rank-3.0.0.tgz#2d5c6f2807a7af5c45f74e623498dd6054d2aba8" + integrity sha512-EJKb8oMUXVHcWZTDepnr+WNbfnXKFNf9duMesmr4S8SXTJBJ9M4Yok08pu9vxdJwdlGRhVumk9mEhkEvKGifwA== dependencies: - "@types/parse5" "^5.0.0" - hastscript "^6.0.0" - property-information "^5.0.0" - vfile "^4.0.0" - vfile-location "^3.2.0" - web-namespaces "^1.0.0" + "@types/hast" "^3.0.0" + +hast-util-is-element@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/hast-util-is-element/-/hast-util-is-element-3.0.0.tgz#6e31a6532c217e5b533848c7e52c9d9369ca0932" + integrity sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g== + dependencies: + "@types/hast" "^3.0.0" hast-util-parse-selector@^2.0.0: version "2.2.5" resolved "https://registry.yarnpkg.com/hast-util-parse-selector/-/hast-util-parse-selector-2.2.5.tgz#d57c23f4da16ae3c63b3b6ca4616683313499c3a" integrity sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ== -hast-util-raw@6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/hast-util-raw/-/hast-util-raw-6.0.1.tgz#973b15930b7529a7b66984c98148b46526885977" - integrity sha512-ZMuiYA+UF7BXBtsTBNcLBF5HzXzkyE6MLzJnL605LKE8GJylNjGc4jjxazAHUtcwT5/CEt6afRKViYB4X66dig== - dependencies: - "@types/hast" "^2.0.0" - hast-util-from-parse5 "^6.0.0" - hast-util-to-parse5 "^6.0.0" - html-void-elements "^1.0.0" - parse5 "^6.0.0" - unist-util-position "^3.0.0" - vfile "^4.0.0" - web-namespaces "^1.0.0" - xtend "^4.0.0" - zwitch "^1.0.0" - -hast-util-to-estree@^2.0.0: - version "2.3.2" - resolved "https://registry.yarnpkg.com/hast-util-to-estree/-/hast-util-to-estree-2.3.2.tgz#11ab0cd2e70ecf0305151af56e636b1cdfbba0bf" - integrity sha512-YYDwATNdnvZi3Qi84iatPIl1lWpXba1MeNrNbDfJfVzEBZL8uUmtR7mt7bxKBC8kuAuvb0bkojXYZzsNHyHCLg== - dependencies: - "@types/estree" "^1.0.0" - "@types/estree-jsx" "^1.0.0" - "@types/hast" "^2.0.0" - "@types/unist" "^2.0.0" - comma-separated-tokens "^2.0.0" - estree-util-attach-comments "^2.0.0" - estree-util-is-identifier-name "^2.0.0" - hast-util-whitespace "^2.0.0" - mdast-util-mdx-expression "^1.0.0" - mdast-util-mdxjs-esm "^1.0.0" - property-information "^6.0.0" - space-separated-tokens "^2.0.0" - style-to-object "^0.4.1" - unist-util-position "^4.0.0" - zwitch "^2.0.0" - -hast-util-to-parse5@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/hast-util-to-parse5/-/hast-util-to-parse5-6.0.0.tgz#1ec44650b631d72952066cea9b1445df699f8479" - integrity sha512-Lu5m6Lgm/fWuz8eWnrKezHtVY83JeRGaNQ2kn9aJgqaxvVkFCZQBEhgodZUDUvoodgyROHDb3r5IxAEdl6suJQ== +hast-util-to-string@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/hast-util-to-string/-/hast-util-to-string-3.0.0.tgz#2a131948b4b1b26461a2c8ac876e2c88d02946bd" + integrity sha512-OGkAxX1Ua3cbcW6EJ5pT/tslVb90uViVkcJ4ZZIMW/R33DX/AkcJcRrPebPwJkHYwlDHXz4aIwvAAaAdtrACFA== dependencies: - hast-to-hyperscript "^9.0.0" - property-information "^5.0.0" - web-namespaces "^1.0.0" - xtend "^4.0.0" - zwitch "^1.0.0" - -hast-util-whitespace@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/hast-util-whitespace/-/hast-util-whitespace-2.0.1.tgz#0ec64e257e6fc216c7d14c8a1b74d27d650b4557" - integrity sha512-nAxA0v8+vXSBDt3AnRUNjyRIQ0rD+ntpbAp4LnPkumc5M9yUbSMa4XDU9Q6etY4f1Wp4bNgvc1yjiZtsTTrSng== + "@types/hast" "^3.0.0" hastscript@^5.0.0: version "5.1.2" @@ -11937,6 +13260,21 @@ he@^1.2.0: resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== +hex-rgb@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/hex-rgb/-/hex-rgb-4.3.0.tgz#af5e974e83bb2fefe44d55182b004ec818c07776" + integrity sha512-Ox1pJVrDCyGHMG9CFg1tmrRUMRPRsAWYc/PinY0XzJU4K7y7vjNoLKIQ7BR5UJMCxNN8EM1MNDmHWA/B3aZUuw== + +hey-listen@^1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/hey-listen/-/hey-listen-1.0.8.tgz#8e59561ff724908de1aa924ed6ecc84a56a9aa68" + integrity sha512-COpmrF2NOg4TBWUJ5UVyaCU2A88wEMkUPK4hNqyCkqHbxT92BbvfjoSozkAIIm6XhicGlJHhFdullInrdhwU8Q== + +highlight.js@^10.4.1, highlight.js@~10.7.0: + version "10.7.3" + resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-10.7.3.tgz#697272e3991356e40c3cac566a74eef681756531" + integrity sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A== + highlight.js@~9.13.0: version "9.13.1" resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-9.13.1.tgz#054586d53a6863311168488a0f58d6c505ce641e" @@ -11968,42 +13306,35 @@ hosted-git-info@^2.1.4: resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9" integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw== -hosted-git-info@^4.0.1: +hosted-git-info@^4.0.0, hosted-git-info@^4.0.1: version "4.1.0" resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-4.1.0.tgz#827b82867e9ff1c8d0c4d9d53880397d2c86d224" integrity sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA== dependencies: lru-cache "^6.0.0" -html-encoding-sniffer@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz#e70d84b94da53aa375e11fe3a351be6642ca46f8" - integrity sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw== - dependencies: - whatwg-encoding "^1.0.1" - html-entities@^2.1.0: - version "2.3.3" - resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-2.3.3.tgz#117d7626bece327fc8baace8868fa6f5ef856e46" - integrity sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA== + version "2.4.0" + resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-2.4.0.tgz#edd0cee70402584c8c76cc2c0556db09d1f45061" + integrity sha512-igBTJcNNNhvZFRtm8uA6xMY6xYleeDwn3PeBCkDz7tHttv4F2hsDI2aPgNERWzvRcNYHNT3ymRaQzllmXj4YsQ== html-escaper@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== -html-minifier-terser@^5.0.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/html-minifier-terser/-/html-minifier-terser-5.1.1.tgz#922e96f1f3bb60832c2634b79884096389b1f054" - integrity sha512-ZPr5MNObqnV/T9akshPKbVgyOqLmy+Bxo7juKCfTfnjNniTAMdy4hz21YQqoofMBJD2kdREaqPPdThoR78Tgxg== +html-minifier-terser@^6.0.2: + version "6.1.0" + resolved "https://registry.yarnpkg.com/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz#bfc818934cc07918f6b3669f5774ecdfd48f32ab" + integrity sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw== dependencies: - camel-case "^4.1.1" - clean-css "^4.2.3" - commander "^4.1.1" + camel-case "^4.1.2" + clean-css "^5.2.2" + commander "^8.3.0" he "^1.2.0" - param-case "^3.0.3" + param-case "^3.0.4" relateurl "^0.2.7" - terser "^4.6.3" + terser "^5.10.0" html-parse-stringify@^3.0.1: version "3.0.1" @@ -12013,36 +13344,27 @@ html-parse-stringify@^3.0.1: void-elements "3.1.0" html-tags@^3.1.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/html-tags/-/html-tags-3.3.0.tgz#02b73689e4b31647edd447bfe9bf5878427582e7" - integrity sha512-mH3dWNbvfCKcAEysbpD7wvtIJ6ImPog8aFhfzqog9gCN8CJFhKjLDtjpohG3IxYRLqHMJ1PWpBvnSMkFJBQ6Jg== + version "3.3.1" + resolved "https://registry.yarnpkg.com/html-tags/-/html-tags-3.3.1.tgz#a04026a18c882e4bba8a01a3d39cfe465d40b5ce" + integrity sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ== -html-void-elements@^1.0.0: - version "1.0.5" - resolved "https://registry.yarnpkg.com/html-void-elements/-/html-void-elements-1.0.5.tgz#ce9159494e86d95e45795b166c2021c2cfca4483" - integrity sha512-uE/TxKuyNIcx44cIWnjr/rfIATDH7ZaOMmstu0CwhFG1Dunhlp4OC6/NMbhiwoq5BpW0ubi303qnEk/PZj614w== - -html-webpack-plugin@^4.0.0: - version "4.5.2" - resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-4.5.2.tgz#76fc83fa1a0f12dd5f7da0404a54e2699666bc12" - integrity sha512-q5oYdzjKUIPQVjOosjgvCHQOv9Ett9CYYHlgvJeXG0qQvdSojnBq4vAdQBwn1+yGveAwHCoe/rMR86ozX3+c2A== - dependencies: - "@types/html-minifier-terser" "^5.0.0" - "@types/tapable" "^1.0.5" - "@types/webpack" "^4.41.8" - html-minifier-terser "^5.0.1" - loader-utils "^1.2.3" - lodash "^4.17.20" - pretty-error "^2.1.1" - tapable "^1.1.3" - util.promisify "1.0.0" +html-webpack-plugin@^5.5.0: + version "5.5.3" + resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-5.5.3.tgz#72270f4a78e222b5825b296e5e3e1328ad525a3e" + integrity sha512-6YrDKTuqaP/TquFH7h4srYWsZx+x6k6+FbsTm0ziCwGHDP78Unr1r9F/H4+sGmMbX08GQcJ+K64x55b+7VM/jg== + dependencies: + "@types/html-minifier-terser" "^6.0.0" + html-minifier-terser "^6.0.2" + lodash "^4.17.21" + pretty-error "^4.0.0" + tapable "^2.0.0" htmlnano@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/htmlnano/-/htmlnano-2.0.3.tgz#50ee639ed63357d4a6c01309f52a35892e4edc2e" - integrity sha512-S4PGGj9RbdgW8LhbILNK7W9JhmYP8zmDY7KDV/8eCiJBQJlbmltp5I0gv8c5ntLljfdxxfmJ+UJVSqyH4mb41A== + version "2.1.0" + resolved "https://registry.yarnpkg.com/htmlnano/-/htmlnano-2.1.0.tgz#67b31b3cd3fad23f0b610ca628fdb48382209c3c" + integrity sha512-jVGRE0Ep9byMBKEu0Vxgl8dhXYOUk0iNQ2pjsG+BcRB0u0oDF5A9p/iBGMg/PGKYUyMD0OAGu8dVT5Lzj8S58g== dependencies: - cosmiconfig "^7.0.1" + cosmiconfig "^8.0.0" posthtml "^0.16.5" timsort "^0.3.0" @@ -12066,11 +13388,6 @@ htmlparser2@^7.1.1: domutils "^2.8.0" entities "^3.0.1" -http-cache-semantics@^4.0.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz#abe02fcb2985460bf0323be664436ec3476a6d5a" - integrity sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ== - http-errors@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" @@ -12082,43 +13399,12 @@ http-errors@2.0.0: statuses "2.0.1" toidentifier "1.0.1" -http-proxy-agent@^4.0.0, http-proxy-agent@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz#8a8c8ef7f5932ccf953c296ca8291b95aa74aa3a" - integrity sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg== - dependencies: - "@tootallnate/once" "1" - agent-base "6" - debug "4" - -http-signature@~1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" - integrity sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ== - dependencies: - assert-plus "^1.0.0" - jsprim "^1.2.2" - sshpk "^1.7.0" - -http-status@1.5.3: - version "1.5.3" - resolved "https://registry.yarnpkg.com/http-status/-/http-status-1.5.3.tgz#9d1f6adcd1a609f535679f6e1b82811b96c3306e" - integrity sha512-jCClqdnnwigYslmtfb28vPplOgoiZ0siP2Z8C5Ua+3UKbx410v+c+jT+jh1bbI4TvcEySuX0vd/CfFZFbDkJeQ== - -http2-wrapper@^1.0.0-beta.5.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/http2-wrapper/-/http2-wrapper-1.0.3.tgz#b8f55e0c1f25d4ebd08b3b0c2c079f9590800b3d" - integrity sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg== - dependencies: - quick-lru "^5.1.1" - resolve-alpn "^1.0.0" - -https-browserify@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" - integrity sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg== +http-shutdown@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/http-shutdown/-/http-shutdown-1.2.2.tgz#41bc78fc767637c4c95179bc492f312c0ae64c5f" + integrity sha512-S9wWkJ/VSY9/k4qcjG318bqJNruzE4HySUhFYknwmu6LBP97KLLfwNf+n4V1BHurvFNkSKLFnK/RsuUnRTf9Vw== -https-proxy-agent@5, https-proxy-agent@^5.0.0: +https-proxy-agent@^5.0.0: version "5.0.1" resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" integrity sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA== @@ -12126,10 +13412,13 @@ https-proxy-agent@5, https-proxy-agent@^5.0.0: agent-base "6" debug "4" -human-signals@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3" - integrity sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw== +https-proxy-agent@^7.0.2: + version "7.0.2" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-7.0.2.tgz#e2645b846b90e96c6e6f347fb5b2e41f1590b09b" + integrity sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA== + dependencies: + agent-base "^7.0.2" + debug "4" human-signals@^2.1.0: version "2.1.0" @@ -12141,10 +13430,10 @@ human-signals@^4.3.0: resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-4.3.1.tgz#ab7f811e851fca97ffbd2c1fe9a958964de321b2" integrity sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ== -humanize-duration@^3.15.3: - version "3.28.0" - resolved "https://registry.yarnpkg.com/humanize-duration/-/humanize-duration-3.28.0.tgz#f79770c0bec34d3bfd4899338cc40643bc04df72" - integrity sha512-jMAxraOOmHuPbffLVDKkEKi/NeG8dMqP8lGRd6Tbf7JgAeG33jjgPWDbXXU7ypCI0o+oNKJFgbSB9FKVdWNI2A== +human-signals@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-5.0.0.tgz#42665a284f9ae0dade3ba41ebc37eb4b852f3a28" + integrity sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ== humanize-ms@^1.2.1: version "1.2.1" @@ -12153,32 +13442,11 @@ humanize-ms@^1.2.1: dependencies: ms "^2.0.0" -husky@^8.0.2, husky@^8.0.3: +husky@^8.0.3: version "8.0.3" resolved "https://registry.yarnpkg.com/husky/-/husky-8.0.3.tgz#4936d7212e46d1dea28fef29bb3a108872cd9184" integrity sha512-+dQSyqPh4x1hlO1swXBiNb2HzTDN1I2IGLQx1GrBuiqFJfoMrnZWwVmatvSiO+Iz8fBUnf+lekwNo4c2LlXItg== -i18next-browser-languagedetector@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/i18next-browser-languagedetector/-/i18next-browser-languagedetector-7.0.1.tgz#ead34592edc96c6c3a618a51cb57ad027c5b5d87" - integrity sha512-Pa5kFwaczXJAeHE56CHG2aWzFBMJNUNghf0Pm4SwSrEMps/PTKqW90EYWlIvhuYStf3Sn1K0vw+gH3+TLdkH1g== - dependencies: - "@babel/runtime" "^7.19.4" - -i18next-http-backend@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/i18next-http-backend/-/i18next-http-backend-2.1.1.tgz#72a21d61c2e96eea9ad45ba1b9dd0090e119709a" - integrity sha512-jByfUCDVgQ8+/Wens7queQhYYvMcGTW/lR4IJJNEDDXnmqjLrwi8ubXKpmp76/JIWEZHffNdWqnxFJcTVGeaOw== - dependencies: - cross-fetch "3.1.5" - -i18next@^22.4.11: - version "22.4.11" - resolved "https://registry.yarnpkg.com/i18next/-/i18next-22.4.11.tgz#8b6c9be95176de90d3f10a78af125d95d3a3258d" - integrity sha512-ShfTzXVMjXdF2iPiT/wbizOrssLh9Ab6VpuVROihLCAu+u25KbZiEYVgsA0W6g0SgjPa/JmGWcUEV/g6cKzEjQ== - dependencies: - "@babel/runtime" "^7.20.6" - iconv-lite@0.4.24, iconv-lite@^0.4.24: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" @@ -12193,18 +13461,16 @@ iconv-lite@^0.6.2: dependencies: safer-buffer ">= 2.1.2 < 3.0.0" -icss-utils@^4.0.0, icss-utils@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-4.1.1.tgz#21170b53789ee27447c2f47dd683081403f9a467" - integrity sha512-4aFq7wvWyMHKgxsH8QQtGpvbASCf+eM3wPRLI6R+MgAnTCZ6STYsRvttLvRWK0Nfif5piF394St3HeJDaljGPA== - dependencies: - postcss "^7.0.14" - icss-utils@^5.0.0, icss-utils@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-5.1.0.tgz#c6be6858abd013d768e98366ae47e25d5887b1ae" integrity sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA== +idb-keyval@^6.2.1: + version "6.2.1" + resolved "https://registry.yarnpkg.com/idb-keyval/-/idb-keyval-6.2.1.tgz#94516d625346d16f56f3b33855da11bfded2db33" + integrity sha512-8Sb3veuYCyrZL+VBt9LJfZjLUPWVvqn8tG28VqYNFCo43KHcKuq+b4EiXGeuaLAQWL2YmyDgMp2aSpH9JHsEQg== + idb@^7.1.1: version "7.1.1" resolved "https://registry.yarnpkg.com/idb/-/idb-7.1.1.tgz#d910ded866d32c7ced9befc5bfdf36f572ced72b" @@ -12215,27 +13481,27 @@ ieee754@^1.1.13, ieee754@^1.1.4, ieee754@^1.2.1: resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== -iferr@^0.1.5: - version "0.1.5" - resolved "https://registry.yarnpkg.com/iferr/-/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501" - integrity sha512-DUNFN5j7Tln0D+TxzloUjKB+CtVu6myn0JEFak6dG18mNt9YkQ6lzGCdafwofISZ1lLF3xRHJ98VKy9ynkcFaA== +ignore@^5.0.4, ignore@^5.2.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.0.tgz#67418ae40d34d6999c95ff56016759c718c82f78" + integrity sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg== -ignore@^4.0.3, ignore@^4.0.6: - version "4.0.6" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" - integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== +immediate@~3.0.5: + version "3.0.6" + resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.0.6.tgz#9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b" + integrity sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ== -ignore@^5.0.4, ignore@^5.1.1, ignore@^5.2.0: - version "5.2.4" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324" - integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== +immer@^10.0.4: + version "10.1.1" + resolved "https://registry.yarnpkg.com/immer/-/immer-10.1.1.tgz#206f344ea372d8ea176891545ee53ccc062db7bc" + integrity sha512-s2MPrmjovJcoMaHtx6K11Ra7oD05NT97w1IC5zpMkT6Atjr7H8LjaDd81iIxUYpMKSRRNMJE703M1Fhr/TctHw== immer@^9.0.19: version "9.0.21" resolved "https://registry.yarnpkg.com/immer/-/immer-9.0.21.tgz#1e025ea31a40f24fb064f1fef23e931496330176" integrity sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA== -import-fresh@^3.0.0, import-fresh@^3.1.0, import-fresh@^3.2.1: +import-fresh@^3.0.0, import-fresh@^3.1.0, import-fresh@^3.2.1, import-fresh@^3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== @@ -12243,36 +13509,16 @@ import-fresh@^3.0.0, import-fresh@^3.1.0, import-fresh@^3.2.1: parent-module "^1.0.0" resolve-from "^4.0.0" -import-local@^3.0.2: - version "3.1.0" - resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.1.0.tgz#b4479df8a5fd44f6cdce24070675676063c95cb4" - integrity sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg== - dependencies: - pkg-dir "^4.2.0" - resolve-cwd "^3.0.0" - imurmurhash@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== -indent-string@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-2.1.0.tgz#8e2d48348742121b4a8218b7a137e9a52049dc80" - integrity sha512-aqwDFWSgSgfRaEwao5lg5KEcVd/2a+D1rvoG7NdilmYz0NwRk6StWpWdz/Hpk34MKPpx7s8XxUqimfcQK6gGlg== - dependencies: - repeating "^2.0.0" - indent-string@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== -infer-owner@^1.0.3, infer-owner@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/infer-owner/-/infer-owner-1.0.4.tgz#c4cefcaa8e51051c2a40ba2ce8a3d27295af9467" - integrity sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A== - inflight@^1.0.4: version "1.0.6" resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" @@ -12281,32 +13527,17 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@2.0.4, inherits@^2.0.0, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3, inherits@~2.0.4: +inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3, inherits@~2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== -inherits@2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" - integrity sha512-8nWq2nLTAwd02jTqJExUYFSD/fKq6VH9Y/oG2accc/kdI0V98Bag8d5a4gi3XHz73rDWa2PvTtvcWYquKqSENA== - -inherits@2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" - integrity sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw== - -ini@~1.3.0: +ini@^1.3.2, ini@^1.3.4: version "1.3.8" resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== -inline-style-parser@0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/inline-style-parser/-/inline-style-parser-0.1.1.tgz#ec8a3b429274e9c0a1f1c4ffa9453a7fef72cea1" - integrity sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q== - -inquirer@^7.0.0: +inquirer@^7.3.3: version "7.3.3" resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-7.3.3.tgz#04d176b2af04afc157a83fd7c100e98ee0aad003" integrity sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA== @@ -12325,102 +13556,80 @@ inquirer@^7.0.0: strip-ansi "^6.0.0" through "^2.3.6" -inquirer@^8.2.1: - version "8.2.5" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-8.2.5.tgz#d8654a7542c35a9b9e069d27e2df4858784d54f8" - integrity sha512-QAgPDQMEgrDssk1XiwwHoOGYF9BAbUcc1+j+FhEvaOt8/cKRqyLn0U5qA6F74fGhTMGxf92pOvPBeh29jQJDTQ== - dependencies: - ansi-escapes "^4.2.1" - chalk "^4.1.1" - cli-cursor "^3.1.0" - cli-width "^3.0.0" - external-editor "^3.0.3" - figures "^3.0.0" - lodash "^4.17.21" - mute-stream "0.0.8" - ora "^5.4.1" - run-async "^2.4.0" - rxjs "^7.5.5" - string-width "^4.1.0" - strip-ansi "^6.0.0" - through "^2.3.6" - wrap-ansi "^7.0.0" +int64-buffer@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/int64-buffer/-/int64-buffer-1.0.1.tgz#c78d841b444cadf036cd04f8683696c740f15dca" + integrity sha512-+3azY4pXrjAupJHU1V9uGERWlhoqNswJNji6aD/02xac7oxol508AsMC5lxKhEqyZeDFy3enq5OGWXF4u75hiw== -internal-slot@^1.0.3, internal-slot@^1.0.4, internal-slot@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.5.tgz#f2a2ee21f668f8627a4667f309dc0f4fb6674986" - integrity sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ== +internal-slot@^1.0.5: + version "1.0.6" + resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.6.tgz#37e756098c4911c5e912b8edbf71ed3aa116f930" + integrity sha512-Xj6dv+PsbtwyPpEflsejS+oIZxmMlV44zAhG479uYu89MsjcYOhCFnNyKrkJrihbsiasQyY0afoCl/9BLR65bg== dependencies: - get-intrinsic "^1.2.0" - has "^1.0.3" + get-intrinsic "^1.2.2" + hasown "^2.0.0" side-channel "^1.0.4" -interpret@^1.0.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e" - integrity sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA== - -interpret@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/interpret/-/interpret-2.2.0.tgz#1a78a0b5965c40a5416d007ad6f50ad27c417df9" - integrity sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw== +internmap@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/internmap/-/internmap-1.0.1.tgz#0017cc8a3b99605f0302f2b198d272e015e5df95" + integrity sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw== -invariant@^2.2.3, invariant@^2.2.4: +invariant@2, invariant@^2.2.3, invariant@^2.2.4: version "2.2.4" resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== dependencies: loose-envify "^1.0.0" -ip-regex@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-2.1.0.tgz#fa78bf5d2e6913c911ce9f819ee5146bb6d844e9" - integrity sha512-58yWmlHpp7VYfcdTwMTvwMmqx/Elfxjd9RXTDyMsbL7lLWmhMylLEqiYVLKuLzOZqVgiWXD9MfR62Vv89VRxkw== - -ip@^1.1.5: - version "1.1.8" - resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.8.tgz#ae05948f6b075435ed3307acce04629da8cdbf48" - integrity sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg== - -ip@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ip/-/ip-2.0.0.tgz#4cf4ab182fee2314c75ede1276f8c80b479936da" - integrity sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ== +ioredis@^5.3.2: + version "5.3.2" + resolved "https://registry.yarnpkg.com/ioredis/-/ioredis-5.3.2.tgz#9139f596f62fc9c72d873353ac5395bcf05709f7" + integrity sha512-1DKMMzlIHM02eBBVOFQ1+AolGjs6+xEcM4PDL7NqOS6szq7H9jSaEkIUH6/a5Hl241LzW6JLSiAbNvTQjUupUA== + dependencies: + "@ioredis/commands" "^1.1.1" + cluster-key-slot "^1.1.0" + debug "^4.3.4" + denque "^2.1.0" + lodash.defaults "^4.2.0" + lodash.isarguments "^3.1.0" + redis-errors "^1.2.0" + redis-parser "^3.0.0" + standard-as-callback "^2.1.0" + +ip-address@^9.0.5: + version "9.0.5" + resolved "https://registry.yarnpkg.com/ip-address/-/ip-address-9.0.5.tgz#117a960819b08780c3bd1f14ef3c1cc1d3f3ea5a" + integrity sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g== + dependencies: + jsbn "1.1.0" + sprintf-js "^1.1.3" + +ip@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/ip/-/ip-2.0.1.tgz#e8f3595d33a3ea66490204234b77636965307105" + integrity sha512-lJUL9imLTNi1ZfXT+DU6rBBdbiKGBuay9B6xGSPVjUeQwaH1RIGqef8RZkUtHioLmSNpPR5M4HVKJGm1j8FWVQ== ipaddr.js@1.9.1: version "1.9.1" resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== -is-absolute-url@^3.0.0: - version "3.0.3" - resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-3.0.3.tgz#96c6a22b6a23929b11ea0afb1836c36ad4a5d698" - integrity sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q== - -is-accessor-descriptor@^0.1.6: - version "0.1.6" - resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" - integrity sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A== - dependencies: - kind-of "^3.0.2" - -is-accessor-descriptor@^1.0.0: +iron-webcrypto@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" - integrity sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ== - dependencies: - kind-of "^6.0.0" + resolved "https://registry.yarnpkg.com/iron-webcrypto/-/iron-webcrypto-1.0.0.tgz#e3b689c0c61b434a0a4cb82d0aeabbc8b672a867" + integrity sha512-anOK1Mktt8U1Xi7fCM3RELTuYbnFikQY5VtrDj7kPgpejV7d43tWKhzgioO0zpkazLEL/j/iayRqnJhrGfqUsg== + +is-absolute-url@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-4.0.1.tgz#16e4d487d4fded05cfe0685e53ec86804a5e94dc" + integrity sha512-/51/TKE88Lmm7Gc4/8btclNXWS+g50wXhYJq8HWIBAGUBnoAdRu1aXeh364t/O7wXDAcTJDP8PNuNKWUDWie+A== -is-alphabetical@1.0.4, is-alphabetical@^1.0.0: +is-alphabetical@^1.0.0: version "1.0.4" resolved "https://registry.yarnpkg.com/is-alphabetical/-/is-alphabetical-1.0.4.tgz#9e7d6b94916be22153745d184c298cbf986a686d" integrity sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg== -is-alphabetical@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-alphabetical/-/is-alphabetical-2.0.1.tgz#01072053ea7c1036df3c7d19a6daaec7f19e789b" - integrity sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ== - is-alphanumerical@^1.0.0: version "1.0.4" resolved "https://registry.yarnpkg.com/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz#7eb9a2431f855f6b1ef1a78e326df515696c4dbf" @@ -12429,14 +13638,6 @@ is-alphanumerical@^1.0.0: is-alphabetical "^1.0.0" is-decimal "^1.0.0" -is-alphanumerical@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz#7c03fbe96e3e931113e57f964b0a368cc2dfd875" - integrity sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw== - dependencies: - is-alphabetical "^2.0.0" - is-decimal "^2.0.0" - is-arguments@^1.0.4, is-arguments@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b" @@ -12459,6 +13660,13 @@ is-arrayish@^0.2.1: resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== +is-async-function@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-async-function/-/is-async-function-2.0.0.tgz#8e4418efd3e5d3a6ebb0164c05ef5afb69aa9646" + integrity sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA== + dependencies: + has-tostringtag "^1.0.0" + is-bigint@^1.0.1: version "1.0.4" resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3" @@ -12466,13 +13674,6 @@ is-bigint@^1.0.1: dependencies: has-bigints "^1.0.1" -is-binary-path@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" - integrity sha512-9fRVlXc0uCxEDj1nQzaWONSpbTfx0FmJfzHF7pwlI8DkWGoHBBea4Pg5Ky0ojwwxQmnSifgbKkI06Qv0Ljgj+Q== - dependencies: - binary-extensions "^1.0.0" - is-binary-path@~2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" @@ -12488,55 +13689,22 @@ is-boolean-object@^1.1.0: call-bind "^1.0.2" has-tostringtag "^1.0.0" -is-buffer@^1.1.5, is-buffer@~1.1.1: +is-buffer@~1.1.1: version "1.1.6" resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== -is-buffer@^2.0.0: - version "2.0.5" - resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.5.tgz#ebc252e400d22ff8d77fa09888821a24a658c191" - integrity sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ== - is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.7: version "1.2.7" resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055" integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== -is-ci@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c" - integrity sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w== - dependencies: - ci-info "^2.0.0" - -is-core-module@^2.11.0, is-core-module@^2.9.0: - version "2.11.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.11.0.tgz#ad4cb3e3863e814523c96f3f58d26cc570ff0144" - integrity sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw== - dependencies: - has "^1.0.3" - -is-core-module@^2.5.0: - version "2.12.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.12.0.tgz#36ad62f6f73c8253fd6472517a12483cf03e7ec4" - integrity sha512-RECHCBCd/viahWmwj6enj19sKbHfJrddi/6cBDsNTKbNq0f7VeaUkBo60BqzvPqo/W54ChS62Z5qyun7cfOMqQ== - dependencies: - has "^1.0.3" - -is-data-descriptor@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" - integrity sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg== - dependencies: - kind-of "^3.0.2" - -is-data-descriptor@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" - integrity sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ== +is-core-module@^2.13.0, is-core-module@^2.13.1, is-core-module@^2.5.0: + version "2.13.1" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.1.tgz#ad0d7532c6fea9da1ebdc82742d74525c6273384" + integrity sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw== dependencies: - kind-of "^6.0.0" + hasown "^2.0.0" is-date-object@^1.0.1, is-date-object@^1.0.5: version "1.0.5" @@ -12550,110 +13718,50 @@ is-decimal@^1.0.0: resolved "https://registry.yarnpkg.com/is-decimal/-/is-decimal-1.0.4.tgz#65a3a5958a1c5b63a706e1b333d7cd9f630d3fa5" integrity sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw== -is-decimal@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-decimal/-/is-decimal-2.0.1.tgz#9469d2dc190d0214fd87d78b78caecc0cc14eef7" - integrity sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A== - is-deflate@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-deflate/-/is-deflate-1.0.0.tgz#c862901c3c161fb09dac7cdc7e784f80e98f2f14" integrity sha512-YDoFpuZWu1VRXlsnlYMzKyVRITXj7Ej/V9gXQ2/pAe7X1J7M/RNOqaIYi6qUn+B7nGyB9pDXrv02dsB58d2ZAQ== -is-descriptor@^0.1.0: - version "0.1.6" - resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" - integrity sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg== - dependencies: - is-accessor-descriptor "^0.1.6" - is-data-descriptor "^0.1.4" - kind-of "^5.0.0" - -is-descriptor@^1.0.0, is-descriptor@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" - integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg== - dependencies: - is-accessor-descriptor "^1.0.0" - is-data-descriptor "^1.0.0" - kind-of "^6.0.2" - is-docker@^2.0.0, is-docker@^2.1.1: version "2.2.1" resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== -is-dom@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-dom/-/is-dom-1.1.0.tgz#af1fced292742443bb59ca3f76ab5e80907b4e8a" - integrity sha512-u82f6mvhYxRPKpw8V1N0W8ce1xXwOrQtgGcxl6UCL5zBmZu3is/18K0rR7uFCnMDuAsS/3W54mGL4vsaFUQlEQ== - dependencies: - is-object "^1.0.1" - is-window "^1.0.2" - -is-extendable@^0.1.0, is-extendable@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" - integrity sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw== - -is-extendable@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" - integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA== - dependencies: - is-plain-object "^2.0.4" - -is-extglob@^2.1.0, is-extglob@^2.1.1: +is-extglob@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== -is-finite@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.1.0.tgz#904135c77fb42c0641d6aa1bcdbc4daa8da082f3" - integrity sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w== - -is-fullwidth-code-point@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" - integrity sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw== +is-finalizationregistry@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-finalizationregistry/-/is-finalizationregistry-1.0.2.tgz#c8749b65f17c133313e661b1289b95ad3dbd62e6" + integrity sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw== dependencies: - number-is-nan "^1.0.0" - -is-fullwidth-code-point@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" - integrity sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w== + call-bind "^1.0.2" is-fullwidth-code-point@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== -is-function@^1.0.1, is-function@^1.0.2: +is-fullwidth-code-point@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz#fae3167c729e7463f8461ce512b080a49268aa88" + integrity sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ== + +is-function@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/is-function/-/is-function-1.0.2.tgz#4f097f30abf6efadac9833b17ca5dc03f8144e08" integrity sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ== -is-generator-fn@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz#7d140adc389aaf3011a8f2a2a4cfa6faadffb118" - integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ== - -is-generator-function@^1.0.7: +is-generator-function@^1.0.10, is-generator-function@^1.0.7: version "1.0.10" resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.10.tgz#f1558baf1ac17e0deea7c0415c438351ff2b3c72" integrity sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A== dependencies: has-tostringtag "^1.0.0" -is-glob@^3.0.0, is-glob@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" - integrity sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw== - dependencies: - is-extglob "^2.1.0" - is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: version "4.0.3" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" @@ -12671,11 +13779,6 @@ is-hexadecimal@^1.0.0: resolved "https://registry.yarnpkg.com/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz#cc35c97588da4bd49a8eedd6bc4082d44dcb23a7" integrity sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw== -is-hexadecimal@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz#86b5bf668fca307498d319dfc03289d781a90027" - integrity sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg== - is-interactive@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-interactive/-/is-interactive-1.0.0.tgz#cea6e6ae5c870a7b0a0004070b7b587e0252912e" @@ -12686,15 +13789,18 @@ is-json@^2.0.1: resolved "https://registry.yarnpkg.com/is-json/-/is-json-2.0.1.tgz#6be166d144828a131d686891b983df62c39491ff" integrity sha512-6BEnpVn1rcf3ngfmViLM6vjUjGErbdrL4rwlv+u1NO1XO8kqT4YGL8+19Q+Z/bas8tY90BTWMk2+fW1g6hQjbA== -is-map@^2.0.1, is-map@^2.0.2: +is-map@^2.0.1: version "2.0.2" resolved "https://registry.yarnpkg.com/is-map/-/is-map-2.0.2.tgz#00922db8c9bf73e81b7a335827bc2a43f2b91127" integrity sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg== -is-module@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-module/-/is-module-1.0.0.tgz#3258fb69f78c14d5b815d664336b4cffb6441591" - integrity sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g== +is-nan@^1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/is-nan/-/is-nan-1.3.2.tgz#043a54adea31748b55b6cd4e09aadafa69bd9e1d" + integrity sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w== + dependencies: + call-bind "^1.0.0" + define-properties "^1.1.3" is-negative-zero@^2.0.2: version "2.0.2" @@ -12708,13 +13814,6 @@ is-number-object@^1.0.4: dependencies: has-tostringtag "^1.0.0" -is-number@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" - integrity sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg== - dependencies: - kind-of "^3.0.2" - is-number@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" @@ -12725,58 +13824,39 @@ is-obj@^2.0.0: resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-2.0.0.tgz#473fb05d973705e3fd9620545018ca8e22ef4982" integrity sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w== -is-object@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.2.tgz#a56552e1c665c9e950b4a025461da87e72f86fcf" - integrity sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA== +is-obj@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-3.0.0.tgz#b0889f1f9f8cb87e87df53a8d1230a2250f8b9be" + integrity sha512-IlsXEHOjtKhpN8r/tRFj2nDyTmHvcfNeu/nrRIcXE17ROeatXchkojffa1SpdqW4cr/Fj6QkEf/Gn4zf6KKvEQ== -is-plain-obj@2.1.0, is-plain-obj@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" - integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== +is-path-cwd@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-2.2.0.tgz#67d43b82664a7b5191fd9119127eb300048a9fdb" + integrity sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ== + +is-path-inside@^3.0.2, is-path-inside@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" + integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== is-plain-obj@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" integrity sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg== -is-plain-obj@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-3.0.0.tgz#af6f2ea14ac5a646183a5bbdb5baabbc156ad9d7" - integrity sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA== - -is-plain-obj@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-4.1.0.tgz#d65025edec3657ce032fd7db63c97883eaed71f0" - integrity sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg== - is-plain-object@5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-5.0.0.tgz#4427f50ab3429e9025ea7d52e9043a9ef4159344" integrity sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q== -is-plain-object@^2.0.3, is-plain-object@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" - integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== - dependencies: - isobject "^3.0.1" - -is-reference@^1.1.2: - version "1.2.1" - resolved "https://registry.yarnpkg.com/is-reference/-/is-reference-1.2.1.tgz#8b2dac0b371f4bc994fdeaba9eb542d03002d0b7" - integrity sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ== - dependencies: - "@types/estree" "*" - -is-reference@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/is-reference/-/is-reference-3.0.1.tgz#d400f4260f7e55733955e60d361d827eb4d3b831" - integrity sha512-baJJdQLiYaJdvFbJqXrcGv3WU3QCzBlUcI5QhbesIm6/xPsvmO+2CDoi/GMOFBQEQm+PXkwOPrp9KK5ozZsp2w== +is-plain-object@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" + integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== dependencies: - "@types/estree" "*" + isobject "^3.0.1" -is-regex@^1.0.4, is-regex@^1.1.2, is-regex@^1.1.4: +is-regex@^1.0.4, is-regex@^1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== @@ -12784,7 +13864,12 @@ is-regex@^1.0.4, is-regex@^1.1.2, is-regex@^1.1.4: call-bind "^1.0.2" has-tostringtag "^1.0.0" -is-set@^2.0.1, is-set@^2.0.2: +is-regexp@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-3.1.0.tgz#0235eab9cda5b83f96ac4a263d8c32c9d5ad7422" + integrity sha512-rbku49cWloU5bSMI+zaRaXdQHXnthP6DZ/vLnfdSKyL4zUzuWnomtOEiZZOd+ioQ+avFo/qau3KPTc7Fjy1uPA== + +is-set@^2.0.1: version "2.0.2" resolved "https://registry.yarnpkg.com/is-set/-/is-set-2.0.2.tgz#90755fa4c2562dc1c5d4024760d6119b94ca18ec" integrity sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g== @@ -12796,7 +13881,7 @@ is-shared-array-buffer@^1.0.2: dependencies: call-bind "^1.0.2" -is-stream@^1.0.1, is-stream@^1.1.0: +is-stream@^1.0.1: version "1.1.0" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" integrity sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ== @@ -12832,18 +13917,21 @@ is-text-path@^1.0.1: dependencies: text-extensions "^1.0.0" -is-typed-array@^1.1.10, is-typed-array@^1.1.3, is-typed-array@^1.1.9: - version "1.1.10" - resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.10.tgz#36a5b5cb4189b575d1a3e4b08536bfb485801e3f" - integrity sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A== +is-text-path@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-text-path/-/is-text-path-2.0.0.tgz#b2484e2b720a633feb2e85b67dc193ff72c75636" + integrity sha512-+oDTluR6WEjdXEJMnC2z6A4FRwFoYuvShVVEGsS7ewc0UTi2QtAKMDJuL4BDEVt+5T7MjFo12RP8ghOM75oKJw== + dependencies: + text-extensions "^2.0.0" + +is-typed-array@^1.1.10, is-typed-array@^1.1.12, is-typed-array@^1.1.3, is-typed-array@^1.1.9: + version "1.1.12" + resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.12.tgz#d0bab5686ef4a76f7a73097b95470ab199c57d4a" + integrity sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg== dependencies: - available-typed-arrays "^1.0.5" - call-bind "^1.0.2" - for-each "^0.3.3" - gopd "^1.0.1" - has-tostringtag "^1.0.0" + which-typed-array "^1.1.11" -is-typedarray@1.0.0, is-typedarray@^1.0.0, is-typedarray@~1.0.0: +is-typedarray@1.0.0, is-typedarray@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" integrity sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA== @@ -12853,11 +13941,6 @@ is-unicode-supported@^0.1.0: resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== -is-utf8@^0.2.0: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" - integrity sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q== - is-weakmap@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/is-weakmap/-/is-weakmap-2.0.1.tgz#5008b59bdc43b698201d18f62b37b2ca243e8cf2" @@ -12878,31 +13961,6 @@ is-weakset@^2.0.1: call-bind "^1.0.2" get-intrinsic "^1.1.1" -is-whitespace-character@^1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-whitespace-character/-/is-whitespace-character-1.0.4.tgz#0858edd94a95594c7c9dd0b5c174ec6e45ee4aa7" - integrity sha512-SDweEzfIZM0SJV0EUga669UTKlmL0Pq8Lno0QDQsPnvECB3IM2aP0gdx5TrU0A01MAPfViaZiI2V1QMZLaKK5w== - -is-window@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-window/-/is-window-1.0.2.tgz#2c896ca53db97de45d3c33133a65d8c9f563480d" - integrity sha512-uj00kdXyZb9t9RcAUAwMZAnkBUwdYGhYlt7djMXhfyhUCzwNba50tIiBKR7q0l7tdoBtFVw/3JmLY6fI3rmZmg== - -is-windows@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" - integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== - -is-word-character@^1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-word-character/-/is-word-character-1.0.4.tgz#ce0e73216f98599060592f62ff31354ddbeb0230" - integrity sha512-5SMO8RVennx3nZrqtKwCGyyetPE9VDba5ugvKLaD4KopPG5kR4mQ7tNt/r7feL5yt5h3lpuBbIUmCOG2eSzXHA== - -is-wsl@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" - integrity sha512-gfygJYZ2gLTDlmbWMI0CE2MwnFzSN/2SZfkMlItC4K/JBlsWVDB0bO6XhqcY13YXE7iMcAJnzTCJjPiTeJJ0Mw== - is-wsl@^2.1.1, is-wsl@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" @@ -12910,39 +13968,22 @@ is-wsl@^2.1.1, is-wsl@^2.2.0: dependencies: is-docker "^2.0.0" -is_js@^0.9.0: - version "0.9.0" - resolved "https://registry.yarnpkg.com/is_js/-/is_js-0.9.0.tgz#0ab94540502ba7afa24c856aa985561669e9c52d" - integrity sha512-8Y5EHSH+TonfUHX2g3pMJljdbGavg55q4jmHzghJCdqYDbdNROC8uw/YFQwIRCRqRJT1EY3pJefz+kglw+o7sg== - -isarray@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" - integrity sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ== +isarray@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" + integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== -isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: +isarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== -isarray@^2.0.1, isarray@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" - integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== - isexe@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== -isobject@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" - integrity sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA== - dependencies: - isarray "1.0.0" - -isobject@^3.0.0, isobject@^3.0.1: +isobject@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg== @@ -12960,7 +14001,7 @@ isomorphic-fetch@^2.1.1: node-fetch "^1.0.1" whatwg-fetch ">=0.10.0" -isomorphic-unfetch@^3.1.0: +isomorphic-unfetch@3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/isomorphic-unfetch/-/isomorphic-unfetch-3.1.0.tgz#87341d5f4f7b63843d468438128cb087b7c3e98f" integrity sha512-geDJjpoZ8N0kWexiwkX8F9NkTsXhetLPVbZFQ+JTW239QNOwvB0gniuR1Wc6f0AMTn7/mFGyXvHTifrCp/GH8Q== @@ -12973,95 +14014,90 @@ isomorphic-ws@^4.0.1: resolved "https://registry.yarnpkg.com/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz#55fd4cd6c5e6491e76dc125938dd863f5cd4f2dc" integrity sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w== -isstream@~0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" - integrity sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g== - -istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz#189e7909d0a39fa5a3dfad5b03f71947770191d3" - integrity sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw== +isows@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/isows/-/isows-1.0.3.tgz#93c1cf0575daf56e7120bab5c8c448b0809d0d74" + integrity sha512-2cKei4vlmg2cxEjm3wVSqn8pcoRF/LX/wpifuuNquFO4SQmPwarClT+SUCA2lt+l581tTeZIPIZuIDo2jWN1fg== -istanbul-lib-instrument@^4.0.0: - version "4.0.3" - resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz#873c6fff897450118222774696a3f28902d77c1d" - integrity sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ== - dependencies: - "@babel/core" "^7.7.5" - "@istanbuljs/schema" "^0.1.2" - istanbul-lib-coverage "^3.0.0" - semver "^6.3.0" +isows@1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/isows/-/isows-1.0.4.tgz#810cd0d90cc4995c26395d2aa4cfa4037ebdf061" + integrity sha512-hEzjY+x9u9hPmBom9IIAqdJCwNLax+xrPb51vEPpERoFlIxgmZcHzsT5jKG06nvInKOBGvReAVz80Umed5CczQ== -istanbul-lib-instrument@^5.0.4: - version "5.2.1" - resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz#d10c8885c2125574e1c231cacadf955675e1ce3d" - integrity sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg== - dependencies: - "@babel/core" "^7.12.3" - "@babel/parser" "^7.14.7" - "@istanbuljs/schema" "^0.1.2" - istanbul-lib-coverage "^3.2.0" - semver "^6.3.0" +istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.2: + version "3.2.2" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz#2d166c4b0644d43a39f04bf6c2edd1e585f31756" + integrity sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg== -istanbul-lib-report@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#7518fe52ea44de372f460a76b5ecda9ffb73d8a6" - integrity sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw== +istanbul-lib-report@^3.0.0, istanbul-lib-report@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz#908305bac9a5bd175ac6a74489eafd0fc2445a7d" + integrity sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw== dependencies: istanbul-lib-coverage "^3.0.0" - make-dir "^3.0.0" + make-dir "^4.0.0" supports-color "^7.1.0" -istanbul-lib-source-maps@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz#895f3a709fcfba34c6de5a42939022f3e4358551" - integrity sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw== +istanbul-lib-source-maps@^5.0.6: + version "5.0.6" + resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-5.0.6.tgz#acaef948df7747c8eb5fbf1265cb980f6353a441" + integrity sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A== dependencies: + "@jridgewell/trace-mapping" "^0.3.23" debug "^4.1.1" istanbul-lib-coverage "^3.0.0" - source-map "^0.6.1" -istanbul-reports@^3.0.2, istanbul-reports@^3.1.4: - version "3.1.5" - resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.1.5.tgz#cc9a6ab25cb25659810e4785ed9d9fb742578bae" - integrity sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w== +istanbul-reports@^3.1.7: + version "3.1.7" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.1.7.tgz#daed12b9e1dca518e15c056e1e537e741280fa0b" + integrity sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g== dependencies: html-escaper "^2.0.0" istanbul-lib-report "^3.0.0" -iterate-iterator@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/iterate-iterator/-/iterate-iterator-1.0.2.tgz#551b804c9eaa15b847ea6a7cdc2f5bf1ec150f91" - integrity sha512-t91HubM4ZDQ70M9wqp+pcNpu8OyJ9UAtXntT/Bcsvp5tZMnz9vRa+IunKXeI8AnfZMTv0jNuVEmGeLSMjVvfPw== +iterator.prototype@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/iterator.prototype/-/iterator.prototype-1.1.2.tgz#5e29c8924f01916cb9335f1ff80619dcff22b0c0" + integrity sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w== + dependencies: + define-properties "^1.2.1" + get-intrinsic "^1.2.1" + has-symbols "^1.0.3" + reflect.getprototypeof "^1.0.4" + set-function-name "^2.0.1" -iterate-value@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/iterate-value/-/iterate-value-1.0.2.tgz#935115bd37d006a52046535ebc8d07e9c9337f57" - integrity sha512-A6fMAio4D2ot2r/TYzr4yUWrmwNdsN5xL7+HUiyACE4DXm+q8HtPcnFTp+NnW3k4N05tZ7FVYFFb2CR13NxyHQ== +jackspeak@^2.3.5: + version "2.3.6" + resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-2.3.6.tgz#647ecc472238aee4b06ac0e461acc21a8c505ca8" + integrity sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ== + dependencies: + "@isaacs/cliui" "^8.0.2" + optionalDependencies: + "@pkgjs/parseargs" "^0.11.0" + +jackspeak@^3.1.2: + version "3.4.3" + resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-3.4.3.tgz#8833a9d89ab4acde6188942bd1c53b6390ed5a8a" + integrity sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw== dependencies: - es-get-iterator "^1.0.2" - iterate-iterator "^1.0.1" + "@isaacs/cliui" "^8.0.2" + optionalDependencies: + "@pkgjs/parseargs" "^0.11.0" jake@^10.8.5: - version "10.8.5" - resolved "https://registry.yarnpkg.com/jake/-/jake-10.8.5.tgz#f2183d2c59382cb274226034543b9c03b8164c46" - integrity sha512-sVpxYeuAhWt0OTWITwT98oyV0GsXyMlXCF+3L1SuafBVUIr/uILGRB+NqwkzhgXKvoJpDIpQvqkUALgdmQsQxw== + version "10.8.7" + resolved "https://registry.yarnpkg.com/jake/-/jake-10.8.7.tgz#63a32821177940c33f356e0ba44ff9d34e1c7d8f" + integrity sha512-ZDi3aP+fG/LchyBzUM804VjddnwfSfsdeYkwt8NcbKRvo4rFkjhs456iLFn3k2ZUWvNe4i48WACDbza8fhq2+w== dependencies: async "^3.2.3" chalk "^4.0.2" - filelist "^1.0.1" - minimatch "^3.0.4" - -javascript-stringify@^2.0.1: - version "2.1.0" - resolved "https://registry.yarnpkg.com/javascript-stringify/-/javascript-stringify-2.1.0.tgz#27c76539be14d8bd128219a2d731b09337904e79" - integrity sha512-JVAfqNPTvNq3sB/VHQJAFxN/sPgKnsKrCwyRt15zwNCdrMMJDdcEOdubuy+DuJYYdm0ox1J4uzEuYKkN+9yhVg== + filelist "^1.0.4" + minimatch "^3.1.2" -jayson@^3.4.4: - version "3.7.0" - resolved "https://registry.yarnpkg.com/jayson/-/jayson-3.7.0.tgz#b735b12d06d348639ae8230d7a1e2916cb078f25" - integrity sha512-tfy39KJMrrXJ+mFcMpxwBvFDetS8LAID93+rycFglIQM4kl3uNR3W4lBLE/FFhsoUCEox5Dt2adVpDm/XtebbQ== +jayson@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/jayson/-/jayson-4.1.0.tgz#60dc946a85197317f2b1439d672a8b0a99cea2f9" + integrity sha512-R6JlbyLN53Mjku329XoRT2zJAE6ZgOQ8f91ucYdMCD4nkGCF9kZSrcGXpHIU4jeKj58zUZke2p+cdQchU7Ly7A== dependencies: "@types/connect" "^3.4.33" "@types/node" "^12.12.54" @@ -13073,440 +14109,25 @@ jayson@^3.4.4: eyes "^0.1.8" isomorphic-ws "^4.0.1" json-stringify-safe "^5.0.1" - lodash "^4.17.20" uuid "^8.3.2" ws "^7.4.5" -jest-changed-files@^25.5.0: - version "25.5.0" - resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-25.5.0.tgz#141cc23567ceb3f534526f8614ba39421383634c" - integrity sha512-EOw9QEqapsDT7mKF162m8HFzRPbmP8qJQny6ldVOdOVBz3ACgPm/1nAn5fPQ/NDaYhX/AHkrGwwkCncpAVSXcw== - dependencies: - "@jest/types" "^25.5.0" - execa "^3.2.0" - throat "^5.0.0" - -jest-cli@^25.5.4: - version "25.5.4" - resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-25.5.4.tgz#b9f1a84d1301a92c5c217684cb79840831db9f0d" - integrity sha512-rG8uJkIiOUpnREh1768/N3n27Cm+xPFkSNFO91tgg+8o2rXeVLStz+vkXkGr4UtzH6t1SNbjwoiswd7p4AhHTw== - dependencies: - "@jest/core" "^25.5.4" - "@jest/test-result" "^25.5.0" - "@jest/types" "^25.5.0" - chalk "^3.0.0" - exit "^0.1.2" - graceful-fs "^4.2.4" - import-local "^3.0.2" - is-ci "^2.0.0" - jest-config "^25.5.4" - jest-util "^25.5.0" - jest-validate "^25.5.0" - prompts "^2.0.1" - realpath-native "^2.0.0" - yargs "^15.3.1" - -jest-config@^25.5.4: - version "25.5.4" - resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-25.5.4.tgz#38e2057b3f976ef7309b2b2c8dcd2a708a67f02c" - integrity sha512-SZwR91SwcdK6bz7Gco8qL7YY2sx8tFJYzvg216DLihTWf+LKY/DoJXpM9nTzYakSyfblbqeU48p/p7Jzy05Atg== - dependencies: - "@babel/core" "^7.1.0" - "@jest/test-sequencer" "^25.5.4" - "@jest/types" "^25.5.0" - babel-jest "^25.5.1" - chalk "^3.0.0" - deepmerge "^4.2.2" - glob "^7.1.1" - graceful-fs "^4.2.4" - jest-environment-jsdom "^25.5.0" - jest-environment-node "^25.5.0" - jest-get-type "^25.2.6" - jest-jasmine2 "^25.5.4" - jest-regex-util "^25.2.6" - jest-resolve "^25.5.1" - jest-util "^25.5.0" - jest-validate "^25.5.0" - micromatch "^4.0.2" - pretty-format "^25.5.0" - realpath-native "^2.0.0" - -jest-diff@^25.2.1, jest-diff@^25.5.0: - version "25.5.0" - resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-25.5.0.tgz#1dd26ed64f96667c068cef026b677dfa01afcfa9" - integrity sha512-z1kygetuPiREYdNIumRpAHY6RXiGmp70YHptjdaxTWGmA085W3iCnXNx0DhflK3vwrKmrRWyY1wUpkPMVxMK7A== - dependencies: - chalk "^3.0.0" - diff-sequences "^25.2.6" - jest-get-type "^25.2.6" - pretty-format "^25.5.0" - -jest-docblock@^25.3.0: - version "25.3.0" - resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-25.3.0.tgz#8b777a27e3477cd77a168c05290c471a575623ef" - integrity sha512-aktF0kCar8+zxRHxQZwxMy70stc9R1mOmrLsT5VO3pIT0uzGRSDAXxSlz4NqQWpuLjPpuMhPRl7H+5FRsvIQAg== - dependencies: - detect-newline "^3.0.0" - -jest-each@^25.5.0: - version "25.5.0" - resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-25.5.0.tgz#0c3c2797e8225cb7bec7e4d249dcd96b934be516" - integrity sha512-QBogUxna3D8vtiItvn54xXde7+vuzqRrEeaw8r1s+1TG9eZLVJE5ZkKoSUlqFwRjnlaA4hyKGiu9OlkFIuKnjA== - dependencies: - "@jest/types" "^25.5.0" - chalk "^3.0.0" - jest-get-type "^25.2.6" - jest-util "^25.5.0" - pretty-format "^25.5.0" - -jest-environment-jsdom@^25.5.0: - version "25.5.0" - resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-25.5.0.tgz#dcbe4da2ea997707997040ecf6e2560aec4e9834" - integrity sha512-7Jr02ydaq4jaWMZLY+Skn8wL5nVIYpWvmeatOHL3tOcV3Zw8sjnPpx+ZdeBfc457p8jCR9J6YCc+Lga0oIy62A== - dependencies: - "@jest/environment" "^25.5.0" - "@jest/fake-timers" "^25.5.0" - "@jest/types" "^25.5.0" - jest-mock "^25.5.0" - jest-util "^25.5.0" - jsdom "^15.2.1" - -jest-environment-node@^25.5.0: - version "25.5.0" - resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-25.5.0.tgz#0f55270d94804902988e64adca37c6ce0f7d07a1" - integrity sha512-iuxK6rQR2En9EID+2k+IBs5fCFd919gVVK5BeND82fYeLWPqvRcFNPKu9+gxTwfB5XwBGBvZ0HFQa+cHtIoslA== - dependencies: - "@jest/environment" "^25.5.0" - "@jest/fake-timers" "^25.5.0" - "@jest/types" "^25.5.0" - jest-mock "^25.5.0" - jest-util "^25.5.0" - semver "^6.3.0" - -jest-get-type@^25.2.6: - version "25.2.6" - resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-25.2.6.tgz#0b0a32fab8908b44d508be81681487dbabb8d877" - integrity sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig== - -jest-haste-map@^25.5.1: - version "25.5.1" - resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-25.5.1.tgz#1df10f716c1d94e60a1ebf7798c9fb3da2620943" - integrity sha512-dddgh9UZjV7SCDQUrQ+5t9yy8iEgKc1AKqZR9YDww8xsVOtzPQSMVLDChc21+g29oTRexb9/B0bIlZL+sWmvAQ== - dependencies: - "@jest/types" "^25.5.0" - "@types/graceful-fs" "^4.1.2" - anymatch "^3.0.3" - fb-watchman "^2.0.0" - graceful-fs "^4.2.4" - jest-serializer "^25.5.0" - jest-util "^25.5.0" - jest-worker "^25.5.0" - micromatch "^4.0.2" - sane "^4.0.3" - walker "^1.0.7" - which "^2.0.2" - optionalDependencies: - fsevents "^2.1.2" - -jest-haste-map@^26.6.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-26.6.2.tgz#dd7e60fe7dc0e9f911a23d79c5ff7fb5c2cafeaa" - integrity sha512-easWIJXIw71B2RdR8kgqpjQrbMRWQBgiBwXYEhtGUTaX+doCjBheluShdDMeR8IMfJiTqH4+zfhtg29apJf/8w== - dependencies: - "@jest/types" "^26.6.2" - "@types/graceful-fs" "^4.1.2" - "@types/node" "*" - anymatch "^3.0.3" - fb-watchman "^2.0.0" - graceful-fs "^4.2.4" - jest-regex-util "^26.0.0" - jest-serializer "^26.6.2" - jest-util "^26.6.2" - jest-worker "^26.6.2" - micromatch "^4.0.2" - sane "^4.0.3" - walker "^1.0.7" - optionalDependencies: - fsevents "^2.1.2" - -jest-jasmine2@^25.5.4: - version "25.5.4" - resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-25.5.4.tgz#66ca8b328fb1a3c5364816f8958f6970a8526968" - integrity sha512-9acbWEfbmS8UpdcfqnDO+uBUgKa/9hcRh983IHdM+pKmJPL77G0sWAAK0V0kr5LK3a8cSBfkFSoncXwQlRZfkQ== - dependencies: - "@babel/traverse" "^7.1.0" - "@jest/environment" "^25.5.0" - "@jest/source-map" "^25.5.0" - "@jest/test-result" "^25.5.0" - "@jest/types" "^25.5.0" - chalk "^3.0.0" - co "^4.6.0" - expect "^25.5.0" - is-generator-fn "^2.0.0" - jest-each "^25.5.0" - jest-matcher-utils "^25.5.0" - jest-message-util "^25.5.0" - jest-runtime "^25.5.4" - jest-snapshot "^25.5.1" - jest-util "^25.5.0" - pretty-format "^25.5.0" - throat "^5.0.0" - -jest-leak-detector@^25.5.0: - version "25.5.0" - resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-25.5.0.tgz#2291c6294b0ce404241bb56fe60e2d0c3e34f0bb" - integrity sha512-rV7JdLsanS8OkdDpZtgBf61L5xZ4NnYLBq72r6ldxahJWWczZjXawRsoHyXzibM5ed7C2QRjpp6ypgwGdKyoVA== - dependencies: - jest-get-type "^25.2.6" - pretty-format "^25.5.0" - -jest-matcher-utils@^25.5.0: - version "25.5.0" - resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-25.5.0.tgz#fbc98a12d730e5d2453d7f1ed4a4d948e34b7867" - integrity sha512-VWI269+9JS5cpndnpCwm7dy7JtGQT30UHfrnM3mXl22gHGt/b7NkjBqXfbhZ8V4B7ANUsjK18PlSBmG0YH7gjw== - dependencies: - chalk "^3.0.0" - jest-diff "^25.5.0" - jest-get-type "^25.2.6" - pretty-format "^25.5.0" - -jest-message-util@^25.5.0: - version "25.5.0" - resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-25.5.0.tgz#ea11d93204cc7ae97456e1d8716251185b8880ea" - integrity sha512-ezddz3YCT/LT0SKAmylVyWWIGYoKHOFOFXx3/nA4m794lfVUskMcwhip6vTgdVrOtYdjeQeis2ypzes9mZb4EA== - dependencies: - "@babel/code-frame" "^7.0.0" - "@jest/types" "^25.5.0" - "@types/stack-utils" "^1.0.1" - chalk "^3.0.0" - graceful-fs "^4.2.4" - micromatch "^4.0.2" - slash "^3.0.0" - stack-utils "^1.0.1" - -jest-mock@^25.5.0: - version "25.5.0" - resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-25.5.0.tgz#a91a54dabd14e37ecd61665d6b6e06360a55387a" - integrity sha512-eXWuTV8mKzp/ovHc5+3USJMYsTBhyQ+5A1Mak35dey/RG8GlM4YWVylZuGgVXinaW6tpvk/RSecmF37FKUlpXA== - dependencies: - "@jest/types" "^25.5.0" - -jest-pnp-resolver@^1.2.1: - version "1.2.3" - resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz#930b1546164d4ad5937d5540e711d4d38d4cad2e" - integrity sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w== - -jest-regex-util@^25.2.1, jest-regex-util@^25.2.6: - version "25.2.6" - resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-25.2.6.tgz#d847d38ba15d2118d3b06390056028d0f2fd3964" - integrity sha512-KQqf7a0NrtCkYmZZzodPftn7fL1cq3GQAFVMn5Hg8uKx/fIenLEobNanUxb7abQ1sjADHBseG/2FGpsv/wr+Qw== - -jest-regex-util@^26.0.0: - version "26.0.0" - resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-26.0.0.tgz#d25e7184b36e39fd466c3bc41be0971e821fee28" - integrity sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A== - -jest-resolve-dependencies@^25.5.4: - version "25.5.4" - resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-25.5.4.tgz#85501f53957c8e3be446e863a74777b5a17397a7" - integrity sha512-yFmbPd+DAQjJQg88HveObcGBA32nqNZ02fjYmtL16t1xw9bAttSn5UGRRhzMHIQbsep7znWvAvnD4kDqOFM0Uw== - dependencies: - "@jest/types" "^25.5.0" - jest-regex-util "^25.2.6" - jest-snapshot "^25.5.1" - -jest-resolve@^25.5.1: - version "25.5.1" - resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-25.5.1.tgz#0e6fbcfa7c26d2a5fe8f456088dc332a79266829" - integrity sha512-Hc09hYch5aWdtejsUZhA+vSzcotf7fajSlPA6EZPE1RmPBAD39XtJhvHWFStid58iit4IPDLI/Da4cwdDmAHiQ== - dependencies: - "@jest/types" "^25.5.0" - browser-resolve "^1.11.3" - chalk "^3.0.0" - graceful-fs "^4.2.4" - jest-pnp-resolver "^1.2.1" - read-pkg-up "^7.0.1" - realpath-native "^2.0.0" - resolve "^1.17.0" - slash "^3.0.0" - -jest-runner@^25.5.4: - version "25.5.4" - resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-25.5.4.tgz#ffec5df3875da5f5c878ae6d0a17b8e4ecd7c71d" - integrity sha512-V/2R7fKZo6blP8E9BL9vJ8aTU4TH2beuqGNxHbxi6t14XzTb+x90B3FRgdvuHm41GY8ch4xxvf0ATH4hdpjTqg== - dependencies: - "@jest/console" "^25.5.0" - "@jest/environment" "^25.5.0" - "@jest/test-result" "^25.5.0" - "@jest/types" "^25.5.0" - chalk "^3.0.0" - exit "^0.1.2" - graceful-fs "^4.2.4" - jest-config "^25.5.4" - jest-docblock "^25.3.0" - jest-haste-map "^25.5.1" - jest-jasmine2 "^25.5.4" - jest-leak-detector "^25.5.0" - jest-message-util "^25.5.0" - jest-resolve "^25.5.1" - jest-runtime "^25.5.4" - jest-util "^25.5.0" - jest-worker "^25.5.0" - source-map-support "^0.5.6" - throat "^5.0.0" - -jest-runtime@^25.5.4: - version "25.5.4" - resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-25.5.4.tgz#dc981fe2cb2137abcd319e74ccae7f7eeffbfaab" - integrity sha512-RWTt8LeWh3GvjYtASH2eezkc8AehVoWKK20udV6n3/gC87wlTbE1kIA+opCvNWyyPeBs6ptYsc6nyHUb1GlUVQ== - dependencies: - "@jest/console" "^25.5.0" - "@jest/environment" "^25.5.0" - "@jest/globals" "^25.5.2" - "@jest/source-map" "^25.5.0" - "@jest/test-result" "^25.5.0" - "@jest/transform" "^25.5.1" - "@jest/types" "^25.5.0" - "@types/yargs" "^15.0.0" - chalk "^3.0.0" - collect-v8-coverage "^1.0.0" - exit "^0.1.2" - glob "^7.1.3" - graceful-fs "^4.2.4" - jest-config "^25.5.4" - jest-haste-map "^25.5.1" - jest-message-util "^25.5.0" - jest-mock "^25.5.0" - jest-regex-util "^25.2.6" - jest-resolve "^25.5.1" - jest-snapshot "^25.5.1" - jest-util "^25.5.0" - jest-validate "^25.5.0" - realpath-native "^2.0.0" - slash "^3.0.0" - strip-bom "^4.0.0" - yargs "^15.3.1" - -jest-serializer@^25.5.0: - version "25.5.0" - resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-25.5.0.tgz#a993f484e769b4ed54e70e0efdb74007f503072b" - integrity sha512-LxD8fY1lByomEPflwur9o4e2a5twSQ7TaVNLlFUuToIdoJuBt8tzHfCsZ42Ok6LkKXWzFWf3AGmheuLAA7LcCA== - dependencies: - graceful-fs "^4.2.4" - -jest-serializer@^26.6.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-26.6.2.tgz#d139aafd46957d3a448f3a6cdabe2919ba0742d1" - integrity sha512-S5wqyz0DXnNJPd/xfIzZ5Xnp1HrJWBczg8mMfMpN78OJ5eDxXyf+Ygld9wX1DnUWbIbhM1YDY95NjR4CBXkb2g== - dependencies: - "@types/node" "*" - graceful-fs "^4.2.4" - -jest-snapshot@^25.5.1: - version "25.5.1" - resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-25.5.1.tgz#1a2a576491f9961eb8d00c2e5fd479bc28e5ff7f" - integrity sha512-C02JE1TUe64p2v1auUJ2ze5vcuv32tkv9PyhEb318e8XOKF7MOyXdJ7kdjbvrp3ChPLU2usI7Rjxs97Dj5P0uQ== - dependencies: - "@babel/types" "^7.0.0" - "@jest/types" "^25.5.0" - "@types/prettier" "^1.19.0" - chalk "^3.0.0" - expect "^25.5.0" - graceful-fs "^4.2.4" - jest-diff "^25.5.0" - jest-get-type "^25.2.6" - jest-matcher-utils "^25.5.0" - jest-message-util "^25.5.0" - jest-resolve "^25.5.1" - make-dir "^3.0.0" - natural-compare "^1.4.0" - pretty-format "^25.5.0" - semver "^6.3.0" - -jest-util@^25.5.0: - version "25.5.0" - resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-25.5.0.tgz#31c63b5d6e901274d264a4fec849230aa3fa35b0" - integrity sha512-KVlX+WWg1zUTB9ktvhsg2PXZVdkI1NBevOJSkTKYAyXyH4QSvh+Lay/e/v+bmaFfrkfx43xD8QTfgobzlEXdIA== - dependencies: - "@jest/types" "^25.5.0" - chalk "^3.0.0" - graceful-fs "^4.2.4" - is-ci "^2.0.0" - make-dir "^3.0.0" +jest-get-type@^29.6.3: + version "29.6.3" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-29.6.3.tgz#36f499fdcea197c1045a127319c0481723908fd1" + integrity sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw== -jest-util@^26.6.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-26.6.2.tgz#907535dbe4d5a6cb4c47ac9b926f6af29576cbc1" - integrity sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q== +jest-validate@^29.4.3: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-29.7.0.tgz#7bf705511c64da591d46b15fce41400d52147d9c" + integrity sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw== dependencies: - "@jest/types" "^26.6.2" - "@types/node" "*" + "@jest/types" "^29.6.3" + camelcase "^6.2.0" chalk "^4.0.0" - graceful-fs "^4.2.4" - is-ci "^2.0.0" - micromatch "^4.0.2" - -jest-validate@^25.5.0: - version "25.5.0" - resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-25.5.0.tgz#fb4c93f332c2e4cf70151a628e58a35e459a413a" - integrity sha512-okUFKqhZIpo3jDdtUXUZ2LxGUZJIlfdYBvZb1aczzxrlyMlqdnnws9MOxezoLGhSaFc2XYaHNReNQfj5zPIWyQ== - dependencies: - "@jest/types" "^25.5.0" - camelcase "^5.3.1" - chalk "^3.0.0" - jest-get-type "^25.2.6" + jest-get-type "^29.6.3" leven "^3.1.0" - pretty-format "^25.5.0" - -jest-watch-typeahead@^0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/jest-watch-typeahead/-/jest-watch-typeahead-0.5.0.tgz#903dba6112f22daae7e90b0a271853f7ff182008" - integrity sha512-4r36w9vU8+rdg48hj0Z7TvcSqVP6Ao8dk04grlHQNgduyCB0SqrI0xWIl85ZhXrzYvxQ0N5H+rRLAejkQzEHeQ== - dependencies: - ansi-escapes "^4.2.1" - chalk "^3.0.0" - jest-regex-util "^25.2.1" - jest-watcher "^25.2.4" - slash "^3.0.0" - string-length "^3.1.0" - strip-ansi "^6.0.0" - -jest-watcher@^25.2.4, jest-watcher@^25.5.0: - version "25.5.0" - resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-25.5.0.tgz#d6110d101df98badebe435003956fd4a465e8456" - integrity sha512-XrSfJnVASEl+5+bb51V0Q7WQx65dTSk7NL4yDdVjPnRNpM0hG+ncFmDYJo9O8jaSRcAitVbuVawyXCRoxGrT5Q== - dependencies: - "@jest/test-result" "^25.5.0" - "@jest/types" "^25.5.0" - ansi-escapes "^4.2.1" - chalk "^3.0.0" - jest-util "^25.5.0" - string-length "^3.1.0" - -jest-worker@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-24.9.0.tgz#5dbfdb5b2d322e98567898238a9697bcce67b3e5" - integrity sha512-51PE4haMSXcHohnSMdM42anbvZANYTqMrr52tVKPqqsPJMzoP6FYYDVqahX/HrAoKEKz3uUPzSvKs9A3qR4iVw== - dependencies: - merge-stream "^2.0.0" - supports-color "^6.1.0" - -jest-worker@^25.5.0: - version "25.5.0" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-25.5.0.tgz#2611d071b79cea0f43ee57a3d118593ac1547db1" - integrity sha512-/dsSmUkIy5EBGfv/IjjqmFxrNAUpBERfGs1oHROyD7yxjG/w+t0GOJDX8O1k32ySmd7+a5IhnJU2qQFcJ4n1vw== - dependencies: - merge-stream "^2.0.0" - supports-color "^7.0.0" - -jest-worker@^26.5.0, jest-worker@^26.6.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-26.6.2.tgz#7f72cbc4d643c365e27b9fd775f9d0eaa9c7a8ed" - integrity sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ== - dependencies: - "@types/node" "*" - merge-stream "^2.0.0" - supports-color "^7.0.0" + pretty-format "^29.7.0" jest-worker@^27.4.5: version "27.5.1" @@ -13517,19 +14138,10 @@ jest-worker@^27.4.5: merge-stream "^2.0.0" supports-color "^8.0.0" -jest@^25.3.0: - version "25.5.4" - resolved "https://registry.yarnpkg.com/jest/-/jest-25.5.4.tgz#f21107b6489cfe32b076ce2adcadee3587acb9db" - integrity sha512-hHFJROBTqZahnO+X+PMtT6G2/ztqAZJveGqz//FnWWHurizkD05PQGzRZOhF3XP6z7SJmL+5tCfW8qV06JypwQ== - dependencies: - "@jest/core" "^25.5.4" - import-local "^3.0.2" - jest-cli "^25.5.4" - -jpjs@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/jpjs/-/jpjs-1.2.1.tgz#f343833de8838a5beba1f42d5a219be0114c44b7" - integrity sha512-GxJWybWU4NV0RNKi6EIqk6IRPOTqd/h+U7sbtyuD7yUISUzV78LdHnq2xkevJsTlz/EImux4sWj+wfMiwKLkiw== +jiti@^1.17.1, jiti@^1.19.1, jiti@^1.20.0: + version "1.21.0" + resolved "https://registry.yarnpkg.com/jiti/-/jiti-1.21.0.tgz#7c97f8fe045724e136a397f7340475244156105d" + integrity sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q== js-crypto-env@^0.3.2: version "0.3.2" @@ -13582,24 +14194,19 @@ js-sha3@0.8.0, js-sha3@^0.8.0: resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840" integrity sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q== -js-string-escape@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/js-string-escape/-/js-string-escape-1.0.1.tgz#e2625badbc0d67c7533e9edc1068c587ae4137ef" - integrity sha512-Smw4xcfIQ5LVjAOuJCvN/zIodzA/BBSsluuoSykP+lUvScIi4U6RJLfwHet5cxFnCswUjISV8oAXaqaJDY3chg== - "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== -js-yaml@4.1.0, js-yaml@^4.0.0: +js-yaml@4.1.0, js-yaml@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== dependencies: argparse "^2.0.1" -js-yaml@^3.10.0, js-yaml@^3.13.1: +js-yaml@^3.10.0: version "3.14.1" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== @@ -13607,47 +14214,41 @@ js-yaml@^3.10.0, js-yaml@^3.13.1: argparse "^1.0.7" esprima "^4.0.0" -jsbn@~0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" - integrity sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg== - -jsdom@^15.2.1: - version "15.2.1" - resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-15.2.1.tgz#d2feb1aef7183f86be521b8c6833ff5296d07ec5" - integrity sha512-fAl1W0/7T2G5vURSyxBzrJ1LSdQn6Tr5UX/xD4PXDx/PDgwygedfW6El/KIj3xJ7FU61TTYnc/l/B7P49Eqt6g== - dependencies: - abab "^2.0.0" - acorn "^7.1.0" - acorn-globals "^4.3.2" - array-equal "^1.0.0" - cssom "^0.4.1" - cssstyle "^2.0.0" - data-urls "^1.1.0" - domexception "^1.0.1" - escodegen "^1.11.1" - html-encoding-sniffer "^1.0.2" - nwsapi "^2.2.0" - parse5 "5.1.0" - pn "^1.1.0" - request "^2.88.0" - request-promise-native "^1.0.7" - saxes "^3.1.9" - symbol-tree "^3.2.2" - tough-cookie "^3.0.1" - w3c-hr-time "^1.0.1" - w3c-xmlserializer "^1.1.2" - webidl-conversions "^4.0.2" - whatwg-encoding "^1.0.5" - whatwg-mimetype "^2.3.0" - whatwg-url "^7.0.0" - ws "^7.0.0" - xml-name-validator "^3.0.0" +jsbn@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-1.1.0.tgz#b01307cb29b618a1ed26ec79e911f803c4da0040" + integrity sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A== -jsesc@3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-3.0.2.tgz#bb8b09a6597ba426425f2e4a07245c3d00b9343e" - integrity sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g== +jscodeshift@^0.15.1: + version "0.15.2" + resolved "https://registry.yarnpkg.com/jscodeshift/-/jscodeshift-0.15.2.tgz#145563860360b4819a558c75c545f39683e5a0be" + integrity sha512-FquR7Okgmc4Sd0aEDwqho3rEiKR3BdvuG9jfdHjLJ6JQoWSMpavug3AoIfnfWhxFlf+5pzQh8qjqz0DWFrNQzA== + dependencies: + "@babel/core" "^7.23.0" + "@babel/parser" "^7.23.0" + "@babel/plugin-transform-class-properties" "^7.22.5" + "@babel/plugin-transform-modules-commonjs" "^7.23.0" + "@babel/plugin-transform-nullish-coalescing-operator" "^7.22.11" + "@babel/plugin-transform-optional-chaining" "^7.23.0" + "@babel/plugin-transform-private-methods" "^7.22.5" + "@babel/preset-flow" "^7.22.15" + "@babel/preset-typescript" "^7.23.0" + "@babel/register" "^7.22.15" + babel-core "^7.0.0-bridge.0" + chalk "^4.1.2" + flow-parser "0.*" + graceful-fs "^4.2.4" + micromatch "^4.0.4" + neo-async "^2.5.0" + node-dir "^0.1.17" + recast "^0.23.3" + temp "^0.8.4" + write-file-atomic "^2.3.0" + +jscrypto@^1.0.0, jscrypto@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/jscrypto/-/jscrypto-1.0.3.tgz#598febca2a939d6f679c54f56e1fe364cef30cc9" + integrity sha512-lryZl0flhodv4SZHOqyb1bx5sKcJxj0VBo0Kzb4QMAg3L021IC9uGpl0RCZa+9KJwlRGSK2C80ITcwbe19OKLQ== jsesc@^2.5.1: version "2.5.2" @@ -13664,7 +14265,7 @@ json-buffer@3.0.1: resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ== -json-parse-better-errors@^1.0.1, json-parse-better-errors@^1.0.2: +json-parse-better-errors@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== @@ -13674,14 +14275,6 @@ json-parse-even-better-errors@^2.3.0, json-parse-even-better-errors@^2.3.1: resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== -json-schema-to-ts@1.6.4: - version "1.6.4" - resolved "https://registry.yarnpkg.com/json-schema-to-ts/-/json-schema-to-ts-1.6.4.tgz#63e4fe854dff093923be9e8b59b39ee9a7971ba4" - integrity sha512-pR4yQ9DHz6itqswtHCm26mw45FSNfQ9rEQjosaZErhn5J3J2sIViQiz8rDaezjKAhFGpmsoczYVBgGHzFw/stA== - dependencies: - "@types/json-schema" "^7.0.6" - ts-toolbelt "^6.15.5" - json-schema-traverse@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" @@ -13692,46 +14285,44 @@ json-schema-traverse@^1.0.0: resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== -json-schema@0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.4.0.tgz#f7de4cf6efab838ebaeb3236474cbba5a1930ab5" - integrity sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA== - json-stable-stringify-without-jsonify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== -json-stringify-safe@^5.0.1, json-stringify-safe@~5.0.1: +json-stable-stringify@^1.0.2, json-stable-stringify@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.1.1.tgz#52d4361b47d49168bcc4e564189a42e5a7439454" + integrity sha512-SU/971Kt5qVQfJpyDveVhQ/vya+5hvrjClFOcr8c0Fq5aODJjMwutrOfCU+eCnVD5gpx1Q3fEqkyom77zH1iIg== + dependencies: + call-bind "^1.0.5" + isarray "^2.0.5" + jsonify "^0.0.1" + object-keys "^1.1.1" + +json-stringify-safe@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" integrity sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA== -json5@2.x, json5@^2.1.2, json5@^2.2.0, json5@^2.2.1, json5@^2.2.2, json5@^2.2.3: - version "2.2.3" - resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" - integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== - -json5@^1.0.1, json5@^1.0.2: +json5@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.2.tgz#63d98d60f21b313b77c4d6da18bfa69d80e1d593" integrity sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA== dependencies: minimist "^1.2.0" +json5@^2.2.0, json5@^2.2.1, json5@^2.2.2, json5@^2.2.3: + version "2.2.3" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" + integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== + jsonc-parser@3.2.0, jsonc-parser@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.2.0.tgz#31ff3f4c2b9793f89c67212627c51c6394f88e76" integrity sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w== -jsonfile@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" - integrity sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg== - optionalDependencies: - graceful-fs "^4.1.6" - -jsonfile@^6.0.1: +jsonfile@^6.0.1, jsonfile@^6.1.0: version "6.1.0" resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ== @@ -13740,38 +14331,49 @@ jsonfile@^6.0.1: optionalDependencies: graceful-fs "^4.1.6" +jsonify@^0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.1.tgz#2aa3111dae3d34a0f151c63f3a45d995d9420978" + integrity sha512-2/Ki0GcmuqSrgFyelQq9M05y7PS0mEwuIzrf3f1fPqkVDVRvZrPZtVSMHxdgo8Aq0sxAOb/cr2aqqA3LeWHVPg== + jsonparse@^1.2.0: version "1.3.1" resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" integrity sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg== -jsprim@^1.2.2: - version "1.4.2" - resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.2.tgz#712c65533a15c878ba59e9ed5f0e26d5b77c5feb" - integrity sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw== - dependencies: - assert-plus "1.0.0" - extsprintf "1.3.0" - json-schema "0.4.0" - verror "1.10.0" +jsonschema@1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/jsonschema/-/jsonschema-1.2.2.tgz#83ab9c63d65bf4d596f91d81195e78772f6452bc" + integrity sha512-iX5OFQ6yx9NgbHCwse51ohhKgLuLL7Z5cNOeZOPIlDUtAMrxlruHLzVZxbltdHE5mEDXN+75oFOwq6Gn0MZwsA== -"jsx-ast-utils@^2.4.1 || ^3.0.0", jsx-ast-utils@^3.3.3: - version "3.3.3" - resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-3.3.3.tgz#76b3e6e6cece5c69d49a5792c3d01bd1a0cdc7ea" - integrity sha512-fYQHZTZ8jSfmWZ0iyzfwiU4WDX4HpHbMCZ3gPlWYiCl3BoeOTsqKBqnTVfH2rYT7eP5c3sVbeSPHnnJOaTrWiw== +jssha@3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/jssha/-/jssha-3.2.0.tgz#88ec50b866dd1411deaddbe6b3e3692e4c710f16" + integrity sha512-QuruyBENDWdN4tZwJbQq7/eAK85FqrI4oDbXjy5IBhYD+2pTJyBUWZe8ctWaCkrV0gy6AaelgOZZBMeswEa/6Q== + +"jsx-ast-utils@^2.4.1 || ^3.0.0": + version "3.3.5" + resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz#4766bd05a8e2a11af222becd19e15575e52a853a" + integrity sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ== dependencies: - array-includes "^3.1.5" - object.assign "^4.1.3" + array-includes "^3.1.6" + array.prototype.flat "^1.3.1" + object.assign "^4.1.4" + object.values "^1.1.6" -junk@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/junk/-/junk-3.1.0.tgz#31499098d902b7e98c5d9b9c80f43457a88abfa1" - integrity sha512-pBxcB3LFc8QVgdggvZWyeys+hnrNWg4OcZIU/1X59k5jQdLBlCsYGRQaz234SqoRLTCgMH00fY0xRJH+F9METQ== +keccak@^3.0.3: + version "3.0.4" + resolved "https://registry.yarnpkg.com/keccak/-/keccak-3.0.4.tgz#edc09b89e633c0549da444432ecf062ffadee86d" + integrity sha512-3vKuW0jV8J3XNTzvfyicFR5qvxrSAGl7KIhvgOu5cmWwM7tZRj3fMbj/pfIf4be7aznbc+prBWGjywox/g2Y6Q== + dependencies: + node-addon-api "^2.0.0" + node-gyp-build "^4.2.0" + readable-stream "^3.6.0" -keyv@^4.0.0: - version "4.5.2" - resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.2.tgz#0e310ce73bf7851ec702f2eaf46ec4e3805cce56" - integrity sha512-5MHbFaKn8cNSmVW7BYnijeAVlE4cYA/SVkifVgrh7yotnfhKmjuXpDKjrABLnT0SfHWV21P8ow07OGfRrNDg8g== +keyv@^4.5.3: + version "4.5.4" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.4.tgz#a879a99e29452f942439f2a405e3af8b31d4de93" + integrity sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw== dependencies: json-buffer "3.0.1" @@ -13780,150 +14382,139 @@ keyvaluestorage-interface@^1.0.0: resolved "https://registry.yarnpkg.com/keyvaluestorage-interface/-/keyvaluestorage-interface-1.0.0.tgz#13ebdf71f5284ad54be94bd1ad9ed79adad515ff" integrity sha512-8t6Q3TclQ4uZynJY9IGr2+SsIGwK9JHcO6ootkHCGA0CrQCRy+VkouYNO2xicET6b9al7QKzpebNow+gkpCL8g== -kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: - version "3.2.2" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" - integrity sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ== - dependencies: - is-buffer "^1.1.5" - -kind-of@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" - integrity sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw== - dependencies: - is-buffer "^1.1.5" - -kind-of@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" - integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== - -kind-of@^6.0.0, kind-of@^6.0.2, kind-of@^6.0.3: +kind-of@^6.0.2, kind-of@^6.0.3: version "6.0.3" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== +klaw-sync@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/klaw-sync/-/klaw-sync-6.0.0.tgz#1fd2cfd56ebb6250181114f0a581167099c2b28c" + integrity sha512-nIeuVSzdCCs6TDPTqI8w1Yre34sSq7AkZ4B3sfOBbI2CgVSB4Du4aLQijFU2+lhAFCwt9+42Hel6lQNIv6AntQ== + dependencies: + graceful-fs "^4.1.11" + kleur@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== -kleur@^4.0.3: - version "4.1.5" - resolved "https://registry.yarnpkg.com/kleur/-/kleur-4.1.5.tgz#95106101795f7050c6c650f350c683febddb1780" - integrity sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ== - -klona@^2.0.4: - version "2.0.6" - resolved "https://registry.yarnpkg.com/klona/-/klona-2.0.6.tgz#85bffbf819c03b2f53270412420a4555ef882e22" - integrity sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA== - -language-subtag-registry@~0.3.2: - version "0.3.22" - resolved "https://registry.yarnpkg.com/language-subtag-registry/-/language-subtag-registry-0.3.22.tgz#2e1500861b2e457eba7e7ae86877cbd08fa1fd1d" - integrity sha512-tN0MCzyWnoz/4nHS6uxdlFWoUZT7ABptwKPQ52Ea7URk6vll88bWBVhodtnlfEuCcKWNGoc+uGbw1cwa9IKh/w== - -language-tags@=1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/language-tags/-/language-tags-1.0.5.tgz#d321dbc4da30ba8bf3024e040fa5c14661f9193a" - integrity sha512-qJhlO9cGXi6hBGKoxEG/sKZDAHD5Hnu9Hs4WbOY3pCWXDhw0N8x1NenNzm2EnNLkLkk7J2SdxAkDSbb6ftT+UQ== - dependencies: - language-subtag-registry "~0.3.2" - -lazy-universal-dotenv@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/lazy-universal-dotenv/-/lazy-universal-dotenv-3.0.1.tgz#a6c8938414bca426ab8c9463940da451a911db38" - integrity sha512-prXSYk799h3GY3iOWnC6ZigYzMPjxN2svgjJ9shk7oMadSNX3wXy0B6F32PMJv7qtMnrIbUxoEHzbutvxR2LBQ== +lazy-universal-dotenv@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/lazy-universal-dotenv/-/lazy-universal-dotenv-4.0.0.tgz#0b220c264e89a042a37181a4928cdd298af73422" + integrity sha512-aXpZJRnTkpK6gQ/z4nk+ZBLd/Qdp118cvPruLSIQzQNRhKwEcdXCOzXuF55VDqIiuAaY3UGZ10DJtvZzDcvsxg== dependencies: - "@babel/runtime" "^7.5.0" app-root-dir "^1.0.2" - core-js "^3.0.4" - dotenv "^8.0.0" - dotenv-expand "^5.1.0" + dotenv "^16.0.0" + dotenv-expand "^10.0.0" leven@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A== -levn@^0.3.0, levn@~0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" - integrity sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA== +levn@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" + integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== + dependencies: + prelude-ls "^1.2.1" + type-check "~0.4.0" + +libsodium-sumo@^0.7.13: + version "0.7.13" + resolved "https://registry.yarnpkg.com/libsodium-sumo/-/libsodium-sumo-0.7.13.tgz#533b97d2be44b1277e59c1f9f60805978ac5542d" + integrity sha512-zTGdLu4b9zSNLfovImpBCbdAA4xkpkZbMnSQjP8HShyOutnGjRHmSOKlsylh1okao6QhLiz7nG98EGn+04cZjQ== + +libsodium-wrappers-sumo@^0.7.11: + version "0.7.13" + resolved "https://registry.yarnpkg.com/libsodium-wrappers-sumo/-/libsodium-wrappers-sumo-0.7.13.tgz#a33aea845a0bb56db067548f04feba28c730ab8e" + integrity sha512-lz4YdplzDRh6AhnLGF2Dj2IUj94xRN6Bh8T0HLNwzYGwPehQJX6c7iYVrFUPZ3QqxE0bqC+K0IIqqZJYWumwSQ== dependencies: - prelude-ls "~1.1.2" - type-check "~0.3.2" + libsodium-sumo "^0.7.13" libsodium-wrappers@^0.7.6: - version "0.7.11" - resolved "https://registry.yarnpkg.com/libsodium-wrappers/-/libsodium-wrappers-0.7.11.tgz#53bd20606dffcc54ea2122133c7da38218f575f7" - integrity sha512-SrcLtXj7BM19vUKtQuyQKiQCRJPgbpauzl3s0rSwD+60wtHqSUuqcoawlMDheCJga85nKOQwxNYQxf/CKAvs6Q== - dependencies: - libsodium "^0.7.11" - -libsodium@^0.7.11: - version "0.7.11" - resolved "https://registry.yarnpkg.com/libsodium/-/libsodium-0.7.11.tgz#cd10aae7bcc34a300cc6ad0ac88fcca674cfbc2e" - integrity sha512-WPfJ7sS53I2s4iM58QxY3Inb83/6mjlYgcmZs7DJsvDlnmVUwNinBCi5vBT43P6bHRy01O4zsMU2CoVR6xJ40A== - -lightningcss-darwin-arm64@1.19.0: - version "1.19.0" - resolved "https://registry.yarnpkg.com/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.19.0.tgz#56ab071e932f845dbb7667f44f5b78441175a343" - integrity sha512-wIJmFtYX0rXHsXHSr4+sC5clwblEMji7HHQ4Ub1/CznVRxtCFha6JIt5JZaNf8vQrfdZnBxLLC6R8pC818jXqg== - -lightningcss-darwin-x64@1.19.0: - version "1.19.0" - resolved "https://registry.yarnpkg.com/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.19.0.tgz#c867308b88859ba61a2c46c82b1ca52ff73a1bd0" - integrity sha512-Lif1wD6P4poaw9c/4Uh2z+gmrWhw/HtXFoeZ3bEsv6Ia4tt8rOJBdkfVaUJ6VXmpKHALve+iTyP2+50xY1wKPw== - -lightningcss-linux-arm-gnueabihf@1.19.0: - version "1.19.0" - resolved "https://registry.yarnpkg.com/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.19.0.tgz#0f921dc45f2e5c3aea70fab98844ac0e5f2f81be" - integrity sha512-P15VXY5682mTXaiDtbnLYQflc8BYb774j2R84FgDLJTN6Qp0ZjWEFyN1SPqyfTj2B2TFjRHRUvQSSZ7qN4Weig== - -lightningcss-linux-arm64-gnu@1.19.0: - version "1.19.0" - resolved "https://registry.yarnpkg.com/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.19.0.tgz#027f9df9c7f4ffa127c37a71726245a5794d7ba2" - integrity sha512-zwXRjWqpev8wqO0sv0M1aM1PpjHz6RVIsBcxKszIG83Befuh4yNysjgHVplF9RTU7eozGe3Ts7r6we1+Qkqsww== - -lightningcss-linux-arm64-musl@1.19.0: - version "1.19.0" - resolved "https://registry.yarnpkg.com/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.19.0.tgz#85ea987da868524eac6db94f8e1eaa23d0b688a3" - integrity sha512-vSCKO7SDnZaFN9zEloKSZM5/kC5gbzUjoJQ43BvUpyTFUX7ACs/mDfl2Eq6fdz2+uWhUh7vf92c4EaaP4udEtA== - -lightningcss-linux-x64-gnu@1.19.0: - version "1.19.0" - resolved "https://registry.yarnpkg.com/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.19.0.tgz#02bec89579ab4153dccc0def755d1fd9e3ee7f3c" - integrity sha512-0AFQKvVzXf9byrXUq9z0anMGLdZJS+XSDqidyijI5njIwj6MdbvX2UZK/c4FfNmeRa2N/8ngTffoIuOUit5eIQ== - -lightningcss-linux-x64-musl@1.19.0: - version "1.19.0" - resolved "https://registry.yarnpkg.com/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.19.0.tgz#e36a5df8193ae961d22974635e4c100a1823bb8c" - integrity sha512-SJoM8CLPt6ECCgSuWe+g0qo8dqQYVcPiW2s19dxkmSI5+Uu1GIRzyKA0b7QqmEXolA+oSJhQqCmJpzjY4CuZAg== - -lightningcss-win32-x64-msvc@1.19.0: - version "1.19.0" - resolved "https://registry.yarnpkg.com/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.19.0.tgz#0854dbd153035eca1396e2227c708ad43655a61c" - integrity sha512-C+VuUTeSUOAaBZZOPT7Etn/agx/MatzJzGRkeV+zEABmPuntv1zihncsi+AyGmjkkzq3wVedEy7h0/4S84mUtg== - -lightningcss@^1.16.1: - version "1.19.0" - resolved "https://registry.yarnpkg.com/lightningcss/-/lightningcss-1.19.0.tgz#fbbad0975de66252e38d96b5bdd2a62f2dd0ffbf" - integrity sha512-yV5UR7og+Og7lQC+70DA7a8ta1uiOPnWPJfxa0wnxylev5qfo4P+4iMpzWAdYWOca4jdNQZii+bDL/l+4hUXIA== + version "0.7.13" + resolved "https://registry.yarnpkg.com/libsodium-wrappers/-/libsodium-wrappers-0.7.13.tgz#83299e06ee1466057ba0e64e532777d2929b90d3" + integrity sha512-kasvDsEi/r1fMzKouIDv7B8I6vNmknXwGiYodErGuESoFTohGSKZplFtVxZqHaoQ217AynyIFgnOVRitpHs0Qw== + dependencies: + libsodium "^0.7.13" + +libsodium@^0.7.13: + version "0.7.13" + resolved "https://registry.yarnpkg.com/libsodium/-/libsodium-0.7.13.tgz#230712ec0b7447c57b39489c48a4af01985fb393" + integrity sha512-mK8ju0fnrKXXfleL53vtp9xiPq5hKM0zbDQtcxQIsSmxNgSxqCj6R7Hl9PkrNe2j29T4yoDaF7DJLK9/i5iWUw== + +lie@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/lie/-/lie-3.1.1.tgz#9a436b2cc7746ca59de7a41fa469b3efb76bd87e" + integrity sha512-RiNhHysUjhrDQntfYSfY4MU24coXXdEOgw9WGcKHNeEwffDYbF//u87M1EWaMGzuFoSbqW0C9C6lEEhDOAswfw== + dependencies: + immediate "~3.0.5" + +lightningcss-darwin-arm64@1.23.0: + version "1.23.0" + resolved "https://registry.yarnpkg.com/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.23.0.tgz#11780f37158a458cead5e89202f74cd99b926e36" + integrity sha512-kl4Pk3Q2lnE6AJ7Qaij47KNEfY2/UXRZBT/zqGA24B8qwkgllr/j7rclKOf1axcslNXvvUdztjo4Xqh39Yq1aA== + +lightningcss-darwin-x64@1.23.0: + version "1.23.0" + resolved "https://registry.yarnpkg.com/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.23.0.tgz#8394edaa04f0984b971eab42b6f68edb1258b3ed" + integrity sha512-KeRFCNoYfDdcolcFXvokVw+PXCapd2yHS1Diko1z1BhRz/nQuD5XyZmxjWdhmhN/zj5sH8YvWsp0/lPLVzqKpg== + +lightningcss-freebsd-x64@1.23.0: + version "1.23.0" + resolved "https://registry.yarnpkg.com/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.23.0.tgz#d3f6faddc424f17ed046e8be9ca97868a5f804ed" + integrity sha512-xhnhf0bWPuZxcqknvMDRFFo2TInrmQRWZGB0f6YoAsZX8Y+epfjHeeOIGCfAmgF0DgZxHwYc8mIR5tQU9/+ROA== + +lightningcss-linux-arm-gnueabihf@1.23.0: + version "1.23.0" + resolved "https://registry.yarnpkg.com/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.23.0.tgz#040e9718c9a9dc088322da33983a894564ffcb10" + integrity sha512-fBamf/bULvmWft9uuX+bZske236pUZEoUlaHNBjnueaCTJ/xd8eXgb0cEc7S5o0Nn6kxlauMBnqJpF70Bgq3zg== + +lightningcss-linux-arm64-gnu@1.23.0: + version "1.23.0" + resolved "https://registry.yarnpkg.com/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.23.0.tgz#05cfcfa2cf47a042ca11cfce520ae9f91e4efcdb" + integrity sha512-RS7sY77yVLOmZD6xW2uEHByYHhQi5JYWmgVumYY85BfNoVI3DupXSlzbw+b45A9NnVKq45+oXkiN6ouMMtTwfg== + +lightningcss-linux-arm64-musl@1.23.0: + version "1.23.0" + resolved "https://registry.yarnpkg.com/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.23.0.tgz#3212a10dff37c70808113fbcf7cbd1b63c6cbc6f" + integrity sha512-cU00LGb6GUXCwof6ACgSMKo3q7XYbsyTj0WsKHLi1nw7pV0NCq8nFTn6ZRBYLoKiV8t+jWl0Hv8KkgymmK5L5g== + +lightningcss-linux-x64-gnu@1.23.0: + version "1.23.0" + resolved "https://registry.yarnpkg.com/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.23.0.tgz#3b27da32889285b1c5de3f26094ee234054634fc" + integrity sha512-q4jdx5+5NfB0/qMbXbOmuC6oo7caPnFghJbIAV90cXZqgV8Am3miZhC4p+sQVdacqxfd+3nrle4C8icR3p1AYw== + +lightningcss-linux-x64-musl@1.23.0: + version "1.23.0" + resolved "https://registry.yarnpkg.com/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.23.0.tgz#ad65b5a944f10d966cc10070bf20f81ddadd4240" + integrity sha512-G9Ri3qpmF4qef2CV/80dADHKXRAQeQXpQTLx7AiQrBYQHqBjB75oxqj06FCIe5g4hNCqLPnM9fsO4CyiT1sFSQ== + +lightningcss-win32-x64-msvc@1.23.0: + version "1.23.0" + resolved "https://registry.yarnpkg.com/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.23.0.tgz#62f3f619a7bb44f8713973103fbe1bcbd9d455f9" + integrity sha512-1rcBDJLU+obPPJM6qR5fgBUiCdZwZLafZM5f9kwjFLkb/UBNIzmae39uCSmh71nzPCTXZqHbvwu23OWnWEz+eg== + +lightningcss@^1.22.1: + version "1.23.0" + resolved "https://registry.yarnpkg.com/lightningcss/-/lightningcss-1.23.0.tgz#58c94a533d02d8416d4f2ec9ab87641f61943c78" + integrity sha512-SEArWKMHhqn/0QzOtclIwH5pXIYQOUEkF8DgICd/105O+GCgd7jxjNod/QPnBCSWvpRHQBGVz5fQ9uScby03zA== dependencies: detect-libc "^1.0.3" optionalDependencies: - lightningcss-darwin-arm64 "1.19.0" - lightningcss-darwin-x64 "1.19.0" - lightningcss-linux-arm-gnueabihf "1.19.0" - lightningcss-linux-arm64-gnu "1.19.0" - lightningcss-linux-arm64-musl "1.19.0" - lightningcss-linux-x64-gnu "1.19.0" - lightningcss-linux-x64-musl "1.19.0" - lightningcss-win32-x64-msvc "1.19.0" - -lilconfig@^2.0.5, lilconfig@^2.0.6: + lightningcss-darwin-arm64 "1.23.0" + lightningcss-darwin-x64 "1.23.0" + lightningcss-freebsd-x64 "1.23.0" + lightningcss-linux-arm-gnueabihf "1.23.0" + lightningcss-linux-arm64-gnu "1.23.0" + lightningcss-linux-arm64-musl "1.23.0" + lightningcss-linux-x64-gnu "1.23.0" + lightningcss-linux-x64-musl "1.23.0" + lightningcss-win32-x64-msvc "1.23.0" + +lilconfig@2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-2.1.0.tgz#78e23ac89ebb7e1bfbf25b18043de756548e7f52" integrity sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ== @@ -13934,38 +14525,103 @@ lines-and-columns@^1.1.6: integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== lines-and-columns@~2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-2.0.3.tgz#b2f0badedb556b747020ab8ea7f0373e22efac1b" - integrity sha512-cNOjgCnLB+FnvWWtyRTzmB3POJ+cXxTA81LoW7u8JdmhfXzriropYwpjShnz1QLLWsQwY7nIxoDmcPTwphDK9w== + version "2.0.4" + resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-2.0.4.tgz#d00318855905d2660d8c0822e3f5a4715855fc42" + integrity sha512-wM1+Z03eypVAVUCE7QdSqpVIvelbOakn1M0bPDoA4SGWPx3sNDVUiMo3L6To6WWGClB7VyXnhQ4Sn7gxiJbE6A== + +lint-staged@^13.2.2: + version "13.3.0" + resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-13.3.0.tgz#7965d72a8d6a6c932f85e9c13ccf3596782d28a5" + integrity sha512-mPRtrYnipYYv1FEE134ufbWpeggNTo+O/UPzngoaKzbzHAthvR55am+8GfHTnqNRQVRRrYQLGW9ZyUoD7DsBHQ== + dependencies: + chalk "5.3.0" + commander "11.0.0" + debug "4.3.4" + execa "7.2.0" + lilconfig "2.1.0" + listr2 "6.6.1" + micromatch "4.0.5" + pidtree "0.6.0" + string-argv "0.3.2" + yaml "2.3.1" + +listhen@^1.5.5: + version "1.5.5" + resolved "https://registry.yarnpkg.com/listhen/-/listhen-1.5.5.tgz#58915512af70f770aa3e9fb19367adf479bb58c4" + integrity sha512-LXe8Xlyh3gnxdv4tSjTjscD1vpr/2PRpzq8YIaMJgyKzRG8wdISlWVWnGThJfHnlJ6hmLt2wq1yeeix0TEbuoA== + dependencies: + "@parcel/watcher" "^2.3.0" + "@parcel/watcher-wasm" "2.3.0" + citty "^0.1.4" + clipboardy "^3.0.0" + consola "^3.2.3" + defu "^6.1.2" + get-port-please "^3.1.1" + h3 "^1.8.1" + http-shutdown "^1.2.2" + jiti "^1.20.0" + mlly "^1.4.2" + node-forge "^1.3.1" + pathe "^1.1.1" + std-env "^3.4.3" + ufo "^1.3.0" + untun "^0.1.2" + uqr "^0.1.2" + +listr2@6.6.1: + version "6.6.1" + resolved "https://registry.yarnpkg.com/listr2/-/listr2-6.6.1.tgz#08b2329e7e8ba6298481464937099f4a2cd7f95d" + integrity sha512-+rAXGHh0fkEWdXBmX+L6mmfmXmXvDGEKzkjxO+8mP3+nI/r/CWznVBvsibXdxda9Zz0OW2e2ikphN3OwCT/jSg== + dependencies: + cli-truncate "^3.1.0" + colorette "^2.0.20" + eventemitter3 "^5.0.1" + log-update "^5.0.1" + rfdc "^1.3.0" + wrap-ansi "^8.1.0" + +lit-element@^3.3.0: + version "3.3.3" + resolved "https://registry.yarnpkg.com/lit-element/-/lit-element-3.3.3.tgz#10bc19702b96ef5416cf7a70177255bfb17b3209" + integrity sha512-XbeRxmTHubXENkV4h8RIPyr8lXc+Ff28rkcQzw3G6up2xg5E8Zu1IgOWIwBLEQsu3cOVFqdYwiVi0hv0SlpqUA== + dependencies: + "@lit-labs/ssr-dom-shim" "^1.1.0" + "@lit/reactive-element" "^1.3.0" + lit-html "^2.8.0" -lmdb@2.5.2: - version "2.5.2" - resolved "https://registry.yarnpkg.com/lmdb/-/lmdb-2.5.2.tgz#37e28a9fb43405f4dc48c44cec0e13a14c4a6ff1" - integrity sha512-V5V5Xa2Hp9i2XsbDALkBTeHXnBXh/lEmk9p22zdr7jtuOIY9TGhjK6vAvTpOOx9IKU4hJkRWZxn/HsvR1ELLtA== +lit-html@^2.8.0: + version "2.8.0" + resolved "https://registry.yarnpkg.com/lit-html/-/lit-html-2.8.0.tgz#96456a4bb4ee717b9a7d2f94562a16509d39bffa" + integrity sha512-o9t+MQM3P4y7M7yNzqAyjp7z+mQGa4NS4CxiyLqFPyFWyc4O+nodLrkrxSaCTrla6M5YOLaT3RpbbqjszB5g3Q== dependencies: - msgpackr "^1.5.4" - node-addon-api "^4.3.0" - node-gyp-build-optional-packages "5.0.3" - ordered-binary "^1.2.4" + "@types/trusted-types" "^2.0.2" + +lit@2.8.0: + version "2.8.0" + resolved "https://registry.yarnpkg.com/lit/-/lit-2.8.0.tgz#4d838ae03059bf9cafa06e5c61d8acc0081e974e" + integrity sha512-4Sc3OFX9QHOJaHbmTMk28SYgVxLN3ePDjg7hofEft2zWlehFL3LiAuapWc4U/kYwMYJSh2hTCPZ6/LIC7ii0MA== + dependencies: + "@lit/reactive-element" "^1.6.0" + lit-element "^3.3.0" + lit-html "^2.8.0" + +lmdb@2.8.5: + version "2.8.5" + resolved "https://registry.yarnpkg.com/lmdb/-/lmdb-2.8.5.tgz#ce191110c755c0951caa062722e300c703973837" + integrity sha512-9bMdFfc80S+vSldBmG3HOuLVHnxRdNTlpzR6QDnzqCQtCzGUEAGTzBKYMeIM+I/sU4oZfgbcbS7X7F65/z/oxQ== + dependencies: + msgpackr "^1.9.5" + node-addon-api "^6.1.0" + node-gyp-build-optional-packages "5.1.1" + ordered-binary "^1.4.1" weak-lru-cache "^1.2.2" optionalDependencies: - "@lmdb/lmdb-darwin-arm64" "2.5.2" - "@lmdb/lmdb-darwin-x64" "2.5.2" - "@lmdb/lmdb-linux-arm" "2.5.2" - "@lmdb/lmdb-linux-arm64" "2.5.2" - "@lmdb/lmdb-linux-x64" "2.5.2" - "@lmdb/lmdb-win32-x64" "2.5.2" - -load-json-file@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" - integrity sha512-cy7ZdNRXdablkXYNI049pthVeXFurRyb9+hA/dZzerZ0pGTx42z+y+ssxBaVV2l70t1muq5IdKhn4UtcoGUY9A== - dependencies: - graceful-fs "^4.1.2" - parse-json "^2.2.0" - pify "^2.0.0" - pinkie-promise "^2.0.0" - strip-bom "^2.0.0" + "@lmdb/lmdb-darwin-arm64" "2.8.5" + "@lmdb/lmdb-darwin-x64" "2.8.5" + "@lmdb/lmdb-linux-arm" "2.8.5" + "@lmdb/lmdb-linux-arm64" "2.8.5" + "@lmdb/lmdb-linux-x64" "2.8.5" + "@lmdb/lmdb-win32-x64" "2.8.5" load-json-file@^4.0.0: version "4.0.0" @@ -13977,38 +14633,33 @@ load-json-file@^4.0.0: pify "^3.0.0" strip-bom "^3.0.0" -loader-runner@^2.4.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.4.0.tgz#ed47066bfe534d7e84c4c7b9998c2a75607d9357" - integrity sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw== - loader-runner@^4.2.0: version "4.3.0" resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.3.0.tgz#c1b4a163b99f614830353b16755e7149ac2314e1" integrity sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg== -loader-utils@^1.2.3: - version "1.4.2" - resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.4.2.tgz#29a957f3a63973883eb684f10ffd3d151fec01a3" - integrity sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg== +local-pkg@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/local-pkg/-/local-pkg-0.5.0.tgz#093d25a346bae59a99f80e75f6e9d36d7e8c925c" + integrity sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg== + dependencies: + mlly "^1.4.2" + pkg-types "^1.0.3" + +localforage@^1.8.1: + version "1.10.0" + resolved "https://registry.yarnpkg.com/localforage/-/localforage-1.10.0.tgz#5c465dc5f62b2807c3a84c0c6a1b1b3212781dd4" + integrity sha512-14/H1aX7hzBBmmh7sGPd+AOMkkIrHM3Z1PAyGgZigA1H1p5O5ANnMyWzvpAETtG68/dC4pC0ncy3+PPGzXZHPg== dependencies: - big.js "^5.2.2" - emojis-list "^3.0.0" - json5 "^1.0.1" + lie "3.1.1" -loader-utils@^2.0.0, loader-utils@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.4.tgz#8b5cb38b5c34a9a018ee1fc0e6a066d1dfcc528c" - integrity sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw== +locate-path@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" + integrity sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA== dependencies: - big.js "^5.2.2" - emojis-list "^3.0.0" - json5 "^2.1.2" - -loader-utils@^3.2.0: - version "3.2.1" - resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-3.2.1.tgz#4fb104b599daafd82ef3e1a41fb9265f87e1f576" - integrity sha512-ZvFw1KWS3GVyYBYb7qkmRM/WwL2TQQBxgCK62rlvm4WpVQ23Nb4tYjApUlfjrEGvOs7KHEsmyUn75OHZrJMWPw== + p-locate "^2.0.0" + path-exists "^3.0.0" locate-path@^3.0.0: version "3.0.0" @@ -14032,6 +14683,13 @@ locate-path@^6.0.0: dependencies: p-locate "^5.0.0" +locate-path@^7.1.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-7.2.0.tgz#69cb1779bd90b35ab1e771e1f2f89a202c2a8a8a" + integrity sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA== + dependencies: + p-locate "^6.0.0" + lodash-es@^4.17.15: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.21.tgz#43e626c46e6591b7750beb2b50117390c609e3ee" @@ -14047,12 +14705,47 @@ lodash.debounce@^4.0.8: resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" integrity sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow== +lodash.defaults@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-4.2.0.tgz#d09178716ffea4dde9e5fb7b37f6f0802274580c" + integrity sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ== + +lodash.get@^4.4.2: + version "4.4.2" + resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99" + integrity sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ== + +lodash.isarguments@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a" + integrity sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg== + +lodash.isequal@4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0" + integrity sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ== + +lodash.isfunction@^3.0.9: + version "3.0.9" + resolved "https://registry.yarnpkg.com/lodash.isfunction/-/lodash.isfunction-3.0.9.tgz#06de25df4db327ac931981d1bdb067e5af68d051" + integrity sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw== + lodash.ismatch@^4.4.0: version "4.4.0" resolved "https://registry.yarnpkg.com/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz#756cb5150ca3ba6f11085a78849645f188f85f37" integrity sha512-fPMfXjGQEV9Xsq/8MTSgUf255gawYRbjwMyDbcvDhXgV7enSZA0hynz6vMPnpAb5iONEzBHBPsT+0zes5Z301g== -lodash.memoize@4.x, lodash.memoize@^4.1.2: +lodash.isplainobject@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb" + integrity sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA== + +lodash.kebabcase@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz#8489b1cb0d29ff88195cceca448ff6d6cc295c36" + integrity sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g== + +lodash.memoize@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" integrity sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag== @@ -14062,33 +14755,51 @@ lodash.merge@^4.6.2: resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== +lodash.mergewith@^4.6.2: + version "4.6.2" + resolved "https://registry.yarnpkg.com/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz#617121f89ac55f59047c7aec1ccd6654c6590f55" + integrity sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ== + +lodash.snakecase@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz#39d714a35357147837aefd64b5dcbb16becd8f8d" + integrity sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw== + lodash.sortby@^4.7.0: version "4.7.0" resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" integrity sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA== +lodash.startcase@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/lodash.startcase/-/lodash.startcase-4.4.0.tgz#9436e34ed26093ed7ffae1936144350915d9add8" + integrity sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg== + lodash.throttle@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/lodash.throttle/-/lodash.throttle-4.1.1.tgz#c23e91b710242ac70c37f1e1cda9274cc39bf2f4" integrity sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ== -lodash.uniq@4.5.0: +lodash.uniq@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" integrity sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ== -lodash@^4.0.1, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21: +lodash.upperfirst@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/lodash.upperfirst/-/lodash.upperfirst-4.3.1.tgz#1365edf431480481ef0d1c68957a5ed99d49f7ce" + integrity sha512-sReKOYJIJf74dhJONhU4e0/shzi1trVbSWDOhKYE5XV2O+H7Sb2Dihwuc7xWxVl+DgFPyTqIN3zMfT9cq5iWDg== + +lodash.zipobject@^4.1.3: + version "4.1.3" + resolved "https://registry.yarnpkg.com/lodash.zipobject/-/lodash.zipobject-4.1.3.tgz#b399f5aba8ff62a746f6979bf20b214f964dbef8" + integrity sha512-A9SzX4hMKWS25MyalwcOnNoplyHbkNVsjidhTp8ru0Sj23wY9GWBKS8gAIGDSAqeWjIjvE4KBEl24XXAs+v4wQ== + +lodash@^4.0.1, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17.4: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== -log-symbols@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-3.0.0.tgz#f3a08516a5dea893336a7dee14d18a1cfdab77c4" - integrity sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ== - dependencies: - chalk "^2.4.2" - log-symbols@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" @@ -14097,36 +14808,26 @@ log-symbols@^4.1.0: chalk "^4.1.0" is-unicode-supported "^0.1.0" -log-update@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/log-update/-/log-update-2.3.0.tgz#88328fd7d1ce7938b29283746f0b1bc126b24708" - integrity sha512-vlP11XfFGyeNQlmEn9tJ66rEW1coA/79m5z6BCkudjbAGE83uhAcGYrBFwfs3AdLiLzGRusRPAbSPK9xZteCmg== - dependencies: - ansi-escapes "^3.0.0" - cli-cursor "^2.0.0" - wrap-ansi "^3.0.1" - -lolex@^5.0.0: - version "5.1.2" - resolved "https://registry.yarnpkg.com/lolex/-/lolex-5.1.2.tgz#953694d098ce7c07bc5ed6d0e42bc6c0c6d5a367" - integrity sha512-h4hmjAvHTmd+25JSwrtTIuwbKdwg5NzZVRMLn9saij4SZaepCrTCxPr35H/3bjwfMJtN+t3CX8672UIkglz28A== +log-update@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/log-update/-/log-update-5.0.1.tgz#9e928bf70cb183c1f0c9e91d9e6b7115d597ce09" + integrity sha512-5UtUDQ/6edw4ofyljDNcOVJQ4c7OjDro4h3y8e1GQL5iYElYclVHJ3zeWchylvMaKnDbDilC8irOVyexnA/Slw== dependencies: - "@sinonjs/commons" "^1.7.0" + ansi-escapes "^5.0.0" + cli-cursor "^4.0.0" + slice-ansi "^5.0.0" + strip-ansi "^7.0.1" + wrap-ansi "^8.0.1" long@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28" integrity sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA== -long@^5.2.1: - version "5.2.1" - resolved "https://registry.yarnpkg.com/long/-/long-5.2.1.tgz#e27595d0083d103d2fa2c20c7699f8e0c92b897f" - integrity sha512-GKSNGeNAtw8IryjjkhZxuKB3JzlcLTwjtiQCHKvqQet81I93kXslhDQruGI/QsddO83mcDToBVy7GqGS/zYf/A== - -longest-streak@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/longest-streak/-/longest-streak-3.1.0.tgz#62fa67cd958742a1574af9f39866364102d90cd4" - integrity sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g== +long@^5.2.3: + version "5.2.3" + resolved "https://registry.yarnpkg.com/long/-/long-5.2.3.tgz#a3ba97f3877cf1d778eccbcb048525ebb77499e1" + integrity sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q== loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.3.1, loose-envify@^1.4.0: version "1.4.0" @@ -14135,13 +14836,12 @@ loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.3.1, loose-envify@^1.4 dependencies: js-tokens "^3.0.0 || ^4.0.0" -loud-rejection@^1.0.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f" - integrity sha512-RPNliZOFkqFumDhvYqOaNY4Uz9oJM2K9tC6JWsJJsNdhuONW4LQHRBpb0qf4pJApVffI5N39SwzWZJuEhfd7eQ== +loupe@^3.1.0, loupe@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/loupe/-/loupe-3.1.1.tgz#71d038d59007d890e3247c5db97c1ec5a92edc54" + integrity sha512-edNu/8D5MKVfGVFRhFf8aAxiTM6Wumfz5XsaatSxlD3w4R1d/WEKUTydCdPGbl9K7QG/Ca3GnDV2sIKIpXRQcw== dependencies: - currently-unhandled "^0.4.1" - signal-exit "^3.0.0" + get-func-name "^2.0.1" lower-case@^2.0.2: version "2.0.2" @@ -14150,10 +14850,13 @@ lower-case@^2.0.2: dependencies: tslib "^2.0.3" -lowercase-keys@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479" - integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA== +lowlight@^1.17.0: + version "1.20.0" + resolved "https://registry.yarnpkg.com/lowlight/-/lowlight-1.20.0.tgz#ddb197d33462ad0d93bf19d17b6c301aa3941888" + integrity sha512-8Ktj+prEb1RoCPkEOrPMYUN/nCggB7qAWe3a7OpMjWQkh3l2RD5wKRQ+o8Q8YuI9RG/xs95waaI/E6ym/7NsTw== + dependencies: + fault "^1.0.0" + highlight.js "~10.7.0" lowlight@~1.11.0: version "1.11.0" @@ -14163,6 +14866,16 @@ lowlight@~1.11.0: fault "^1.0.2" highlight.js "~9.13.0" +lru-cache@^10.0.2, "lru-cache@^9.1.1 || ^10.0.0": + version "10.1.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.1.0.tgz#2098d41c2dc56500e6c88584aa656c84de7d0484" + integrity sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag== + +lru-cache@^10.2.0: + version "10.4.3" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.4.3.tgz#410fc8a17b70e598013df257c2446b7f3383f119" + integrity sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ== + lru-cache@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" @@ -14177,17 +14890,40 @@ lru-cache@^6.0.0: dependencies: yallist "^4.0.0" -lru-cache@^7.14.1: - version "7.18.3" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-7.18.3.tgz#f793896e0fd0e954a59dfdd82f0773808df6aa89" - integrity sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA== +lz-string@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/lz-string/-/lz-string-1.5.0.tgz#c1ab50f77887b712621201ba9fd4e3a6ed099941" + integrity sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ== + +magic-string@^0.27.0: + version "0.27.0" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.27.0.tgz#e4a3413b4bab6d98d2becffd48b4a257effdbbf3" + integrity sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA== + dependencies: + "@jridgewell/sourcemap-codec" "^1.4.13" + +magic-string@^0.30.0, magic-string@^0.30.5: + version "0.30.9" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.9.tgz#8927ae21bfdd856310e07a1bc8dd5e73cb6c251d" + integrity sha512-S1+hd+dIrC8EZqKyT9DstTH/0Z+f76kmmvZnkfQVmOpDEF9iVgdYif3Q/pIWHmCoo59bQVGW0kVL3e2nl+9+Sw== + dependencies: + "@jridgewell/sourcemap-codec" "^1.4.15" + +magic-string@^0.30.10: + version "0.30.11" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.11.tgz#301a6f93b3e8c2cb13ac1a7a673492c0dfd12954" + integrity sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A== + dependencies: + "@jridgewell/sourcemap-codec" "^1.5.0" -magic-string@^0.25.2, magic-string@^0.25.3, magic-string@^0.25.7: - version "0.25.9" - resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.25.9.tgz#de7f9faf91ef8a1c91d02c2e5314c8277dbcdd1c" - integrity sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ== +magicast@^0.3.4: + version "0.3.4" + resolved "https://registry.yarnpkg.com/magicast/-/magicast-0.3.4.tgz#bbda1791d03190a24b00ff3dd18151e7fd381d19" + integrity sha512-TyDF/Pn36bBji9rWKHlZe+PZb6Mx5V8IHCSxk7X4aljM4e/vyDvZZYwHewdVaqiA0nb3ghfHU/6AUpDxWoER2Q== dependencies: - sourcemap-codec "^1.4.8" + "@babel/parser" "^7.24.4" + "@babel/types" "^7.24.0" + source-map-js "^1.2.0" make-dir@^2.0.0, make-dir@^2.1.0: version "2.1.0" @@ -14197,31 +14933,21 @@ make-dir@^2.0.0, make-dir@^2.1.0: pify "^4.0.1" semver "^5.6.0" -make-dir@^3.0.0, make-dir@^3.0.2, make-dir@^3.1.0: +make-dir@^3.0.2: version "3.1.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== dependencies: semver "^6.0.0" -make-error@1.x, make-error@^1.1.1: - version "1.3.6" - resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" - integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== - -makeerror@1.0.12: - version "1.0.12" - resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.12.tgz#3e5dd2079a82e812e983cc6610c4a2cb0eaa801a" - integrity sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg== +make-dir@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-4.0.0.tgz#c3c2307a771277cd9638305f915c29ae741b614e" + integrity sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw== dependencies: - tmpl "1.0.5" - -map-cache@^0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" - integrity sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg== + semver "^7.5.3" -map-obj@^1.0.0, map-obj@^1.0.1: +map-obj@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" integrity sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg== @@ -14236,22 +14962,10 @@ map-or-similar@^1.5.0: resolved "https://registry.yarnpkg.com/map-or-similar/-/map-or-similar-1.5.0.tgz#6de2653174adfb5d9edc33c69d3e92a1b76faf08" integrity sha512-0aF7ZmVon1igznGI4VS30yugpduQW3y3GkcgGJOp7d8x8QrizhigUxjI/m2UojsXXto+jLAH3KSz+xOJTiORjg== -map-visit@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" - integrity sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w== - dependencies: - object-visit "^1.0.0" - -markdown-escapes@^1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/markdown-escapes/-/markdown-escapes-1.0.4.tgz#c95415ef451499d7602b91095f3c8e8975f78535" - integrity sha512-8z4efJYk43E0upd0NbVXwgSTQs6cT3T06etieCMEg7dRbzCbxUCK/GHlX8mhHRDcp+OLlHkPKsvqQTCvsRl2cg== - -markdown-extensions@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/markdown-extensions/-/markdown-extensions-1.1.1.tgz#fea03b539faeaee9b4ef02a3769b455b189f7fc3" - integrity sha512-WWC0ZuMzCyDHYCasEGs4IPvLyTGftYwh6wIEOULOF0HXcqZlhwRzrK0w2VUlxWA98xnvb/jszw4ZSkJ6ADpM6Q== +markdown-to-jsx@7.3.2: + version "7.3.2" + resolved "https://registry.yarnpkg.com/markdown-to-jsx/-/markdown-to-jsx-7.3.2.tgz#f286b4d112dad3028acc1e77dfe1f653b347e131" + integrity sha512-B+28F5ucp83aQm+OxNrPkS8z0tMKaeHiy0lHJs3LqCyDQFtWuenaIrkaVTgAm1pf1AU85LXltva86hlaT17i8Q== markdown-to-jsx@^6.11.4: version "6.11.4" @@ -14280,6 +14994,11 @@ material-colors@^1.2.1: resolved "https://registry.yarnpkg.com/material-colors/-/material-colors-1.2.6.tgz#6d1958871126992ceecc72f4bcc4d8f010865f46" integrity sha512-6qE4B9deFBIa9YSpOc9O0Sgc43zTeVYbgDT5veRKSlB2+ZuHNoVVxA1L/ckMUayV9Ay9y7Z/SZCLcGteW9i7bg== +math-expression-evaluator@^1.2.14: + version "1.4.0" + resolved "https://registry.yarnpkg.com/math-expression-evaluator/-/math-expression-evaluator-1.4.0.tgz#3d66031117fbb7b9715ea6c9c68c2cd2eebd37e2" + integrity sha512-4vRUvPyxdO8cWULGTh9dZWL2tZK6LDBvj+OGHBER7poH9Qdt7kXEoj20wiz4lQUbUXQZFjPbe5mVDo9nutizCw== + md5.js@^1.3.4: version "1.3.5" resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" @@ -14298,197 +15017,32 @@ md5@~2.2.1: crypt "~0.0.1" is-buffer "~1.1.1" -mdast-squeeze-paragraphs@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/mdast-squeeze-paragraphs/-/mdast-squeeze-paragraphs-4.0.0.tgz#7c4c114679c3bee27ef10b58e2e015be79f1ef97" - integrity sha512-zxdPn69hkQ1rm4J+2Cs2j6wDEv7O17TfXTJ33tl/+JPIoEmtV9t2ZzBM5LPHE8QlHsmVD8t3vPKCyY3oH+H8MQ== - dependencies: - unist-util-remove "^2.0.0" - -mdast-util-definitions@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/mdast-util-definitions/-/mdast-util-definitions-4.0.0.tgz#c5c1a84db799173b4dcf7643cda999e440c24db2" - integrity sha512-k8AJ6aNnUkB7IE+5azR9h81O5EQ/cTDXtWdMq9Kk5KcEW/8ritU5CeLg/9HhOC++nALHBlaogJ5jz0Ybk3kPMQ== - dependencies: - unist-util-visit "^2.0.0" - -mdast-util-definitions@^5.0.0: - version "5.1.2" - resolved "https://registry.yarnpkg.com/mdast-util-definitions/-/mdast-util-definitions-5.1.2.tgz#9910abb60ac5d7115d6819b57ae0bcef07a3f7a7" - integrity sha512-8SVPMuHqlPME/z3gqVwWY4zVXn8lqKv/pAhC57FuJ40ImXyBpmO5ukh98zB2v7Blql2FiHjHv9LVztSIqjY+MA== - dependencies: - "@types/mdast" "^3.0.0" - "@types/unist" "^2.0.0" - unist-util-visit "^4.0.0" - -mdast-util-from-markdown@^1.0.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/mdast-util-from-markdown/-/mdast-util-from-markdown-1.3.0.tgz#0214124154f26154a2b3f9d401155509be45e894" - integrity sha512-HN3W1gRIuN/ZW295c7zi7g9lVBllMgZE40RxCX37wrTPWXCWtpvOZdfnuK+1WNpvZje6XuJeI3Wnb4TJEUem+g== - dependencies: - "@types/mdast" "^3.0.0" - "@types/unist" "^2.0.0" - decode-named-character-reference "^1.0.0" - mdast-util-to-string "^3.1.0" - micromark "^3.0.0" - micromark-util-decode-numeric-character-reference "^1.0.0" - micromark-util-decode-string "^1.0.0" - micromark-util-normalize-identifier "^1.0.0" - micromark-util-symbol "^1.0.0" - micromark-util-types "^1.0.0" - unist-util-stringify-position "^3.0.0" - uvu "^0.5.0" - -mdast-util-frontmatter@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/mdast-util-frontmatter/-/mdast-util-frontmatter-1.0.1.tgz#79c46d7414eb9d3acabe801ee4a70a70b75e5af1" - integrity sha512-JjA2OjxRqAa8wEG8hloD0uTU0kdn8kbtOWpPP94NBkfAlbxn4S8gCGf/9DwFtEeGPXrDcNXdiDjVaRdUFqYokw== - dependencies: - "@types/mdast" "^3.0.0" - mdast-util-to-markdown "^1.3.0" - micromark-extension-frontmatter "^1.0.0" - -mdast-util-mdx-expression@^1.0.0: - version "1.3.2" - resolved "https://registry.yarnpkg.com/mdast-util-mdx-expression/-/mdast-util-mdx-expression-1.3.2.tgz#d027789e67524d541d6de543f36d51ae2586f220" - integrity sha512-xIPmR5ReJDu/DHH1OoIT1HkuybIfRGYRywC+gJtI7qHjCJp/M9jrmBEJW22O8lskDWm562BX2W8TiAwRTb0rKA== - dependencies: - "@types/estree-jsx" "^1.0.0" - "@types/hast" "^2.0.0" - "@types/mdast" "^3.0.0" - mdast-util-from-markdown "^1.0.0" - mdast-util-to-markdown "^1.0.0" - -mdast-util-mdx-jsx@^1.0.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-1.2.0.tgz#c0f5140e021fd134fa90272eb8bbddb39f8db399" - integrity sha512-5+ot/kfxYd3ChgEMwsMUO71oAfYjyRI3pADEK4I7xTmWLGQ8Y7ghm1CG36zUoUvDPxMlIYwQV/9DYHAUWdG4dA== - dependencies: - "@types/estree-jsx" "^0.0.1" - "@types/mdast" "^3.0.0" - mdast-util-to-markdown "^1.0.0" - parse-entities "^4.0.0" - stringify-entities "^4.0.0" - unist-util-remove-position "^4.0.0" - unist-util-stringify-position "^3.0.0" - vfile-message "^3.0.0" - -mdast-util-mdx@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/mdast-util-mdx/-/mdast-util-mdx-1.1.0.tgz#c98612804719309aea97e3da068658392e126488" - integrity sha512-leKb9uG7laXdyFlTleYV4ZEaCpsxeU1LlkkR/xp35pgKrfV1Y0fNCuOw9vaRc2a9YDpH22wd145Wt7UY5yzeZw== - dependencies: - mdast-util-mdx-expression "^1.0.0" - mdast-util-mdx-jsx "^1.0.0" - mdast-util-mdxjs-esm "^1.0.0" - -mdast-util-mdxjs-esm@^1.0.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-1.3.1.tgz#645d02cd607a227b49721d146fd81796b2e2d15b" - integrity sha512-SXqglS0HrEvSdUEfoXFtcg7DRl7S2cwOXc7jkuusG472Mmjag34DUDeOJUZtl+BVnyeO1frIgVpHlNRWc2gk/w== - dependencies: - "@types/estree-jsx" "^1.0.0" - "@types/hast" "^2.0.0" - "@types/mdast" "^3.0.0" - mdast-util-from-markdown "^1.0.0" - mdast-util-to-markdown "^1.0.0" - -mdast-util-phrasing@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/mdast-util-phrasing/-/mdast-util-phrasing-3.0.1.tgz#c7c21d0d435d7fb90956038f02e8702781f95463" - integrity sha512-WmI1gTXUBJo4/ZmSk79Wcb2HcjPJBzM1nlI/OUWA8yk2X9ik3ffNbBGsU+09BFmXaL1IBb9fiuvq6/KMiNycSg== - dependencies: - "@types/mdast" "^3.0.0" - unist-util-is "^5.0.0" - -mdast-util-to-hast@10.0.1: - version "10.0.1" - resolved "https://registry.yarnpkg.com/mdast-util-to-hast/-/mdast-util-to-hast-10.0.1.tgz#0cfc82089494c52d46eb0e3edb7a4eb2aea021eb" - integrity sha512-BW3LM9SEMnjf4HXXVApZMt8gLQWVNXc3jryK0nJu/rOXPOnlkUjmdkDlmxMirpbU9ILncGFIwLH/ubnWBbcdgA== - dependencies: - "@types/mdast" "^3.0.0" - "@types/unist" "^2.0.0" - mdast-util-definitions "^4.0.0" - mdurl "^1.0.0" - unist-builder "^2.0.0" - unist-util-generated "^1.0.0" - unist-util-position "^3.0.0" - unist-util-visit "^2.0.0" - -mdast-util-to-hast@^11.0.0: - version "11.3.0" - resolved "https://registry.yarnpkg.com/mdast-util-to-hast/-/mdast-util-to-hast-11.3.0.tgz#ea9220617a710e80aa5cc3ac7cc9d4bb0440ae7a" - integrity sha512-4o3Cli3hXPmm1LhB+6rqhfsIUBjnKFlIUZvudaermXB+4/KONdd/W4saWWkC+LBLbPMqhFSSTSRgafHsT5fVJw== - dependencies: - "@types/hast" "^2.0.0" - "@types/mdast" "^3.0.0" - "@types/mdurl" "^1.0.0" - mdast-util-definitions "^5.0.0" - mdurl "^1.0.0" - unist-builder "^3.0.0" - unist-util-generated "^2.0.0" - unist-util-position "^4.0.0" - unist-util-visit "^4.0.0" - -mdast-util-to-markdown@^1.0.0, mdast-util-to-markdown@^1.3.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/mdast-util-to-markdown/-/mdast-util-to-markdown-1.5.0.tgz#c13343cb3fc98621911d33b5cd42e7d0731171c6" - integrity sha512-bbv7TPv/WC49thZPg3jXuqzuvI45IL2EVAr/KxF0BSdHsU0ceFHOmwQn6evxAh1GaoK/6GQ1wp4R4oW2+LFL/A== - dependencies: - "@types/mdast" "^3.0.0" - "@types/unist" "^2.0.0" - longest-streak "^3.0.0" - mdast-util-phrasing "^3.0.0" - mdast-util-to-string "^3.0.0" - micromark-util-decode-string "^1.0.0" - unist-util-visit "^4.0.0" - zwitch "^2.0.0" - -mdast-util-to-string@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/mdast-util-to-string/-/mdast-util-to-string-1.1.0.tgz#27055500103f51637bd07d01da01eb1967a43527" - integrity sha512-jVU0Nr2B9X3MU4tSK7JP1CMkSvOj7X5l/GboG1tKRw52lLF1x2Ju92Ms9tNetCcbfX3hzlM73zYo2NKkWSfF/A== - -mdast-util-to-string@^3.0.0, mdast-util-to-string@^3.1.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/mdast-util-to-string/-/mdast-util-to-string-3.2.0.tgz#66f7bb6324756741c5f47a53557f0cbf16b6f789" - integrity sha512-V4Zn/ncyN1QNSqSBxTrMOLpjr+IKdHl2v3KVLoWmDPscP4r9GcCi71gjgvUV1SFSKh92AjAG4peFuBl2/YgCJg== - dependencies: - "@types/mdast" "^3.0.0" - mdn-data@2.0.14: version "2.0.14" resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.14.tgz#7113fc4281917d63ce29b43446f701e68c25ba50" integrity sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow== -mdurl@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e" - integrity sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g== +mdn-data@2.0.28: + version "2.0.28" + resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.28.tgz#5ec48e7bef120654539069e1ae4ddc81ca490eba" + integrity sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g== -media-query-parser@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/media-query-parser/-/media-query-parser-2.0.2.tgz#ff79e56cee92615a304a1c2fa4f2bd056c0a1d29" - integrity sha512-1N4qp+jE0pL5Xv4uEcwVUhIkwdUO3S/9gML90nqKA7v7FcOS5vUtatfzok9S9U1EJU8dHWlcv95WLnKmmxZI9w== - dependencies: - "@babel/runtime" "^7.12.5" +mdn-data@2.0.30: + version "2.0.30" + resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.30.tgz#ce4df6f80af6cfbe218ecd5c552ba13c4dfa08cc" + integrity sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA== media-typer@0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== -memfs@^3.1.2: - version "3.4.13" - resolved "https://registry.yarnpkg.com/memfs/-/memfs-3.4.13.tgz#248a8bd239b3c240175cd5ec548de5227fc4f345" - integrity sha512-omTM41g3Skpvx5dSYeZIbXKcXoAVc/AoMNwn9TKx++L/gaen/+4TTttmu8ZSch5vfVJ8uJvGbroTsIlslRg6lg== +memfs@^3.4.1, memfs@^3.4.12: + version "3.6.0" + resolved "https://registry.yarnpkg.com/memfs/-/memfs-3.6.0.tgz#d7a2110f86f79dd950a8b6df6d57bc984aa185f6" + integrity sha512-EGowvkkgbMcIChjMTMkESFDbZeSh8xZ7kNSF0hAiAN4Jh6jgHCRS0Ga/+C8y6Au+oqpezRHCfPsmJ2+DwAgiwQ== dependencies: - fs-monkey "^1.0.3" - -"memoize-one@>=3.1.1 <6": - version "5.2.1" - resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-5.2.1.tgz#8337aa3c4335581839ec01c3d594090cebe8f00e" - integrity sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q== + fs-monkey "^1.0.4" memoizerific@^1.11.3: version "1.11.3" @@ -14497,42 +15051,15 @@ memoizerific@^1.11.3: dependencies: map-or-similar "^1.5.0" -memory-fs@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552" - integrity sha512-cda4JKCxReDXFXRqOHPQscuIYg1PvxbE2S2GP45rnwfEK+vZaXC8C1OFvdHIbgw0DLzowXGVoxLaAmlgRy14GQ== - dependencies: - errno "^0.1.3" - readable-stream "^2.0.1" - -memory-fs@^0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.5.0.tgz#324c01288b88652966d161db77838720845a8e3c" - integrity sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA== - dependencies: - errno "^0.1.3" - readable-stream "^2.0.1" - memorystream@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/memorystream/-/memorystream-0.3.1.tgz#86d7090b30ce455d63fbae12dda51a47ddcaf9b2" integrity sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw== -meow@^3.1.0: - version "3.7.0" - resolved "https://registry.yarnpkg.com/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb" - integrity sha512-TNdwZs0skRlpPpCUK25StC4VH+tP5GgeY1HQOOGP+lQ2xtdkN2VtT/5tiX9k3IWpkBPV9b3LsAWXn4GGi/PrSA== - dependencies: - camelcase-keys "^2.0.0" - decamelize "^1.1.2" - loud-rejection "^1.0.0" - map-obj "^1.0.1" - minimist "^1.1.3" - normalize-package-data "^2.3.4" - object-assign "^4.0.1" - read-pkg-up "^1.0.1" - redent "^1.0.0" - trim-newlines "^1.0.0" +meow@^12.0.1: + version "12.1.1" + resolved "https://registry.yarnpkg.com/meow/-/meow-12.1.1.tgz#e558dddbab12477b69b2e9a2728c327f191bace6" + integrity sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw== meow@^8.0.0: version "8.1.2" @@ -14551,17 +15078,17 @@ meow@^8.0.0: type-fest "^0.18.0" yargs-parser "^20.2.3" -merge-descriptors@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" - integrity sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w== +merge-descriptors@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.3.tgz#d80319a65f3c7935351e5cfdac8f9318504dbed5" + integrity sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ== merge-stream@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== -merge2@^1.2.3, merge2@^1.3.0, merge2@^1.4.1: +merge2@^1.3.0, merge2@^1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== @@ -14571,307 +15098,15 @@ methods@~1.1.2: resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== -microevent.ts@~0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/microevent.ts/-/microevent.ts-0.1.1.tgz#70b09b83f43df5172d0205a63025bce0f7357fa0" - integrity sha512-jo1OfR4TaEwd5HOrt5+tAZ9mqT4jmpNAusXtyfNzqVm9uiSYFZlKM1wYL4oU7azZW/PxQW53wM0S6OR1JHNa2g== - -micromark-core-commonmark@^1.0.0, micromark-core-commonmark@^1.0.1: - version "1.0.6" - resolved "https://registry.yarnpkg.com/micromark-core-commonmark/-/micromark-core-commonmark-1.0.6.tgz#edff4c72e5993d93724a3c206970f5a15b0585ad" - integrity sha512-K+PkJTxqjFfSNkfAhp4GB+cZPfQd6dxtTXnf+RjZOV7T4EEXnvgzOcnp+eSTmpGk9d1S9sL6/lqrgSNn/s0HZA== - dependencies: - decode-named-character-reference "^1.0.0" - micromark-factory-destination "^1.0.0" - micromark-factory-label "^1.0.0" - micromark-factory-space "^1.0.0" - micromark-factory-title "^1.0.0" - micromark-factory-whitespace "^1.0.0" - micromark-util-character "^1.0.0" - micromark-util-chunked "^1.0.0" - micromark-util-classify-character "^1.0.0" - micromark-util-html-tag-name "^1.0.0" - micromark-util-normalize-identifier "^1.0.0" - micromark-util-resolve-all "^1.0.0" - micromark-util-subtokenize "^1.0.0" - micromark-util-symbol "^1.0.0" - micromark-util-types "^1.0.1" - uvu "^0.5.0" - -micromark-extension-frontmatter@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/micromark-extension-frontmatter/-/micromark-extension-frontmatter-1.1.0.tgz#f8da3c2d880266c809dcf07eb0606448b2f837c5" - integrity sha512-0nLelmvXR5aZ+F2IL6/Ed4cDnHLpL/VD/EELKuclsTWHrLI8UgxGHEmeoumeX2FXiM6z2WrBIOEcbKUZR8RYNg== - dependencies: - fault "^2.0.0" - micromark-util-character "^1.0.0" - micromark-util-symbol "^1.0.0" - micromark-util-types "^1.0.0" - -micromark-extension-mdx-expression@^1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/micromark-extension-mdx-expression/-/micromark-extension-mdx-expression-1.0.4.tgz#33fe2c6ee214738255de175a084281c11894ddda" - integrity sha512-TCgLxqW6ReQ3AJgtj1P0P+8ZThBTloLbeb7jNaqr6mCOLDpxUiBFE/9STgooMZttEwOQu5iEcCCa3ZSDhY9FGw== - dependencies: - micromark-factory-mdx-expression "^1.0.0" - micromark-factory-space "^1.0.0" - micromark-util-character "^1.0.0" - micromark-util-events-to-acorn "^1.0.0" - micromark-util-symbol "^1.0.0" - micromark-util-types "^1.0.0" - uvu "^0.5.0" - -micromark-extension-mdx-jsx@^1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/micromark-extension-mdx-jsx/-/micromark-extension-mdx-jsx-1.0.3.tgz#9f196be5f65eb09d2a49b237a7b3398bba2999be" - integrity sha512-VfA369RdqUISF0qGgv2FfV7gGjHDfn9+Qfiv5hEwpyr1xscRj/CiVRkU7rywGFCO7JwJ5L0e7CJz60lY52+qOA== - dependencies: - "@types/acorn" "^4.0.0" - estree-util-is-identifier-name "^2.0.0" - micromark-factory-mdx-expression "^1.0.0" - micromark-factory-space "^1.0.0" - micromark-util-character "^1.0.0" - micromark-util-symbol "^1.0.0" - micromark-util-types "^1.0.0" - uvu "^0.5.0" - vfile-message "^3.0.0" - -micromark-extension-mdx-md@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/micromark-extension-mdx-md/-/micromark-extension-mdx-md-1.0.0.tgz#382f5df9ee3706dd120b51782a211f31f4760d22" - integrity sha512-xaRAMoSkKdqZXDAoSgp20Azm0aRQKGOl0RrS81yGu8Hr/JhMsBmfs4wR7m9kgVUIO36cMUQjNyiyDKPrsv8gOw== - dependencies: - micromark-util-types "^1.0.0" - -micromark-extension-mdxjs-esm@^1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/micromark-extension-mdxjs-esm/-/micromark-extension-mdxjs-esm-1.0.3.tgz#630d9dc9db2c2fd470cac8c1e7a824851267404d" - integrity sha512-2N13ol4KMoxb85rdDwTAC6uzs8lMX0zeqpcyx7FhS7PxXomOnLactu8WI8iBNXW8AVyea3KIJd/1CKnUmwrK9A== - dependencies: - micromark-core-commonmark "^1.0.0" - micromark-util-character "^1.0.0" - micromark-util-events-to-acorn "^1.0.0" - micromark-util-symbol "^1.0.0" - micromark-util-types "^1.0.0" - unist-util-position-from-estree "^1.1.0" - uvu "^0.5.0" - vfile-message "^3.0.0" - -micromark-extension-mdxjs@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/micromark-extension-mdxjs/-/micromark-extension-mdxjs-1.0.0.tgz#772644e12fc8299a33e50f59c5aa15727f6689dd" - integrity sha512-TZZRZgeHvtgm+IhtgC2+uDMR7h8eTKF0QUX9YsgoL9+bADBpBY6SiLvWqnBlLbCEevITmTqmEuY3FoxMKVs1rQ== - dependencies: - acorn "^8.0.0" - acorn-jsx "^5.0.0" - micromark-extension-mdx-expression "^1.0.0" - micromark-extension-mdx-jsx "^1.0.0" - micromark-extension-mdx-md "^1.0.0" - micromark-extension-mdxjs-esm "^1.0.0" - micromark-util-combine-extensions "^1.0.0" - micromark-util-types "^1.0.0" - -micromark-factory-destination@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/micromark-factory-destination/-/micromark-factory-destination-1.0.0.tgz#fef1cb59ad4997c496f887b6977aa3034a5a277e" - integrity sha512-eUBA7Rs1/xtTVun9TmV3gjfPz2wEwgK5R5xcbIM5ZYAtvGF6JkyaDsj0agx8urXnO31tEO6Ug83iVH3tdedLnw== - dependencies: - micromark-util-character "^1.0.0" - micromark-util-symbol "^1.0.0" - micromark-util-types "^1.0.0" - -micromark-factory-label@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/micromark-factory-label/-/micromark-factory-label-1.0.2.tgz#6be2551fa8d13542fcbbac478258fb7a20047137" - integrity sha512-CTIwxlOnU7dEshXDQ+dsr2n+yxpP0+fn271pu0bwDIS8uqfFcumXpj5mLn3hSC8iw2MUr6Gx8EcKng1dD7i6hg== - dependencies: - micromark-util-character "^1.0.0" - micromark-util-symbol "^1.0.0" - micromark-util-types "^1.0.0" - uvu "^0.5.0" - -micromark-factory-mdx-expression@^1.0.0: - version "1.0.7" - resolved "https://registry.yarnpkg.com/micromark-factory-mdx-expression/-/micromark-factory-mdx-expression-1.0.7.tgz#e38298dc1f7eaf6ba1d9f210531ceae17155c00f" - integrity sha512-QAdFbkQagTZ/eKb8zDGqmjvgevgJH3+aQpvvKrXWxNJp3o8/l2cAbbrBd0E04r0Gx6nssPpqWIjnbHFvZu5qsQ== - dependencies: - micromark-factory-space "^1.0.0" - micromark-util-character "^1.0.0" - micromark-util-events-to-acorn "^1.0.0" - micromark-util-symbol "^1.0.0" - micromark-util-types "^1.0.0" - unist-util-position-from-estree "^1.0.0" - uvu "^0.5.0" - vfile-message "^3.0.0" - -micromark-factory-space@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/micromark-factory-space/-/micromark-factory-space-1.0.0.tgz#cebff49968f2b9616c0fcb239e96685cb9497633" - integrity sha512-qUmqs4kj9a5yBnk3JMLyjtWYN6Mzfcx8uJfi5XAveBniDevmZasdGBba5b4QsvRcAkmvGo5ACmSUmyGiKTLZew== - dependencies: - micromark-util-character "^1.0.0" - micromark-util-types "^1.0.0" - -micromark-factory-title@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/micromark-factory-title/-/micromark-factory-title-1.0.2.tgz#7e09287c3748ff1693930f176e1c4a328382494f" - integrity sha512-zily+Nr4yFqgMGRKLpTVsNl5L4PMu485fGFDOQJQBl2NFpjGte1e86zC0da93wf97jrc4+2G2GQudFMHn3IX+A== - dependencies: - micromark-factory-space "^1.0.0" - micromark-util-character "^1.0.0" - micromark-util-symbol "^1.0.0" - micromark-util-types "^1.0.0" - uvu "^0.5.0" - -micromark-factory-whitespace@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/micromark-factory-whitespace/-/micromark-factory-whitespace-1.0.0.tgz#e991e043ad376c1ba52f4e49858ce0794678621c" - integrity sha512-Qx7uEyahU1lt1RnsECBiuEbfr9INjQTGa6Err+gF3g0Tx4YEviPbqqGKNv/NrBaE7dVHdn1bVZKM/n5I/Bak7A== - dependencies: - micromark-factory-space "^1.0.0" - micromark-util-character "^1.0.0" - micromark-util-symbol "^1.0.0" - micromark-util-types "^1.0.0" - -micromark-util-character@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/micromark-util-character/-/micromark-util-character-1.1.0.tgz#d97c54d5742a0d9611a68ca0cd4124331f264d86" - integrity sha512-agJ5B3unGNJ9rJvADMJ5ZiYjBRyDpzKAOk01Kpi1TKhlT1APx3XZk6eN7RtSz1erbWHC2L8T3xLZ81wdtGRZzg== - dependencies: - micromark-util-symbol "^1.0.0" - micromark-util-types "^1.0.0" - -micromark-util-chunked@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/micromark-util-chunked/-/micromark-util-chunked-1.0.0.tgz#5b40d83f3d53b84c4c6bce30ed4257e9a4c79d06" - integrity sha512-5e8xTis5tEZKgesfbQMKRCyzvffRRUX+lK/y+DvsMFdabAicPkkZV6gO+FEWi9RfuKKoxxPwNL+dFF0SMImc1g== - dependencies: - micromark-util-symbol "^1.0.0" - -micromark-util-classify-character@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/micromark-util-classify-character/-/micromark-util-classify-character-1.0.0.tgz#cbd7b447cb79ee6997dd274a46fc4eb806460a20" - integrity sha512-F8oW2KKrQRb3vS5ud5HIqBVkCqQi224Nm55o5wYLzY/9PwHGXC01tr3d7+TqHHz6zrKQ72Okwtvm/xQm6OVNZA== - dependencies: - micromark-util-character "^1.0.0" - micromark-util-symbol "^1.0.0" - micromark-util-types "^1.0.0" - -micromark-util-combine-extensions@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/micromark-util-combine-extensions/-/micromark-util-combine-extensions-1.0.0.tgz#91418e1e74fb893e3628b8d496085639124ff3d5" - integrity sha512-J8H058vFBdo/6+AsjHp2NF7AJ02SZtWaVUjsayNFeAiydTxUwViQPxN0Hf8dp4FmCQi0UUFovFsEyRSUmFH3MA== - dependencies: - micromark-util-chunked "^1.0.0" - micromark-util-types "^1.0.0" - -micromark-util-decode-numeric-character-reference@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-1.0.0.tgz#dcc85f13b5bd93ff8d2868c3dba28039d490b946" - integrity sha512-OzO9AI5VUtrTD7KSdagf4MWgHMtET17Ua1fIpXTpuhclCqD8egFWo85GxSGvxgkGS74bEahvtM0WP0HjvV0e4w== - dependencies: - micromark-util-symbol "^1.0.0" - -micromark-util-decode-string@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/micromark-util-decode-string/-/micromark-util-decode-string-1.0.2.tgz#942252ab7a76dec2dbf089cc32505ee2bc3acf02" - integrity sha512-DLT5Ho02qr6QWVNYbRZ3RYOSSWWFuH3tJexd3dgN1odEuPNxCngTCXJum7+ViRAd9BbdxCvMToPOD/IvVhzG6Q== - dependencies: - decode-named-character-reference "^1.0.0" - micromark-util-character "^1.0.0" - micromark-util-decode-numeric-character-reference "^1.0.0" - micromark-util-symbol "^1.0.0" - -micromark-util-encode@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/micromark-util-encode/-/micromark-util-encode-1.0.1.tgz#2c1c22d3800870ad770ece5686ebca5920353383" - integrity sha512-U2s5YdnAYexjKDel31SVMPbfi+eF8y1U4pfiRW/Y8EFVCy/vgxk/2wWTxzcqE71LHtCuCzlBDRU2a5CQ5j+mQA== - -micromark-util-events-to-acorn@^1.0.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/micromark-util-events-to-acorn/-/micromark-util-events-to-acorn-1.2.1.tgz#d5b9dfbc589ece7917de24de0a57b909c0d36583" - integrity sha512-mkg3BaWlw6ZTkQORrKVBW4o9ICXPxLtGz51vml5mQpKFdo9vqIX68CAx5JhTOdjQyAHH7JFmm4rh8toSPQZUmg== - dependencies: - "@types/acorn" "^4.0.0" - "@types/estree" "^1.0.0" - estree-util-visit "^1.0.0" - micromark-util-types "^1.0.0" - uvu "^0.5.0" - vfile-location "^4.0.0" - vfile-message "^3.0.0" - -micromark-util-html-tag-name@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/micromark-util-html-tag-name/-/micromark-util-html-tag-name-1.1.0.tgz#eb227118befd51f48858e879b7a419fc0df20497" - integrity sha512-BKlClMmYROy9UiV03SwNmckkjn8QHVaWkqoAqzivabvdGcwNGMMMH/5szAnywmsTBUzDsU57/mFi0sp4BQO6dA== - -micromark-util-normalize-identifier@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-1.0.0.tgz#4a3539cb8db954bbec5203952bfe8cedadae7828" - integrity sha512-yg+zrL14bBTFrQ7n35CmByWUTFsgst5JhA4gJYoty4Dqzj4Z4Fr/DHekSS5aLfH9bdlfnSvKAWsAgJhIbogyBg== - dependencies: - micromark-util-symbol "^1.0.0" - -micromark-util-resolve-all@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/micromark-util-resolve-all/-/micromark-util-resolve-all-1.0.0.tgz#a7c363f49a0162e931960c44f3127ab58f031d88" - integrity sha512-CB/AGk98u50k42kvgaMM94wzBqozSzDDaonKU7P7jwQIuH2RU0TeBqGYJz2WY1UdihhjweivStrJ2JdkdEmcfw== - dependencies: - micromark-util-types "^1.0.0" - -micromark-util-sanitize-uri@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-1.1.0.tgz#f12e07a85106b902645e0364feb07cf253a85aee" - integrity sha512-RoxtuSCX6sUNtxhbmsEFQfWzs8VN7cTctmBPvYivo98xb/kDEoTCtJQX5wyzIYEmk/lvNFTat4hL8oW0KndFpg== - dependencies: - micromark-util-character "^1.0.0" - micromark-util-encode "^1.0.0" - micromark-util-symbol "^1.0.0" - -micromark-util-subtokenize@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/micromark-util-subtokenize/-/micromark-util-subtokenize-1.0.2.tgz#ff6f1af6ac836f8bfdbf9b02f40431760ad89105" - integrity sha512-d90uqCnXp/cy4G881Ub4psE57Sf8YD0pim9QdjCRNjfas2M1u6Lbt+XZK9gnHL2XFhnozZiEdCa9CNfXSfQ6xA== +micromatch@4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.2.tgz#4fcb0999bf9fbc2fcbdd212f6d629b9a56c39259" + integrity sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q== dependencies: - micromark-util-chunked "^1.0.0" - micromark-util-symbol "^1.0.0" - micromark-util-types "^1.0.0" - uvu "^0.5.0" - -micromark-util-symbol@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/micromark-util-symbol/-/micromark-util-symbol-1.0.1.tgz#b90344db62042ce454f351cf0bebcc0a6da4920e" - integrity sha512-oKDEMK2u5qqAptasDAwWDXq0tG9AssVwAx3E9bBF3t/shRIGsWIRG+cGafs2p/SnDSOecnt6hZPCE2o6lHfFmQ== + braces "^3.0.1" + picomatch "^2.0.5" -micromark-util-types@^1.0.0, micromark-util-types@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/micromark-util-types/-/micromark-util-types-1.0.2.tgz#f4220fdb319205812f99c40f8c87a9be83eded20" - integrity sha512-DCfg/T8fcrhrRKTPjRrw/5LLvdGV7BHySf/1LOZx7TzWZdYRjogNtyNq885z3nNallwr3QUKARjqvHqX1/7t+w== - -micromark@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/micromark/-/micromark-3.1.0.tgz#eeba0fe0ac1c9aaef675157b52c166f125e89f62" - integrity sha512-6Mj0yHLdUZjHnOPgr5xfWIMqMWS12zDN6iws9SLuSz76W8jTtAv24MN4/CL7gJrl5vtxGInkkqDv/JIoRsQOvA== - dependencies: - "@types/debug" "^4.0.0" - debug "^4.0.0" - decode-named-character-reference "^1.0.0" - micromark-core-commonmark "^1.0.1" - micromark-factory-space "^1.0.0" - micromark-util-character "^1.0.0" - micromark-util-chunked "^1.0.0" - micromark-util-combine-extensions "^1.0.0" - micromark-util-decode-numeric-character-reference "^1.0.0" - micromark-util-encode "^1.0.0" - micromark-util-normalize-identifier "^1.0.0" - micromark-util-resolve-all "^1.0.0" - micromark-util-sanitize-uri "^1.0.0" - micromark-util-subtokenize "^1.0.0" - micromark-util-symbol "^1.0.0" - micromark-util-types "^1.0.1" - uvu "^0.5.0" - -micromatch@4.x, micromatch@^4.0.2, micromatch@^4.0.4, micromatch@^4.0.5: +micromatch@4.0.5, micromatch@^4.0.2, micromatch@^4.0.4, micromatch@^4.0.5: version "4.0.5" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== @@ -14879,25 +15114,6 @@ micromatch@4.x, micromatch@^4.0.2, micromatch@^4.0.4, micromatch@^4.0.5: braces "^3.0.2" picomatch "^2.3.1" -micromatch@^3.1.10, micromatch@^3.1.4: - version "3.1.10" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" - integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== - dependencies: - arr-diff "^4.0.0" - array-unique "^0.3.2" - braces "^2.3.1" - define-property "^2.0.2" - extend-shallow "^3.0.2" - extglob "^2.0.4" - fragment-cache "^0.2.1" - kind-of "^6.0.2" - nanomatch "^1.2.9" - object.pick "^1.3.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.2" - miller-rabin@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d" @@ -14911,7 +15127,7 @@ mime-db@1.52.0, "mime-db@>= 1.43.0 < 2": resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== -mime-types@^2.1.12, mime-types@^2.1.27, mime-types@~2.1.19, mime-types@~2.1.24, mime-types@~2.1.34: +mime-types@^2.1.12, mime-types@^2.1.27, mime-types@^2.1.31, mime-types@~2.1.24, mime-types@~2.1.34: version "2.1.35" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== @@ -14923,15 +15139,10 @@ mime@1.6.0: resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== -mime@^2.4.4: - version "2.6.0" - resolved "https://registry.yarnpkg.com/mime/-/mime-2.6.0.tgz#a2a682a95cd4d0cb1d6257e28f83da7e35800367" - integrity sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg== - -mimic-fn@^1.0.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" - integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ== +mime@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-3.0.0.tgz#b374550dca3a0c18443b0c950a6a58f1931cf7a7" + integrity sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A== mimic-fn@^2.1.0: version "2.1.0" @@ -14943,21 +15154,6 @@ mimic-fn@^4.0.0: resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-4.0.0.tgz#60a90550d5cb0b239cca65d893b1a53b29871ecc" integrity sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw== -mimic-response@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" - integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== - -mimic-response@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-2.1.0.tgz#d13763d35f613d09ec37ebb30bac0469c0ee8f43" - integrity sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA== - -mimic-response@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9" - integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ== - min-document@^2.19.0: version "2.19.0" resolved "https://registry.yarnpkg.com/min-document/-/min-document-2.19.0.tgz#7bd282e3f5842ed295bb748cdd9f1ffa2c824685" @@ -14965,7 +15161,7 @@ min-document@^2.19.0: dependencies: dom-walk "^0.1.0" -min-indent@^1.0.0: +min-indent@^1.0.0, min-indent@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/min-indent/-/min-indent-1.0.1.tgz#a63f681673b30571fbe8bc25686ae746eefa9869" integrity sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg== @@ -14987,7 +15183,7 @@ minimatch@3.0.5: dependencies: brace-expansion "^1.1.7" -minimatch@^3.0.2, minimatch@^3.0.4, minimatch@^3.1.1, minimatch@^3.1.2: +minimatch@^3.0.2, minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== @@ -15001,6 +15197,20 @@ minimatch@^5.0.1: dependencies: brace-expansion "^2.0.1" +minimatch@^9.0.1: + version "9.0.3" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.3.tgz#a6e00c3de44c3a542bfaae70abfc22420a6da825" + integrity sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg== + dependencies: + brace-expansion "^2.0.1" + +minimatch@^9.0.4: + version "9.0.5" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.5.tgz#d74f9dd6b57d83d8e98cfb82133b03978bc929e5" + integrity sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow== + dependencies: + brace-expansion "^2.0.1" + minimist-options@4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/minimist-options/-/minimist-options-4.1.0.tgz#c0655713c53a8a2ebd77ffa247d342c40f010619" @@ -15010,43 +15220,32 @@ minimist-options@4.1.0: is-plain-obj "^1.1.0" kind-of "^6.0.3" -minimist@^1.1.1, minimist@^1.1.3, minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.5, minimist@^1.2.6: +minimist@^1.2.0, minimist@^1.2.5, minimist@^1.2.6: version "1.2.8" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== -minipass-collect@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/minipass-collect/-/minipass-collect-1.0.2.tgz#22b813bf745dc6edba2576b940022ad6edc8c617" - integrity sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA== - dependencies: - minipass "^3.0.0" - -minipass-flush@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/minipass-flush/-/minipass-flush-1.0.5.tgz#82e7135d7e89a50ffe64610a787953c4c4cbb373" - integrity sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw== - dependencies: - minipass "^3.0.0" - -minipass-pipeline@^1.2.2: - version "1.2.4" - resolved "https://registry.yarnpkg.com/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz#68472f79711c084657c067c5c6ad93cddea8214c" - integrity sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A== - dependencies: - minipass "^3.0.0" - -minipass@^3.0.0, minipass@^3.1.1: +minipass@^3.0.0: version "3.3.6" resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.3.6.tgz#7bba384db3a1520d18c9c0e5251c3444e95dd94a" integrity sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw== dependencies: yallist "^4.0.0" -minipass@^4.0.0: - version "4.2.5" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-4.2.5.tgz#9e0e5256f1e3513f8c34691dd68549e85b2c8ceb" - integrity sha512-+yQl7SX3bIT83Lhb4BVorMAHVuqsskxRdlmO9kTpyukp8vsm2Sn/fUOV9xlnG8/a5JsypJzap21lz/y3FBMJ8Q== +minipass@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-5.0.0.tgz#3e9788ffb90b694a5d0ec94479a45b5d8738133d" + integrity sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ== + +"minipass@^5.0.0 || ^6.0.2 || ^7.0.0": + version "7.0.4" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.0.4.tgz#dbce03740f50a4786ba994c1fb908844d27b038c" + integrity sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ== + +minipass@^7.1.2: + version "7.1.2" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.1.2.tgz#93a9626ce5e5e66bd4db86849e7515e92340a707" + integrity sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw== minizlib@^2.1.1: version "2.1.2" @@ -15061,80 +15260,67 @@ miscreant@0.3.2: resolved "https://registry.yarnpkg.com/miscreant/-/miscreant-0.3.2.tgz#a91c046566cca70bd6b5e9fbdd3f67617fa85034" integrity sha512-fL9KxsQz9BJB2KGPMHFrReioywkiomBiuaLk6EuChijK0BsJsIKJXdVomR+/bPj5mvbFD6wM0CM3bZio9g7OHA== -mississippi@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/mississippi/-/mississippi-3.0.0.tgz#ea0a3291f97e0b5e8776b363d5f0a12d94c67022" - integrity sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA== - dependencies: - concat-stream "^1.5.0" - duplexify "^3.4.2" - end-of-stream "^1.1.0" - flush-write-stream "^1.0.0" - from2 "^2.1.0" - parallel-transform "^1.1.0" - pump "^3.0.0" - pumpify "^1.3.3" - stream-each "^1.1.0" - through2 "^2.0.0" - mitt@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/mitt/-/mitt-3.0.0.tgz#69ef9bd5c80ff6f57473e8d89326d01c414be0bd" - integrity sha512-7dX2/10ITVyqh4aOSVI9gdape+t9l2/8QxHrFmUXu4EEUpdlxl6RudZUPZoc+zuY2hk1j7XxVroIVIan/pD/SQ== + version "3.0.1" + resolved "https://registry.yarnpkg.com/mitt/-/mitt-3.0.1.tgz#ea36cf0cc30403601ae074c8f77b7092cdab36d1" + integrity sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw== -mixin-deep@^1.2.0: - version "1.3.2" - resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566" - integrity sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA== +mix-css-color@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/mix-css-color/-/mix-css-color-0.2.0.tgz#413a2346effcb36a815b1d09bcbac12bcf3aac63" + integrity sha512-mZugANySFPE21tjELbQddhC6HAZNzqp7gDxmW8fJFURSWtJ0nuXU26dyrb/1AR6ZYxdEAtW2bbWT9QnRtI6Jzg== dependencies: - for-in "^1.0.2" - is-extendable "^1.0.1" + parse-css-color "^0.1.2" + pure-color "^1.3.0" -mkdirp-classic@^0.5.2, mkdirp-classic@^0.5.3: +mkdirp-classic@^0.5.2: version "0.5.3" resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113" integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A== -mkdirp@0.x, mkdirp@^0.5.1, mkdirp@^0.5.3: - version "0.5.6" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6" - integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw== - dependencies: - minimist "^1.2.6" - -mkdirp@^1.0.3, mkdirp@^1.0.4: +mkdirp@^1.0.3: version "1.0.4" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== -mlly@^1.1.0, mlly@^1.1.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/mlly/-/mlly-1.2.0.tgz#f0f6c2fc8d2d12ea6907cd869066689b5031b613" - integrity sha512-+c7A3CV0KGdKcylsI6khWyts/CYrGTrRVo4R/I7u/cUsy0Conxa6LUhiEzVKIw14lc2L5aiO4+SeVe4TeGRKww== +mlly@^1.2.0, mlly@^1.4.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/mlly/-/mlly-1.4.2.tgz#7cf406aa319ff6563d25da6b36610a93f2a8007e" + integrity sha512-i/Ykufi2t1EZ6NaPLdfnZk2AX8cs0d+mTzVKuPfqPKPatxLApaBoxJQ9x1/uckXtrS/U5oisPMDkNs0yQTaBRg== dependencies: - acorn "^8.8.2" - pathe "^1.1.0" - pkg-types "^1.0.2" - ufo "^1.1.1" + acorn "^8.10.0" + pathe "^1.1.1" + pkg-types "^1.0.3" + ufo "^1.3.0" -modify-values@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/modify-values/-/modify-values-1.0.1.tgz#b3939fa605546474e3e3e3c63d64bd43b4ee6022" - integrity sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw== +mobile-detect@^1.4.5: + version "1.4.5" + resolved "https://registry.yarnpkg.com/mobile-detect/-/mobile-detect-1.4.5.tgz#da393c3c413ca1a9bcdd9ced653c38281c0fb6ad" + integrity sha512-yc0LhH6tItlvfLBugVUEtgawwFU2sIe+cSdmRJJCTMZ5GEJyLxNyC/NIOAOGk67Fa8GNpOttO3Xz/1bHpXFD/g== -move-concurrently@^1.0.1: +modify-values@^1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92" - integrity sha512-hdrFxZOycD/g6A6SoI2bB5NA/5NEqD0569+S47WZhPvm46sD50ZHdYaFmnua5lndde9rCHGjmfK7Z8BuCt/PcQ== - dependencies: - aproba "^1.1.1" - copy-concurrently "^1.0.0" - fs-write-stream-atomic "^1.0.8" - mkdirp "^0.5.1" - rimraf "^2.5.4" - run-queue "^1.0.3" + resolved "https://registry.yarnpkg.com/modify-values/-/modify-values-1.0.1.tgz#b3939fa605546474e3e3e3c63d64bd43b4ee6022" + integrity sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw== -mri@1.2.0, mri@^1.1.0: +moo@^0.5.1: + version "0.5.2" + resolved "https://registry.yarnpkg.com/moo/-/moo-0.5.2.tgz#f9fe82473bc7c184b0d32e2215d3f6e67278733c" + integrity sha512-iSAJLHYKnX41mKcJKjqvnAN9sf0LMDTXDEvFv+ffuRR9a1MIuXLjMNL6EsnDHSkKLTWNqQQ5uo61P4EbU4NU+Q== + +motion@10.16.2: + version "10.16.2" + resolved "https://registry.yarnpkg.com/motion/-/motion-10.16.2.tgz#7dc173c6ad62210a7e9916caeeaf22c51e598d21" + integrity sha512-p+PurYqfUdcJZvtnmAqu5fJgV2kR0uLFQuBKtLeFVTrYEVllI99tiOTSefVNYuip9ELTEkepIIDftNdze76NAQ== + 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" + +mri@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/mri/-/mri-1.2.0.tgz#6721480fec2a11a4889861115a48b6cbe7cc8f0b" integrity sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA== @@ -15144,11 +15330,6 @@ ms@2.0.0: resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== -ms@2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" - integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== - ms@2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" @@ -15159,7 +15340,7 @@ ms@2.1.3, ms@^2.0.0, ms@^2.1.1: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== -msgpackr-extract@^3.0.1: +msgpackr-extract@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/msgpackr-extract/-/msgpackr-extract-3.0.2.tgz#e05ec1bb4453ddf020551bcd5daaf0092a2c279d" integrity sha512-SdzXp4kD/Qf8agZ9+iTu6eql0m3kWm1A2y1hkpTeVNENutaB0BwHlSvAIaMxwntmRUAUjon2V4L8Z/njd0Ct8A== @@ -15173,97 +15354,63 @@ msgpackr-extract@^3.0.1: "@msgpackr-extract/msgpackr-extract-linux-x64" "3.0.2" "@msgpackr-extract/msgpackr-extract-win32-x64" "3.0.2" -msgpackr@^1.5.4: - version "1.8.5" - resolved "https://registry.yarnpkg.com/msgpackr/-/msgpackr-1.8.5.tgz#8cadfb935357680648f33699d0e833c9179dbfeb" - integrity sha512-mpPs3qqTug6ahbblkThoUY2DQdNXcm4IapwOS3Vm/87vmpzLVelvp9h3It1y9l1VPpiFLV11vfOXnmeEwiIXwg== +msgpackr@^1.9.5, msgpackr@^1.9.9: + version "1.10.1" + resolved "https://registry.yarnpkg.com/msgpackr/-/msgpackr-1.10.1.tgz#51953bb4ce4f3494f0c4af3f484f01cfbb306555" + integrity sha512-r5VRLv9qouXuLiIBrLpl2d5ZvPt8svdQTl5/vMvE4nzDMyEX4sgW5yWhuBBj5UmgwOTWj8CIdSXn5sAfsHAWIQ== optionalDependencies: - msgpackr-extract "^3.0.1" + msgpackr-extract "^3.0.2" + +multiformats@^9.4.2: + version "9.9.0" + resolved "https://registry.yarnpkg.com/multiformats/-/multiformats-9.9.0.tgz#c68354e7d21037a8f1f8833c8ccd68618e8f1d37" + integrity sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg== mute-stream@0.0.8: version "0.0.8" resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== -nan@^2.12.1, nan@^2.13.2: - version "2.17.0" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.17.0.tgz#c0150a2368a182f033e9aa5195ec76ea41a199cb" - integrity sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ== +nan@^2.13.2: + version "2.18.0" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.18.0.tgz#26a6faae7ffbeb293a39660e88a76b82e30b7554" + integrity sha512-W7tfG7vMOGtD30sHoZSSc/JVYiyDPEyQVso/Zz+/uQd0B0L46gtC+pHha5FFMRpil6fm/AoEcRWyOVi4+E/f8w== -nanoid@^3.3.1, nanoid@^3.3.4: - version "3.3.6" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.6.tgz#443380c856d6e9f9824267d960b4236ad583ea4c" - integrity sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA== - -nanomatch@^1.2.9: - version "1.2.13" - resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" - integrity sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA== - dependencies: - arr-diff "^4.0.0" - array-unique "^0.3.2" - define-property "^2.0.2" - extend-shallow "^3.0.2" - fragment-cache "^0.2.1" - is-windows "^1.0.2" - kind-of "^6.0.2" - object.pick "^1.3.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" +nanoid@^3.3.6, nanoid@^3.3.7: + version "3.3.8" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.8.tgz#b1be3030bee36aaff18bacb375e5cce521684baf" + integrity sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w== -nanospinner@^1.1.0: +napi-wasm@^1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/nanospinner/-/nanospinner-1.1.0.tgz#d17ff621cb1784b0a206b400da88a0ef6db39b97" - integrity sha512-yFvNYMig4AthKYfHFl1sLj7B2nkHL4lzdig4osvl9/LdGbXwrdFRoqBS98gsEsOakr0yH+r5NZ/1Y9gdVB8trA== - dependencies: - picocolors "^1.0.0" + resolved "https://registry.yarnpkg.com/napi-wasm/-/napi-wasm-1.1.0.tgz#bbe617823765ae9c1bc12ff5942370eae7b2ba4e" + integrity sha512-lHwIAJbmLSjF9VDRm9GoVOy9AGp3aIvkjv+Kvz9h16QR3uSVYH78PNQUnT2U4X53mhlnV2M7wrhibQ3GHicDmg== -napi-build-utils@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/napi-build-utils/-/napi-build-utils-1.0.2.tgz#b1fddc0b2c46e380a0b7a76f984dd47c41a13806" - integrity sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg== +natural-compare-lite@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz#17b09581988979fddafe0201e931ba933c96cbb4" + integrity sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g== natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== -ndjson@^1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/ndjson/-/ndjson-1.5.0.tgz#ae603b36b134bcec347b452422b0bf98d5832ec8" - integrity sha512-hUPLuaziboGjNF7wHngkgVc0FOclR8dDk/HfEvTtDr/iUrqBWiRcRSTK3/nLOqKH33th714BrMmTPtObI9gZxQ== - dependencies: - json-stringify-safe "^5.0.1" - minimist "^1.2.0" - split2 "^2.1.0" - through2 "^2.0.3" - negotiator@0.6.3: version "0.6.3" resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== -neo-async@^2.5.0, neo-async@^2.6.0, neo-async@^2.6.1, neo-async@^2.6.2: +neo-async@^2.5.0, neo-async@^2.6.2: version "2.6.2" resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== -nested-error-stacks@^2.0.0, nested-error-stacks@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/nested-error-stacks/-/nested-error-stacks-2.1.1.tgz#26c8a3cee6cc05fbcf1e333cd2fc3e003326c0b5" - integrity sha512-9iN1ka/9zmX1ZvLV9ewJYEk9h7RyRRtqdK0woXcqohu8EWIerfPUjYJPg0ULy0UqP7cslmdGc8xKDJcojlKiaw== - nested-object-assign@^1.0.3: version "1.0.4" resolved "https://registry.yarnpkg.com/nested-object-assign/-/nested-object-assign-1.0.4.tgz#c9db56078eb6043960fdb6ba918a5122a06ccac4" integrity sha512-FlZ7oN9ICt+fbcJ4ag2IsALIcalfE/E16ttdSA8peBiHJI+oEKdOcafqDnUbeUe5NwWGn/m9zZGO9qrAGzfesg== -netmask@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/netmask/-/netmask-2.0.2.tgz#8b01a07644065d536383835823bc52004ebac5e7" - integrity sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg== - nice-try@^1.0.4: version "1.0.5" resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" @@ -15277,41 +15424,52 @@ no-case@^3.0.4: lower-case "^2.0.2" tslib "^2.0.3" -node-abi@^2.21.0: - version "2.30.1" - resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-2.30.1.tgz#c437d4b1fe0e285aaf290d45b45d4d7afedac4cf" - integrity sha512-/2D0wOQPgaUWzVSVgRMx+trKJRC2UG4SUc4oCJoXx9Uxjtp0Vy3/kt7zcbxHF8+Z/pK3UloLWzBISg72brfy1w== - dependencies: - semver "^5.4.1" +node-abort-controller@^3.0.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/node-abort-controller/-/node-abort-controller-3.1.1.tgz#a94377e964a9a37ac3976d848cb5c765833b8548" + integrity sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ== -node-addon-api@^1.7.1: - version "1.7.2" - resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-1.7.2.tgz#3df30b95720b53c24e59948b49532b662444f54d" - integrity sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg== +node-addon-api@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-2.0.2.tgz#432cfa82962ce494b132e9d72a15b29f71ff5d32" + integrity sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA== -node-addon-api@^3.0.2, node-addon-api@^3.2.1: +node-addon-api@^3.0.0, node-addon-api@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-3.2.1.tgz#81325e0a2117789c0128dab65e7e38f07ceba161" integrity sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A== -node-addon-api@^4.2.0, node-addon-api@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-4.3.0.tgz#52a1a0b475193e0928e98e0426a0d1254782b77f" - integrity sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ== +node-addon-api@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-5.1.0.tgz#49da1ca055e109a23d537e9de43c09cca21eb762" + integrity sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA== + +node-addon-api@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-6.1.0.tgz#ac8470034e58e67d0c6f1204a18ae6995d9c0d76" + integrity sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA== + +node-addon-api@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-7.0.0.tgz#8136add2f510997b3b94814f4af1cce0b0e3962e" + integrity sha512-vgbBJTS4m5/KkE16t5Ly0WW9hz46swAstv0hYYwMtbG7AznRhNyfLRe8HZAiWIpcHzoO7HxhLuBQj9rJ/Ho0ZA== -node-dir@^0.1.10: +node-addon-api@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-8.0.0.tgz#5453b7ad59dd040d12e0f1a97a6fa1c765c5c9d2" + integrity sha512-ipO7rsHEBqa9STO5C5T10fj732ml+5kLN1cAG8/jdHd56ldQeGj3Q7+scUS+VHK/qy1zLEwC4wMK5+yM0btPvw== + +node-dir@^0.1.17: version "0.1.17" resolved "https://registry.yarnpkg.com/node-dir/-/node-dir-0.1.17.tgz#5f5665d93351335caabef8f1c554516cf5f1e4e5" integrity sha512-tmPX422rYgofd4epzrNoOXiE8XFZYOcCq1vD7MAXCDO+O+zndlA2ztdKKMa+EeuBG5tHETpr4ml4RGgpqDCCAg== dependencies: minimatch "^3.0.2" -node-fetch@2.6.7: - version "2.6.7" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" - integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ== - dependencies: - whatwg-url "^5.0.0" +node-fetch-native@^1.4.0, node-fetch-native@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/node-fetch-native/-/node-fetch-native-1.4.1.tgz#5a336e55b4e1b1e72b9927da09fecd2b374c9be5" + integrity sha512-NsXBU0UgBxo2rQLOeWNZqS3fvflWePMECr8CoSWoSTqCqGbVVsvl9vZu1HfQicYN0g5piV9Gh8RTEvo/uP752w== node-fetch@^1.0.1: version "1.7.3" @@ -15321,95 +15479,56 @@ node-fetch@^1.0.1: encoding "^0.1.11" is-stream "^1.0.1" -node-fetch@^2.6.1, node-fetch@^2.6.7: - version "2.6.9" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.9.tgz#7c7f744b5cc6eb5fd404e0c7a9fec630a55657e6" - integrity sha512-DJm/CJkZkRjKKj4Zi4BsKVZh3ValV5IR5s7LVZnW+6YMh0W1BfNA8XSs6DLMGYlId5F3KnA70uu2qepcR08Qqg== +node-fetch@^2.0.0, node-fetch@^2.6.1, node-fetch@^2.6.12, node-fetch@^2.6.9, node-fetch@^2.7.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" + integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A== dependencies: whatwg-url "^5.0.0" -node-gyp-build-optional-packages@5.0.3: - version "5.0.3" - resolved "https://registry.yarnpkg.com/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.0.3.tgz#92a89d400352c44ad3975010368072b41ad66c17" - integrity sha512-k75jcVzk5wnnc/FMxsf4udAoTEUv2jY3ycfdSd3yWu6Cnd1oee6/CfZJApyscA4FJOmdoixWwiwOyf16RzD5JA== +node-forge@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.3.1.tgz#be8da2af243b2417d5f646a770663a92b7e9ded3" + integrity sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA== node-gyp-build-optional-packages@5.0.7: version "5.0.7" resolved "https://registry.yarnpkg.com/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.0.7.tgz#5d2632bbde0ab2f6e22f1bbac2199b07244ae0b3" integrity sha512-YlCCc6Wffkx0kHkmam79GKvDQ6x+QZkMjFGrIMxgFNILFvGSbCp2fCBC55pGTT9gVaz8Na5CLmxt/urtzRv36w== -node-gyp-build@^4.2.2, node-gyp-build@^4.3.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.6.0.tgz#0c52e4cbf54bbd28b709820ef7b6a3c2d6209055" - integrity sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ== - -node-hid@2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/node-hid/-/node-hid-2.1.1.tgz#f83c8aa0bb4e6758b5f7383542477da93f67359d" - integrity sha512-Skzhqow7hyLZU93eIPthM9yjot9lszg9xrKxESleEs05V2NcbUptZc5HFqzjOkSmL0sFlZFr3kmvaYebx06wrw== +node-gyp-build-optional-packages@5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.1.1.tgz#52b143b9dd77b7669073cbfe39e3f4118bfc603c" + integrity sha512-+P72GAjVAbTxjjwUmwjVrqrdZROD4nf8KgpBoDxqXXTiYZZt/ud60dE5yvCSr9lRO8e8yv6kgJIC0K0PfZFVQw== dependencies: - bindings "^1.5.0" - node-addon-api "^3.0.2" - prebuild-install "^6.0.0" + detect-libc "^2.0.1" -node-int64@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" - integrity sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw== +node-gyp-build@^4.2.0, node-gyp-build@^4.3.0: + version "4.7.1" + resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.7.1.tgz#cd7d2eb48e594874053150a9418ac85af83ca8f7" + integrity sha512-wTSrZ+8lsRRa3I3H8Xr65dLWSgCvY2l4AOnaeKdPA9TB/WYMPaTcrzf3rXvFoVvjKNVnu0CcWSx54qq9GKRUYg== -node-libs-browser@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.2.1.tgz#b64f513d18338625f90346d27b0d235e631f6425" - integrity sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q== - dependencies: - assert "^1.1.1" - browserify-zlib "^0.2.0" - buffer "^4.3.0" - console-browserify "^1.1.0" - constants-browserify "^1.0.0" - crypto-browserify "^3.11.0" - domain-browser "^1.1.1" - events "^3.0.0" - https-browserify "^1.0.0" - os-browserify "^0.3.0" - path-browserify "0.0.1" - process "^0.11.10" - punycode "^1.2.4" - querystring-es3 "^0.2.0" - readable-stream "^2.3.3" - stream-browserify "^2.0.1" - stream-http "^2.7.2" - string_decoder "^1.0.0" - timers-browserify "^2.0.4" - tty-browserify "0.0.0" - url "^0.11.0" - util "^0.11.0" - vm-browserify "^1.0.1" +node-gyp-build@^4.2.2, node-gyp-build@^4.5.0: + version "4.8.1" + resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.8.1.tgz#976d3ad905e71b76086f4f0b0d3637fe79b6cda5" + integrity sha512-OSs33Z9yWr148JZcbZd5WiAXhh/n9z8TxQcdMhIOlpN9AhWpLfvVFO73+m77bBABQMaY9XSvIa+qk0jlI7Gcaw== -node-notifier@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-6.0.0.tgz#cea319e06baa16deec8ce5cd7f133c4a46b68e12" - integrity sha512-SVfQ/wMw+DesunOm5cKqr6yDcvUTDl/yc97ybGHMrteNEY6oekXpNpS3lZwgLlwz0FLgHoiW28ZpmBHUDg37cw== - dependencies: - growly "^1.3.0" - is-wsl "^2.1.1" - semver "^6.3.0" - shellwords "^0.1.1" - which "^1.3.1" +node-releases@^2.0.13: + version "2.0.13" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.13.tgz#d5ed1627c23e3461e819b02e57b75e4899b1c81d" + integrity sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ== -node-releases@^2.0.8: - version "2.0.10" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.10.tgz#c311ebae3b6a148c89b1813fd7c4d3c024ef537f" - integrity sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w== +node-releases@^2.0.14: + version "2.0.14" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.14.tgz#2ffb053bceb8b2be8495ece1ab6ce600c4461b0b" + integrity sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw== -nopt@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-5.0.0.tgz#530942bb58a512fccafe53fe210f13a25355dc88" - integrity sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ== - dependencies: - abbrev "1" +node-releases@^2.0.18: + version "2.0.18" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.18.tgz#f010e8d35e2fe8d6b2944f03f70213ecedc4ca3f" + integrity sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g== -normalize-package-data@^2.3.2, normalize-package-data@^2.3.4, normalize-package-data@^2.5.0: +normalize-package-data@^2.3.2, normalize-package-data@^2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== @@ -15429,28 +15548,11 @@ normalize-package-data@^3.0.0: semver "^7.3.4" validate-npm-package-license "^3.0.1" -normalize-path@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" - integrity sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w== - dependencies: - remove-trailing-separator "^1.0.1" - normalize-path@^3.0.0, normalize-path@~3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== -normalize-range@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942" - integrity sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA== - -normalize-url@^6.0.1: - version "6.1.0" - resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-6.1.0.tgz#40d0885b535deffe3f3147bec877d05fe4c5668a" - integrity sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A== - npm-run-all@^4.1.5: version "4.1.5" resolved "https://registry.yarnpkg.com/npm-run-all/-/npm-run-all-4.1.5.tgz#04476202a15ee0e2e214080861bff12a51d98fba" @@ -15466,14 +15568,7 @@ npm-run-all@^4.1.5: shell-quote "^1.6.1" string.prototype.padend "^3.0.0" -npm-run-path@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" - integrity sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw== - dependencies: - path-key "^2.0.0" - -npm-run-path@^4.0.0, npm-run-path@^4.0.1: +npm-run-path@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== @@ -15487,26 +15582,6 @@ npm-run-path@^5.1.0: dependencies: path-key "^4.0.0" -npmlog@^4.0.1: - version "4.1.2" - resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" - integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== - dependencies: - are-we-there-yet "~1.1.2" - console-control-strings "~1.1.0" - gauge "~2.7.3" - set-blocking "~2.0.0" - -npmlog@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-5.0.1.tgz#f06678e80e29419ad67ab964e0fa69959c1eb8b0" - integrity sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw== - dependencies: - are-we-there-yet "^2.0.0" - console-control-strings "^1.1.0" - gauge "^3.0.0" - set-blocking "^2.0.0" - nth-check@^2.0.1: version "2.1.1" resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.1.1.tgz#c9eab428effce36cd6b92c924bdb000ef1f1ed1d" @@ -15519,28 +15594,63 @@ nullthrows@^1.1.1: resolved "https://registry.yarnpkg.com/nullthrows/-/nullthrows-1.1.1.tgz#7818258843856ae971eae4208ad7d7eb19a431b1" integrity sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw== -num2fraction@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/num2fraction/-/num2fraction-1.2.2.tgz#6f682b6a027a4e9ddfa4564cd2589d1d4e669ede" - integrity sha512-Y1wZESM7VUThYY+4W+X4ySH2maqcA+p7UR+w8VWNWVAd6lwuXXWz/w/Cz43J/dI2I+PS6wD5N+bJUF+gjWvIqg== - -number-is-nan@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" - integrity sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ== - -nwsapi@^2.2.0: - version "2.2.2" - resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.2.tgz#e5418863e7905df67d51ec95938d67bf801f0bb0" - integrity sha512-90yv+6538zuvUMnN+zCr8LuV6bPFdq50304114vJYJ8RDyK8D5O9Phpbd6SZWgI7PwzmmfN1upeOJlvybDSgCw== - -nx@15.9.2: - version "15.9.2" - resolved "https://registry.yarnpkg.com/nx/-/nx-15.9.2.tgz#d7ace1e5ae64a47f1b553dc5da08dbdd858bde96" - integrity sha512-wtcs+wsuplSckvgk+bV+/XuGlo+sVWzSG0RpgWBjQYeqA3QsVFEAPVY66Z5cSoukDbTV77ddcAjEw+Rz8oOR1A== +nx@15.9.7: + version "15.9.7" + resolved "https://registry.yarnpkg.com/nx/-/nx-15.9.7.tgz#f0e713cedb8637a517d9c4795c99afec4959a1b6" + integrity sha512-1qlEeDjX9OKZEryC8i4bA+twNg+lB5RKrozlNwWx/lLJHqWPUfvUTvxh+uxlPYL9KzVReQjUuxMLFMsHNqWUrA== dependencies: - "@nrwl/cli" "15.9.2" - "@nrwl/tao" "15.9.2" + "@nrwl/cli" "15.9.7" + "@nrwl/tao" "15.9.7" + "@parcel/watcher" "2.0.4" + "@yarnpkg/lockfile" "^1.1.0" + "@yarnpkg/parsers" "3.0.0-rc.46" + "@zkochan/js-yaml" "0.0.6" + axios "^1.0.0" + chalk "^4.1.0" + cli-cursor "3.1.0" + cli-spinners "2.6.1" + cliui "^7.0.2" + dotenv "~10.0.0" + enquirer "~2.3.6" + fast-glob "3.2.7" + figures "3.2.0" + flat "^5.0.2" + fs-extra "^11.1.0" + glob "7.1.4" + ignore "^5.0.4" + js-yaml "4.1.0" + jsonc-parser "3.2.0" + lines-and-columns "~2.0.3" + minimatch "3.0.5" + npm-run-path "^4.0.1" + open "^8.4.0" + semver "7.5.4" + string-width "^4.2.3" + strong-log-transformer "^2.1.0" + tar-stream "~2.2.0" + tmp "~0.2.1" + tsconfig-paths "^4.1.2" + tslib "^2.3.0" + v8-compile-cache "2.3.0" + yargs "^17.6.2" + yargs-parser "21.1.1" + optionalDependencies: + "@nrwl/nx-darwin-arm64" "15.9.7" + "@nrwl/nx-darwin-x64" "15.9.7" + "@nrwl/nx-linux-arm-gnueabihf" "15.9.7" + "@nrwl/nx-linux-arm64-gnu" "15.9.7" + "@nrwl/nx-linux-arm64-musl" "15.9.7" + "@nrwl/nx-linux-x64-gnu" "15.9.7" + "@nrwl/nx-linux-x64-musl" "15.9.7" + "@nrwl/nx-win32-arm64-msvc" "15.9.7" + "@nrwl/nx-win32-x64-msvc" "15.9.7" + +nx@16.2.1: + version "16.2.1" + resolved "https://registry.yarnpkg.com/nx/-/nx-16.2.1.tgz#8571a4663c79dc9d60c98599b19146b58c59b473" + integrity sha512-O+yGcYIQtYKYagbIuOQFk1P8ki5PHn0BZjdZpsa4K8UZ4pCaRWzlwWwwUL91FUJe6tdhic5710DwAAakbGKP7Q== + dependencies: + "@nrwl/tao" "16.2.1" "@parcel/watcher" "2.0.4" "@yarnpkg/lockfile" "^1.1.0" "@yarnpkg/parsers" "^3.0.0-rc.18" @@ -15575,41 +15685,27 @@ nx@15.9.2: yargs "^17.6.2" yargs-parser "21.1.1" optionalDependencies: - "@nrwl/nx-darwin-arm64" "15.9.2" - "@nrwl/nx-darwin-x64" "15.9.2" - "@nrwl/nx-linux-arm-gnueabihf" "15.9.2" - "@nrwl/nx-linux-arm64-gnu" "15.9.2" - "@nrwl/nx-linux-arm64-musl" "15.9.2" - "@nrwl/nx-linux-x64-gnu" "15.9.2" - "@nrwl/nx-linux-x64-musl" "15.9.2" - "@nrwl/nx-win32-arm64-msvc" "15.9.2" - "@nrwl/nx-win32-x64-msvc" "15.9.2" - -oauth-sign@~0.9.0: - version "0.9.0" - resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" - integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== - -object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: + "@nx/nx-darwin-arm64" "16.2.1" + "@nx/nx-darwin-x64" "16.2.1" + "@nx/nx-linux-arm-gnueabihf" "16.2.1" + "@nx/nx-linux-arm64-gnu" "16.2.1" + "@nx/nx-linux-arm64-musl" "16.2.1" + "@nx/nx-linux-x64-gnu" "16.2.1" + "@nx/nx-linux-x64-musl" "16.2.1" + "@nx/nx-win32-arm64-msvc" "16.2.1" + "@nx/nx-win32-x64-msvc" "16.2.1" + +object-assign@^4.1.0, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== -object-copy@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" - integrity sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ== - dependencies: - copy-descriptor "^0.1.0" - define-property "^0.2.5" - kind-of "^3.0.3" - -object-inspect@^1.12.3, object-inspect@^1.9.0: - version "1.12.3" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.3.tgz#ba62dffd67ee256c8c086dfae69e016cd1f198b9" - integrity sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g== +object-inspect@^1.13.1, object-inspect@^1.9.0: + version "1.13.1" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.1.tgz#b96c6109324ccfef6b12216a956ca4dc2ff94bc2" + integrity sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ== -object-is@^1.0.1, object-is@^1.1.5: +object-is@^1.1.5: version "1.1.5" resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.5.tgz#b9deeaa5fc7f1846a0faecdceec138e5778f53ac" integrity sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw== @@ -15622,14 +15718,7 @@ object-keys@^1.1.1: resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== -object-visit@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" - integrity sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA== - dependencies: - isobject "^3.0.0" - -object.assign@^4.1.3, object.assign@^4.1.4: +object.assign@^4.1.4: version "4.1.4" resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.4.tgz#9673c7c7c351ab8c4d0b516f4343ebf4dfb7799f" integrity sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ== @@ -15639,63 +15728,70 @@ object.assign@^4.1.3, object.assign@^4.1.4: has-symbols "^1.0.3" object-keys "^1.1.1" -object.entries@^1.1.0, object.entries@^1.1.6: - version "1.1.6" - resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.6.tgz#9737d0e5b8291edd340a3e3264bb8a3b00d5fa23" - integrity sha512-leTPzo4Zvg3pmbQ3rDK69Rl8GQvIqMWubrkxONG9/ojtFE2rD9fjMKfSI5BxW3osRH1m6VdzmqK8oAY9aT4x5w== +object.entries@^1.1.6: + version "1.1.7" + resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.7.tgz#2b47760e2a2e3a752f39dd874655c61a7f03c131" + integrity sha512-jCBs/0plmPsOnrKAfFQXRG2NFjlhZgjjcBLSmTnEhU8U6vVTsVe8ANeQJCHTl3gSsI4J+0emOoCgoKlmQPMgmA== dependencies: call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.4" + define-properties "^1.2.0" + es-abstract "^1.22.1" -"object.fromentries@^2.0.0 || ^1.0.0", object.fromentries@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.6.tgz#cdb04da08c539cffa912dcd368b886e0904bfa73" - integrity sha512-VciD13dswC4j1Xt5394WR4MzmAQmlgN72phd/riNp9vtD7tp4QQWJ0R4wvclXcafgcYK8veHRed2W6XeGBvcfg== +object.fromentries@^2.0.6, object.fromentries@^2.0.7: + version "2.0.7" + resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.7.tgz#71e95f441e9a0ea6baf682ecaaf37fa2a8d7e616" + integrity sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA== dependencies: call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.4" + define-properties "^1.2.0" + es-abstract "^1.22.1" -object.getownpropertydescriptors@^2.0.3, object.getownpropertydescriptors@^2.1.2: - version "2.1.5" - resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.5.tgz#db5a9002489b64eef903df81d6623c07e5b4b4d3" - integrity sha512-yDNzckpM6ntyQiGTik1fKV1DcVDRS+w8bvpWNCBanvH5LfRX9O8WTHqQzG4RZwRAM4I0oU7TV11Lj5v0g20ibw== +object.groupby@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/object.groupby/-/object.groupby-1.0.1.tgz#d41d9f3c8d6c778d9cbac86b4ee9f5af103152ee" + integrity sha512-HqaQtqLnp/8Bn4GL16cj+CUYbnpe1bh0TtEaWvybszDG4tgxCJuRpV8VGuvNaI1fAnI4lUJzDG55MXcOH4JZcQ== dependencies: - array.prototype.reduce "^1.0.5" call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.4" + define-properties "^1.2.0" + es-abstract "^1.22.1" + get-intrinsic "^1.2.1" object.hasown@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/object.hasown/-/object.hasown-1.1.2.tgz#f919e21fad4eb38a57bc6345b3afd496515c3f92" - integrity sha512-B5UIT3J1W+WuWIU55h0mjlwaqxiE5vYENJXIXZ4VFe05pNYrkKuK0U/6aFcb0pKywYJh7IhfoqUfKVmrJJHZHw== - dependencies: - define-properties "^1.1.4" - es-abstract "^1.20.4" - -object.pick@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" - integrity sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ== + version "1.1.3" + resolved "https://registry.yarnpkg.com/object.hasown/-/object.hasown-1.1.3.tgz#6a5f2897bb4d3668b8e79364f98ccf971bda55ae" + integrity sha512-fFI4VcYpRHvSLXxP7yiZOMAd331cPfd2p7PFDVbgUsYOfCT3tICVqXWngbjr4m49OvsBwUBQ6O2uQoJvy3RexA== dependencies: - isobject "^3.0.1" + define-properties "^1.2.0" + es-abstract "^1.22.1" -object.values@^1.1.0, object.values@^1.1.6: - version "1.1.6" - resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.6.tgz#4abbaa71eba47d63589d402856f908243eea9b1d" - integrity sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw== +object.values@^1.1.6, object.values@^1.1.7: + version "1.1.7" + resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.7.tgz#617ed13272e7e1071b43973aa1655d9291b8442a" + integrity sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng== dependencies: call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.4" + define-properties "^1.2.0" + es-abstract "^1.22.1" objectorarray@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/objectorarray/-/objectorarray-1.0.5.tgz#2c05248bbefabd8f43ad13b41085951aac5e68a5" integrity sha512-eJJDYkhJFFbBBAxeh8xW+weHlkI28n2ZdQV/J/DNfWfSKlGEf2xcfAbZTv3riEXHAhL9SVOTs2pRmXiSTf78xg== +ofetch@^1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/ofetch/-/ofetch-1.3.3.tgz#588cb806a28e5c66c2c47dd8994f9059a036d8c0" + integrity sha512-s1ZCMmQWXy4b5K/TW9i/DtiN8Ku+xCiHcjQ6/J/nDdssirrQNOoB165Zu8EqLMA2lln1JUth9a0aW9Ap2ctrUg== + dependencies: + destr "^2.0.1" + node-fetch-native "^1.4.0" + ufo "^1.3.0" + +on-exit-leak-free@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/on-exit-leak-free/-/on-exit-leak-free-0.2.0.tgz#b39c9e3bf7690d890f4861558b0d7b90a442d209" + integrity sha512-dqaz3u44QbRXQooZLTUKU41ZrzYrcvLISVgbrzbyCMxpmSLJvZ3ZamIJIZ29P6OhZIkNIQKosdeM6t1LYbA9hg== + on-finished@2.4.1: version "2.4.1" resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" @@ -15715,13 +15811,6 @@ once@^1.3.0, once@^1.3.1, once@^1.4.0: dependencies: wrappy "1" -onetime@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" - integrity sha512-oyyPpiMaKARvvcgip+JV+7zci5L8D1W9RZIz2l1o08AM3pfspitVWnPt3mzHcBPp12oYMTy0pqrFs/C+m3EwsQ== - dependencies: - mimic-fn "^1.0.0" - onetime@^5.1.0, onetime@^5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" @@ -15736,7 +15825,7 @@ onetime@^6.0.0: dependencies: mimic-fn "^4.0.0" -open@^7.0.3: +open@^7.4.2: version "7.4.2" resolved "https://registry.yarnpkg.com/open/-/open-7.4.2.tgz#b8147e26dcf3e426316c730089fd71edd29c2321" integrity sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q== @@ -15744,7 +15833,7 @@ open@^7.0.3: is-docker "^2.0.0" is-wsl "^2.1.1" -open@^8.4.0: +open@^8.0.4, open@^8.4.0: version "8.4.2" resolved "https://registry.yarnpkg.com/open/-/open-8.4.2.tgz#5b5ffe2a8f793dcd2aad73e550cb87b59cb084f9" integrity sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ== @@ -15753,33 +15842,19 @@ open@^8.4.0: is-docker "^2.1.1" is-wsl "^2.2.0" -optionator@^0.8.1, optionator@^0.8.3: - version "0.8.3" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" - integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA== - dependencies: - deep-is "~0.1.3" - fast-levenshtein "~2.0.6" - levn "~0.3.0" - prelude-ls "~1.1.2" - type-check "~0.3.2" - word-wrap "~1.2.3" - -ora@^4.0.3: - version "4.1.1" - resolved "https://registry.yarnpkg.com/ora/-/ora-4.1.1.tgz#566cc0348a15c36f5f0e979612842e02ba9dddbc" - integrity sha512-sjYP8QyVWBpBZWD6Vr1M/KwknSw6kJOz41tvGMlwWeClHBtYKTbHMki1PsLZnxKpXMPbTKv9b3pjQu3REib96A== +optionator@^0.9.3: + version "0.9.3" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.3.tgz#007397d44ed1872fdc6ed31360190f81814e2c64" + integrity sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg== dependencies: - chalk "^3.0.0" - cli-cursor "^3.1.0" - cli-spinners "^2.2.0" - is-interactive "^1.0.0" - log-symbols "^3.0.0" - mute-stream "0.0.8" - strip-ansi "^6.0.0" - wcwidth "^1.0.1" + "@aashutoshrathi/word-wrap" "^1.2.3" + deep-is "^0.1.3" + fast-levenshtein "^2.0.6" + levn "^0.4.1" + prelude-ls "^1.2.1" + type-check "^0.4.0" -ora@^5.4.1: +ora@^5.1.0, ora@^5.4.1: version "5.4.1" resolved "https://registry.yarnpkg.com/ora/-/ora-5.4.1.tgz#1b2678426af4ac4a509008e5e4ac9e9959db9e18" integrity sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ== @@ -15794,71 +15869,27 @@ ora@^5.4.1: strip-ansi "^6.0.0" wcwidth "^1.0.1" -ordered-binary@^1.2.4: - version "1.4.0" - resolved "https://registry.yarnpkg.com/ordered-binary/-/ordered-binary-1.4.0.tgz#6bb53d44925f3b8afc33d1eed0fa15693b211389" - integrity sha512-EHQ/jk4/a9hLupIKxTfUsQRej1Yd/0QLQs3vGvIqg5ZtCYSzNhkzHoZc7Zf4e4kUlDaC3Uw8Q/1opOLNN2OKRQ== +ordered-binary@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/ordered-binary/-/ordered-binary-1.4.1.tgz#205cb6efd6c27fa0ef4eced994a023e081cdc911" + integrity sha512-9LtiGlPy982CsgxZvJGNNp2/NnrgEr6EAyN3iIEP3/8vd3YLgAZQHbQ75ZrkfBRGrNg37Dk3U6tuVb+B4Xfslg== os-browserify@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27" integrity sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A== -os-homedir@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" - integrity sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ== - os-tmpdir@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" integrity sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g== -outdent@^0.8.0: - version "0.8.0" - resolved "https://registry.yarnpkg.com/outdent/-/outdent-0.8.0.tgz#2ebc3e77bf49912543f1008100ff8e7f44428eb0" - integrity sha512-KiOAIsdpUTcAXuykya5fnVVT+/5uS0Q1mrkRHcF89tpieSmY33O/tmc54CqwA+bfhbtEfZUNLHaPUiB9X3jt1A== - -p-all@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/p-all/-/p-all-2.1.0.tgz#91419be56b7dee8fe4c5db875d55e0da084244a0" - integrity sha512-HbZxz5FONzz/z2gJfk6bFca0BCiSRF8jU3yCsWOen/vR6lZjfPOu/e7L3uFzTW1i0H8TlC3vqQstEJPQL4/uLA== - dependencies: - p-map "^2.0.0" - -p-cancelable@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-2.1.1.tgz#aab7fbd416582fa32a3db49859c122487c5ed2cf" - integrity sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg== - -p-each-series@^2.1.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/p-each-series/-/p-each-series-2.2.0.tgz#105ab0357ce72b202a8a8b94933672657b5e2a9a" - integrity sha512-ycIL2+1V32th+8scbpTvyHNaHe02z0sjgh91XXjAk+ZeXoPN4Z46DVUnzdso0aX4KckKw0FNNFHdjZ2UsZvxiA== - -p-event@^4.1.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/p-event/-/p-event-4.2.0.tgz#af4b049c8acd91ae81083ebd1e6f5cae2044c1b5" - integrity sha512-KXatOjCRXXkSePPb1Nbi0p0m+gQAwdlbhi4wQKJPI1HsMQS9g+Sqp2o+QHziPr7eYJyOZet836KoHEVM1mwOrQ== - dependencies: - p-timeout "^3.1.0" - -p-filter@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/p-filter/-/p-filter-2.1.0.tgz#1b1472562ae7a0f742f0f3d3d3718ea66ff9c09c" - integrity sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw== +p-limit@^1.1.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" + integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== dependencies: - p-map "^2.0.0" - -p-finally@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" - integrity sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow== - -p-finally@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-2.0.1.tgz#bd6fcaa9c559a096b680806f4d657b3f0f240561" - integrity sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw== + p-try "^1.0.0" p-limit@^2.0.0, p-limit@^2.2.0: version "2.3.0" @@ -15874,6 +15905,20 @@ p-limit@^3.0.2: dependencies: yocto-queue "^0.1.0" +p-limit@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-4.0.0.tgz#914af6544ed32bfa54670b061cafcbd04984b644" + integrity sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ== + dependencies: + yocto-queue "^1.0.0" + +p-locate@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" + integrity sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg== + dependencies: + p-limit "^1.1.0" + p-locate@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" @@ -15895,17 +15940,12 @@ p-locate@^5.0.0: dependencies: p-limit "^3.0.2" -p-map@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/p-map/-/p-map-2.1.0.tgz#310928feef9c9ecc65b68b17693018a665cea175" - integrity sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw== - -p-map@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/p-map/-/p-map-3.0.0.tgz#d704d9af8a2ba684e2600d9a215983d4141a979d" - integrity sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ== +p-locate@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-6.0.0.tgz#3da9a49d4934b901089dca3302fa65dc5a05c04f" + integrity sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw== dependencies: - aggregate-error "^3.0.0" + p-limit "^4.0.0" p-map@^4.0.0: version "4.0.0" @@ -15914,43 +15954,22 @@ p-map@^4.0.0: dependencies: aggregate-error "^3.0.0" -p-timeout@^3.1.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-3.2.0.tgz#c7e17abc971d2a7962ef83626b35d635acf23dfe" - integrity sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg== - dependencies: - p-finally "^1.0.0" +p-try@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" + integrity sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww== p-try@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== -pac-proxy-agent@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/pac-proxy-agent/-/pac-proxy-agent-5.0.0.tgz#b718f76475a6a5415c2efbe256c1c971c84f635e" - integrity sha512-CcFG3ZtnxO8McDigozwE3AqAw15zDvGH+OjXO4kzf7IkEKkQ4gxQ+3sdF50WmhQ4P/bVusXcqNE2S3XrNURwzQ== - dependencies: - "@tootallnate/once" "1" - agent-base "6" - debug "4" - get-uri "3" - http-proxy-agent "^4.0.1" - https-proxy-agent "5" - pac-resolver "^5.0.0" - raw-body "^2.2.0" - socks-proxy-agent "5" - -pac-resolver@^5.0.0: - version "5.0.1" - resolved "https://registry.yarnpkg.com/pac-resolver/-/pac-resolver-5.0.1.tgz#c91efa3a9af9f669104fa2f51102839d01cde8e7" - integrity sha512-cy7u00ko2KVgBAjuhevqpPeHIkCIqPe1v24cydhWjmeuzaBfmUWFCZJ1iAh5TuVzVZoUzXIW7K8sMYOZ84uZ9Q== - dependencies: - degenerator "^3.0.2" - ip "^1.1.5" - netmask "^2.0.2" +package-json-from-dist@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz#e501cd3094b278495eb4258d4c9f6d5ac3019f00" + integrity sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw== -pako@1.0.11, pako@~1.0.5: +pako@1.0.11: version "1.0.11" resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf" integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw== @@ -15960,16 +15979,7 @@ pako@~0.2.0: resolved "https://registry.yarnpkg.com/pako/-/pako-0.2.9.tgz#f3f7522f4ef782348da8161bad9ecfd51bf83a75" integrity sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA== -parallel-transform@^1.1.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/parallel-transform/-/parallel-transform-1.2.0.tgz#9049ca37d6cb2182c3b1d2c720be94d14a5814fc" - integrity sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg== - dependencies: - cyclist "^1.0.1" - inherits "^2.0.3" - readable-stream "^2.1.5" - -param-case@^3.0.3: +param-case@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/param-case/-/param-case-3.0.4.tgz#7d17fe4aa12bde34d4a77d91acfb6219caad01c5" integrity sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A== @@ -15977,25 +15987,25 @@ param-case@^3.0.3: dot-case "^3.0.4" tslib "^2.0.3" -parcel@^2.7.0, parcel@^2.8.0: - version "2.8.3" - resolved "https://registry.yarnpkg.com/parcel/-/parcel-2.8.3.tgz#1ff71d7317274fd367379bc7310a52c6b75d30c2" - integrity sha512-5rMBpbNE72g6jZvkdR5gS2nyhwIXaJy8i65osOqs/+5b7zgf3eMKgjSsDrv6bhz3gzifsba6MBJiZdBckl+vnA== - dependencies: - "@parcel/config-default" "2.8.3" - "@parcel/core" "2.8.3" - "@parcel/diagnostic" "2.8.3" - "@parcel/events" "2.8.3" - "@parcel/fs" "2.8.3" - "@parcel/logger" "2.8.3" - "@parcel/package-manager" "2.8.3" - "@parcel/reporter-cli" "2.8.3" - "@parcel/reporter-dev-server" "2.8.3" - "@parcel/utils" "2.8.3" +parcel@^2.11.0: + version "2.12.0" + resolved "https://registry.yarnpkg.com/parcel/-/parcel-2.12.0.tgz#60529c268c2ce0754b225af835f1519da1364298" + integrity sha512-W+gxAq7aQ9dJIg/XLKGcRT0cvnStFAQHPaI0pvD0U2l6IVLueUAm3nwN7lkY62zZNmlvNx6jNtE4wlbS+CyqSg== + dependencies: + "@parcel/config-default" "2.12.0" + "@parcel/core" "2.12.0" + "@parcel/diagnostic" "2.12.0" + "@parcel/events" "2.12.0" + "@parcel/fs" "2.12.0" + "@parcel/logger" "2.12.0" + "@parcel/package-manager" "2.12.0" + "@parcel/reporter-cli" "2.12.0" + "@parcel/reporter-dev-server" "2.12.0" + "@parcel/reporter-tracer" "2.12.0" + "@parcel/utils" "2.12.0" chalk "^4.1.0" commander "^7.0.0" get-port "^4.2.0" - v8-compile-cache "^2.0.0" parent-module@^1.0.0: version "1.0.1" @@ -16004,7 +16014,7 @@ parent-module@^1.0.0: dependencies: callsites "^3.0.0" -parse-asn1@^5.0.0, parse-asn1@^5.1.5: +parse-asn1@^5.0.0, parse-asn1@^5.1.6: version "5.1.6" resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.6.tgz#385080a3ec13cb62a62d39409cb3e88844cdaed4" integrity sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw== @@ -16015,6 +16025,22 @@ parse-asn1@^5.0.0, parse-asn1@^5.1.5: pbkdf2 "^3.0.3" safe-buffer "^5.1.1" +parse-css-color@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/parse-css-color/-/parse-css-color-0.2.0.tgz#e9f2d620900787164022f0c6b909a72ce4cd03db" + integrity sha512-uWQyuOe+SMxnUgHf4mjdn2C/YzA1tOW+uU8Z2UiV3qnao9ZFnvYeyzeoU7TNv8NLIJo0PiRkETW48QNJZ4IA9g== + dependencies: + color-name "^1.1.4" + hex-rgb "^4.1.0" + +parse-css-color@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/parse-css-color/-/parse-css-color-0.1.2.tgz#9d178f2d2b5eb7245c0deb22ea35046b79ff3f83" + integrity sha512-z7v/tf0edGsnlm9VONQtH+u/YVrdUqZXrSBzqM13scef8Abl2VyZfYsZaJoyb/AyY4SIxtoJChSQ4MURHfY3Sg== + dependencies: + color-name "^1.1.4" + hex-rgb "^4.1.0" + parse-entities@^1.1.2: version "1.2.2" resolved "https://registry.yarnpkg.com/parse-entities/-/parse-entities-1.2.2.tgz#c31bf0f653b6661354f8973559cb86dd1d5edf50" @@ -16039,27 +16065,6 @@ parse-entities@^2.0.0: is-decimal "^1.0.0" is-hexadecimal "^1.0.0" -parse-entities@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/parse-entities/-/parse-entities-4.0.1.tgz#4e2a01111fb1c986549b944af39eeda258fc9e4e" - integrity sha512-SWzvYcSJh4d/SGLIOQfZ/CoNv6BTlI6YEQ7Nj82oDVnRpwe/Z/F1EMx42x3JAOwGBlCjeCH0BRJQbQ/opHL17w== - dependencies: - "@types/unist" "^2.0.0" - character-entities "^2.0.0" - character-entities-legacy "^3.0.0" - character-reference-invalid "^2.0.0" - decode-named-character-reference "^1.0.0" - is-alphanumerical "^2.0.0" - is-decimal "^2.0.0" - is-hexadecimal "^2.0.0" - -parse-json@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" - integrity sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ== - dependencies: - error-ex "^1.2.0" - parse-json@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" @@ -16068,7 +16073,7 @@ parse-json@^4.0.0: error-ex "^1.3.1" json-parse-better-errors "^1.0.1" -parse-json@^5.0.0: +parse-json@^5.0.0, parse-json@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== @@ -16078,27 +16083,12 @@ parse-json@^5.0.0: json-parse-even-better-errors "^2.3.0" lines-and-columns "^1.1.6" -parse-ms@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/parse-ms/-/parse-ms-2.1.0.tgz#348565a753d4391fa524029956b172cb7753097d" - integrity sha512-kHt7kzLoS9VBZfUsiKjv43mr91ea+U05EyKkEtqp7vNbHxmaVuEqN7XxeEVnGrMtYOAxGrDElSi96K7EgO1zCA== - -parse5@5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/parse5/-/parse5-5.1.0.tgz#c59341c9723f414c452975564c7c00a68d58acd2" - integrity sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ== - -parse5@^6.0.0: - version "6.0.1" - resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b" - integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw== - -parseurl@~1.3.2, parseurl@~1.3.3: +parseurl@~1.3.3: version "1.3.3" resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== -pascal-case@^3.1.1, pascal-case@^3.1.2: +pascal-case@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/pascal-case/-/pascal-case-3.1.2.tgz#b48e0ef2b98e205e7c1dae747d0b1508237660eb" integrity sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g== @@ -16106,33 +16096,32 @@ pascal-case@^3.1.1, pascal-case@^3.1.2: no-case "^3.0.4" tslib "^2.0.3" -pascalcase@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" - integrity sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw== - -path-browserify@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.1.tgz#e6c4ddd7ed3aa27c68a20cc4e50e1a4ee83bbc4a" - integrity sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ== +patch-package@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/patch-package/-/patch-package-8.0.0.tgz#d191e2f1b6e06a4624a0116bcb88edd6714ede61" + integrity sha512-da8BVIhzjtgScwDJ2TtKsfT5JFWz1hYoBl9rUQ1f38MC2HwnEIkK8VN3dKMKcP7P7bvvgzNDbfNHtx3MsQb5vA== + dependencies: + "@yarnpkg/lockfile" "^1.1.0" + chalk "^4.1.2" + ci-info "^3.7.0" + cross-spawn "^7.0.3" + find-yarn-workspace-root "^2.0.0" + fs-extra "^9.0.0" + json-stable-stringify "^1.0.2" + klaw-sync "^6.0.0" + minimist "^1.2.6" + open "^7.4.2" + rimraf "^2.6.3" + semver "^7.5.3" + slash "^2.0.0" + tmp "^0.0.33" + yaml "^2.2.2" path-browserify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-1.0.1.tgz#d98454a9c3753d5790860f16f68867b9e46be1fd" integrity sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g== -path-dirname@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" - integrity sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q== - -path-exists@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" - integrity sha512-yTltuKuhtNeFJKa1PiRzfLAU5182q1y4Eb4XCJ3PBqyzEDkAZRzBrKKBct682ls9reBVHf9udYLN5Nd+K1B9BQ== - dependencies: - pinkie-promise "^2.0.0" - path-exists@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" @@ -16143,12 +16132,17 @@ path-exists@^4.0.0: resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== +path-exists@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-5.0.0.tgz#a6aad9489200b21fab31e49cf09277e5116fb9e7" + integrity sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ== + path-is-absolute@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== -path-key@^2.0.0, path-key@^2.0.1: +path-key@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" integrity sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw== @@ -16163,35 +16157,37 @@ path-key@^4.0.0: resolved "https://registry.yarnpkg.com/path-key/-/path-key-4.0.0.tgz#295588dc3aee64154f877adb9d780b81c554bf18" integrity sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ== -path-parse@^1.0.6, path-parse@^1.0.7: +path-parse@^1.0.7: version "1.0.7" resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== -path-to-regexp@0.1.7: - version "0.1.7" - resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" - integrity sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ== +path-scurry@^1.10.1: + version "1.10.1" + resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.10.1.tgz#9ba6bf5aa8500fe9fd67df4f0d9483b2b0bfc698" + integrity sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ== + dependencies: + lru-cache "^9.1.1 || ^10.0.0" + minipass "^5.0.0 || ^6.0.2 || ^7.0.0" + +path-scurry@^1.11.1: + version "1.11.1" + resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.11.1.tgz#7960a668888594a0720b12a911d1a742ab9f11d2" + integrity sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA== + dependencies: + lru-cache "^10.2.0" + minipass "^5.0.0 || ^6.0.2 || ^7.0.0" + +path-to-regexp@0.1.10: + version "0.1.10" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.10.tgz#67e9108c5c0551b9e5326064387de4763c4d5f8b" + integrity sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w== path-to-regexp@6.1.0: version "6.1.0" resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-6.1.0.tgz#0b18f88b7a0ce0bfae6a25990c909ab86f512427" integrity sha512-h9DqehX3zZZDCEm+xbfU0ZmwCGFCAAraPJWMXJ4+v32NjZJilVg3k1TcKsRgIb8IQ/izZSaydDc1OhJCZvs2Dw== -path-to-regexp@6.2.1: - version "6.2.1" - resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-6.2.1.tgz#d54934d6798eb9e5ef14e7af7962c945906918e5" - integrity sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw== - -path-type@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" - integrity sha512-S4eENJz1pkiQn9Znv33Q+deTOKmbl+jj1Fl+qiP/vYezj+S8x+J3Uo0ISrx/QoEvIlOaDWJhPaRd1flJ9HXZqg== - dependencies: - graceful-fs "^4.1.2" - pify "^2.0.0" - pinkie-promise "^2.0.0" - path-type@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" @@ -16204,10 +16200,20 @@ path-type@^4.0.0: resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== -pathe@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/pathe/-/pathe-1.1.0.tgz#e2e13f6c62b31a3289af4ba19886c230f295ec03" - integrity sha512-ODbEPR0KKHqECXW1GoxdDb+AZvULmXjVPy4rt+pGo2+TnjJTIPJQSVS6N63n8T2Ip+syHhbn52OewKicV0373w== +pathe@^1.1.0, pathe@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/pathe/-/pathe-1.1.1.tgz#1dd31d382b974ba69809adc9a7a347e65d84829a" + integrity sha512-d+RQGp0MAYTIaDBIMmOfMwz3E+LOZnxx1HZd5R18mmCZY0QBlK0LDZfPc8FW8Ed2DlvsuE6PRjroDY+wg4+j/Q== + +pathe@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/pathe/-/pathe-1.1.2.tgz#6c4cb47a945692e48a1ddd6e4094d170516437ec" + integrity sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ== + +pathval@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/pathval/-/pathval-2.0.0.tgz#7e2550b422601d4f6b8e26f1301bc8f15a741a25" + integrity sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA== pbkdf2@^3.0.16, pbkdf2@^3.0.3, pbkdf2@^3.1.1: version "3.1.2" @@ -16229,41 +16235,37 @@ peek-stream@^1.1.0: duplexify "^3.5.0" through2 "^2.0.3" -performance-now@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" - integrity sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow== - -periscopic@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/periscopic/-/periscopic-3.1.0.tgz#7e9037bf51c5855bd33b48928828db4afa79d97a" - integrity sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw== - dependencies: - "@types/estree" "^1.0.0" - estree-walker "^3.0.0" - is-reference "^3.0.0" - -picocolors@1.0.0, picocolors@^1.0.0: +picocolors@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== -picocolors@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-0.2.1.tgz#570670f793646851d1ba135996962abad587859f" - integrity sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA== +picocolors@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.1.tgz#a8ad579b571952f0e5d25892de5445bcfe25aaa1" + integrity sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew== + +picocolors@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.0.tgz#5358b76a78cde483ba5cef6a9dc9671440b27d59" + integrity sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw== -picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.2, picomatch@^2.3.0, picomatch@^2.3.1: +picomatch@^2.0.4, picomatch@^2.0.5, picomatch@^2.2.1, picomatch@^2.3.0, picomatch@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== +pidtree@0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/pidtree/-/pidtree-0.6.0.tgz#90ad7b6d42d5841e69e0a2419ef38f8883aa057c" + integrity sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g== + pidtree@^0.3.0: version "0.3.1" resolved "https://registry.yarnpkg.com/pidtree/-/pidtree-0.3.1.tgz#ef09ac2cc0533df1f3250ccf2c4d366b0d12114a" integrity sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA== -pify@^2.0.0: +pify@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" integrity sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog== @@ -16278,22 +16280,40 @@ pify@^4.0.1: resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== -pinkie-promise@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" - integrity sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw== +pino-abstract-transport@v0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/pino-abstract-transport/-/pino-abstract-transport-0.5.0.tgz#4b54348d8f73713bfd14e3dc44228739aa13d9c0" + integrity sha512-+KAgmVeqXYbTtU2FScx1XS3kNyfZ5TrXY07V96QnUSFqo2gAqlvmaxH67Lj7SWazqsMabf+58ctdTcBgnOLUOQ== dependencies: - pinkie "^2.0.0" + duplexify "^4.1.2" + split2 "^4.0.0" -pinkie@^2.0.0: - version "2.0.4" - resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" - integrity sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg== - -pirates@^4.0.1, pirates@^4.0.5: - version "4.0.5" - resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.5.tgz#feec352ea5c3268fb23a37c702ab1699f35a5f3b" - integrity sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ== +pino-std-serializers@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/pino-std-serializers/-/pino-std-serializers-4.0.0.tgz#1791ccd2539c091ae49ce9993205e2cd5dbba1e2" + integrity sha512-cK0pekc1Kjy5w9V2/n+8MkZwusa6EyyxfeQCB799CQRhRt/CqYKiWs5adeu8Shve2ZNffvfC/7J64A2PJo1W/Q== + +pino@7.11.0: + version "7.11.0" + resolved "https://registry.yarnpkg.com/pino/-/pino-7.11.0.tgz#0f0ea5c4683dc91388081d44bff10c83125066f6" + integrity sha512-dMACeu63HtRLmCG8VKdy4cShCPKaYDR4youZqoSWLxl5Gu99HUw8bw75thbPv9Nip+H+QYX8o3ZJbTdVZZ2TVg== + dependencies: + atomic-sleep "^1.0.0" + fast-redact "^3.0.0" + on-exit-leak-free "^0.2.0" + pino-abstract-transport v0.5.0 + pino-std-serializers "^4.0.0" + process-warning "^1.0.0" + quick-format-unescaped "^4.0.3" + real-require "^0.1.0" + safe-stable-stringify "^2.1.0" + sonic-boom "^2.2.1" + thread-stream "^0.15.1" + +pirates@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.6.tgz#3018ae32ecfcff6c29ba2267cbf21166ac1f36b9" + integrity sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg== pkg-dir@^3.0.0: version "3.0.0" @@ -16302,7 +16322,7 @@ pkg-dir@^3.0.0: dependencies: find-up "^3.0.0" -pkg-dir@^4.1.0, pkg-dir@^4.2.0: +pkg-dir@^4.1.0: version "4.2.0" resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== @@ -16316,31 +16336,38 @@ pkg-dir@^5.0.0: dependencies: find-up "^5.0.0" -pkg-types@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/pkg-types/-/pkg-types-1.0.2.tgz#c233efc5210a781e160e0cafd60c0d0510a4b12e" - integrity sha512-hM58GKXOcj8WTqUXnsQyJYXdeAPbythQgEF3nTcEo+nkD49chjQ9IKm/QJy9xf6JakXptz86h7ecP2024rrLaQ== +pkg-dir@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-7.0.0.tgz#8f0c08d6df4476756c5ff29b3282d0bab7517d11" + integrity sha512-Ie9z/WINcxxLp27BKOCHGde4ITq9UklYKDzVo1nhk5sqGEXU3FpkwP5GM2voTGJkGd9B3Otl+Q4uwSOeSUtOBA== + dependencies: + find-up "^6.3.0" + +pkg-types@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/pkg-types/-/pkg-types-1.0.3.tgz#988b42ab19254c01614d13f4f65a2cfc7880f868" + integrity sha512-nN7pYi0AQqJnoLPC9eHFQ8AcyaixBUOwvqc5TDnIKCMEE6I0y8P7OKA7fPexsXGCGxQDl/cmrLAp26LhcwxZ4A== dependencies: jsonc-parser "^3.2.0" - mlly "^1.1.1" + mlly "^1.2.0" pathe "^1.1.0" -pn@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/pn/-/pn-1.1.0.tgz#e2f4cef0e219f463c179ab37463e4e1ecdccbafb" - integrity sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA== +pkg-up@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-3.1.0.tgz#100ec235cc150e4fd42519412596a28512a0def5" + integrity sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA== + dependencies: + find-up "^3.0.0" -pngjs@^3.3.0: - version "3.4.0" - resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-3.4.0.tgz#99ca7d725965fb655814eaf65f38f12bbdbf555f" - integrity sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w== +pngjs@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-5.0.0.tgz#e79dd2b215767fd9c04561c01236df960bce7fbb" + integrity sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw== -pnp-webpack-plugin@1.6.4: - version "1.6.4" - resolved "https://registry.yarnpkg.com/pnp-webpack-plugin/-/pnp-webpack-plugin-1.6.4.tgz#c9711ac4dc48a685dabafc86f8b6dd9f8df84149" - integrity sha512-7Wjy+9E3WwLOEL30D+m8TSTF7qJJUJLONBnwQp0518siuMxUQUbgZwssaFX+QKlZkjHZcw/IpZCt/H0srrntSg== - dependencies: - ts-pnp "^1.1.6" +pofile@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/pofile/-/pofile-1.1.4.tgz#eab7e29f5017589b2a61b2259dff608c0cad76a2" + integrity sha512-r6Q21sKsY1AjTVVjOuU02VYKVNQGJNQHjTIvs4dEbeuuYfxgYk/DGD2mqqq4RDaVkwdSq0VEtmQUOPe/wH8X3g== polished@^3.3.1: version "3.7.2" @@ -16361,81 +16388,20 @@ popper.js@^1.14.4, popper.js@^1.14.7: resolved "https://registry.yarnpkg.com/popper.js/-/popper.js-1.16.1.tgz#2a223cb3dc7b6213d740e40372be40de43e65b1b" integrity sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ== -posix-character-classes@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" - integrity sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg== - -postcss-discard-duplicates@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/postcss-discard-duplicates/-/postcss-discard-duplicates-5.1.0.tgz#9eb4fe8456706a4eebd6d3b7b777d07bad03e848" - integrity sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw== - -postcss-flexbugs-fixes@^4.2.1: - version "4.2.1" - resolved "https://registry.yarnpkg.com/postcss-flexbugs-fixes/-/postcss-flexbugs-fixes-4.2.1.tgz#9218a65249f30897deab1033aced8578562a6690" - integrity sha512-9SiofaZ9CWpQWxOwRh1b/r85KD5y7GgvsNt1056k6OYLvWUun0czCvogfJgylC22uJTwW1KzY3Gz65NZRlvoiQ== - dependencies: - postcss "^7.0.26" - -postcss-load-config@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/postcss-load-config/-/postcss-load-config-4.0.1.tgz#152383f481c2758274404e4962743191d73875bd" - integrity sha512-vEJIc8RdiBRu3oRAI0ymerOn+7rPuMvRXslTvZUKZonDHFIczxztIyJ1urxM1x9JXEikvpWWTUUqal5j/8QgvA== - dependencies: - lilconfig "^2.0.5" - yaml "^2.1.1" - -postcss-loader@^4.2.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/postcss-loader/-/postcss-loader-4.3.0.tgz#2c4de9657cd4f07af5ab42bd60a673004da1b8cc" - integrity sha512-M/dSoIiNDOo8Rk0mUqoj4kpGq91gcxCfb9PoyZVdZ76/AuhxylHDYZblNE8o+EQ9AMSASeMFEKxZf5aU6wlx1Q== - dependencies: - cosmiconfig "^7.0.0" - klona "^2.0.4" - loader-utils "^2.0.0" - schema-utils "^3.0.0" - semver "^7.3.4" - -postcss-modules-extract-imports@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-2.0.0.tgz#818719a1ae1da325f9832446b01136eeb493cd7e" - integrity sha512-LaYLDNS4SG8Q5WAWqIJgdHPJrDDr/Lv775rMBFUbgjTz6j34lUznACHcdRWroPvXANP2Vj7yNK57vp9eFqzLWQ== - dependencies: - postcss "^7.0.5" - postcss-modules-extract-imports@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz#cda1f047c0ae80c97dbe28c3e76a43b88025741d" integrity sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw== -postcss-modules-local-by-default@^3.0.2: - version "3.0.3" - resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-3.0.3.tgz#bb14e0cc78279d504dbdcbfd7e0ca28993ffbbb0" - integrity sha512-e3xDq+LotiGesympRlKNgaJ0PCzoUIdpH0dj47iWAui/kyTgh3CiAr1qP54uodmJhl6p9rN6BoNcdEDVJx9RDw== - dependencies: - icss-utils "^4.1.1" - postcss "^7.0.32" - postcss-selector-parser "^6.0.2" - postcss-value-parser "^4.1.0" - -postcss-modules-local-by-default@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.0.tgz#ebbb54fae1598eecfdf691a02b3ff3b390a5a51c" - integrity sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ== +postcss-modules-local-by-default@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.3.tgz#b08eb4f083050708998ba2c6061b50c2870ca524" + integrity sha512-2/u2zraspoACtrbFRnTijMiQtb4GW4BvatjaG/bCjYQo8kLTdevCUlwuBHx2sCnSyrI3x3qj4ZK1j5LQBgzmwA== dependencies: icss-utils "^5.0.0" postcss-selector-parser "^6.0.2" postcss-value-parser "^4.1.0" -postcss-modules-scope@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-2.2.0.tgz#385cae013cc7743f5a7d7602d1073a89eaae62ee" - integrity sha512-YyEgsTMRpNd+HmyC7H/mh3y+MeFWevy7V1evVhJWewmMbjDHIbZbOXICC2y+m1xI1UVfIT1HMW/O04Hxyu9oXQ== - dependencies: - postcss "^7.0.6" - postcss-selector-parser "^6.0.0" - postcss-modules-scope@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz#9ef3151456d3bbfa120ca44898dfca6f2fa01f06" @@ -16443,14 +16409,6 @@ postcss-modules-scope@^3.0.0: dependencies: postcss-selector-parser "^6.0.4" -postcss-modules-values@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-3.0.0.tgz#5b5000d6ebae29b4255301b4a3a54574423e7f10" - integrity sha512-1//E5jCBrZ9DmRX+zCtmQtRSV6PV42Ix7Bzj9GbwJceduuf7IqP8MgeTXuRDHOWj2m0VzZD5+roFWDuU8RQjcg== - dependencies: - icss-utils "^4.0.0" - postcss "^7.0.6" - postcss-modules-values@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz#d7c5e7e68c3bb3c9b27cbf48ca0bb3ffb4602c9c" @@ -16458,24 +16416,10 @@ postcss-modules-values@^4.0.0: dependencies: icss-utils "^5.0.0" -postcss-modules@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/postcss-modules/-/postcss-modules-6.0.0.tgz#cac283dbabbbdc2558c45391cbd0e2df9ec50118" - integrity sha512-7DGfnlyi/ju82BRzTIjWS5C4Tafmzl3R79YP/PASiocj+aa6yYphHhhKUOEoXQToId5rgyFgJ88+ccOUydjBXQ== - dependencies: - generic-names "^4.0.0" - icss-utils "^5.1.0" - lodash.camelcase "^4.3.0" - postcss-modules-extract-imports "^3.0.0" - postcss-modules-local-by-default "^4.0.0" - postcss-modules-scope "^3.0.0" - postcss-modules-values "^4.0.0" - string-hash "^1.1.1" - -postcss-selector-parser@^6.0.0, postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4: - version "6.0.11" - resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.11.tgz#2e41dc39b7ad74046e1615185185cd0b17d0c8dc" - integrity sha512-zbARubNdogI9j7WY4nQJBiNqQf3sLS3wCP4WfOidu+p28LofJqDH1tcXypGrcmMHhDk2t9wGhCsYe/+szLTy1g== +postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4: + version "6.0.13" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz#d05d8d76b1e8e173257ef9d60b706a8e5e99bf1b" + integrity sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ== dependencies: cssesc "^3.0.0" util-deprecate "^1.0.2" @@ -16485,23 +16429,24 @@ postcss-value-parser@^4.1.0, postcss-value-parser@^4.2.0: resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514" integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== -postcss@^7.0.14, postcss@^7.0.26, postcss@^7.0.32, postcss@^7.0.36, postcss@^7.0.5, postcss@^7.0.6: - version "7.0.39" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.39.tgz#9624375d965630e2e1f2c02a935c82a59cb48309" - integrity sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA== - dependencies: - picocolors "^0.2.1" - source-map "^0.6.1" - -postcss@^8.4.19, postcss@^8.4.21: - version "8.4.21" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.21.tgz#c639b719a57efc3187b13a1d765675485f4134f4" - integrity sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg== +postcss@^8.4.21: + version "8.4.31" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.31.tgz#92b451050a9f914da6755af352bdc0192508656d" + integrity sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ== dependencies: - nanoid "^3.3.4" + nanoid "^3.3.6" picocolors "^1.0.0" source-map-js "^1.0.2" +postcss@^8.4.43: + version "8.4.47" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.47.tgz#5bf6c9a010f3e724c503bf03ef7947dcb0fea365" + integrity sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ== + dependencies: + nanoid "^3.3.7" + picocolors "^1.1.0" + source-map-js "^1.2.1" + posthtml-parser@^0.10.1: version "0.10.2" resolved "https://registry.yarnpkg.com/posthtml-parser/-/posthtml-parser-0.10.2.tgz#df364d7b179f2a6bf0466b56be7b98fd4e97c573" @@ -16531,34 +16476,15 @@ posthtml@^0.16.4, posthtml@^0.16.5: posthtml-parser "^0.11.0" posthtml-render "^3.0.0" -preact@10.4.1: - version "10.4.1" - resolved "https://registry.yarnpkg.com/preact/-/preact-10.4.1.tgz#9b3ba020547673a231c6cf16f0fbaef0e8863431" - integrity sha512-WKrRpCSwL2t3tpOOGhf2WfTpcmbpxaWtDbdJdKdjd0aEiTkvOmS4NBkG6kzlaAHI9AkQ3iVqbFWM3Ei7mZ4o1Q== - -prebuild-install@^6.0.0: - version "6.1.4" - resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-6.1.4.tgz#ae3c0142ad611d58570b89af4986088a4937e00f" - integrity sha512-Z4vpywnK1lBg+zdPCVCsKq0xO66eEV9rWo2zrROGGiRS4JtueBOdlB1FnY8lcy7JsUud/Q3ijUxyWN26Ika0vQ== - dependencies: - detect-libc "^1.0.3" - expand-template "^2.0.3" - github-from-package "0.0.0" - minimist "^1.2.3" - mkdirp-classic "^0.5.3" - napi-build-utils "^1.0.1" - node-abi "^2.21.0" - npmlog "^4.0.1" - pump "^3.0.0" - rc "^1.2.7" - simple-get "^3.0.3" - tar-fs "^2.0.0" - tunnel-agent "^0.6.0" +postinstall-postinstall@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/postinstall-postinstall/-/postinstall-postinstall-2.1.0.tgz#4f7f77441ef539d1512c40bd04c71b06a4704ca3" + integrity sha512-7hQX6ZlZXIoRiWNrbMQaLzUUfH+sSx39u8EJ9HYuDc1kLo9IXKWjM5RSquZN1ad5GnH8CGFM78fsAAQi3OKEEQ== -prelude-ls@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" - integrity sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w== +prelude-ls@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" + integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== prettier-linter-helpers@^1.0.0: version "1.0.0" @@ -16567,62 +16493,48 @@ prettier-linter-helpers@^1.0.0: dependencies: fast-diff "^1.1.2" -prettier@2.7.1: - version "2.7.1" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.7.1.tgz#e235806850d057f97bb08368a4f7d899f7760c64" - integrity sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g== - -"prettier@>=2.2.1 <=2.3.0": - version "2.3.0" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.3.0.tgz#b6a5bf1284026ae640f17f7ff5658a7567fc0d18" - integrity sha512-kXtO4s0Lz/DW/IJ9QdWhAf7/NmPWQXkFr/r/WkR3vyI+0v8amTDxiaQSLzs8NBlytfLWX/7uQUMIW677yLKl4w== - -prettier@^1.19.1: - version "1.19.1" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.19.1.tgz#f7d7f5ff8a9cd872a7be4ca142095956a60797cb" - integrity sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew== - -prettier@^2.7.1: - version "2.8.7" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.7.tgz#bb79fc8729308549d28fe3a98fce73d2c0656450" - integrity sha512-yPngTo3aXUUmyuTjeTUT75txrf+aMh9FiD7q9ZE/i6r0bPb22g4FsE6Y338PQX1bmfy08i9QQCB7/rcUAVntfw== +prettier@^2.7.1, prettier@^2.8.7: + version "2.8.8" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.8.tgz#e8c5d7e98a4305ffe3de2e1fc4aca1a71c28b1da" + integrity sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q== -pretty-bytes@5.6.0: - version "5.6.0" - resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-5.6.0.tgz#356256f643804773c82f64723fe78c92c62beaeb" - integrity sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg== +prettier@^3.1.1: + version "3.2.5" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.2.5.tgz#e52bc3090586e824964a8813b09aba6233b28368" + integrity sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A== -pretty-error@^2.1.1: - version "2.1.2" - resolved "https://registry.yarnpkg.com/pretty-error/-/pretty-error-2.1.2.tgz#be89f82d81b1c86ec8fdfbc385045882727f93b6" - integrity sha512-EY5oDzmsX5wvuynAByrmY0P0hcp+QpnAKbJng2A2MPjVKXCxrDSUkzghVJ4ZGPIv+JC4gX8fPUWscC0RtjsWGw== +pretty-error@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/pretty-error/-/pretty-error-4.0.0.tgz#90a703f46dd7234adb46d0f84823e9d1cb8f10d6" + integrity sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw== dependencies: lodash "^4.17.20" - renderkid "^2.0.4" + renderkid "^3.0.0" -pretty-format@^25.2.1, pretty-format@^25.5.0: - version "25.5.0" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-25.5.0.tgz#7873c1d774f682c34b8d48b6743a2bf2ac55791a" - integrity sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ== +pretty-format@^27.0.2: + version "27.5.1" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-27.5.1.tgz#2181879fdea51a7a5851fb39d920faa63f01d88e" + integrity sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ== dependencies: - "@jest/types" "^25.5.0" - ansi-regex "^5.0.0" - ansi-styles "^4.0.0" - react-is "^16.12.0" + ansi-regex "^5.0.1" + ansi-styles "^5.0.0" + react-is "^17.0.1" + +pretty-format@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.7.0.tgz#ca42c758310f365bfa71a0bda0a807160b776812" + integrity sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ== + dependencies: + "@jest/schemas" "^29.6.3" + ansi-styles "^5.0.0" + react-is "^18.0.0" pretty-hrtime@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz#b7e3ea42435a4c9b2759d99e0f201eb195802ee1" integrity sha512-66hKPCr+72mlfiSjlEB1+45IjXSqvVAIy6mocupoww4tBFE9R9IhwwUGoI4G++Tc9Aq+2rxOt0RFU6gPcrte0A== -pretty-ms@7.0.1, pretty-ms@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/pretty-ms/-/pretty-ms-7.0.1.tgz#7d903eaab281f7d8e03c66f867e239dc32fb73e8" - integrity sha512-973driJZvxiGOQ5ONsFhOF/DtzPMOMtgC11kCpUrPGMTgqp2q/1gwzCquocrN33is0VZ5GFHXZYMM9l6h67v2Q== - dependencies: - parse-ms "^2.1.0" - -prismjs@^1.8.4: +prismjs@^1.27.0, prismjs@^1.8.4: version "1.29.0" resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.29.0.tgz#f113555a8fa9b57c35e637bba27509dcf802dd12" integrity sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q== @@ -16634,56 +16546,33 @@ prismjs@~1.17.0: optionalDependencies: clipboard "^2.0.0" +prismjs@~1.27.0: + version "1.27.0" + resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.27.0.tgz#bb6ee3138a0b438a3653dd4d6ce0cc6510a45057" + integrity sha512-t13BGPUlFDR7wRB5kQDG4jjl7XeuH6jbJGt11JHPL96qwsEHNX2+68tFXqc1/k+/jALsbSWJKUOT/hcYAZ5LkA== + process-nextick-args@~2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== +process-warning@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/process-warning/-/process-warning-1.0.0.tgz#980a0b25dc38cd6034181be4b7726d89066b4616" + integrity sha512-du4wfLyj4yCZq1VupnVSZmRsPJsNuxoDQFdCFHLaYiEbFBD7QE0a+I4D7hOxrVnh78QE/YipFAj9lXHiXocV+Q== + process@^0.11.10: version "0.11.10" resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A== -progress-estimator@^0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/progress-estimator/-/progress-estimator-0.2.2.tgz#1c3947a5782ea56e40c8fccc290ac7ceeb1b91cb" - integrity sha512-GF76Ac02MTJD6o2nMNtmtOFjwWCnHcvXyn5HOWPQnEMO8OTLw7LAvNmrwe8LmdsB+eZhwUu9fX/c9iQnBxWaFA== - dependencies: - chalk "^2.4.1" - cli-spinners "^1.3.1" - humanize-duration "^3.15.3" - log-update "^2.3.0" - -progress@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" - integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== - -promise-inflight@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" - integrity sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g== - -promise.allsettled@^1.0.0: - version "1.0.6" - resolved "https://registry.yarnpkg.com/promise.allsettled/-/promise.allsettled-1.0.6.tgz#8dc8ba8edf429feb60f8e81335b920e109c94b6e" - integrity sha512-22wJUOD3zswWFqgwjNHa1965LvqTX87WPu/lreY2KSd7SVcERfuZ4GfUaOnJNnvtoIv2yXT/W00YIGMetXtFXg== - dependencies: - array.prototype.map "^1.0.5" - call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.4" - get-intrinsic "^1.1.3" - iterate-value "^1.0.2" - -promise.prototype.finally@^3.1.0: - version "3.1.4" - resolved "https://registry.yarnpkg.com/promise.prototype.finally/-/promise.prototype.finally-3.1.4.tgz#4e756a154e4db27fae24c6b18703495c31da3927" - integrity sha512-nNc3YbgMfLzqtqvO/q5DP6RR0SiHI9pUPGzyDf1q+usTwCN2kjvAnJkBb7bHe3o+fFSBPpsGMoYtaSi+LTNqng== +promise-retry@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/promise-retry/-/promise-retry-2.0.1.tgz#ff747a13620ab57ba688f5fc67855410c370da22" + integrity sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g== dependencies: - call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.4" + err-code "^2.0.2" + retry "^0.12.0" promise@^7.1.1: version "7.3.1" @@ -16692,7 +16581,7 @@ promise@^7.1.1: dependencies: asap "~2.0.3" -prompts@^2.0.1, prompts@^2.4.0: +prompts@^2.4.0: version "2.4.2" resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.2.tgz#7b57e73b3a48029ad10ebd44f74b01722a4cb069" integrity sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q== @@ -16700,7 +16589,7 @@ prompts@^2.0.1, prompts@^2.4.0: kleur "^3.0.3" sisteransi "^1.0.5" -prop-types@^15.0.0, prop-types@^15.5.10, prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2, prop-types@^15.8.1: +prop-types@^15.5.10, prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2, prop-types@^15.8.1: version "15.8.1" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5" integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== @@ -16709,22 +16598,17 @@ prop-types@^15.0.0, prop-types@^15.5.10, prop-types@^15.6.0, prop-types@^15.6.1, object-assign "^4.1.1" react-is "^16.13.1" -property-information@^5.0.0, property-information@^5.3.0: +property-information@^5.0.0: version "5.6.0" resolved "https://registry.yarnpkg.com/property-information/-/property-information-5.6.0.tgz#61675545fb23002f245c6540ec46077d4da3ed69" integrity sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA== dependencies: xtend "^4.0.0" -property-information@^6.0.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/property-information/-/property-information-6.2.0.tgz#b74f522c31c097b5149e3c3cb8d7f3defd986a1d" - integrity sha512-kma4U7AFCTwpqq5twzC1YVIDXSqg6qQK6JN0smOw8fgRy1OkMi0CYSzFmsy6dnqSenamAtj0CyXMUJ1Mf6oROg== - -protobufjs@6.11.3, protobufjs@^6.10.2, protobufjs@^6.8.8, protobufjs@~6.11.2, protobufjs@~6.11.3: - version "6.11.3" - resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-6.11.3.tgz#637a527205a35caa4f3e2a9a4a13ddffe0e7af74" - integrity sha512-xL96WDdCZYdU7Slin569tFX712BxsxslWwAfAhCYjQKGTq7dAU91Lomy6nLLhh/dyGhk/YH4TwTSRxTzhuHyZg== +protobufjs@6.11.3, protobufjs@7.2.6, protobufjs@^6.10.2, protobufjs@^6.11.4, protobufjs@^6.8.8, protobufjs@~6.10.2, protobufjs@~6.11.2, protobufjs@~6.11.3: + version "6.11.4" + resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-6.11.4.tgz#29a412c38bf70d89e537b6d02d904a6f448173aa" + integrity sha512-5kQWPaJHi1WoCpjTGszzQ32PG2F4+wRY6BmAT4Vfw56Q2FZ4YZzK20xUYQH4YkfehY1e6QSICrJquM6xXZNcrw== dependencies: "@protobufjs/aspromise" "^1.1.2" "@protobufjs/base64" "^1.1.2" @@ -16740,34 +16624,6 @@ protobufjs@6.11.3, protobufjs@^6.10.2, protobufjs@^6.8.8, protobufjs@~6.11.2, pr "@types/node" ">=13.7.0" long "^4.0.0" -protobufjs@~6.10.2: - version "6.10.3" - resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-6.10.3.tgz#11ed1dd02acbfcb330becf1611461d4b407f9eef" - integrity sha512-yvAslS0hNdBhlSKckI4R1l7wunVilX66uvrjzE4MimiAt7/qw1nLpMhZrn/ObuUTM/c3Xnfl01LYMdcSJe6dwg== - dependencies: - "@protobufjs/aspromise" "^1.1.2" - "@protobufjs/base64" "^1.1.2" - "@protobufjs/codegen" "^2.0.4" - "@protobufjs/eventemitter" "^1.1.0" - "@protobufjs/fetch" "^1.1.0" - "@protobufjs/float" "^1.0.2" - "@protobufjs/inquire" "^1.1.0" - "@protobufjs/path" "^1.1.2" - "@protobufjs/pool" "^1.1.0" - "@protobufjs/utf8" "^1.1.0" - "@types/long" "^4.0.1" - "@types/node" "^13.7.0" - long "^4.0.0" - -protocol-buffers-encodings@^1.1.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/protocol-buffers-encodings/-/protocol-buffers-encodings-1.2.0.tgz#39900b85dcff3172a23f15bdf3fda70daa2b38d3" - integrity sha512-daeNPuKh1NlLD1uDfbLpD+xyUTc07nEtfHwmBZmt/vH0B7VOM+JOCOpDcx9ZRpqHjAiIkGqyTDi+wfGSl17R9w== - dependencies: - b4a "^1.6.0" - signed-varint "^2.0.1" - varint "5.0.0" - proxy-addr@~2.0.7: version "2.0.7" resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" @@ -16776,34 +16632,22 @@ proxy-addr@~2.0.7: forwarded "0.2.0" ipaddr.js "1.9.1" -proxy-agent@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/proxy-agent/-/proxy-agent-5.0.0.tgz#d31405c10d6e8431fde96cba7a0c027ce01d633b" - integrity sha512-gkH7BkvLVkSfX9Dk27W6TyNOWWZWRilRfk1XxGNWOYJ2TuedAv1yFpCaU9QSBmBe716XOTNpYNOzhysyw8xn7g== - dependencies: - agent-base "^6.0.0" - debug "4" - http-proxy-agent "^4.0.0" - https-proxy-agent "^5.0.0" - lru-cache "^5.1.1" - pac-proxy-agent "^5.0.0" - proxy-from-env "^1.0.0" - socks-proxy-agent "^5.0.0" +proxy-compare@2.5.1: + version "2.5.1" + resolved "https://registry.yarnpkg.com/proxy-compare/-/proxy-compare-2.5.1.tgz#17818e33d1653fbac8c2ec31406bce8a2966f600" + integrity sha512-oyfc0Tx87Cpwva5ZXezSp5V9vht1c7dZBhvuV/y3ctkgMVUmiAGDVeeB0dKhGSyT0v1ZTEQYpe/RXlBVBNuCLA== -proxy-from-env@^1.0.0, proxy-from-env@^1.1.0: +proxy-from-env@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== -prr@~1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" - integrity sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw== - -psl@^1.1.28: - version "1.9.0" - resolved "https://registry.yarnpkg.com/psl/-/psl-1.9.0.tgz#d0df2a137f00794565fcaf3b2c00cd09f8d5a5a7" - integrity sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag== +pseudolocale@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/pseudolocale/-/pseudolocale-2.0.0.tgz#4dbe725a6b5a6fb71aba8ba64ae2be71f5267316" + integrity sha512-g1K9tCQYY4e3UGtnW8qs3kGWAOONxt7i5wuOFvf3N1EIIRhiLVIhZ9AM/ZyGTxsp231JbFywJU/EbJ5ZoqnZdg== + dependencies: + commander "^10.0.0" public-encrypt@^4.0.0: version "4.0.3" @@ -16842,67 +16686,57 @@ pumpify@^1.3.3: inherits "^2.0.3" pump "^2.0.0" -pumpify@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-2.0.1.tgz#abfc7b5a621307c728b551decbbefb51f0e4aa1e" - integrity sha512-m7KOje7jZxrmutanlkS1daj1dS6z6BgslzOXmcSEpIlCxM3VJH7lG5QLeck/6hgF6F4crFf01UtQmNsJfweTAw== - dependencies: - duplexify "^4.1.1" - inherits "^2.0.3" - pump "^3.0.0" - -punycode@1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" - integrity sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw== - -punycode@^1.2.4, punycode@^1.4.1: +punycode@^1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" integrity sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ== -punycode@^2.1.0, punycode@^2.1.1: - version "2.3.0" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.0.tgz#f67fa67c94da8f4d0cfff981aee4118064199b8f" - integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA== +punycode@^2.1.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5" + integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg== + +pure-color@1.3.0, pure-color@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/pure-color/-/pure-color-1.3.0.tgz#1fe064fb0ac851f0de61320a8bf796836422f33e" + integrity sha512-QFADYnsVoBMw1srW7OVKEYjG+MbIa49s54w1MA1EDY6r2r/sTcKKYqRX1f4GYvnXP7eN/Pe9HFcX+hwzmrXRHA== + +pushdata-bitcoin@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/pushdata-bitcoin/-/pushdata-bitcoin-1.0.1.tgz#15931d3cd967ade52206f523aa7331aef7d43af7" + integrity sha512-hw7rcYTJRAl4olM8Owe8x0fBuJJ+WGbMhQuLWOXEMN3PxPCKQHRkhfL+XG0+iXUmSHjkMmb3Ba55Mt21cZc9kQ== + dependencies: + bitcoin-ops "^1.3.0" q@^1.5.1: version "1.5.1" resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" integrity sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw== -qrcode@1.4.4: - version "1.4.4" - resolved "https://registry.yarnpkg.com/qrcode/-/qrcode-1.4.4.tgz#f0c43568a7e7510a55efc3b88d9602f71963ea83" - integrity sha512-oLzEC5+NKFou9P0bMj5+v6Z40evexeE29Z9cummZXZ9QXyMr3lphkURzxjXgPJC5azpxcshoDWV1xE46z+/c3Q== +qrcode@1.5.3, qrcode@^1.5.0: + version "1.5.3" + resolved "https://registry.yarnpkg.com/qrcode/-/qrcode-1.5.3.tgz#03afa80912c0dccf12bc93f615a535aad1066170" + integrity sha512-puyri6ApkEHYiVl4CFzo1tDkAZ+ATcnbJrJ6RiBM1Fhctdn/ix9MTE3hRph33omisEbC/2fcfemsseiKgBPKZg== dependencies: - buffer "^5.4.3" - buffer-alloc "^1.2.0" - buffer-from "^1.1.1" dijkstrajs "^1.0.1" - isarray "^2.0.1" - pngjs "^3.3.0" - yargs "^13.2.4" + encode-utf8 "^1.0.3" + pngjs "^5.0.0" + yargs "^15.3.1" -qs@6.11.0: - version "6.11.0" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a" - integrity sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q== +qs@6.13.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.13.0.tgz#6ca3bd58439f7e245655798997787b0d88a51906" + integrity sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg== dependencies: - side-channel "^1.0.4" + side-channel "^1.0.6" -qs@^6.10.0, qs@^6.6.0: - version "6.11.1" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.1.tgz#6c29dff97f0c0060765911ba65cbc9764186109f" - integrity sha512-0wsrzgTz/kAVIeuxSjnpGC56rzYtr6JT/2BwEvMaPhFIoYa1aGO8LbzuU1R0uUYQkLpWBTOj0l/CLAJB64J6nQ== +qs@^6.10.0, qs@^6.11.2, qs@^6.6.0: + version "6.11.2" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.2.tgz#64bea51f12c1f5da1bc01496f48ffcff7c69d7d9" + integrity sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA== dependencies: side-channel "^1.0.4" -qs@~6.5.2: - version "6.5.3" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.3.tgz#3aeeffc91967ef6e35c0e488ef46fb296ab76aad" - integrity sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA== - query-string@6.13.5: version "6.13.5" resolved "https://registry.yarnpkg.com/query-string/-/query-string-6.13.5.tgz#99e95e2fb7021db90a6f373f990c0c814b3812d8" @@ -16912,35 +16746,50 @@ query-string@6.13.5: split-on-first "^1.0.0" strict-uri-encode "^2.0.0" -querystring-es3@^0.2.0: +query-string@7.1.3: + version "7.1.3" + resolved "https://registry.yarnpkg.com/query-string/-/query-string-7.1.3.tgz#a1cf90e994abb113a325804a972d98276fe02328" + integrity sha512-hh2WYhq4fi8+b+/2Kg9CEge4fDPvHS534aOOvOZeQ3+Vf2mCFsaFBYj0i+iXcAq6I9Vzp5fjMFBlONvayDC1qg== + dependencies: + decode-uri-component "^0.2.2" + filter-obj "^1.1.0" + split-on-first "^1.0.0" + strict-uri-encode "^2.0.0" + +querystring-es3@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" integrity sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA== -querystring@0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" - integrity sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g== - queue-microtask@^1.2.2: version "1.2.3" resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== +quick-format-unescaped@^4.0.3: + version "4.0.4" + resolved "https://registry.yarnpkg.com/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz#93ef6dd8d3453cbc7970dd614fad4c5954d6b5a7" + integrity sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg== + quick-lru@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-4.0.1.tgz#5b8878f113a58217848c6482026c73e1ba57727f" integrity sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g== -quick-lru@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932" - integrity sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA== +radix3@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/radix3/-/radix3-1.1.0.tgz#9745df67a49c522e94a33d0a93cf743f104b6e0d" + integrity sha512-pNsHDxbGORSvuSScqNJ+3Km6QAVqk8CfsCBIEoDgpqLrkD2f3QM4I7d1ozJJ172OmIcoUcerZaNWqtLkRXTV3A== -ramda@^0.28.0: - version "0.28.0" - resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.28.0.tgz#acd785690100337e8b063cab3470019be427cc97" - integrity sha512-9QnLuG/kPVgWvMQ4aODhsBUFKOUmnbUnsSXACv+NCQZcHbeb+v8Lodp8OVxtRULN1/xOyYLLaL6npE6dMq5QTA== +ramda@0.29.0: + version "0.29.0" + resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.29.0.tgz#fbbb67a740a754c8a4cbb41e2a6e0eb8507f55fb" + integrity sha512-BBea6L67bYLtdbOqfp8f58fPMqEwx0doL+pAi8TZyp2YWz8R9G8z9x75CZI8W+ftqhFHCpEX2cRnUUXK130iKA== + +ramda@^0.27.1: + version "0.27.2" + resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.27.2.tgz#84463226f7f36dc33592f6f4ed6374c48306c3f1" + integrity sha512-SbiLPU40JuJniHexQSAgad32hfwd+DRUdwF2PlVuI5RZD0/vahUco7R8vD86J/tcEKKF9vZrUVwgtmGCqlCKyA== randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5, randombytes@^2.1.0: version "2.1.0" @@ -16962,56 +16811,35 @@ range-parser@^1.2.1, range-parser@~1.2.1: resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== -rango-sdk-basic@^0.0.9: - version "0.0.9" - resolved "https://registry.yarnpkg.com/rango-sdk-basic/-/rango-sdk-basic-0.0.9.tgz#df7084aaf04b16e8a1f82dfe91e29b8b012d82e1" - integrity sha512-Qclq2+lxoEnlxC+5jMZxvgVLRcZhEA1qERjI1bwyqqL6PnBuh8vFYYJcoHGFSuQA7hObpxZ+3KWaX0TciI9naA== - dependencies: - axios "^0.24.0" - bignumber.js "^9.0.2" - uuid "^8.3.2" - -rango-sdk@^0.1.20: - version "0.1.20" - resolved "https://registry.yarnpkg.com/rango-sdk/-/rango-sdk-0.1.20.tgz#fad3cabef81f0c5586a06aab68479ca27ed2112f" - integrity sha512-YGTIvnML6pH6cSDHLdqcKU+2FhqWhnuDDJ7PGwGY1M4VqrbgZ2t8PnNf2TFwWNu5UqfP3xUPuIu5E6MOfEHc7Q== +rango-sdk-basic@^0.1.57: + version "0.1.57" + resolved "https://registry.yarnpkg.com/rango-sdk-basic/-/rango-sdk-basic-0.1.57.tgz#d20d28837efdfe7f2bf986a8a76a0c9edae99b97" + integrity sha512-YZNj+eY9uTgd4+upXPOE5yzHNbr5CdNkLP0pddi1GN70rQhs8SHUY3FLhFJGNgvZWAgikIWjIZ12T9L/Jsq0WQ== dependencies: - axios "^1.2.6" - bignumber.js "^9.1.1" - rango-types "^0.1.23" + axios "^1.7.4" + rango-types "^0.1.74" uuid-random "^1.3.2" -rango-sdk@^0.1.23: - version "0.1.23" - resolved "https://registry.yarnpkg.com/rango-sdk/-/rango-sdk-0.1.23.tgz#4f5d779bf4be08fe391b5848ecc82a2054c9033f" - integrity sha512-LJd9apkYyzxKlOk+XE/KnghcQxWROinaH+Bsl+tEoBpr9LDC3Szca5J4mTqbcC/fYtwQBrTDrB4tnFTUO2dfFw== +rango-sdk@^0.1.57: + version "0.1.57" + resolved "https://registry.yarnpkg.com/rango-sdk/-/rango-sdk-0.1.57.tgz#94b96120b9365086bafc7e398a192ee28d675dbf" + integrity sha512-Dz4GIUSSfImgmzTV0rnkZOvMr3ursreNluuKIa+JF3UR6Yj//x90/pcv5I0C7VDhsBIKoeJCBPIUesTwiwzbfA== dependencies: - axios "^1.2.6" - bignumber.js "^9.1.1" - rango-types "^0.1.28" + axios "^1.7.4" + rango-types "^0.1.74" uuid-random "^1.3.2" -rango-types@^0.1.23: - version "0.1.23" - resolved "https://registry.yarnpkg.com/rango-types/-/rango-types-0.1.23.tgz#3b3ad12fba7120838deb1b016ad16754da13deec" - integrity sha512-Q2E/17IOCMULYvF0siey87Qjlx7r4VGZeHrPxraHmI0RXbVqB+p2G7t3nTEZT8ex2VChRu8SAQCRhgYAr/5K7A== +rango-types@^0.1.74: + version "0.1.74" + resolved "https://registry.yarnpkg.com/rango-types/-/rango-types-0.1.74.tgz#a6049242ce60f5d84d638c70650735529979a8dd" + integrity sha512-sMWGAxNF2Yv/PG3eTL01FoHEVf40VEypt1VqPP0HkIwo+gR8WGhEL3JFkAo0UE3gJ7rjgwmMLziAMu1zwwJ+ng== -rango-types@^0.1.28: - version "0.1.28" - resolved "https://registry.yarnpkg.com/rango-types/-/rango-types-0.1.28.tgz#931ddf57e38115fab6f85cb5f6bacb3fb46c20eb" - integrity sha512-pZtblD2JvH6nB26TKW/6ySTwVlxYRJksMC6UIDfpmpn/6g/LHf3RxAGkrltC1wzdmGP1QxAUWOeq4JJv2lAFtQ== +rango-types@^0.1.75: + version "0.1.75" + resolved "https://registry.yarnpkg.com/rango-types/-/rango-types-0.1.75.tgz#24d2a3a30e113a7bf1088853e89b39b5722e9c04" + integrity sha512-Xb/lfV+fXEQdk6APY77C0oKl++mqdDdwlRyfVi10tV5tfw0Yvl5+p8Av16oPqBcM20WJGjBFCUpHEAKsEprXNQ== -raw-body@2.5.1: - version "2.5.1" - resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.1.tgz#fe1b1628b181b700215e5fd42389f98b71392857" - integrity sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig== - dependencies: - bytes "3.1.2" - http-errors "2.0.0" - iconv-lite "0.4.24" - unpipe "1.0.0" - -raw-body@^2.2.0: +raw-body@2.5.2: version "2.5.2" resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.2.tgz#99febd83b90e08975087e8f1f9419a149366b68a" integrity sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA== @@ -17021,24 +16849,6 @@ raw-body@^2.2.0: iconv-lite "0.4.24" unpipe "1.0.0" -raw-loader@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/raw-loader/-/raw-loader-4.0.2.tgz#1aac6b7d1ad1501e66efdac1522c73e59a584eb6" - integrity sha512-ZnScIV3ag9A4wPX/ZayxL/jZH+euYb6FcUinPcgiQW0+UBtEv0O6Q3lGd3cqJ+GHH+rksEv3Pj99oxJ3u3VIKA== - dependencies: - loader-utils "^2.0.0" - schema-utils "^3.0.0" - -rc@^1.2.7: - version "1.2.8" - resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" - integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== - dependencies: - deep-extend "^0.6.0" - ini "~1.3.0" - minimist "^1.2.0" - strip-json-comments "~2.0.1" - react-addons-create-fragment@^15.6.2: version "15.6.2" resolved "https://registry.yarnpkg.com/react-addons-create-fragment/-/react-addons-create-fragment-15.6.2.tgz#a394de7c2c7becd6b5475ba1b97ac472ce7c74f8" @@ -17068,26 +16878,46 @@ react-color@^2.19.3: reactcss "^1.2.0" tinycolor2 "^1.4.1" -react-docgen-typescript@^2.1.1: +react-colorful@^5.1.2: + version "5.6.1" + resolved "https://registry.yarnpkg.com/react-colorful/-/react-colorful-5.6.1.tgz#7dc2aed2d7c72fac89694e834d179e32f3da563b" + integrity sha512-1exovf0uGTGyq5mXQT0zgQ80uvj2PCwvF8zY1RN9/vbJVSjSo3fsB/4L3ObbF7u70NduSiK4xu4Y6q1MHoUGEw== + +react-confetti@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/react-confetti/-/react-confetti-6.1.0.tgz#03dc4340d955acd10b174dbf301f374a06e29ce6" + integrity sha512-7Ypx4vz0+g8ECVxr88W9zhcQpbeujJAVqL14ZnXJ3I23mOI9/oBVTQ3dkJhUmB0D6XOtCZEM6N0Gm9PMngkORw== + dependencies: + tween-functions "^1.2.0" + +react-docgen-typescript@^2.2.2: version "2.2.2" resolved "https://registry.yarnpkg.com/react-docgen-typescript/-/react-docgen-typescript-2.2.2.tgz#4611055e569edc071204aadb20e1c93e1ab1659c" integrity sha512-tvg2ZtOpOi6QDwsb3GZhOjDkkX0h8Z2gipvTg6OVMUyoYoURhEiRNePT8NZItTVCDh39JJHnLdfCOkzoLbFnTg== -react-docgen@^5.0.0: - version "5.4.3" - resolved "https://registry.yarnpkg.com/react-docgen/-/react-docgen-5.4.3.tgz#7d297f73b977d0c7611402e5fc2a168acf332b26" - integrity sha512-xlLJyOlnfr8lLEEeaDZ+X2J/KJoe6Nr9AzxnkdQWush5hz2ZSu66w6iLMOScMmxoSHWpWMn+k3v5ZiyCfcWsOA== - dependencies: - "@babel/core" "^7.7.5" - "@babel/generator" "^7.12.11" - "@babel/runtime" "^7.7.6" - ast-types "^0.14.2" - commander "^2.19.0" +react-docgen@^7.0.0: + version "7.0.3" + resolved "https://registry.yarnpkg.com/react-docgen/-/react-docgen-7.0.3.tgz#f811b785f07b1f2023cb899b6bcf9d522b21b95d" + integrity sha512-i8aF1nyKInZnANZ4uZrH49qn1paRgBZ7wZiCNBMnenlPzEv0mRl+ShpTVEI6wZNl8sSc79xZkivtgLKQArcanQ== + dependencies: + "@babel/core" "^7.18.9" + "@babel/traverse" "^7.18.9" + "@babel/types" "^7.18.9" + "@types/babel__core" "^7.18.0" + "@types/babel__traverse" "^7.18.0" + "@types/doctrine" "^0.0.9" + "@types/resolve" "^1.20.2" doctrine "^3.0.0" - estree-to-babel "^3.1.0" - neo-async "^2.6.1" - node-dir "^0.1.10" - strip-indent "^3.0.0" + resolve "^1.22.1" + strip-indent "^4.0.0" + +"react-dom@^16.8.0 || ^17.0.0 || ^18.0.0", react-dom@^18.2.0: + version "18.2.0" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.2.0.tgz#22aaf38708db2674ed9ada224ca4aa708d821e3d" + integrity sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g== + dependencies: + loose-envify "^1.1.0" + scheduler "^0.23.0" react-dom@^16.8.3: version "16.14.0" @@ -17099,15 +16929,7 @@ react-dom@^16.8.3: prop-types "^15.6.2" scheduler "^0.19.1" -react-dom@^18.2.0: - version "18.2.0" - resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.2.0.tgz#22aaf38708db2674ed9ada224ca4aa708d821e3d" - integrity sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g== - dependencies: - loose-envify "^1.1.0" - scheduler "^0.23.0" - -react-element-to-jsx-string@^14.0.2, react-element-to-jsx-string@^14.3.4: +react-element-to-jsx-string@^14.0.2: version "14.3.4" resolved "https://registry.yarnpkg.com/react-element-to-jsx-string/-/react-element-to-jsx-string-14.3.4.tgz#709125bc72f06800b68f9f4db485f2c7d31218a8" integrity sha512-t4ZwvV6vwNxzujDQ+37bspnLwA4JlgUPWhLjBJWsNIDceAf6ZKUTCjdm08cN6WeZ5pTMKiCJkmAYnpmR4Bm+dg== @@ -17116,23 +16938,39 @@ react-element-to-jsx-string@^14.0.2, react-element-to-jsx-string@^14.3.4: is-plain-object "5.0.0" react-is "17.0.2" +react-element-to-jsx-string@^15.0.0: + version "15.0.0" + resolved "https://registry.yarnpkg.com/react-element-to-jsx-string/-/react-element-to-jsx-string-15.0.0.tgz#1cafd5b6ad41946ffc8755e254da3fc752a01ac6" + integrity sha512-UDg4lXB6BzlobN60P8fHWVPX3Kyw8ORrTeBtClmIlGdkOOE+GYQSFvmEU5iLLpwp/6v42DINwNcwOhOLfQ//FQ== + dependencies: + "@base2/pretty-print-object" "1.0.1" + is-plain-object "5.0.0" + react-is "18.1.0" + +react-error-boundary@^3.1.0: + version "3.1.4" + resolved "https://registry.yarnpkg.com/react-error-boundary/-/react-error-boundary-3.1.4.tgz#255db92b23197108757a888b01e5b729919abde0" + integrity sha512-uM9uPzZJTF6wRQORmSrvOIgt4lJ9MC1sNgEOj2XGsDTRE4kmpWxg7ENK9EWNKJRMAOY9z0MuF4yIfl6gp4sotA== + dependencies: + "@babel/runtime" "^7.12.5" + react-error-overlay@6.0.9: version "6.0.9" resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-6.0.9.tgz#3c743010c9359608c375ecd6bc76f35d93995b0a" integrity sha512-nQTTcUu+ATDbrSD1BZHr5kgSD4oF8OFjxun8uAaL8RwPBacGBNPf/yAuVVdx17N8XNzRDMrZ9XcKZHCjPW+9ew== react-fast-compare@^3.2.0: - version "3.2.1" - resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-3.2.1.tgz#53933d9e14f364281d6cba24bfed7a4afb808b5f" - integrity sha512-xTYf9zFim2pEif/Fw16dBiXpe0hoy5PxcD8+OwBnTtNLfIm3g6WxhKNurY+6OmdH1u6Ta/W/Vl6vjbYP1MFnDg== + version "3.2.2" + resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-3.2.2.tgz#929a97a532304ce9fee4bcae44234f1ce2c21d49" + integrity sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ== react-focus-lock@^2.1.0: - version "2.9.4" - resolved "https://registry.yarnpkg.com/react-focus-lock/-/react-focus-lock-2.9.4.tgz#4753f6dcd167c39050c9d84f9c63c71b3ff8462e" - integrity sha512-7pEdXyMseqm3kVjhdVH18sovparAzLg5h6WvIx7/Ck3ekjhrrDMEegHSa3swwC8wgfdd7DIdUVRGeiHT9/7Sgg== + version "2.9.6" + resolved "https://registry.yarnpkg.com/react-focus-lock/-/react-focus-lock-2.9.6.tgz#cad168a150fdd72d5ab2419ba8e62780788011b1" + integrity sha512-B7gYnCjHNrNYwY2juS71dHbf0+UpXXojt02svxybj8N5bxceAkzPChKEncHuratjUHkIFNCn06k2qj1DRlzTug== dependencies: "@babel/runtime" "^7.0.0" - focus-lock "^0.11.6" + focus-lock "^1.0.0" prop-types "^15.6.2" react-clientside-effect "^1.2.6" use-callback-ref "^1.3.0" @@ -17150,33 +16988,34 @@ react-helmet-async@^1.0.2: shallowequal "^1.1.0" react-i18next@^12.2.0: - version "12.2.0" - resolved "https://registry.yarnpkg.com/react-i18next/-/react-i18next-12.2.0.tgz#010e3f6070b8d700442947233352ebe4b252d7a1" - integrity sha512-5XeVgSygaGfyFmDd2WcXvINRw2WEC1XviW1LXY/xLOEMzsCFRwKqfnHN+hUjla8ZipbVJR27GCMSuTr0BhBBBQ== + version "12.3.1" + resolved "https://registry.yarnpkg.com/react-i18next/-/react-i18next-12.3.1.tgz#30134a41a2a71c61dc69c6383504929aed1c99e7" + integrity sha512-5v8E2XjZDFzK7K87eSwC7AJcAkcLt5xYZ4+yTPDAW1i7C93oOY1dnr4BaQM7un4Hm+GmghuiPvevWwlca5PwDA== dependencies: "@babel/runtime" "^7.20.6" html-parse-stringify "^3.0.1" -react-inspector@^5.1.0: - version "5.1.1" - resolved "https://registry.yarnpkg.com/react-inspector/-/react-inspector-5.1.1.tgz#58476c78fde05d5055646ed8ec02030af42953c8" - integrity sha512-GURDaYzoLbW8pMGXwYPDBIv6nqei4kK7LPRZ9q9HCZF54wqXz/dnylBp/kfE9XmekBhHvLDdcYeyIwSrvtOiWg== - dependencies: - "@babel/runtime" "^7.0.0" - is-dom "^1.0.0" - prop-types "^15.0.0" - -react-is@17.0.2: +react-is@17.0.2, react-is@^17.0.1: version "17.0.2" resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== -react-is@^16.12.0, react-is@^16.13.1, react-is@^16.7.0, react-is@^16.8.3: +react-is@18.1.0: + version "18.1.0" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.1.0.tgz#61aaed3096d30eacf2a2127118b5b41387d32a67" + integrity sha512-Fl7FuabXsJnV5Q1qIOQwx/sagGF18kogb4gpfcG4gjLBWO0WDiiz1ko/ExayuxE7InyQkBLkxRFG5oxY6Uu3Kg== + +"react-is@^16.12.0 || ^17.0.0 || ^18.0.0", react-is@^18.3.1: + version "18.3.1" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.3.1.tgz#e83557dc12eae63a99e003a46388b1dcbb44db7e" + integrity sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg== + +react-is@^16.13.1, react-is@^16.7.0, react-is@^16.8.3: version "16.13.1" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== -react-is@^18.2.0: +react-is@^18.0.0, react-is@^18.2.0: version "18.2.0" resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b" integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w== @@ -17207,35 +17046,61 @@ react-popper@^1.3.7: typed-styles "^0.0.7" warning "^4.0.2" -react-refresh@^0.11.0: - version "0.11.0" - resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.11.0.tgz#77198b944733f0f1f1a90e791de4541f9f074046" - integrity sha512-F27qZr8uUqwhWZboondsPx8tnC3Ct3SxZA3V5WyEvujRyyNv0VYPhoBg1gZ8/MV5tubQp76Trw8lTv9hzRBa+A== +react-refresh@0.9.0, react-refresh@^0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.9.0.tgz#71863337adc3e5c2f8a6bfddd12ae3bfe32aafbf" + integrity sha512-Gvzk7OZpiqKSkxsQvO/mbTN1poglhmAV7gR/DdIrRrSMXraRQQlfikRJOr3Nb9GTMPC5kof948Zy6jJZIFtDvQ== + +react-remove-scroll-bar@^2.3.3: + version "2.3.4" + resolved "https://registry.yarnpkg.com/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.4.tgz#53e272d7a5cb8242990c7f144c44d8bd8ab5afd9" + integrity sha512-63C4YQBUt0m6ALadE9XV56hV8BgJWDmmTPY758iIJjfQKt2nYwoUrPk0LXRXcB/yIj82T1/Ixfdpdk68LwIB0A== + dependencies: + react-style-singleton "^2.2.1" + tslib "^2.0.0" + +react-remove-scroll@2.5.5: + version "2.5.5" + resolved "https://registry.yarnpkg.com/react-remove-scroll/-/react-remove-scroll-2.5.5.tgz#1e31a1260df08887a8a0e46d09271b52b3a37e77" + integrity sha512-ImKhrzJJsyXJfBZ4bzu8Bwpka14c/fQt0k+cyFp/PBhTfyDnU5hjOtM4AG/0AMyy8oKzOTR0lDgJIM7pYXI0kw== + dependencies: + react-remove-scroll-bar "^2.3.3" + react-style-singleton "^2.2.1" + tslib "^2.1.0" + use-callback-ref "^1.3.0" + use-sidecar "^1.1.2" -react-refresh@^0.14.0: - version "0.14.0" - resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.14.0.tgz#4e02825378a5f227079554d4284889354e5f553e" - integrity sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ== +react-router-dom@^6.10.0, react-router-dom@^6.8.0: + version "6.20.0" + resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-6.20.0.tgz#7b9527a1e29c7fb90736a5f89d54ca01f40e264b" + integrity sha512-CbcKjEyiSVpA6UtCHOIYLUYn/UJfwzp55va4yEfpk7JBN3GPqWfHrdLkAvNCcpXr8QoihcDMuk0dzWZxtlB/mQ== + dependencies: + "@remix-run/router" "1.13.0" + react-router "6.20.0" -react-refresh@^0.9.0: - version "0.9.0" - resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.9.0.tgz#71863337adc3e5c2f8a6bfddd12ae3bfe32aafbf" - integrity sha512-Gvzk7OZpiqKSkxsQvO/mbTN1poglhmAV7gR/DdIrRrSMXraRQQlfikRJOr3Nb9GTMPC5kof948Zy6jJZIFtDvQ== +react-router@6.20.0: + version "6.20.0" + resolved "https://registry.yarnpkg.com/react-router/-/react-router-6.20.0.tgz#4275a3567ecc55f7703073158048db10096bb539" + integrity sha512-pVvzsSsgUxxtuNfTHC4IxjATs10UaAtvLGVSA1tbUE4GDaOSU1Esu2xF5nWLz7KPiMuW8BJWuPFdlGYJ7/rW0w== + dependencies: + "@remix-run/router" "1.13.0" -react-router-dom@^6.8.0: - version "6.10.0" - resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-6.10.0.tgz#090ddc5c84dc41b583ce08468c4007c84245f61f" - integrity sha512-E5dfxRPuXKJqzwSe/qGcqdwa18QiWC6f3H3cWXM24qj4N0/beCIf/CWTipop2xm7mR0RCS99NnaqPNjHtrAzCg== +react-shallow-renderer@^16.15.0: + version "16.15.0" + resolved "https://registry.yarnpkg.com/react-shallow-renderer/-/react-shallow-renderer-16.15.0.tgz#48fb2cf9b23d23cde96708fe5273a7d3446f4457" + integrity sha512-oScf2FqQ9LFVQgA73vr86xl2NaOIX73rh+YFqcOp68CWj56tSfgtGKrEbyhCj0rSijyG9M1CYprTh39fBi5hzA== dependencies: - "@remix-run/router" "1.5.0" - react-router "6.10.0" + object-assign "^4.1.1" + react-is "^16.12.0 || ^17.0.0 || ^18.0.0" -react-router@6.10.0: - version "6.10.0" - resolved "https://registry.yarnpkg.com/react-router/-/react-router-6.10.0.tgz#230f824fde9dd0270781b5cb497912de32c0a971" - integrity sha512-Nrg0BWpQqrC3ZFFkyewrflCud9dio9ME3ojHCF/WLsprJVzkq3q3UeEhMCAW1dobjeGbWgjNn/PVF6m46ANxXQ== +react-style-singleton@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/react-style-singleton/-/react-style-singleton-2.2.1.tgz#f99e420492b2d8f34d38308ff660b60d0b1205b4" + integrity sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g== dependencies: - "@remix-run/router" "1.5.0" + get-nonce "^1.0.0" + invariant "^2.2.4" + tslib "^2.0.0" react-syntax-highlighter@^11.0.2: version "11.0.3" @@ -17248,6 +17113,26 @@ react-syntax-highlighter@^11.0.2: prismjs "^1.8.4" refractor "^2.4.1" +react-syntax-highlighter@^15.5.0: + version "15.5.0" + resolved "https://registry.yarnpkg.com/react-syntax-highlighter/-/react-syntax-highlighter-15.5.0.tgz#4b3eccc2325fa2ec8eff1e2d6c18fa4a9e07ab20" + integrity sha512-+zq2myprEnQmH5yw6Gqc8lD55QHnpKaU8TOcFeC/Lg/MQSs8UknEA0JC4nTZGFAXC2J2Hyj/ijJ7NlabyPi2gg== + dependencies: + "@babel/runtime" "^7.3.1" + highlight.js "^10.4.1" + lowlight "^1.17.0" + prismjs "^1.27.0" + refractor "^3.6.0" + +react-test-renderer@^18.3.1: + version "18.3.1" + resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-18.3.1.tgz#e693608a1f96283400d4a3afead6893f958b80b4" + integrity sha512-KkAgygexHUkQqtvvx/otwxtuFu5cVjfzTCtjXLH9boS19/Nbtg84zS7wIQn39G8IlrhThBpQsMKkq5ZHZIYFXA== + dependencies: + react-is "^18.3.1" + react-shallow-renderer "^16.15.0" + scheduler "^0.23.2" + react-textarea-autosize@^7.1.0: version "7.1.2" resolved "https://registry.yarnpkg.com/react-textarea-autosize/-/react-textarea-autosize-7.1.2.tgz#70fdb333ef86bcca72717e25e623e90c336e2cda" @@ -17256,23 +17141,24 @@ react-textarea-autosize@^7.1.0: "@babel/runtime" "^7.1.2" prop-types "^15.6.0" -react-virtualized-auto-sizer@^1.0.7: - version "1.0.11" - resolved "https://registry.yarnpkg.com/react-virtualized-auto-sizer/-/react-virtualized-auto-sizer-1.0.11.tgz#2ec880161c91327531f56b218d067736fd4ae3fe" - integrity sha512-v2YlC4KCnjEF7V5KtxrHCy50vPhbL73BS1qNOXFYaaE1XGeRqZHrGP+F4BE0QDv2pP+f1t9twL1n5pRp5GPMkQ== +react-use-measure@^2.0.4: + version "2.1.1" + resolved "https://registry.yarnpkg.com/react-use-measure/-/react-use-measure-2.1.1.tgz#5824537f4ee01c9469c45d5f7a8446177c6cc4ba" + integrity sha512-nocZhN26cproIiIduswYpV5y5lQpSQS1y/4KuvUCjSKmw7ZWIS/+g3aFnX3WdBkyuGUtTLif3UTqnLLhbDoQig== + dependencies: + debounce "^1.2.1" -react-window-infinite-loader@^1.0.8: - version "1.0.8" - resolved "https://registry.yarnpkg.com/react-window-infinite-loader/-/react-window-infinite-loader-1.0.8.tgz#f88b1444829e732a3f4c5ae861644815329ddd88" - integrity sha512-907ZLAiZZfBHuZyiY0V7uiSL4P/rI6UQyCF9wES1cDWTeyNLgGLaxu+BZkcUW3R5tSCQcbCcWBl0jVIpYzrKGQ== +react-virtuoso@^4.6.2: + version "4.6.2" + resolved "https://registry.yarnpkg.com/react-virtuoso/-/react-virtuoso-4.6.2.tgz#74b59ebe3260e1f73e92340ffec84a6853285a12" + integrity sha512-vvlqvzPif+MvBrJ09+hJJrVY0xJK9yran+A+/1iwY78k0YCVKsyoNPqoLxOxzYPggspNBNXqUXEcvckN29OxyQ== -react-window@^1.8.8: - version "1.8.8" - resolved "https://registry.yarnpkg.com/react-window/-/react-window-1.8.8.tgz#1b52919f009ddf91970cbdb2050a6c7be44df243" - integrity sha512-D4IiBeRtGXziZ1n0XklnFGu7h9gU684zepqyKzgPNzrsrk7xOCxni+TCckjg2Nr/DiaEEGVVmnhYSlT2rB47dQ== +"react@^16.8.0 || ^17.0.0 || ^18.0.0", react@^18.2.0: + version "18.2.0" + resolved "https://registry.yarnpkg.com/react/-/react-18.2.0.tgz#555bd98592883255fa00de14f1151a917b5d77d5" + integrity sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ== dependencies: - "@babel/runtime" "^7.0.0" - memoize-one ">=3.1.1 <6" + loose-envify "^1.1.0" react@^16.8.3: version "16.14.0" @@ -17283,13 +17169,6 @@ react@^16.8.3: object-assign "^4.1.1" prop-types "^15.6.2" -react@^18.2.0: - version "18.2.0" - resolved "https://registry.yarnpkg.com/react/-/react-18.2.0.tgz#555bd98592883255fa00de14f1151a917b5d77d5" - integrity sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ== - dependencies: - loose-envify "^1.1.0" - reactcss@^1.2.0: version "1.2.3" resolved "https://registry.yarnpkg.com/reactcss/-/reactcss-1.2.3.tgz#c00013875e557b1cf0dfd9a368a1c3dab3b548dd" @@ -17297,13 +17176,13 @@ reactcss@^1.2.0: dependencies: lodash "^4.0.1" -read-pkg-up@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" - integrity sha512-WD9MTlNtI55IwYUS27iHh9tK3YoIVhxis8yKhLpTqWtml739uXc9NWTpxoHkfZf3+DkCCsXox94/VWZniuZm6A== +read-pkg-up@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-3.0.0.tgz#3ed496685dba0f8fe118d0691dc51f4a1ff96f07" + integrity sha512-YFzFrVvpC6frF1sz8psoHDBGF7fLPc+llq/8NB43oagqWkx8ar5zYtsTORtOjw9W2RHLpWP+zTWwBvf1bCmcSw== dependencies: - find-up "^1.0.0" - read-pkg "^1.0.0" + find-up "^2.0.0" + read-pkg "^3.0.0" read-pkg-up@^7.0.1: version "7.0.1" @@ -17314,15 +17193,6 @@ read-pkg-up@^7.0.1: read-pkg "^5.2.0" type-fest "^0.8.1" -read-pkg@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" - integrity sha512-7BGwRHqt4s/uVbuyoeejRn4YmFnYZiFl4AuaeXHlgZf3sONF0SOGlxs2Pw8g6hCKupo08RafIO5YXFNOKTfwsQ== - dependencies: - load-json-file "^1.0.0" - normalize-package-data "^2.3.2" - path-type "^1.0.0" - read-pkg@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389" @@ -17342,7 +17212,16 @@ read-pkg@^5.2.0: parse-json "^5.0.0" type-fest "^0.6.0" -"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.6, readable-stream@~2.3.6: +readable-stream@3, readable-stream@^3.0.0, readable-stream@^3.0.2, readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.5.0, readable-stream@^3.6.0, readable-stream@^3.6.2: + version "3.6.2" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" + integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + +readable-stream@^2.0.0, readable-stream@~2.3.6: version "2.3.8" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b" integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA== @@ -17355,33 +17234,12 @@ read-pkg@^5.2.0: string_decoder "~1.1.1" util-deprecate "~1.0.1" -readable-stream@1.1.x: - version "1.1.14" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" - integrity sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ== - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.1" - isarray "0.0.1" - string_decoder "~0.10.x" - -readable-stream@3, readable-stream@^3.0.0, readable-stream@^3.0.2, readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.5.0, readable-stream@^3.6.0: - version "3.6.2" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" - integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== - dependencies: - inherits "^2.0.3" - string_decoder "^1.1.1" - util-deprecate "^1.0.1" - -readdirp@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" - integrity sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ== +readdirp@~3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.5.0.tgz#9ba74c019b15d365278d2e91bb8c48d7b4d42c9e" + integrity sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ== dependencies: - graceful-fs "^4.1.11" - micromatch "^3.1.10" - readable-stream "^2.0.2" + picomatch "^2.2.1" readdirp@~3.6.0: version "3.6.0" @@ -17395,36 +17253,22 @@ readonly-date@^1.0.0: resolved "https://registry.yarnpkg.com/readonly-date/-/readonly-date-1.0.0.tgz#5af785464d8c7d7c40b9d738cbde8c646f97dcd9" integrity sha512-tMKIV7hlk0h4mO3JTmmVuIlJVXjKk3Sep9Bf5OH0O+758ruuVkUy2J9SttDLm91IEX/WHlXPSpxMGjPj4beMIQ== -realpath-native@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/realpath-native/-/realpath-native-2.0.0.tgz#7377ac429b6e1fd599dc38d08ed942d0d7beb866" - integrity sha512-v1SEYUOXXdbBZK8ZuNgO4TBjamPsiSgcFr0aP+tEKpQZK8vooEUqV6nm6Cv502mX4NF2EfsnVqtNAHG+/6Ur1Q== +real-require@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/real-require/-/real-require-0.1.0.tgz#736ac214caa20632847b7ca8c1056a0767df9381" + integrity sha512-r/H9MzAWtrv8aSVjPCMFpDMl5q66GqtmmRkRjpHTsp4zBAa+snZyiQNlMONiUmEJcsnaw0wCauJ2GWODr/aFkg== -recast@^0.21.5: - version "0.21.5" - resolved "https://registry.yarnpkg.com/recast/-/recast-0.21.5.tgz#e8cd22bb51bcd6130e54f87955d33a2b2e57b495" - integrity sha512-hjMmLaUXAm1hIuTqOdeYObMslq/q+Xff6QE3Y2P+uoHAg2nmVlLBps2hzh1UJDdMtDTMXOFewK6ky51JQIeECg== +recast@^0.23.3, recast@^0.23.5: + version "0.23.6" + resolved "https://registry.yarnpkg.com/recast/-/recast-0.23.6.tgz#198fba74f66143a30acc81929302d214ce4e3bfa" + integrity sha512-9FHoNjX1yjuesMwuthAmPKabxYQdOgihFYmT5ebXfYGBcnqXZf3WOVz+5foEZ8Y83P4ZY6yQD5GMmtV+pgCCAQ== dependencies: - ast-types "0.15.2" + ast-types "^0.16.1" esprima "~4.0.0" source-map "~0.6.1" + tiny-invariant "^1.3.3" tslib "^2.0.1" -rechoir@^0.6.2: - version "0.6.2" - resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" - integrity sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw== - dependencies: - resolve "^1.1.6" - -redent@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/redent/-/redent-1.0.0.tgz#cf916ab1fd5f1f16dfb20822dd6ec7f730c2afde" - integrity sha512-qtW5hKzGQZqKoh6JNSD+4lfitfPKGz42e6QwiRmPM5mmKtR0N41AbJRYu0xJi7nhOJ4WDgRkKvAk6tw4WIwR4g== - dependencies: - indent-string "^2.1.0" - strip-indent "^1.0.1" - redent@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/redent/-/redent-3.0.0.tgz#e557b7998316bb53c9f1f56fa626352c6963059f" @@ -17433,6 +17277,46 @@ redent@^3.0.0: indent-string "^4.0.0" strip-indent "^3.0.0" +redis-errors@^1.0.0, redis-errors@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/redis-errors/-/redis-errors-1.2.0.tgz#eb62d2adb15e4eaf4610c04afe1529384250abad" + integrity sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w== + +redis-parser@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/redis-parser/-/redis-parser-3.0.0.tgz#b66d828cdcafe6b4b8a428a7def4c6bcac31c8b4" + integrity sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A== + dependencies: + redis-errors "^1.0.0" + +reduce-css-calc@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/reduce-css-calc/-/reduce-css-calc-1.3.0.tgz#747c914e049614a4c9cfbba629871ad1d2927716" + integrity sha512-0dVfwYVOlf/LBA2ec4OwQ6p3X9mYxn/wOl2xTcLwjnPYrkgEfPx3VI4eGCH3rQLlPISG5v9I9bkZosKsNRTRKA== + dependencies: + balanced-match "^0.4.2" + math-expression-evaluator "^1.2.14" + reduce-function-call "^1.0.1" + +reduce-function-call@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/reduce-function-call/-/reduce-function-call-1.0.3.tgz#60350f7fb252c0a67eb10fd4694d16909971300f" + integrity sha512-Hl/tuV2VDgWgCSEeWMLwxLZqX7OK59eU1guxXsRKTAyeYimivsKdtcV4fu3r710tpG5GmDKDhQ0HSZLExnNmyQ== + dependencies: + balanced-match "^1.0.0" + +reflect.getprototypeof@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/reflect.getprototypeof/-/reflect.getprototypeof-1.0.4.tgz#aaccbf41aca3821b87bb71d9dcbc7ad0ba50a3f3" + integrity sha512-ECkTw8TmJwW60lOTR+ZkODISW6RQ8+2CL3COqtiJKLd6MmB45hN51HprHFziKLGkAuTGQhBb91V8cy+KHlaCjw== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + get-intrinsic "^1.2.1" + globalthis "^1.0.3" + which-builtin-type "^1.1.3" + refractor@^2.4.1: version "2.10.1" resolved "https://registry.yarnpkg.com/refractor/-/refractor-2.10.1.tgz#166c32f114ed16fd96190ad21d5193d3afc7d34e" @@ -17442,10 +17326,19 @@ refractor@^2.4.1: parse-entities "^1.1.2" prismjs "~1.17.0" +refractor@^3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/refractor/-/refractor-3.6.0.tgz#ac318f5a0715ead790fcfb0c71f4dd83d977935a" + integrity sha512-MY9W41IOWxxk31o+YvFCNyNzdkc9M20NoZK5vq6jkv4I/uh2zkWcfudj0Q1fovjUQJrNewS9NMzeTtqPf+n5EA== + dependencies: + hastscript "^6.0.0" + parse-entities "^2.0.0" + prismjs "~1.27.0" + regenerate-unicode-properties@^10.1.0: - version "10.1.0" - resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz#7c3192cab6dd24e21cb4461e5ddd7dd24fa8374c" - integrity sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ== + version "10.1.1" + resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.1.tgz#6b0e05489d9076b04c436f318d9b067bba459480" + integrity sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q== dependencies: regenerate "^1.4.2" @@ -17454,44 +17347,31 @@ regenerate@^1.4.2: resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a" integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A== -regenerator-runtime@^0.13.11, regenerator-runtime@^0.13.4, regenerator-runtime@^0.13.7: +regenerator-runtime@^0.13.7: version "0.13.11" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9" integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg== -regenerator-transform@^0.15.1: - version "0.15.1" - resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.15.1.tgz#f6c4e99fc1b4591f780db2586328e4d9a9d8dc56" - integrity sha512-knzmNAcuyxV+gQCufkYcvOqX/qIIfHLv0u5x79kRxuGojfYVky1f15TzZEu2Avte8QGepvUNTnLskf8E6X6Vyg== - dependencies: - "@babel/runtime" "^7.8.4" +regenerator-runtime@^0.14.0: + version "0.14.0" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz#5e19d68eb12d486f797e15a3c6a918f7cec5eb45" + integrity sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA== -regex-not@^1.0.0, regex-not@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" - integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A== +regenerator-transform@^0.15.2: + version "0.15.2" + resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.15.2.tgz#5bbae58b522098ebdf09bca2f83838929001c7a4" + integrity sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg== dependencies: - extend-shallow "^3.0.2" - safe-regex "^1.1.0" + "@babel/runtime" "^7.8.4" -regexp.prototype.flags@^1.2.0, regexp.prototype.flags@^1.4.3: - version "1.4.3" - resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz#87cab30f80f66660181a3bb7bf5981a872b367ac" - integrity sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA== +regexp.prototype.flags@^1.5.0, regexp.prototype.flags@^1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.5.1.tgz#90ce989138db209f81492edd734183ce99f9677e" + integrity sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg== dependencies: call-bind "^1.0.2" - define-properties "^1.1.3" - functions-have-names "^1.2.2" - -regexpp@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f" - integrity sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw== - -regexpp@^3.0.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" - integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== + define-properties "^1.2.0" + set-function-name "^2.0.0" regexpu-core@^5.3.1: version "5.3.2" @@ -17512,192 +17392,44 @@ regjsparser@^0.9.1: dependencies: jsesc "~0.5.0" -relateurl@^0.2.7: - version "0.2.7" - resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9" - integrity sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog== - -remark-external-links@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/remark-external-links/-/remark-external-links-8.0.0.tgz#308de69482958b5d1cd3692bc9b725ce0240f345" - integrity sha512-5vPSX0kHoSsqtdftSHhIYofVINC8qmp0nctkeU9YoJwV3YfiBRiI6cbFRJ0oI/1F9xS+bopXG0m2KS8VFscuKA== - dependencies: - extend "^3.0.0" - is-absolute-url "^3.0.0" - mdast-util-definitions "^4.0.0" - space-separated-tokens "^1.0.0" - unist-util-visit "^2.0.0" - -remark-footnotes@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/remark-footnotes/-/remark-footnotes-2.0.0.tgz#9001c4c2ffebba55695d2dd80ffb8b82f7e6303f" - integrity sha512-3Clt8ZMH75Ayjp9q4CorNeyjwIxHFcTkaektplKGl2A1jNGEUey8cKL0ZC5vJwfcD5GFGsNLImLG/NGzWIzoMQ== - -remark-frontmatter@4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/remark-frontmatter/-/remark-frontmatter-4.0.1.tgz#84560f7ccef114ef076d3d3735be6d69f8922309" - integrity sha512-38fJrB0KnmD3E33a5jZC/5+gGAC2WKNiPw1/fdXJvijBlhA7RCsvJklrYJakS0HedninvaCYW8lQGf9C918GfA== - dependencies: - "@types/mdast" "^3.0.0" - mdast-util-frontmatter "^1.0.0" - micromark-extension-frontmatter "^1.0.0" - unified "^10.0.0" - -remark-mdx-frontmatter@^1.0.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/remark-mdx-frontmatter/-/remark-mdx-frontmatter-1.1.1.tgz#54cfb3821fbb9cb6057673e0570ae2d645f6fe32" - integrity sha512-7teX9DW4tI2WZkXS4DBxneYSY7NHiXl4AKdWDO9LXVweULlCT8OPWsOjLEnMIXViN1j+QcY8mfbq3k0EK6x3uA== - dependencies: - estree-util-is-identifier-name "^1.0.0" - estree-util-value-to-estree "^1.0.0" - js-yaml "^4.0.0" - toml "^3.0.0" - -remark-mdx@1.6.22: - version "1.6.22" - resolved "https://registry.yarnpkg.com/remark-mdx/-/remark-mdx-1.6.22.tgz#06a8dab07dcfdd57f3373af7f86bd0e992108bbd" - integrity sha512-phMHBJgeV76uyFkH4rvzCftLfKCr2RZuF+/gmVcaKrpsihyzmhXjA0BEMDaPTXG5y8qZOKPVo83NAOX01LPnOQ== - dependencies: - "@babel/core" "7.12.9" - "@babel/helper-plugin-utils" "7.10.4" - "@babel/plugin-proposal-object-rest-spread" "7.12.1" - "@babel/plugin-syntax-jsx" "7.12.1" - "@mdx-js/util" "1.6.22" - is-alphabetical "1.0.4" - remark-parse "8.0.3" - unified "9.2.0" - -remark-parse@8.0.3: - version "8.0.3" - resolved "https://registry.yarnpkg.com/remark-parse/-/remark-parse-8.0.3.tgz#9c62aa3b35b79a486454c690472906075f40c7e1" - integrity sha512-E1K9+QLGgggHxCQtLt++uXltxEprmWzNfg+MxpfHsZlrddKzZ/hZyWHDbK3/Ap8HJQqYJRXP+jHczdL6q6i85Q== - dependencies: - ccount "^1.0.0" - collapse-white-space "^1.0.2" - is-alphabetical "^1.0.0" - is-decimal "^1.0.0" - is-whitespace-character "^1.0.0" - is-word-character "^1.0.0" - markdown-escapes "^1.0.0" - parse-entities "^2.0.0" - repeat-string "^1.5.4" - state-toggle "^1.0.0" - trim "0.0.1" - trim-trailing-lines "^1.0.0" - unherit "^1.0.4" - unist-util-remove-position "^2.0.0" - vfile-location "^3.0.0" - xtend "^4.0.1" - -remark-parse@^10.0.0: - version "10.0.1" - resolved "https://registry.yarnpkg.com/remark-parse/-/remark-parse-10.0.1.tgz#6f60ae53edbf0cf38ea223fe643db64d112e0775" - integrity sha512-1fUyHr2jLsVOkhbvPRBJ5zTKZZyD6yZzYaWCS6BPBdQ8vEMBCH+9zNCDA6tET/zHCi/jLqjCWtlJZUPk+DbnFw== - dependencies: - "@types/mdast" "^3.0.0" - mdast-util-from-markdown "^1.0.0" - unified "^10.0.0" - -remark-rehype@^9.0.0: - version "9.1.0" - resolved "https://registry.yarnpkg.com/remark-rehype/-/remark-rehype-9.1.0.tgz#e4b5b6e19c125b3780343eb66c3e9b99b0f06a81" - integrity sha512-oLa6YmgAYg19zb0ZrBACh40hpBLteYROaPLhBXzLgjqyHQrN+gVP9N/FJvfzuNNuzCutktkroXEZBrxAxKhh7Q== - dependencies: - "@types/hast" "^2.0.0" - "@types/mdast" "^3.0.0" - mdast-util-to-hast "^11.0.0" - unified "^10.0.0" - -remark-slug@^6.0.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/remark-slug/-/remark-slug-6.1.0.tgz#0503268d5f0c4ecb1f33315c00465ccdd97923ce" - integrity sha512-oGCxDF9deA8phWvxFuyr3oSJsdyUAxMFbA0mZ7Y1Sas+emILtO+e5WutF9564gDsEN4IXaQXm5pFo6MLH+YmwQ== +rehype-external-links@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/rehype-external-links/-/rehype-external-links-3.0.0.tgz#2b28b5cda1932f83f045b6f80a3e1b15f168c6f6" + integrity sha512-yp+e5N9V3C6bwBeAC4n796kc86M4gJCdlVhiMTxIrJG5UHDMh+PJANf9heqORJbt1nrCbDwIlAZKjANIaVBbvw== dependencies: - github-slugger "^1.0.0" - mdast-util-to-string "^1.0.0" - unist-util-visit "^2.0.0" + "@types/hast" "^3.0.0" + "@ungap/structured-clone" "^1.0.0" + hast-util-is-element "^3.0.0" + is-absolute-url "^4.0.0" + space-separated-tokens "^2.0.0" + unist-util-visit "^5.0.0" -remark-squeeze-paragraphs@4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/remark-squeeze-paragraphs/-/remark-squeeze-paragraphs-4.0.0.tgz#76eb0e085295131c84748c8e43810159c5653ead" - integrity sha512-8qRqmL9F4nuLPIgl92XUuxI3pFxize+F1H0e/W3llTk0UsjJaj01+RrirkMw7P21RKe4X6goQhYRSvNWX+70Rw== +rehype-slug@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/rehype-slug/-/rehype-slug-6.0.0.tgz#1d21cf7fc8a83ef874d873c15e6adaee6344eaf1" + integrity sha512-lWyvf/jwu+oS5+hL5eClVd3hNdmwM1kAC0BUvEGD19pajQMIzcNUd/k9GsfQ+FfECvX+JE+e9/btsKH0EjJT6A== dependencies: - mdast-squeeze-paragraphs "^4.0.0" + "@types/hast" "^3.0.0" + github-slugger "^2.0.0" + hast-util-heading-rank "^3.0.0" + hast-util-to-string "^3.0.0" + unist-util-visit "^5.0.0" -remove-trailing-separator@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" - integrity sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw== +relateurl@^0.2.7: + version "0.2.7" + resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9" + integrity sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog== -renderkid@^2.0.4: - version "2.0.7" - resolved "https://registry.yarnpkg.com/renderkid/-/renderkid-2.0.7.tgz#464f276a6bdcee606f4a15993f9b29fc74ca8609" - integrity sha512-oCcFyxaMrKsKcTY59qnCAtmDVSLfPbrv6A3tVbPdFMMrv5jaK10V6m40cKsoPNhAqN6rmHW9sswW4o3ruSrwUQ== +renderkid@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/renderkid/-/renderkid-3.0.0.tgz#5fd823e4d6951d37358ecc9a58b1f06836b6268a" + integrity sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg== dependencies: css-select "^4.1.3" dom-converter "^0.2.0" htmlparser2 "^6.1.0" lodash "^4.17.21" - strip-ansi "^3.0.1" - -repeat-element@^1.1.2: - version "1.1.4" - resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.4.tgz#be681520847ab58c7568ac75fbfad28ed42d39e9" - integrity sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ== - -repeat-string@^1.5.4, repeat-string@^1.6.1: - version "1.6.1" - resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" - integrity sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w== - -repeating@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" - integrity sha512-ZqtSMuVybkISo2OWvqvm7iHSWngvdaW3IpsT9/uP8v4gMi591LY6h35wdOfvQdWCKFWZWm2Y1Opp4kV7vQKT6A== - dependencies: - is-finite "^1.0.0" - -request-promise-core@1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.4.tgz#3eedd4223208d419867b78ce815167d10593a22f" - integrity sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw== - dependencies: - lodash "^4.17.19" - -request-promise-native@^1.0.7: - version "1.0.9" - resolved "https://registry.yarnpkg.com/request-promise-native/-/request-promise-native-1.0.9.tgz#e407120526a5efdc9a39b28a5679bf47b9d9dc28" - integrity sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g== - dependencies: - request-promise-core "1.1.4" - stealthy-require "^1.1.1" - tough-cookie "^2.3.3" - -request@^2.88.0: - version "2.88.2" - resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" - integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== - dependencies: - aws-sign2 "~0.7.0" - aws4 "^1.8.0" - caseless "~0.12.0" - combined-stream "~1.0.6" - extend "~3.0.2" - forever-agent "~0.6.1" - form-data "~2.3.2" - har-validator "~5.1.3" - http-signature "~1.2.0" - is-typedarray "~1.0.0" - isstream "~0.1.2" - json-stringify-safe "~5.0.1" - mime-types "~2.1.19" - oauth-sign "~0.9.0" - performance-now "^2.1.0" - qs "~6.5.2" - safe-buffer "^5.1.2" - tough-cookie "~2.5.0" - tunnel-agent "^0.6.0" - uuid "^3.3.2" + strip-ansi "^6.0.1" require-directory@^2.1.1: version "2.1.1" @@ -17709,93 +17441,61 @@ require-from-string@^2.0.2: resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== -"require-like@>= 0.1.1": - version "0.1.2" - resolved "https://registry.yarnpkg.com/require-like/-/require-like-0.1.2.tgz#ad6f30c13becd797010c468afa775c0c0a6b47fa" - integrity sha512-oyrU88skkMtDdauHDuKVrgR+zuItqr6/c//FXzvmxRGMexSDc6hNvJInGW3LL46n+8b50RykrvwSUIIQH2LQ5A== - require-main-filename@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== +requireindex@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/requireindex/-/requireindex-1.1.0.tgz#e5404b81557ef75db6e49c5a72004893fe03e162" + integrity sha512-LBnkqsDE7BZKvqylbmn7lTIVdpx4K/QCduRATpO5R+wtPmky/a8pN1bO2D6wXppn1497AJF9mNjqAXr6bdl9jg== + resize-observer-polyfill@^1.5.1: version "1.5.1" resolved "https://registry.yarnpkg.com/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz#0e9020dd3d21024458d4ebd27e23e40269810464" integrity sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg== -resolve-alpn@^1.0.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/resolve-alpn/-/resolve-alpn-1.2.1.tgz#b7adbdac3546aaaec20b45e7d8265927072726f9" - integrity sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g== - -resolve-cwd@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d" - integrity sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg== - dependencies: - resolve-from "^5.0.0" +resolve-from@5.0.0, resolve-from@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" + integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== resolve-from@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== -resolve-from@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" - integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== - -resolve-url@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" - integrity sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg== - -resolve@1.1.7: - version "1.1.7" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" - integrity sha512-9znBF0vBcaSN3W2j7wKvdERPwqTxSpCq+if5C0WoTCyV9n24rua28jeuQ2pL/HOf+yUe/Mef+H/5p60K0Id3bg== - -resolve@1.17.0: - version "1.17.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.17.0.tgz#b25941b54968231cc2d1bb76a79cb7f2c0bf8444" - integrity sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w== +resolve-global@1.0.0, resolve-global@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/resolve-global/-/resolve-global-1.0.0.tgz#a2a79df4af2ca3f49bf77ef9ddacd322dad19255" + integrity sha512-zFa12V4OLtT5XUX/Q4VLvTfBf+Ok0SPc1FNGM/z9ctUdiU618qwKpWnd0CHs3+RqROfyEg/DhuHbMWYqcgljEw== dependencies: - path-parse "^1.0.6" + global-dirs "^0.1.1" + +resolve.exports@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-2.0.2.tgz#f8c934b8e6a13f539e38b7098e2e36134f01e800" + integrity sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg== -resolve@^1.1.6, resolve@^1.10.0, resolve@^1.11.0, resolve@^1.12.0, resolve@^1.14.2, resolve@^1.17.0, resolve@^1.19.0, resolve@^1.22.1, resolve@^1.3.2: - version "1.22.1" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177" - integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw== +resolve@^1.10.0, resolve@^1.12.0, resolve@^1.14.2, resolve@^1.19.0, resolve@^1.22.1, resolve@^1.22.4, resolve@^1.22.8: + version "1.22.8" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d" + integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw== dependencies: - is-core-module "^2.9.0" + is-core-module "^2.13.0" path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" resolve@^2.0.0-next.4: - version "2.0.0-next.4" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-2.0.0-next.4.tgz#3d37a113d6429f496ec4752d2a2e58efb1fd4660" - integrity sha512-iMDbmAWtfU+MHpxt/I5iWI7cY6YVEZUQ3MBgPQ++XD1PELuJHIl82xBmObyP2KyQmkNB2dsqF7seoQQiAn5yDQ== + version "2.0.0-next.5" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-2.0.0-next.5.tgz#6b0ec3107e671e52b68cd068ef327173b90dc03c" + integrity sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA== dependencies: - is-core-module "^2.9.0" + is-core-module "^2.13.0" path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" -responselike@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/responselike/-/responselike-2.0.1.tgz#9a0bc8fdc252f3fb1cca68b016591059ba1422bc" - integrity sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw== - dependencies: - lowercase-keys "^2.0.0" - -restore-cursor@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" - integrity sha512-6IzJLuGi4+R14vwagDHX+JrXmPVtPpn4mffDJ1UdR7/Edm87fl6yi8mMBIVvFtJaNTUvjughmW4hwLhRG7gC1Q== - dependencies: - onetime "^2.0.0" - signal-exit "^3.0.2" - restore-cursor@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e" @@ -17804,24 +17504,30 @@ restore-cursor@^3.1.0: onetime "^5.1.0" signal-exit "^3.0.2" -ret@~0.1.10: - version "0.1.15" - resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" - integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== +restore-cursor@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-4.0.0.tgz#519560a4318975096def6e609d44100edaa4ccb9" + integrity sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg== + dependencies: + onetime "^5.1.0" + signal-exit "^3.0.2" + +retry@^0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" + integrity sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow== reusify@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== -rimraf@2.6.3: - version "2.6.3" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" - integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== - dependencies: - glob "^7.1.3" +rfdc@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.3.0.tgz#d0b7c441ab2720d05dc4cf26e01c89631d9da08b" + integrity sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA== -rimraf@^2.5.4, rimraf@^2.6.3: +rimraf@^2.6.3: version "2.7.1" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== @@ -17835,6 +17541,20 @@ rimraf@^3.0.0, rimraf@^3.0.2: dependencies: glob "^7.1.3" +rimraf@^5.0.1: + version "5.0.5" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-5.0.5.tgz#9be65d2d6e683447d2e9013da2bf451139a61ccf" + integrity sha512-CqDakW+hMe/Bz202FPEymy68P+G50RfMQK+Qo5YUqc9SPipvbGjCGKd0RSKEelbsfQuw3g5NZDSrlZZAJurH1A== + dependencies: + glob "^10.3.7" + +rimraf@~2.6.2: + version "2.6.3" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" + integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== + dependencies: + glob "^7.1.3" + ripemd160@^2.0.0, ripemd160@^2.0.1, ripemd160@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" @@ -17843,79 +17563,91 @@ ripemd160@^2.0.0, ripemd160@^2.0.1, ripemd160@^2.0.2: hash-base "^3.0.0" inherits "^2.0.1" -rollup-plugin-inject@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/rollup-plugin-inject/-/rollup-plugin-inject-3.0.2.tgz#e4233855bfba6c0c12a312fd6649dff9a13ee9f4" - integrity sha512-ptg9PQwzs3orn4jkgXJ74bfs5vYz1NCZlSQMBUA0wKcGp5i5pA1AO3fOUEte8enhGUC+iapTCzEWw2jEFFUO/w== - dependencies: - estree-walker "^0.6.1" - magic-string "^0.25.3" - rollup-pluginutils "^2.8.1" - -rollup-plugin-node-polyfills@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/rollup-plugin-node-polyfills/-/rollup-plugin-node-polyfills-0.2.1.tgz#53092a2744837164d5b8a28812ba5f3ff61109fd" - integrity sha512-4kCrKPTJ6sK4/gLL/U5QzVT8cxJcofO0OU74tnB19F40cmuAKSzH5/siithxlofFEjwvw1YAhPmbvGNA6jEroA== - dependencies: - rollup-plugin-inject "^3.0.0" - -rollup-plugin-sourcemaps@^0.6.2: - version "0.6.3" - resolved "https://registry.yarnpkg.com/rollup-plugin-sourcemaps/-/rollup-plugin-sourcemaps-0.6.3.tgz#bf93913ffe056e414419607f1d02780d7ece84ed" - integrity sha512-paFu+nT1xvuO1tPFYXGe+XnQvg4Hjqv/eIhG8i5EspfYYPBKL57X7iVbfv55aNVASg3dzWvES9dmWsL2KhfByw== +ripple-address-codec@^4.1.1, ripple-address-codec@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/ripple-address-codec/-/ripple-address-codec-4.3.1.tgz#68fbaf646bb8567f70743af7f1ce4479f73efbf6" + integrity sha512-Qa3+9wKVvpL/xYtT6+wANsn0A1QcC5CT6IMZbRJZ/1lGt7gmwIfsrCuz1X0+LCEO7zgb+3UT1I1dc0k/5dwKQQ== dependencies: - "@rollup/pluginutils" "^3.0.9" - source-map-resolve "^0.6.0" + base-x "^3.0.9" + create-hash "^1.1.2" -rollup-plugin-terser@^5.1.2: - version "5.3.1" - resolved "https://registry.yarnpkg.com/rollup-plugin-terser/-/rollup-plugin-terser-5.3.1.tgz#8c650062c22a8426c64268548957463bf981b413" - integrity sha512-1pkwkervMJQGFYvM9nscrUoncPwiKR/K+bHdjv6PFgRo3cgPHoRT83y2Aa3GvINj4539S15t/tpFPb775TDs6w== +ripple-binary-codec@^1.1.3: + version "1.11.0" + resolved "https://registry.yarnpkg.com/ripple-binary-codec/-/ripple-binary-codec-1.11.0.tgz#d99c848c51a19746b738785001fb7208704bfe30" + integrity sha512-g7+gs3T+NfoeW6vIq5dcN0CkIT4t/zwRzFxz8X2RzfbrWRnewPUKqQbmBgs05tXLX5NuWPaneiaAVpFpYBcdfw== dependencies: - "@babel/code-frame" "^7.5.5" - jest-worker "^24.9.0" - rollup-pluginutils "^2.8.2" - serialize-javascript "^4.0.0" - terser "^4.6.2" + assert "^2.0.0" + big-integer "^1.6.48" + buffer "6.0.3" + create-hash "^1.2.0" + decimal.js "^10.2.0" + ripple-address-codec "^4.3.1" -rollup-plugin-typescript2@^0.27.3: - version "0.27.3" - resolved "https://registry.yarnpkg.com/rollup-plugin-typescript2/-/rollup-plugin-typescript2-0.27.3.tgz#cd9455ac026d325b20c5728d2cc54a08a771b68b" - integrity sha512-gmYPIFmALj9D3Ga1ZbTZAKTXq1JKlTQBtj299DXhqYz9cL3g/AQfUvbb2UhH+Nf++cCq941W2Mv7UcrcgLzJJg== +ripple-keypairs@^1.0.3: + version "1.3.1" + resolved "https://registry.yarnpkg.com/ripple-keypairs/-/ripple-keypairs-1.3.1.tgz#7fa531df36b138134afb53555a87d7f5eb465b2e" + integrity sha512-dmPlraWKJciFJxHcoubDahGnoIalG5e/BtV6HNDUs7wLXmtnLMHt6w4ed9R8MTL2zNrVPiIdI/HCtMMo0Tm7JQ== dependencies: - "@rollup/pluginutils" "^3.1.0" - find-cache-dir "^3.3.1" - fs-extra "8.1.0" - resolve "1.17.0" - tslib "2.0.1" + bn.js "^5.1.1" + brorand "^1.0.5" + elliptic "^6.5.4" + hash.js "^1.0.3" + ripple-address-codec "^4.3.1" -rollup-pluginutils@^2.8.1, rollup-pluginutils@^2.8.2: - version "2.8.2" - resolved "https://registry.yarnpkg.com/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz#72f2af0748b592364dbd3389e600e5a9444a351e" - integrity sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ== +ripple-lib-transactionparser@0.8.2: + version "0.8.2" + resolved "https://registry.yarnpkg.com/ripple-lib-transactionparser/-/ripple-lib-transactionparser-0.8.2.tgz#7aaad3ba1e1aeee1d5bcff32334a7a838f834dce" + integrity sha512-1teosQLjYHLyOQrKUQfYyMjDR3MAq/Ga+MJuLUfpBMypl4LZB4bEoMcmG99/+WVTEiZOezJmH9iCSvm/MyxD+g== dependencies: - estree-walker "^0.6.1" + bignumber.js "^9.0.0" + lodash "^4.17.15" -rollup@^1.32.1: - version "1.32.1" - resolved "https://registry.yarnpkg.com/rollup/-/rollup-1.32.1.tgz#4480e52d9d9e2ae4b46ba0d9ddeaf3163940f9c4" - integrity sha512-/2HA0Ec70TvQnXdzynFffkjA6XN+1e2pEv/uKS5Ulca40g2L7KuOE3riasHoNVHOsFD5KKZgDsMk1CP3Tw9s+A== +ripple-lib@^1.10.1: + version "1.10.1" + resolved "https://registry.yarnpkg.com/ripple-lib/-/ripple-lib-1.10.1.tgz#9c353702792b25465cdb269265d6f5bb27b1471b" + integrity sha512-OQk+Syl2JfxKxV2KuF/kBMtnh012I5tNnziP3G4WDGCGSIAgeqkOgkR59IQ0YDNrs1YW8GbApxrdMSRi/QClcA== dependencies: - "@types/estree" "*" - "@types/node" "*" - acorn "^7.1.0" - -rollup@^3.18.0: - version "3.20.2" - resolved "https://registry.yarnpkg.com/rollup/-/rollup-3.20.2.tgz#f798c600317f216de2e4ad9f4d9ab30a89b690ff" - integrity sha512-3zwkBQl7Ai7MFYQE0y1MeQ15+9jsi7XxfrqwTb/9EK8D9C9+//EBR4M+CuA1KODRaNbFez/lWxA5vhEGZp4MUg== + "@types/lodash" "^4.14.136" + "@types/ws" "^7.2.0" + bignumber.js "^9.0.0" + https-proxy-agent "^5.0.0" + jsonschema "1.2.2" + lodash "^4.17.4" + ripple-address-codec "^4.1.1" + ripple-binary-codec "^1.1.3" + ripple-keypairs "^1.0.3" + ripple-lib-transactionparser "0.8.2" + ws "^7.2.0" + +rollup@^4.20.0: + version "4.24.0" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.24.0.tgz#c14a3576f20622ea6a5c9cad7caca5e6e9555d05" + integrity sha512-DOmrlGSXNk1DM0ljiQA+i+o0rSLhtii1je5wgk60j49d1jHT5YYttBv1iWOnYSTG+fZZESUOSNiAl89SIet+Cg== + dependencies: + "@types/estree" "1.0.6" optionalDependencies: + "@rollup/rollup-android-arm-eabi" "4.24.0" + "@rollup/rollup-android-arm64" "4.24.0" + "@rollup/rollup-darwin-arm64" "4.24.0" + "@rollup/rollup-darwin-x64" "4.24.0" + "@rollup/rollup-linux-arm-gnueabihf" "4.24.0" + "@rollup/rollup-linux-arm-musleabihf" "4.24.0" + "@rollup/rollup-linux-arm64-gnu" "4.24.0" + "@rollup/rollup-linux-arm64-musl" "4.24.0" + "@rollup/rollup-linux-powerpc64le-gnu" "4.24.0" + "@rollup/rollup-linux-riscv64-gnu" "4.24.0" + "@rollup/rollup-linux-s390x-gnu" "4.24.0" + "@rollup/rollup-linux-x64-gnu" "4.24.0" + "@rollup/rollup-linux-x64-musl" "4.24.0" + "@rollup/rollup-win32-arm64-msvc" "4.24.0" + "@rollup/rollup-win32-ia32-msvc" "4.24.0" + "@rollup/rollup-win32-x64-msvc" "4.24.0" fsevents "~2.3.2" rpc-websockets@^7.5.1: - version "7.5.1" - resolved "https://registry.yarnpkg.com/rpc-websockets/-/rpc-websockets-7.5.1.tgz#e0a05d525a97e7efc31a0617f093a13a2e10c401" - integrity sha512-kGFkeTsmd37pHPMaHIgN1LVKXMi0JD782v4Ds9ZKtLlwdTKjn+CxM9A9/gLT2LaOuEcEFGL98h1QWQtlOIdW0w== + version "7.8.0" + resolved "https://registry.yarnpkg.com/rpc-websockets/-/rpc-websockets-7.8.0.tgz#1bcf571f65c51803e81f0824e9540a0da35a5287" + integrity sha512-AStkq6KDvSAmA4WiwlK1pDvj/33BWmExTATUokC0v+NhWekXSTNzXS5OGXeYwq501/pj6lBZMofg/h4dx4/tCg== dependencies: "@babel/runtime" "^7.17.2" eventemitter3 "^4.0.7" @@ -17925,10 +17657,21 @@ rpc-websockets@^7.5.1: bufferutil "^4.0.1" utf-8-validate "^5.0.2" -rsvp@^4.8.4: - version "4.8.5" - resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-4.8.5.tgz#c8f155311d167f68f21e168df71ec5b083113734" - integrity sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA== +rpc-websockets@^9.0.0: + version "9.0.1" + resolved "https://registry.yarnpkg.com/rpc-websockets/-/rpc-websockets-9.0.1.tgz#a69c83ffd5e26bdd6117f5b434ae68133c4805b6" + integrity sha512-JCkdc/TfJBGRfmjIFK7cmqX79nwPWUd9xCM0DAydRbdLShsW3j/GV2gmPlaFa8V1+2u4V/O47fm4ZR5+F6HyDw== + dependencies: + "@swc/helpers" "^0.5.11" + "@types/uuid" "^8.3.4" + "@types/ws" "^8.2.2" + buffer "^6.0.3" + eventemitter3 "^5.0.1" + uuid "^8.3.2" + ws "^8.5.0" + optionalDependencies: + bufferutil "^4.0.1" + utf-8-validate "^5.0.2" run-async@^2.4.0: version "2.4.1" @@ -17942,54 +17685,40 @@ run-parallel@^1.1.9: dependencies: queue-microtask "^1.2.2" -run-queue@^1.0.0, run-queue@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/run-queue/-/run-queue-1.0.3.tgz#e848396f057d223f24386924618e25694161ec47" - integrity sha512-ntymy489o0/QQplUDnpYAYUsO50K9SBrIVaKCWDOJzYJts0f9WH9RFJkyagebkw5+y1oi00R7ynNW/d12GBumg== - dependencies: - aproba "^1.1.1" - -rxjs@6, rxjs@^6.5.4, rxjs@^6.6.0: +rxjs@^6.5.4, rxjs@^6.6.0: version "6.6.7" resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.7.tgz#90ac018acabf491bf65044235d5863c4dab804c9" integrity sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ== dependencies: tslib "^1.9.0" -rxjs@^7.5.5: - version "7.8.0" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.8.0.tgz#90a938862a82888ff4c7359811a595e14e1e09a4" - integrity sha512-F2+gxDshqmIub1KdvZkaEfGDwLNpPvk9Fs6LD/MyQxNgMds/WH9OdDDXOmxUZpME+iSK3rQCctkL0DYyytUqMg== +rxjs@^7.0.0, rxjs@^7.8.1: + version "7.8.1" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.8.1.tgz#6f6f3d99ea8044291efd92e7c7fcf562c4057543" + integrity sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg== dependencies: tslib "^2.1.0" -sade@^1.4.2, sade@^1.7.3: - version "1.8.1" - resolved "https://registry.yarnpkg.com/sade/-/sade-1.8.1.tgz#0a78e81d658d394887be57d2a409bf703a3b2701" - integrity sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A== +safe-array-concat@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/safe-array-concat/-/safe-array-concat-1.0.1.tgz#91686a63ce3adbea14d61b14c99572a8ff84754c" + integrity sha512-6XbUAseYE2KtOuGueyeobCySj9L4+66Tn6KQMOPQJrAJEowYKW/YR/MGJZl7FdydUdaFu4LYyDZjxf4/Nmo23Q== dependencies: - mri "^1.1.0" - -safe-buffer@5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" - integrity sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg== + call-bind "^1.0.2" + get-intrinsic "^1.2.1" + has-symbols "^1.0.3" + isarray "^2.0.5" safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.2" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== -safe-buffer@5.2.1, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@~5.2.0: +safe-buffer@5.2.1, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@^5.2.1, safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== -safe-json-utils@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/safe-json-utils/-/safe-json-utils-1.1.1.tgz#0e883874467d95ab914c3f511096b89bfb3e63b1" - integrity sha512-SAJWGKDs50tAbiDXLf89PDwt9XYkWyANFWVzn4dTXl5QyI8t2o/bW5/OJl3lvc2WVU4MEpTo9Yz5NVFNsp+OJQ== - safe-regex-test@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/safe-regex-test/-/safe-regex-test-1.0.0.tgz#793b874d524eb3640d1873aad03596db2d4f2295" @@ -17999,40 +17728,16 @@ safe-regex-test@^1.0.0: get-intrinsic "^1.1.3" is-regex "^1.1.4" -safe-regex@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" - integrity sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg== - dependencies: - ret "~0.1.10" +safe-stable-stringify@^2.1.0: + version "2.4.3" + resolved "https://registry.yarnpkg.com/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz#138c84b6f6edb3db5f8ef3ef7115b8f55ccbf886" + integrity sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g== -"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: +"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0", safer-buffer@^2.1.0: version "2.1.2" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== -sane@^4.0.3: - version "4.1.0" - resolved "https://registry.yarnpkg.com/sane/-/sane-4.1.0.tgz#ed881fd922733a6c461bc189dc2b6c006f3ffded" - integrity sha512-hhbzAgTIX8O7SHfp2c8/kREfEn4qO/9q8C9beyY6+tvZ87EpoZ3i1RIEvp27YBswnNbY9mWd6paKVmKbAgLfZA== - dependencies: - "@cnakazawa/watch" "^1.0.3" - anymatch "^2.0.0" - capture-exit "^2.0.0" - exec-sh "^0.3.2" - execa "^1.0.0" - fb-watchman "^2.0.0" - micromatch "^3.1.4" - minimist "^1.1.1" - walker "~1.0.5" - -saxes@^3.1.9: - version "3.1.11" - resolved "https://registry.yarnpkg.com/saxes/-/saxes-3.1.11.tgz#d59d1fd332ec92ad98a2e0b2ee644702384b1c5b" - integrity sha512-Ydydq3zC+WYDJK1+gRxRapLIED9PWeSuuS41wqyoRmzvhhh9nc+QQrVMKJYzJFULazeGhzSV0QleN2wD3boh2g== - dependencies: - xmlchars "^2.1.1" - scheduler@^0.19.1: version "0.19.1" resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.19.1.tgz#4f3e2ed2c1a7d65681f4c854fa8c5a1ccb40f196" @@ -18048,57 +17753,46 @@ scheduler@^0.23.0: dependencies: loose-envify "^1.1.0" -schema-utils@2.7.0: - version "2.7.0" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.7.0.tgz#17151f76d8eae67fbbf77960c33c676ad9f4efc7" - integrity sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A== - dependencies: - "@types/json-schema" "^7.0.4" - ajv "^6.12.2" - ajv-keywords "^3.4.1" - -schema-utils@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-1.0.0.tgz#0b79a93204d7b600d4b2850d1f66c2a34951c770" - integrity sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g== - dependencies: - ajv "^6.1.0" - ajv-errors "^1.0.0" - ajv-keywords "^3.1.0" - -schema-utils@^2.6.5, schema-utils@^2.7.0: - version "2.7.1" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.7.1.tgz#1ca4f32d1b24c590c203b8e7a50bf0ea4cd394d7" - integrity sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg== +scheduler@^0.23.2: + version "0.23.2" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.23.2.tgz#414ba64a3b282892e944cf2108ecc078d115cdc3" + integrity sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ== dependencies: - "@types/json-schema" "^7.0.5" - ajv "^6.12.4" - ajv-keywords "^3.5.2" + loose-envify "^1.1.0" -schema-utils@^3.0.0, schema-utils@^3.1.0, schema-utils@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.1.1.tgz#bc74c4b6b6995c1d88f76a8b77bea7219e0c8281" - integrity sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw== +schema-utils@^3.1.1, schema-utils@^3.2.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.3.0.tgz#f50a88877c3c01652a15b622ae9e9795df7a60fe" + integrity sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg== dependencies: "@types/json-schema" "^7.0.8" ajv "^6.12.5" ajv-keywords "^3.5.2" schema-utils@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-4.0.0.tgz#60331e9e3ae78ec5d16353c467c34b3a0a1d3df7" - integrity sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg== + version "4.2.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-4.2.0.tgz#70d7c93e153a273a805801882ebd3bff20d89c8b" + integrity sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw== dependencies: "@types/json-schema" "^7.0.9" - ajv "^8.8.0" + ajv "^8.9.0" ajv-formats "^2.1.1" - ajv-keywords "^5.0.0" + ajv-keywords "^5.1.0" scrypt-js@3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/scrypt-js/-/scrypt-js-3.0.1.tgz#d314a57c2aef69d1ad98a138a21fe9eafa9ee312" integrity sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA== +secp256k1@^4.0.0, secp256k1@^4.0.2: + version "4.0.4" + resolved "https://registry.yarnpkg.com/secp256k1/-/secp256k1-4.0.4.tgz#58f0bfe1830fe777d9ca1ffc7574962a8189f8ab" + integrity sha512-6JfvwvjUOn8F/jUoBY2Q1v5WY5XS+rj8qSe0v8Y4ezH4InLgTEeOOPQsRll9OV429Pvo6BCHGavIyJfr3TAhsw== + dependencies: + elliptic "^6.5.7" + node-addon-api "^5.0.0" + node-gyp-build "^4.2.0" + secretjs@^0.17.0: version "0.17.8" resolved "https://registry.yarnpkg.com/secretjs/-/secretjs-0.17.8.tgz#a7158ebf492727da8297f9b80cf9c83597e70cc9" @@ -18116,7 +17810,7 @@ secretjs@^0.17.0: protobufjs "6.11.3" secure-random "1.1.2" -secure-random@1.1.2, secure-random@^1.1.2: +secure-random@1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/secure-random/-/secure-random-1.1.2.tgz#ed103b460a851632d420d46448b2a900a41e7f7c" integrity sha512-H2bdSKERKdBV1SwoqYm6C0y+9EA94v6SUBOWO8kDndc4NoUih7Dv6Tsgma7zO1lv27wIvjlD0ZpMQk7um5dheQ== @@ -18126,20 +17820,15 @@ select@^1.1.2: resolved "https://registry.yarnpkg.com/select/-/select-1.1.2.tgz#0e7350acdec80b1108528786ec1d4418d11b396d" integrity sha512-OwpTSOfy6xSs1+pwcNrv0RBMOzI39Lp3qQKUTPVVPRjCdNa5JH/oPRiqsesIskK8TVgmRiHwO4KXlV2Li9dANA== -"semver@2 || 3 || 4 || 5", semver@^5.4.1, semver@^5.5.0, semver@^5.6.0, semver@^5.7.0, semver@^5.7.1: - version "5.7.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" - integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== - -semver@6.1.1: - version "6.1.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-6.1.1.tgz#53f53da9b30b2103cd4f15eab3a18ecbcb210c9b" - integrity sha512-rWYq2e5iYW+fFe/oPPtYJxYgjBm8sC4rmoGdUOgBB7VnwKt6HrL793l2voH1UlsyYZpJ4g0wfjnTEO1s1NP2eQ== +semver-parser@^4.1.4: + version "4.1.6" + resolved "https://registry.yarnpkg.com/semver-parser/-/semver-parser-4.1.6.tgz#9d6b1e06bab8d727d117d522991ca1999c67323d" + integrity sha512-i37y4KxCbaYXIwQKLLUC2nsFYxCeiguMrS6lfv4rU0aHd59fSAypcE+jGib2sbQRcJp2C2NL5ngKAqpKqd0SJw== -semver@6.x, semver@^6.0.0, semver@^6.1.1, semver@^6.1.2, semver@^6.3.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" - integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== +"semver@2 || 3 || 4 || 5", semver@^5.5.0, semver@^5.6.0: + version "5.7.2" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" + integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== semver@7.3.4: version "7.3.4" @@ -18148,17 +17837,29 @@ semver@7.3.4: dependencies: lru-cache "^6.0.0" -semver@7.3.8, semver@^7.1.1, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5, semver@^7.3.7: - version "7.3.8" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.8.tgz#07a78feafb3f7b32347d725e33de7e2a2df67798" - integrity sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A== +semver@7.5.4, semver@^7.3.4, semver@^7.3.5, semver@^7.3.7, semver@^7.3.8, semver@^7.5.2, semver@^7.5.3: + version "7.5.4" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" + integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== + dependencies: + lru-cache "^6.0.0" + +semver@7.6.0: + version "7.6.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.0.tgz#1a46a4db4bffcccd97b743b5005c8325f23d4e2d" + integrity sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg== dependencies: lru-cache "^6.0.0" -send@0.18.0: - version "0.18.0" - resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be" - integrity sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg== +semver@^6.0.0, semver@^6.3.1: + version "6.3.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" + integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== + +send@0.19.0: + version "0.19.0" + resolved "https://registry.yarnpkg.com/send/-/send-0.19.0.tgz#bbc5a388c8ea6c048967049dbeac0e4a3f09d7f8" + integrity sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw== dependencies: debug "2.6.9" depd "2.0.0" @@ -18174,20 +17875,6 @@ send@0.18.0: range-parser "~1.2.1" statuses "2.0.1" -serialize-javascript@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-4.0.0.tgz#b525e1238489a5ecfc42afacc3fe99e666f4b1aa" - integrity sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw== - dependencies: - randombytes "^2.1.0" - -serialize-javascript@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-5.0.1.tgz#7886ec848049a462467a97d3d918ebb2aaf934f4" - integrity sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA== - dependencies: - randombytes "^2.1.0" - serialize-javascript@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.1.tgz#b206efb27c3da0b0ab6b52f48d170b7996458e5c" @@ -18195,48 +17882,53 @@ serialize-javascript@^6.0.1: dependencies: randombytes "^2.1.0" -serve-favicon@^2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/serve-favicon/-/serve-favicon-2.5.0.tgz#935d240cdfe0f5805307fdfe967d88942a2cbcf0" - integrity sha512-FMW2RvqNr03x+C0WxTyu6sOv21oOjkq5j8tjquWccwa6ScNyGFOGJVpuS1NmTVGBAHS07xnSKotgf2ehQmf9iA== - dependencies: - etag "~1.8.1" - fresh "0.5.2" - ms "2.1.1" - parseurl "~1.3.2" - safe-buffer "5.1.1" - -serve-static@1.15.0: - version "1.15.0" - resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.15.0.tgz#faaef08cffe0a1a62f60cad0c4e513cff0ac9540" - integrity sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g== +serve-static@1.16.2: + version "1.16.2" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.16.2.tgz#b6a5343da47f6bdd2673848bf45754941e803296" + integrity sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw== dependencies: - encodeurl "~1.0.2" + encodeurl "~2.0.0" escape-html "~1.0.3" parseurl "~1.3.3" - send "0.18.0" + send "0.19.0" -set-blocking@^2.0.0, set-blocking@~2.0.0: +set-blocking@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw== -set-cookie-parser@^2.4.8: - version "2.6.0" - resolved "https://registry.yarnpkg.com/set-cookie-parser/-/set-cookie-parser-2.6.0.tgz#131921e50f62ff1a66a461d7d62d7b21d5d15a51" - integrity sha512-RVnVQxTXuerk653XfuliOxBP81Sf0+qfQE73LIYKcyMYHG94AuH0kgrQpRDuTZnSmjpysHmzxJXKNfa6PjFhyQ== +set-function-length@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.1.1.tgz#4bc39fafb0307224a33e106a7d35ca1218d659ed" + integrity sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ== + dependencies: + define-data-property "^1.1.1" + get-intrinsic "^1.2.1" + gopd "^1.0.1" + has-property-descriptors "^1.0.0" + +set-function-length@^1.2.1: + version "1.2.2" + resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.2.2.tgz#aac72314198eaed975cf77b2c3b6b880695e5449" + integrity sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg== + dependencies: + define-data-property "^1.1.4" + es-errors "^1.3.0" + function-bind "^1.1.2" + get-intrinsic "^1.2.4" + gopd "^1.0.1" + has-property-descriptors "^1.0.2" -set-value@^2.0.0, set-value@^2.0.1: +set-function-name@^2.0.0, set-function-name@^2.0.1: version "2.0.1" - resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b" - integrity sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw== + resolved "https://registry.yarnpkg.com/set-function-name/-/set-function-name-2.0.1.tgz#12ce38b7954310b9f61faa12701620a0c882793a" + integrity sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA== dependencies: - extend-shallow "^2.0.1" - is-extendable "^0.1.1" - is-plain-object "^2.0.3" - split-string "^3.0.1" + define-data-property "^1.0.1" + functions-have-names "^1.2.3" + has-property-descriptors "^1.0.0" -setimmediate@^1.0.4, setimmediate@^1.0.5: +setimmediate@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" integrity sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA== @@ -18307,20 +17999,6 @@ shell-quote@^1.6.1: resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.8.1.tgz#6dbf4db75515ad5bac63b4f1894c3a154c766680" integrity sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA== -shelljs@^0.8.3: - version "0.8.5" - resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.8.5.tgz#de055408d8361bed66c669d2f000538ced8ee20c" - integrity sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow== - dependencies: - glob "^7.0.0" - interpret "^1.0.0" - rechoir "^0.6.2" - -shellwords@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b" - integrity sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww== - side-channel@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" @@ -18330,31 +18008,30 @@ side-channel@^1.0.4: get-intrinsic "^1.0.2" object-inspect "^1.9.0" -signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.7: +side-channel@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.6.tgz#abd25fb7cd24baf45466406b1096b7831c9215f2" + integrity sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA== + dependencies: + call-bind "^1.0.7" + es-errors "^1.3.0" + get-intrinsic "^1.2.4" + object-inspect "^1.13.1" + +siginfo@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/siginfo/-/siginfo-2.0.0.tgz#32e76c70b79724e3bb567cb9d543eb858ccfaf30" + integrity sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g== + +signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.7: version "3.0.7" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== -signed-varint@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/signed-varint/-/signed-varint-2.0.1.tgz#50a9989da7c98c2c61dad119bc97470ef8528129" - integrity sha512-abgDPg1106vuZZOvw7cFwdCABddfJRz5akcCcchzTbhyhYnsG31y4AlZEgp315T7W3nQq5P4xeOm186ZiPVFzw== - dependencies: - varint "~5.0.0" - -simple-concat@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.1.tgz#f46976082ba35c2263f1c8ab5edfe26c41c9552f" - integrity sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q== - -simple-get@^3.0.3: - version "3.1.1" - resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-3.1.1.tgz#cc7ba77cfbe761036fbfce3d021af25fc5584d55" - integrity sha512-CQ5LTKGfCpvE1K0n2us+kuMPbk/q0EKl82s4aheV9oXjFEz6W/Y7oQFVJuU6QG77hRT4Ghb5RURteF5vnWjupA== - dependencies: - decompress-response "^4.2.0" - once "^1.3.1" - simple-concat "^1.0.0" +signal-exit@^4.0.1, signal-exit@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04" + integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== simplebar-react@^1.0.0-alpha.6: version "1.2.3" @@ -18381,18 +18058,6 @@ sisteransi@^1.0.5: resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" integrity sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg== -size-limit@^8.1.0: - version "8.2.4" - resolved "https://registry.yarnpkg.com/size-limit/-/size-limit-8.2.4.tgz#0ab0df7cbc89007d544a50b451f5fb4d110694ca" - integrity sha512-Un16nSreD1v2CYwSorattiJcHuAWqXvg4TsGgzpjnoByqQwsSfCIEQHuaD14HNStzredR8cdsO9oGH91ibypTA== - dependencies: - bytes-iec "^3.1.1" - chokidar "^3.5.3" - globby "^11.1.0" - lilconfig "^2.0.6" - nanospinner "^1.1.0" - picocolors "^1.0.0" - slash@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44" @@ -18403,114 +18068,67 @@ slash@^3.0.0: resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== -slice-ansi@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-2.1.0.tgz#cacd7693461a637a5788d92a7dd4fba068e81636" - integrity sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ== +slice-ansi@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-5.0.0.tgz#b73063c57aa96f9cd881654b15294d95d285c42a" + integrity sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ== dependencies: - ansi-styles "^3.2.0" - astral-regex "^1.0.0" - is-fullwidth-code-point "^2.0.0" + ansi-styles "^6.0.0" + is-fullwidth-code-point "^4.0.0" smart-buffer@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.2.0.tgz#6e1d71fa4f18c05f7d0ff216dd16a481d0e8d9ae" integrity sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg== -snapdragon-node@^2.0.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" - integrity sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw== - dependencies: - define-property "^1.0.0" - isobject "^3.0.0" - snapdragon-util "^3.0.1" - -snapdragon-util@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" - integrity sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ== +snake-case@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/snake-case/-/snake-case-3.0.4.tgz#4f2bbd568e9935abdfd593f34c691dadb49c452c" + integrity sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg== dependencies: - kind-of "^3.2.0" + dot-case "^3.0.4" + tslib "^2.0.3" -snapdragon@^0.8.1: - version "0.8.2" - resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" - integrity sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg== - dependencies: - base "^0.11.1" - debug "^2.2.0" - define-property "^0.2.5" - extend-shallow "^2.0.1" - map-cache "^0.2.2" - source-map "^0.5.6" - source-map-resolve "^0.5.0" - use "^3.1.0" - -socks-proxy-agent@5, socks-proxy-agent@^5.0.0: - version "5.0.1" - resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-5.0.1.tgz#032fb583048a29ebffec2e6a73fca0761f48177e" - integrity sha512-vZdmnjb9a2Tz6WEQVIurybSwElwPxMZaIc7PzqbJTrezcKNznv6giT7J7tZDZ1BojVaa1jvO/UiUdhDVB0ACoQ== +socks-proxy-agent@6.1.1: + version "6.1.1" + resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-6.1.1.tgz#e664e8f1aaf4e1fb3df945f09e3d94f911137f87" + integrity sha512-t8J0kG3csjA4g6FTbsMOWws+7R7vuRC8aQ/wy3/1OWmsgwA68zs/+cExQ0koSitUDXqhufF/YJr9wtNMZHw5Ew== dependencies: agent-base "^6.0.2" - debug "4" - socks "^2.3.3" + debug "^4.3.1" + socks "^2.6.1" -socks@^2.3.3: - version "2.7.1" - resolved "https://registry.yarnpkg.com/socks/-/socks-2.7.1.tgz#d8e651247178fde79c0663043e07240196857d55" - integrity sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ== +socks@^2.6.1: + version "2.8.3" + resolved "https://registry.yarnpkg.com/socks/-/socks-2.8.3.tgz#1ebd0f09c52ba95a09750afe3f3f9f724a800cb5" + integrity sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw== dependencies: - ip "^2.0.0" + ip-address "^9.0.5" smart-buffer "^4.2.0" -sort-object-keys@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/sort-object-keys/-/sort-object-keys-1.1.3.tgz#bff833fe85cab147b34742e45863453c1e190b45" - integrity sha512-855pvK+VkU7PaKYPc+Jjnmt4EzejQHyhhF33q31qG8x7maDzkeFhAAThdCYay11CISO+qAMwjOBP+fPZe0IPyg== - -sort-package-json@^1.55.0: - version "1.57.0" - resolved "https://registry.yarnpkg.com/sort-package-json/-/sort-package-json-1.57.0.tgz#e95fb44af8ede0bb6147e3f39258102d4bb23fc4" - integrity sha512-FYsjYn2dHTRb41wqnv+uEqCUvBpK3jZcTp9rbz2qDTmel7Pmdtf+i2rLaaPMRZeSVM60V3Se31GyWFpmKs4Q5Q== - dependencies: - detect-indent "^6.0.0" - detect-newline "3.1.0" - git-hooks-list "1.0.3" - globby "10.0.0" - is-plain-obj "2.1.0" - sort-object-keys "^1.1.3" - -source-list-map@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" - integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw== +sonic-boom@^2.2.1: + version "2.8.0" + resolved "https://registry.yarnpkg.com/sonic-boom/-/sonic-boom-2.8.0.tgz#c1def62a77425090e6ad7516aad8eb402e047611" + integrity sha512-kuonw1YOYYNOve5iHdSahXPOK49GqwA+LZhI6Wz/l0rP57iKyXXIHaRagOBHAPmGwJC6od2Z9zgvZ5loSgMlVg== + dependencies: + atomic-sleep "^1.0.0" -source-map-js@^1.0.2: +source-map-js@^1.0.1, source-map-js@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c" integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== -source-map-resolve@^0.5.0: - version "0.5.3" - resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.3.tgz#190866bece7553e1f8f267a2ee82c606b5509a1a" - integrity sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw== - dependencies: - atob "^2.1.2" - decode-uri-component "^0.2.0" - resolve-url "^0.2.1" - source-map-url "^0.4.0" - urix "^0.1.0" +source-map-js@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.0.tgz#16b809c162517b5b8c3e7dcd315a2a5c2612b2af" + integrity sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg== -source-map-resolve@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.6.0.tgz#3d9df87e236b53f16d01e58150fc7711138e5ed2" - integrity sha512-KXBr9d/fO/bWo97NXsPIAW1bFSBOuCnjbNTBMO7N59hsv5i9yzRDfcYwwt0l04+VqnKC+EwzvJZIP/qkuMgR/w== - dependencies: - atob "^2.1.2" - decode-uri-component "^0.2.0" +source-map-js@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.1.tgz#1ce5650fddd87abc099eda37dcff024c2667ae46" + integrity sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA== -source-map-support@^0.5.16, source-map-support@^0.5.21, source-map-support@^0.5.6, source-map-support@~0.5.12, source-map-support@~0.5.20: +source-map-support@^0.5.16, source-map-support@~0.5.20: version "0.5.21" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== @@ -18518,12 +18136,7 @@ source-map-support@^0.5.16, source-map-support@^0.5.21, source-map-support@^0.5. buffer-from "^1.0.0" source-map "^0.6.0" -source-map-url@^0.4.0: - version "0.4.1" - resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.1.tgz#0af66605a745a5a2f91cf1bbf8a7afbc283dec56" - integrity sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw== - -source-map@^0.5.0, source-map@^0.5.6, source-map@^0.5.7: +source-map@^0.5.7: version "0.5.7" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" integrity sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ== @@ -18533,15 +18146,12 @@ source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1: resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== -source-map@^0.7.0, source-map@^0.7.3: - version "0.7.4" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.4.tgz#a9bbe705c9d8846f4e08ff6765acf0f1b0898656" - integrity sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA== - -sourcemap-codec@^1.4.8: - version "1.4.8" - resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz#ea804bd94857402e6992d05a38ef1ae35a9ab4c4" - integrity sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA== +source-map@^0.8.0-beta.0: + version "0.8.0-beta.0" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.8.0-beta.0.tgz#d4c1bb42c3f7ee925f005927ba10709e0d1d1f11" + integrity sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA== + dependencies: + whatwg-url "^7.0.0" space-separated-tokens@^1.0.0: version "1.1.5" @@ -18575,29 +18185,15 @@ spdx-expression-parse@^3.0.0: spdx-license-ids "^3.0.0" spdx-license-ids@^3.0.0: - version "3.0.13" - resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.13.tgz#7189a474c46f8d47c7b0da4b987bb45e908bd2d5" - integrity sha512-XkD+zwiqXHikFZm4AX/7JSCXA98U5Db4AFd5XUg/+9UNtnH75+Z9KxtpYiJZx36mUDVOwH83pl7yvCer6ewM3w== + version "3.0.16" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.16.tgz#a14f64e0954f6e25cc6587bd4f392522db0d998f" + integrity sha512-eWN+LnM3GR6gPu35WxNgbGl8rmY1AEmoMDvL/QD6zYmPWgywxWqJWNdLGT+ke8dKNWrcYgYjPpG5gbTfghP8rw== split-on-first@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/split-on-first/-/split-on-first-1.1.0.tgz#f610afeee3b12bce1d0c30425e76398b78249a5f" integrity sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw== -split-string@^3.0.1, split-string@^3.0.2: - version "3.1.0" - resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" - integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw== - dependencies: - extend-shallow "^3.0.0" - -split2@^2.1.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/split2/-/split2-2.2.0.tgz#186b2575bcf83e85b7d18465756238ee4ee42493" - integrity sha512-RAb22TG39LhI31MbreBgIuKiIKhVsawfTgEGqKHTK87aG+ul/PB8Sqoi3I7kVdRWiCfrKxK3uo4/YUkpNvhPbw== - dependencies: - through2 "^2.0.2" - split2@^3.0.0: version "3.2.2" resolved "https://registry.yarnpkg.com/split2/-/split2-3.2.2.tgz#bf2cf2a37d838312c249c89206fd7a17dd12365f" @@ -18605,6 +18201,23 @@ split2@^3.0.0: dependencies: readable-stream "^3.0.0" +split2@^4.0.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/split2/-/split2-4.2.0.tgz#c9c5920904d148bab0b9f67145f245a86aadbfa4" + integrity sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg== + +split@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/split/-/split-1.0.1.tgz#605bd9be303aa59fb35f9229fbea0ddec9ea07d9" + integrity sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg== + dependencies: + through "2" + +sprintf-js@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.1.3.tgz#4914b903a2f8b685d17fdf78a70e917e872e444a" + integrity sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA== + sprintf-js@~1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" @@ -18615,94 +18228,47 @@ srcset@4: resolved "https://registry.yarnpkg.com/srcset/-/srcset-4.0.0.tgz#336816b665b14cd013ba545b6fe62357f86e65f4" integrity sha512-wvLeHgcVHKO8Sc/H/5lkGreJQVeYMm9rlmt8PuR1xE31rIuXhuzznUUqAt8MqLhB3MqJdFzlNAfpcWnxiFUcPw== -sshpk@^1.7.0: - version "1.17.0" - resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.17.0.tgz#578082d92d4fe612b13007496e543fa0fbcbe4c5" - integrity sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ== - dependencies: - asn1 "~0.2.3" - assert-plus "^1.0.0" - bcrypt-pbkdf "^1.0.0" - dashdash "^1.12.0" - ecc-jsbn "~0.1.1" - getpass "^0.1.1" - jsbn "~0.1.0" - safer-buffer "^2.0.2" - tweetnacl "~0.14.0" - -ssri@^6.0.1: - version "6.0.2" - resolved "https://registry.yarnpkg.com/ssri/-/ssri-6.0.2.tgz#157939134f20464e7301ddba3e90ffa8f7728ac5" - integrity sha512-cepbSq/neFK7xB6A50KHN0xHDotYzq58wWCa5LeWqnPrHG8GzfEjO/4O8kpmcGW+oaxkvhEJCWgbgNk4/ZV93Q== - dependencies: - figgy-pudding "^3.5.1" - -ssri@^8.0.1: - version "8.0.1" - resolved "https://registry.yarnpkg.com/ssri/-/ssri-8.0.1.tgz#638e4e439e2ffbd2cd289776d5ca457c4f51a2af" - integrity sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ== - dependencies: - minipass "^3.1.1" - stable@^0.1.8: version "0.1.8" resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf" integrity sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w== -stack-utils@^1.0.1: - version "1.0.5" - resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-1.0.5.tgz#a19b0b01947e0029c8e451d5d61a498f5bb1471b" - integrity sha512-KZiTzuV3CnSnSvgMRrARVCj+Ht7rMbauGDK0LdVFRGyenwdylpajAp4Q0i6SX8rEmbTpMMf6ryq2gb8pPq2WgQ== - dependencies: - escape-string-regexp "^2.0.0" - -stackframe@^1.3.4: - version "1.3.4" - resolved "https://registry.yarnpkg.com/stackframe/-/stackframe-1.3.4.tgz#b881a004c8c149a5e8efef37d51b16e412943310" - integrity sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw== - -state-toggle@^1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/state-toggle/-/state-toggle-1.0.3.tgz#e123b16a88e143139b09c6852221bc9815917dfe" - integrity sha512-d/5Z4/2iiCnHw6Xzghyhb+GcmF89bxwgXG60wjIiZaxnymbyOmI8Hk4VqHXiVVp6u2ysaskFfXg3ekCj4WNftQ== +stackback@0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/stackback/-/stackback-0.0.2.tgz#1ac8a0d9483848d1695e418b6d031a3c3ce68e3b" + integrity sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw== -static-extend@^0.1.1: - version "0.1.2" - resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" - integrity sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g== - dependencies: - define-property "^0.2.5" - object-copy "^0.1.0" +standard-as-callback@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/standard-as-callback/-/standard-as-callback-2.1.0.tgz#8953fc05359868a77b5b9739a665c5977bb7df45" + integrity sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A== statuses@2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== -stealthy-require@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b" - integrity sha512-ZnWpYnYugiOVEY5GkcuJK1io5V8QmNYChG62gSit9pQVGErXtrKuPC55ITaVSukmMta5qpMU7vqLt2Lnni4f/g== +std-env@^3.4.3: + version "3.5.0" + resolved "https://registry.yarnpkg.com/std-env/-/std-env-3.5.0.tgz#83010c9e29bd99bf6f605df87c19012d82d63b97" + integrity sha512-JGUEaALvL0Mf6JCfYnJOTcobY+Nc7sG/TemDRBqCA0wEr4DER7zDchaaixTlmOxAjG1uRJmX82EQcxwTQTkqVA== -stop-iteration-iterator@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz#6a60be0b4ee757d1ed5254858ec66b10c49285e4" - integrity sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ== - dependencies: - internal-slot "^1.0.4" +std-env@^3.7.0: + version "3.7.0" + resolved "https://registry.yarnpkg.com/std-env/-/std-env-3.7.0.tgz#c9f7386ced6ecf13360b6c6c55b8aaa4ef7481d2" + integrity sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg== -store2@^2.12.0, store2@^2.7.1: +store2@^2.14.2, store2@^2.7.1: version "2.14.2" resolved "https://registry.yarnpkg.com/store2/-/store2-2.14.2.tgz#56138d200f9fe5f582ad63bc2704dbc0e4a45068" integrity sha512-siT1RiqlfQnGqgT/YzXVUNsom9S0H1OX+dpdGN1xkyYATo4I6sep5NmsRD/40s3IIOvlCq6akxkqG82urIZW1w== -stream-browserify@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.2.tgz#87521d38a44aa7ee91ce1cd2a47df0cb49dd660b" - integrity sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg== +storybook@^8.0.8: + version "8.0.8" + resolved "https://registry.yarnpkg.com/storybook/-/storybook-8.0.8.tgz#1ef69577d8eb174f8d62e1bd3302a9baa157e670" + integrity sha512-9gTnnAakJBtMCg8oPGqnpy7g/C3Tj2IWiVflHiFg1SDD9zXBoc4mZhaYPTne4LRBUhXk7XuFagKfiRN2V/MuKA== dependencies: - inherits "~2.0.1" - readable-stream "^2.0.2" + "@storybook/cli" "8.0.8" stream-browserify@^3.0.0: version "3.0.0" @@ -18712,25 +18278,6 @@ stream-browserify@^3.0.0: inherits "~2.0.4" readable-stream "^3.5.0" -stream-each@^1.1.0: - version "1.2.3" - resolved "https://registry.yarnpkg.com/stream-each/-/stream-each-1.2.3.tgz#ebe27a0c389b04fbcc233642952e10731afa9bae" - integrity sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw== - dependencies: - end-of-stream "^1.1.0" - stream-shift "^1.0.0" - -stream-http@^2.7.2: - version "2.8.3" - resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.8.3.tgz#b2d242469288a5a27ec4fe8933acf623de6514fc" - integrity sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw== - dependencies: - builtin-status-codes "^3.0.0" - inherits "^2.0.1" - readable-stream "^2.3.6" - to-arraybuffer "^1.0.0" - xtend "^4.0.0" - stream-shift@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.1.tgz#d7088281559ab2778424279b0877da3c392d5a3d" @@ -18741,29 +18288,12 @@ strict-uri-encode@^2.0.0: resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz#b9c7330c7042862f6b142dc274bbcc5866ce3546" integrity sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ== -string-hash@^1.1.1: - version "1.1.3" - resolved "https://registry.yarnpkg.com/string-hash/-/string-hash-1.1.3.tgz#e8aafc0ac1855b4666929ed7dd1275df5d6c811b" - integrity sha512-kJUvRUFK49aub+a7T1nNE66EJbZBMnBgoC1UbCZ5n6bsZKBRga4KgBRTMn/pFkeCZSYtNeSyMxPDM0AXWELk2A== - -string-length@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/string-length/-/string-length-3.1.0.tgz#107ef8c23456e187a8abd4a61162ff4ac6e25837" - integrity sha512-Ttp5YvkGm5v9Ijagtaz1BnN+k9ObpvS0eIBblPMp2YWL8FBmi9qblQ9fexc2k/CXFgrTIteU3jAw3payCnwSTA== - dependencies: - astral-regex "^1.0.0" - strip-ansi "^5.2.0" - -string-width@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" - integrity sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw== - dependencies: - code-point-at "^1.0.0" - is-fullwidth-code-point "^1.0.0" - strip-ansi "^3.0.0" +string-argv@0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.3.2.tgz#2b6d0ef24b656274d957d54e0a4bbf6153dc02b6" + integrity sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q== -"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2, string-width@^4.2.3: +"string-width-cjs@npm:string-width@^4.2.0": version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -18772,94 +18302,82 @@ string-width@^1.0.1: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" -string-width@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" - integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== +string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== dependencies: - is-fullwidth-code-point "^2.0.0" - strip-ansi "^4.0.0" + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" -string-width@^3.0.0, string-width@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" - integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== +string-width@^5.0.0, string-width@^5.0.1, string-width@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794" + integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== dependencies: - emoji-regex "^7.0.1" - is-fullwidth-code-point "^2.0.0" - strip-ansi "^5.1.0" + eastasianwidth "^0.2.0" + emoji-regex "^9.2.2" + strip-ansi "^7.0.1" -"string.prototype.matchall@^4.0.0 || ^3.0.1", string.prototype.matchall@^4.0.8: - version "4.0.8" - resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-4.0.8.tgz#3bf85722021816dcd1bf38bb714915887ca79fd3" - integrity sha512-6zOCOcJ+RJAQshcTvXPHoxoQGONa3e/Lqx90wUA+wEzX78sg5Bo+1tQo4N0pohS0erG9qtCqJDjNCQBjeWVxyg== +string.prototype.matchall@^4.0.8: + version "4.0.10" + resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-4.0.10.tgz#a1553eb532221d4180c51581d6072cd65d1ee100" + integrity sha512-rGXbGmOEosIQi6Qva94HUjgPs9vKW+dkG7Y8Q5O2OYkWL6wFaTRZO8zM4mhP94uX55wgyrXzfS2aGtGzUL7EJQ== dependencies: call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.4" - get-intrinsic "^1.1.3" + define-properties "^1.2.0" + es-abstract "^1.22.1" + get-intrinsic "^1.2.1" has-symbols "^1.0.3" - internal-slot "^1.0.3" - regexp.prototype.flags "^1.4.3" + internal-slot "^1.0.5" + regexp.prototype.flags "^1.5.0" + set-function-name "^2.0.0" side-channel "^1.0.4" string.prototype.padend@^3.0.0: - version "3.1.4" - resolved "https://registry.yarnpkg.com/string.prototype.padend/-/string.prototype.padend-3.1.4.tgz#2c43bb3a89eb54b6750de5942c123d6c98dd65b6" - integrity sha512-67otBXoksdjsnXXRUq+KMVTdlVRZ2af422Y0aTyTjVaoQkGr3mxl2Bc5emi7dOQ3OGVVQQskmLEWwFXwommpNw== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.4" - -string.prototype.padstart@^3.0.0: - version "3.1.4" - resolved "https://registry.yarnpkg.com/string.prototype.padstart/-/string.prototype.padstart-3.1.4.tgz#4842d58a09df2addac23cf0b325ce9f087978e90" - integrity sha512-XqOHj8horGsF+zwxraBvMTkBFM28sS/jHBJajh17JtJKA92qazidiQbLosV4UA18azvLOVKYo/E3g3T9Y5826w== + version "3.1.5" + resolved "https://registry.yarnpkg.com/string.prototype.padend/-/string.prototype.padend-3.1.5.tgz#311ef3a4e3c557dd999cdf88fbdde223f2ac0f95" + integrity sha512-DOB27b/2UTTD+4myKUFh+/fXWcu/UDyASIXfg+7VzoCNNGOfWvoyU/x5pvVHr++ztyt/oSYI1BcWBBG/hmlNjA== dependencies: call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.4" + define-properties "^1.2.0" + es-abstract "^1.22.1" -string.prototype.trim@^1.2.7: - version "1.2.7" - resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.7.tgz#a68352740859f6893f14ce3ef1bb3037f7a90533" - integrity sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg== +string.prototype.trim@^1.2.8: + version "1.2.8" + resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz#f9ac6f8af4bd55ddfa8895e6aea92a96395393bd" + integrity sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ== dependencies: call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.4" + define-properties "^1.2.0" + es-abstract "^1.22.1" -string.prototype.trimend@^1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz#c4a27fa026d979d79c04f17397f250a462944533" - integrity sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ== +string.prototype.trimend@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.7.tgz#1bb3afc5008661d73e2dc015cd4853732d6c471e" + integrity sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA== dependencies: call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.4" + define-properties "^1.2.0" + es-abstract "^1.22.1" -string.prototype.trimstart@^1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz#e90ab66aa8e4007d92ef591bbf3cd422c56bdcf4" - integrity sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA== +string.prototype.trimstart@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz#d4cdb44b83a4737ffbac2d406e405d43d0184298" + integrity sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg== dependencies: call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.4" + define-properties "^1.2.0" + es-abstract "^1.22.1" -string_decoder@^1.0.0, string_decoder@^1.1.1: +string_decoder@^1.1.1: version "1.3.0" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== dependencies: safe-buffer "~5.2.0" -string_decoder@~0.10.x: - version "0.10.31" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" - integrity sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ== - string_decoder@~1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" @@ -18867,34 +18385,21 @@ string_decoder@~1.1.1: dependencies: safe-buffer "~5.1.0" -stringify-entities@^4.0.0: - version "4.0.3" - resolved "https://registry.yarnpkg.com/stringify-entities/-/stringify-entities-4.0.3.tgz#cfabd7039d22ad30f3cc435b0ca2c1574fc88ef8" - integrity sha512-BP9nNHMhhfcMbiuQKCqMjhDP5yBCAxsPu4pHFFzJ6Alo9dZgY4VLDPutXqIjpRiMoKdp7Av85Gr73Q5uH9k7+g== - dependencies: - character-entities-html4 "^2.0.0" - character-entities-legacy "^3.0.0" - -strip-ansi@^3.0.0, strip-ansi@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" - integrity sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg== - dependencies: - ansi-regex "^2.0.0" - -strip-ansi@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" - integrity sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow== +stringify-object@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/stringify-object/-/stringify-object-5.0.0.tgz#d5b05649fedaf8860640471641f70906fea7f351" + integrity sha512-zaJYxz2FtcMb4f+g60KsRNFOpVMUyuJgA51Zi5Z1DOTC3S59+OQiVOzE9GZt0x72uBGWKsQIuBKeF9iusmKFsg== dependencies: - ansi-regex "^3.0.0" + get-own-enumerable-keys "^1.0.0" + is-obj "^3.0.0" + is-regexp "^3.1.0" -strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" - integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== +"strip-ansi-cjs@npm:strip-ansi@^6.0.1": + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== dependencies: - ansi-regex "^4.1.0" + ansi-regex "^5.0.1" strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" @@ -18903,28 +18408,18 @@ strip-ansi@^6.0.0, strip-ansi@^6.0.1: dependencies: ansi-regex "^5.0.1" -strip-bom@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" - integrity sha512-kwrX1y7czp1E69n2ajbG65mIo9dqvJ+8aBQXOGVxqwvNbsXdFM6Lq37dLAY3mknUwru8CfcCbfOLL/gMo+fi3g== +strip-ansi@^7.0.1, strip-ansi@^7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" + integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ== dependencies: - is-utf8 "^0.2.0" + ansi-regex "^6.0.1" strip-bom@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" integrity sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA== -strip-bom@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-4.0.0.tgz#9c3505c1db45bcedca3d9cf7a16f5c5aa3901878" - integrity sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w== - -strip-eof@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" - integrity sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q== - strip-final-newline@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" @@ -18935,13 +18430,6 @@ strip-final-newline@^3.0.0: resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-3.0.0.tgz#52894c313fbff318835280aed60ff71ebf12b8fd" integrity sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw== -strip-indent@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-1.0.1.tgz#0c7962a6adefa7bbd4ac366460a638552ae1a0a2" - integrity sha512-I5iQq6aFMM62fBEAIB/hXzwJD6EEZ0xEGCX2t7oXqaKPIRgt4WruAQ285BISgdkP+HLGWyeGmNJcpIwFeRYRUA== - dependencies: - get-stdin "^4.0.1" - strip-indent@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-3.0.0.tgz#c32e1cee940b6b3432c771bc2c54bcce73cd3001" @@ -18949,16 +18437,18 @@ strip-indent@^3.0.0: dependencies: min-indent "^1.0.0" -strip-json-comments@^3.0.1: +strip-indent@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-4.0.0.tgz#b41379433dd06f5eae805e21d631e07ee670d853" + integrity sha512-mnVSV2l+Zv6BLpSD/8V87CW/y9EmmbYzGCIavsnsI6/nwn26DwffM/yztm30Z/I2DY9wdS3vXVCMnHDgZaVNoA== + dependencies: + min-indent "^1.0.1" + +strip-json-comments@^3.0.1, strip-json-comments@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== -strip-json-comments@~2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" - integrity sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ== - strong-log-transformer@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/strong-log-transformer/-/strong-log-transformer-2.1.0.tgz#0f5ed78d325e0421ac6f90f7f10e691d6ae3ae10" @@ -18968,33 +18458,26 @@ strong-log-transformer@^2.1.0: minimist "^1.2.0" through "^2.3.4" -style-loader@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-1.3.0.tgz#828b4a3b3b7e7aa5847ce7bae9e874512114249e" - integrity sha512-V7TCORko8rs9rIqkSrlMfkqA63DfoGBBJmK1kKGCcSi+BWb4cqz0SRsnp4l6rU5iwOEd0/2ePv68SV22VXon4Q== - dependencies: - loader-utils "^2.0.0" - schema-utils "^2.7.0" - -style-to-object@0.3.0, style-to-object@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/style-to-object/-/style-to-object-0.3.0.tgz#b1b790d205991cc783801967214979ee19a76e46" - integrity sha512-CzFnRRXhzWIdItT3OmF8SQfWyahHhjq3HwcMNCNLn+N7klOOqPjMeG/4JSu77D7ypZdGvSzvkrbyeTMizz2VrA== - dependencies: - inline-style-parser "0.1.1" +style-loader@^3.3.1: + version "3.3.3" + resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-3.3.3.tgz#bba8daac19930169c0c9c96706749a597ae3acff" + integrity sha512-53BiGLXAcll9maCYtZi2RCQZKa8NQQai5C4horqKyRmHj9H7QmcUyucrH+4KW/gBQbXM2AsB0axoEcFZPlfPcw== -style-to-object@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/style-to-object/-/style-to-object-0.4.1.tgz#53cf856f7cf7f172d72939d9679556469ba5de37" - integrity sha512-HFpbb5gr2ypci7Qw+IOhnP2zOU7e77b+rzM+wTzXzfi1PrtBCX0E7Pk4wL4iTLnhzZ+JgEGAhX81ebTg/aYjQw== - dependencies: - inline-style-parser "0.1.1" +subtract-object@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/subtract-object/-/subtract-object-1.1.0.tgz#a26bb771e4b861f230bf38aa6cec4b861533261d" + integrity sha512-b6J++yZCkkmP1PODlbhjy3MNHOEkzIynZfqU6KeTzgBcFHB4KgqFPf0AMU1U8he7FQa2wq6/k3MjqObcovU28w== superstruct@^0.14.2: version "0.14.2" resolved "https://registry.yarnpkg.com/superstruct/-/superstruct-0.14.2.tgz#0dbcdf3d83676588828f1cf5ed35cda02f59025b" integrity sha512-nPewA6m9mR3d6k7WkZ8N8zpTWfenFH3q9pA2PkuiZxINr9DKB2+40wEQf0ixn8VaGuJ78AB6iWOtStI+/4FKZQ== +superstruct@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/superstruct/-/superstruct-1.0.4.tgz#0adb99a7578bd2f1c526220da6571b2d485d91ca" + integrity sha512-7JpaAoX2NGyoFlI9NBh66BQXGONc+uE+MRS5i2iOBKuS4e+ccgMDjATgZldkah+33DakBxDHiss9kvUcGAO8UQ== + supports-color@^5.3.0: version "5.5.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" @@ -19002,14 +18485,7 @@ supports-color@^5.3.0: dependencies: has-flag "^3.0.0" -supports-color@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.1.0.tgz#0764abc69c63d5ac842dd4867e8d025e880df8f3" - integrity sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ== - dependencies: - has-flag "^3.0.0" - -supports-color@^7.0.0, supports-color@^7.1.0: +supports-color@^7.1.0: version "7.2.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== @@ -19023,19 +18499,16 @@ supports-color@^8.0.0: dependencies: has-flag "^4.0.0" -supports-hyperlinks@^2.0.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz#3943544347c1ff90b15effb03fc14ae45ec10624" - integrity sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA== - dependencies: - has-flag "^4.0.0" - supports-color "^7.0.0" - supports-preserve-symlinks-flag@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== +svg-parser@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/svg-parser/-/svg-parser-2.0.4.tgz#fdc2e29e13951736140b76cb122c8ee6630eb6b5" + integrity sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ== + svgo@^2.4.0: version "2.8.0" resolved "https://registry.yarnpkg.com/svgo/-/svgo-2.8.0.tgz#4ff80cce6710dc2795f0c7c74101e6764cfccd24" @@ -19043,58 +18516,46 @@ svgo@^2.4.0: dependencies: "@trysound/sax" "0.2.0" commander "^7.2.0" - css-select "^4.1.3" - css-tree "^1.1.3" - csso "^4.2.0" + css-select "^4.1.3" + css-tree "^1.1.3" + csso "^4.2.0" + picocolors "^1.0.0" + stable "^0.1.8" + +svgo@^3.0.2: + version "3.0.4" + resolved "https://registry.yarnpkg.com/svgo/-/svgo-3.0.4.tgz#67b40a710743e358e8d19ec288de8f1e388afbb4" + integrity sha512-T+Xul3JwuJ6VGXKo/p2ndqx1ibxNKnLTvRc1ZTWKCfyKS/GgNjRZcYsK84fxTsy/izr91g/Rwx6fGnVgaFSI5g== + dependencies: + "@trysound/sax" "0.2.0" + commander "^7.2.0" + css-select "^5.1.0" + css-tree "^2.2.1" + css-what "^6.1.0" + csso "5.0.5" picocolors "^1.0.0" - stable "^0.1.8" symbol-observable@^2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-2.0.3.tgz#5b521d3d07a43c351055fa43b8355b62d33fd16a" integrity sha512-sQV7phh2WCYAn81oAkakC5qjq2Ml0g8ozqz03wOGnx9dDlG1de6yrF+0RAzSJD8fPUow3PTSMf2SAbOGxb93BA== -symbol-tree@^3.2.2: - version "3.2.4" - resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" - integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== - -symbol.prototype.description@^1.0.0: - version "1.0.5" - resolved "https://registry.yarnpkg.com/symbol.prototype.description/-/symbol.prototype.description-1.0.5.tgz#d30e01263b6020fbbd2d2884a6276ce4d49ab568" - integrity sha512-x738iXRYsrAt9WBhRCVG5BtIC3B7CUkFwbHW2zOvGtwM33s7JjrCDyq8V0zgMYVb5ymsL8+qkzzpANH63CPQaQ== - dependencies: - call-bind "^1.0.2" - get-symbol-description "^1.0.0" - has-symbols "^1.0.2" - object.getownpropertydescriptors "^2.1.2" +symbol.inspect@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/symbol.inspect/-/symbol.inspect-1.0.1.tgz#e13125b8038c4996eb0dfa1567332ad4dcd0763f" + integrity sha512-YQSL4duoHmLhsTD1Pw8RW6TZ5MaTX5rXJnqacJottr2P2LZBF/Yvrc3ku4NUpMOm8aM0KOCqM+UAkMA5HWQCzQ== synchronous-promise@^2.0.15: version "2.0.17" resolved "https://registry.yarnpkg.com/synchronous-promise/-/synchronous-promise-2.0.17.tgz#38901319632f946c982152586f2caf8ddc25c032" integrity sha512-AsS729u2RHUfEra9xJrE39peJcc2stq2+poBXX8bcM08Y6g9j/i/PUzwNQqkaJde7Ntg1TO7bSREbR5sdosQ+g== -table@^5.2.3: - version "5.4.6" - resolved "https://registry.yarnpkg.com/table/-/table-5.4.6.tgz#1292d19500ce3f86053b05f0e8e7e4a3bb21079e" - integrity sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug== - dependencies: - ajv "^6.10.2" - lodash "^4.17.14" - slice-ansi "^2.1.0" - string-width "^3.0.0" - -tapable@^1.0.0, tapable@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2" - integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA== - -tapable@^2.1.1, tapable@^2.2.0: +tapable@^2.0.0, tapable@^2.1.1, tapable@^2.2.0, tapable@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== -tar-fs@^2.0.0, tar-fs@^2.1.1: +tar-fs@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.1.1.tgz#489a15ab85f1f0befabb370b7de4f9eb5cbe8784" integrity sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng== @@ -19115,14 +18576,14 @@ tar-stream@^2.1.4, tar-stream@~2.2.0: inherits "^2.0.3" readable-stream "^3.1.1" -tar@^6.0.2, tar@^6.1.11: - version "6.1.13" - resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.13.tgz#46e22529000f612180601a6fe0680e7da508847b" - integrity sha512-jdIBIN6LTIe2jqzay/2vtYLlBHa3JF42ot3h1dW8Q0PaAG4v8rm0cvpVePtau5C6OKXGGcgO9q2AMNSWxiLqKw== +tar@^6.2.0: + version "6.2.1" + resolved "https://registry.yarnpkg.com/tar/-/tar-6.2.1.tgz#717549c541bc3c2af15751bea94b1dd068d4b03a" + integrity sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A== dependencies: chownr "^2.0.0" fs-minipass "^2.0.0" - minipass "^4.0.0" + minipass "^5.0.0" minizlib "^2.1.1" mkdirp "^1.0.3" yallist "^4.0.0" @@ -19141,101 +18602,99 @@ telejson@^3.2.0: lodash "^4.17.15" memoizerific "^1.11.3" -telejson@^6.0.8: - version "6.0.8" - resolved "https://registry.yarnpkg.com/telejson/-/telejson-6.0.8.tgz#1c432db7e7a9212c1fbd941c3e5174ec385148f7" - integrity sha512-nerNXi+j8NK1QEfBHtZUN/aLdDcyupA//9kAboYLrtzZlPLpUfqbVGWb9zz91f/mIjRbAYhbgtnJHY8I1b5MBg== +telejson@^7.2.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/telejson/-/telejson-7.2.0.tgz#3994f6c9a8f8d7f2dba9be2c7c5bbb447e876f32" + integrity sha512-1QTEcJkJEhc8OnStBx/ILRu5J2p0GjvWsBx56bmZRqnrkdBMUe+nX92jxV+p3dB4CP6PZCdJMQJwCggkNBMzkQ== dependencies: - "@types/is-function" "^1.0.0" - global "^4.4.0" - is-function "^1.0.2" - is-regex "^1.1.2" - is-symbol "^1.0.3" - isobject "^4.0.0" - lodash "^4.17.21" memoizerific "^1.11.3" -term-size@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/term-size/-/term-size-2.2.1.tgz#2a6a54840432c2fb6320fea0f415531e90189f54" - integrity sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg== +temp-dir@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/temp-dir/-/temp-dir-2.0.0.tgz#bde92b05bdfeb1516e804c9c00ad45177f31321e" + integrity sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg== -terminal-link@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/terminal-link/-/terminal-link-2.1.1.tgz#14a64a27ab3c0df933ea546fba55f2d078edc994" - integrity sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ== +temp@^0.8.4: + version "0.8.4" + resolved "https://registry.yarnpkg.com/temp/-/temp-0.8.4.tgz#8c97a33a4770072e0a05f919396c7665a7dd59f2" + integrity sha512-s0ZZzd0BzYv5tLSptZooSjK8oj6C+c19p7Vqta9+6NPOf7r+fxq0cJe6/oN4LTC79sy5NY8ucOJNgwsKCSbfqg== dependencies: - ansi-escapes "^4.2.1" - supports-hyperlinks "^2.0.0" + rimraf "~2.6.2" -terser-webpack-plugin@^1.4.3: - version "1.4.5" - resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-1.4.5.tgz#a217aefaea330e734ffacb6120ec1fa312d6040b" - integrity sha512-04Rfe496lN8EYruwi6oPQkG0vo8C+HT49X687FZnpPF0qMAIHONI6HEXYPKDOE8e5HjXTyKfqRd/agHtH0kOtw== - dependencies: - cacache "^12.0.2" - find-cache-dir "^2.1.0" - is-wsl "^1.1.0" - schema-utils "^1.0.0" - serialize-javascript "^4.0.0" - source-map "^0.6.1" - terser "^4.1.2" - webpack-sources "^1.4.0" - worker-farm "^1.7.0" +tempfile@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/tempfile/-/tempfile-3.0.0.tgz#5376a3492de7c54150d0cc0612c3f00e2cdaf76c" + integrity sha512-uNFCg478XovRi85iD42egu+eSFUmmka750Jy7L5tfHI5hQKKtbPnxaSaXAbBqCDYrw3wx4tXjKwci4/QmsZJxw== + dependencies: + temp-dir "^2.0.0" + uuid "^3.3.2" -terser-webpack-plugin@^4.2.3: - version "4.2.3" - resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-4.2.3.tgz#28daef4a83bd17c1db0297070adc07fc8cfc6a9a" - integrity sha512-jTgXh40RnvOrLQNgIkwEKnQ8rmHjHK4u+6UBEi+W+FPmvb+uo+chJXntKe7/3lW5mNysgSWD60KyesnhW8D6MQ== +tempy@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/tempy/-/tempy-1.0.1.tgz#30fe901fd869cfb36ee2bd999805aa72fbb035de" + integrity sha512-biM9brNqxSc04Ee71hzFbryD11nX7VPhQQY32AdDmjFvodsRFz/3ufeoTZ6uYkRFfGo188tENcASNs3vTdsM0w== dependencies: - cacache "^15.0.5" - find-cache-dir "^3.3.1" - jest-worker "^26.5.0" - p-limit "^3.0.2" - schema-utils "^3.0.0" - serialize-javascript "^5.0.1" - source-map "^0.6.1" - terser "^5.3.4" - webpack-sources "^1.4.3" + del "^6.0.0" + is-stream "^2.0.0" + temp-dir "^2.0.0" + type-fest "^0.16.0" + unique-string "^2.0.0" + +term-size@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/term-size/-/term-size-2.2.1.tgz#2a6a54840432c2fb6320fea0f415531e90189f54" + integrity sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg== -terser-webpack-plugin@^5.1.3: - version "5.3.7" - resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.7.tgz#ef760632d24991760f339fe9290deb936ad1ffc7" - integrity sha512-AfKwIktyP7Cu50xNjXF/6Qb5lBNzYaWpU6YfoX3uZicTx0zTy0stDDCsvjDapKsSDvOeWo5MEq4TmdBy2cNoHw== +terser-webpack-plugin@^5.3.1: + version "5.3.9" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.9.tgz#832536999c51b46d468067f9e37662a3b96adfe1" + integrity sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA== dependencies: "@jridgewell/trace-mapping" "^0.3.17" jest-worker "^27.4.5" schema-utils "^3.1.1" serialize-javascript "^6.0.1" - terser "^5.16.5" + terser "^5.16.8" -terser@^4.1.2, terser@^4.6.2, terser@^4.6.3: - version "4.8.1" - resolved "https://registry.yarnpkg.com/terser/-/terser-4.8.1.tgz#a00e5634562de2239fd404c649051bf6fc21144f" - integrity sha512-4GnLC0x667eJG0ewJTa6z/yXrbLGv80D9Ru6HIpCQmO+Q4PfEtBFi0ObSckqwL6VyQv/7ENJieXHo2ANmdQwgw== +terser-webpack-plugin@^5.3.10: + version "5.3.10" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz#904f4c9193c6fd2a03f693a2150c62a92f40d199" + integrity sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w== dependencies: + "@jridgewell/trace-mapping" "^0.3.20" + jest-worker "^27.4.5" + schema-utils "^3.1.1" + serialize-javascript "^6.0.1" + terser "^5.26.0" + +terser@^5.10.0, terser@^5.16.8: + version "5.24.0" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.24.0.tgz#4ae50302977bca4831ccc7b4fef63a3c04228364" + integrity sha512-ZpGR4Hy3+wBEzVEnHvstMvqpD/nABNelQn/z2r0fjVWGQsN3bpOLzQlqDxmb4CDZnXq5lpjnQ+mHQLAOpfM5iw== + dependencies: + "@jridgewell/source-map" "^0.3.3" + acorn "^8.8.2" commander "^2.20.0" - source-map "~0.6.1" - source-map-support "~0.5.12" + source-map-support "~0.5.20" -terser@^5.16.5, terser@^5.2.0, terser@^5.3.4: - version "5.16.8" - resolved "https://registry.yarnpkg.com/terser/-/terser-5.16.8.tgz#ccde583dabe71df3f4ed02b65eb6532e0fae15d5" - integrity sha512-QI5g1E/ef7d+PsDifb+a6nnVgC4F22Bg6T0xrBrz6iloVB4PUkkunp6V8nzoOOZJIzjWVdAGqCdlKlhLq/TbIA== +terser@^5.26.0: + version "5.33.0" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.33.0.tgz#8f9149538c7468ffcb1246cfec603c16720d2db1" + integrity sha512-JuPVaB7s1gdFKPKTelwUyRq5Sid2A3Gko2S0PncwdBq7kN9Ti9HPWDQ06MPsEDGsZeVESjKEnyGy68quBk1w6g== dependencies: - "@jridgewell/source-map" "^0.3.2" - acorn "^8.5.0" + "@jridgewell/source-map" "^0.3.3" + acorn "^8.8.2" commander "^2.20.0" source-map-support "~0.5.20" -test-exclude@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-6.0.0.tgz#04a8698661d805ea6fa293b6cb9e63ac044ef15e" - integrity sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w== +test-exclude@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-7.0.1.tgz#20b3ba4906ac20994e275bbcafd68d510264c2a2" + integrity sha512-pFYqmTw68LXVjeWJMST4+borgQP2AyMNbg1BpZh9LbyhUeNkeaPF9gzfPGUAnSMV3qPYdWUwDIjjCLiSDOl7vg== dependencies: "@istanbuljs/schema" "^0.1.2" - glob "^7.1.4" - minimatch "^3.0.4" + glob "^10.4.1" + minimatch "^9.0.4" text-encoding-utf-8@^1.0.2: version "1.0.2" @@ -19247,17 +18706,24 @@ text-extensions@^1.0.0: resolved "https://registry.yarnpkg.com/text-extensions/-/text-extensions-1.9.0.tgz#1853e45fee39c945ce6f6c36b2d659b5aabc2a26" integrity sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ== +text-extensions@^2.0.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/text-extensions/-/text-extensions-2.4.0.tgz#a1cfcc50cf34da41bfd047cc744f804d1680ea34" + integrity sha512-te/NtwBwfiNRLf9Ijqx3T0nlqZiQ2XrrtBvu+cLL8ZRrGkO0NHTug8MYFKyoSrv/sHTaSKfilUkizV6XhxMJ3g== + text-table@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== -throat@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/throat/-/throat-5.0.0.tgz#c5199235803aad18754a667d659b5e72ce16764b" - integrity sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA== +thread-stream@^0.15.1: + version "0.15.2" + resolved "https://registry.yarnpkg.com/thread-stream/-/thread-stream-0.15.2.tgz#fb95ad87d2f1e28f07116eb23d85aba3bc0425f4" + integrity sha512-UkEhKIg2pD+fjkHQKyJO3yoIvAP3N6RlNFt2dUhcS1FGvCD1cQa1M/PGknCLFIyZdtJOWQjejp7bdNqmN7zwdA== + dependencies: + real-require "^0.1.0" -through2@^2.0.0, through2@^2.0.2, through2@^2.0.3: +through2@^2.0.0, through2@^2.0.3: version "2.0.5" resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ== @@ -19272,25 +18738,11 @@ through2@^4.0.0: dependencies: readable-stream "3" -"through@>=2.2.7 <3", through@^2.3.4, through@^2.3.6: +through@2, "through@>=2.2.7 <3", through@^2.3.4, through@^2.3.6: version "2.3.8" resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg== -time-span@4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/time-span/-/time-span-4.0.0.tgz#fe74cd50a54e7998712f90ddfe47109040c985c4" - integrity sha512-MyqZCTGLDZ77u4k+jqg4UlrzPTPZ49NDlaekU6uuFaJLzPIN1woaRXCbGeqOfxwc3Y37ZROGAJ614Rdv7Olt+g== - dependencies: - convert-hrtime "^3.0.0" - -timers-browserify@^2.0.4: - version "2.0.12" - resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.12.tgz#44a45c11fbf407f34f97bccd1577c652361b00ee" - integrity sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ== - dependencies: - setimmediate "^1.0.4" - timsort@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/timsort/-/timsort-0.3.0.tgz#405411a8e7e6339fe64db9a234de11dc31e02bd4" @@ -19301,15 +18753,17 @@ tiny-emitter@^2.0.0: resolved "https://registry.yarnpkg.com/tiny-emitter/-/tiny-emitter-2.1.0.tgz#1d1a56edfc51c43e863cbb5382a72330e3555423" integrity sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q== -tiny-glob@^0.2.6: - version "0.2.9" - resolved "https://registry.yarnpkg.com/tiny-glob/-/tiny-glob-0.2.9.tgz#2212d441ac17928033b110f8b3640683129d31e2" - integrity sha512-g/55ssRPUjShh+xkfx9UPDXqhckHEsHr4Vd9zX55oSdGZc/MD0m3sferOkwWtp98bv+kcVfEHtRJgBVJzelrzg== - dependencies: - globalyzer "0.1.0" - globrex "^0.1.2" +tiny-invariant@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.3.1.tgz#8560808c916ef02ecfd55e66090df23a4b7aa642" + integrity sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw== + +tiny-invariant@^1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.3.3.tgz#46680b7a873a0d5d10005995eb90a70d74d60127" + integrity sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg== -tiny-secp256k1@^1.1.3: +tiny-secp256k1@^1.1.3, tiny-secp256k1@^1.1.6: version "1.1.6" resolved "https://registry.yarnpkg.com/tiny-secp256k1/-/tiny-secp256k1-1.1.6.tgz#7e224d2bee8ab8283f284e40e6b4acb74ffe047c" integrity sha512-FmqJZGduTyvsr2cF3375fqGHUovSwDi/QytexX1Se4BPuPZpTE5Ftp5fg+EFSuEf3lhZqgCRjEG3ydUQ/aNiwA== @@ -19320,11 +18774,31 @@ tiny-secp256k1@^1.1.3: elliptic "^6.4.0" nan "^2.13.2" +tinybench@^2.8.0: + version "2.9.0" + resolved "https://registry.yarnpkg.com/tinybench/-/tinybench-2.9.0.tgz#103c9f8ba6d7237a47ab6dd1dcff77251863426b" + integrity sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg== + tinycolor2@^1.4.1: version "1.6.0" resolved "https://registry.yarnpkg.com/tinycolor2/-/tinycolor2-1.6.0.tgz#f98007460169b0263b97072c5ae92484ce02d09e" integrity sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw== +tinypool@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/tinypool/-/tinypool-1.0.0.tgz#a68965218e04f4ad9de037d2a1cd63cda9afb238" + integrity sha512-KIKExllK7jp3uvrNtvRBYBWBOAXSX8ZvoaD8T+7KB/QHIuoJW3Pmr60zucywjAlMb5TeXUkcs/MWeWLu0qvuAQ== + +tinyrainbow@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/tinyrainbow/-/tinyrainbow-1.2.0.tgz#5c57d2fc0fb3d1afd78465c33ca885d04f02abb5" + integrity sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ== + +tinyspy@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/tinyspy/-/tinyspy-3.0.0.tgz#cb61644f2713cd84dee184863f4642e06ddf0585" + integrity sha512-q5nmENpTHgiPVd1cJDDc9cVoYN5x4vCvwT3FMilvKPKneCBZAxn2YWQjDF0UMcE9k0Cay1gBiDfTMU0g+mPMQA== + tmp@^0.0.33: version "0.0.33" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" @@ -19332,43 +18806,18 @@ tmp@^0.0.33: dependencies: os-tmpdir "~1.0.2" -tmp@~0.2.1: +tmp@^0.2.1, tmp@~0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.1.tgz#8457fc3037dcf4719c251367a1af6500ee1ccf14" integrity sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ== dependencies: rimraf "^3.0.0" -tmpl@1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc" - integrity sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw== - -to-arraybuffer@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" - integrity sha512-okFlQcoGTi4LQBG/PgSYblw9VOyptsz2KJZqc6qtgGdes8VktzUQkj4BI2blit072iS8VODNcMA+tvnS9dnuMA== - to-fast-properties@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" integrity sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog== -to-object-path@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" - integrity sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg== - dependencies: - kind-of "^3.0.2" - -to-regex-range@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" - integrity sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg== - dependencies: - is-number "^3.0.0" - repeat-string "^1.6.1" - to-regex-range@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" @@ -19376,15 +18825,10 @@ to-regex-range@^5.0.1: dependencies: is-number "^7.0.0" -to-regex@^3.0.1, to-regex@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" - integrity sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw== - dependencies: - define-property "^2.0.2" - extend-shallow "^3.0.2" - regex-not "^1.0.2" - safe-regex "^1.1.0" +tocbot@^4.20.1: + version "4.23.0" + resolved "https://registry.yarnpkg.com/tocbot/-/tocbot-4.23.0.tgz#5d3788ccf5a8b0ae2c00819b1ed0c127013e2e34" + integrity sha512-5DWuSZXsqG894mkGb8ZsQt9myyQyVxE50AiGRZ0obV0BVUTVkaZmc9jbgpknaAAPUm4FIrzGkEseD6FuQJYJDQ== toggle-selection@^1.0.6: version "1.0.6" @@ -19396,28 +18840,6 @@ toidentifier@1.0.1: resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== -toml@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/toml/-/toml-3.0.0.tgz#342160f1af1904ec9d204d03a5d61222d762c5ee" - integrity sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w== - -tough-cookie@^2.3.3, tough-cookie@~2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" - integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== - dependencies: - psl "^1.1.28" - punycode "^2.1.1" - -tough-cookie@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-3.0.1.tgz#9df4f57e739c26930a018184887f4adb7dca73b2" - integrity sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg== - dependencies: - ip-regex "^2.1.0" - psl "^1.1.28" - punycode "^2.1.1" - tr46@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09" @@ -19430,36 +18852,11 @@ tr46@~0.0.3: resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== -trim-newlines@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613" - integrity sha512-Nm4cF79FhSTzrLKGDMi3I4utBtFv8qKy4sq1enftf2gMdpqI8oVQTAfySkTz5r49giVzDj88SVZXP4CeYQwjaw== - trim-newlines@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-3.0.1.tgz#260a5d962d8b752425b32f3a7db0dcacd176c144" integrity sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw== -trim-trailing-lines@^1.0.0: - version "1.1.4" - resolved "https://registry.yarnpkg.com/trim-trailing-lines/-/trim-trailing-lines-1.1.4.tgz#bd4abbec7cc880462f10b2c8b5ce1d8d1ec7c2c0" - integrity sha512-rjUWSqnfTNrjbB9NQWfPMH/xRK1deHeGsHoVfpxJ++XeYXE0d6B1En37AHfw3jtfTU7dzMzZL2jjpe8Qb5gLIQ== - -trim@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/trim/-/trim-0.0.1.tgz#5858547f6b290757ee95cccc666fb50084c460dd" - integrity sha512-YzQV+TZg4AxpKxaTHK3c3D+kRDCGVEE7LemdlQZoQXn0iennk10RsIoY6ikzAqJTc9Xjl9C1/waHom/J86ziAQ== - -trough@^1.0.0: - version "1.0.5" - resolved "https://registry.yarnpkg.com/trough/-/trough-1.0.5.tgz#b8b639cefad7d0bb2abd37d433ff8293efa5f406" - integrity sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA== - -trough@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/trough/-/trough-2.1.0.tgz#0f7b511a4fde65a46f18477ab38849b22c554876" - integrity sha512-AqTiAOLcj85xS7vQ8QkAV41hPDIJ71XJB4RCUrzo/1GM2CQwhkJGaf9Hgr7BOugMRpgGUrqRg/DrBDl4H40+8g== - ts-dedent@^1.1.0: version "1.2.0" resolved "https://registry.yarnpkg.com/ts-dedent/-/ts-dedent-1.2.0.tgz#6aa2229d837159bb6d635b6b233002423b91e0b0" @@ -19470,60 +18867,12 @@ ts-dedent@^2.0.0: resolved "https://registry.yarnpkg.com/ts-dedent/-/ts-dedent-2.2.0.tgz#39e4bd297cd036292ae2394eb3412be63f563bb5" integrity sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ== -ts-jest@^25.3.1: - version "25.5.1" - resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-25.5.1.tgz#2913afd08f28385d54f2f4e828be4d261f4337c7" - integrity sha512-kHEUlZMK8fn8vkxDjwbHlxXRB9dHYpyzqKIGDNxbzs+Rz+ssNDSDNusEK8Fk/sDd4xE6iKoQLfFkFVaskmTJyw== - dependencies: - bs-logger "0.x" - buffer-from "1.x" - fast-json-stable-stringify "2.x" - json5 "2.x" - lodash.memoize "4.x" - make-error "1.x" - micromatch "4.x" - mkdirp "0.x" - semver "6.x" - yargs-parser "18.x" - -ts-morph@12.0.0: - version "12.0.0" - resolved "https://registry.yarnpkg.com/ts-morph/-/ts-morph-12.0.0.tgz#a601c3538703755cbfa2d42b62c52df73e9dbbd7" - integrity sha512-VHC8XgU2fFW7yO1f/b3mxKDje1vmyzFXHWzOYmKEkCEwcLjDtbdLgBQviqj4ZwP4MJkQtRo6Ha2I29lq/B+VxA== - dependencies: - "@ts-morph/common" "~0.11.0" - code-block-writer "^10.1.1" - -ts-node@10.9.1: - version "10.9.1" - resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.1.tgz#e73de9102958af9e1f0b168a6ff320e25adcff4b" - integrity sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw== - dependencies: - "@cspotcode/source-map-support" "^0.8.0" - "@tsconfig/node10" "^1.0.7" - "@tsconfig/node12" "^1.0.7" - "@tsconfig/node14" "^1.0.0" - "@tsconfig/node16" "^1.0.2" - acorn "^8.4.1" - acorn-walk "^8.1.1" - arg "^4.1.0" - create-require "^1.1.0" - diff "^4.0.1" - make-error "^1.1.1" - v8-compile-cache-lib "^3.0.1" - yn "3.1.1" - -ts-pnp@^1.1.6: - version "1.2.0" - resolved "https://registry.yarnpkg.com/ts-pnp/-/ts-pnp-1.2.0.tgz#a500ad084b0798f1c3071af391e65912c86bca92" - integrity sha512-csd+vJOb/gkzvcCHgTGSChYpy5f1/XKNsmvBGO4JXS+z1v2HobugDz4s1IeFXM3wZB44uczs+eazB5Q/ccdhQw== - -ts-toolbelt@^6.15.5: - version "6.15.5" - resolved "https://registry.yarnpkg.com/ts-toolbelt/-/ts-toolbelt-6.15.5.tgz#cb3b43ed725cb63644782c64fbcad7d8f28c0a83" - integrity sha512-FZIXf1ksVyLcfr7M317jbB67XFJhOO1YqdTcuGaq9q5jLUoTikukZ+98TPjKiP2jC5CgmYdWWYs0s2nLSU0/1A== +ts-mixer@^6.0.3: + version "6.0.4" + resolved "https://registry.yarnpkg.com/ts-mixer/-/ts-mixer-6.0.4.tgz#1da39ceabc09d947a82140d9f09db0f84919ca28" + integrity sha512-ufKpbmrugz5Aou4wcr5Wc1UUFWOLhq+Fm6qa6P0w0K5Qw2yhaUoiWszhCVuNQyNwrlGiscHOmqYoAox1PtvgjA== -tsconfig-paths@^3.14.1: +tsconfig-paths@^3.14.2: version "3.14.2" resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz#6e32f1f79412decd261f92d633a9dc1cfa99f088" integrity sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g== @@ -19533,7 +18882,7 @@ tsconfig-paths@^3.14.1: minimist "^1.2.6" strip-bom "^3.0.0" -tsconfig-paths@^4.0.0, tsconfig-paths@^4.1.2: +tsconfig-paths@^4.1.2, tsconfig-paths@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz#ef78e19039133446d244beac0fd6a1632e2d107c" integrity sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg== @@ -19542,118 +18891,64 @@ tsconfig-paths@^4.0.0, tsconfig-paths@^4.1.2: minimist "^1.2.6" strip-bom "^3.0.0" -tsdx@^0.14.1: - version "0.14.1" - resolved "https://registry.yarnpkg.com/tsdx/-/tsdx-0.14.1.tgz#8771d509b6fc523ad971bae3a63ebe3a88355ab3" - integrity sha512-keHmFdCL2kx5nYFlBdbE3639HQ2v9iGedAFAajobrUTH2wfX0nLPdDhbHv+GHLQZqf0c5ur1XteE8ek/+Eyj5w== - dependencies: - "@babel/core" "^7.4.4" - "@babel/helper-module-imports" "^7.0.0" - "@babel/parser" "^7.11.5" - "@babel/plugin-proposal-class-properties" "^7.4.4" - "@babel/preset-env" "^7.11.0" - "@babel/traverse" "^7.11.5" - "@rollup/plugin-babel" "^5.1.0" - "@rollup/plugin-commonjs" "^11.0.0" - "@rollup/plugin-json" "^4.0.0" - "@rollup/plugin-node-resolve" "^9.0.0" - "@rollup/plugin-replace" "^2.2.1" - "@types/jest" "^25.2.1" - "@typescript-eslint/eslint-plugin" "^2.12.0" - "@typescript-eslint/parser" "^2.12.0" - ansi-escapes "^4.2.1" - asyncro "^3.0.0" - babel-eslint "^10.0.3" - babel-plugin-annotate-pure-calls "^0.4.0" - babel-plugin-dev-expression "^0.2.1" - babel-plugin-macros "^2.6.1" - babel-plugin-polyfill-regenerator "^0.0.4" - babel-plugin-transform-rename-import "^2.3.0" - camelcase "^6.0.0" - chalk "^4.0.0" - enquirer "^2.3.4" - eslint "^6.1.0" - eslint-config-prettier "^6.0.0" - eslint-config-react-app "^5.2.1" - eslint-plugin-flowtype "^3.13.0" - eslint-plugin-import "^2.18.2" - eslint-plugin-jsx-a11y "^6.2.3" - eslint-plugin-prettier "^3.1.0" - eslint-plugin-react "^7.14.3" - eslint-plugin-react-hooks "^2.2.0" - execa "^4.0.3" - fs-extra "^9.0.0" - jest "^25.3.0" - jest-watch-typeahead "^0.5.0" - jpjs "^1.2.1" - lodash.merge "^4.6.2" - ora "^4.0.3" - pascal-case "^3.1.1" - prettier "^1.19.1" - progress-estimator "^0.2.2" - regenerator-runtime "^0.13.7" - rollup "^1.32.1" - rollup-plugin-sourcemaps "^0.6.2" - rollup-plugin-terser "^5.1.2" - rollup-plugin-typescript2 "^0.27.3" - sade "^1.4.2" - semver "^7.1.1" - shelljs "^0.8.3" - tiny-glob "^0.2.6" - ts-jest "^25.3.1" - tslib "^1.9.3" - typescript "^3.7.3" - -tslib@1.14.1, tslib@^1.8.1, tslib@^1.9.0, tslib@^1.9.3: +tslib@1.14.1, tslib@^1.13.0, tslib@^1.8.1, tslib@^1.9.0: version "1.14.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== -tslib@2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.0.1.tgz#410eb0d113e5b6356490eec749603725b021b43e" - integrity sha512-SgIkNheinmEBgx1IUNirK0TUD4X9yjjBRTqqjggWCU3pUEqIk3/Uwl3yRixYKT6WjQuGiwDv4NomL3wqRCj+CQ== +tslib@2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3" + integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ== -tslib@^2.0.0, tslib@^2.0.1, tslib@^2.0.3, tslib@^2.1.0, tslib@^2.3.0, tslib@^2.4.0, tslib@^2.4.1: - version "2.5.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.5.0.tgz#42bfed86f5787aeb41d031866c8f402429e0fddf" - integrity sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg== +tslib@^2.0.0, tslib@^2.0.1, tslib@^2.0.3, tslib@^2.1.0, tslib@^2.3.0, tslib@^2.3.1, tslib@^2.4.0, tslib@^2.4.1: + version "2.6.2" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae" + integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== -tsutils@^3.17.1: +tsutils@^3.21.0: version "3.21.0" resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA== dependencies: tslib "^1.8.1" -tty-browserify@0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6" - integrity sha512-JVa5ijo+j/sOoHGjw0sxw734b1LhBkQ3bvUGNdxnVXDCX81Yx7TFgnZygxrIIWn23hbfTaMYLwRmAxFyDuFmIw== +tty-browserify@^0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.1.tgz#3f05251ee17904dfd0677546670db9651682b811" + integrity sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw== + +tunnel@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/tunnel/-/tunnel-0.0.6.tgz#72f1314b34a5b192db012324df2cc587ca47f92c" + integrity sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg== -tunnel-agent@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" - integrity sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w== - dependencies: - safe-buffer "^5.0.1" +tween-functions@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/tween-functions/-/tween-functions-1.2.0.tgz#1ae3a50e7c60bb3def774eac707acbca73bbc3ff" + integrity sha512-PZBtLYcCLtEcjL14Fzb1gSxPBeL7nWvGhO5ZFPGqziCcr8uvHp0NDmdjBchp6KHL+tExcg0m3NISmKxhU394dA== -tweetnacl@^0.14.3, tweetnacl@~0.14.0: - version "0.14.5" - resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" - integrity sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA== +tweetnacl-util@^0.15.1: + version "0.15.1" + resolved "https://registry.yarnpkg.com/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz#b80fcdb5c97bcc508be18c44a4be50f022eea00b" + integrity sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw== -type-check@~0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" - integrity sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg== +tweetnacl@1.0.3, tweetnacl@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-1.0.3.tgz#ac0af71680458d8a6378d0d0d050ab1407d35596" + integrity sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw== + +type-check@^0.4.0, type-check@~0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" + integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== dependencies: - prelude-ls "~1.1.2" + prelude-ls "^1.2.1" -type-detect@4.0.8: - version "4.0.8" - resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" - integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== +type-fest@^0.16.0: + version "0.16.0" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.16.0.tgz#3240b891a78b0deae910dbeb86553e552a148860" + integrity sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg== type-fest@^0.18.0: version "0.18.1" @@ -19680,6 +18975,16 @@ type-fest@^0.8.1: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== +type-fest@^1.0.2: + version "1.4.0" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-1.4.0.tgz#e9fb813fe3bf1744ec359d55d1affefa76f14be1" + integrity sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA== + +type-fest@^2.19.0, type-fest@~2.19: + version "2.19.0" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-2.19.0.tgz#88068015bb33036a598b952e55e9311a60fd3a9b" + integrity sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA== + type-is@~1.6.18: version "1.6.18" resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" @@ -19693,6 +18998,36 @@ type-tagger@^1.0.0: resolved "https://registry.yarnpkg.com/type-tagger/-/type-tagger-1.0.0.tgz#dc6297e52e17097c1b92b42c16816a18f631e7f4" integrity sha512-FIPqqpmDgdaulCnRoKv1/d3U4xVBUrYn42QXWNP3XYmgfPUDuBUsgFOb9ntT0aIe0UsUP+lknpQ5d9Kn36RssA== +typed-array-buffer@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz#18de3e7ed7974b0a729d3feecb94338d1472cd60" + integrity sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.2.1" + is-typed-array "^1.1.10" + +typed-array-byte-length@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz#d787a24a995711611fb2b87a4052799517b230d0" + integrity sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA== + dependencies: + call-bind "^1.0.2" + for-each "^0.3.3" + has-proto "^1.0.1" + is-typed-array "^1.1.10" + +typed-array-byte-offset@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz#cbbe89b51fdef9cd6aaf07ad4707340abbc4ea0b" + integrity sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg== + dependencies: + available-typed-arrays "^1.0.5" + call-bind "^1.0.2" + for-each "^0.3.3" + has-proto "^1.0.1" + is-typed-array "^1.1.10" + typed-array-length@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/typed-array-length/-/typed-array-length-1.0.4.tgz#89d83785e5c4098bec72e08b319651f0eac9c1bb" @@ -19707,7 +19042,7 @@ typed-styles@^0.0.7: resolved "https://registry.yarnpkg.com/typed-styles/-/typed-styles-0.0.7.tgz#93392a008794c4595119ff62dde6809dbc40a3d9" integrity sha512-pzP0PWoZUhsECYjABgCGQlRGL1n7tOHsgwYv3oIiEpJwGhFTuty/YNeduxQYzXXa3Ge5BdT6sHYIQYpl4uJ+5Q== -typedarray-to-buffer@3.1.5, typedarray-to-buffer@^3.1.5: +typedarray-to-buffer@3.1.5: version "3.1.5" resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q== @@ -19719,55 +19054,52 @@ typedarray@^0.0.6: resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" integrity sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA== -typeforce@^1.11.5: +typeforce@^1.11.5, typeforce@^1.18.0: version "1.18.0" resolved "https://registry.yarnpkg.com/typeforce/-/typeforce-1.18.0.tgz#d7416a2c5845e085034d70fcc5b6cc4a90edbfdc" integrity sha512-7uc1O8h1M1g0rArakJdf0uLRSSgFcYexrVoKo+bzJd32gd4gDy2L/Z+8/FjPnU9ydY3pEnVPtr9FyscYY60K1g== -typescript@4.3.4: - version "4.3.4" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.3.4.tgz#3f85b986945bcf31071decdd96cf8bfa65f9dcbc" - integrity sha512-uauPG7XZn9F/mo+7MrsRjyvbxFpzemRjKEZXS4AK83oP2KKOJPvb+9cO/gmnv8arWZvhnjVOXz7B49m1l0e9Ew== - -typescript@^3.7.3: - version "3.9.10" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.10.tgz#70f3910ac7a51ed6bef79da7800690b19bf778b8" - integrity sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q== - -typescript@^4.8.4, typescript@^4.9.3: - version "4.9.5" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a" - integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g== +typescript@^5.3.3: + version "5.3.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.3.3.tgz#b3ce6ba258e72e6305ba66f5c9b452aaee3ffe37" + integrity sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw== typical@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/typical/-/typical-4.0.0.tgz#cbeaff3b9d7ae1e2bbfaf5a4e6f11eccfde94fc4" integrity sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw== -u2f-api@0.2.7: - version "0.2.7" - resolved "https://registry.yarnpkg.com/u2f-api/-/u2f-api-0.2.7.tgz#17bf196b242f6bf72353d9858e6a7566cc192720" - integrity sha512-fqLNg8vpvLOD5J/z4B6wpPg4Lvowz1nJ9xdHcCzdUPKcFE/qNCceV2gNZxSJd5vhAZemHr/K/hbzVA0zxB5mkg== - ua-parser-js@^0.7.30: - version "0.7.35" - resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.35.tgz#8bda4827be4f0b1dda91699a29499575a1f1d307" - integrity sha512-veRf7dawaj9xaWEu9HoTVn5Pggtc/qj+kqTOFvNiN1l0YdxwC1kvel57UCjThjGa3BHBihE8/UJAHI+uQHmd/g== + version "0.7.37" + resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.37.tgz#e464e66dac2d33a7a1251d7d7a99d6157ec27832" + integrity sha512-xV8kqRKM+jhMvcHWUKthV9fNebIzrNy//2O9ZwWcfiBFR5f25XVZPLlEajk/sf3Ra15V92isyQqnIEXRDaZWEA== -ufo@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/ufo/-/ufo-1.1.1.tgz#e70265e7152f3aba425bd013d150b2cdf4056d7c" - integrity sha512-MvlCc4GHrmZdAllBc0iUDowff36Q9Ndw/UzqmEKyrfSzokTd9ZCy1i+IIk5hrYKkjoYVQyNbrw7/F8XJ2rEwTg== +ua-parser-js@^1.0.35: + version "1.0.39" + resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-1.0.39.tgz#bfc07f361549bf249bd8f4589a4cccec18fd2018" + integrity sha512-k24RCVWlEcjkdOxYmVJgeD/0a1TiSpqLg+ZalVGV9lsnr4yqu0w7tX/x2xX6G4zpkgQnRf89lxuZ1wsbjXM8lw== + +ua-parser-js@^1.0.37: + version "1.0.38" + resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-1.0.38.tgz#66bb0c4c0e322fe48edfe6d446df6042e62f25e2" + integrity sha512-Aq5ppTOfvrCMgAPneW1HfWj66Xi7XL+/mIy996R1/CLS/rcyJQm6QZdsKrUeivDFQ+Oc9Wyuwor8Ze8peEoUoQ== + +ufo@^1.3.0, ufo@^1.3.1, ufo@^1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/ufo/-/ufo-1.3.2.tgz#c7d719d0628a1c80c006d2240e0d169f6e3c0496" + integrity sha512-o+ORpgGwaYQXgqGDwd+hkS4PuZ3QnmqMMxRuajK/a38L6fTpcE5GPIfrf+L/KemFzfUpeUQc1rRS1iDBozvnFA== uglify-js@^3.1.4: version "3.17.4" resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.17.4.tgz#61678cf5fa3f5b7eb789bb345df29afb8257c22c" integrity sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g== -ultron@~1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.1.1.tgz#9fe1536a10a664a65266a1e3ccf85fd36302bc9c" - integrity sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og== +uint8arrays@^3.0.0, uint8arrays@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/uint8arrays/-/uint8arrays-3.1.1.tgz#2d8762acce159ccd9936057572dade9459f65ae0" + integrity sha512-+QJa8QRnbdXVpHYjLoTpJIdCTiw9Ir62nocClWuXIq2JIh4Uta0cQsTSpFL678p2CN8B+XSApwcU+pQEqVpKWg== + dependencies: + multiformats "^9.4.2" unbox-primitive@^1.0.2: version "1.0.2" @@ -19779,19 +19111,39 @@ unbox-primitive@^1.0.2: has-symbols "^1.0.3" which-boxed-primitive "^1.0.2" +uncrypto@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/uncrypto/-/uncrypto-0.1.3.tgz#e1288d609226f2d02d8d69ee861fa20d8348ef2b" + integrity sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q== + +undici-types@~5.26.4: + version "5.26.5" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617" + integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== + +undici@^5.25.4: + version "5.28.4" + resolved "https://registry.yarnpkg.com/undici/-/undici-5.28.4.tgz#6b280408edb6a1a604a9b20340f45b422e373068" + integrity sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g== + dependencies: + "@fastify/busboy" "^2.0.0" + +unenv@^1.7.4: + version "1.8.0" + resolved "https://registry.yarnpkg.com/unenv/-/unenv-1.8.0.tgz#0f860d5278405700bd95d47b23bc01f3a735d68c" + integrity sha512-uIGbdCWZfhRRmyKj1UioCepQ0jpq638j/Cf0xFTn4zD1nGJ2lSdzYHLzfdXN791oo/0juUiSWW1fBklXMTsuqg== + dependencies: + consola "^3.2.3" + defu "^6.1.3" + mime "^3.0.0" + node-fetch-native "^1.4.1" + pathe "^1.1.1" + unfetch@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/unfetch/-/unfetch-4.2.0.tgz#7e21b0ef7d363d8d9af0fb929a5555f6ef97a3be" integrity sha512-F9p7yYCn6cIW9El1zi0HI6vqpeIvBsr3dSuRO6Xuppb1u5rXpCPmMvLSyECLhybr9isec8Ohl0hPekMVrEinDA== -unherit@^1.0.4: - version "1.1.3" - resolved "https://registry.yarnpkg.com/unherit/-/unherit-1.1.3.tgz#6c9b503f2b41b262330c80e91c8614abdaa69c22" - integrity sha512-Ft16BJcnapDKp0+J/rqFC3Rrk6Y/Ng4nzsC028k2jdDII/rdZ7Wd3pPT/6+vIIxRagwRc9K0IUX0Ra4fKvw+WQ== - dependencies: - inherits "^2.0.0" - xtend "^4.0.0" - unicode-canonical-property-names-ecmascript@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz#301acdc525631670d39f6146e0e77ff6bbdebddc" @@ -19815,187 +19167,41 @@ unicode-property-aliases-ecmascript@^2.0.0: resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz#43d41e3be698bd493ef911077c9b131f827e8ccd" integrity sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w== -unified@9.2.0: - version "9.2.0" - resolved "https://registry.yarnpkg.com/unified/-/unified-9.2.0.tgz#67a62c627c40589edebbf60f53edfd4d822027f8" - integrity sha512-vx2Z0vY+a3YoTj8+pttM3tiJHCwY5UFbYdiWrwBEbHmK8pvsPj2rtAX2BFfgXen8T39CJWblWRDT4L5WGXtDdg== - dependencies: - bail "^1.0.0" - extend "^3.0.0" - is-buffer "^2.0.0" - is-plain-obj "^2.0.0" - trough "^1.0.0" - vfile "^4.0.0" - -unified@^10.0.0: - version "10.1.2" - resolved "https://registry.yarnpkg.com/unified/-/unified-10.1.2.tgz#b1d64e55dafe1f0b98bb6c719881103ecf6c86df" - integrity sha512-pUSWAi/RAnVy1Pif2kAoeWNBa3JVrx0MId2LASj8G+7AiHWoKZNTomq6LG326T68U7/e263X6fTdcXIy7XnF7Q== - dependencies: - "@types/unist" "^2.0.0" - bail "^2.0.0" - extend "^3.0.0" - is-buffer "^2.0.0" - is-plain-obj "^4.0.0" - trough "^2.0.0" - vfile "^5.0.0" - -union-value@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847" - integrity sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg== - dependencies: - arr-union "^3.1.0" - get-value "^2.0.6" - is-extendable "^0.1.1" - set-value "^2.0.1" - -unique-filename@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.1.tgz#1d69769369ada0583103a1e6ae87681b56573230" - integrity sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ== - dependencies: - unique-slug "^2.0.0" - -unique-slug@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-2.0.2.tgz#baabce91083fc64e945b0f3ad613e264f7cd4e6c" - integrity sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w== - dependencies: - imurmurhash "^0.1.4" - -unist-builder@2.0.3, unist-builder@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/unist-builder/-/unist-builder-2.0.3.tgz#77648711b5d86af0942f334397a33c5e91516436" - integrity sha512-f98yt5pnlMWlzP539tPc4grGMsFaQQlP/vM396b00jngsiINumNmsY8rkXjfoi1c6QaM8nQ3vaGDuoKWbe/1Uw== - -unist-builder@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/unist-builder/-/unist-builder-3.0.1.tgz#258b89dcadd3c973656b2327b347863556907f58" - integrity sha512-gnpOw7DIpCA0vpr6NqdPvTWnlPTApCTRzr+38E6hCWx3rz/cjo83SsKIlS1Z+L5ttScQ2AwutNnb8+tAvpb6qQ== - dependencies: - "@types/unist" "^2.0.0" - -unist-util-generated@^1.0.0: - version "1.1.6" - resolved "https://registry.yarnpkg.com/unist-util-generated/-/unist-util-generated-1.1.6.tgz#5ab51f689e2992a472beb1b35f2ce7ff2f324d4b" - integrity sha512-cln2Mm1/CZzN5ttGK7vkoGw+RZ8VcUH6BtGbq98DDtRGquAAOXig1mrBQYelOwMXYS8rK+vZDyyojSjp7JX+Lg== - -unist-util-generated@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/unist-util-generated/-/unist-util-generated-2.0.1.tgz#e37c50af35d3ed185ac6ceacb6ca0afb28a85cae" - integrity sha512-qF72kLmPxAw0oN2fwpWIqbXAVyEqUzDHMsbtPvOudIlUzXYFIeQIuxXQCRCFh22B7cixvU0MG7m3MW8FTq/S+A== - -unist-util-is@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/unist-util-is/-/unist-util-is-4.1.0.tgz#976e5f462a7a5de73d94b706bac1b90671b57797" - integrity sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg== - -unist-util-is@^5.0.0: - version "5.2.1" - resolved "https://registry.yarnpkg.com/unist-util-is/-/unist-util-is-5.2.1.tgz#b74960e145c18dcb6226bc57933597f5486deae9" - integrity sha512-u9njyyfEh43npf1M+yGKDGVPbY/JWEemg5nH05ncKPfi+kBbKBJoTdsogMu33uhytuLlv9y0O7GH7fEdwLdLQw== - dependencies: - "@types/unist" "^2.0.0" - -unist-util-position-from-estree@^1.0.0, unist-util-position-from-estree@^1.1.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/unist-util-position-from-estree/-/unist-util-position-from-estree-1.1.2.tgz#8ac2480027229de76512079e377afbcabcfcce22" - integrity sha512-poZa0eXpS+/XpoQwGwl79UUdea4ol2ZuCYguVaJS4qzIOMDzbqz8a3erUCOmubSZkaOuGamb3tX790iwOIROww== - dependencies: - "@types/unist" "^2.0.0" - -unist-util-position@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/unist-util-position/-/unist-util-position-3.1.0.tgz#1c42ee6301f8d52f47d14f62bbdb796571fa2d47" - integrity sha512-w+PkwCbYSFw8vpgWD0v7zRCl1FpY3fjDSQ3/N/wNd9Ffa4gPi8+4keqt99N3XW6F99t/mUzp2xAhNmfKWp95QA== - -unist-util-position@^4.0.0: - version "4.0.4" - resolved "https://registry.yarnpkg.com/unist-util-position/-/unist-util-position-4.0.4.tgz#93f6d8c7d6b373d9b825844645877c127455f037" - integrity sha512-kUBE91efOWfIVBo8xzh/uZQ7p9ffYRtUbMRZBNFYwf0RK8koUMx6dGUfwylLOKmaT2cs4wSW96QoYUSXAyEtpg== - dependencies: - "@types/unist" "^2.0.0" - -unist-util-remove-position@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/unist-util-remove-position/-/unist-util-remove-position-2.0.1.tgz#5d19ca79fdba712301999b2b73553ca8f3b352cc" - integrity sha512-fDZsLYIe2uT+oGFnuZmy73K6ZxOPG/Qcm+w7jbEjaFcJgbQ6cqjs/eSPzXhsmGpAsWPkqZM9pYjww5QTn3LHMA== - dependencies: - unist-util-visit "^2.0.0" - -unist-util-remove-position@^4.0.0: - version "4.0.2" - resolved "https://registry.yarnpkg.com/unist-util-remove-position/-/unist-util-remove-position-4.0.2.tgz#a89be6ea72e23b1a402350832b02a91f6a9afe51" - integrity sha512-TkBb0HABNmxzAcfLf4qsIbFbaPDvMO6wa3b3j4VcEzFVaw1LBKwnW4/sRJ/atSLSzoIg41JWEdnE7N6DIhGDGQ== - dependencies: - "@types/unist" "^2.0.0" - unist-util-visit "^4.0.0" - -unist-util-remove@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/unist-util-remove/-/unist-util-remove-2.1.0.tgz#b0b4738aa7ee445c402fda9328d604a02d010588" - integrity sha512-J8NYPyBm4baYLdCbjmf1bhPu45Cr1MWTm77qd9istEkzWpnN6O9tMsEbB2JhNnBCqGENRqEWomQ+He6au0B27Q== - dependencies: - unist-util-is "^4.0.0" - -unist-util-stringify-position@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz#cce3bfa1cdf85ba7375d1d5b17bdc4cada9bd9da" - integrity sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g== - dependencies: - "@types/unist" "^2.0.2" - -unist-util-stringify-position@^3.0.0: - version "3.0.3" - resolved "https://registry.yarnpkg.com/unist-util-stringify-position/-/unist-util-stringify-position-3.0.3.tgz#03ad3348210c2d930772d64b489580c13a7db39d" - integrity sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg== - dependencies: - "@types/unist" "^2.0.0" - -unist-util-visit-parents@^3.0.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/unist-util-visit-parents/-/unist-util-visit-parents-3.1.1.tgz#65a6ce698f78a6b0f56aa0e88f13801886cdaef6" - integrity sha512-1KROIZWo6bcMrZEwiH2UrXDyalAa0uqzWCxCJj6lPOvTve2WkfgCytoDTPaMnodXh1WrXOq0haVYHj99ynJlsg== +unique-string@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-2.0.0.tgz#39c6451f81afb2749de2b233e3f7c5e8843bd89d" + integrity sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg== dependencies: - "@types/unist" "^2.0.0" - unist-util-is "^4.0.0" + crypto-random-string "^2.0.0" -unist-util-visit-parents@^5.1.1: - version "5.1.3" - resolved "https://registry.yarnpkg.com/unist-util-visit-parents/-/unist-util-visit-parents-5.1.3.tgz#b4520811b0ca34285633785045df7a8d6776cfeb" - integrity sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg== +unist-util-is@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/unist-util-is/-/unist-util-is-6.0.0.tgz#b775956486aff107a9ded971d996c173374be424" + integrity sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw== dependencies: - "@types/unist" "^2.0.0" - unist-util-is "^5.0.0" + "@types/unist" "^3.0.0" -unist-util-visit@2.0.3, unist-util-visit@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/unist-util-visit/-/unist-util-visit-2.0.3.tgz#c3703893146df47203bb8a9795af47d7b971208c" - integrity sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q== +unist-util-visit-parents@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz#4d5f85755c3b8f0dc69e21eca5d6d82d22162815" + integrity sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw== dependencies: - "@types/unist" "^2.0.0" - unist-util-is "^4.0.0" - unist-util-visit-parents "^3.0.0" + "@types/unist" "^3.0.0" + unist-util-is "^6.0.0" -unist-util-visit@^4.0.0: - version "4.1.2" - resolved "https://registry.yarnpkg.com/unist-util-visit/-/unist-util-visit-4.1.2.tgz#125a42d1eb876283715a3cb5cceaa531828c72e2" - integrity sha512-MSd8OUGISqHdVvfY9TPhyK2VdUrPgxkUtWSuMHF6XAAFuL4LokseigBnZtPnJMu+FbynTkFNnFlyjxpVKujMRg== +unist-util-visit@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/unist-util-visit/-/unist-util-visit-5.0.0.tgz#a7de1f31f72ffd3519ea71814cccf5fd6a9217d6" + integrity sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg== dependencies: - "@types/unist" "^2.0.0" - unist-util-is "^5.0.0" - unist-util-visit-parents "^5.1.1" - -universalify@^0.1.0: - version "0.1.2" - resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" - integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== + "@types/unist" "^3.0.0" + unist-util-is "^6.0.0" + unist-util-visit-parents "^6.0.0" universalify@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" - integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== + version "2.0.1" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.1.tgz#168efc2180964e6386d061e094df61afe239b18d" + integrity sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw== unorm@^1.5.0: version "1.6.0" @@ -20007,39 +19213,83 @@ unpipe@1.0.0, unpipe@~1.0.0: resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== +unplugin@^1.3.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/unplugin/-/unplugin-1.5.1.tgz#806688376fa3dcca4d2fa2c5d27cf6cd0370fbef" + integrity sha512-0QkvG13z6RD+1L1FoibQqnvTwVBXvS4XSPwAyinVgoOCl2jAgwzdUKmEj05o4Lt8xwQI85Hb6mSyYkcAGwZPew== + dependencies: + acorn "^8.11.2" + chokidar "^3.5.3" + webpack-sources "^3.2.3" + webpack-virtual-modules "^0.6.0" + unquote@^1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/unquote/-/unquote-1.1.1.tgz#8fded7324ec6e88a0ff8b905e7c098cdc086d544" integrity sha512-vRCqFv6UhXpWxZPyGDh/F3ZpNv8/qo7w6iufLpQg9aKnQ71qM4B5KiI7Mia9COcjEhrO9LueHpMYjYzsWH3OIg== -unset-value@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" - integrity sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ== - dependencies: - has-value "^0.3.1" - isobject "^3.0.0" +unraw@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/unraw/-/unraw-2.0.1.tgz#7b51dcdfb1e43d59d5e52cdb44d349d029edbaba" + integrity sha512-tdOvLfRzHolwYcHS6HIX860MkK9LQ4+oLuNwFYL7bpgTEO64PZrcQxkisgwJYCfF8sKiWLwwu1c83DvMkbefIQ== + +unraw@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/unraw/-/unraw-3.0.0.tgz#73443ed70d2ab09ccbac2b00525602d5991fbbe3" + integrity sha512-08/DA66UF65OlpUDIQtbJyrqTR0jTAlJ+jsnkQ4jxR7+K5g5YG1APZKQSMCE1vqqmD+2pv6+IdEjmopFatacvg== -untildify@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/untildify/-/untildify-2.1.0.tgz#17eb2807987f76952e9c0485fc311d06a826a2e0" - integrity sha512-sJjbDp2GodvkB0FZZcn7k6afVisqX5BZD7Yq3xp4nN2O15BBK0cLm3Vwn2vQaF7UDS0UUsrQMkkplmDI5fskig== +unstorage@^1.9.0: + version "1.10.1" + resolved "https://registry.yarnpkg.com/unstorage/-/unstorage-1.10.1.tgz#bf8cc00a406e40a6293e893da9807057d95875b0" + integrity sha512-rWQvLRfZNBpF+x8D3/gda5nUCQL2PgXy2jNG4U7/Rc9BGEv9+CAJd0YyGCROUBKs9v49Hg8huw3aih5Bf5TAVw== dependencies: - os-homedir "^1.0.0" + anymatch "^3.1.3" + chokidar "^3.5.3" + destr "^2.0.2" + h3 "^1.8.2" + ioredis "^5.3.2" + listhen "^1.5.5" + lru-cache "^10.0.2" + mri "^1.2.0" + node-fetch-native "^1.4.1" + ofetch "^1.3.3" + ufo "^1.3.1" + +untildify@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/untildify/-/untildify-4.0.0.tgz#2bc947b953652487e4600949fb091e3ae8cd919b" + integrity sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw== -upath@^1.1.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894" - integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg== +untun@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/untun/-/untun-0.1.2.tgz#fa42a62ae24c1c5c6f3209692a2b0e1f573f1353" + integrity sha512-wLAMWvxfqyTiBODA1lg3IXHQtjggYLeTK7RnSfqtOXixWJ3bAa2kK/HHmOOg19upteqO3muLvN6O/icbyQY33Q== + dependencies: + citty "^0.1.3" + consola "^3.2.3" + pathe "^1.1.1" -update-browserslist-db@^1.0.10: - version "1.0.10" - resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz#0f54b876545726f17d00cd9a2561e6dade943ff3" - integrity sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ== +update-browserslist-db@^1.0.13: + version "1.0.13" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz#3c5e4f5c083661bd38ef64b6328c26ed6c8248c4" + integrity sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg== dependencies: escalade "^3.1.1" picocolors "^1.0.0" +update-browserslist-db@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz#7ca61c0d8650766090728046e416a8cde682859e" + integrity sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ== + dependencies: + escalade "^3.1.2" + picocolors "^1.0.1" + +uqr@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/uqr/-/uqr-0.1.2.tgz#5c6cd5dcff9581f9bb35b982cb89e2c483a41d7d" + integrity sha512-MJu7ypHq6QasgF5YRTjqscSzQp/W11zoUk6kvmlH+fmWEs63Y0Eib13hYFwAzagRJcVY8WVnlV+eBDUGMJ5IbA== + uri-js@^4.2.2: version "4.4.1" resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" @@ -20047,35 +19297,22 @@ uri-js@^4.2.2: dependencies: punycode "^2.1.0" -urix@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" - integrity sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg== - -url-loader@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/url-loader/-/url-loader-4.1.1.tgz#28505e905cae158cf07c92ca622d7f237e70a4e2" - integrity sha512-3BTV812+AVHHOJQO8O5MkWgZ5aosP7GnROJwvzLS9hWDj00lZ6Z0wNak423Lp9PBZN05N+Jk/N5Si8jRAlGyWA== - dependencies: - loader-utils "^2.0.0" - mime-types "^2.1.27" - schema-utils "^3.0.0" - url@^0.11.0: - version "0.11.0" - resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" - integrity sha512-kbailJa29QrtXnxgq+DdCEGlbTeYM2eJUxsz6vjZavrCYPMIFHMKQmSKYAIuUK2i7hgPm28a8piX5NTUtM/LKQ== + version "0.11.3" + resolved "https://registry.yarnpkg.com/url/-/url-0.11.3.tgz#6f495f4b935de40ce4a0a52faee8954244f3d3ad" + integrity sha512-6hxOLGfZASQK/cijlZnZJTq8OXAkt/3YGfQX45vvMYXpZoo8NdWZcY73K108Jf759lS1Bv/8wXnHDTSz17dSRw== dependencies: - punycode "1.3.2" - querystring "0.2.0" + punycode "^1.4.1" + qs "^6.11.2" -usb@^1.7.0: - version "1.9.2" - resolved "https://registry.yarnpkg.com/usb/-/usb-1.9.2.tgz#fb6b36f744ecc707a196c45a6ec72442cb6f2b73" - integrity sha512-dryNz030LWBPAf6gj8vyq0Iev3vPbCLHCT8dBw3gQRXRzVNsIdeuU+VjPp3ksmSPkeMAl1k+kQ14Ij0QHyeiAg== +usb@^2.11.0: + version "2.13.0" + resolved "https://registry.yarnpkg.com/usb/-/usb-2.13.0.tgz#521d11244cbe991a3f247c770821635abdcc9c7f" + integrity sha512-pTNKyxD1DfC1DYu8kFcIdpE8f33e0c2Sbmmi0HEs28HTVC555uocvYR1g5DDv4CBibacCh4BqRyYZJylN4mBbw== dependencies: - node-addon-api "^4.2.0" - node-gyp-build "^4.3.0" + "@types/w3c-web-usb" "^1.0.6" + node-addon-api "^8.0.0" + node-gyp-build "^4.5.0" use-callback-ref@^1.3.0: version "1.3.0" @@ -20084,11 +19321,6 @@ use-callback-ref@^1.3.0: dependencies: tslib "^2.0.0" -use-isomorphic-layout-effect@^1.1.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.2.tgz#497cefb13d863d687b08477d9e5a164ad8c1a6fb" - integrity sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA== - use-sidecar@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/use-sidecar/-/use-sidecar-1.1.2.tgz#2f43126ba2d7d7e117aa5855e5d8f0276dfe73c2" @@ -20102,12 +19334,12 @@ use-sync-external-store@1.2.0: resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz#7dbefd6ef3fe4e767a0cf5d7287aacfb5846928a" integrity sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA== -use@^3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" - integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== +use-sync-external-store@1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.2.2.tgz#c3b6390f3a30eba13200d2302dcdf1e7b57b2ef9" + integrity sha512-PElTlVMwpblvbNqQ82d2n6RjStvdSoNe9FG28kNfz3WiXilJm4DdNkEzRhCZuIDwY8U08WVihhGR5iRqAwfDiw== -utf-8-validate@^5.0.2: +utf-8-validate@^5.0.2, utf-8-validate@^5.0.5: version "5.0.10" resolved "https://registry.yarnpkg.com/utf-8-validate/-/utf-8-validate-5.0.10.tgz#d7d10ea39318171ca982718b6b96a8d2442571a2" integrity sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ== @@ -20119,29 +19351,7 @@ util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== -util.promisify@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.0.tgz#440f7165a459c9a16dc145eb8e72f35687097030" - integrity sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA== - dependencies: - define-properties "^1.1.2" - object.getownpropertydescriptors "^2.0.3" - -util@0.10.3: - version "0.10.3" - resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" - integrity sha512-5KiHfsmkqacuKjkRkdV7SsfDJ2EGiPsK92s2MhNSY0craxjTdKTtqKsJaCWp4LW33ZZ0OPUv1WO/TFvNQRiQxQ== - dependencies: - inherits "2.0.1" - -util@^0.11.0: - version "0.11.1" - resolved "https://registry.yarnpkg.com/util/-/util-0.11.1.tgz#3236733720ec64bb27f6e26f421aaa2e1b588d61" - integrity sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ== - dependencies: - inherits "2.0.3" - -util@^0.12.3: +util@^0.12.3, util@^0.12.4, util@^0.12.5: version "0.12.5" resolved "https://registry.yarnpkg.com/util/-/util-0.12.5.tgz#5f17a6059b73db61a875668781a1c2b136bd6fbc" integrity sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA== @@ -20167,11 +19377,6 @@ utils-merge@1.0.1: resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== -uuid-browser@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/uuid-browser/-/uuid-browser-3.1.0.tgz#0f05a40aef74f9e5951e20efbf44b11871e56410" - integrity sha512-dsNgbLaTrd6l3MMxTtouOCFw4CBFc/3a+GgYA2YyrJvyQ1u6q4pcu3ktLoUZ/VN/Aw9WsauazbgsgdfVWgAKQg== - uuid-random@^1.3.2: version "1.3.2" resolved "https://registry.yarnpkg.com/uuid-random/-/uuid-random-1.3.2.tgz#96715edbaef4e84b1dcf5024b00d16f30220e2d0" @@ -20188,48 +19393,15 @@ uuid@^8.3.2: integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== uuid@^9.0.0: - version "9.0.0" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.0.tgz#592f550650024a38ceb0c562f2f6aa435761efb5" - integrity sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg== - -uvu@^0.5.0: - version "0.5.6" - resolved "https://registry.yarnpkg.com/uvu/-/uvu-0.5.6.tgz#2754ca20bcb0bb59b64e9985e84d2e81058502df" - integrity sha512-+g8ENReyr8YsOc6fv/NVJs2vFdHBnBNdfE49rshrTzDWOlUx4Gq7KOS2GD8eqhy2j+Ejq29+SbKH8yjkAqXqoA== - dependencies: - dequal "^2.0.0" - diff "^5.0.0" - kleur "^4.0.3" - sade "^1.7.3" - -v8-compile-cache-lib@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf" - integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg== + version "9.0.1" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.1.tgz#e188d4c8853cc722220392c424cd637f32293f30" + integrity sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA== -v8-compile-cache@2.3.0, v8-compile-cache@^2.0.0, v8-compile-cache@^2.0.3: +v8-compile-cache@2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== -v8-to-istanbul@^4.1.3: - version "4.1.4" - resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-4.1.4.tgz#b97936f21c0e2d9996d4985e5c5156e9d4e49cd6" - integrity sha512-Rw6vJHj1mbdK8edjR7+zuJrpDtKIgNdAvTSAcpYfgMIw+u2dPDntD3dgN4XQFLU2/fvFQdzj+EeSGfd/jnY5fQ== - dependencies: - "@types/istanbul-lib-coverage" "^2.0.1" - convert-source-map "^1.6.0" - source-map "^0.7.3" - -v8-to-istanbul@^9.0.0: - version "9.1.0" - resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-9.1.0.tgz#1b83ed4e397f58c85c266a570fc2558b5feb9265" - integrity sha512-6z3GW9x8G1gd+JIIgQQQxXuiJtCXeAjp6RaPEPLv62mH3iPHPxV6W3robxtCzNErRo6ZwTmzWhsbNvjyEBKzKA== - dependencies: - "@jridgewell/trace-mapping" "^0.3.12" - "@types/istanbul-lib-coverage" "^2.0.1" - convert-source-map "^1.6.0" - validate-npm-package-license@^3.0.1: version "3.0.4" resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" @@ -20238,162 +19410,121 @@ validate-npm-package-license@^3.0.1: spdx-correct "^3.0.0" spdx-expression-parse "^3.0.0" -varint@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/varint/-/varint-5.0.0.tgz#d826b89f7490732fabc0c0ed693ed475dcb29ebf" - integrity sha512-gC13b/bWrqQoKY2EmROCZ+AR0jitc6DnDGaQ6Ls9QpKmuSgJB1eQ7H3KETtQm7qSdMWMKCmsshyCmUwMLh3OAA== - -varint@~5.0.0: - version "5.0.2" - resolved "https://registry.yarnpkg.com/varint/-/varint-5.0.2.tgz#5b47f8a947eb668b848e034dcfa87d0ff8a7f7a4" - integrity sha512-lKxKYG6H03yCZUpAGOPOsMcGxd1RHCu1iKvEHYDPmTyq2HueGhD73ssNBqqQWfvYs04G9iUFRvmAVLW20Jw6ow== - -vary@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" - integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== - -vercel@^28.16.12: - version "28.18.3" - resolved "https://registry.yarnpkg.com/vercel/-/vercel-28.18.3.tgz#2729512d7022b1a406200f77b92e38859c399a88" - integrity sha512-DUAHpIK5d4s8cz4AgFmpSaMyoq8c2ESmHLhSQRyYo6UY48IhczJfzZdi8CJUfQF79Qmf1wrJWaQ42m9/0MeCfA== - dependencies: - "@vercel/build-utils" "6.7.0" - "@vercel/go" "2.4.3" - "@vercel/hydrogen" "0.0.61" - "@vercel/next" "3.7.3" - "@vercel/node" "2.10.2" - "@vercel/python" "3.1.57" - "@vercel/redwood" "1.1.13" - "@vercel/remix-builder" "1.8.3" - "@vercel/ruby" "1.3.74" - "@vercel/static-build" "1.3.21" - -verror@1.10.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" - integrity sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw== - dependencies: - assert-plus "^1.0.0" - core-util-is "1.0.2" - extsprintf "^1.2.0" - -vfile-location@^3.0.0, vfile-location@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/vfile-location/-/vfile-location-3.2.0.tgz#d8e41fbcbd406063669ebf6c33d56ae8721d0f3c" - integrity sha512-aLEIZKv/oxuCDZ8lkJGhuhztf/BW4M+iHdCwglA/eWc+vtuRFJj8EtgceYFX4LRjOhCAAiNHsKGssC6onJ+jbA== - -vfile-location@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/vfile-location/-/vfile-location-4.1.0.tgz#69df82fb9ef0a38d0d02b90dd84620e120050dd0" - integrity sha512-YF23YMyASIIJXpktBa4vIGLJ5Gs88UB/XePgqPmTa7cDA+JeO3yclbpheQYCHjVHBn/yePzrXuygIL+xbvRYHw== - dependencies: - "@types/unist" "^2.0.0" - vfile "^5.0.0" - -vfile-message@^2.0.0: - version "2.0.4" - resolved "https://registry.yarnpkg.com/vfile-message/-/vfile-message-2.0.4.tgz#5b43b88171d409eae58477d13f23dd41d52c371a" - integrity sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ== +valtio@1.11.2: + version "1.11.2" + resolved "https://registry.yarnpkg.com/valtio/-/valtio-1.11.2.tgz#b8049c02dfe65620635d23ebae9121a741bb6530" + integrity sha512-1XfIxnUXzyswPAPXo1P3Pdx2mq/pIqZICkWN60Hby0d9Iqb+MEIpqgYVlbflvHdrp2YR/q3jyKWRPJJ100yxaw== dependencies: - "@types/unist" "^2.0.0" - unist-util-stringify-position "^2.0.0" + proxy-compare "2.5.1" + use-sync-external-store "1.2.0" -vfile-message@^3.0.0: - version "3.1.4" - resolved "https://registry.yarnpkg.com/vfile-message/-/vfile-message-3.1.4.tgz#15a50816ae7d7c2d1fa87090a7f9f96612b59dea" - integrity sha512-fa0Z6P8HUrQN4BZaX05SIVXic+7kE3b05PWAtPuYP9QLHsLKYR7/AlLW3NtOrpXRLeawpDLMsVkmk5DG0NXgWw== +values.js@2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/values.js/-/values.js-2.1.1.tgz#d9b2aa5c6aca0b27411114e2832455840796f065" + integrity sha512-pI6dKW3kv7BR/WzS0NvIuxegeH1r8gk8y6BuXrIYGVccynmUsUZPhSpTfkt39VBHyciD7WZi+lM+7Zyamowzeg== dependencies: - "@types/unist" "^2.0.0" - unist-util-stringify-position "^3.0.0" + mix-css-color "0.2.0" + parse-css-color "0.2.0" + pure-color "1.3.0" -vfile@^4.0.0: - version "4.2.1" - resolved "https://registry.yarnpkg.com/vfile/-/vfile-4.2.1.tgz#03f1dce28fc625c625bc6514350fbdb00fa9e624" - integrity sha512-O6AE4OskCG5S1emQ/4gl8zK586RqA3srz3nfK/Viy0UPToBc5Trp9BVFb1u0CjsKrAWwnpr4ifM/KBXPWwJbCA== +varuint-bitcoin@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/varuint-bitcoin/-/varuint-bitcoin-1.1.2.tgz#e76c138249d06138b480d4c5b40ef53693e24e92" + integrity sha512-4EVb+w4rx+YfVM32HQX42AbbT7/1f5zwAYhIujKXKk8NQK+JfRVl3pqT3hjNn/L+RstigmGGKVwHA/P0wgITZw== dependencies: - "@types/unist" "^2.0.0" - is-buffer "^2.0.0" - unist-util-stringify-position "^2.0.0" - vfile-message "^2.0.0" + safe-buffer "^5.1.1" -vfile@^5.0.0: - version "5.3.7" - resolved "https://registry.yarnpkg.com/vfile/-/vfile-5.3.7.tgz#de0677e6683e3380fafc46544cfe603118826ab7" - integrity sha512-r7qlzkgErKjobAmyNIkkSpizsFPYiUPuJb5pNW1RB4JcYVZhs4lIbVqk8XPk033CV/1z8ss5pkax8SuhGpcG8g== - dependencies: - "@types/unist" "^2.0.0" - is-buffer "^2.0.0" - unist-util-stringify-position "^3.0.0" - vfile-message "^3.0.0" +vary@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== -vite-node@^0.28.5: - version "0.28.5" - resolved "https://registry.yarnpkg.com/vite-node/-/vite-node-0.28.5.tgz#56d0f78846ea40fddf2e28390899df52a4738006" - integrity sha512-LmXb9saMGlrMZbXTvOveJKwMTBTNUH66c8rJnQ0ZPNX+myPEol64+szRzXtV5ORb0Hb/91yq+/D3oERoyAt6LA== +viem@^1.0.0: + version "1.19.9" + resolved "https://registry.yarnpkg.com/viem/-/viem-1.19.9.tgz#a11f3ad4a3323994ebd2010dbc659d1a2b12e583" + integrity sha512-Sf9U2x4jU0S/FALqYypcspWOGene0NZyD470oUripNhE0Ta6uOE/OgE4toTDVfRxov8qw0JFinr/wPGxYE3+HQ== + dependencies: + "@adraffy/ens-normalize" "1.10.0" + "@noble/curves" "1.2.0" + "@noble/hashes" "1.3.2" + "@scure/bip32" "1.3.2" + "@scure/bip39" "1.2.1" + abitype "0.9.8" + isows "1.0.3" + ws "8.13.0" + +viem@^2.1.1: + version "2.21.9" + resolved "https://registry.yarnpkg.com/viem/-/viem-2.21.9.tgz#5676f81b07286ad88852a239e1eeb18c7f9b40a6" + integrity sha512-fWPDX2ABEo/mLiDN+wsmYJDJk0a/ZCafquxInR2+HZv/7UTgHbLgjZs4SotpEeFAYjgVThJ7A9TPmrRjaaYqvw== + dependencies: + "@adraffy/ens-normalize" "1.10.0" + "@noble/curves" "1.4.0" + "@noble/hashes" "1.4.0" + "@scure/bip32" "1.4.0" + "@scure/bip39" "1.4.0" + abitype "1.0.5" + isows "1.0.4" + webauthn-p256 "0.0.5" + ws "8.17.1" + +vite-node@2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/vite-node/-/vite-node-2.0.5.tgz#36d909188fc6e3aba3da5fc095b3637d0d18e27b" + integrity sha512-LdsW4pxj0Ot69FAoXZ1yTnA9bjGohr2yNBU7QKRxpz8ITSkhuDl6h3zS/tvgz4qrNjeRnvrWeXQ8ZF7Um4W00Q== dependencies: cac "^6.7.14" - debug "^4.3.4" - mlly "^1.1.0" - pathe "^1.1.0" - picocolors "^1.0.0" - source-map "^0.6.1" - source-map-support "^0.5.21" - vite "^3.0.0 || ^4.0.0" - -"vite@^3.0.0 || ^4.0.0", vite@^4.1.4: - version "4.2.1" - resolved "https://registry.yarnpkg.com/vite/-/vite-4.2.1.tgz#6c2eb337b0dfd80a9ded5922163b94949d7fc254" - integrity sha512-7MKhqdy0ISo4wnvwtqZkjke6XN4taqQ2TBaTccLIpOKv7Vp2h4Y+NpmWCnGDeSvvn45KxvWgGyb0MkHvY1vgbg== - dependencies: - esbuild "^0.17.5" - postcss "^8.4.21" - resolve "^1.22.1" - rollup "^3.18.0" + debug "^4.3.5" + pathe "^1.1.2" + tinyrainbow "^1.2.0" + vite "^5.0.0" + +vite@^5.0.0: + version "5.4.8" + resolved "https://registry.yarnpkg.com/vite/-/vite-5.4.8.tgz#af548ce1c211b2785478d3ba3e8da51e39a287e8" + integrity sha512-FqrItQ4DT1NC4zCUqMB4c4AZORMKIa0m8/URVCZ77OZ/QSNeJ54bU1vrFADbDsuwfIPcgknRkmqakQcgnL4GiQ== + dependencies: + esbuild "^0.21.3" + postcss "^8.4.43" + rollup "^4.20.0" optionalDependencies: - fsevents "~2.3.2" + fsevents "~2.3.3" -vm-browserify@^1.0.1: +vitest@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/vitest/-/vitest-2.0.5.tgz#2f15a532704a7181528e399cc5b754c7f335fd62" + integrity sha512-8GUxONfauuIdeSl5f9GTgVEpg5BTOlplET4WEDaeY2QBiN8wSm68vxN/tb5z405OwppfoCavnwXafiaYBC/xOA== + dependencies: + "@ampproject/remapping" "^2.3.0" + "@vitest/expect" "2.0.5" + "@vitest/pretty-format" "^2.0.5" + "@vitest/runner" "2.0.5" + "@vitest/snapshot" "2.0.5" + "@vitest/spy" "2.0.5" + "@vitest/utils" "2.0.5" + chai "^5.1.1" + debug "^4.3.5" + execa "^8.0.1" + magic-string "^0.30.10" + pathe "^1.1.2" + std-env "^3.7.0" + tinybench "^2.8.0" + tinypool "^1.0.0" + tinyrainbow "^1.2.0" + vite "^5.0.0" + vite-node "2.0.5" + why-is-node-running "^2.3.0" + +vm-browserify@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0" integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ== -vm2@^3.9.11: - version "3.9.14" - resolved "https://registry.yarnpkg.com/vm2/-/vm2-3.9.14.tgz#964042b474cf1e6e4f475a39144773cdb9deb734" - integrity sha512-HgvPHYHeQy8+QhzlFryvSteA4uQLBCOub02mgqdR+0bN/akRZ48TGB1v0aCv7ksyc0HXx16AZtMHKS38alc6TA== - dependencies: - acorn "^8.7.0" - acorn-walk "^8.2.0" - void-elements@3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-3.1.0.tgz#614f7fbf8d801f0bb5f0661f5b2f5785750e4f09" integrity sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w== -w3c-hr-time@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz#0a89cdf5cc15822df9c360543676963e0cc308cd" - integrity sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ== - dependencies: - browser-process-hrtime "^1.0.0" - -w3c-xmlserializer@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/w3c-xmlserializer/-/w3c-xmlserializer-1.1.2.tgz#30485ca7d70a6fd052420a3d12fd90e6339ce794" - integrity sha512-p10l/ayESzrBMYWRID6xbuCKh2Fp77+sA0doRuGn4tTIMrrZVeqfpKjXHY+oDh3K4nLdPgNwMTVP6Vp4pvqbNg== - dependencies: - domexception "^1.0.1" - webidl-conversions "^4.0.2" - xml-name-validator "^3.0.0" - -walker@^1.0.7, walker@~1.0.5: - version "1.0.8" - resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.8.tgz#bd498db477afe573dc04185f011d3ab8a8d7653f" - integrity sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ== - dependencies: - makeerror "1.0.12" - warning@^4.0.2, warning@^4.0.3: version "4.0.3" resolved "https://registry.yarnpkg.com/warning/-/warning-4.0.3.tgz#16e9e077eb8a86d6af7d64aa1e05fd85b4678ca3" @@ -20401,25 +19532,7 @@ warning@^4.0.2, warning@^4.0.3: dependencies: loose-envify "^1.0.0" -watchpack-chokidar2@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/watchpack-chokidar2/-/watchpack-chokidar2-2.0.1.tgz#38500072ee6ece66f3769936950ea1771be1c957" - integrity sha512-nCFfBIPKr5Sh61s4LPpy1Wtfi0HE8isJ3d2Yb5/Ppw2P2B/3eVSEBjKfN0fmHJSK14+31KwMKmcrzs2GM4P0Ww== - dependencies: - chokidar "^2.1.8" - -watchpack@^1.7.4: - version "1.7.5" - resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.7.5.tgz#1267e6c55e0b9b5be44c2023aed5437a2c26c453" - integrity sha512-9P3MWk6SrKjHsGkLT2KHXdQ/9SNkyoJbabxnKOoJepsvJjJG8uYTR3yTPxPQvNDI3w4Nz1xnE0TLHK4RIVe/MQ== - dependencies: - graceful-fs "^4.1.2" - neo-async "^2.5.0" - optionalDependencies: - chokidar "^3.4.1" - watchpack-chokidar2 "^2.0.1" - -watchpack@^2.2.0, watchpack@^2.4.0: +watchpack@^2.2.0: version "2.4.0" resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.0.tgz#fa33032374962c78113f93c7f2fb4c54c9862a5d" integrity sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg== @@ -20427,6 +19540,14 @@ watchpack@^2.2.0, watchpack@^2.4.0: glob-to-regexp "^0.4.1" graceful-fs "^4.1.2" +watchpack@^2.4.1: + version "2.4.2" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.2.tgz#2feeaed67412e7c33184e5a79ca738fbd38564da" + integrity sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw== + dependencies: + glob-to-regexp "^0.4.1" + graceful-fs "^4.1.2" + wcwidth@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" @@ -20439,15 +19560,13 @@ weak-lru-cache@^1.2.2: resolved "https://registry.yarnpkg.com/weak-lru-cache/-/weak-lru-cache-1.2.2.tgz#fdbb6741f36bae9540d12f480ce8254060dccd19" integrity sha512-DEAoo25RfSYMuTGc9vPJzZcZullwIqRDSI9LOy+fkCJPi6hykCnfKaXTuPBDuXAUcqHXyOgFtHNp/kB2FjYHbw== -web-namespaces@^1.0.0: - version "1.1.4" - resolved "https://registry.yarnpkg.com/web-namespaces/-/web-namespaces-1.1.4.tgz#bc98a3de60dadd7faefc403d1076d529f5e030ec" - integrity sha512-wYxSGajtmoP4WxfejAPIr4l0fVh+jeMXZb08wNc0tMg6xsfZXj3cECqIK0G7ZAqUq0PP8WlMDtaOGVBTAWztNw== - -web-vitals@0.2.4: - version "0.2.4" - resolved "https://registry.yarnpkg.com/web-vitals/-/web-vitals-0.2.4.tgz#ec3df43c834a207fd7cdefd732b2987896e08511" - integrity sha512-6BjspCO9VriYy12z356nL6JBS0GYeEcA457YyRzD+dD6XYCQ75NKhcOHUMHentOE7OcVCIXXDvOm0jKFfQG2Gg== +webauthn-p256@0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/webauthn-p256/-/webauthn-p256-0.0.5.tgz#0baebd2ba8a414b21cc09c0d40f9dd0be96a06bd" + integrity sha512-drMGNWKdaixZNobeORVIqq7k5DsRC9FnG201K2QjeOoQLmtSDaSsVZdkg6n5jUALJKcAG++zBPJXmv6hy0nWFg== + dependencies: + "@noble/curves" "^1.4.0" + "@noble/hashes" "^1.4.0" webidl-conversions@^3.0.0: version "3.0.1" @@ -20459,146 +19578,84 @@ webidl-conversions@^4.0.2: resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" integrity sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg== -webpack-dev-middleware@^3.7.3: - version "3.7.3" - resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-3.7.3.tgz#0639372b143262e2b84ab95d3b91a7597061c2c5" - integrity sha512-djelc/zGiz9nZj/U7PTBi2ViorGJXEWo/3ltkPbDyxCXhhEXkW0ce99falaok4TPj+AsxLiXJR0EBOb0zh9fKQ== +webidl-conversions@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-7.0.0.tgz#256b4e1882be7debbf01d05f0aa2039778ea080a" + integrity sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g== + +webpack-dev-middleware@^6.1.2: + version "6.1.3" + resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-6.1.3.tgz#79f4103f8c898564c9e96c3a9c2422de50f249bc" + integrity sha512-A4ChP0Qj8oGociTs6UdlRUGANIGrCDL3y+pmQMc+dSsraXHCatFpmMey4mYELA+juqwUqwQsUgJJISXl1KWmiw== dependencies: - memory-fs "^0.4.1" - mime "^2.4.4" - mkdirp "^0.5.1" + colorette "^2.0.10" + memfs "^3.4.12" + mime-types "^2.1.31" range-parser "^1.2.1" - webpack-log "^2.0.0" - -webpack-filter-warnings-plugin@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/webpack-filter-warnings-plugin/-/webpack-filter-warnings-plugin-1.2.1.tgz#dc61521cf4f9b4a336fbc89108a75ae1da951cdb" - integrity sha512-Ez6ytc9IseDMLPo0qCuNNYzgtUl8NovOqjIq4uAU8LTD4uoa1w1KpZyyzFtLTEMZpkkOkLfL9eN+KGYdk1Qtwg== + schema-utils "^4.0.0" webpack-hot-middleware@^2.25.1: - version "2.25.3" - resolved "https://registry.yarnpkg.com/webpack-hot-middleware/-/webpack-hot-middleware-2.25.3.tgz#be343ce2848022cfd854dd82820cd730998c6794" - integrity sha512-IK/0WAHs7MTu1tzLTjio73LjS3Ov+VvBKQmE8WPlJutgG5zT6Urgq/BbAdRrHTRpyzK0dvAvFh1Qg98akxgZpA== + version "2.25.4" + resolved "https://registry.yarnpkg.com/webpack-hot-middleware/-/webpack-hot-middleware-2.25.4.tgz#d8bc9e9cb664fc3105c8e83d2b9ed436bee4e193" + integrity sha512-IRmTspuHM06aZh98OhBJtqLpeWFM8FXJS5UYpKYxCJzyFoyWj1w6VGFfomZU7OPA55dMLrQK0pRT1eQ3PACr4w== dependencies: ansi-html-community "0.0.8" html-entities "^2.1.0" strip-ansi "^6.0.0" -webpack-log@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/webpack-log/-/webpack-log-2.0.0.tgz#5b7928e0637593f119d32f6227c1e0ac31e1b47f" - integrity sha512-cX8G2vR/85UYG59FgkoMamwHUIkSSlV3bBMRsbxVXVUk2j6NleCKjQ/WE9eYg9WY4w25O9w8wKP4rzNZFmUcUg== - dependencies: - ansi-colors "^3.0.0" - uuid "^3.3.2" - -webpack-sources@^1.4.0, webpack-sources@^1.4.1, webpack-sources@^1.4.3: - version "1.4.3" - resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.4.3.tgz#eedd8ec0b928fbf1cbfe994e22d2d890f330a933" - integrity sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ== - dependencies: - source-list-map "^2.0.0" - source-map "~0.6.1" - webpack-sources@^3.2.3: version "3.2.3" resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde" integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== -webpack-virtual-modules@^0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/webpack-virtual-modules/-/webpack-virtual-modules-0.2.2.tgz#20863dc3cb6bb2104729fff951fbe14b18bd0299" - integrity sha512-kDUmfm3BZrei0y+1NTHJInejzxfhtU8eDj2M7OKb2IWrPFAeO1SOH2KuQ68MSZu9IGEHcxbkKKR1v18FrUSOmA== - dependencies: - debug "^3.0.0" - -webpack@4: - version "4.46.0" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.46.0.tgz#bf9b4404ea20a073605e0a011d188d77cb6ad542" - integrity sha512-6jJuJjg8znb/xRItk7bkT0+Q7AHCYjjFnvKIWQPkNIOyRqoCGvkOs0ipeQzrqz4l5FtN5ZI/ukEHroeX/o1/5Q== - dependencies: - "@webassemblyjs/ast" "1.9.0" - "@webassemblyjs/helper-module-context" "1.9.0" - "@webassemblyjs/wasm-edit" "1.9.0" - "@webassemblyjs/wasm-parser" "1.9.0" - acorn "^6.4.1" - ajv "^6.10.2" - ajv-keywords "^3.4.1" - chrome-trace-event "^1.0.2" - enhanced-resolve "^4.5.0" - eslint-scope "^4.0.3" - json-parse-better-errors "^1.0.2" - loader-runner "^2.4.0" - loader-utils "^1.2.3" - memory-fs "^0.4.1" - micromatch "^3.1.10" - mkdirp "^0.5.3" - neo-async "^2.6.1" - node-libs-browser "^2.2.1" - schema-utils "^1.0.0" - tapable "^1.1.3" - terser-webpack-plugin "^1.4.3" - watchpack "^1.7.4" - webpack-sources "^1.4.1" - -"webpack@>=4.43.0 <6.0.0": - version "5.77.0" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.77.0.tgz#dea3ad16d7ea6b84aa55fa42f4eac9f30e7eb9b4" - integrity sha512-sbGNjBr5Ya5ss91yzjeJTLKyfiwo5C628AFjEa6WSXcZa4E+F57om3Cc8xLb1Jh0b243AWuSYRf3dn7HVeFQ9Q== - dependencies: - "@types/eslint-scope" "^3.7.3" - "@types/estree" "^0.0.51" - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/wasm-edit" "1.11.1" - "@webassemblyjs/wasm-parser" "1.11.1" +webpack-virtual-modules@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/webpack-virtual-modules/-/webpack-virtual-modules-0.5.0.tgz#362f14738a56dae107937ab98ea7062e8bdd3b6c" + integrity sha512-kyDivFZ7ZM0BVOUteVbDFhlRt7Ah/CSPwJdi8hBpkK7QLumUqdLtVfm/PX/hkcnrvr0i77fO5+TjZ94Pe+C9iw== + +webpack-virtual-modules@^0.6.0: + version "0.6.1" + resolved "https://registry.yarnpkg.com/webpack-virtual-modules/-/webpack-virtual-modules-0.6.1.tgz#ac6fdb9c5adb8caecd82ec241c9631b7a3681b6f" + integrity sha512-poXpCylU7ExuvZK8z+On3kX+S8o/2dQ/SVYueKA0D4WEMXROXgY8Ez50/bQEUmvoSMMrWcrJqCHuhAbsiwg7Dg== + +webpack@5: + version "5.94.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.94.0.tgz#77a6089c716e7ab90c1c67574a28da518a20970f" + integrity sha512-KcsGn50VT+06JH/iunZJedYGUJS5FGjow8wb9c0v5n1Om8O1g4L6LjtfxwlXIATopoQu+vOXXa7gYisWxCoPyg== + dependencies: + "@types/estree" "^1.0.5" + "@webassemblyjs/ast" "^1.12.1" + "@webassemblyjs/wasm-edit" "^1.12.1" + "@webassemblyjs/wasm-parser" "^1.12.1" acorn "^8.7.1" - acorn-import-assertions "^1.7.6" - browserslist "^4.14.5" + acorn-import-attributes "^1.9.5" + browserslist "^4.21.10" chrome-trace-event "^1.0.2" - enhanced-resolve "^5.10.0" - es-module-lexer "^0.9.0" + enhanced-resolve "^5.17.1" + es-module-lexer "^1.2.1" eslint-scope "5.1.1" events "^3.2.0" glob-to-regexp "^0.4.1" - graceful-fs "^4.2.9" + graceful-fs "^4.2.11" json-parse-even-better-errors "^2.3.1" loader-runner "^4.2.0" mime-types "^2.1.27" neo-async "^2.6.2" - schema-utils "^3.1.0" + schema-utils "^3.2.0" tapable "^2.1.1" - terser-webpack-plugin "^5.1.3" - watchpack "^2.4.0" + terser-webpack-plugin "^5.3.10" + watchpack "^2.4.1" webpack-sources "^3.2.3" -websocket-stream@^5.5.0: - version "5.5.2" - resolved "https://registry.yarnpkg.com/websocket-stream/-/websocket-stream-5.5.2.tgz#49d87083d96839f0648f5513bbddd581f496b8a2" - integrity sha512-8z49MKIHbGk3C4HtuHWDtYX8mYej1wWabjthC/RupM9ngeukU4IWoM46dgth1UOS/T4/IqgEdCDJuMe2039OQQ== - dependencies: - duplexify "^3.5.1" - inherits "^2.0.1" - readable-stream "^2.3.3" - safe-buffer "^5.1.2" - ws "^3.2.0" - xtend "^4.0.0" - -whatwg-encoding@^1.0.1, whatwg-encoding@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz#5abacf777c32166a51d085d6b4f3e7d27113ddb0" - integrity sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw== - dependencies: - iconv-lite "0.4.24" - whatwg-fetch@>=0.10.0: - version "3.6.2" - resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.6.2.tgz#dced24f37f2624ed0281725d51d0e2e3fe677f8c" - integrity sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA== + version "3.6.19" + resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.6.19.tgz#caefd92ae630b91c07345537e67f8354db470973" + integrity sha512-d67JP4dHSbm2TrpFj8AbO8DnL1JXL5J9u0Kq2xW6d0TFDbCA3Muhdt8orXC22utleTVj7Prqt82baN6RBvnEgw== -whatwg-mimetype@^2.2.0, whatwg-mimetype@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf" - integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g== +whatwg-mimetype@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz#5fa1a7623867ff1af6ca3dc72ad6b8a4208beba7" + integrity sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q== whatwg-url@^5.0.0: version "5.0.0" @@ -20628,6 +19685,24 @@ which-boxed-primitive@^1.0.2: is-string "^1.0.5" is-symbol "^1.0.3" +which-builtin-type@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/which-builtin-type/-/which-builtin-type-1.1.3.tgz#b1b8443707cc58b6e9bf98d32110ff0c2cbd029b" + integrity sha512-YmjsSMDBYsM1CaFiayOVT06+KJeXf0o5M/CAd4o1lTadFAtacTUM49zoYxr/oroopFDfhvN6iEcBxUyc3gvKmw== + dependencies: + function.prototype.name "^1.1.5" + has-tostringtag "^1.0.0" + is-async-function "^2.0.0" + is-date-object "^1.0.5" + is-finalizationregistry "^1.0.2" + is-generator-function "^1.0.10" + is-regex "^1.1.4" + is-weakref "^1.0.2" + isarray "^2.0.5" + which-boxed-primitive "^1.0.2" + which-collection "^1.0.1" + which-typed-array "^1.1.9" + which-collection@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/which-collection/-/which-collection-1.0.1.tgz#70eab71ebbbd2aefaf32f917082fc62cdcb70906" @@ -20639,49 +19714,42 @@ which-collection@^1.0.1: is-weakset "^2.0.1" which-module@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" - integrity sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q== + version "2.0.1" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.1.tgz#776b1fe35d90aebe99e8ac15eb24093389a4a409" + integrity sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ== -which-typed-array@^1.1.2, which-typed-array@^1.1.9: - version "1.1.9" - resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.9.tgz#307cf898025848cf995e795e8423c7f337efbde6" - integrity sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA== +which-typed-array@^1.1.11, which-typed-array@^1.1.13, which-typed-array@^1.1.2, which-typed-array@^1.1.9: + version "1.1.13" + resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.13.tgz#870cd5be06ddb616f504e7b039c4c24898184d36" + integrity sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow== dependencies: available-typed-arrays "^1.0.5" - call-bind "^1.0.2" + call-bind "^1.0.4" for-each "^0.3.3" gopd "^1.0.1" has-tostringtag "^1.0.0" - is-typed-array "^1.1.10" -which@^1.2.9, which@^1.3.1: +which@^1.2.9: version "1.3.1" resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== dependencies: isexe "^2.0.0" -which@^2.0.1, which@^2.0.2: +which@^2.0.1: version "2.0.2" resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== dependencies: isexe "^2.0.0" -wide-align@^1.1.0, wide-align@^1.1.2: - version "1.1.5" - resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.5.tgz#df1d4c206854369ecf3c9a4898f1b23fbd9d15d3" - integrity sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg== - dependencies: - string-width "^1.0.2 || 2 || 3 || 4" - -widest-line@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-3.1.0.tgz#8292333bbf66cb45ff0de1603b136b7ae1496eca" - integrity sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg== +why-is-node-running@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/why-is-node-running/-/why-is-node-running-2.3.0.tgz#a3f69a97107f494b3cdc3bdddd883a7d65cebf04" + integrity sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w== dependencies: - string-width "^4.0.0" + siginfo "^2.0.0" + stackback "0.0.2" wif@^2.0.6: version "2.0.6" @@ -20690,46 +19758,26 @@ wif@^2.0.6: dependencies: bs58check "<3.0.0" -word-wrap@~1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" - integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== +wif@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/wif/-/wif-4.0.0.tgz#598d4659f361b1d2a8aed13214783fa374b4b146" + integrity sha512-kADznC+4AFJNXpT8rLhbsfI7EmAcorc5nWvAdKUchGmwXEBD3n55q0/GZ3DBmc6auAvuTSsr/utiKizuXdNYOQ== + dependencies: + bs58check "^3.0.1" wordwrap@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" integrity sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q== -worker-farm@^1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.7.0.tgz#26a94c5391bbca926152002f69b84a4bf772e5a8" - integrity sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw== - dependencies: - errno "~0.1.7" - -worker-rpc@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/worker-rpc/-/worker-rpc-0.1.1.tgz#cb565bd6d7071a8f16660686051e969ad32f54d5" - integrity sha512-P1WjMrUB3qgJNI9jfmpZ/htmBEjFh//6l/5y8SD9hg1Ef5zTTVVoRjTrTEzPrNBQvmhMxkoTsjOXN10GWU7aCg== - dependencies: - microevent.ts "~0.1.1" - -wrap-ansi@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-3.0.1.tgz#288a04d87eda5c286e060dfe8f135ce8d007f8ba" - integrity sha512-iXR3tDXpbnTpzjKSylUJRkLuOrEC7hwEB221cgn6wtF8wpmz28puFXAEfPT5zrjM3wahygB//VuWEr1vTkDcNQ== - dependencies: - string-width "^2.1.1" - strip-ansi "^4.0.0" - -wrap-ansi@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09" - integrity sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q== +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== dependencies: - ansi-styles "^3.2.0" - string-width "^3.0.0" - strip-ansi "^5.0.0" + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" wrap-ansi@^6.2.0: version "6.2.0" @@ -20749,27 +19797,28 @@ wrap-ansi@^7.0.0: string-width "^4.1.0" strip-ansi "^6.0.0" +wrap-ansi@^8.0.1, wrap-ansi@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" + integrity sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ== + dependencies: + ansi-styles "^6.1.0" + string-width "^5.0.1" + strip-ansi "^7.0.1" + wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== -write-file-atomic@^3.0.0: - version "3.0.3" - resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-3.0.3.tgz#56bd5c5a5c70481cd19c571bd39ab965a5de56e8" - integrity sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q== +write-file-atomic@^2.3.0: + version "2.4.3" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.4.3.tgz#1fd2e9ae1df3e75b8d8c367443c692d4ca81f481" + integrity sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ== dependencies: + graceful-fs "^4.1.11" imurmurhash "^0.1.4" - is-typedarray "^1.0.0" signal-exit "^3.0.2" - typedarray-to-buffer "^3.1.5" - -write@1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/write/-/write-1.0.3.tgz#0800e14523b923a387e415123c865616aae0f5c3" - integrity sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig== - dependencies: - mkdirp "^0.5.1" ws@7.4.6: version "7.4.6" @@ -20781,75 +19830,30 @@ ws@7.5.3: resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.3.tgz#160835b63c7d97bfab418fc1b8a9fced2ac01a74" integrity sha512-kQ/dHIzuLrS6Je9+uv81ueZomEwH0qVYstcAQ4/Z93K8zeko9gtAbttJWzoC5ukqXY1PpoouV3+VSOqEAFt5wg== -ws@^3.2.0: - version "3.3.3" - resolved "https://registry.yarnpkg.com/ws/-/ws-3.3.3.tgz#f1cf84fe2d5e901ebce94efaece785f187a228f2" - integrity sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA== - dependencies: - async-limiter "~1.0.0" - safe-buffer "~5.1.0" - ultron "~1.1.0" - -ws@^7, ws@^7.0.0, ws@^7.4.0, ws@^7.4.5: - version "7.5.9" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.9.tgz#54fa7db29f4c7cec68b1ddd3a89de099942bb591" - integrity sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q== - -ws@^8.2.3, ws@^8.5.0: +ws@8.13.0: version "8.13.0" resolved "https://registry.yarnpkg.com/ws/-/ws-8.13.0.tgz#9a9fb92f93cf41512a0735c8f4dd09b8a1211cd0" integrity sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA== -x-default-browser@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/x-default-browser/-/x-default-browser-0.4.0.tgz#70cf0da85da7c0ab5cb0f15a897f2322a6bdd481" - integrity sha512-7LKo7RtWfoFN/rHx1UELv/2zHGMx8MkZKDq1xENmOCTkfIqZJ0zZ26NEJX8czhnPXVcqS0ARjjfJB+eJ0/5Cvw== - optionalDependencies: - default-browser-id "^1.0.4" - -xdm@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/xdm/-/xdm-2.1.0.tgz#d0060eb0f1230b47247bc6b3208ca3965d0053a4" - integrity sha512-3LxxbxKcRogYY7cQSMy1tUuU1zKNK9YPqMT7/S0r7Cz2QpyF8O9yFySGD7caOZt+LWUOQioOIX+6ZzCoBCpcAA== - dependencies: - "@rollup/pluginutils" "^4.0.0" - "@types/estree-jsx" "^0.0.1" - astring "^1.6.0" - estree-util-build-jsx "^2.0.0" - estree-util-is-identifier-name "^2.0.0" - estree-walker "^3.0.0" - got "^11.0.0" - hast-util-to-estree "^2.0.0" - loader-utils "^2.0.0" - markdown-extensions "^1.0.0" - mdast-util-mdx "^1.0.0" - micromark-extension-mdxjs "^1.0.0" - periscopic "^3.0.0" - remark-parse "^10.0.0" - remark-rehype "^9.0.0" - source-map "^0.7.0" - unified "^10.0.0" - unist-util-position-from-estree "^1.0.0" - unist-util-stringify-position "^3.0.0" - unist-util-visit "^4.0.0" - vfile "^5.0.0" - optionalDependencies: - deasync "^0.1.0" +ws@8.17.1, ws@^8.16.0: + version "8.17.1" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.17.1.tgz#9293da530bb548febc95371d90f9c878727d919b" + integrity sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ== -xml-name-validator@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a" - integrity sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw== +ws@^7, ws@^7.4.5, ws@^7.5.1, ws@^7.5.5, ws@^7.5.9: + version "7.5.9" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.9.tgz#54fa7db29f4c7cec68b1ddd3a89de099942bb591" + integrity sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q== -xmlchars@^2.1.1: - version "2.2.0" - resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb" - integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw== +ws@^7.2.0: + version "7.5.10" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.10.tgz#58b5c20dc281633f6c19113f39b349bd8bd558d9" + integrity sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ== -xregexp@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/xregexp/-/xregexp-2.0.0.tgz#52a63e56ca0b84a7f3a5f3d61872f126ad7a5943" - integrity sha512-xl/50/Cf32VsGq/1R8jJE5ajH1yMCQkpmoS10QbFZWl2Oor4H0Me64Pu2yxvsRWK3m6soJbmGfzSR7BYmDcWAA== +ws@^8.2.3, ws@^8.5.0: + version "8.14.2" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.14.2.tgz#6c249a806eb2db7a20d26d51e7709eab7b2e6c7f" + integrity sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g== xstream@^11.14.0: version "11.14.0" @@ -20859,16 +19863,11 @@ xstream@^11.14.0: globalthis "^1.0.1" symbol-observable "^2.0.3" -xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.1: +xtend@^4.0.0, xtend@~4.0.1: version "4.0.2" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== -xxhash-wasm@^0.4.2: - version "0.4.2" - resolved "https://registry.yarnpkg.com/xxhash-wasm/-/xxhash-wasm-0.4.2.tgz#752398c131a4dd407b5132ba62ad372029be6f79" - integrity sha512-/eyHVRJQCirEkSZ1agRSCwriMhwlyUcFkXD5TPVSLP+IPzjsqMVzZwdoczLp1SoQU0R3dxz1RpIK+4YNQbCVOA== - y18n@^4.0.0: version "4.0.3" resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.3.tgz#b5f259c82cd6e336921efd7bfd8bf560de9eeedf" @@ -20889,58 +19888,39 @@ yallist@^4.0.0: resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== +yaml@2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.3.1.tgz#02fe0975d23cd441242aa7204e09fc28ac2ac33b" + integrity sha512-2eHWfjaoXgTBC2jNM1LRef62VQa0umtvRiDSk6HSzW7RvS5YtkabJrwYLLEKWBc8a5U2PTSCs+dJjUTJdlHsWQ== + yaml@^1.10.0, yaml@^1.7.2: version "1.10.2" resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== -yaml@^2.1.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.2.1.tgz#3014bf0482dcd15147aa8e56109ce8632cd60ce4" - integrity sha512-e0WHiYql7+9wr4cWMx3TVQrNwejKaEe7/rHNmQmqRjazfOP5W8PB6Jpebb5o6fIapbz9o9+2ipcaTM2ZwDI6lw== - -yargs-parser@18.x, yargs-parser@^18.1.2: - version "18.1.3" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-18.1.3.tgz#be68c4975c6b2abf469236b0c870362fab09a7b0" - integrity sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ== - dependencies: - camelcase "^5.0.0" - decamelize "^1.2.0" +yaml@^2.2.2: + version "2.5.0" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.5.0.tgz#c6165a721cf8000e91c36490a41d7be25176cf5d" + integrity sha512-2wWLbGbYDiSqqIKoPjar3MPgB94ErzCtrNE1FdqGuaO0pi2JGjmE8aW8TDZwzU7vuxcGRdL/4gPQwQ7hD5AMSw== yargs-parser@21.1.1, yargs-parser@^21.1.1: version "21.1.1" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== -yargs-parser@^13.1.2: - version "13.1.2" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.2.tgz#130f09702ebaeef2650d54ce6e3e5706f7a4fb38" - integrity sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg== +yargs-parser@^18.1.2: + version "18.1.3" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-18.1.3.tgz#be68c4975c6b2abf469236b0c870362fab09a7b0" + integrity sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ== dependencies: camelcase "^5.0.0" decamelize "^1.2.0" -yargs-parser@^20.2.2, yargs-parser@^20.2.3, yargs-parser@^20.2.9: +yargs-parser@^20.2.2, yargs-parser@^20.2.3: version "20.2.9" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== -yargs@^13.2.4: - version "13.3.2" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.2.tgz#ad7ffefec1aa59565ac915f82dccb38a9c31a2dd" - integrity sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw== - dependencies: - cliui "^5.0.0" - find-up "^3.0.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 "^3.0.0" - which-module "^2.0.0" - y18n "^4.0.0" - yargs-parser "^13.1.2" - yargs@^15.3.1: version "15.4.1" resolved "https://registry.yarnpkg.com/yargs/-/yargs-15.4.1.tgz#0d87a16de01aee9d8bec2bfbf74f67851730f4f8" @@ -20971,10 +19951,10 @@ yargs@^16.2.0: y18n "^5.0.5" yargs-parser "^20.2.2" -yargs@^17.6.2: - version "17.7.1" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.1.tgz#34a77645201d1a8fc5213ace787c220eabbd0967" - integrity sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw== +yargs@^17.0.0, yargs@^17.6.2: + version "17.7.2" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269" + integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w== dependencies: cliui "^8.0.1" escalade "^3.1.1" @@ -20984,29 +19964,26 @@ yargs@^17.6.2: y18n "^5.0.5" yargs-parser "^21.1.1" -yn@3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" - integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== - yocto-queue@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== +yocto-queue@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-1.0.0.tgz#7f816433fb2cbc511ec8bf7d263c3b58a1a3c251" + integrity sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g== + zustand@^4.3.2: - version "4.3.7" - resolved "https://registry.yarnpkg.com/zustand/-/zustand-4.3.7.tgz#501b1f0393a7f1d103332e45ab574be5747fedce" - integrity sha512-dY8ERwB9Nd21ellgkBZFhudER8KVlelZm8388B5nDAXhO/+FZDhYMuRnqDgu5SYyRgz/iaf8RKnbUs/cHfOGlQ== + version "4.4.6" + resolved "https://registry.yarnpkg.com/zustand/-/zustand-4.4.6.tgz#03c78e3e2686c47095c93714c0c600b72a6512bd" + integrity sha512-Rb16eW55gqL4W2XZpJh0fnrATxYEG3Apl2gfHTyDSE965x/zxslTikpNch0JgNjJA9zK6gEFW8Fl6d1rTZaqgg== dependencies: use-sync-external-store "1.2.0" -zwitch@^1.0.0: - version "1.0.5" - resolved "https://registry.yarnpkg.com/zwitch/-/zwitch-1.0.5.tgz#d11d7381ffed16b742f6af7b3f223d5cd9fe9920" - integrity sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw== - -zwitch@^2.0.0: - version "2.0.4" - resolved "https://registry.yarnpkg.com/zwitch/-/zwitch-2.0.4.tgz#c827d4b0acb76fc3e685a4c6ec2902d51070e9d7" - integrity sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A== +zustand@^4.5.2: + version "4.5.5" + resolved "https://registry.yarnpkg.com/zustand/-/zustand-4.5.5.tgz#f8c713041543715ec81a2adda0610e1dc82d4ad1" + integrity sha512-+0PALYNJNgK6hldkgDq2vLrw5f6g/jCInz52n9RTpropGgeAf/ioFUCdtsjCqu4gNhW9D01rUQBROoRjdzyn2Q== + dependencies: + use-sync-external-store "1.2.2"