diff --git a/.github/actions/testsSetup/action.yml b/.github/actions/testsSetup/action.yml index 9fb418eafd..3669ea171b 100644 --- a/.github/actions/testsSetup/action.yml +++ b/.github/actions/testsSetup/action.yml @@ -8,18 +8,18 @@ inputs: runs: using: 'composite' steps: - - uses: actions/setup-node@v3 + - uses: actions/setup-node@v4 with: - node-version: "18.18.0" + node-version: "20.16.0" - name: Download deps cache artifacts - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: node_modules.tar.gz - name: Unzip node_modules shell: 'bash' run: tar xzf node_modules.tar.gz - name: Download build artifacts - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: rainbowbx-${{ github.sha }} path: build @@ -33,7 +33,7 @@ runs: uses: foundry-rs/foundry-toolchain@v1 with: version: nightly - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: repository: 'rainbow-me/browser-extension-env' token: ${{ inputs.gh-access-token }} diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 85072710f7..a29bd07192 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -16,10 +16,10 @@ jobs: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true steps: - - uses: actions/checkout@v3 - - uses: actions/setup-node@v3 + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 with: - node-version: "18.18.0" + node-version: "20.16.0" cache: 'yarn' - name: Install deps via Yarn run: yarn setup @@ -28,7 +28,7 @@ jobs: - name: Zip node_modules run: tar czf node_modules.tar.gz node_modules/ - name: Upload deps artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: node_modules.tar.gz path: node_modules.tar.gz @@ -38,17 +38,17 @@ jobs: runs-on: ubuntu-latest needs: [install] steps: - - uses: actions/checkout@v3 - - uses: actions/setup-node@v3 + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 with: - node-version: "18.18.0" + node-version: "20.16.0" - name: Download deps cache artifacts - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: node_modules.tar.gz - name: Unzip node_modules run: tar xzf node_modules.tar.gz - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: repository: 'rainbow-me/browser-extension-env' token: ${{ secrets.DOTENV_GITHUB_ACCESS_TOKEN }} @@ -63,7 +63,7 @@ jobs: - name: Build the extension run: yarn build:webpack - name: Upload artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: rainbowbx-${{ github.sha }} path: build/ @@ -78,7 +78,7 @@ jobs: # DISPLAY: :0 # VITEST_SEGFAULT_RETRY: 4 # steps: - # - uses: actions/checkout@v3 + # - uses: actions/checkout@v4 # - uses: ./.github/actions/firefoxTestsSetup # with: # gh-access-token: ${{ secrets.DOTENV_GITHUB_ACCESS_TOKEN }} @@ -93,7 +93,7 @@ jobs: # yarn vitest:parallel # - name: Upload deps artifacts # if: steps.FFE2eParallel.outcome == 'failure' - # uses: actions/upload-artifact@v3 + # uses: actions/upload-artifact@v4 # with: # name: screenshots # path: screenshots/ @@ -108,7 +108,7 @@ jobs: # DISPLAY: :0 # VITEST_SEGFAULT_RETRY: 4 # steps: - # - uses: actions/checkout@v3 + # - uses: actions/checkout@v4 # - uses: ./.github/actions/firefoxTestsSetup # with: # gh-access-token: ${{ secrets.DOTENV_GITHUB_ACCESS_TOKEN }} @@ -123,7 +123,7 @@ jobs: # yarn vitest:swap # - name: Upload deps artifacts # if: steps.FFE2eSwap.outcome == 'failure' - # uses: actions/upload-artifact@v3 + # uses: actions/upload-artifact@v4 # with: # name: screenshots # path: screenshots/ @@ -138,7 +138,7 @@ jobs: # DISPLAY: :0 # VITEST_SEGFAULT_RETRY: 4 # steps: - # - uses: actions/checkout@v3 + # - uses: actions/checkout@v4 # - uses: ./.github/actions/firefoxTestsSetup # with: # gh-access-token: ${{ secrets.DOTENV_GITHUB_ACCESS_TOKEN }} @@ -153,7 +153,7 @@ jobs: # yarn vitest:send # - name: Upload deps artifacts # if: steps.FFE2eSend.outcome == 'failure' - # uses: actions/upload-artifact@v3 + # uses: actions/upload-artifact@v4 # with: # name: screenshots # path: screenshots/ @@ -168,7 +168,7 @@ jobs: # DISPLAY: :0 # VITEST_SEGFAULT_RETRY: 4 # steps: - # - uses: actions/checkout@v3 + # - uses: actions/checkout@v4 # - uses: ./.github/actions/firefoxTestsSetup # with: # gh-access-token: ${{ secrets.DOTENV_GITHUB_ACCESS_TOKEN }} @@ -183,7 +183,7 @@ jobs: # yarn vitest:dappInteractions # - name: Upload deps artifacts # if: steps.FFE2eDappInteractions.outcome == 'failure' - # uses: actions/upload-artifact@v3 + # uses: actions/upload-artifact@v4 # with: # name: screenshots # path: screenshots/ @@ -192,14 +192,14 @@ jobs: # run: exit 1 # CHROME TESTS chrome-e2e-parallel: - runs-on: ubuntu-latest + runs-on: beefy-runner-bx timeout-minutes: 18 needs: [build] env: DISPLAY: :0 VITEST_SEGFAULT_RETRY: 4 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: ./.github/actions/chromeTestsSetup with: gh-access-token: ${{ secrets.DOTENV_GITHUB_ACCESS_TOKEN }} @@ -213,7 +213,7 @@ jobs: yarn vitest:parallel - name: Upload deps artifacts if: steps.ChromeE2EParallel.outcome == 'failure' - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: screenshots path: screenshots/ @@ -228,7 +228,7 @@ jobs: DISPLAY: :0 VITEST_SEGFAULT_RETRY: 3 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: ./.github/actions/chromeTestsSetup with: gh-access-token: ${{ secrets.DOTENV_GITHUB_ACCESS_TOKEN }} @@ -242,7 +242,7 @@ jobs: yarn vitest:swap - name: Upload deps artifacts if: steps.ChromeE2ESwaps.outcome == 'failure' - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: screenshots path: screenshots/ @@ -257,7 +257,7 @@ jobs: DISPLAY: :0 VITEST_SEGFAULT_RETRY: 3 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: ./.github/actions/chromeTestsSetup with: gh-access-token: ${{ secrets.DOTENV_GITHUB_ACCESS_TOKEN }} @@ -271,7 +271,7 @@ jobs: yarn vitest:send - name: Upload deps artifacts if: steps.ChromeE2ESend.outcome == 'failure' - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: screenshots path: screenshots/ @@ -286,7 +286,7 @@ jobs: DISPLAY: :0 VITEST_SEGFAULT_RETRY: 3 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: ./.github/actions/chromeTestsSetup with: gh-access-token: ${{ secrets.DOTENV_GITHUB_ACCESS_TOKEN }} @@ -300,7 +300,7 @@ jobs: yarn vitest:send:optimism - name: Upload deps artifacts if: steps.ChromeOpE2ESend.outcome == 'failure' - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: screenshots path: screenshots/ @@ -315,7 +315,7 @@ jobs: DISPLAY: :0 VITEST_SEGFAULT_RETRY: 3 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: ./.github/actions/chromeTestsSetup with: gh-access-token: ${{ secrets.DOTENV_GITHUB_ACCESS_TOKEN }} @@ -329,7 +329,7 @@ jobs: yarn vitest:dappInteractions - name: Upload deps artifacts if: steps.ChromeE2EDappInteractions.outcome == 'failure' - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: screenshots path: screenshots/ @@ -345,18 +345,18 @@ jobs: # DISPLAY: :0 # VITEST_SEGFAULT_RETRY: 3 # steps: - # - uses: actions/checkout@v3 - # - uses: actions/setup-node@v3 + # - uses: actions/checkout@v4 + # - uses: actions/setup-node@v4 # with: - # node-version: "18.18.0" + # node-version: "20.16.0" # - name: Download deps cache artifacts - # uses: actions/download-artifact@v3 + # uses: actions/download-artifact@v4 # with: # name: node_modules.tar.gz # - name: Unzip node_modules # run: tar xzvf node_modules.tar.gz # - name: Download build artifacts - # uses: actions/download-artifact@v3 + # uses: actions/download-artifact@v4 # with: # name: rainbowbx-${{ github.sha }} # path: build @@ -376,7 +376,7 @@ jobs: # uses: foundry-rs/foundry-toolchain@v1 # with: # version: nightly - # - uses: actions/checkout@v3 + # - uses: actions/checkout@v4 # with: # repository: 'rainbow-me/browser-extension-env' # token: ${{ secrets.DOTENV_GITHUB_ACCESS_TOKEN }} @@ -394,30 +394,28 @@ jobs: runs-on: ubuntu-latest needs: [install] steps: - - uses: actions/checkout@v3 - - uses: actions/setup-node@v3 + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 with: - node-version: "18.18.0" + node-version: "20.16.0" - name: Download deps cache artifacts - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: node_modules.tar.gz - name: Unzip node_modules run: tar xzf node_modules.tar.gz - name: Install rust - uses: actions-rs/toolchain@v1 + uses: moonrepo/setup-rust@v1.2.1 with: - toolchain: stable - target: wasm32-unknown-unknown + channel: stable profile: minimal - override: true - name: Fetch networks run: yarn fetch:networks - name: Install Anvil uses: foundry-rs/foundry-toolchain@v1 with: version: nightly - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: repository: 'rainbow-me/browser-extension-env' token: ${{ secrets.DOTENV_GITHUB_ACCESS_TOKEN }} @@ -435,12 +433,12 @@ jobs: runs-on: ubuntu-latest needs: [install] steps: - - uses: actions/checkout@v3 - - uses: actions/setup-node@v3 + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 with: - node-version: "18.18.0" + node-version: "20.16.0" - name: Download deps cache artifacts - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: node_modules.tar.gz - name: Unzip node_modules @@ -459,9 +457,9 @@ jobs: runs-on: ubuntu-latest needs: [chrome-e2e-parallel, chrome-e2e-swap, chrome-e2e-send, chrome-e2e-dappInteractions, chrome-optimism-e2e-send, unit-tests, ci-checks] steps: - - uses: geekyeggo/delete-artifact@v2 + - uses: geekyeggo/delete-artifact@v5 with: name: node_modules.tar.gz - - uses: geekyeggo/delete-artifact@v2 + - uses: geekyeggo/delete-artifact@v5 with: name: screenshots diff --git a/.github/workflows/publish-internal.yml b/.github/workflows/publish-internal.yml index 69fecf61b0..c98852fd61 100644 --- a/.github/workflows/publish-internal.yml +++ b/.github/workflows/publish-internal.yml @@ -12,7 +12,7 @@ jobs: concurrency: group: ${{ github.workflow }}-${{ github.ref }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: repository: ${{ github.event.pull_request.head.repo.full_name }} ref: ${{ github.event.pull_request.head.ref }} @@ -24,13 +24,13 @@ jobs: echo "No new commits. Canceling publish..." exit 1 fi - - uses: actions/setup-node@v2 + - uses: actions/setup-node@v4 with: - node-version: "18.18.0" + node-version: "20.16.0" cache: 'yarn' - name: Install deps via Yarn run: yarn setup - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: repository: 'rainbow-me/browser-extension-env' token: ${{ secrets.DOTENV_GITHUB_ACCESS_TOKEN }} @@ -50,7 +50,7 @@ jobs: - name: Zip it run: yarn zip - name: Archive the build artifact - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: rainbowbx-v${{ env.release_version }} path: build/ diff --git a/.github/workflows/publish-prod-chrome.yml b/.github/workflows/publish-prod-chrome.yml index bc29228155..8b8846c4ca 100644 --- a/.github/workflows/publish-prod-chrome.yml +++ b/.github/workflows/publish-prod-chrome.yml @@ -9,18 +9,18 @@ jobs: concurrency: group: ${{ github.workflow }}-${{ github.ref }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: repository: ${{ github.event.pull_request.head.repo.full_name }} ref: ${{ github.event.pull_request.head.ref }} token: ${{ secrets.REPO_TOKEN }} - - uses: actions/setup-node@v2 + - uses: actions/setup-node@v4 with: - node-version: "18.18.0" + node-version: "20.16.0" cache: 'yarn' - name: Install deps via Yarn run: yarn setup - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: repository: 'rainbow-me/browser-extension-env' token: ${{ secrets.DOTENV_GITHUB_ACCESS_TOKEN }} @@ -34,7 +34,7 @@ jobs: - name: Update the manifest run: yarn update-manifest prod - name: Archive the build artifact - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: rainbowbx-chrome-v${{ env.release_version }} path: build/ diff --git a/.github/workflows/publish-prod-firefox.yml b/.github/workflows/publish-prod-firefox.yml index e0bb93c26c..b876399a17 100644 --- a/.github/workflows/publish-prod-firefox.yml +++ b/.github/workflows/publish-prod-firefox.yml @@ -9,18 +9,18 @@ jobs: concurrency: group: ${{ github.workflow }}-${{ github.ref }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: repository: ${{ github.event.pull_request.head.repo.full_name }} ref: ${{ github.event.pull_request.head.ref }} token: ${{ secrets.REPO_TOKEN }} - - uses: actions/setup-node@v2 + - uses: actions/setup-node@v4 with: - node-version: "18.18.0" + node-version: "20.16.0" cache: 'yarn' - name: Install deps via Yarn run: yarn setup - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: repository: 'rainbow-me/browser-extension-env' token: ${{ secrets.DOTENV_GITHUB_ACCESS_TOKEN }} @@ -34,7 +34,7 @@ jobs: - name: Update the manifest run: yarn update-manifest prod - name: Archive the build artifact - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: rainbowbx-firefox-v${{ env.release_version }} path: build/ diff --git a/.github/workflows/rebase.yml b/.github/workflows/rebase.yml index 80829a3475..12d8ad582f 100644 --- a/.github/workflows/rebase.yml +++ b/.github/workflows/rebase.yml @@ -9,7 +9,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout the latest code - uses: actions/checkout@v2 + uses: actions/checkout@v4 with: token: ${{ secrets.GITHUB_TOKEN }} fetch-depth: 0 # otherwise, you will fail to push refs to dest repo diff --git a/.nvmrc b/.nvmrc index b714151ef9..b427e2ae2f 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -v18.18.0 \ No newline at end of file +v20.16.0 \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 01db726ee9..17a753acb8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,41 @@ and this project adheres to [Semantic Versioning](http://semver.org/) ### Testing +## [v1.5.32](https://github.com/rainbow-me/browser-extension/releases/tag/v1.5.32) + +### Added + +- Degen Mode is here to make Swapping even faster. Turn it on in Swap Settings to skip the review steps #1652 + +### Changed + +- Automatically defaulting ETH as the output for Swaps, and using Max values to reduce clicks #1622 #1653 +- Swap values are now rounded to match the Rainbow App. Pasting an exact amount or Maxing will continue to function as expected #1656 +- Added support for Ham and Cronos chains in Custom Networks #1658 +- You'll now see Hardware Wallet identifiers for wallets in the Send flow #1659 + +### Fixed + +- Token balances will now update in realtime alongside relevant transactions #1649 +- Fixed an issue where Pending Transactions would sometimes disappear from Activity between submission and confirmation #1649 +- Fixed an issue where Rainbow Rewards claim confirmations were not properly rendered #1668 +- Fixed percentage difference calculation for Token charts #1660 +- Fixed an issue with keyboard navigation highlights for Rewards #1672 +- Now merging Private Keys and Wallet Groups where possible upon import #1435 +- Fixed an issue with the font for Tip highlights on Firefox #1661 + +### Internal + +- Reduced artifact noise by deprecating artifact comment links and leveraging persistent artifacts on workflow runs instead #1628 +- Added axios advisory to allowlist #1664 +- Upgraded to Swap SDK v23 #1662 +- Re-adding optional chaining for sellAsset and buyAsset on quote response, related to #1662 (#1673) +- Fix Wrapping and Unwrapping, related to #1662 (#1675) + +### Testing + +- Use beefy-runner-bx in the chrome-e2e-parallel suite #1665 + ## [v1.5.23](https://github.com/rainbow-me/browser-extension/releases/tag/v1.5.23) ### Fixed diff --git a/README.md b/README.md index ed245f6adb..dc82825506 100644 --- a/README.md +++ b/README.md @@ -60,7 +60,7 @@ Additionally, we're using some well known tools engineered by the MetaMask team: ### 1. Set up Node -Use node v18 or if you use nvm follow the instructions below +Use node v20 or if you use nvm follow the instructions below ```bash nvm install diff --git a/README_FIREFOX.md b/README_FIREFOX.md index 17c8443e55..d1e29fc012 100644 --- a/README_FIREFOX.md +++ b/README_FIREFOX.md @@ -9,12 +9,12 @@ ### 1. Set up Node -Use node v18 (18.18) or if you use nvm follow the instructions below +Use node v20 (20.16.0) or if you use nvm follow the instructions below ```bash -nvm install 18.18 +nvm install 20.16.0 # or -nvm use 18.18 +nvm use 20.16.0 ``` ### 2. Install project dependencies diff --git a/e2e/serial/dappInteractions/1_appInteractionsFlow.test.ts b/e2e/serial/dappInteractions/1_appInteractionsFlow.test.ts index c2b67356d1..339267ce56 100644 --- a/e2e/serial/dappInteractions/1_appInteractionsFlow.test.ts +++ b/e2e/serial/dappInteractions/1_appInteractionsFlow.test.ts @@ -91,13 +91,11 @@ describe.runIf(browser !== 'firefox')('App interactions flow', () => { rootURL += extensionId; }); - // eslint-disable-next-line @typescript-eslint/no-explicit-any - beforeEach(async (context: any) => { + beforeEach<{ driver: WebDriver }>(async (context) => { context.driver = driver; }); - // eslint-disable-next-line @typescript-eslint/no-explicit-any - afterEach(async (context: any) => { + afterEach<{ driver: WebDriver }>(async (context) => { await takeScreenshotOnFailure(context); }); diff --git a/e2e/serial/dappInteractions/2_dappInteractionFlow.test.ts b/e2e/serial/dappInteractions/2_dappInteractionFlow.test.ts index c2ea4f6c85..aa0f12c92c 100644 --- a/e2e/serial/dappInteractions/2_dappInteractionFlow.test.ts +++ b/e2e/serial/dappInteractions/2_dappInteractionFlow.test.ts @@ -59,13 +59,11 @@ describe.runIf(browser !== 'firefox')('App interactions flow', () => { rootURL += extensionId; }); - // eslint-disable-next-line @typescript-eslint/no-explicit-any - beforeEach(async (context: any) => { + beforeEach<{ driver: WebDriver }>(async (context) => { context.driver = driver; }); - // eslint-disable-next-line @typescript-eslint/no-explicit-any - afterEach(async (context: any) => { + afterEach<{ driver: WebDriver }>(async (context) => { await takeScreenshotOnFailure(context); }); diff --git a/e2e/serial/dappInteractions/3_dappAccountsSwitcher.test.ts b/e2e/serial/dappInteractions/3_dappAccountsSwitcher.test.ts index 50d2926815..6a83b37e80 100644 --- a/e2e/serial/dappInteractions/3_dappAccountsSwitcher.test.ts +++ b/e2e/serial/dappInteractions/3_dappAccountsSwitcher.test.ts @@ -55,13 +55,11 @@ describe.runIf(browser !== 'firefox')('Dapp accounts switcher flow', () => { rootURL += extensionId; }); - // eslint-disable-next-line @typescript-eslint/no-explicit-any - beforeEach(async (context: any) => { + beforeEach<{ driver: WebDriver }>(async (context) => { context.driver = driver; }); - // eslint-disable-next-line @typescript-eslint/no-explicit-any - afterEach(async (context: any) => { + afterEach<{ driver: WebDriver }>(async (context) => { await takeScreenshotOnFailure(context); }); diff --git a/e2e/serial/dappInteractions/4_networksAndTestnetModeFlow.test.ts b/e2e/serial/dappInteractions/4_networksAndTestnetModeFlow.test.ts index 0aa51a1bd1..4f62f2a920 100644 --- a/e2e/serial/dappInteractions/4_networksAndTestnetModeFlow.test.ts +++ b/e2e/serial/dappInteractions/4_networksAndTestnetModeFlow.test.ts @@ -52,12 +52,10 @@ describe.runIf(browser !== 'firefox')('Networks & Testnet Mode flows', () => { }); afterAll(async () => await driver.quit()); - // eslint-disable-next-line @typescript-eslint/no-explicit-any beforeEach<{ driver: WebDriver }>(async (context) => { context.driver = driver; }); - // eslint-disable-next-line @typescript-eslint/no-explicit-any afterEach<{ driver: WebDriver }>(async (context) => { await takeScreenshotOnFailure(context); }); diff --git a/e2e/serial/dappInteractions/5_maliciousDapp.test.ts b/e2e/serial/dappInteractions/5_maliciousDapp.test.ts new file mode 100644 index 0000000000..dbcf576dc4 --- /dev/null +++ b/e2e/serial/dappInteractions/5_maliciousDapp.test.ts @@ -0,0 +1,123 @@ +import 'chromedriver'; +import 'geckodriver'; +import { WebDriver } from 'selenium-webdriver'; +import { + afterAll, + afterEach, + beforeAll, + beforeEach, + describe, + expect, + it, +} from 'vitest'; + +import { + checkWalletName, + delayTime, + findElementByTestId, + findElementByTestIdAndClick, + findElementByText, + getAllWindowHandles, + getExtensionIdByName, + getRootUrl, + getWindowHandle, + goToPopup, + importWalletFlow, + initDriverWithOptions, + takeScreenshotOnFailure, + waitAndClick, +} from '../../helpers'; +import { TEST_VARIABLES } from '../../walletVariables'; + +let rootURL = getRootUrl(); +let driver: WebDriver; + +const browser = process.env.BROWSER || 'chrome'; +const os = process.env.OS || 'mac'; + +describe('App interactions flow', () => { + beforeAll(async () => { + driver = await initDriverWithOptions({ + browser, + os, + }); + const extensionId = await getExtensionIdByName(driver, 'Rainbow'); + if (!extensionId) throw new Error('Extension not found'); + rootURL += extensionId; + }); + + beforeEach<{ driver: WebDriver }>(async (context) => { + context.driver = driver; + }); + + afterEach<{ driver: WebDriver }>(async (context) => { + await takeScreenshotOnFailure(context); + }); + + afterAll(() => driver.quit()); + + it('should be able import a wallet via seed', async () => { + await importWalletFlow(driver, rootURL, TEST_VARIABLES.EMPTY_WALLET.SECRET); + }); + + it('should display account name', async () => { + await checkWalletName(driver, rootURL, TEST_VARIABLES.EMPTY_WALLET.ADDRESS); + }); + + it('should be able to go to setings', async () => { + await goToPopup(driver, rootURL); + await findElementByTestIdAndClick({ id: 'home-page-header-right', driver }); + await findElementByTestIdAndClick({ id: 'settings-link', driver }); + }); + + it('should be able to connect to hardhat', async () => { + await findElementByTestIdAndClick({ id: 'connect-to-hardhat', driver }); + const button = await findElementByText(driver, 'Disconnect from Hardhat'); + expect(button).toBeTruthy(); + await findElementByTestIdAndClick({ + id: 'navbar-button-with-back', + driver, + }); + }); + + it('should be able to navigate to the malicious app and click connect', async () => { + await delayTime('long'); + await driver.get('https://test-dap-welps.vercel.app/'); + const dappHandler = await getWindowHandle({ driver }); + + const button = await findElementByTestId({ + id: 'rk-connect-button', + driver, + }); + expect(button).toBeTruthy(); + await waitAndClick(button, driver); + + await delayTime('long'); + + await findElementByTestIdAndClick({ + id: 'rk-wallet-option-rainbow', + driver, + }); + await delayTime('long'); + + const { popupHandler } = await getAllWindowHandles({ driver, dappHandler }); + await driver.switchTo().window(popupHandler); + }); + + it('should be able to navigate to switch to BX and see malicious app warning', async () => { + await delayTime('long'); + const dappWarning = await findElementByTestId({ + id: 'malicious-request-warning', + driver, + }); + const warningText = await dappWarning.getText(); + + const warningText1 = 'This app is likely malicious'; + const warningText2 = + 'Signing messages or transactions from this app could result in losing your assets'; + + expect(dappWarning).toBeTruthy(); + expect(warningText).toContain(warningText1); + expect(warningText).toContain(warningText2); + }); +}); diff --git a/e2e/serial/swap/1_swapFlow1.test.ts b/e2e/serial/swap/1_swapFlow1.test.ts index d31b8471c5..ad28107fac 100644 --- a/e2e/serial/swap/1_swapFlow1.test.ts +++ b/e2e/serial/swap/1_swapFlow1.test.ts @@ -474,25 +474,15 @@ it('should be able to open remove token to buy and check favorites and verified }); it('should be able to favorite a token and check the info button is present', async () => { - await findElementByTestIdAndClick({ - id: `${SWAP_VARIABLES.ZEROX_MAINNET_ID}-verified-token-to-buy-row-favorite-button`, - driver, - }); await delayTime('short'); await findElementByTestIdAndClick({ - id: `${SWAP_VARIABLES.ZEROX_MAINNET_ID}-favorites-token-to-buy-row-info-button`, + id: `${SWAP_VARIABLES.WBTC_MAINNET_ID}-favorites-token-to-buy-row-info-button`, driver, }); await findElementByTestIdAndClick({ - id: `${SWAP_VARIABLES.ZEROX_MAINNET_ID}-favorites-token-to-buy-row-info-button-copy`, + id: `${SWAP_VARIABLES.WBTC_MAINNET_ID}-favorites-token-to-buy-row-info-button-copy`, driver, }); - if (isFirefox) { - await findElementByTestIdAndClick({ - id: `${SWAP_VARIABLES.ZEROX_MAINNET_ID}-token-to-buy-token-input-remove`, - driver, - }); - } await findElementByTestIdAndClick({ id: `${SWAP_VARIABLES.WBTC_MAINNET_ID}-favorites-token-to-buy-row`, driver, diff --git a/e2e/walletVariables.ts b/e2e/walletVariables.ts index 6de5eadede..9412fd5fac 100644 --- a/e2e/walletVariables.ts +++ b/e2e/walletVariables.ts @@ -49,6 +49,7 @@ export const SWAP_VARIABLES = { USDC_MAINNET_ADDRESS: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', WBTC_MAINNET_ID: '0x2260fac5e5542a773aa44fbcfedf7c193bc2c599_1', ZEROX_MAINNET_ID: '0xe41d2489571d322189246dafa5ebde1f4699f498_1', + REKT_MAINNET_ID: '0x4f8b986ecffe7bed5dbeb2b49310fb00ca85a539_1', }; export const HARDWARE_WALLETS = { diff --git a/lavamoat/build-webpack/policy.json b/lavamoat/build-webpack/policy.json index e2a8f44a30..19440ec708 100644 --- a/lavamoat/build-webpack/policy.json +++ b/lavamoat/build-webpack/policy.json @@ -571,8 +571,36 @@ "packages": { "eslint-config-rainbow>eslint-import-resolver-babel-module>@babel/core>@babel/helper-compilation-targets>@babel/compat-data": true, "eslint-config-rainbow>eslint-import-resolver-babel-module>@babel/core>@babel/helper-compilation-targets>@babel/helper-validator-option": true, - "semver": true, - "webpack>browserslist": true + "eslint-config-rainbow>eslint-import-resolver-babel-module>@babel/core>@babel/helper-compilation-targets>browserslist": true, + "semver": true + } + }, + "eslint-config-rainbow>eslint-import-resolver-babel-module>@babel/core>@babel/helper-compilation-targets>browserslist": { + "builtin": { + "fs.existsSync": true, + "fs.readFileSync": true, + "fs.statSync": true, + "path.basename": true, + "path.dirname": true, + "path.join": true, + "path.resolve": true + }, + "globals": { + "console.warn": true, + "process.env.BROWSERSLIST": true, + "process.env.BROWSERSLIST_CONFIG": true, + "process.env.BROWSERSLIST_DANGEROUS_EXTEND": true, + "process.env.BROWSERSLIST_DISABLE_CACHE": true, + "process.env.BROWSERSLIST_ENV": true, + "process.env.BROWSERSLIST_IGNORE_OLD_DATA": true, + "process.env.BROWSERSLIST_STATS": true, + "process.env.NODE_ENV": true, + "process.versions.node": true + }, + "packages": { + "eslint-config-rainbow>eslint-import-resolver-babel-module>@babel/core>@babel/helper-compilation-targets>browserslist>caniuse-lite": true, + "eslint-config-rainbow>eslint-import-resolver-babel-module>@babel/core>@babel/helper-compilation-targets>browserslist>electron-to-chromium": true, + "eslint-config-rainbow>eslint-import-resolver-babel-module>@babel/core>@babel/helper-compilation-targets>browserslist>node-releases": true } }, "eslint-config-rainbow>eslint-import-resolver-babel-module>@babel/core>@babel/helper-module-transforms": { @@ -1659,33 +1687,6 @@ "Buffer": true } }, - "web-ext>watchpack": { - "builtin": { - "events.EventEmitter": true, - "fs.readlinkSync": true, - "fs.watch": true, - "os.platform": true, - "path.basename": true, - "path.dirname": true, - "path.join": true, - "path.resolve": true - }, - "globals": { - "clearTimeout": true, - "console.error": true, - "process.env.WATCHPACK_POLLING": true, - "process.env.WATCHPACK_RECURSIVE_WATCHER_LOGGING": true, - "process.env.WATCHPACK_WATCHER_LIMIT": true, - "process.nextTick": true, - "process.platform": true, - "process.stderr.write": true, - "setTimeout": true - }, - "packages": { - "webpack>glob-to-regexp": true, - "webpack>graceful-fs": true - } - }, "webpack": { "builtin": { "buffer.constants.MAX_LENGTH": true, @@ -1720,7 +1721,8 @@ "util.deprecate": true, "util.format": true, "util.inspect.custom": true, - "vm.runInNewContext": true, + "vm.createContext": true, + "vm.runInContext": true, "vm.runInThisContext": true, "zlib.constants.BROTLI_MODE_TEXT": true, "zlib.constants.BROTLI_PARAM_DISABLE_LITERAL_CONTEXT_MODELING": true, @@ -1772,12 +1774,11 @@ "html-webpack-plugin": true, "mini-css-extract-plugin": true, "ts-loader": true, - "web-ext>watchpack": true, "webpack>@webassemblyjs/ast": true, "webpack>@webassemblyjs/wasm-edit": true, "webpack>@webassemblyjs/wasm-parser": true, "webpack>acorn": true, - "webpack>acorn-import-assertions": true, + "webpack>acorn-import-attributes": true, "webpack>browserslist": true, "webpack>chrome-trace-event": true, "webpack>enhanced-resolve": true, @@ -1792,6 +1793,7 @@ "webpack>schema-utils": true, "webpack>tapable": true, "webpack>terser-webpack-plugin": true, + "webpack>watchpack": true, "webpack>webpack-sources": true } }, @@ -1939,11 +1941,6 @@ "webpack>@webassemblyjs/wasm-parser": true } }, - "webpack>@webassemblyjs/wasm-edit>@webassemblyjs/helper-buffer": { - "globals": { - "Buffer.from": true - } - }, "webpack>@webassemblyjs/wasm-edit>@webassemblyjs/helper-wasm-section": { "packages": { "webpack>@webassemblyjs/ast": true, @@ -1970,7 +1967,6 @@ }, "webpack>@webassemblyjs/wasm-parser": { "globals": { - "Buffer.from": true, "console.log": true, "console.warn": true }, @@ -2005,7 +2001,7 @@ "define": true } }, - "webpack>acorn-import-assertions": { + "webpack>acorn-import-attributes": { "packages": { "webpack>acorn": true } @@ -2018,18 +2014,12 @@ "path.basename": true, "path.dirname": true, "path.join": true, + "path.relative": true, "path.resolve": true }, "globals": { "console.warn": true, - "process.env.BROWSERSLIST": true, - "process.env.BROWSERSLIST_CONFIG": true, - "process.env.BROWSERSLIST_DANGEROUS_EXTEND": true, - "process.env.BROWSERSLIST_DISABLE_CACHE": true, - "process.env.BROWSERSLIST_ENV": true, - "process.env.BROWSERSLIST_IGNORE_OLD_DATA": true, - "process.env.BROWSERSLIST_STATS": true, - "process.env.NODE_ENV": true, + "process.env": true, "process.versions.node": true }, "packages": { @@ -2049,22 +2039,41 @@ }, "webpack>enhanced-resolve": { "builtin": { + "module.findPnpApi": true, "path.basename": true, - "path.join": true, "path.posix.normalize": true, "path.win32.normalize": true, "process.nextTick": true, "process.versions.pnp": true }, "globals": { + "Buffer.isBuffer": true, + "URL": true, "clearTimeout": true, "setTimeout": true }, "packages": { - "webpack>graceful-fs": true, + "webpack>enhanced-resolve>graceful-fs": true, "webpack>tapable": true } }, + "webpack>enhanced-resolve>graceful-fs": { + "builtin": { + "assert.equal": true, + "constants.O_SYMLINK": true, + "constants.O_WRONLY": true, + "constants.hasOwnProperty": true, + "fs": true, + "stream.Stream.call": true, + "util": true + }, + "globals": { + "clearTimeout": true, + "console.error": true, + "process": true, + "setTimeout": true + } + }, "webpack>es-module-lexer": { "globals": { "Buffer": true, @@ -2257,6 +2266,50 @@ "define": true } }, + "webpack>watchpack": { + "builtin": { + "events.EventEmitter": true, + "fs.readlinkSync": true, + "fs.watch": true, + "os.platform": true, + "path.basename": true, + "path.dirname": true, + "path.join": true, + "path.resolve": true + }, + "globals": { + "clearTimeout": true, + "console.error": true, + "process.env.WATCHPACK_POLLING": true, + "process.env.WATCHPACK_RECURSIVE_WATCHER_LOGGING": true, + "process.env.WATCHPACK_WATCHER_LIMIT": true, + "process.nextTick": true, + "process.platform": true, + "process.stderr.write": true, + "setTimeout": true + }, + "packages": { + "webpack>glob-to-regexp": true, + "webpack>watchpack>graceful-fs": true + } + }, + "webpack>watchpack>graceful-fs": { + "builtin": { + "assert.equal": true, + "constants.O_SYMLINK": true, + "constants.O_WRONLY": true, + "constants.hasOwnProperty": true, + "fs": true, + "stream.Stream.call": true, + "util": true + }, + "globals": { + "clearTimeout": true, + "console.error": true, + "process": true, + "setTimeout": true + } + }, "webpack>webpack-sources": { "globals": { "Buffer.byteLength": true, diff --git a/package.json b/package.json index 5c1c3e1ee0..dde2f4dfd4 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "browser-extension", "license": "GPL-3.0-only", - "version": "1.5.29", + "version": "1.5.37", "scripts": { "//enable dev mode": "", "devmode:on": "sed -i'' -e 's/IS_DEV.*/IS_DEV=true/g' .env", @@ -76,6 +76,9 @@ "firefox:lint": "yarn web-ext lint --source-dir ./build", "firefox:run": "yarn web-ext run --source-dir ./build/ -f='/Applications/Firefox Developer Edition.app/Contents/MacOS/firefox'" }, + "engines": { + "node": ">=20.16.0" + }, "dependencies": { "@capsizecss/core": "3.0.0", "@ethereumjs/tx": "5.0.0", @@ -105,7 +108,7 @@ "@radix-ui/react-tabs": "1.0.4", "@radix-ui/react-tooltip": "1.0.3", "@rainbow-me/provider": "0.1.1", - "@rainbow-me/swaps": "0.23.0", + "@rainbow-me/swaps": "0.24.0", "@rudderstack/analytics-js-service-worker": "3.0.6", "@scure/bip39": "1.2.1", "@sentry/browser": "8.15.0", @@ -154,7 +157,7 @@ "react-switch": "7.0.0", "socket.io-client": "4.5.3", "validator": "13.9.0", - "viem": "2.17.0", + "viem": "2.21.0", "wagmi": "2.8.1", "word-wrap": "1.2.4", "zustand": "4.1.5" @@ -226,7 +229,7 @@ "typescript": "5.2.2", "vitest": "0.34.6", "web-ext": "7.6.2", - "webpack": "5.79.0", + "webpack": "5.94.0", "webpack-bundle-analyzer": "4.8.0", "webpack-cli": "5.1.4", "webpack-extension-reloader": "rainbow-me/webpack-extension-reloader#23fc3ed1f59f295702d459ad58aec90d6f0a3551", @@ -272,7 +275,9 @@ "jose": "4.15.5", "phin": "3.7.1", "braces": "3.0.3", - "ws": "8.17.1" + "ws": "8.17.1", + "micromatch": "4.0.8", + "webpack": "5.94.0" }, "lavamoat": { "allowScripts": { diff --git a/patches/webpack+5.79.0.patch b/patches/webpack+5.79.0.patch deleted file mode 100644 index d152756030..0000000000 --- a/patches/webpack+5.79.0.patch +++ /dev/null @@ -1,557 +0,0 @@ -# These patches are required for LavaMoat Node compat -diff --git a/node_modules/webpack/lib/Compiler.js b/node_modules/webpack/lib/Compiler.js -index 2d59a1a..9e23b9a 100644 ---- a/node_modules/webpack/lib/Compiler.js -+++ b/node_modules/webpack/lib/Compiler.js -@@ -449,16 +449,16 @@ class Compiler { - const onCompiled = (err, compilation) => { - if (err) return finalCallback(err); - -- if (this.hooks.shouldEmit.call(compilation) === false) { -- compilation.startTime = startTime; -- compilation.endTime = Date.now(); -- const stats = new Stats(compilation); -- this.hooks.done.callAsync(stats, err => { -- if (err) return finalCallback(err); -- return finalCallback(null, stats); -- }); -- return; -- } -+ // if (this.hooks.shouldEmit.call(compilation) === false) { -+ // compilation.startTime = startTime; -+ // compilation.endTime = Date.now(); -+ // const stats = new Stats(compilation); -+ // this.hooks.done.callAsync(stats, err => { -+ // if (err) return finalCallback(err); -+ // return finalCallback(null, stats); -+ // }); -+ // return; -+ // } - - process.nextTick(() => { - logger = compilation.getLogger("webpack.Compiler"); -diff --git a/node_modules/webpack/lib/RuntimeGlobals.js b/node_modules/webpack/lib/RuntimeGlobals.js -index 90d16b0..a53face 100644 ---- a/node_modules/webpack/lib/RuntimeGlobals.js -+++ b/node_modules/webpack/lib/RuntimeGlobals.js -@@ -349,7 +349,7 @@ exports.system = "__webpack_require__.System"; - * the shorthand for Object.prototype.hasOwnProperty - * using of it decreases the compiled bundle size - */ --exports.hasOwnProperty = "__webpack_require__.o"; -+exports.hasOwnProperty_ = "__webpack_require__.o"; - - /** - * the System.register context object -diff --git a/node_modules/webpack/lib/RuntimePlugin.js b/node_modules/webpack/lib/RuntimePlugin.js -index 624473d..7d513dd 100644 ---- a/node_modules/webpack/lib/RuntimePlugin.js -+++ b/node_modules/webpack/lib/RuntimePlugin.js -@@ -78,7 +78,7 @@ const MODULE_DEPENDENCIES = { - }; - - const TREE_DEPENDENCIES = { -- [RuntimeGlobals.definePropertyGetters]: [RuntimeGlobals.hasOwnProperty], -+ [RuntimeGlobals.definePropertyGetters]: [RuntimeGlobals.hasOwnProperty_], - [RuntimeGlobals.compatGetDefaultExport]: [ - RuntimeGlobals.definePropertyGetters - ], -@@ -88,7 +88,7 @@ const TREE_DEPENDENCIES = { - RuntimeGlobals.require - ], - [RuntimeGlobals.initializeSharing]: [RuntimeGlobals.shareScopeMap], -- [RuntimeGlobals.shareScopeMap]: [RuntimeGlobals.hasOwnProperty] -+ [RuntimeGlobals.shareScopeMap]: [RuntimeGlobals.hasOwnProperty_] - }; - - class RuntimePlugin { -@@ -167,7 +167,7 @@ class RuntimePlugin { - return true; - }); - compilation.hooks.runtimeRequirementInTree -- .for(RuntimeGlobals.hasOwnProperty) -+ .for(RuntimeGlobals.hasOwnProperty_) - .tap("RuntimePlugin", chunk => { - compilation.addRuntimeModule( - chunk, -diff --git a/node_modules/webpack/lib/container/ContainerEntryModule.js b/node_modules/webpack/lib/container/ContainerEntryModule.js -index 0de4d58..7d83410 100644 ---- a/node_modules/webpack/lib/container/ContainerEntryModule.js -+++ b/node_modules/webpack/lib/container/ContainerEntryModule.js -@@ -144,7 +144,7 @@ class ContainerEntryModule extends Module { - const sources = new Map(); - const runtimeRequirements = new Set([ - RuntimeGlobals.definePropertyGetters, -- RuntimeGlobals.hasOwnProperty, -+ RuntimeGlobals.hasOwnProperty_, - RuntimeGlobals.exports - ]); - const getters = []; -@@ -207,7 +207,7 @@ class ContainerEntryModule extends Module { - // reusing the getScope variable to avoid creating a new var (and module is also used later) - "getScope = (", - Template.indent([ -- `${RuntimeGlobals.hasOwnProperty}(moduleMap, module)`, -+ `${RuntimeGlobals.hasOwnProperty_}(moduleMap, module)`, - Template.indent([ - "? moduleMap[module]()", - `: Promise.resolve().then(${runtimeTemplate.basicFunction( -diff --git a/node_modules/webpack/lib/container/ContainerReferencePlugin.js b/node_modules/webpack/lib/container/ContainerReferencePlugin.js -index f860fba..d0fda61 100644 ---- a/node_modules/webpack/lib/container/ContainerReferencePlugin.js -+++ b/node_modules/webpack/lib/container/ContainerReferencePlugin.js -@@ -129,7 +129,7 @@ class ContainerReferencePlugin { - .tap("ContainerReferencePlugin", (chunk, set) => { - set.add(RuntimeGlobals.module); - set.add(RuntimeGlobals.moduleFactoriesAddOnly); -- set.add(RuntimeGlobals.hasOwnProperty); -+ set.add(RuntimeGlobals.hasOwnProperty_); - set.add(RuntimeGlobals.initializeSharing); - set.add(RuntimeGlobals.shareScopeMap); - compilation.addRuntimeModule(chunk, new RemoteRuntimeModule()); -diff --git a/node_modules/webpack/lib/container/RemoteRuntimeModule.js b/node_modules/webpack/lib/container/RemoteRuntimeModule.js -index 7f4d15b..dfd1189 100644 ---- a/node_modules/webpack/lib/container/RemoteRuntimeModule.js -+++ b/node_modules/webpack/lib/container/RemoteRuntimeModule.js -@@ -58,7 +58,7 @@ class RemoteRuntimeModule extends RuntimeModule { - `${ - RuntimeGlobals.ensureChunkHandlers - }.remotes = ${runtimeTemplate.basicFunction("chunkId, promises", [ -- `if(${RuntimeGlobals.hasOwnProperty}(chunkMapping, chunkId)) {`, -+ `if(${RuntimeGlobals.hasOwnProperty_}(chunkMapping, chunkId)) {`, - Template.indent([ - `chunkMapping[chunkId].forEach(${runtimeTemplate.basicFunction("id", [ - `var getScope = ${RuntimeGlobals.currentRemoteGetScope};`, -diff --git a/node_modules/webpack/lib/css/CssLoadingRuntimeModule.js b/node_modules/webpack/lib/css/CssLoadingRuntimeModule.js -index 15dbef8..ed0ffc9 100644 ---- a/node_modules/webpack/lib/css/CssLoadingRuntimeModule.js -+++ b/node_modules/webpack/lib/css/CssLoadingRuntimeModule.js -@@ -278,7 +278,7 @@ class CssLoadingRuntimeModule extends RuntimeModule { - ? Template.asString([ - `${fn}.css = ${runtimeTemplate.basicFunction("chunkId, promises", [ - "// css chunk loading", -- `var installedChunkData = ${RuntimeGlobals.hasOwnProperty}(installedChunks, chunkId) ? installedChunks[chunkId] : undefined;`, -+ `var installedChunkData = ${RuntimeGlobals.hasOwnProperty_}(installedChunks, chunkId) ? installedChunks[chunkId] : undefined;`, - 'if(installedChunkData !== 0) { // 0 means "already installed".', - Template.indent([ - "", -@@ -305,7 +305,7 @@ class CssLoadingRuntimeModule extends RuntimeModule { - `var loadingEnded = ${runtimeTemplate.basicFunction( - "event", - [ -- `if(${RuntimeGlobals.hasOwnProperty}(installedChunks, chunkId)) {`, -+ `if(${RuntimeGlobals.hasOwnProperty_}(installedChunks, chunkId)) {`, - Template.indent([ - "installedChunkData = installedChunks[chunkId];", - "if(installedChunkData !== 0) installedChunks[chunkId] = undefined;", -diff --git a/node_modules/webpack/lib/css/CssModulesPlugin.js b/node_modules/webpack/lib/css/CssModulesPlugin.js -index 23c3d5d..4d0a46d 100644 ---- a/node_modules/webpack/lib/css/CssModulesPlugin.js -+++ b/node_modules/webpack/lib/css/CssModulesPlugin.js -@@ -246,7 +246,7 @@ class CssModulesPlugin { - - set.add(RuntimeGlobals.publicPath); - set.add(RuntimeGlobals.getChunkCssFilename); -- set.add(RuntimeGlobals.hasOwnProperty); -+ set.add(RuntimeGlobals.hasOwnProperty_); - set.add(RuntimeGlobals.moduleFactoriesAddOnly); - set.add(RuntimeGlobals.makeNamespaceObject); - -diff --git a/node_modules/webpack/lib/dependencies/HarmonyExportImportedSpecifierDependency.js b/node_modules/webpack/lib/dependencies/HarmonyExportImportedSpecifierDependency.js -index 3859254..cae7623 100644 ---- a/node_modules/webpack/lib/dependencies/HarmonyExportImportedSpecifierDependency.js -+++ b/node_modules/webpack/lib/dependencies/HarmonyExportImportedSpecifierDependency.js -@@ -1205,9 +1205,9 @@ HarmonyExportImportedSpecifierDependency.Template = class HarmonyExportImportedS - - runtimeRequirements.add(RuntimeGlobals.exports); - runtimeRequirements.add(RuntimeGlobals.definePropertyGetters); -- runtimeRequirements.add(RuntimeGlobals.hasOwnProperty); -+ runtimeRequirements.add(RuntimeGlobals.hasOwnProperty_); - -- return `if(${RuntimeGlobals.hasOwnProperty}(${name}, ${JSON.stringify( -+ return `if(${RuntimeGlobals.hasOwnProperty_}(${name}, ${JSON.stringify( - valueKey[0] - )})) ${ - RuntimeGlobals.definePropertyGetters -diff --git a/node_modules/webpack/lib/esm/ModuleChunkLoadingPlugin.js b/node_modules/webpack/lib/esm/ModuleChunkLoadingPlugin.js -index 5c984a5..6a91cec 100644 ---- a/node_modules/webpack/lib/esm/ModuleChunkLoadingPlugin.js -+++ b/node_modules/webpack/lib/esm/ModuleChunkLoadingPlugin.js -@@ -36,7 +36,7 @@ class ModuleChunkLoadingPlugin { - onceForChunkSet.add(chunk); - if (!isEnabledForChunk(chunk)) return; - set.add(RuntimeGlobals.moduleFactoriesAddOnly); -- set.add(RuntimeGlobals.hasOwnProperty); -+ set.add(RuntimeGlobals.hasOwnProperty_); - compilation.addRuntimeModule( - chunk, - new ModuleChunkLoadingRuntimeModule(set) -diff --git a/node_modules/webpack/lib/esm/ModuleChunkLoadingRuntimeModule.js b/node_modules/webpack/lib/esm/ModuleChunkLoadingRuntimeModule.js -index 4a846a7..416677a 100644 ---- a/node_modules/webpack/lib/esm/ModuleChunkLoadingRuntimeModule.js -+++ b/node_modules/webpack/lib/esm/ModuleChunkLoadingRuntimeModule.js -@@ -149,7 +149,7 @@ class ModuleChunkLoadingRuntimeModule extends RuntimeModule { - "var moduleId, chunkId, i = 0;", - "for(moduleId in modules) {", - Template.indent([ -- `if(${RuntimeGlobals.hasOwnProperty}(modules, moduleId)) {`, -+ `if(${RuntimeGlobals.hasOwnProperty_}(modules, moduleId)) {`, - Template.indent( - `${RuntimeGlobals.moduleFactories}[moduleId] = modules[moduleId];` - ), -@@ -160,7 +160,7 @@ class ModuleChunkLoadingRuntimeModule extends RuntimeModule { - "for(;i < ids.length; i++) {", - Template.indent([ - "chunkId = ids[i];", -- `if(${RuntimeGlobals.hasOwnProperty}(installedChunks, chunkId) && installedChunks[chunkId]) {`, -+ `if(${RuntimeGlobals.hasOwnProperty_}(installedChunks, chunkId) && installedChunks[chunkId]) {`, - Template.indent("installedChunks[chunkId][0]();"), - "}", - "installedChunks[ids[i]] = 0;" -@@ -177,7 +177,7 @@ class ModuleChunkLoadingRuntimeModule extends RuntimeModule { - hasJsMatcher !== false - ? Template.indent([ - "// import() chunk loading for javascript", -- `var installedChunkData = ${RuntimeGlobals.hasOwnProperty}(installedChunks, chunkId) ? installedChunks[chunkId] : undefined;`, -+ `var installedChunkData = ${RuntimeGlobals.hasOwnProperty_}(installedChunks, chunkId) ? installedChunks[chunkId] : undefined;`, - 'if(installedChunkData !== 0) { // 0 means "already installed".', - Template.indent([ - "", -diff --git a/node_modules/webpack/lib/node/CommonJsChunkLoadingPlugin.js b/node_modules/webpack/lib/node/CommonJsChunkLoadingPlugin.js -index 2653d78..838ab97 100644 ---- a/node_modules/webpack/lib/node/CommonJsChunkLoadingPlugin.js -+++ b/node_modules/webpack/lib/node/CommonJsChunkLoadingPlugin.js -@@ -50,7 +50,7 @@ class CommonJsChunkLoadingPlugin { - onceForChunkSet.add(chunk); - if (!isEnabledForChunk(chunk)) return; - set.add(RuntimeGlobals.moduleFactoriesAddOnly); -- set.add(RuntimeGlobals.hasOwnProperty); -+ set.add(RuntimeGlobals.hasOwnProperty_); - compilation.addRuntimeModule( - chunk, - new ChunkLoadingRuntimeModule(set) -diff --git a/node_modules/webpack/lib/node/ReadFileChunkLoadingRuntimeModule.js b/node_modules/webpack/lib/node/ReadFileChunkLoadingRuntimeModule.js -index 68e292f..944cc6d 100644 ---- a/node_modules/webpack/lib/node/ReadFileChunkLoadingRuntimeModule.js -+++ b/node_modules/webpack/lib/node/ReadFileChunkLoadingRuntimeModule.js -@@ -117,7 +117,7 @@ class ReadFileChunkLoadingRuntimeModule extends RuntimeModule { - "var moreModules = chunk.modules, chunkIds = chunk.ids, runtime = chunk.runtime;", - "for(var moduleId in moreModules) {", - Template.indent([ -- `if(${RuntimeGlobals.hasOwnProperty}(moreModules, moduleId)) {`, -+ `if(${RuntimeGlobals.hasOwnProperty_}(moreModules, moduleId)) {`, - Template.indent([ - `${RuntimeGlobals.moduleFactories}[moduleId] = moreModules[moduleId];` - ]), -@@ -215,7 +215,7 @@ class ReadFileChunkLoadingRuntimeModule extends RuntimeModule { - "var runtime = update.runtime;", - "for(var moduleId in updatedModules) {", - Template.indent([ -- `if(${RuntimeGlobals.hasOwnProperty}(updatedModules, moduleId)) {`, -+ `if(${RuntimeGlobals.hasOwnProperty_}(updatedModules, moduleId)) {`, - Template.indent([ - `currentUpdate[moduleId] = updatedModules[moduleId];`, - "if(updatedModulesList) updatedModulesList.push(moduleId);" -@@ -244,7 +244,7 @@ class ReadFileChunkLoadingRuntimeModule extends RuntimeModule { - /\$ensureChunkHandlers\$/g, - RuntimeGlobals.ensureChunkHandlers - ) -- .replace(/\$hasOwnProperty\$/g, RuntimeGlobals.hasOwnProperty) -+ .replace(/\$hasOwnProperty\$/g, RuntimeGlobals.hasOwnProperty_) - .replace(/\$hmrModuleData\$/g, RuntimeGlobals.hmrModuleData) - .replace( - /\$hmrDownloadUpdateHandlers\$/g, -diff --git a/node_modules/webpack/lib/node/RequireChunkLoadingRuntimeModule.js b/node_modules/webpack/lib/node/RequireChunkLoadingRuntimeModule.js -index 8b46fbc..8024947 100644 ---- a/node_modules/webpack/lib/node/RequireChunkLoadingRuntimeModule.js -+++ b/node_modules/webpack/lib/node/RequireChunkLoadingRuntimeModule.js -@@ -117,7 +117,7 @@ class RequireChunkLoadingRuntimeModule extends RuntimeModule { - "var moreModules = chunk.modules, chunkIds = chunk.ids, runtime = chunk.runtime;", - "for(var moduleId in moreModules) {", - Template.indent([ -- `if(${RuntimeGlobals.hasOwnProperty}(moreModules, moduleId)) {`, -+ `if(${RuntimeGlobals.hasOwnProperty_}(moreModules, moduleId)) {`, - Template.indent([ - `${RuntimeGlobals.moduleFactories}[moduleId] = moreModules[moduleId];` - ]), -@@ -179,7 +179,7 @@ class RequireChunkLoadingRuntimeModule extends RuntimeModule { - "var runtime = update.runtime;", - "for(var moduleId in updatedModules) {", - Template.indent([ -- `if(${RuntimeGlobals.hasOwnProperty}(updatedModules, moduleId)) {`, -+ `if(${RuntimeGlobals.hasOwnProperty_}(updatedModules, moduleId)) {`, - Template.indent([ - `currentUpdate[moduleId] = updatedModules[moduleId];`, - "if(updatedModulesList) updatedModulesList.push(moduleId);" -@@ -203,7 +203,7 @@ class RequireChunkLoadingRuntimeModule extends RuntimeModule { - /\$ensureChunkHandlers\$/g, - RuntimeGlobals.ensureChunkHandlers - ) -- .replace(/\$hasOwnProperty\$/g, RuntimeGlobals.hasOwnProperty) -+ .replace(/\$hasOwnProperty\$/g, RuntimeGlobals.hasOwnProperty_) - .replace(/\$hmrModuleData\$/g, RuntimeGlobals.hmrModuleData) - .replace( - /\$hmrDownloadUpdateHandlers\$/g, -diff --git a/node_modules/webpack/lib/runtime/DefinePropertyGettersRuntimeModule.js b/node_modules/webpack/lib/runtime/DefinePropertyGettersRuntimeModule.js -index 5fce2be..acdb38c 100644 ---- a/node_modules/webpack/lib/runtime/DefinePropertyGettersRuntimeModule.js -+++ b/node_modules/webpack/lib/runtime/DefinePropertyGettersRuntimeModule.js -@@ -24,7 +24,7 @@ class DefinePropertyGettersRuntimeModule extends HelperRuntimeModule { - `${fn} = ${runtimeTemplate.basicFunction("exports, definition", [ - `for(var key in definition) {`, - Template.indent([ -- `if(${RuntimeGlobals.hasOwnProperty}(definition, key) && !${RuntimeGlobals.hasOwnProperty}(exports, key)) {`, -+ `if(${RuntimeGlobals.hasOwnProperty_}(definition, key) && !${RuntimeGlobals.hasOwnProperty_}(exports, key)) {`, - Template.indent([ - "Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });" - ]), -diff --git a/node_modules/webpack/lib/runtime/HasOwnPropertyRuntimeModule.js b/node_modules/webpack/lib/runtime/HasOwnPropertyRuntimeModule.js -index 1971794..6bc4a9c 100644 ---- a/node_modules/webpack/lib/runtime/HasOwnPropertyRuntimeModule.js -+++ b/node_modules/webpack/lib/runtime/HasOwnPropertyRuntimeModule.js -@@ -21,7 +21,7 @@ class HasOwnPropertyRuntimeModule extends RuntimeModule { - const { runtimeTemplate } = this.compilation; - - return Template.asString([ -- `${RuntimeGlobals.hasOwnProperty} = ${runtimeTemplate.returningFunction( -+ `${RuntimeGlobals.hasOwnProperty_} = ${runtimeTemplate.returningFunction( - "Object.prototype.hasOwnProperty.call(obj, prop)", - "obj, prop" - )}` -diff --git a/node_modules/webpack/lib/sharing/ConsumeSharedPlugin.js b/node_modules/webpack/lib/sharing/ConsumeSharedPlugin.js -index a1a3c85..9629bdd 100644 ---- a/node_modules/webpack/lib/sharing/ConsumeSharedPlugin.js -+++ b/node_modules/webpack/lib/sharing/ConsumeSharedPlugin.js -@@ -304,7 +304,7 @@ class ConsumeSharedPlugin { - set.add(RuntimeGlobals.moduleFactoriesAddOnly); - set.add(RuntimeGlobals.shareScopeMap); - set.add(RuntimeGlobals.initializeSharing); -- set.add(RuntimeGlobals.hasOwnProperty); -+ set.add(RuntimeGlobals.hasOwnProperty_); - compilation.addRuntimeModule( - chunk, - new ConsumeSharedRuntimeModule(set) -diff --git a/node_modules/webpack/lib/sharing/ConsumeSharedRuntimeModule.js b/node_modules/webpack/lib/sharing/ConsumeSharedRuntimeModule.js -index 78edabd..18cbec9 100644 ---- a/node_modules/webpack/lib/sharing/ConsumeSharedRuntimeModule.js -+++ b/node_modules/webpack/lib/sharing/ConsumeSharedRuntimeModule.js -@@ -81,7 +81,7 @@ class ConsumeSharedRuntimeModule extends RuntimeModule { - satisfyRuntimeCode(runtimeTemplate), - `var ensureExistence = ${runtimeTemplate.basicFunction("scopeName, key", [ - `var scope = ${RuntimeGlobals.shareScopeMap}[scopeName];`, -- `if(!scope || !${RuntimeGlobals.hasOwnProperty}(scope, key)) throw new Error("Shared module " + key + " doesn't exist in shared scope " + scopeName);`, -+ `if(!scope || !${RuntimeGlobals.hasOwnProperty_}(scope, key)) throw new Error("Shared module " + key + " doesn't exist in shared scope " + scopeName);`, - "return scope;" - ])};`, - `var findVersion = ${runtimeTemplate.basicFunction("scope, key", [ -@@ -199,7 +199,7 @@ class ConsumeSharedRuntimeModule extends RuntimeModule { - `var loadFallback = /*#__PURE__*/ init(${runtimeTemplate.basicFunction( - "scopeName, scope, key, fallback", - [ -- `return scope && ${RuntimeGlobals.hasOwnProperty}(scope, key) ? get(findVersion(scope, key)) : fallback();` -+ `return scope && ${RuntimeGlobals.hasOwnProperty_}(scope, key) ? get(findVersion(scope, key)) : fallback();` - ] - )});`, - `var loadVersionCheck = /*#__PURE__*/ init(${runtimeTemplate.basicFunction( -@@ -240,35 +240,35 @@ class ConsumeSharedRuntimeModule extends RuntimeModule { - `var loadVersionCheckFallback = /*#__PURE__*/ init(${runtimeTemplate.basicFunction( - "scopeName, scope, key, version, fallback", - [ -- `if(!scope || !${RuntimeGlobals.hasOwnProperty}(scope, key)) return fallback();`, -+ `if(!scope || !${RuntimeGlobals.hasOwnProperty_}(scope, key)) return fallback();`, - "return get(findValidVersion(scope, key, version) || warnInvalidVersion(scope, scopeName, key, version) || findVersion(scope, key));" - ] - )});`, - `var loadSingletonFallback = /*#__PURE__*/ init(${runtimeTemplate.basicFunction( - "scopeName, scope, key, fallback", - [ -- `if(!scope || !${RuntimeGlobals.hasOwnProperty}(scope, key)) return fallback();`, -+ `if(!scope || !${RuntimeGlobals.hasOwnProperty_}(scope, key)) return fallback();`, - "return getSingleton(scope, scopeName, key);" - ] - )});`, - `var loadSingletonVersionCheckFallback = /*#__PURE__*/ init(${runtimeTemplate.basicFunction( - "scopeName, scope, key, version, fallback", - [ -- `if(!scope || !${RuntimeGlobals.hasOwnProperty}(scope, key)) return fallback();`, -+ `if(!scope || !${RuntimeGlobals.hasOwnProperty_}(scope, key)) return fallback();`, - "return getSingletonVersion(scope, scopeName, key, version);" - ] - )});`, - `var loadStrictVersionCheckFallback = /*#__PURE__*/ init(${runtimeTemplate.basicFunction( - "scopeName, scope, key, version, fallback", - [ -- `var entry = scope && ${RuntimeGlobals.hasOwnProperty}(scope, key) && findValidVersion(scope, key, version);`, -+ `var entry = scope && ${RuntimeGlobals.hasOwnProperty_}(scope, key) && findValidVersion(scope, key, version);`, - `return entry ? get(entry) : fallback();` - ] - )});`, - `var loadStrictSingletonVersionCheckFallback = /*#__PURE__*/ init(${runtimeTemplate.basicFunction( - "scopeName, scope, key, version, fallback", - [ -- `if(!scope || !${RuntimeGlobals.hasOwnProperty}(scope, key)) return fallback();`, -+ `if(!scope || !${RuntimeGlobals.hasOwnProperty_}(scope, key)) return fallback();`, - "return getStrictSingletonVersion(scope, scopeName, key, version);" - ] - )});`, -@@ -309,12 +309,12 @@ class ConsumeSharedRuntimeModule extends RuntimeModule { - `${ - RuntimeGlobals.ensureChunkHandlers - }.consumes = ${runtimeTemplate.basicFunction("chunkId, promises", [ -- `if(${RuntimeGlobals.hasOwnProperty}(chunkMapping, chunkId)) {`, -+ `if(${RuntimeGlobals.hasOwnProperty_}(chunkMapping, chunkId)) {`, - Template.indent([ - `chunkMapping[chunkId].forEach(${runtimeTemplate.basicFunction( - "id", - [ -- `if(${RuntimeGlobals.hasOwnProperty}(installedModules, id)) return promises.push(installedModules[id]);`, -+ `if(${RuntimeGlobals.hasOwnProperty_}(installedModules, id)) return promises.push(installedModules[id]);`, - `var onFactory = ${runtimeTemplate.basicFunction( - "factory", - [ -diff --git a/node_modules/webpack/lib/sharing/ShareRuntimeModule.js b/node_modules/webpack/lib/sharing/ShareRuntimeModule.js -index eca7252..1a98697 100644 ---- a/node_modules/webpack/lib/sharing/ShareRuntimeModule.js -+++ b/node_modules/webpack/lib/sharing/ShareRuntimeModule.js -@@ -74,7 +74,7 @@ class ShareRuntimeModule extends RuntimeModule { - "// only runs once", - "if(initPromises[name]) return initPromises[name];", - "// creates a new share scope if needed", -- `if(!${RuntimeGlobals.hasOwnProperty}(${RuntimeGlobals.shareScopeMap}, name)) ${RuntimeGlobals.shareScopeMap}[name] = {};`, -+ `if(!${RuntimeGlobals.hasOwnProperty_}(${RuntimeGlobals.shareScopeMap}, name)) ${RuntimeGlobals.shareScopeMap}[name] = {};`, - "// runs all init snippets from all modules reachable", - `var scope = ${RuntimeGlobals.shareScopeMap}[name];`, - `var warn = ${runtimeTemplate.returningFunction( -diff --git a/node_modules/webpack/lib/web/JsonpChunkLoadingPlugin.js b/node_modules/webpack/lib/web/JsonpChunkLoadingPlugin.js -index 34f0cc7..a5368cc 100644 ---- a/node_modules/webpack/lib/web/JsonpChunkLoadingPlugin.js -+++ b/node_modules/webpack/lib/web/JsonpChunkLoadingPlugin.js -@@ -35,7 +35,7 @@ class JsonpChunkLoadingPlugin { - onceForChunkSet.add(chunk); - if (!isEnabledForChunk(chunk)) return; - set.add(RuntimeGlobals.moduleFactoriesAddOnly); -- set.add(RuntimeGlobals.hasOwnProperty); -+ set.add(RuntimeGlobals.hasOwnProperty_); - compilation.addRuntimeModule( - chunk, - new JsonpChunkLoadingRuntimeModule(set) -diff --git a/node_modules/webpack/lib/web/JsonpChunkLoadingRuntimeModule.js b/node_modules/webpack/lib/web/JsonpChunkLoadingRuntimeModule.js -index ea7bfb4..6e268cd 100644 ---- a/node_modules/webpack/lib/web/JsonpChunkLoadingRuntimeModule.js -+++ b/node_modules/webpack/lib/web/JsonpChunkLoadingRuntimeModule.js -@@ -139,7 +139,7 @@ class JsonpChunkLoadingRuntimeModule extends RuntimeModule { - hasJsMatcher !== false - ? Template.indent([ - "// JSONP chunk loading for javascript", -- `var installedChunkData = ${RuntimeGlobals.hasOwnProperty}(installedChunks, chunkId) ? installedChunks[chunkId] : undefined;`, -+ `var installedChunkData = ${RuntimeGlobals.hasOwnProperty_}(installedChunks, chunkId) ? installedChunks[chunkId] : undefined;`, - 'if(installedChunkData !== 0) { // 0 means "already installed".', - Template.indent([ - "", -@@ -168,7 +168,7 @@ class JsonpChunkLoadingRuntimeModule extends RuntimeModule { - `var loadingEnded = ${runtimeTemplate.basicFunction( - "event", - [ -- `if(${RuntimeGlobals.hasOwnProperty}(installedChunks, chunkId)) {`, -+ `if(${RuntimeGlobals.hasOwnProperty_}(installedChunks, chunkId)) {`, - Template.indent([ - "installedChunkData = installedChunks[chunkId];", - "if(installedChunkData !== 0) installedChunks[chunkId] = undefined;", -@@ -205,7 +205,7 @@ class JsonpChunkLoadingRuntimeModule extends RuntimeModule { - RuntimeGlobals.prefetchChunkHandlers - }.j = ${runtimeTemplate.basicFunction("chunkId", [ - `if((!${ -- RuntimeGlobals.hasOwnProperty -+ RuntimeGlobals.hasOwnProperty_ - }(installedChunks, chunkId) || installedChunks[chunkId] === undefined) && ${ - hasJsMatcher === true ? "true" : hasJsMatcher("chunkId") - }) {`, -@@ -241,7 +241,7 @@ class JsonpChunkLoadingRuntimeModule extends RuntimeModule { - RuntimeGlobals.preloadChunkHandlers - }.j = ${runtimeTemplate.basicFunction("chunkId", [ - `if((!${ -- RuntimeGlobals.hasOwnProperty -+ RuntimeGlobals.hasOwnProperty_ - }(installedChunks, chunkId) || installedChunks[chunkId] === undefined) && ${ - hasJsMatcher === true ? "true" : hasJsMatcher("chunkId") - }) {`, -@@ -326,7 +326,7 @@ class JsonpChunkLoadingRuntimeModule extends RuntimeModule { - [ - "for(var moduleId in moreModules) {", - Template.indent([ -- `if(${RuntimeGlobals.hasOwnProperty}(moreModules, moduleId)) {`, -+ `if(${RuntimeGlobals.hasOwnProperty_}(moreModules, moduleId)) {`, - Template.indent([ - "currentUpdate[moduleId] = moreModules[moduleId];", - "if(currentUpdatedModulesList) currentUpdatedModulesList.push(moduleId);" -@@ -356,7 +356,7 @@ class JsonpChunkLoadingRuntimeModule extends RuntimeModule { - /\$ensureChunkHandlers\$/g, - RuntimeGlobals.ensureChunkHandlers - ) -- .replace(/\$hasOwnProperty\$/g, RuntimeGlobals.hasOwnProperty) -+ .replace(/\$hasOwnProperty\$/g, RuntimeGlobals.hasOwnProperty_) - .replace(/\$hmrModuleData\$/g, RuntimeGlobals.hmrModuleData) - .replace( - /\$hmrDownloadUpdateHandlers\$/g, -@@ -415,7 +415,7 @@ class JsonpChunkLoadingRuntimeModule extends RuntimeModule { - Template.indent([ - "for(moduleId in moreModules) {", - Template.indent([ -- `if(${RuntimeGlobals.hasOwnProperty}(moreModules, moduleId)) {`, -+ `if(${RuntimeGlobals.hasOwnProperty_}(moreModules, moduleId)) {`, - Template.indent( - `${RuntimeGlobals.moduleFactories}[moduleId] = moreModules[moduleId];` - ), -@@ -429,7 +429,7 @@ class JsonpChunkLoadingRuntimeModule extends RuntimeModule { - "for(;i < chunkIds.length; i++) {", - Template.indent([ - "chunkId = chunkIds[i];", -- `if(${RuntimeGlobals.hasOwnProperty}(installedChunks, chunkId) && installedChunks[chunkId]) {`, -+ `if(${RuntimeGlobals.hasOwnProperty_}(installedChunks, chunkId) && installedChunks[chunkId]) {`, - Template.indent("installedChunks[chunkId][0]();"), - "}", - "installedChunks[chunkId] = 0;" -diff --git a/node_modules/webpack/lib/webworker/ImportScriptsChunkLoadingPlugin.js b/node_modules/webpack/lib/webworker/ImportScriptsChunkLoadingPlugin.js -index b0dda12..1476bb7 100644 ---- a/node_modules/webpack/lib/webworker/ImportScriptsChunkLoadingPlugin.js -+++ b/node_modules/webpack/lib/webworker/ImportScriptsChunkLoadingPlugin.js -@@ -41,7 +41,7 @@ class ImportScriptsChunkLoadingPlugin { - if (!isEnabledForChunk(chunk)) return; - const withCreateScriptUrl = !!compilation.outputOptions.trustedTypes; - set.add(RuntimeGlobals.moduleFactoriesAddOnly); -- set.add(RuntimeGlobals.hasOwnProperty); -+ set.add(RuntimeGlobals.hasOwnProperty_); - if (withCreateScriptUrl) { - set.add(RuntimeGlobals.createScriptUrl); - } -diff --git a/node_modules/webpack/lib/webworker/ImportScriptsChunkLoadingRuntimeModule.js b/node_modules/webpack/lib/webworker/ImportScriptsChunkLoadingRuntimeModule.js -index b9947d6..2ef98fc 100644 ---- a/node_modules/webpack/lib/webworker/ImportScriptsChunkLoadingRuntimeModule.js -+++ b/node_modules/webpack/lib/webworker/ImportScriptsChunkLoadingRuntimeModule.js -@@ -113,7 +113,7 @@ class ImportScriptsChunkLoadingRuntimeModule extends RuntimeModule { - ), - "for(var moduleId in moreModules) {", - Template.indent([ -- `if(${RuntimeGlobals.hasOwnProperty}(moreModules, moduleId)) {`, -+ `if(${RuntimeGlobals.hasOwnProperty_}(moreModules, moduleId)) {`, - Template.indent( - `${RuntimeGlobals.moduleFactories}[moduleId] = moreModules[moduleId];` - ), -@@ -169,7 +169,7 @@ class ImportScriptsChunkLoadingRuntimeModule extends RuntimeModule { - )}] = ${runtimeTemplate.basicFunction("_, moreModules, runtime", [ - "for(var moduleId in moreModules) {", - Template.indent([ -- `if(${RuntimeGlobals.hasOwnProperty}(moreModules, moduleId)) {`, -+ `if(${RuntimeGlobals.hasOwnProperty_}(moreModules, moduleId)) {`, - Template.indent([ - "currentUpdate[moduleId] = moreModules[moduleId];", - "if(updatedModulesList) updatedModulesList.push(moduleId);" -@@ -202,7 +202,7 @@ class ImportScriptsChunkLoadingRuntimeModule extends RuntimeModule { - /\$ensureChunkHandlers\$/g, - RuntimeGlobals.ensureChunkHandlers - ) -- .replace(/\$hasOwnProperty\$/g, RuntimeGlobals.hasOwnProperty) -+ .replace(/\$hasOwnProperty\$/g, RuntimeGlobals.hasOwnProperty_) - .replace(/\$hmrModuleData\$/g, RuntimeGlobals.hmrModuleData) - .replace( - /\$hmrDownloadUpdateHandlers\$/g, diff --git a/src/core/network/tokenSearch.ts b/src/core/network/tokenSearch.ts index d4a8fd5a4e..fec95b3225 100644 --- a/src/core/network/tokenSearch.ts +++ b/src/core/network/tokenSearch.ts @@ -1,6 +1,6 @@ import { createHttpClient } from './internal/createHttpClient'; export const tokenSearchHttp = createHttpClient({ - baseUrl: 'https://token-search.rainbow.me/v2', + baseUrl: 'https://token-search.rainbow.me/v3/tokens', params: {}, }); diff --git a/src/core/references/assets.ts b/src/core/references/assets.ts index 0099d05bec..5e4a30d7e5 100644 --- a/src/core/references/assets.ts +++ b/src/core/references/assets.ts @@ -6,11 +6,13 @@ import { blast, blastSepolia, bob, + bobSepolia, boba, canto, celo, celoAlfajores, classic, + coreDao, cronos, cronosTestnet, degen, @@ -54,6 +56,7 @@ import { polygonZkEvmCardona, polygonZkEvmTestnet, pulsechain, + pulsechainV4, redstone, ronin, rootstock, @@ -61,8 +64,13 @@ import { saigon, scroll, scrollSepolia, - zkSync, - zkSyncSepoliaTestnet, + shapeSepolia, + xai, + xaiTestnet, + zkLinkNova, + zkLinkNovaSepoliaTestnet, + zksync, + zksyncSepoliaTestnet, } from 'viem/chains'; import { ChainId } from '../types/chains'; @@ -76,18 +84,18 @@ export const customChainIdsToAssetNames: Record = { [blastSepolia.id]: 'blastsepolia', [bob.id]: 'bob', [boba.id]: 'boba', - 28882: 'bobasepolia', + [bobSepolia.id]: 'bobasepolia', 223: 'bsquared', 1123: 'bsquaredtestnet', [celo.id]: 'celo', [celoAlfajores.id]: 'celoalfajores', - [classic.id]: 'classic', 63: 'classicmordor', - 1116: 'core', + [classic.id]: 'classic', + [coreDao.id]: 'core', 1115: 'coretestnet', [cronos.id]: 'cronos', - [cronosTestnet.id]: 'cronostestnet', 282: 'cronoszkevmtestnet', + [cronosTestnet.id]: 'cronostestnet', [degen.id]: 'degen', [dogechain.id]: 'dogechain', 568: 'dogechaintestnet', @@ -98,6 +106,7 @@ export const customChainIdsToAssetNames: Record = { [filecoinCalibration.id]: 'filecoincalibration', 32659: 'fusion', 46688: 'fusiontestnet', + [ChainId.godwoken]: 'godwoken', [ham.id]: 'ham', [harmonyOne.id]: 'harmony', [hedera.id]: 'hedera', @@ -113,6 +122,7 @@ export const customChainIdsToAssetNames: Record = { [lightlinkPegasus.id]: 'lightlinkpegasus', [linea.id]: 'linea', [lineaSepolia.id]: 'lineasepolia', + [ChainId.loot]: 'loot', [lyra.id]: 'lyra', [manta.id]: 'manta', [mantaSepoliaTestnet.id]: 'mantasepolia', @@ -136,8 +146,11 @@ export const customChainIdsToAssetNames: Record = { [polygonZkEvm.id]: 'polygonzkevm', [polygonZkEvmCardona.id]: 'polygonzkevmcardona', [polygonZkEvmTestnet.id]: 'polygonzkevmtestnet', + [ChainId.proofOfPlayApex]: 'proofofplayapex', + 70800: 'proofofplaybarret', + [ChainId.proofOfPlayBoss]: 'proofofplayboss', [pulsechain.id]: 'pulsechain', - 943: 'pulsechaintestnet', + [pulsechainV4.id]: 'pulsechaintestnet', 1380012617: 'rari', 1918988905: 'raritestnet', [redstone.id]: 'redstone', @@ -149,10 +162,13 @@ export const customChainIdsToAssetNames: Record = { [rootstockTestnet.id]: 'rootstocktestnet', [scroll.id]: 'scroll', [scrollSepolia.id]: 'scrollsepolia', + [shapeSepolia.id]: 'shapesepolia', + [xai.id]: 'xai', + [xaiTestnet.id]: 'xaisepolia', [gnosis.id]: 'xdai', [gnosisChiado.id]: 'xdaichiado', - 810180: 'zklink', - 810181: 'zklinktestnet', - [zkSync.id]: 'zksync', - [zkSyncSepoliaTestnet.id]: 'zksyncsepolia', + [zkLinkNova.id]: 'zklink', + [zkLinkNovaSepoliaTestnet.id]: 'zklinktestnet', + [zksync.id]: 'zksync', + [zksyncSepoliaTestnet.id]: 'zksyncsepolia', }; diff --git a/src/core/state/quickPromo/index.ts b/src/core/state/quickPromo/index.ts index ab35c8d169..bd1990c927 100644 --- a/src/core/state/quickPromo/index.ts +++ b/src/core/state/quickPromo/index.ts @@ -6,6 +6,7 @@ export enum promoTypes { command_k = 'command_k', wallet_switcher = 'wallet_switcher', network_settings = 'network_settings', + degen_mode = 'degen_mode', } export type PromoTypes = keyof typeof promoTypes; @@ -20,6 +21,7 @@ export const quickPromoStore = createStore( command_k: false, wallet_switcher: false, network_settings: false, + degen_mode: false, }, setSeenPromo: (key: PromoTypes) => { const seenPromos = get().seenPromos; diff --git a/src/core/types/assets.ts b/src/core/types/assets.ts index f52ec5e786..1d3e231e1d 100644 --- a/src/core/types/assets.ts +++ b/src/core/types/assets.ts @@ -159,7 +159,8 @@ export type ProtocolType = | 'yearn-v3' | 'venus' | 'sushiswap' - | 'native'; + | 'native' + | 'wrapped-native'; export type AssetMetadata = { circulatingSupply: number; diff --git a/src/core/types/chains.ts b/src/core/types/chains.ts index 1e96061929..9b7dcd8f6d 100644 --- a/src/core/types/chains.ts +++ b/src/core/types/chains.ts @@ -40,101 +40,149 @@ export enum ChainName { arbitrumSepolia = 'arbitrum-sepolia', avalanche = 'avalanche', avalancheFuji = 'avalanche-fuji', + b3 = 'b3', base = 'base', + baseSepolia = 'base-sepolia', blast = 'blast', blastSepolia = 'blast-sepolia', bsc = 'bsc', + bscTestnet = 'bsc-testnet', + canto = 'canto', celo = 'celo', degen = 'degen', + fantom = 'fantom', + forma = 'forma', + godwoken = 'godwoken', gnosis = 'gnosis', + hardhat = 'hardhat', + hardhatOptimism = 'hardhat-optimism', + holesky = 'holesky', + immutableZkEvm = 'immutable-zkevm', linea = 'linea', + loot = 'loot', + mainnet = 'mainnet', manta = 'manta', + mode = 'mode', + moonbeam = 'moonbeam', + opbnb = 'opbnb', optimism = 'optimism', + optimismSepolia = 'optimism-sepolia', + palm = 'palm', polygon = 'polygon', + polygonAmoy = 'polygon-amoy', polygonZkEvm = 'polygon-zkevm', + proofOfPlayApex = 'proof-of-play', + proofOfPlayBoss = 'proof-of-play-boss', rari = 'rari', scroll = 'scroll', - zora = 'zora', - mainnet = 'mainnet', - holesky = 'holesky', - hardhat = 'hardhat', - hardhatOptimism = 'hardhat-optimism', + sei = 'sei', sepolia = 'sepolia', - optimismSepolia = 'optimism-sepolia', - bscTestnet = 'bsc-testnet', - baseSepolia = 'base-sepolia', + xai = 'xai', + zksync = 'zksync-era', + zora = 'zora', zoraSepolia = 'zora-sepolia', - polygonAmoy = 'polygon-amoy', } export enum ChainId { arbitrum = chains.arbitrum.id, arbitrumNova = chains.arbitrumNova.id, + arbitrumSepolia = chains.arbitrumSepolia.id, avalanche = chains.avalanche.id, avalancheFuji = chains.avalancheFuji.id, + b3 = chains.b3.id, base = chains.base.id, + baseSepolia = chains.baseSepolia.id, blast = chains.blast.id, blastSepolia = chains.blastSepolia.id, bsc = chains.bsc.id, + bscTestnet = chains.bscTestnet.id, + canto = chains.canto.id, celo = chains.celo.id, + degen = chains.degen.id, + fantom = chains.fantom.id, + forma = chains.forma.id, gnosis = chains.gnosis.id, + godwoken = 71402, + hardhat = chainHardhat.id, + hardhatOptimism = chainHardhatOptimism.id, + holesky = chains.holesky.id, + immutableZkEvm = chains.immutableZkEvm.id, linea = chains.linea.id, + loot = 5151706, + mainnet = chains.mainnet.id, manta = chains.manta.id, + mode = chains.mode.id, + moonbeam = chains.moonbeam.id, + opbnb = 204, optimism = chains.optimism.id, - mainnet = chains.mainnet.id, + optimismSepolia = chains.optimismSepolia.id, + palm = chains.palm.id, polygon = chains.polygon.id, + polygonAmoy = chains.polygonAmoy.id, polygonZkEvm = chains.polygonZkEvm.id, + proofOfPlayApex = 70700, + proofOfPlayBoss = 70701, rari = 1380012617, - zora = chains.zora.id, - hardhat = chainHardhat.id, - hardhatOptimism = chainHardhatOptimism.id, - sepolia = chains.sepolia.id, scroll = chains.scroll.id, - holesky = chains.holesky.id, - optimismSepolia = chains.optimismSepolia.id, - bscTestnet = chains.bscTestnet.id, - arbitrumSepolia = chains.arbitrumSepolia.id, - baseSepolia = chains.baseSepolia.id, + sei = chains.sei.id, + sepolia = chains.sepolia.id, + xai = chains.xai.id, + zksync = chains.zksync.id, + zora = chains.zora.id, zoraSepolia = chains.zoraSepolia.id, - polygonAmoy = chains.polygonAmoy.id, - degen = chains.degen.id, } export const chainNameToIdMapping: { [key in ChainName | 'ethereum' | 'ethereum-sepolia']: ChainId; } = { ['ethereum']: ChainId.mainnet, + ['ethereum-sepolia']: ChainId.sepolia, [ChainName.arbitrum]: ChainId.arbitrum, [ChainName.arbitrumNova]: ChainId.arbitrumNova, [ChainName.arbitrumSepolia]: ChainId.arbitrumSepolia, [ChainName.avalanche]: ChainId.avalanche, [ChainName.avalancheFuji]: ChainId.avalancheFuji, + [ChainName.b3]: ChainId.b3, [ChainName.base]: ChainId.base, + [ChainName.baseSepolia]: ChainId.baseSepolia, + [ChainName.blast]: ChainId.blast, + [ChainName.blastSepolia]: ChainId.blastSepolia, [ChainName.bsc]: ChainId.bsc, + [ChainName.bscTestnet]: ChainId.bscTestnet, + [ChainName.canto]: ChainId.canto, [ChainName.celo]: ChainId.celo, + [ChainName.degen]: ChainId.degen, + [ChainName.fantom]: ChainId.fantom, + [ChainName.forma]: ChainId.forma, [ChainName.gnosis]: ChainId.gnosis, + [ChainName.godwoken]: ChainId.godwoken, + [ChainName.hardhat]: ChainId.hardhat, + [ChainName.hardhatOptimism]: ChainId.hardhatOptimism, + [ChainName.holesky]: ChainId.holesky, + [ChainName.immutableZkEvm]: ChainId.immutableZkEvm, [ChainName.linea]: ChainId.linea, + [ChainName.loot]: ChainId.loot, + [ChainName.mainnet]: ChainId.mainnet, [ChainName.manta]: ChainId.manta, + [ChainName.mode]: ChainId.mode, + [ChainName.moonbeam]: ChainId.moonbeam, + [ChainName.opbnb]: ChainId.opbnb, [ChainName.optimism]: ChainId.optimism, + [ChainName.optimismSepolia]: ChainId.optimismSepolia, + [ChainName.palm]: ChainId.palm, [ChainName.polygon]: ChainId.polygon, + [ChainName.polygonAmoy]: ChainId.polygonAmoy, [ChainName.polygonZkEvm]: ChainId.polygonZkEvm, + [ChainName.proofOfPlayApex]: ChainId.proofOfPlayApex, + [ChainName.proofOfPlayBoss]: ChainId.proofOfPlayBoss, [ChainName.rari]: ChainId.rari, [ChainName.scroll]: ChainId.scroll, - [ChainName.zora]: ChainId.zora, - [ChainName.mainnet]: ChainId.mainnet, - [ChainName.holesky]: ChainId.holesky, - [ChainName.hardhat]: ChainId.hardhat, - [ChainName.hardhatOptimism]: ChainId.hardhatOptimism, - ['ethereum-sepolia']: ChainId.sepolia, + [ChainName.sei]: ChainId.sei, [ChainName.sepolia]: ChainId.sepolia, - [ChainName.optimismSepolia]: ChainId.optimismSepolia, - [ChainName.bscTestnet]: ChainId.bscTestnet, - [ChainName.baseSepolia]: ChainId.baseSepolia, + [ChainName.xai]: ChainId.xai, + [ChainName.zksync]: ChainId.zksync, + [ChainName.zora]: ChainId.zora, [ChainName.zoraSepolia]: ChainId.zoraSepolia, - [ChainName.blast]: ChainId.blast, - [ChainName.blastSepolia]: ChainId.blastSepolia, - [ChainName.polygonAmoy]: ChainId.polygonAmoy, - [ChainName.degen]: ChainId.degen, }; export const chainIdToNameMapping: { @@ -146,30 +194,44 @@ export const chainIdToNameMapping: { [ChainId.avalanche]: ChainName.avalanche, [ChainId.avalancheFuji]: ChainName.avalancheFuji, [ChainId.base]: ChainName.base, + [ChainId.baseSepolia]: ChainName.baseSepolia, [ChainId.blast]: ChainName.blast, [ChainId.blastSepolia]: ChainName.blastSepolia, [ChainId.bsc]: ChainName.bsc, + [ChainId.bscTestnet]: ChainName.bscTestnet, [ChainId.celo]: ChainName.celo, + [ChainId.degen]: ChainName.degen, + [ChainId.fantom]: ChainName.fantom, + [ChainId.forma]: ChainName.forma, [ChainId.gnosis]: ChainName.gnosis, + [ChainId.godwoken]: ChainName.godwoken, + [ChainId.hardhat]: ChainName.hardhat, + [ChainId.hardhatOptimism]: ChainName.hardhatOptimism, + [ChainId.holesky]: ChainName.holesky, + [ChainId.immutableZkEvm]: ChainName.immutableZkEvm, [ChainId.linea]: ChainName.linea, + [ChainId.loot]: ChainName.loot, + [ChainId.mainnet]: ChainName.mainnet, [ChainId.manta]: ChainName.manta, + [ChainId.mode]: ChainName.mode, + [ChainId.moonbeam]: ChainName.moonbeam, + [ChainId.opbnb]: ChainName.opbnb, [ChainId.optimism]: ChainName.optimism, + [ChainId.optimismSepolia]: ChainName.optimismSepolia, + [ChainId.palm]: ChainName.palm, [ChainId.polygon]: ChainName.polygon, + [ChainId.polygonAmoy]: ChainName.polygonAmoy, [ChainId.polygonZkEvm]: ChainName.polygonZkEvm, + [ChainId.proofOfPlayApex]: ChainName.proofOfPlayApex, + [ChainId.proofOfPlayBoss]: ChainName.proofOfPlayBoss, [ChainId.rari]: ChainName.rari, [ChainId.scroll]: ChainName.scroll, - [ChainId.zora]: ChainName.zora, - [ChainId.mainnet]: ChainName.mainnet, - [ChainId.holesky]: ChainName.holesky, - [ChainId.hardhat]: ChainName.hardhat, - [ChainId.hardhatOptimism]: ChainName.hardhatOptimism, + [ChainId.sei]: ChainName.sei, [ChainId.sepolia]: ChainName.sepolia, - [ChainId.optimismSepolia]: ChainName.optimismSepolia, - [ChainId.bscTestnet]: ChainName.bscTestnet, - [ChainId.baseSepolia]: ChainName.baseSepolia, + [ChainId.xai]: ChainName.xai, + [ChainId.zksync]: ChainName.zksync, + [ChainId.zora]: ChainName.zora, [ChainId.zoraSepolia]: ChainName.zoraSepolia, - [ChainId.polygonAmoy]: ChainName.polygonAmoy, - [ChainId.degen]: ChainName.degen, }; export interface BackendNetworkServices { diff --git a/src/core/types/nfts.ts b/src/core/types/nfts.ts index a2d63abc0a..839d36dbc4 100644 --- a/src/core/types/nfts.ts +++ b/src/core/types/nfts.ts @@ -7,29 +7,66 @@ export interface PolygonAllowListDictionary { } export enum SimpleHashChain { + AlignTestnet = 'align-testnet', + AnomalyAndromedaTestnet = 'anomaly-andromeda-testnet', Arbitrum = 'arbitrum', - Bsc = 'bsc', - Ethereum = 'ethereum', - Gnosis = 'gnosis', - Optimism = 'optimism', - Polygon = 'polygon', - Zora = 'zora', - Base = 'base', ArbitrumNova = 'arbitrum-nova', + ArbitrumSepolia = 'arbitrum-sepolia', Avalanche = 'avalanche', + AvalancheFuji = 'avalanche-fuji', + B3 = 'b3', + B3Sepolia = 'b3-sepolia', + Base = 'base', + BaseSepolia = 'base-sepolia', + Blast = 'blast', + BlastSepolia = 'blast-sepolia', + Bsc = 'bsc', + BscTestnet = 'bsc-testnet', + CampTestnet = 'camp-testnet', + Canto = 'canto', Celo = 'celo', + Degen = 'degen', + Ethereum = 'ethereum', + EthereumSepolia = 'ethereum-sepolia', + Fantom = 'fantom', + FlowEvmPreviewnet = 'flow-evm-previewnet', + FlowEvmTestnet = 'flow-evm-testnet', + Forma = 'forma', + Godwoken = 'godwoken', + GodwokenTestnet = 'godwoken-testnet', + Gnosis = 'gnosis', + ImmutableZkEvm = 'immutable-zkevm', + ImmutableZkEvmTestnet = 'immutable-zkevm-testnet', + LensSepolia = 'lens-sepolia', Linea = 'linea', + Loot = 'loot', Manta = 'manta', - PolygonZkEVM = 'polygon-zkevm', + Mode = 'mode', + Moonbeam = 'moonbeam', + OpBnb = 'opbnb', + Optimism = 'optimism', + OptimismSepolia = 'optimism-sepolia', + Palm = 'palm', + PalmTestnet = 'palm-testnet', + Polygon = 'polygon', + PolygonAmoy = 'polygon-amoy', + PolygonZkEvm = 'polygon-zkevm', + ProofOfPlayApex = 'proof-of-play', + ProofOfPlayBarretTestnet = 'proof-of-play-barret', + ProofOfPlayBoss = 'proof-of-play-boss', Rari = 'rari', + RariTestnet = 'rari-testnet', Scroll = 'scroll', - ArbitrumSepolia = 'arbitrum-sepolia', - BaseSepolia = 'base-sepolia', - OptimismSepolia = 'optimism-sepolia', + ScrollSepolia = 'scroll-sepolia', + Sei = 'sei', + SeiAtlantic = 'sei-atlantic-2', + ShapeSepolia = 'shape-sepolia', + Xai = 'xai', + XaiSepolia = 'xai-sepolia', + ZeroSepolia = 'zero-sepolia', + ZkSync = 'zksync-era', + Zora = 'zora', ZoraSepolia = 'zora-sepolia', - Blast = 'blast', - BlastSepolia = 'blast-sepolia', - PolygonAmoy = 'polygon-amoy', } /** diff --git a/src/core/utils/__test__/numbers.test.ts b/src/core/utils/__test__/numbers.test.ts new file mode 100644 index 0000000000..1505472349 --- /dev/null +++ b/src/core/utils/__test__/numbers.test.ts @@ -0,0 +1,105 @@ +import { describe, expect, test } from 'vitest'; + +import { isExceedingMaxCharacters, truncateNumber } from '../numbers'; + +describe('numbers', () => { + describe('truncateNumber', () => { + test('should return maximum 10 characters from amount', () => { + const numbers = [ + { + input: 123456789.1234567, + output: '123456789.1', + }, + { + input: 123456.123456789, + output: '123456.1234', + }, + { + input: 1.111111111111111, + output: '1.111111111', + }, + { + input: 33.33333333333333, + output: '33.33333333', + }, + { + input: 10000000000000000, + output: '1000000000', + }, + { + input: 9000000000000000000, + output: '9000000000', + }, + ]; + + for (const { input, output } of numbers) { + // Check both number and string number + expect(truncateNumber(input)).toBe(output); + expect(truncateNumber(input.toString())).toBe(output); + } + }); + + test('should return existing number if not exceeding 10 character limit', () => { + const numbers = [ + { + input: 33.33, + output: '33.33', + }, + { + input: 20.22, + output: '20.22', + }, + { + input: 45555.9999, + output: '45555.9999', + }, + { + input: 2000.0, + output: '2000', + }, + { + input: 3999.999, + output: '3999.999', + }, + { + input: 123456789.123, + output: '123456789.1', + }, + ]; + + for (const { input, output } of numbers) { + // Check both number and string number + expect(truncateNumber(input)).toBe(output); + expect(truncateNumber(input.toString())).toBe(output); + } + }); + + test('should handle decimal points', () => { + expect(truncateNumber('33.')).toBe('33.'); + expect(truncateNumber('333.333')).toBe('333.333'); + expect(truncateNumber('.')).toBe('0.'); + }); + + test('should handle empty string', () => { + expect(truncateNumber('')).toBe(''); + }); + }); + + describe('isExceedingMaxCharacters', () => { + test('should return false if max characters exceeded', () => { + const MAX_CHARS = 5; + + expect(isExceedingMaxCharacters('1.123', MAX_CHARS)).toBe(false); + expect(isExceedingMaxCharacters('12.12', MAX_CHARS)).toBe(false); + expect(isExceedingMaxCharacters('123.1', MAX_CHARS)).toBe(false); + }); + + test('should return true if max characters exceeded', () => { + const MAX_CHARS = 6; + + expect(isExceedingMaxCharacters('123.4567', MAX_CHARS)).toBe(true); + expect(isExceedingMaxCharacters('1234567', MAX_CHARS)).toBe(true); + expect(isExceedingMaxCharacters('12345.67', MAX_CHARS)).toBe(true); + }); + }); +}); diff --git a/src/core/utils/nfts.ts b/src/core/utils/nfts.ts index 1602d050f2..b0647e79ca 100644 --- a/src/core/utils/nfts.ts +++ b/src/core/utils/nfts.ts @@ -19,21 +19,38 @@ export const ENS_NFT_CONTRACT_ADDRESS = export const simpleHashSupportedChainNames = [ 'ethereum', - ChainName.polygon, ChainName.arbitrum, ChainName.arbitrumNova, ChainName.avalanche, + ChainName.b3, ChainName.base, ChainName.blast, ChainName.bsc, + ChainName.canto, ChainName.celo, + ChainName.degen, + ChainName.fantom, + ChainName.forma, ChainName.gnosis, + ChainName.godwoken, + ChainName.immutableZkEvm, ChainName.linea, + ChainName.loot, ChainName.manta, + ChainName.mode, + ChainName.moonbeam, ChainName.optimism, + ChainName.opbnb, + ChainName.palm, + ChainName.polygon, ChainName.polygonZkEvm, + ChainName.proofOfPlayApex, + ChainName.proofOfPlayBoss, ChainName.rari, ChainName.scroll, + ChainName.sei, + ChainName.xai, + ChainName.zksync, ChainName.zora, ] as (ChainName | 'ethereum' | 'ethereum-sepolia')[]; @@ -41,10 +58,11 @@ export const simpleHashSupportedTestnetChainNames = [ 'ethereum-sepolia', ChainName.arbitrumSepolia, ChainName.baseSepolia, + ChainName.bscTestnet, ChainName.blastSepolia, ChainName.optimismSepolia, - ChainName.zoraSepolia, ChainName.polygonAmoy, + ChainName.zoraSepolia, ] as (ChainName | 'ethereum-sepolia' | 'ethereum')[]; /** @@ -73,51 +91,91 @@ export function getNetworkFromSimpleHashChain( chain: SimpleHashChain, ): ChainName { switch (chain) { - case SimpleHashChain.Ethereum: - case SimpleHashChain.Gnosis: - return ChainName.mainnet; - case SimpleHashChain.Polygon: - return ChainName.polygon; - case SimpleHashChain.Arbitrum: - return ChainName.arbitrum; - case SimpleHashChain.Optimism: - return ChainName.optimism; - case SimpleHashChain.Bsc: - return ChainName.bsc; - case SimpleHashChain.Zora: - return ChainName.zora; - case SimpleHashChain.Base: - return ChainName.base; case SimpleHashChain.Avalanche: return ChainName.avalanche; + case SimpleHashChain.AvalancheFuji: + return ChainName.avalancheFuji; + case SimpleHashChain.Arbitrum: + return ChainName.arbitrum; case SimpleHashChain.ArbitrumNova: return ChainName.arbitrumNova; + case SimpleHashChain.ArbitrumSepolia: + return ChainName.arbitrumSepolia; + case SimpleHashChain.Base: + return ChainName.base; + case SimpleHashChain.BaseSepolia: + return ChainName.baseSepolia; + case SimpleHashChain.B3: + return ChainName.b3; + case SimpleHashChain.Blast: + return ChainName.blast; + case SimpleHashChain.BlastSepolia: + return ChainName.blastSepolia; + case SimpleHashChain.Bsc: + return ChainName.bsc; + case SimpleHashChain.BscTestnet: + return ChainName.bscTestnet; + case SimpleHashChain.Canto: + return ChainName.canto; case SimpleHashChain.Celo: return ChainName.celo; + case SimpleHashChain.Degen: + return ChainName.degen; + case SimpleHashChain.Ethereum: + case SimpleHashChain.Gnosis: + return ChainName.mainnet; + case SimpleHashChain.EthereumSepolia: + return ChainName.sepolia; + case SimpleHashChain.Fantom: + return ChainName.fantom; + case SimpleHashChain.Forma: + return ChainName.forma; + case SimpleHashChain.Godwoken: + return ChainName.godwoken; + case SimpleHashChain.ImmutableZkEvm: + return ChainName.immutableZkEvm; case SimpleHashChain.Linea: return ChainName.linea; + case SimpleHashChain.Loot: + return ChainName.loot; case SimpleHashChain.Manta: return ChainName.manta; - case SimpleHashChain.PolygonZkEVM: + case SimpleHashChain.Mode: + return ChainName.mode; + case SimpleHashChain.Moonbeam: + return ChainName.moonbeam; + case SimpleHashChain.OpBnb: + return ChainName.opbnb; + case SimpleHashChain.Optimism: + return ChainName.optimism; + case SimpleHashChain.OptimismSepolia: + return ChainName.optimismSepolia; + case SimpleHashChain.Palm: + return ChainName.palm; + case SimpleHashChain.Polygon: + return ChainName.polygon; + case SimpleHashChain.PolygonAmoy: + return ChainName.polygonAmoy; + case SimpleHashChain.PolygonZkEvm: return ChainName.polygonZkEvm; + case SimpleHashChain.ProofOfPlayApex: + return ChainName.proofOfPlayApex; + case SimpleHashChain.ProofOfPlayBoss: + return ChainName.proofOfPlayBoss; case SimpleHashChain.Rari: return ChainName.rari; case SimpleHashChain.Scroll: return ChainName.scroll; - case SimpleHashChain.ArbitrumSepolia: - return ChainName.arbitrumSepolia; - case SimpleHashChain.BaseSepolia: - return ChainName.baseSepolia; - case SimpleHashChain.OptimismSepolia: - return ChainName.optimismSepolia; + case SimpleHashChain.Sei: + return ChainName.sei; + case SimpleHashChain.Xai: + return ChainName.xai; + case SimpleHashChain.ZkSync: + return ChainName.zksync; + case SimpleHashChain.Zora: + return ChainName.zora; case SimpleHashChain.ZoraSepolia: return ChainName.zoraSepolia; - case SimpleHashChain.Blast: - return ChainName.blast; - case SimpleHashChain.BlastSepolia: - return ChainName.blastSepolia; - case SimpleHashChain.PolygonAmoy: - return ChainName.polygonAmoy; default: /* * Throws here because according to TS types, we should NEVER hit this diff --git a/src/core/utils/numbers.ts b/src/core/utils/numbers.ts index 282a470d84..8d4a91671b 100644 --- a/src/core/utils/numbers.ts +++ b/src/core/utils/numbers.ts @@ -4,6 +4,7 @@ import currency from 'currency.js'; import { isNil } from 'lodash'; import { supportedCurrencies } from '~/core/references'; +import { maskInput } from '~/entries/popup/components/InputMask/utils'; import { formatCurrency } from './formatNumber'; import { BigNumberish } from './hex'; @@ -503,3 +504,30 @@ export const processExchangeRateArray = (arr: string[]): string[] => { return item; }); }; + +export const truncateNumber = (n: string | number, maxChars = 10): string => { + const value = typeof n === 'number' ? n.toString() : n; + + if (!value) return ''; + + const parts = value.replace(/,/g, '').split('.'); + const integers = parts[0] || ''; + + if (integers.length > maxChars) { + return maskInput({ + inputValue: value, + decimals: 0, + integers: maxChars, + }); + } + + return maskInput({ + inputValue: value, + decimals: maxChars - integers.length, + integers: maxChars, + }); +}; + +export const isExceedingMaxCharacters = (value: string, maxChars: number) => { + return value.replace('.', '').length > maxChars; +}; diff --git a/src/core/utils/swaps.ts b/src/core/utils/swaps.ts index 7f4fd24a24..ee3a209826 100644 --- a/src/core/utils/swaps.ts +++ b/src/core/utils/swaps.ts @@ -7,6 +7,7 @@ import { import { i18n } from '../languages'; import { useConnectedToHardhatStore } from '../state/currentSettings/connectedToHardhat'; +import { ParsedSearchAsset } from '../types/assets'; import { ChainId } from '../types/chains'; import { isLowerCaseMatch } from './strings'; @@ -90,3 +91,18 @@ export const isWrapEth = ({ ) ); }; + +export const isWrapOrUnwrapEth = ({ + assetToBuy, + assetToSell, +}: { + assetToBuy: ParsedSearchAsset | null; + assetToSell: ParsedSearchAsset | null; +}) => { + return ( + assetToBuy?.chainId === assetToSell?.chainId && + ((assetToBuy?.type === 'native' && + assetToSell?.type === 'wrapped-native') || + (assetToSell?.type === 'native' && assetToBuy?.type === 'wrapped-native')) + ); +}; diff --git a/src/entries/popup/components/ImportWallet/ImportWalletViaSeed.tsx b/src/entries/popup/components/ImportWallet/ImportWalletViaSeed.tsx index 09c09c68f0..7f20807127 100644 --- a/src/entries/popup/components/ImportWallet/ImportWalletViaSeed.tsx +++ b/src/entries/popup/components/ImportWallet/ImportWalletViaSeed.tsx @@ -183,9 +183,9 @@ const ImportWalletViaSeed = () => { const toggleWordLength = useCallback(() => { if (secrets.length === 12) { - setSecrets(emptySecrets12); - } else { setSecrets(emptySecrets24); + } else { + setSecrets(emptySecrets12); } setInvalidWords([]); setGlobalError(false); @@ -274,7 +274,7 @@ const ImportWalletViaSeed = () => { setSecrets(words); } else { setGlobalError(true); - setSecrets(Array.from({ length: 12 }).map(() => '')); + setSecrets(emptySecrets12); } }, []); diff --git a/src/entries/popup/components/Tooltip/CursorTooltip.tsx b/src/entries/popup/components/Tooltip/CursorTooltip.tsx index 6c62f07210..6b212b35dd 100644 --- a/src/entries/popup/components/Tooltip/CursorTooltip.tsx +++ b/src/entries/popup/components/Tooltip/CursorTooltip.tsx @@ -30,6 +30,7 @@ export const CursorTooltip = ({ textWeight, textSize, textColor, + hideTooltipOnMouseDown, children, hint, }: { @@ -42,6 +43,7 @@ export const CursorTooltip = ({ textSize?: TextStyles['fontSize']; textWeight?: TextStyles['fontWeight']; textColor?: TextStyles['color']; + hideTooltipOnMouseDown?: boolean; hint?: string; }) => { const [open, setOpen] = useState(false); @@ -117,6 +119,13 @@ export const CursorTooltip = ({ setOpen(false); showTimer.current && clearTimeout(showTimer.current); }} + onMouseDown={() => { + if (hideTooltipOnMouseDown) { + setIsHovering(false); + setOpen(false); + showTimer.current && clearTimeout(showTimer.current); + } + }} > {children} diff --git a/src/entries/popup/hooks/swap/useSwapInputs.ts b/src/entries/popup/hooks/swap/useSwapInputs.ts index 6ff60b7123..d1adf10aa7 100644 --- a/src/entries/popup/hooks/swap/useSwapInputs.ts +++ b/src/entries/popup/hooks/swap/useSwapInputs.ts @@ -12,13 +12,19 @@ import { convertAmountToRawAmount, convertRawAmountToBalance, handleSignificantDecimals, + isExceedingMaxCharacters, lessThan, minus, + truncateNumber, } from '~/core/utils/numbers'; import { isLowerCaseMatch } from '~/core/utils/strings'; import { TokenInputRef } from '../../pages/swap/SwapTokenInput/TokenInput'; +// The maximum number of characters for the input field. +// This does not include the decimal point. +const MAX_INPUT_CHARACTERS = 11; + const focusOnInput = (inputRef: React.RefObject) => { setTimeout(() => { inputRef?.current?.focus(); @@ -55,9 +61,22 @@ export const useSwapInputs = ({ const [assetToBuyDropdownClosed, setAssetToBuyDropdownClosed] = useState( inputToOpenOnMount !== 'buy', ); - const [assetToSellValue, setAssetToSellValue] = useState(''); + const [assetToSellValue, setAssetToSellValueState] = useState(''); + const [assetToBuyValue, setAssetToBuyValueState] = useState(''); const [assetToSellNativeValue, setAssetToSellNativeValue] = useState(''); - const [assetToBuyValue, setAssetToBuyValue] = useState(''); + + // Rounded input values (maximum 12 characters including decimal point) + const [assetToSellValueRounded, setAssetToSellValueRounded] = useState(''); + const [assetToBuyValueRounded, setAssetToBuyValueRounded] = useState(''); + + const maxCharacters = useMemo( + () => + (assetToSell?.symbol?.length || 0) > 3 + ? // In case an asset symbol is 4 characters or more (e.g WETH) + MAX_INPUT_CHARACTERS - 1 + : MAX_INPUT_CHARACTERS, + [assetToSell], + ); const { saveSwapAmount, @@ -85,6 +104,22 @@ export const useSwapInputs = ({ [assetToBuy, assetToSell, saveSwapField], ); + const setAssetToSellValue = useCallback( + (value: string) => { + setAssetToSellValueRounded(truncateNumber(value, maxCharacters)); + setAssetToSellValueState(value); + }, + [maxCharacters], + ); + + const setAssetToBuyValue = useCallback( + (value: string) => { + setAssetToBuyValueRounded(truncateNumber(value, maxCharacters)); + setAssetToBuyValueState(value); + }, + [maxCharacters], + ); + useEffect(() => { if (savedSwapField) { setIndependentField(savedSwapField); @@ -93,21 +128,30 @@ export const useSwapInputs = ({ }, []); const setAssetToSellInputValue = useCallback( - (value: string) => { + (value: string, isInput = true) => { setAssetToSellDropdownClosed(true); - saveSwapAmount({ amount: value }); - setAssetToSellValue(value); setIndependentFieldIfOccupied('sellField'); - setIndependentValue(value); + let inputValue = value; + if (isInput && isExceedingMaxCharacters(value, maxCharacters)) { + inputValue = truncateNumber(value, maxCharacters); + } + saveSwapAmount({ amount: inputValue }); + setAssetToSellValue(inputValue); + setIndependentValue(inputValue); }, - [saveSwapAmount, setIndependentFieldIfOccupied], + [ + maxCharacters, + saveSwapAmount, + setAssetToSellValue, + setIndependentFieldIfOccupied, + ], ); const setAssetToSellInputNativeValue = useCallback( (value: string) => { setAssetToSellDropdownClosed(true); - setAssetToSellNativeValue(value); setIndependentFieldIfOccupied('sellNativeField'); + setAssetToSellNativeValue(value); setIndependentValue(value); setAssetToSellValue( value @@ -124,19 +168,29 @@ export const useSwapInputs = ({ assetToSell?.decimals, assetToSell?.price?.value, saveSwapAmount, + setAssetToSellValue, setIndependentFieldIfOccupied, ], ); const setAssetToBuyInputValue = useCallback( - (value: string) => { + (value: string, isInput = true) => { setAssetToBuyDropdownClosed(true); - setAssetToBuyValue(value); setIndependentFieldIfOccupied('buyField'); - setIndependentValue(value); - saveSwapAmount({ amount: value }); + let inputValue = value; + if (isInput && isExceedingMaxCharacters(value, maxCharacters)) { + inputValue = truncateNumber(value, maxCharacters); + } + setAssetToBuyValue(inputValue); + setIndependentValue(inputValue); + saveSwapAmount({ amount: inputValue }); }, - [saveSwapAmount, setIndependentFieldIfOccupied], + [ + maxCharacters, + saveSwapAmount, + setAssetToBuyValue, + setIndependentFieldIfOccupied, + ], ); const onAssetToSellInputOpen = useCallback( @@ -164,7 +218,7 @@ export const useSwapInputs = ({ const rawAssetBalanceAmount = assetToSell?.isNativeAsset && lessThan(selectedGas?.gasFee?.amount, assetBalanceAmount) - ? minus(assetBalanceAmount, addBuffer(selectedGas?.gasFee?.amount, 1.1)) + ? minus(assetBalanceAmount, addBuffer(selectedGas?.gasFee?.amount, 1.3)) : assetBalanceAmount; const assetBalance = convertRawAmountToBalance(rawAssetBalanceAmount, { @@ -185,6 +239,7 @@ export const useSwapInputs = ({ setIndependentFieldIfOccupied('sellField'); }, [ assetToSellMaxValue.amount, + setAssetToSellValue, saveSwapAmount, setIndependentFieldIfOccupied, ]); @@ -226,26 +281,28 @@ export const useSwapInputs = ({ setAssetToSellDropdownClosed(true); setAssetToBuyDropdownClosed(true); }, [ - assetToBuy, - assetToBuyValue, + bridge, assetToSell, - assetToSellValue, + assetToBuy, independentField, - independentValue, - saveSwapField, setAssetToBuy, setAssetToSell, - setIndependentField, - bridge, + setAssetToBuyValue, + setAssetToSellValue, + assetToBuyValue, + saveSwapField, + independentValue, + assetToSellValue, ]); - const assetToSellDisplay = useMemo( - () => + const assetToSellDisplay = useMemo(() => { + const amount = independentField === 'buyField' ? assetToSellValue && handleSignificantDecimals(assetToSellValue, 5) - : assetToSellValue, - [assetToSellValue, independentField], - ); + : assetToSellValue; + + return { amount, display: truncateNumber(amount, maxCharacters) }; + }, [maxCharacters, assetToSellValue, independentField]); const assetToBuyDisplay = useMemo( () => @@ -333,6 +390,8 @@ export const useSwapInputs = ({ assetToSellDisplay, assetToBuyDisplay, assetToSellDropdownClosed, + assetToSellValueRounded, + assetToBuyValueRounded, assetToBuyDropdownClosed, independentField, flipAssets, diff --git a/src/entries/popup/hooks/swap/useSwapNativeAmounts.tsx b/src/entries/popup/hooks/swap/useSwapNativeAmounts.tsx index f8a920f657..6eb34d07ac 100644 --- a/src/entries/popup/hooks/swap/useSwapNativeAmounts.tsx +++ b/src/entries/popup/hooks/swap/useSwapNativeAmounts.tsx @@ -31,12 +31,12 @@ export const useSwapNativeAmounts = ({ let nativeDisplay = null; if (isWrapOrUnwrapEth) { nativeDisplay = - !quote?.sellAmount || !quote.sellTokenAsset.price.value + !quote?.sellAmount || !assetToSell?.price?.value ? null : convertRawAmountToNativeDisplay( quote?.sellAmount?.toString(), - quote.sellTokenAsset.decimals || 18, - quote.sellTokenAsset.price.value, + quote?.sellTokenAsset?.decimals || 18, + assetToSell?.price?.value, currentCurrency, ); } else if (assetToSell?.native?.price?.amount && assetToSellValue) { @@ -47,12 +47,12 @@ export const useSwapNativeAmounts = ({ ); } else { nativeDisplay = - !quote?.sellAmountInEth || !quote.sellTokenAsset.price.value + !quote?.sellAmountInEth || !quote?.sellTokenAsset?.price?.value ? null : convertRawAmountToNativeDisplay( - quote?.sellAmountInEth.toString(), - quote.sellTokenAsset.decimals || 18, - quote.sellTokenAsset.price?.value, + quote?.sellAmountInEth?.toString(), + quote?.sellTokenAsset?.decimals || 18, + quote?.sellTokenAsset?.price?.value, currentCurrency, ); } @@ -69,11 +69,12 @@ export const useSwapNativeAmounts = ({ }, [ isWrapOrUnwrapEth, assetToSell?.native?.price?.amount, + assetToSell?.price?.value, assetToSellValue, currentCurrency, quote?.sellAmount, - quote?.sellTokenAsset.price.value, - quote?.sellTokenAsset.decimals, + quote?.sellTokenAsset?.decimals, + quote?.sellTokenAsset?.price?.value, quote?.sellAmountInEth, ]); @@ -97,12 +98,12 @@ export const useSwapNativeAmounts = ({ ); } else { nativeDisplay = - !quote?.buyAmountInEth || !quote.buyTokenAsset.price?.value + !quote?.buyAmountInEth || !quote?.buyTokenAsset?.price?.value ? null : convertRawAmountToNativeDisplay( - quote?.buyAmountInEth.toString(), - quote.buyTokenAsset.decimals || 18, - quote.buyTokenAsset.price?.value, + quote?.buyAmountInEth?.toString(), + quote?.buyTokenAsset?.decimals || 18, + quote?.buyTokenAsset?.price?.value, currentCurrency, ); } @@ -124,8 +125,8 @@ export const useSwapNativeAmounts = ({ quote?.buyAmount, quote?.buyAmountInEth, currentCurrency, - quote?.buyTokenAsset.price?.value, - quote?.buyTokenAsset.decimals, + quote?.buyTokenAsset?.price?.value, + quote?.buyTokenAsset?.decimals, ]); return { diff --git a/src/entries/popup/pages/home/Points/PointsDashboard.tsx b/src/entries/popup/pages/home/Points/PointsDashboard.tsx index 5bb86cd1c9..ba9553c540 100644 --- a/src/entries/popup/pages/home/Points/PointsDashboard.tsx +++ b/src/entries/popup/pages/home/Points/PointsDashboard.tsx @@ -74,11 +74,20 @@ function Card({ }: PropsWithChildren & { onClick?: () => void; }) { + const getTabIndex = () => { + if (typeof props.tabIndex === 'number') { + return props.tabIndex; + } else if (props.onClick) { + return 0; + } + return -1; + }; return ( {formatReferralCode(data.user.referralCode)} @@ -334,6 +344,7 @@ function ReferralCode() { onTap={() => copyReferralLink(data.user.referralCode)} onClick={() => copyReferralLink(data.user.referralCode)} style={{ height: 40, willChange: 'transform' }} + tabIndex={-1} > { - if (value < 0) return { color: 'red', symbol: 'arrow.down' }; - if (value > 0) return { color: 'green', symbol: 'arrow.up' }; - return { color: 'labelSecondary', symbol: '' }; + changePercentage: number, +): { label: string; color: TextProps['color']; symbol: SymbolName | '' } => { + const label = Math.abs(changePercentage).toFixed(2) + ' %'; + + if (changePercentage === Infinity) + return { label: '∞ %', color: 'green', symbol: '' }; + + if (changePercentage < 0) + return { label, color: 'red', symbol: 'arrow.down' }; + + if (changePercentage > 0) + return { label, color: 'green', symbol: 'arrow.up' }; + + return { label, color: 'labelSecondary', symbol: '' }; }; type PriceChange = { @@ -44,7 +53,7 @@ const PriceChange = memo(function PriceChange({ changePercentage = 0, date, }: PriceChange) { - const { color, symbol } = parsePriceChange(+changePercentage.toFixed(2)); + const { color, symbol, label } = parsePriceChange(changePercentage); return ( @@ -58,7 +67,7 @@ const PriceChange = memo(function PriceChange({ cursor="text" userSelect="text" > - {Math.abs(changePercentage).toFixed(2)} % + {label} @@ -165,7 +174,7 @@ const usePriceChart = ({ }; const percentDiff = (current = 1, last = 0) => - ((current - last) / current) * 100; + ((current - last) / last) * 100 || 0; const now = new Date(); const chartTimeToTimestamp = { diff --git a/src/entries/popup/pages/messages/DappScanStatus.tsx b/src/entries/popup/pages/messages/DappScanStatus.tsx index fa7b887d05..1addb3cf2b 100644 --- a/src/entries/popup/pages/messages/DappScanStatus.tsx +++ b/src/entries/popup/pages/messages/DappScanStatus.tsx @@ -17,6 +17,7 @@ export function MaliciousRequestWarning({ }) { return ( { + const isWrapOrUnwrap = isWrapOrUnwrapEth({ assetToBuy, assetToSell }); + if ( !assetToSellNativeDisplay?.amount || assetToSellNativeDisplay?.amount === '0' || !assetToBuyNativeDisplay?.amount || - assetToBuyNativeDisplay?.amount === '0' - ) + assetToBuyNativeDisplay?.amount === '0' || + isWrapOrUnwrap + ) { return null; + } const division = divide( subtract(assetToBuyNativeDisplay.amount, assetToSellNativeDisplay.amount), assetToBuyNativeDisplay.amount, @@ -62,7 +68,12 @@ export const TokenToBuyInfo = ({ lessThan(abs(division), 0.01) ? '-0.01' : division, ); return nativeDifference; - }, [assetToBuyNativeDisplay, assetToSellNativeDisplay]); + }, [ + assetToBuy, + assetToSell, + assetToBuyNativeDisplay, + assetToSellNativeDisplay, + ]); if (!assetToBuy) return null; return ( diff --git a/src/entries/popup/pages/swap/SwapTokenInput/TokenInput.tsx b/src/entries/popup/pages/swap/SwapTokenInput/TokenInput.tsx index d5f6c23eaa..ed44f975c9 100644 --- a/src/entries/popup/pages/swap/SwapTokenInput/TokenInput.tsx +++ b/src/entries/popup/pages/swap/SwapTokenInput/TokenInput.tsx @@ -22,28 +22,47 @@ import { SwapInputActionButton } from '../SwapInputActionButton'; const SwapInputMaskWrapper = ({ inputDisabled, + value, + symbol, children, }: { inputDisabled?: boolean; + value?: string; + symbol?: string; children: ReactElement; }) => { - return inputDisabled ? ( + if (inputDisabled) { + return ( + + {children} + + ); + } + + return ( {children} - ) : ( - children ); }; interface TokenInputProps { accentCaretColor?: boolean; asset: ParsedSearchAsset | null; + assetTooltipValue?: string; assetFilter: string; dropdownHeight?: number; dropdownComponent: ReactElement; @@ -74,6 +93,7 @@ export const TokenInput = React.forwardRef< { accentCaretColor, asset, + assetTooltipValue, assetFilter, dropdownHeight, dropdownComponent, @@ -97,6 +117,7 @@ export const TokenInput = React.forwardRef< forwardedRef, ) { const [dropdownVisible, setDropdownVisible] = useState(false); + const prevDropdownVisible = usePrevious(dropdownVisible); useImperativeHandle(forwardedRef, () => ({ @@ -191,7 +212,11 @@ export const TokenInput = React.forwardRef< ) : ( - + void }) => { + const { featureFlags } = useFeatureFlagsStore(); + const { seenPromos, setSeenPromo } = useQuickPromoStore(); + const isDegenModeEnabled = useDegenMode((s) => s.isDegenModeEnabled); + + if (!featureFlags.degen_mode && !config.degen_mode) return null; + if (seenPromos.degen_mode || isDegenModeEnabled) return null; + + return ( + + { + setSeenPromo(promoTypes.degen_mode); + onClick(); + }} + > + + + + + + {i18n.t('swap.promo.degen_mode.title')} + + + + + + + ); +}; + +const SwapAlerts = ({ + timeEstimate, + priceImpact, + quote, + onClick, +}: { + timeEstimate?: SwapTimeEstimate | null; + priceImpact?: SwapPriceImpact; + quote: Quote | CrosschainQuote | QuoteError | undefined; + onClick: () => void; +}) => { + const showWarning = useMemo(() => { + return ( + priceImpact?.type !== SwapPriceImpactType.none || timeEstimate?.isLongWait + ); + }, [priceImpact?.type, timeEstimate?.isLongWait]); + + const quoteError = (quote as QuoteError)?.error; + + if (showWarning) { + return ( + + ); + } else if (quote && !quoteError) { + return ; + } + return null; +}; + function SwapButton({ quote, assetToSell, @@ -411,6 +487,8 @@ export function Swap({ bridge = false }: { bridge?: boolean }) { assetToBuyInputRef, assetToSellMaxValue, assetToBuyValue, + assetToSellValueRounded, + assetToBuyValueRounded, assetToSellValue, selectAssetToSell, assetToSellNativeValue, @@ -549,9 +627,9 @@ export function Swap({ bridge = false }: { bridge?: boolean }) { const field = savedField || 'sellField'; if (savedAmount) { if (field === 'buyField') { - setAssetToBuyInputValue(savedAmount); + setAssetToBuyInputValue(savedAmount, false); } else if (field === 'sellField') { - setAssetToSellInputValue(savedAmount); + setAssetToSellInputValue(savedAmount, false); } else { setAssetToSellInputNativeValue(savedAmount); } @@ -711,7 +789,12 @@ export function Swap({ bridge = false }: { bridge?: boolean }) { setAssetToSellMaxValue={setAssetToSellMaxValue} assetToSellValue={ independentField === 'sellNativeField' - ? assetToSellDisplay + ? assetToSellDisplay.display + : assetToSellValueRounded + } + assetToSellFullValue={ + independentField === 'sellNativeField' + ? assetToSellDisplay.amount : assetToSellValue } setAssetToSellInputValue={setAssetToSellInputValue} @@ -794,6 +877,7 @@ export function Swap({ bridge = false }: { bridge?: boolean }) { assetFilter={assetToBuyFilter} setAssetFilter={setAssetToBuyFilter} assetToBuyValue={assetToBuyValue} + assetToBuyInputValue={assetToBuyValueRounded} assetToSellValue={assetToSellValue} setAssetToBuyInputValue={setAssetToBuyInputValue} inputRef={assetToBuyInputRef} @@ -805,14 +889,12 @@ export function Swap({ bridge = false }: { bridge?: boolean }) { /> - - {/* */} diff --git a/src/test/setup.ts b/src/test/setup.ts index 4b96a93985..4c8cff7434 100644 --- a/src/test/setup.ts +++ b/src/test/setup.ts @@ -1,4 +1,3 @@ -import { Crypto } from '@peculiar/webcrypto'; import { rest } from 'msw'; import { setupServer } from 'msw/node'; import { afterAll, afterEach, beforeAll, vi } from 'vitest'; @@ -25,9 +24,6 @@ vi.stubGlobal('window.location', { pathname: 'popup.html', }); -// @ts-ignore -global.crypto = new Crypto(); - const abortFn = vi.fn(); // @ts-ignore diff --git a/static/json/languages/ar_AR.json b/static/json/languages/ar_AR.json index 290ca2f038..d0701fa9b2 100644 --- a/static/json/languages/ar_AR.json +++ b/static/json/languages/ar_AR.json @@ -294,7 +294,8 @@ "full_watching_wallets": "الوصول الكامل إلى المحافظ المراقبة", "hw_wallets_enabled": "تفعيل دعم المحفظة الأجهزة", "command_k_internal_shortcuts_enabled": "تفعيل الاختصارات الداخلية ⌘K", - "custom_rpc": "Custom RPC" + "custom_rpc": "Custom RPC", + "degen_mode": "وضع Degen" } }, "transactions": { @@ -776,6 +777,10 @@ } }, "got_it": "فهمت" + }, + "degen_mode": { + "title": "وضع Degen", + "description": "تخطي خطوة المراجعة لتبديل أسرع" } }, "actions": { @@ -785,7 +790,10 @@ "fee_on_transfer_token": "الرسوم على نقل العملة", "no_route": "لم يتم العثور على مسار", "no_quote": "لا يوجد عرض متاح", - "enter_an_amount": "أدخل كمية" + "enter_an_amount": "أدخل كمية", + "swap": "%{Action}", + "swapping": "%{Actioning} عبر", + "waiting_signature": "تأكيد على جهازك" }, "review": { "title": "مراجعة و %{Action}", @@ -942,7 +950,8 @@ "import_wallet_group": "استيراد مجموعة محفظة", "n_words_might_be_wrong": "%{n} الكلمات قد تكون مخطئة أو غير صحيحة.", "1_word_might_be_wrong": "1 كلمة قد تكون مخطئة أو غير صحيحة.", - "couldnt_paste": "لم نتمكن من لصق عبارة الاسترداد السرية" + "couldnt_paste": "لم نتمكن من لصق عبارة الاسترداد السرية", + "duplicate_seed": "هذه البذرة مستوردة بالفعل" }, "import_wallet_via_private_key": { "title": "استورد محفظتك", diff --git a/static/json/languages/en_US.json b/static/json/languages/en_US.json index 8d0ab58003..8bf73db4f2 100644 --- a/static/json/languages/en_US.json +++ b/static/json/languages/en_US.json @@ -740,6 +740,11 @@ "description": "If you decide to continue, be sure that you are satisfied receiving the quoted amount." } }, + "promo": { + "degen_mode": { + "title": "Try Degen Mode to skip the review" + } + }, "aggregators": { "rainbow": "Auto" }, diff --git a/static/json/languages/es_419.json b/static/json/languages/es_419.json index 67c8465062..9d5d480fcd 100644 --- a/static/json/languages/es_419.json +++ b/static/json/languages/es_419.json @@ -294,7 +294,8 @@ "full_watching_wallets": "Acceso completo a billeteras vigiladas", "hw_wallets_enabled": "Habilitar soporte para billeteras de hardware", "command_k_internal_shortcuts_enabled": "Habilitar accesos directos internos ⌘K", - "custom_rpc": "RPC Personalizado" + "custom_rpc": "RPC Personalizado", + "degen_mode": "Modo Degen" } }, "transactions": { @@ -776,6 +777,10 @@ } }, "got_it": "Entendido" + }, + "degen_mode": { + "title": "Modo Degen", + "description": "Omite el paso de revisión para intercambiar más rápido" } }, "actions": { @@ -785,7 +790,10 @@ "fee_on_transfer_token": "Comisión en el Token de Transferencia", "no_route": "No se encontró ruta", "no_quote": "No hay cotización disponible", - "enter_an_amount": "Ingresa una cantidad" + "enter_an_amount": "Ingresa una cantidad", + "swap": "%{Action}", + "swapping": "%{Actioning}", + "waiting_signature": "Confirmar en tu dispositivo" }, "review": { "title": "Revisar y %{Action}", @@ -942,7 +950,8 @@ "import_wallet_group": "Importar grupo de billetera", "n_words_might_be_wrong": "%{n} palabras podrían estar mal escritas o incorrectas.", "1_word_might_be_wrong": "1 palabra podría estar mal escrita o incorrecta.", - "couldnt_paste": "No pudimos pegar tu Frase de Recuperación Secreta" + "couldnt_paste": "No pudimos pegar tu Frase de Recuperación Secreta", + "duplicate_seed": "Esta seed ya está importada" }, "import_wallet_via_private_key": { "title": "Importar tu billetera", diff --git a/static/json/languages/fr_FR.json b/static/json/languages/fr_FR.json index 6d68a31f89..d335d7b2b6 100644 --- a/static/json/languages/fr_FR.json +++ b/static/json/languages/fr_FR.json @@ -294,7 +294,8 @@ "full_watching_wallets": "Accès complet aux portefeuilles surveillés", "hw_wallets_enabled": "Activer la prise en charge des portefeuilles matériels", "command_k_internal_shortcuts_enabled": "Activer les raccourcis internes ⌘K", - "custom_rpc": "RPC personnalisé" + "custom_rpc": "RPC personnalisé", + "degen_mode": "Mode Degen" } }, "transactions": { @@ -776,6 +777,10 @@ } }, "got_it": "Compris" + }, + "degen_mode": { + "title": "Mode Degen", + "description": "Sautez l'étape de révision pour échanger plus rapidement" } }, "actions": { @@ -785,7 +790,10 @@ "fee_on_transfer_token": "Frais sur Transfert de Jeton", "no_route": "Aucun itinéraire trouvé", "no_quote": "Aucune citation disponible", - "enter_an_amount": "Entrez un montant" + "enter_an_amount": "Entrez un montant", + "swap": "%{Action}", + "swapping": "%{Actioning}", + "waiting_signature": "Confirmer sur votre appareil" }, "review": { "title": "Réviser & %{Action}", @@ -942,7 +950,8 @@ "import_wallet_group": "Importer un groupe de portefeuilles", "n_words_might_be_wrong": "%{n} mots peuvent être mal orthographiés ou incorrects.", "1_word_might_be_wrong": "1 mot peut être mal orthographié ou incorrect.", - "couldnt_paste": "Nous n'avons pas pu coller votre Phrase de récupération secrète" + "couldnt_paste": "Nous n'avons pas pu coller votre Phrase de récupération secrète", + "duplicate_seed": "Cette graine est déjà importée" }, "import_wallet_via_private_key": { "title": "Importer votre portefeuille", diff --git a/static/json/languages/hi_IN.json b/static/json/languages/hi_IN.json index d93fb8b153..7dd2d546a3 100644 --- a/static/json/languages/hi_IN.json +++ b/static/json/languages/hi_IN.json @@ -294,7 +294,8 @@ "full_watching_wallets": "Watched वॉलेट्स का पूरा उपयोग", "hw_wallets_enabled": "हार्डवेयर वॉलेट समर्थन सक्षम करें", "command_k_internal_shortcuts_enabled": "⌘K आंतरिक शॉर्टकट्स सक्षम करें", - "custom_rpc": "कस्टम RPC" + "custom_rpc": "कस्टम RPC", + "degen_mode": "Degen मोड" } }, "transactions": { @@ -776,6 +777,10 @@ } }, "got_it": "समझ गया" + }, + "degen_mode": { + "title": "Degen मोड", + "description": "तेज स्वैप के लिए समीक्षा चरण छोड़ें" } }, "actions": { @@ -785,7 +790,10 @@ "fee_on_transfer_token": "स्थानांतरण पर शुल्क टोकन", "no_route": "कोई मार्ग नहीं मिला", "no_quote": "कोई कोट उपलब्ध नहीं", - "enter_an_amount": "राशि दर्ज करें" + "enter_an_amount": "राशि दर्ज करें", + "swap": "%{Action}", + "swapping": "%{Actioning} के माध्यम से", + "waiting_signature": "अपनी डिवाइस पर पुष्टि करें" }, "review": { "title": "समीक्षा और %{Action}", @@ -942,7 +950,8 @@ "import_wallet_group": "वॉलेट समूह आयात करें", "n_words_might_be_wrong": "%{n} शब्द गलत या गलत हो सकते हैं।", "1_word_might_be_wrong": "1 शब्द गलत या गलत हो सकता है।", - "couldnt_paste": "हम आपके सीक्रेट रिकवरी फ्रेज़ को पेस्ट नहीं कर सके" + "couldnt_paste": "हम आपके सीक्रेट रिकवरी फ्रेज़ को पेस्ट नहीं कर सके", + "duplicate_seed": "यह बीज पहले ही आयात हो चुका है" }, "import_wallet_via_private_key": { "title": "अपना वॉलेट इम्पोर्ट करें", diff --git a/static/json/languages/id_ID.json b/static/json/languages/id_ID.json index 99b5736194..30ceaaf8b0 100644 --- a/static/json/languages/id_ID.json +++ b/static/json/languages/id_ID.json @@ -294,7 +294,8 @@ "full_watching_wallets": "Akses Penuh ke Dompet Tertonton", "hw_wallets_enabled": "Aktifkan Dukungan Dompet Perangkat Keras", "command_k_internal_shortcuts_enabled": "Aktifkan Pintasan Internal ⌘K", - "custom_rpc": "RPC Kustom" + "custom_rpc": "RPC Kustom", + "degen_mode": "Degen Mode" } }, "transactions": { @@ -776,6 +777,10 @@ } }, "got_it": "Mengerti" + }, + "degen_mode": { + "title": "Degen Mode", + "description": "Lewati langkah ulasan untuk bertukar lebih cepat" } }, "actions": { @@ -785,7 +790,10 @@ "fee_on_transfer_token": "Biaya Pada Transfer Token", "no_route": "Tidak ada rute yang ditemukan", "no_quote": "Tidak ada kutipan yang tersedia", - "enter_an_amount": "Masukkan jumlah" + "enter_an_amount": "Masukkan jumlah", + "swap": "%{Action}", + "swapping": "%{Actioning} melalui", + "waiting_signature": "Konfirmasi di perangkat Anda" }, "review": { "title": "Ulas & %{Action}", @@ -942,7 +950,8 @@ "import_wallet_group": "Impor grup dompet", "n_words_might_be_wrong": "%{n} kata mungkin salah penulisan atau tidak benar.", "1_word_might_be_wrong": "1 kata mungkin salah penulisan atau tidak benar.", - "couldnt_paste": "Kami tidak dapat menempelkan Frasa Pemulihan Rahasia Anda" + "couldnt_paste": "Kami tidak dapat menempelkan Frasa Pemulihan Rahasia Anda", + "duplicate_seed": "Seed ini sudah diimpor" }, "import_wallet_via_private_key": { "title": "Impor Dompet Anda", diff --git a/static/json/languages/ja_JP.json b/static/json/languages/ja_JP.json index 4cc0022786..9d13387e76 100644 --- a/static/json/languages/ja_JP.json +++ b/static/json/languages/ja_JP.json @@ -294,7 +294,8 @@ "full_watching_wallets": "ウォレットの監視機能を完全に有効にする", "hw_wallets_enabled": "ハードウェアウォレットサポートを有効にする", "command_k_internal_shortcuts_enabled": "⌘K の内部ショートカットを有効にする", - "custom_rpc": "カスタムRPC" + "custom_rpc": "カスタムRPC", + "degen_mode": "Degenモード" } }, "transactions": { @@ -776,6 +777,10 @@ } }, "got_it": "了解" + }, + "degen_mode": { + "title": "Degenモード", + "description": "検討ステップをスキップして、より迅速に交換" } }, "actions": { @@ -785,7 +790,10 @@ "fee_on_transfer_token": "転送トークンの手数料", "no_route": "ルートが見つかりません", "no_quote": "利用可能な見積もりなし", - "enter_an_amount": "金額を入力してください" + "enter_an_amount": "金額を入力してください", + "swap": "%{Action}", + "swapping": "%{Actioning}", + "waiting_signature": "デバイスで確認してください" }, "review": { "title": "レビュー & %{Action}", @@ -942,7 +950,8 @@ "import_wallet_group": "ウォレットグループをインポートする", "n_words_might_be_wrong": "%{n} 単語がスペルミスや誤りがある可能性があります。", "1_word_might_be_wrong": "1 単語がスペルミスや誤りがある可能性があります。", - "couldnt_paste": "シークレットリカバリーフレーズを貼り付けることができませんでした。" + "couldnt_paste": "シークレットリカバリーフレーズを貼り付けることができませんでした。", + "duplicate_seed": "このシードはすでにインポートされています" }, "import_wallet_via_private_key": { "title": "ウォレットのインポート", diff --git a/static/json/languages/ko_KR.json b/static/json/languages/ko_KR.json index 9a73d48aa6..b40d03025c 100644 --- a/static/json/languages/ko_KR.json +++ b/static/json/languages/ko_KR.json @@ -294,7 +294,8 @@ "full_watching_wallets": "감시 중인 지갑에 대한 완전한 접근", "hw_wallets_enabled": "하드웨어 지갑 지원 활성화", "command_k_internal_shortcuts_enabled": "⌘K 내부 단축키 활성화", - "custom_rpc": "사용자 정의 RPC" + "custom_rpc": "사용자 정의 RPC", + "degen_mode": "Degen모드" } }, "transactions": { @@ -776,6 +777,10 @@ } }, "got_it": "확인" + }, + "degen_mode": { + "title": "Degen모드", + "description": "더 빠르게 교환하기 위해 검토 단계를 건너뜁니다" } }, "actions": { @@ -785,7 +790,10 @@ "fee_on_transfer_token": "전송 토큰에 대한 수수료", "no_route": "경로를 찾을 수 없음", "no_quote": "견적을 받을 수 없음", - "enter_an_amount": "금액 입력" + "enter_an_amount": "금액 입력", + "swap": "%{Action}", + "swapping": "%{Actioning}", + "waiting_signature": "장치에서 확인" }, "review": { "title": "검토 및 %{Action}", @@ -942,7 +950,8 @@ "import_wallet_group": "지갑 그룹 가져오기", "n_words_might_be_wrong": "%{n} 단어가 잘못 입력되었거나 올바르지 않을 수 있습니다", "1_word_might_be_wrong": "1개의 단어가 잘못 입력되었거나 올바르지 않을 수 있습니다", - "couldnt_paste": "비밀 복구 구문을 붙여넣을 수 없습니다" + "couldnt_paste": "비밀 복구 구문을 붙여넣을 수 없습니다", + "duplicate_seed": "이 시드는 이미 가져왔습니다" }, "import_wallet_via_private_key": { "title": "지갑 가져오기", diff --git a/static/json/languages/pt_BR.json b/static/json/languages/pt_BR.json index 553a99cfd8..0ef414fedf 100644 --- a/static/json/languages/pt_BR.json +++ b/static/json/languages/pt_BR.json @@ -294,7 +294,8 @@ "full_watching_wallets": "Acesso completo às Carteiras Observadas", "hw_wallets_enabled": "Habilitar Suporte para Carteiras de Hardware", "command_k_internal_shortcuts_enabled": "Habilitar Atalhos Internos ⌘K", - "custom_rpc": "RPC personalizado" + "custom_rpc": "RPC personalizado", + "degen_mode": "Modo Degen" } }, "transactions": { @@ -776,6 +777,10 @@ } }, "got_it": "Entendi" + }, + "degen_mode": { + "title": "Modo Degen", + "description": "Pule a etapa de revisão para trocar mais rápido" } }, "actions": { @@ -785,7 +790,10 @@ "fee_on_transfer_token": "Taxa em Token de Transferência", "no_route": "Nenhuma rota encontrada", "no_quote": "Nenhuma cotação disponível", - "enter_an_amount": "Insira um valor" + "enter_an_amount": "Insira um valor", + "swap": "%{Action}", + "swapping": "%{Actioning}", + "waiting_signature": "Confirmar no seu dispositivo" }, "review": { "title": "Revisar & %{Action}", @@ -942,7 +950,8 @@ "import_wallet_group": "Importar grupo de carteira", "n_words_might_be_wrong": "%{n} palavras podem estar escritas erradas ou incorretas.", "1_word_might_be_wrong": "1 palavra pode estar escrita errada ou incorreta.", - "couldnt_paste": "Não foi possível colar sua Frase de Recuperação Secreta" + "couldnt_paste": "Não foi possível colar sua Frase de Recuperação Secreta", + "duplicate_seed": "Esta semente já foi importada" }, "import_wallet_via_private_key": { "title": "Importar sua Carteira", diff --git a/static/json/languages/ru_RU.json b/static/json/languages/ru_RU.json index 50999900c4..25301a4b4f 100644 --- a/static/json/languages/ru_RU.json +++ b/static/json/languages/ru_RU.json @@ -294,7 +294,8 @@ "full_watching_wallets": "Полный доступ к отслеживаемым кошелькам", "hw_wallets_enabled": "Включить поддержку аппаратных кошельков", "command_k_internal_shortcuts_enabled": "Включить внутренние ярлыки ⌘K", - "custom_rpc": "Пользовательский RPC" + "custom_rpc": "Пользовательский RPC", + "degen_mode": "Degenмод" } }, "transactions": { @@ -776,6 +777,10 @@ } }, "got_it": "Понятно" + }, + "degen_mode": { + "title": "Degenмод", + "description": "Пропустить этап проверки, чтобы быстрее обменять" } }, "actions": { @@ -785,7 +790,10 @@ "fee_on_transfer_token": "Комиссия на токены при переводе", "no_route": "Маршрут не найден", "no_quote": "Нет доступного предложения", - "enter_an_amount": "Введите сумму" + "enter_an_amount": "Введите сумму", + "swap": "%{Action}", + "swapping": "%{Actioning}", + "waiting_signature": "Подтвердите на вашем устройстве" }, "review": { "title": "Обзор и %{Action}", @@ -942,7 +950,8 @@ "import_wallet_group": "Импортировать группу кошельков", "n_words_might_be_wrong": "%{n} слов могут быть написаны с ошибками или некорректными.", "1_word_might_be_wrong": "1 слово может быть написано с ошибкой или некорректно.", - "couldnt_paste": "Мы не смогли вставить вашу Секретную фразу восстановления" + "couldnt_paste": "Мы не смогли вставить вашу Секретную фразу восстановления", + "duplicate_seed": "Этот seed уже импортирован" }, "import_wallet_via_private_key": { "title": "Импортировать ваш кошелек", diff --git a/static/json/languages/th_TH.json b/static/json/languages/th_TH.json index e98efad5a8..e681596b37 100644 --- a/static/json/languages/th_TH.json +++ b/static/json/languages/th_TH.json @@ -294,7 +294,8 @@ "full_watching_wallets": "สิทธิ์เข้าถึงเต็มรูปแบบของ Wallet ที่ถูกติดตาม", "hw_wallets_enabled": "เปิดการสนับสนุน Hardware Wallet", "command_k_internal_shortcuts_enabled": "เปิดใช้งาน ⌘K Shortcut ภายใน", - "custom_rpc": "Custom RPC" + "custom_rpc": "Custom RPC", + "degen_mode": "โหมด Degen" } }, "transactions": { @@ -776,6 +777,10 @@ } }, "got_it": "เข้าใจแล้ว" + }, + "degen_mode": { + "title": "โหมด Degen", + "description": "ข้ามขั้นตอนการตรวจสอบเพื่อแลกเปลี่ยนได้เร็วขึ้น" } }, "actions": { @@ -785,7 +790,10 @@ "fee_on_transfer_token": "ค่าธรรมเนียมสำหรับการโอนโทเค็น", "no_route": "ไม่พบเส้นทาง", "no_quote": "ไม่มีใบเสนอราคาที่มีอยู่", - "enter_an_amount": "ป้อนจำนวน" + "enter_an_amount": "ป้อนจำนวน", + "swap": "%{Action}", + "swapping": "%{Actioning}", + "waiting_signature": "ยืนยันบนอุปกรณ์ของคุณ" }, "review": { "title": "รีวิว & %{Action}", @@ -942,7 +950,8 @@ "import_wallet_group": "นำเข้ากลุ่มกระเป๋าสตางค์", "n_words_might_be_wrong": "%{n} คำอาจจะสะกดไม่ถูกต้องหรือไม่ถูกต้อง", "1_word_might_be_wrong": "1 คำอาจจะสะกดไม่ถูกต้องหรือไม่ถูกต้อง", - "couldnt_paste": "เราไม่สามารถวางวลีกู้คืนลับของคุณ" + "couldnt_paste": "เราไม่สามารถวางวลีกู้คืนลับของคุณ", + "duplicate_seed": "เมล็ดนี้นำเข้าแล้ว" }, "import_wallet_via_private_key": { "title": "นำกระเป๋าเงินของคุณเข้า", diff --git a/static/json/languages/tr_TR.json b/static/json/languages/tr_TR.json index ad0f9f2d6c..48d2ebb9d3 100644 --- a/static/json/languages/tr_TR.json +++ b/static/json/languages/tr_TR.json @@ -294,7 +294,8 @@ "full_watching_wallets": "İzlenen Cüzdanlara Tam Erişim", "hw_wallets_enabled": "Donanım Cüzdanı Desteğini Etkinleştir", "command_k_internal_shortcuts_enabled": "⌘K İç Hızlı Kısayollarını Etkinleştir", - "custom_rpc": "Özel RPC" + "custom_rpc": "Özel RPC", + "degen_mode": "Degen Modu" } }, "transactions": { @@ -776,6 +777,10 @@ } }, "got_it": "Anladım" + }, + "degen_mode": { + "title": "Degen Modu", + "description": "Daha hızlı değiştirmek için inceleme adımını atlayın" } }, "actions": { @@ -785,7 +790,10 @@ "fee_on_transfer_token": "Transfer Token Üzerine Ücret", "no_route": "Rota bulunamadı", "no_quote": "Teklif mevcut değil", - "enter_an_amount": "Bir miktar girin" + "enter_an_amount": "Bir miktar girin", + "swap": "%{Action}", + "swapping": "%{Actioning}", + "waiting_signature": "Cihazınızda Onaylayın" }, "review": { "title": "Gözden Geçir & %{Action}", @@ -942,7 +950,8 @@ "import_wallet_group": "12 kelime kullanıyorum", "n_words_might_be_wrong": "%{n} kelimenin yanlış yazılmış veya hatalı olabileceği belirlendi.", "1_word_might_be_wrong": "0 kelime yanlış yazılmış veya hatalı olabilir.", - "couldnt_paste": "1 kelime yanlış yazılmış veya hatalı olabilir." + "couldnt_paste": "1 kelime yanlış yazılmış veya hatalı olabilir.", + "duplicate_seed": "Bu tohum zaten ithal edildi" }, "import_wallet_via_private_key": { "title": "Gizli Kurtarma Cümlesini yapıştıramadık", diff --git a/static/json/languages/zh_CN.json b/static/json/languages/zh_CN.json index e0f71a4099..2b0a8eebdc 100644 --- a/static/json/languages/zh_CN.json +++ b/static/json/languages/zh_CN.json @@ -294,7 +294,8 @@ "full_watching_wallets": "完全访问被监视的钱包", "hw_wallets_enabled": "启用硬件钱包支持", "command_k_internal_shortcuts_enabled": "启用 ⌘K 内部快捷键", - "custom_rpc": "自定义RPC" + "custom_rpc": "自定义RPC", + "degen_mode": "Degen模式" } }, "transactions": { @@ -776,6 +777,10 @@ } }, "got_it": "知道了" + }, + "degen_mode": { + "title": "Degen模式", + "description": "跳过审核步骤以更快地交换" } }, "actions": { @@ -785,7 +790,10 @@ "fee_on_transfer_token": "转账代币的费用", "no_route": "找不到路由", "no_quote": "无可用报价", - "enter_an_amount": "输入金额" + "enter_an_amount": "输入金额", + "swap": "%{Action}", + "swapping": "%{Actioning}", + "waiting_signature": "在您的设备上确认" }, "review": { "title": "审查 & %{Action}", @@ -942,7 +950,8 @@ "import_wallet_group": "导入钱包组", "n_words_might_be_wrong": "可能有%{n} 个单词拼写错误或不正确", "1_word_might_be_wrong": "可能有1个单词拼写错误或不正确", - "couldnt_paste": "无法粘贴您的秘密恢复短语" + "couldnt_paste": "无法粘贴您的秘密恢复短语", + "duplicate_seed": "此种子已导入" }, "import_wallet_via_private_key": { "title": "导入您的钱包", diff --git a/static/manifest.json b/static/manifest.json index e0579d9443..66d984b48b 100644 --- a/static/manifest.json +++ b/static/manifest.json @@ -68,7 +68,7 @@ "notifications" ], "short_name": "Rainbow", - "version": "1.5.29", + "version": "1.5.37", "web_accessible_resources": [ { "matches": [ diff --git a/yarn.lock b/yarn.lock index 49cf06ed99..dd3c2e5cf2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2886,6 +2886,13 @@ dependencies: "@noble/hashes" "1.3.3" +"@noble/curves@^1.4.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.5.0.tgz#7a9b9b507065d516e6dce275a1e31db8d2a100dd" + integrity sha512-J5EKamIHnKPyClwVrzmaf5wSdQXgdHcPZIZLu3bwnbeCx8/7NPK5q2ZBWF+5FvYGByjiQQsJYX6jfgB2wDPn3A== + dependencies: + "@noble/hashes" "1.4.0" + "@noble/curves@~1.4.0": version "1.4.2" resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.4.2.tgz#40309198c76ed71bc6dbf7ba24e81ceb4d0d1fe9" @@ -2908,7 +2915,7 @@ resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.3.tgz#39908da56a4adc270147bb07968bf3b16cfe1699" integrity sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA== -"@noble/hashes@1.4.0", "@noble/hashes@^1.3.3", "@noble/hashes@~1.4.0": +"@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== @@ -3932,10 +3939,10 @@ eventemitter3 "5.0.1" viem "1.21.4" -"@rainbow-me/swaps@0.23.0": - version "0.23.0" - resolved "https://registry.yarnpkg.com/@rainbow-me/swaps/-/swaps-0.23.0.tgz#888e61a302e0f642e4ac7c5f58e6bd6d90b7c953" - integrity sha512-r6xF2v6bPguz7ytHO/UY+IjvyI8QqbytuXikXT8zCp1TVcXYWESsxJbVsGHd4utJOswSt5M7H1He0wY7shBh6g== +"@rainbow-me/swaps@0.24.0": + version "0.24.0" + resolved "https://registry.yarnpkg.com/@rainbow-me/swaps/-/swaps-0.24.0.tgz#c5436bb1caf584a4e580cf6ca5117a998152010c" + integrity sha512-j696H7RUdu4KeHZR55bGBMJ6a+dx3zGF5Y7Nv89vUrkSGaXfakDCBvYlGhHzNMxYX/jFd+jXm5v0Y8ZQUNBQcg== dependencies: "@ethereumjs/util" "9.0.0" "@ethersproject/abi" "5.7.0" @@ -4527,32 +4534,6 @@ resolved "https://registry.yarnpkg.com/@types/dom-screen-wake-lock/-/dom-screen-wake-lock-1.0.3.tgz#c3588a5f6f40fae957f9ce5be9bc4927a61bb9a0" integrity sha512-3Iten7X3Zgwvk6kh6/NRdwN7WbZ760YgFCsF5AxDifltUQzW1RaW+WRmcVtgwFzLjaNu64H+0MPJ13yRa8g3Dw== -"@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/eslint@*": - version "8.4.6" - resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.4.6.tgz#7976f054c1bccfcf514bff0564c0c41df5c08207" - integrity sha512-/fqTbjxyFUaYNO7VcW5g+4npmqVACz1bB7RTHYuLj+PRjw9hrCwrUXVQFpChUS0JsyEFvMZ7U/PfmvWgxJhI9g== - dependencies: - "@types/estree" "*" - "@types/json-schema" "*" - -"@types/estree@*": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.0.tgz#5fb2e536c1ae9bf35366eed879e827fa59ca41c2" - integrity sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ== - -"@types/estree@^1.0.0": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.1.tgz#aa22750962f3bf0e79d753d3cc067f010c95f194" - integrity sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA== - "@types/estree@^1.0.5": version "1.0.5" resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.5.tgz#a6ce3e556e00fd9895dd872dd172ad0d4bd687f4" @@ -4631,16 +4612,16 @@ resolved "https://registry.yarnpkg.com/@types/js-levenshtein/-/js-levenshtein-1.1.1.tgz#ba05426a43f9e4e30b631941e0aa17bf0c890ed5" integrity sha512-qC4bCqYGy1y/NP7dDVr7KJarn+PbX1nSpwA7JXdu0HxT3QYjO8MJ+cntENtHFVy2dRAyBV23OZ6MxsW1AM1L8g== -"@types/json-schema@*", "@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.12": version "7.0.12" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.12.tgz#d70faba7039d5fca54c83c7dbab41051d2b6f6cb" integrity sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA== +"@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/json5@^0.0.29": version "0.0.29" resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" @@ -5566,14 +5547,6 @@ loglevel-plugin-prefix "^0.8.4" strip-ansi "^7.1.0" -"@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== - dependencies: - "@webassemblyjs/helper-numbers" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" - "@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" @@ -5582,45 +5555,21 @@ "@webassemblyjs/helper-numbers" "1.11.6" "@webassemblyjs/helper-wasm-bytecode" "1.11.6" -"@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.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-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.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-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.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== - dependencies: - "@webassemblyjs/floating-point-hex-parser" "1.11.1" - "@webassemblyjs/helper-api-error" "1.11.1" - "@xtuc/long" "4.2.2" - "@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" @@ -5630,26 +5579,11 @@ "@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.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/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.12.1": version "1.12.1" resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz#3da623233ae1a60409b509a52ade9bc22a37f7bf" @@ -5660,13 +5594,6 @@ "@webassemblyjs/helper-wasm-bytecode" "1.11.6" "@webassemblyjs/wasm-gen" "1.12.1" -"@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== - dependencies: - "@xtuc/ieee754" "^1.2.0" - "@webassemblyjs/ieee754@1.11.6": version "1.11.6" resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz#bb665c91d0b14fffceb0e38298c329af043c6e3a" @@ -5674,13 +5601,6 @@ 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.11.6": version "1.11.6" resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.11.6.tgz#70e60e5e82f9ac81118bc25381a0b283893240d7" @@ -5688,30 +5608,11 @@ 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.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.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.12.1": version "1.12.1" resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz#9f9f3ff52a14c980939be0ef9d5df9ebc678ae3b" @@ -5726,17 +5627,6 @@ "@webassemblyjs/wasm-parser" "1.12.1" "@webassemblyjs/wast-printer" "1.12.1" -"@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.12.1": version "1.12.1" resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz#a6520601da1b5700448273666a71ad0a45d78547" @@ -5748,16 +5638,6 @@ "@webassemblyjs/leb128" "1.11.6" "@webassemblyjs/utf8" "1.11.6" -"@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.12.1": version "1.12.1" resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz#9e6e81475dfcfb62dab574ac2dda38226c232bc5" @@ -5768,18 +5648,6 @@ "@webassemblyjs/wasm-gen" "1.12.1" "@webassemblyjs/wasm-parser" "1.12.1" -"@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.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" @@ -5792,14 +5660,6 @@ "@webassemblyjs/leb128" "1.11.6" "@webassemblyjs/utf8" "1.11.6" -"@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== - dependencies: - "@webassemblyjs/ast" "1.11.1" - "@xtuc/long" "4.2.2" - "@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" @@ -5905,10 +5765,10 @@ abort-controller@^3.0.0: dependencies: event-target-shim "^5.0.0" -acorn-import-assertions@^1.7.6, acorn-import-assertions@^1.9.0: - version "1.9.0" - resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz#507276249d684797c84e0734ef84860334cfb1ac" - integrity sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA== +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.3.2: version "5.3.2" @@ -6708,7 +6568,7 @@ brace-expansion@^1.1.7: balanced-match "^1.0.0" concat-map "0.0.1" -braces@3.0.3, braces@^3.0.2, braces@~3.0.2: +braces@3.0.3, braces@^3.0.3, 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== @@ -6854,16 +6714,6 @@ browserify@17.0.0: vm-browserify "^1.0.0" xtend "^4.0.0" -browserslist@^4.14.5, browserslist@^4.21.3: - version "4.21.4" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.4.tgz#e7496bbc67b9e39dd0f98565feccdcb0d4ff6987" - integrity sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw== - dependencies: - caniuse-lite "^1.0.30001400" - electron-to-chromium "^1.4.251" - node-releases "^2.0.6" - update-browserslist-db "^1.0.9" - browserslist@^4.21.10: version "4.23.0" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.23.0.tgz#8f3acc2bbe73af7213399430890f86c63a5674ab" @@ -6874,6 +6724,16 @@ browserslist@^4.21.10: node-releases "^2.0.14" update-browserslist-db "^1.0.13" +browserslist@^4.21.3: + version "4.21.4" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.4.tgz#e7496bbc67b9e39dd0f98565feccdcb0d4ff6987" + integrity sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw== + dependencies: + caniuse-lite "^1.0.30001400" + electron-to-chromium "^1.4.251" + node-releases "^2.0.6" + update-browserslist-db "^1.0.9" + bs58@^4.0.0, bs58@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/bs58/-/bs58-4.0.1.tgz#be161e76c354f6f788ae4071f63f34e8c4f0a42a" @@ -8543,18 +8403,10 @@ enhanced-resolve@^5.0.0: graceful-fs "^4.2.4" tapable "^2.2.0" -enhanced-resolve@^5.10.0: - version "5.15.0" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz#1af946c7d93603eb88e9896cee4904dc012e9c35" - integrity sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg== - dependencies: - graceful-fs "^4.2.4" - tapable "^2.2.0" - -enhanced-resolve@^5.16.0: - version "5.16.1" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.16.1.tgz#e8bc63d51b826d6f1cbc0a150ecb5a8b0c62e567" - integrity sha512-4U5pNsuDl0EhuZpq46M5xPslstkviJuhrdobaRDBk2Jy2KO37FDAJl4lb2KlNabxT0m4MTK2UHNrsAcphE8nyw== +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" @@ -12973,12 +12825,12 @@ micro-ftch@^0.3.1: resolved "https://registry.yarnpkg.com/micro-ftch/-/micro-ftch-0.3.1.tgz#6cb83388de4c1f279a034fb0cf96dfc050853c5f" integrity sha512-/0LLxhzP0tfiR5hcQebtudP56gUurs2CLkGarnCiB/OqEyUFQ6U3paQi/tgLv0hBJYt2rnr9MNpxz4fiiugstg== -micromatch@^4.0.0, 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== +micromatch@4.0.8, micromatch@^4.0.0, micromatch@^4.0.2, micromatch@^4.0.4, micromatch@^4.0.5: + version "4.0.8" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.8.tgz#d66fa18f3a47076789320b9b1af32bd86d9fa202" + integrity sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA== dependencies: - braces "^3.0.2" + braces "^3.0.3" picomatch "^2.3.1" miller-rabin@^4.0.0: @@ -15436,7 +15288,7 @@ schema-utils@^3.0.0, schema-utils@^3.1.1: ajv "^6.12.5" ajv-keywords "^3.5.2" -schema-utils@^3.1.0, schema-utils@^3.2.0: +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== @@ -16324,17 +16176,6 @@ terser-webpack-plugin@^5.3.10: serialize-javascript "^6.0.1" terser "^5.26.0" -terser-webpack-plugin@^5.3.7: - 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.8" - terser@^5.10.0: version "5.15.0" resolved "https://registry.yarnpkg.com/terser/-/terser-5.15.0.tgz#e16967894eeba6e1091509ec83f0c60e179f2425" @@ -16345,16 +16186,6 @@ terser@^5.10.0: commander "^2.20.0" source-map-support "~0.5.20" -terser@^5.16.8: - version "5.19.4" - resolved "https://registry.yarnpkg.com/terser/-/terser-5.19.4.tgz#941426fa482bf9b40a0308ab2b3cd0cf7c775ebd" - integrity sha512-6p1DjHeuluwxDXcuT9VR8p64klWJKo1ILiy19s6C9+0Bh2+NWTX6nD9EPppiER4ICkHDVB1RkVpin/YW2nQn/g== - dependencies: - "@jridgewell/source-map" "^0.3.3" - acorn "^8.8.2" - commander "^2.20.0" - source-map-support "~0.5.20" - terser@^5.26.0: version "5.31.0" resolved "https://registry.yarnpkg.com/terser/-/terser-5.31.0.tgz#06eef86f17007dbad4593f11a574c7f5eb02c6a1" @@ -17153,10 +16984,10 @@ viem@1.21.4, viem@^1.0.0, viem@^1.1.4: isows "1.0.3" ws "8.13.0" -viem@2.17.0: - version "2.17.0" - resolved "https://registry.yarnpkg.com/viem/-/viem-2.17.0.tgz#5d7537e4e465e551c41a5304126d6d4a25468aa9" - integrity sha512-+gaVlsfDsHL1oYdjpatdRxW1WK/slLYVvpOws3fEdLfQFUToezKI6YLC9l1g2uKm4Hg3OdGX1KQy/G7/58tTKQ== +viem@2.21.0: + version "2.21.0" + resolved "https://registry.yarnpkg.com/viem/-/viem-2.21.0.tgz#715ad561853fba50d6ed48ebcaee007b5f9bf7ff" + integrity sha512-9g3Gw2nOU6t4bNuoDI5vwVExzIxseU0J7Jjx10gA2RNQVrytIrLxggW++tWEe3w4mnnm/pS1WgZFjQ/QKf/nHw== dependencies: "@adraffy/ens-normalize" "1.10.0" "@noble/curves" "1.4.0" @@ -17165,6 +16996,7 @@ viem@2.17.0: "@scure/bip39" "1.3.0" abitype "1.0.5" isows "1.0.4" + webauthn-p256 "0.0.5" ws "8.17.1" vite-node@0.34.6: @@ -17241,7 +17073,7 @@ walker@^1.0.8: dependencies: makeerror "1.0.12" -watchpack@2.4.0, watchpack@^2.4.0: +watchpack@2.4.0: version "2.4.0" resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.0.tgz#fa33032374962c78113f93c7f2fb4c54c9862a5d" integrity sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg== @@ -17321,6 +17153,14 @@ web-streams-polyfill@^3.2.1: resolved "https://registry.yarnpkg.com/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz#2073b91a2fdb1fbfbd401e7de0ac9f8214cecb4b" integrity sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw== +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" + webcrypto-core@^1.7.4: version "1.7.5" resolved "https://registry.yarnpkg.com/webcrypto-core/-/webcrypto-core-1.7.5.tgz#c02104c953ca7107557f9c165d194c6316587ca4" @@ -17441,51 +17281,20 @@ webpack-sources@^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@5.79.0: - version "5.79.0" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.79.0.tgz#8552b5da5a26e4e25842c08a883e08fc7740547a" - integrity sha512-3mN4rR2Xq+INd6NnYuL9RC9GAmc1ROPKJoHhrZ4pAjdMFEkJJWrsPw8o2JjCIyQyTu7rTXYn4VG6OpyB3CobZg== - dependencies: - "@types/eslint-scope" "^3.7.3" - "@types/estree" "^1.0.0" - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/wasm-edit" "1.11.1" - "@webassemblyjs/wasm-parser" "1.11.1" - acorn "^8.7.1" - acorn-import-assertions "^1.7.6" - browserslist "^4.14.5" - chrome-trace-event "^1.0.2" - enhanced-resolve "^5.10.0" - 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" - 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" - tapable "^2.1.1" - terser-webpack-plugin "^5.3.7" - watchpack "^2.4.0" - webpack-sources "^3.2.3" - -webpack@^5.91.0: - version "5.91.0" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.91.0.tgz#ffa92c1c618d18c878f06892bbdc3373c71a01d9" - integrity sha512-rzVwlLeBWHJbmgTC/8TvAcu5vpJNII+MelQpylD4jNERPwpBJOE2lEcko1zJX3QJeLjTTAnQxn/OJ8bjDzVQaw== +webpack@5.94.0, webpack@^5.91.0: + version "5.94.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.94.0.tgz#77a6089c716e7ab90c1c67574a28da518a20970f" + integrity sha512-KcsGn50VT+06JH/iunZJedYGUJS5FGjow8wb9c0v5n1Om8O1g4L6LjtfxwlXIATopoQu+vOXXa7gYisWxCoPyg== dependencies: - "@types/eslint-scope" "^3.7.3" "@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.9.0" + acorn-import-attributes "^1.9.5" browserslist "^4.21.10" chrome-trace-event "^1.0.2" - enhanced-resolve "^5.16.0" + enhanced-resolve "^5.17.1" es-module-lexer "^1.2.1" eslint-scope "5.1.1" events "^3.2.0"