diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 83824cf6..cb859b14 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -8,16 +8,12 @@ jobs: build: runs-on: ubuntu-latest - strategy: - matrix: - node-version: [16.x, 18.x] - steps: - uses: actions/checkout@v3 - - name: Use Node.js ${{ matrix.node-version }} + - name: Use Node.js 20.x uses: actions/setup-node@v3 with: - node-version: ${{ matrix.node-version }} + node-version: 20.x cache: "npm" - run: npm ci - run: npm run build @@ -25,16 +21,12 @@ jobs: build-storybook: runs-on: ubuntu-latest - strategy: - matrix: - node-version: [16.x, 18.x] - steps: - uses: actions/checkout@v3 - - name: Use Node.js ${{ matrix.node-version }} + - name: Use Node.js 20.x uses: actions/setup-node@v3 with: - node-version: ${{ matrix.node-version }} + node-version: 20.x cache: "npm" - run: npm ci - run: npm run storybook:build diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 1bd73473..d582daf4 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -11,7 +11,7 @@ jobs: - name: Use Node.js uses: actions/setup-node@v3 with: - node-version: 16 + node-version: 20.x cache: "npm" - run: npm ci - run: npm run fmt:check diff --git a/.github/workflows/npm-publish-dev.yml b/.github/workflows/npm-publish-dev.yml index e77fb39f..09da155a 100644 --- a/.github/workflows/npm-publish-dev.yml +++ b/.github/workflows/npm-publish-dev.yml @@ -17,7 +17,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-node@v3 with: - node-version: 16 + node-version: 20.x registry-url: https://registry.npmjs.org - run: ./scripts/publish-dev.sh env: diff --git a/.github/workflows/npm-publish.yml b/.github/workflows/npm-publish.yml index 735b3cb5..5ec9d8ce 100644 --- a/.github/workflows/npm-publish.yml +++ b/.github/workflows/npm-publish.yml @@ -18,7 +18,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions/setup-node@v3 with: - node-version: 16 + node-version: 20.x registry-url: https://registry.npmjs.org - run: | npm pkg delete scripts.prepare diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 45a1f1d4..af254d8e 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -8,27 +8,24 @@ jobs: test: runs-on: ubuntu-latest - strategy: - matrix: - node-version: [16.x, 18.x] - steps: - uses: actions/checkout@v3 - - name: Use Node.js ${{ matrix.node-version }} + - name: Use Node.js 20.x uses: actions/setup-node@v3 with: - node-version: ${{ matrix.node-version }} + node-version: 20.x cache: "npm" - run: npm ci - run: npm run test - env: - VITE_CI_TEST: true + # Snapshot comparison disabled + # env: + # VITE_CI_TEST: true - name: Upload Artifacts if: always() uses: actions/upload-artifact@v3 with: - name: test-results-${{ matrix.node-version }} + name: test-results path: | ./cypress-visual-report/* ./cypress-visual-screenshots/* diff --git a/cypress-visual-screenshots/baseline/Balance.cy.tsx-balance-with-equal.png b/cypress-visual-screenshots/baseline/Balance.cy.tsx-balance-with-equal.png new file mode 100755 index 00000000..c50bd175 Binary files /dev/null and b/cypress-visual-screenshots/baseline/Balance.cy.tsx-balance-with-equal.png differ diff --git a/cypress-visual-screenshots/baseline/Balance.cy.tsx-balance-without-equal.png b/cypress-visual-screenshots/baseline/Balance.cy.tsx-balance-without-equal.png new file mode 100755 index 00000000..15a1ae35 Binary files /dev/null and b/cypress-visual-screenshots/baseline/Balance.cy.tsx-balance-without-equal.png differ diff --git a/cypress-visual-screenshots/baseline/Button.cy.tsx-primary-button-with-both-icons-and-with-children.png b/cypress-visual-screenshots/baseline/Button.cy.tsx-primary-button-with-both-icons-and-with-children.png new file mode 100755 index 00000000..e34a2b7f Binary files /dev/null and b/cypress-visual-screenshots/baseline/Button.cy.tsx-primary-button-with-both-icons-and-with-children.png differ diff --git a/cypress-visual-screenshots/baseline/Button.cy.tsx-primary-button-with-posIcon-with-children.png b/cypress-visual-screenshots/baseline/Button.cy.tsx-primary-button-with-posIcon-with-children.png new file mode 100755 index 00000000..af2b3eb8 Binary files /dev/null and b/cypress-visual-screenshots/baseline/Button.cy.tsx-primary-button-with-posIcon-with-children.png differ diff --git a/cypress-visual-screenshots/baseline/Button.cy.tsx-primary-button-with-posIcon.png b/cypress-visual-screenshots/baseline/Button.cy.tsx-primary-button-with-posIcon.png new file mode 100755 index 00000000..a604fbee Binary files /dev/null and b/cypress-visual-screenshots/baseline/Button.cy.tsx-primary-button-with-posIcon.png differ diff --git a/cypress-visual-screenshots/baseline/Button.cy.tsx-primary-button-with-preIcon-with-children.png b/cypress-visual-screenshots/baseline/Button.cy.tsx-primary-button-with-preIcon-with-children.png new file mode 100755 index 00000000..fe0a7739 Binary files /dev/null and b/cypress-visual-screenshots/baseline/Button.cy.tsx-primary-button-with-preIcon-with-children.png differ diff --git a/cypress-visual-screenshots/baseline/Button.cy.tsx-primary-button-with-preIcon.png b/cypress-visual-screenshots/baseline/Button.cy.tsx-primary-button-with-preIcon.png new file mode 100755 index 00000000..aabb6260 Binary files /dev/null and b/cypress-visual-screenshots/baseline/Button.cy.tsx-primary-button-with-preIcon.png differ diff --git a/cypress-visual-screenshots/baseline/Button.cy.tsx-primary-button-without-icons-and-with-children.png b/cypress-visual-screenshots/baseline/Button.cy.tsx-primary-button-without-icons-and-with-children.png new file mode 100755 index 00000000..c1ace830 Binary files /dev/null and b/cypress-visual-screenshots/baseline/Button.cy.tsx-primary-button-without-icons-and-with-children.png differ diff --git a/cypress-visual-screenshots/baseline/Button.cy.tsx-primary-button-without-icons.png b/cypress-visual-screenshots/baseline/Button.cy.tsx-primary-button-without-icons.png new file mode 100755 index 00000000..358497a6 Binary files /dev/null and b/cypress-visual-screenshots/baseline/Button.cy.tsx-primary-button-without-icons.png differ diff --git a/cypress-visual-screenshots/baseline/Button.cy.tsx-secondary-button-with-both-icons-and-with-children.png b/cypress-visual-screenshots/baseline/Button.cy.tsx-secondary-button-with-both-icons-and-with-children.png new file mode 100755 index 00000000..f2db714a Binary files /dev/null and b/cypress-visual-screenshots/baseline/Button.cy.tsx-secondary-button-with-both-icons-and-with-children.png differ diff --git a/cypress-visual-screenshots/baseline/Button.cy.tsx-secondary-button-with-posIcon-with-children.png b/cypress-visual-screenshots/baseline/Button.cy.tsx-secondary-button-with-posIcon-with-children.png new file mode 100755 index 00000000..f2db714a Binary files /dev/null and b/cypress-visual-screenshots/baseline/Button.cy.tsx-secondary-button-with-posIcon-with-children.png differ diff --git a/cypress-visual-screenshots/baseline/Button.cy.tsx-secondary-button-with-posIcon.png b/cypress-visual-screenshots/baseline/Button.cy.tsx-secondary-button-with-posIcon.png new file mode 100755 index 00000000..f2db714a Binary files /dev/null and b/cypress-visual-screenshots/baseline/Button.cy.tsx-secondary-button-with-posIcon.png differ diff --git a/cypress-visual-screenshots/baseline/Button.cy.tsx-secondary-button-with-preIcon-with-children.png b/cypress-visual-screenshots/baseline/Button.cy.tsx-secondary-button-with-preIcon-with-children.png new file mode 100755 index 00000000..358497a6 Binary files /dev/null and b/cypress-visual-screenshots/baseline/Button.cy.tsx-secondary-button-with-preIcon-with-children.png differ diff --git a/cypress-visual-screenshots/baseline/Button.cy.tsx-secondary-button-with-preIcon.png b/cypress-visual-screenshots/baseline/Button.cy.tsx-secondary-button-with-preIcon.png new file mode 100755 index 00000000..f2db714a Binary files /dev/null and b/cypress-visual-screenshots/baseline/Button.cy.tsx-secondary-button-with-preIcon.png differ diff --git a/cypress-visual-screenshots/baseline/Button.cy.tsx-secondary-button-without-icons-and-with-children.png b/cypress-visual-screenshots/baseline/Button.cy.tsx-secondary-button-without-icons-and-with-children.png new file mode 100755 index 00000000..f2db714a Binary files /dev/null and b/cypress-visual-screenshots/baseline/Button.cy.tsx-secondary-button-without-icons-and-with-children.png differ diff --git a/cypress-visual-screenshots/baseline/Button.cy.tsx-secondary-button-without-icons.png b/cypress-visual-screenshots/baseline/Button.cy.tsx-secondary-button-without-icons.png new file mode 100755 index 00000000..358497a6 Binary files /dev/null and b/cypress-visual-screenshots/baseline/Button.cy.tsx-secondary-button-without-icons.png differ diff --git a/cypress-visual-screenshots/baseline/Clipboard.cy.tsx-clipboard-raw-content-success-flow.png b/cypress-visual-screenshots/baseline/Clipboard.cy.tsx-clipboard-raw-content-success-flow.png index 6e93ed1d..e7b595c5 100755 Binary files a/cypress-visual-screenshots/baseline/Clipboard.cy.tsx-clipboard-raw-content-success-flow.png and b/cypress-visual-screenshots/baseline/Clipboard.cy.tsx-clipboard-raw-content-success-flow.png differ diff --git a/cypress-visual-screenshots/baseline/Clipboard.cy.tsx-clipboard-success-flow.png b/cypress-visual-screenshots/baseline/Clipboard.cy.tsx-clipboard-success-flow.png deleted file mode 100755 index 175d2a59..00000000 Binary files a/cypress-visual-screenshots/baseline/Clipboard.cy.tsx-clipboard-success-flow.png and /dev/null differ diff --git a/cypress-visual-screenshots/baseline/Clipboard.cy.tsx-clipboard-with-displayed-content.png b/cypress-visual-screenshots/baseline/Clipboard.cy.tsx-clipboard-with-displayed-content.png index 175d2a59..1265f1c9 100755 Binary files a/cypress-visual-screenshots/baseline/Clipboard.cy.tsx-clipboard-with-displayed-content.png and b/cypress-visual-screenshots/baseline/Clipboard.cy.tsx-clipboard-with-displayed-content.png differ diff --git a/cypress-visual-screenshots/baseline/Clipboard.cy.tsx-clipboard-with-only-raw-content.png b/cypress-visual-screenshots/baseline/Clipboard.cy.tsx-clipboard-with-only-raw-content.png index 6e93ed1d..e7b595c5 100755 Binary files a/cypress-visual-screenshots/baseline/Clipboard.cy.tsx-clipboard-with-only-raw-content.png and b/cypress-visual-screenshots/baseline/Clipboard.cy.tsx-clipboard-with-only-raw-content.png differ diff --git a/cypress-visual-screenshots/baseline/Dropdown.cy.tsx-default-dropdown-flow.png b/cypress-visual-screenshots/baseline/Dropdown.cy.tsx-default-dropdown-flow.png new file mode 100755 index 00000000..da9ce634 Binary files /dev/null and b/cypress-visual-screenshots/baseline/Dropdown.cy.tsx-default-dropdown-flow.png differ diff --git a/cypress-visual-screenshots/baseline/Dropdown.cy.tsx-default-dropdown.png b/cypress-visual-screenshots/baseline/Dropdown.cy.tsx-default-dropdown.png new file mode 100755 index 00000000..da9ce634 Binary files /dev/null and b/cypress-visual-screenshots/baseline/Dropdown.cy.tsx-default-dropdown.png differ diff --git a/cypress-visual-screenshots/baseline/Dropdown.cy.tsx-default-md-dropdown.png b/cypress-visual-screenshots/baseline/Dropdown.cy.tsx-default-md-dropdown.png new file mode 100755 index 00000000..da9ce634 Binary files /dev/null and b/cypress-visual-screenshots/baseline/Dropdown.cy.tsx-default-md-dropdown.png differ diff --git a/cypress-visual-screenshots/baseline/Dropdown.cy.tsx-default-xs-dropdown.png b/cypress-visual-screenshots/baseline/Dropdown.cy.tsx-default-xs-dropdown.png new file mode 100755 index 00000000..6ce1a53f Binary files /dev/null and b/cypress-visual-screenshots/baseline/Dropdown.cy.tsx-default-xs-dropdown.png differ diff --git a/cypress-visual-screenshots/baseline/Input.cy.tsx-regular-input-with-content-and-error.png b/cypress-visual-screenshots/baseline/Input.cy.tsx-regular-input-with-content-and-error.png index 9c15f938..3facb901 100755 Binary files a/cypress-visual-screenshots/baseline/Input.cy.tsx-regular-input-with-content-and-error.png and b/cypress-visual-screenshots/baseline/Input.cy.tsx-regular-input-with-content-and-error.png differ diff --git a/cypress-visual-screenshots/baseline/Input.cy.tsx-regular-input-with-placeholder-and-error.png b/cypress-visual-screenshots/baseline/Input.cy.tsx-regular-input-with-placeholder-and-error.png index 66882a15..95ef87a4 100755 Binary files a/cypress-visual-screenshots/baseline/Input.cy.tsx-regular-input-with-placeholder-and-error.png and b/cypress-visual-screenshots/baseline/Input.cy.tsx-regular-input-with-placeholder-and-error.png differ diff --git a/cypress-visual-screenshots/baseline/Input.cy.tsx-regular-input-with-placeholder-and-warning.png b/cypress-visual-screenshots/baseline/Input.cy.tsx-regular-input-with-placeholder-and-warning.png index 49d311ac..e397e365 100755 Binary files a/cypress-visual-screenshots/baseline/Input.cy.tsx-regular-input-with-placeholder-and-warning.png and b/cypress-visual-screenshots/baseline/Input.cy.tsx-regular-input-with-placeholder-and-warning.png differ diff --git a/cypress-visual-screenshots/baseline/Input.cy.tsx-regular-input-with-placeholder.png b/cypress-visual-screenshots/baseline/Input.cy.tsx-regular-input-with-placeholder.png index e71c23ff..ca03e23b 100755 Binary files a/cypress-visual-screenshots/baseline/Input.cy.tsx-regular-input-with-placeholder.png and b/cypress-visual-screenshots/baseline/Input.cy.tsx-regular-input-with-placeholder.png differ diff --git a/cypress-visual-screenshots/baseline/Money.cy.tsx-default-money.png b/cypress-visual-screenshots/baseline/Money.cy.tsx-default-money.png new file mode 100755 index 00000000..239e1ed6 Binary files /dev/null and b/cypress-visual-screenshots/baseline/Money.cy.tsx-default-money.png differ diff --git a/cypress-visual-screenshots/baseline/Password.cy.tsx-default-password-with-error.png b/cypress-visual-screenshots/baseline/Password.cy.tsx-default-password-with-error.png index 7dec26e6..a8fd53d9 100755 Binary files a/cypress-visual-screenshots/baseline/Password.cy.tsx-default-password-with-error.png and b/cypress-visual-screenshots/baseline/Password.cy.tsx-default-password-with-error.png differ diff --git a/cypress-visual-screenshots/baseline/Password.cy.tsx-default-password-with-warning.png b/cypress-visual-screenshots/baseline/Password.cy.tsx-default-password-with-warning.png index ac3187da..36873869 100755 Binary files a/cypress-visual-screenshots/baseline/Password.cy.tsx-default-password-with-warning.png and b/cypress-visual-screenshots/baseline/Password.cy.tsx-default-password-with-warning.png differ diff --git a/cypress-visual-screenshots/baseline/Password.cy.tsx-default-password.png b/cypress-visual-screenshots/baseline/Password.cy.tsx-default-password.png index a9ef98fd..a80abef6 100755 Binary files a/cypress-visual-screenshots/baseline/Password.cy.tsx-default-password.png and b/cypress-visual-screenshots/baseline/Password.cy.tsx-default-password.png differ diff --git a/package-lock.json b/package-lock.json index 7a0ab0da..e5379c97 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2839,6 +2839,57 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, + "node_modules/@ethereumjs/common": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@ethereumjs/common/-/common-3.2.0.tgz", + "integrity": "sha512-pksvzI0VyLgmuEF2FA/JR/4/y6hcPq8OUail3/AvycBaW1d5VSauOZzqGvJ3RTmR4MU35lWE8KseKOsEhrFRBA==", + "license": "MIT", + "dependencies": { + "@ethereumjs/util": "^8.1.0", + "crc-32": "^1.2.0" + } + }, + "node_modules/@ethereumjs/rlp": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@ethereumjs/rlp/-/rlp-4.0.1.tgz", + "integrity": "sha512-tqsQiBQDQdmPWE1xkkBq4rlSW5QZpLOUJ5RJh2/9fug+q9tnUhuZoVLk7s0scUIKTOzEtR72DFBXI4WiZcMpvw==", + "license": "MPL-2.0", + "bin": { + "rlp": "bin/rlp" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@ethereumjs/tx": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@ethereumjs/tx/-/tx-4.2.0.tgz", + "integrity": "sha512-1nc6VO4jtFd172BbSnTnDQVr9IYBFl1y4xPzZdtkrkKIncBCkdbgfdRV+MiTkJYAtTxvV12GRZLqBFT1PNK6Yw==", + "license": "MPL-2.0", + "dependencies": { + "@ethereumjs/common": "^3.2.0", + "@ethereumjs/rlp": "^4.0.1", + "@ethereumjs/util": "^8.1.0", + "ethereum-cryptography": "^2.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@ethereumjs/util": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@ethereumjs/util/-/util-8.1.0.tgz", + "integrity": "sha512-zQ0IqbdX8FZ9aw11vP+dZkKDkS+kgIvQPHnSAXzP9pLu+Rfu3D3XEeLbicvoXJTYnhZiPmsZUxgdzXwNKxRPbA==", + "license": "MPL-2.0", + "dependencies": { + "@ethereumjs/rlp": "^4.0.1", + "ethereum-cryptography": "^2.0.0", + "micro-ftch": "^0.3.1" + }, + "engines": { + "node": ">=14" + } + }, "node_modules/@fal-works/esbuild-plugin-global-externals": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/@fal-works/esbuild-plugin-global-externals/-/esbuild-plugin-global-externals-2.1.2.tgz", @@ -3936,9 +3987,9 @@ } }, "node_modules/@massalabs/massa-web3": { - "version": "5.0.1-dev.20241128131418", - "resolved": "https://registry.npmjs.org/@massalabs/massa-web3/-/massa-web3-5.0.1-dev.20241128131418.tgz", - "integrity": "sha512-5o1XYLHu9qmET7XabQP7xqJKZN33N2tcbYz+FRsfjmwhTCikSADemi4hH2wh9gODZvCGP7rseg/xQ3wH5lLpgA==", + "version": "5.0.1-dev.20241212140726", + "resolved": "https://registry.npmjs.org/@massalabs/massa-web3/-/massa-web3-5.0.1-dev.20241212140726.tgz", + "integrity": "sha512-FlPS6U2ckTYXDlMsnoDHj+aMZJ/pCZt+aWnjMYgl6PNvuMN5nuqrr6c0ryUwF1w3wX1adCPYsyXcYeO7Purzqg==", "license": "MIT", "dependencies": { "@noble/ed25519": "^1.7.3", @@ -3967,13 +4018,14 @@ } }, "node_modules/@massalabs/wallet-provider": { - "version": "3.0.1-dev.20241128132550", - "resolved": "https://registry.npmjs.org/@massalabs/wallet-provider/-/wallet-provider-3.0.1-dev.20241128132550.tgz", - "integrity": "sha512-HEBNmVe+lOgs2PxQZ0Oa7pyw9X5/8GsVc7+ONUuQ6lMwLEXgGsT0bRWF7l5O4Oue55/iP734vB2qogQxN5im6w==", + "version": "3.0.1-dev.20241219125941", + "resolved": "https://registry.npmjs.org/@massalabs/wallet-provider/-/wallet-provider-3.0.1-dev.20241219125941.tgz", + "integrity": "sha512-lxI9XhZpcZx2pt85m3AP5c9n/9+Zpwjh3uCd7u+/QvcgWr3JuAohdPo1O8hFZnc6xIKFqa/xlpmWPmQ6/H4bGA==", "license": "(MIT AND Apache-2.0)", "dependencies": { "@hicaru/bearby.js": "^0.5.9", "@massalabs/massa-web3": "^5.0.1-dev", + "@metamask/providers": "^18.1.1", "axios": "^0.28.0", "bs58check": "^4.0.0", "buffer": "^6.0.3", @@ -4022,6 +4074,232 @@ "react": ">=16" } }, + "node_modules/@metamask/json-rpc-engine": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/@metamask/json-rpc-engine/-/json-rpc-engine-10.0.2.tgz", + "integrity": "sha512-UZKKvgEGVZyBOTKe0NrERv6J4QtR1X4a3Ppa10FZ2tY+nNvwQg3gFpWPRsYNQdPDFxtIsUdrMrqKvbkYSuHZkw==", + "license": "ISC", + "dependencies": { + "@metamask/rpc-errors": "^7.0.2", + "@metamask/safe-event-emitter": "^3.0.0", + "@metamask/utils": "^11.0.1" + }, + "engines": { + "node": "^18.18 || >=20" + } + }, + "node_modules/@metamask/json-rpc-engine/node_modules/@metamask/utils": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/@metamask/utils/-/utils-11.0.1.tgz", + "integrity": "sha512-tZlBvEJ6VhhfEiMV+Ad8rWRMjHKpbMogG01YU22JlsIeJptgIdZX1G8jJzhZH0Gxrixa2BeARh7m9lZWQo6rMg==", + "license": "ISC", + "dependencies": { + "@ethereumjs/tx": "^4.2.0", + "@metamask/superstruct": "^3.1.0", + "@noble/hashes": "^1.3.1", + "@scure/base": "^1.1.3", + "@types/debug": "^4.1.7", + "debug": "^4.3.4", + "pony-cause": "^2.1.10", + "semver": "^7.5.4", + "uuid": "^9.0.1" + }, + "engines": { + "node": "^18.18 || ^20.14 || >=22" + } + }, + "node_modules/@metamask/json-rpc-engine/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@metamask/json-rpc-middleware-stream": { + "version": "8.0.6", + "resolved": "https://registry.npmjs.org/@metamask/json-rpc-middleware-stream/-/json-rpc-middleware-stream-8.0.6.tgz", + "integrity": "sha512-wE2CfuNZHnWbSjLEPCCb4MSyWgbQBUI5cslGZb+uRdXNzYOM/RDfq8FAdl6HhjmldHKdBFCW0L3kDr8frgahqA==", + "license": "ISC", + "dependencies": { + "@metamask/json-rpc-engine": "^10.0.2", + "@metamask/safe-event-emitter": "^3.0.0", + "@metamask/utils": "^11.0.1", + "readable-stream": "^3.6.2" + }, + "engines": { + "node": "^18.18 || >=20" + } + }, + "node_modules/@metamask/json-rpc-middleware-stream/node_modules/@metamask/utils": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/@metamask/utils/-/utils-11.0.1.tgz", + "integrity": "sha512-tZlBvEJ6VhhfEiMV+Ad8rWRMjHKpbMogG01YU22JlsIeJptgIdZX1G8jJzhZH0Gxrixa2BeARh7m9lZWQo6rMg==", + "license": "ISC", + "dependencies": { + "@ethereumjs/tx": "^4.2.0", + "@metamask/superstruct": "^3.1.0", + "@noble/hashes": "^1.3.1", + "@scure/base": "^1.1.3", + "@types/debug": "^4.1.7", + "debug": "^4.3.4", + "pony-cause": "^2.1.10", + "semver": "^7.5.4", + "uuid": "^9.0.1" + }, + "engines": { + "node": "^18.18 || ^20.14 || >=22" + } + }, + "node_modules/@metamask/json-rpc-middleware-stream/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@metamask/object-multiplex": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@metamask/object-multiplex/-/object-multiplex-2.1.0.tgz", + "integrity": "sha512-4vKIiv0DQxljcXwfpnbsXcfa5glMj5Zg9mqn4xpIWqkv6uJ2ma5/GtUfLFSxhlxnR8asRMv8dDmWya1Tc1sDFA==", + "license": "ISC", + "dependencies": { + "once": "^1.4.0", + "readable-stream": "^3.6.2" + }, + "engines": { + "node": "^16.20 || ^18.16 || >=20" + } + }, + "node_modules/@metamask/providers": { + "version": "18.3.0", + "resolved": "https://registry.npmjs.org/@metamask/providers/-/providers-18.3.0.tgz", + "integrity": "sha512-9XRLIvctXtucShCwe1b8mC8PMd/TgiEFH/PFyF8EfxutNakbXBCbQvpml4XU/rVIltR68TsYpPe7Weaw+n7A5Q==", + "license": "MIT", + "dependencies": { + "@metamask/json-rpc-engine": "^10.0.1", + "@metamask/json-rpc-middleware-stream": "^8.0.5", + "@metamask/object-multiplex": "^2.0.0", + "@metamask/rpc-errors": "^7.0.1", + "@metamask/safe-event-emitter": "^3.1.1", + "@metamask/utils": "^10.0.0", + "detect-browser": "^5.2.0", + "extension-port-stream": "^4.1.0", + "fast-deep-equal": "^3.1.3", + "is-stream": "^2.0.0", + "readable-stream": "^3.6.2" + }, + "engines": { + "node": "^18.18 || >=20" + }, + "peerDependencies": { + "webextension-polyfill": "^0.10.0 || ^0.11.0 || ^0.12.0" + } + }, + "node_modules/@metamask/rpc-errors": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@metamask/rpc-errors/-/rpc-errors-7.0.2.tgz", + "integrity": "sha512-YYYHsVYd46XwY2QZzpGeU4PSdRhHdxnzkB8piWGvJW2xbikZ3R+epAYEL4q/K8bh9JPTucsUdwRFnACor1aOYw==", + "license": "MIT", + "dependencies": { + "@metamask/utils": "^11.0.1", + "fast-safe-stringify": "^2.0.6" + }, + "engines": { + "node": "^18.20 || ^20.17 || >=22" + } + }, + "node_modules/@metamask/rpc-errors/node_modules/@metamask/utils": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/@metamask/utils/-/utils-11.0.1.tgz", + "integrity": "sha512-tZlBvEJ6VhhfEiMV+Ad8rWRMjHKpbMogG01YU22JlsIeJptgIdZX1G8jJzhZH0Gxrixa2BeARh7m9lZWQo6rMg==", + "license": "ISC", + "dependencies": { + "@ethereumjs/tx": "^4.2.0", + "@metamask/superstruct": "^3.1.0", + "@noble/hashes": "^1.3.1", + "@scure/base": "^1.1.3", + "@types/debug": "^4.1.7", + "debug": "^4.3.4", + "pony-cause": "^2.1.10", + "semver": "^7.5.4", + "uuid": "^9.0.1" + }, + "engines": { + "node": "^18.18 || ^20.14 || >=22" + } + }, + "node_modules/@metamask/rpc-errors/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@metamask/safe-event-emitter": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@metamask/safe-event-emitter/-/safe-event-emitter-3.1.2.tgz", + "integrity": "sha512-5yb2gMI1BDm0JybZezeoX/3XhPDOtTbcFvpTXM9kxsoZjPZFh4XciqRbpD6N86HYZqWDhEaKUDuOyR0sQHEjMA==", + "license": "ISC", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@metamask/superstruct": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@metamask/superstruct/-/superstruct-3.1.0.tgz", + "integrity": "sha512-N08M56HdOgBfRKkrgCMZvQppkZGcArEop3kixNEtVbJKm6P9Cfg0YkI6X0s1g78sNrj2fWUwvJADdZuzJgFttA==", + "license": "MIT", + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@metamask/utils": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/@metamask/utils/-/utils-10.0.1.tgz", + "integrity": "sha512-zHgAitJtRwviVVFnRUA2PLRMaAwatr3jiHgiH7mPicJaeSK4ma01aGR4fHy0iy5tlVo1ZiioTmJ1Hbp8FZ6pSg==", + "license": "ISC", + "dependencies": { + "@ethereumjs/tx": "^4.2.0", + "@metamask/superstruct": "^3.1.0", + "@noble/hashes": "^1.3.1", + "@scure/base": "^1.1.3", + "@types/debug": "^4.1.7", + "debug": "^4.3.4", + "pony-cause": "^2.1.10", + "semver": "^7.5.4", + "uuid": "^9.0.1" + }, + "engines": { + "node": "^18.18 || ^20.14 || >=22" + } + }, + "node_modules/@metamask/utils/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/@microsoft/tsdoc": { "version": "0.14.2", "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.14.2.tgz", @@ -7720,6 +7998,15 @@ "@types/node": "*" } }, + "node_modules/@types/debug": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", + "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", + "license": "MIT", + "dependencies": { + "@types/ms": "*" + } + }, "node_modules/@types/detect-port": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/@types/detect-port/-/detect-port-1.3.5.tgz", @@ -7956,6 +8243,12 @@ "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==", "dev": true }, + "node_modules/@types/ms": { + "version": "0.7.34", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.34.tgz", + "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==", + "license": "MIT" + }, "node_modules/@types/node": { "version": "20.7.0", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.7.0.tgz", @@ -10659,6 +10952,18 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/crc-32": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", + "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", + "license": "Apache-2.0", + "bin": { + "crc32": "bin/crc32.njs" + }, + "engines": { + "node": ">=0.8" + } + }, "node_modules/create-jest": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz", @@ -11361,6 +11666,12 @@ "npm": "1.2.8000 || >= 1.4.16" } }, + "node_modules/detect-browser": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/detect-browser/-/detect-browser-5.3.0.tgz", + "integrity": "sha512-53rsFbGdwMwlF7qvCt0ypLM5V5/Mbl0szB7GPN8y9NCcbknYOeVVXdrXEq+90IwAfrrzt6Hd+u2E2ntakICU8w==", + "license": "MIT" + }, "node_modules/detect-indent": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz", @@ -12439,6 +12750,30 @@ "node": ">= 0.6" } }, + "node_modules/ethereum-cryptography": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-2.2.1.tgz", + "integrity": "sha512-r/W8lkHSiTLxUxW8Rf3u4HGB0xQweG2RyETjywylKZSzLWoWAijRz8WCuOtJ6wah+avllXBqZuk29HCCvhEIRg==", + "license": "MIT", + "dependencies": { + "@noble/curves": "1.4.2", + "@noble/hashes": "1.4.0", + "@scure/bip32": "1.4.0", + "@scure/bip39": "1.3.0" + } + }, + "node_modules/ethereum-cryptography/node_modules/@noble/curves": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.4.2.tgz", + "integrity": "sha512-TavHr8qycMChk8UwMld0ZDRvatedkzWfH8IiaeGCfymOP5i0hSCozz9vHOL0nkwk7HRMlFnAiKpS2jrUmSybcw==", + "license": "MIT", + "dependencies": { + "@noble/hashes": "1.4.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/eventemitter2": { "version": "6.4.7", "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.7.tgz", @@ -12598,6 +12933,21 @@ "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", "dev": true }, + "node_modules/extension-port-stream": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/extension-port-stream/-/extension-port-stream-4.2.0.tgz", + "integrity": "sha512-i5IgiPVMVrHN+Zx8PRjvFsOw8L1A3sboVwPZghDjW9Yp1BMmBDE6mCcTNu4xMXPYduBOwI3CBK7wd72LcOyD6g==", + "license": "ISC", + "dependencies": { + "readable-stream": "^3.6.2 || ^4.4.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "webextension-polyfill": "^0.10.0 || ^0.11.0 || ^0.12.0" + } + }, "node_modules/extract-zip": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", @@ -12630,8 +12980,7 @@ "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, "node_modules/fast-glob": { "version": "3.3.1", @@ -12671,6 +13020,12 @@ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, + "node_modules/fast-safe-stringify": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", + "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==", + "license": "MIT" + }, "node_modules/fastq": { "version": "1.15.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", @@ -14297,7 +14652,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "dev": true, "engines": { "node": ">=8" }, @@ -17825,6 +18179,12 @@ "node": ">= 0.6" } }, + "node_modules/micro-ftch": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/micro-ftch/-/micro-ftch-0.3.1.tgz", + "integrity": "sha512-/0LLxhzP0tfiR5hcQebtudP56gUurs2CLkGarnCiB/OqEyUFQ6U3paQi/tgLv0hBJYt2rnr9MNpxz4fiiugstg==", + "license": "MIT" + }, "node_modules/micromatch": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", @@ -18992,6 +19352,15 @@ "node": ">=10" } }, + "node_modules/pony-cause": { + "version": "2.1.11", + "resolved": "https://registry.npmjs.org/pony-cause/-/pony-cause-2.1.11.tgz", + "integrity": "sha512-M7LhCsdNbNgiLYiP4WjsfLUuFmCfnjdF6jKe2R9NKl4WFN+HZPGHJZ9lnLP7f9ZnKe3U9nuWD0szirmj+migUg==", + "license": "0BSD", + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/possible-typed-array-names": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", @@ -20092,7 +20461,6 @@ "version": "3.6.2", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dev": true, "license": "MIT", "dependencies": { "inherits": "^2.0.3", @@ -20497,7 +20865,6 @@ "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true, "funding": [ { "type": "github", @@ -21021,7 +21388,6 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dev": true, "dependencies": { "safe-buffer": "~5.2.0" } @@ -22291,7 +22657,6 @@ "version": "9.0.1", "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", - "dev": true, "funding": [ "https://github.com/sponsors/broofa", "https://github.com/sponsors/ctavan" @@ -22610,6 +22975,13 @@ "tslib": "^2.4.0" } }, + "node_modules/webextension-polyfill": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/webextension-polyfill/-/webextension-polyfill-0.12.0.tgz", + "integrity": "sha512-97TBmpoWJEE+3nFBQ4VocyCdLKfw54rFaJ6EVQYLBCXqCIpLSZkwGgASpv4oPt9gdKCJ80RJlcmNzNn008Ag6Q==", + "license": "MPL-2.0", + "peer": true + }, "node_modules/webidl-conversions": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", diff --git a/package.json b/package.json index cc0a00ca..27daa72b 100644 --- a/package.json +++ b/package.json @@ -7,6 +7,7 @@ "style": "src/global.css", "scripts": { "build": "tsc", + "build:watch": "tsc --watch", "storybook": "storybook dev -p 6006", "storybook:build": "storybook build", "lint": "eslint .", diff --git a/src/lib/ConnectMassaWallets/components/BearbyWallet.tsx b/src/lib/ConnectMassaWallets/components/BearbyWallet.tsx index 8d60fc63..b9f1ee84 100644 --- a/src/lib/ConnectMassaWallets/components/BearbyWallet.tsx +++ b/src/lib/ConnectMassaWallets/components/BearbyWallet.tsx @@ -10,24 +10,24 @@ import { useAccountStore } from '../store'; import { BEARBY_INSTALL } from '../../massa-react/const'; export default function BearbyWallet() { - const { connectedAccount } = useAccountStore(); + const { connectedAccount, isFetching } = useAccountStore(); - if (connectedAccount) { + if (!connectedAccount && !isFetching) { return ( -
- - -
+ ); } return ( - +
+ + +
); } diff --git a/src/lib/ConnectMassaWallets/components/ConnectMassaWallet.tsx b/src/lib/ConnectMassaWallets/components/ConnectMassaWallet.tsx index eb608842..3a952611 100644 --- a/src/lib/ConnectMassaWallets/components/ConnectMassaWallet.tsx +++ b/src/lib/ConnectMassaWallets/components/ConnectMassaWallet.tsx @@ -1,3 +1,4 @@ +import { MetaMaskSvg } from './MetaMaskSvg'; import { BearbySvg } from './BearbySvg'; import BearbyWallet from './BearbyWallet'; import SelectMassaWallet from './SelectMassaWallet'; @@ -8,17 +9,29 @@ import Intl from '../i18n'; import { useAccountStore } from '../store'; import { MassaWallet, Tooltip } from '../../../components'; import { WalletName } from '@massalabs/wallet-provider'; +import MetamaskWallet from './MetamaskWallet'; +import { Network } from './Network'; +import { useEffect, useState } from 'react'; export const ConnectMassaWallet = () => { const { currentWallet, wallets, setCurrentWallet, isFetching } = useAccountStore(); + const [selectedWallet, setSelectedWallet] = useState(null); + + useEffect(() => { + if (currentWallet) { + setSelectedWallet(currentWallet.name()); + } + }, [currentWallet]); function renderWallet() { - switch (currentWallet?.name()) { + switch (selectedWallet) { case WalletName.MassaStation: return ; case WalletName.Bearby: return ; + case WalletName.Metamask: + return ; default: // Should not happen return <>Error: no wallet selected; @@ -26,7 +39,7 @@ export const ConnectMassaWallet = () => { } function renderSelectedWallet() { - switch (currentWallet?.name()) { + switch (selectedWallet) { case WalletName.MassaStation: return ( <> @@ -41,18 +54,26 @@ export const ConnectMassaWallet = () => { {Intl.t(`connect-wallet.${WalletName.Bearby}`)} ); + case WalletName.Metamask: + return ( + <> + + {Intl.t(`connect-wallet.${WalletName.Metamask}`)} + + ); } } - if (!currentWallet) { + if (!selectedWallet && !isFetching) { return (
{ - const provider = wallets.find((p) => p.name() === providerName); - if (provider) { - await setCurrentWallet(provider); + const wallet = wallets.find((p) => p.name() === providerName); + if (wallet) { + await setCurrentWallet(wallet); } + setSelectedWallet(providerName); }} />
@@ -68,6 +89,7 @@ export const ConnectMassaWallet = () => {
{renderSelectedWallet()} + {currentWallet?.name() === WalletName.Bearby && ( { { setCurrentWallet(); + setSelectedWallet(null); }} />
- {!isFetching && renderWallet()} + {renderWallet()} ); }; diff --git a/src/lib/ConnectMassaWallets/components/MASBalance.tsx b/src/lib/ConnectMassaWallets/components/MASBalance.tsx index d66ebabb..186a6927 100644 --- a/src/lib/ConnectMassaWallets/components/MASBalance.tsx +++ b/src/lib/ConnectMassaWallets/components/MASBalance.tsx @@ -7,21 +7,22 @@ import { useEffect, useState } from 'react'; import Intl from '../i18n'; import { useAccountStore } from '../store'; import { FetchingLine } from '../../../components'; -import { fetchMASBalance } from '../../massa-react/utils'; import { massaToken } from '../../massa-react/const'; import { formatAmount } from '../../util/parseAmount'; export function MASBalance() { const [balance, setBalance] = useState(); - const { connectedAccount } = useAccountStore(); + const { connectedAccount, currentWallet, network } = useAccountStore(); useEffect(() => { if (!connectedAccount) return; - fetchMASBalance(connectedAccount).then((balance) => { + const fetchBalance = async () => { + const balance = await connectedAccount.balance(false); setBalance(balance); - }); - }, [connectedAccount, setBalance]); + }; + fetchBalance(); + }, [connectedAccount, setBalance, currentWallet, network]); const formattedBalance = formatAmount(balance?.toString() || '0', 9).full; diff --git a/src/lib/ConnectMassaWallets/components/MetaMaskSvg.tsx b/src/lib/ConnectMassaWallets/components/MetaMaskSvg.tsx new file mode 100644 index 00000000..5fd2ceaf --- /dev/null +++ b/src/lib/ConnectMassaWallets/components/MetaMaskSvg.tsx @@ -0,0 +1,57 @@ +/* eslint-disable max-len */ +export function MetaMaskSvg() { + return ( + + + + + + + + + + + + + + + ); +} diff --git a/src/lib/ConnectMassaWallets/components/MetamaskWallet.tsx b/src/lib/ConnectMassaWallets/components/MetamaskWallet.tsx new file mode 100644 index 00000000..c407e9b6 --- /dev/null +++ b/src/lib/ConnectMassaWallets/components/MetamaskWallet.tsx @@ -0,0 +1,63 @@ +// eslint-disable-next-line @typescript-eslint/ban-ts-comment +// @ts-ignore +import React from 'react'; + +import { ConnectedAccount } from './ConnectedAccount'; +import { MASBalance } from './MASBalance'; +import { WalletError } from './WalletError'; +import Intl from '../i18n'; +import { useAccountStore } from '../store'; +import { METAMASK_INSTALL } from '../../massa-react/const'; +import { Button } from '../../../components'; +import { CHAIN_ID, Network } from '@massalabs/massa-web3'; + +export default function MetamaskWallet() { + const { connectedAccount, currentWallet, network, isFetching } = + useAccountStore(); + + function handleSwitchNetwork(network: Network): void { + if (!currentWallet) return; + if (network.chainId === CHAIN_ID.Mainnet) { + currentWallet.setRpcUrl('https://buildnet.massa.net/api/v2'); + } else { + currentWallet.setRpcUrl('https://mainnet.massa.net/api/v2'); + } + } + + if (!connectedAccount && !isFetching) { + return ( + + ); + } + + return ( +
+ + + {network && currentWallet && ( +
+ handleSwitchNetwork(network)} + /> +
+ )} +
+ ); +} + +function SwitchNetwork({ + networkName, + onClick, +}: { + networkName: string; + onClick: () => void; +}) { + return ; +} diff --git a/src/lib/ConnectMassaWallets/components/Network.tsx b/src/lib/ConnectMassaWallets/components/Network.tsx new file mode 100644 index 00000000..7a9bc053 --- /dev/null +++ b/src/lib/ConnectMassaWallets/components/Network.tsx @@ -0,0 +1,18 @@ +// eslint-disable-next-line @typescript-eslint/ban-ts-comment +// @ts-ignore +import React from 'react'; + +import { Tag, tagTypes } from '../../../components'; +import { useAccountStore } from '../store'; + +export function Network() { + const { network } = useAccountStore(); + + if (!network) return; + + return ; +} + +export function NetworkTag({ networkName }: { networkName: string }) { + return {networkName}; +} diff --git a/src/lib/ConnectMassaWallets/components/SelectMassaWallet.tsx b/src/lib/ConnectMassaWallets/components/SelectMassaWallet.tsx index 3db6b545..df488071 100644 --- a/src/lib/ConnectMassaWallets/components/SelectMassaWallet.tsx +++ b/src/lib/ConnectMassaWallets/components/SelectMassaWallet.tsx @@ -7,6 +7,7 @@ import { Disconnected } from './Status/Disconnected'; import Intl from '../i18n'; import { Dropdown, MassaWallet } from '../../../components'; import { WalletName } from '@massalabs/wallet-provider'; +import { MetaMaskSvg } from './MetaMaskSvg'; const walletList = [ { @@ -17,6 +18,10 @@ const walletList = [ name: WalletName.Bearby, icon: , }, + { + name: WalletName.Metamask, + icon: , + }, ]; interface SelectMassaWalletProps { diff --git a/src/lib/ConnectMassaWallets/components/StationWallet.tsx b/src/lib/ConnectMassaWallets/components/StationWallet.tsx index 3d420d26..81431a2a 100644 --- a/src/lib/ConnectMassaWallets/components/StationWallet.tsx +++ b/src/lib/ConnectMassaWallets/components/StationWallet.tsx @@ -22,7 +22,7 @@ import Intl from '../i18n'; import { useAccountStore } from '../store'; export default function StationWallet() { - const { accounts } = useAccountStore(); + const { accounts, isFetching } = useAccountStore(); const [stationIsOn, setStationIsOn] = useState( undefined, @@ -40,7 +40,7 @@ export default function StationWallet() { }); }); - if (stationIsOn === false) { + if (stationIsOn === false && !isFetching) { return ( ; } diff --git a/src/lib/ConnectMassaWallets/i18n/en_US.json b/src/lib/ConnectMassaWallets/i18n/en_US.json index 590b436b..9ec895ae 100644 --- a/src/lib/ConnectMassaWallets/i18n/en_US.json +++ b/src/lib/ConnectMassaWallets/i18n/en_US.json @@ -16,6 +16,8 @@ "your-wallet": "Your wallet", "bearby-not-installed": "Bearby extension is either turned off or not installed. Make sure the extension is on and refresh the page.", "get-bearby": "Get Bearby here", + "meta-mask-not-connected": "Metamask is not connected. Make sure the extension is on and connected to the right network.", + "get-metamask": "Get Metamask here", "massa-station-not-detected": "Massa Station desktop app is not detected. Make sure the app is opened, or click below to install it.", "get-massa-station": "Get Massa Station", "massa-wallet-not-detected": "Massa Wallet is not detected. Make sure the plugin is installed, or click below to install it.", @@ -26,6 +28,7 @@ }, "MASSASTATION": "MassaWallet", "BEARBY": "Bearby", + "METAMASK": "Metamask", "connected-cards": { "wallet-balance": "Balance: " }, diff --git a/src/lib/ConnectMassaWallets/store/accountStore.ts b/src/lib/ConnectMassaWallets/store/accountStore.ts index e473817c..2be163ee 100644 --- a/src/lib/ConnectMassaWallets/store/accountStore.ts +++ b/src/lib/ConnectMassaWallets/store/accountStore.ts @@ -34,34 +34,46 @@ export const useAccountStore = create((set, get) => ({ setCurrentWallet: async (wallet?: Wallet, account?: Provider) => { set({ isFetching: true }); - if (!wallet) { - resetAll(get, set); - return; - } + try { + if (!wallet) { + resetAll(get, set); + return; + } - if (get().currentWallet?.name() !== wallet.name()) resetObservers(get, set); + if (get().currentWallet?.name() !== wallet.name()) + resetObservers(get, set); - if (wallet.name() === WalletName.Bearby) { - try { - await setupBearbyWallet(wallet, set, get); - } catch (error) { - return; + set({ currentWallet: wallet }); + + if ( + wallet.name() === WalletName.Bearby || + wallet.name() === WalletName.Metamask + ) { + try { + await wallet.connect(); + } catch (error) { + return; + } } - } - if (!get().networkObserver) { - const networkObserver = wallet.listenNetworkChanges(async () => { - get().setCurrentNetwork(await wallet.networkInfos()); - }); - set({ networkObserver }); - } + const accounts = await wallet.accounts(); + + if (!get().accountObserver) { + setupAccountObserver(wallet, set, get); + } + + if (!get().networkObserver) { + setupNetworkObserver(wallet, set, get); + } - set({ currentWallet: wallet }); - const network = await wallet.networkInfos(); - get().setCurrentNetwork(network); - const accounts = await wallet.accounts(); - set({ accounts }); - get().setConnectedAccount(account || accounts[0]); + const network = await wallet.networkInfos(); + get().setCurrentNetwork(network); + + set({ accounts }); + set({ connectedAccount: account || accounts[0] }); + } catch (error) { + console.log('Failed to set current wallet', error); + } set({ isFetching: false }); }, @@ -110,24 +122,43 @@ function resetAll( set({ isFetching: false }); } -async function setupBearbyWallet( +function setupAccountObserver( wallet: Wallet, set: (partial: Partial) => void, get: () => AccountStoreState, ) { - await wallet.connect(); + try { + const observer = wallet.listenAccountChanges(async (newAddress: string) => { + const { connectedAccount, currentWallet, setConnectedAccount } = get(); - const observer = wallet.listenAccountChanges(async (newAddress: string) => { - const { connectedAccount, currentWallet, setConnectedAccount } = get(); + if (!currentWallet || !connectedAccount) return; - if (!currentWallet || !connectedAccount) return; + if (newAddress !== connectedAccount.address) { + const accounts = await currentWallet.accounts(); + const newAccount = accounts.find((acc) => acc.address === newAddress); + setConnectedAccount(newAccount); + } + }); - if (newAddress !== connectedAccount.address) { - const accounts = await currentWallet.accounts(); - const newAccount = accounts.find((acc) => acc.address === newAddress); - setConnectedAccount(newAccount); - } - }); + set({ accountObserver: observer }); + } catch (error) { + // Wallet does not support account observer + // console.log('Failed to setup account observer', error); + } +} - set({ accountObserver: observer }); +function setupNetworkObserver( + wallet: Wallet, + set: (partial: Partial) => void, + get: () => AccountStoreState, +) { + try { + const networkObserver = wallet.listenNetworkChanges(async () => { + get().setCurrentNetwork(await wallet.networkInfos()); + }); + set({ networkObserver }); + } catch (error) { + // Wallet does not support network observer + // console.log('Failed to setup network observer', error); + } } diff --git a/src/lib/massa-react/const.ts b/src/lib/massa-react/const.ts index 478d8281..cb003826 100644 --- a/src/lib/massa-react/const.ts +++ b/src/lib/massa-react/const.ts @@ -8,6 +8,7 @@ export const MASSA_WALLET_CREATE_ACCOUNT = 'http://station.massa/plugin/massa-labs/massa-wallet/web-app/account-create'; export const massaToken = 'MAS'; export const BEARBY_INSTALL = 'https://bearby.io'; +export const METAMASK_INSTALL = 'https://metamask.io/'; export const MASSA_EXPLO_URL = 'https://massexplo.io/tx/'; export const MASSA_EXPLO_EXTENSION = '?network=buildnet'; export const MASSA_EXPLORER_URL =