From eb6a438a6f4fcfb571d056ffd7728754f625b7d0 Mon Sep 17 00:00:00 2001 From: Richard Watts <108257153+rrw-zilliqa@users.noreply.github.com> Date: Thu, 1 Feb 2024 11:12:32 +0000 Subject: [PATCH] Update otterscan (#19) * Bump @types/react from 18.2.33 to 18.2.34 (#1446) * Add meta tag to prevent phone number detection on iOS (#1448) * Use ABI of verified contracts to decode function selectors (#1443) * Use ABI of verified contracts to decode function selectors * Add address parameter to use4Bytes function doc * Apply Sourcify color to MethodName component * Disable tab/route for now; feature will be postponed to the next release (#1451) * Remove old gitcoin link * Bump erigon version * Bump version * Bump vite-imagetools from 6.2.1 to 6.2.4 (#1479) * Bump @testing-library/react from 14.0.0 to 14.1.2 (#1480) * Bump prettier from 3.0.3 to 3.1.0 (#1478) * Bump prettier-plugin-organize-imports from 3.2.3 to 3.2.4 (#1476) * Bump react-intersection-observer from 9.5.2 to 9.5.3 (#1475) * Bump @types/react from 18.2.34 to 18.2.37 (#1467) * Bump sb to 7.5.3 * Bump @types/react-highlight from 0.12.7 to 0.12.8 (#1462) * Bump @types/react-blockies from 1.4.3 to 1.4.4 (#1464) * Bump @types/react-dom from 18.2.14 to 18.2.15 (#1468) * Bump @types/react-syntax-highlighter from 15.5.9 to 15.5.10 (#1463) * Bump @types/jest from 29.5.7 to 29.5.8 (#1470) * Bump prettier-plugin-tailwindcss from 0.5.6 to 0.5.7 (#1469) * Using --link as an attempt to optimize build times * Add Cypress e2e tests and GA workflow (#1481) * Add Cypress e2e tests and GA workflow * Add Cypress project ID and enable test recording * Separate devnet and mainnet e2e tests * Remove extra brace set * Use job outputs to decide secret availability * Add run commands for mainnet and devnet E2E tests * Add names to check-secrets steps * Add workflow_dispatch trigger * Add Action testing for cypress-e2e-tests-2 * Use 127.0.0.1 instead of localhost * Remove extra branch from push trigger * Add testing docs * Bump @vitejs/plugin-react-swc from 3.4.1 to 3.5.0 (#1484) * Bump @types/react from 18.2.37 to 18.2.38 (#1491) * Bump typescript from 5.2.2 to 5.3.2 (#1489) * Bump @types/jest from 29.5.8 to 29.5.10 (#1493) * Bump @types/react-dom from 18.2.15 to 18.2.17 (#1494) * Bump vite-plugin-rewrite-all from 1.0.1 to 1.0.2 (#1485) * Bump react-router-dom from 6.18.0 to 6.20.0 (#1495) * Better use ci instead of install * Bump cypress from 13.5.0 to 13.6.0 (#1498) * Remove commify from raw decoded uints (#1486) * Enable e2e test runs on branches named feature/** * Bump vite from 4.5.0 to 5.0.2 (#1499) * Bump vite from 4.5.0 to 5.0.2 Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 4.5.0 to 5.0.2. - [Release notes](https://github.com/vitejs/vite/releases) - [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md) - [Commits](https://github.com/vitejs/vite/commits/v5.0.2/packages/vite) --- updated-dependencies: - dependency-name: vite dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] * Remove vite-plugin-rewrite-all dependency --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: sealer3 <125761775+sealer3@users.noreply.github.com> * Use gha cache * Add --link to everything else * Improve e2e workflow execution (#1502) * Remove explicit node setup * First attempt to make devnet tests use the standard cypress github action * Make names shorter; cant read them on github UI * Attempt to fix quotes * Attempt #2 * Attempt #3 * Attempt #4: see cypress limitations https://github.com/cypress-io/github-action/issues/482 * Remove manual node setup * Proper golang cache setup * Beautify script * Smoke tests (#1503) * Automate vitalik address navigation smoketest * Increase timeout for slow page load * Enable video * Trying to fix timeouts * Delete video for successful attempts * Add wait for page load * Bump sb to 7.6.1 * Bump vite from 5.0.2 to 5.0.4 (#1518) * Bump @types/react from 18.2.38 to 18.2.39 (#1512) * Bump vite-imagetools from 6.2.4 to 6.2.5 (#1506) * Bump node to v20.10.0 in order to avoid https://github.com/nodejs/node/pull/50136 (#1528) * Bump @fortawesome/fontawesome-svg-core from 6.4.2 to 6.5.0 (#1517) * Bump @fortawesome/free-regular-svg-icons from 6.4.2 to 6.5.0 (#1516) * Bump @fortawesome/free-solid-svg-icons from 6.4.2 to 6.5.0 (#1520) * Bump @fortawesome/free-brands-svg-icons from 6.4.2 to 6.5.0 (#1522) * Prevent SectionHighlighter from truncating by default (#1504) * Remove truncate class from HighlighterBox * Prevent bytes length label from being selected * Enable static network discovery (#1529) * Bump react-helmet-async from 1.3.0 to 2.0.1 (#1492) * Show parameter names for Sourcify verified contracts in traces (#1473) * Use checksummed addresses in Token Balances tab (#1477) * Bump @types/react from 18.2.39 to 18.2.42 (#1567) * Bump postcss from 8.4.31 to 8.4.32 (#1563) * Bump sb to 7.6.3 (#1568) * Bump tspeg from 3.3.0 to 3.3.1 (#1535) * Bump react-router-dom from 6.20.0 to 6.20.1 (#1564) * Bump @adobe/css-tools from 4.3.1 to 4.3.2 (#1543) * Bump @fortawesome/free-brands-svg-icons from 6.5.0 to 6.5.1 (#1550) * Bump @fortawesome/free-solid-svg-icons from 6.5.0 to 6.5.1 (#1553) * Add icon and selector to contract error types (#1542) * Bump @fortawesome/free-regular-svg-icons from 6.5.0 to 6.5.1 (#1556) * Bump @fortawesome/fontawesome-svg-core from 6.5.0 to 6.5.1 (#1555) * Bump vite-imagetools from 6.2.5 to 6.2.7 (#1566) * Bump @testing-library/jest-dom from 6.1.4 to 6.1.5 (#1548) * Bump react-helmet-async from 2.0.1 to 2.0.3 (#1549) * Add Prettier workflow (#1559) * Add Prettier workflow * Run prettier on entire repo * Opt out of Storybook telemetry * Add building to the workflow * Use the Sourcify web server by default (#1544) * Don't replace the @ symbol in Sourcify sources (#1558) * Bump vite from 5.0.4 to 5.0.5 (#1569) * Use .nvmrc for determining node version (#1570) * Add e2e test for tx page navigation (#1561) * Bump vite from 5.0.5 to 5.0.6 (#1574) * Bump tailwindcss from 3.3.5 to 3.3.6 (#1573) * Bump actions/setup-go from 4 to 5 (#1578) * Bump prettier-plugin-tailwindcss from 0.5.7 to 0.5.9 (#1575) * Bump @types/react-syntax-highlighter from 15.5.10 to 15.5.11 (#1577) * Bump @types/jest from 29.5.10 to 29.5.11 (#1572) * Bump cypress from 13.6.0 to 13.6.1 (#1571) * Bump chart.js from 4.4.0 to 4.4.1 (#1576) * Add array entry interface and FunctionParamInput redesign (#1471) * Add array entry interface and FunctionParamInput redesign * Add extra vertical spacing for Remove buttons * Fix variable array entry spacing * Align all buttons * Use same margin for Add Element as for Query * Add arrays to ParamDeclaration * Add more spacing between items and ParamDeclarations * Add space between parameters of the same function * Align ParamDeclaration text with Remove button text * Add e2e test for Read Contract array inputs * Add mainnet Read Contract test * Shorten step name * Display uint256 values with unselectable commas (#1594) * Display uint256 values with unselectable commas * Add DisplayInteger story * Update decimalHint type * Remove shadow hint * Bump @types/react from 18.2.42 to 18.2.45 (#1601) * Bump typescript from 5.3.2 to 5.3.3 (#1587) * Bump sb to 7.6.4 (#1604) * Bump vite from 5.0.6 to 5.0.9 (#1602) * Fix duplicate github actions execution (#1605) * Remove feature/** branch to avoid duplicate jobs execution * Also remove it from e2e workflow * Bump ts-node from 10.9.1 to 10.9.2 (#1592) * Bump prettier from 3.1.0 to 3.1.1 (#1598) * Bump actions/upload-artifact from 3 to 4 (#1606) Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 3 to 4. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/v3...v4) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Temporarily disable arm64 docker builds to debug ga issue (#1615) * Revert "Temporarily disable arm64 docker builds to debug ga issue (#1615)" (#1618) This reverts commit 394419b0692ee786e25562e4bc36159ae44d7a81. * Bump @types/react-dom from 18.2.17 to 18.2.18 (#1617) Bumps [@types/react-dom](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react-dom) from 18.2.17 to 18.2.18. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react-dom) --- updated-dependencies: - dependency-name: "@types/react-dom" dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump vite from 5.0.9 to 5.0.10 (#1611) Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 5.0.9 to 5.0.10. - [Release notes](https://github.com/vitejs/vite/releases) - [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md) - [Commits](https://github.com/vitejs/vite/commits/v5.0.10/packages/vite) --- updated-dependencies: - dependency-name: vite dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Attempt to separate amd64/arm64 builds (#1619) * Bump react-router-dom from 6.20.1 to 6.21.0 (#1603) Bumps [react-router-dom](https://github.com/remix-run/react-router/tree/HEAD/packages/react-router-dom) from 6.20.1 to 6.21.0. - [Release notes](https://github.com/remix-run/react-router/releases) - [Changelog](https://github.com/remix-run/react-router/blob/main/packages/react-router-dom/CHANGELOG.md) - [Commits](https://github.com/remix-run/react-router/commits/react-router-dom@6.21.0/packages/react-router-dom) --- updated-dependencies: - dependency-name: react-router-dom dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump @fontsource/space-grotesk from 5.0.15 to 5.0.16 (#1589) Bumps [@fontsource/space-grotesk](https://github.com/fontsource/font-files/tree/HEAD/fonts/google/space-grotesk) from 5.0.15 to 5.0.16. - [Changelog](https://github.com/fontsource/font-files/blob/main/fonts/google/space-grotesk/CHANGELOG.md) - [Commits](https://github.com/fontsource/font-files/commits/HEAD/fonts/google/space-grotesk) --- updated-dependencies: - dependency-name: "@fontsource/space-grotesk" dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump @fontsource/fira-code from 5.0.15 to 5.0.16 (#1586) Bumps [@fontsource/fira-code](https://github.com/fontsource/font-files/tree/HEAD/fonts/google/fira-code) from 5.0.15 to 5.0.16. - [Changelog](https://github.com/fontsource/font-files/blob/main/fonts/google/fira-code/CHANGELOG.md) - [Commits](https://github.com/fontsource/font-files/commits/HEAD/fonts/google/fira-code) --- updated-dependencies: - dependency-name: "@fontsource/fira-code" dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump @fontsource/roboto-mono from 5.0.15 to 5.0.16 (#1588) Bumps [@fontsource/roboto-mono](https://github.com/fontsource/font-files/tree/HEAD/fonts/google/roboto-mono) from 5.0.15 to 5.0.16. - [Changelog](https://github.com/fontsource/font-files/blob/main/fonts/google/roboto-mono/CHANGELOG.md) - [Commits](https://github.com/fontsource/font-files/commits/HEAD/fonts/google/roboto-mono) --- updated-dependencies: - dependency-name: "@fontsource/roboto-mono" dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump sb to 7.6.5 (#1620) * Add copy button to token addresses on Token Balances page (#1596) * Add copy button to token addresses on Token Balances page * Remove superfluous class name * Use TransactionAddressWithCopy instead * Bump tailwindcss from 3.3.6 to 3.4.0 (#1631) Bumps [tailwindcss](https://github.com/tailwindlabs/tailwindcss) from 3.3.6 to 3.4.0. - [Release notes](https://github.com/tailwindlabs/tailwindcss/releases) - [Changelog](https://github.com/tailwindlabs/tailwindcss/blob/master/CHANGELOG.md) - [Commits](https://github.com/tailwindlabs/tailwindcss/compare/v3.3.6...v3.4.0) --- updated-dependencies: - dependency-name: tailwindcss dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump sb to 7.6.6 (#1633) * Bump react-helmet-async from 2.0.3 to 2.0.4 (#1627) Bumps [react-helmet-async](https://github.com/staylor/react-helmet-async) from 2.0.3 to 2.0.4. - [Release notes](https://github.com/staylor/react-helmet-async/releases) - [Commits](https://github.com/staylor/react-helmet-async/commits) --- updated-dependencies: - dependency-name: react-helmet-async dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Reactivate blocks rewarded support (#1636) * Revert "Disable tab/route for now; feature will be postponed to the next release (#1451)" This reverts commit ff4f1e073fcada4c042b0df72f3bafe283e6adc3. * Rename method * Reactivate blocks rewarded support; added block fees column * Update README (#1637) * Revert "Attempt to separate amd64/arm64 builds (#1619)" (#1638) This reverts commit aac8d4db31bcd22dc75881518ce430b5db965350. * Bump version (#1640) * Fix typo: show as '0 contracts' * Use checksummed addresses in contract lists * Add toggle for non-view functions in Read Contract * Attempt to fix docker ga * Add setup qemu * Debug error on npm ci * Bump @types/react from 18.2.45 to 18.2.46 Bumps [@types/react](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react) from 18.2.45 to 18.2.46. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react) --- updated-dependencies: - dependency-name: "@types/react" dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Bump cypress from 13.6.1 to 13.6.2 Bumps [cypress](https://github.com/cypress-io/cypress) from 13.6.1 to 13.6.2. - [Release notes](https://github.com/cypress-io/cypress/releases) - [Changelog](https://github.com/cypress-io/cypress/blob/develop/CHANGELOG.md) - [Commits](https://github.com/cypress-io/cypress/compare/v13.6.1...v13.6.2) --- updated-dependencies: - dependency-name: cypress dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Bump sb to 7.6.7 * Bump @testing-library/user-event from 14.5.1 to 14.5.2 Bumps [@testing-library/user-event](https://github.com/testing-library/user-event) from 14.5.1 to 14.5.2. - [Release notes](https://github.com/testing-library/user-event/releases) - [Changelog](https://github.com/testing-library/user-event/blob/main/CHANGELOG.md) - [Commits](https://github.com/testing-library/user-event/compare/v14.5.1...v14.5.2) --- updated-dependencies: - dependency-name: "@testing-library/user-event" dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Bump web-vitals from 3.5.0 to 3.5.1 Bumps [web-vitals](https://github.com/GoogleChrome/web-vitals) from 3.5.0 to 3.5.1. - [Changelog](https://github.com/GoogleChrome/web-vitals/blob/main/CHANGELOG.md) - [Commits](https://github.com/GoogleChrome/web-vitals/compare/v3.5.0...v3.5.1) --- updated-dependencies: - dependency-name: web-vitals dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Bump prettier-plugin-tailwindcss from 0.5.9 to 0.5.10 Bumps [prettier-plugin-tailwindcss](https://github.com/tailwindlabs/prettier-plugin-tailwindcss) from 0.5.9 to 0.5.10. - [Release notes](https://github.com/tailwindlabs/prettier-plugin-tailwindcss/releases) - [Changelog](https://github.com/tailwindlabs/prettier-plugin-tailwindcss/blob/main/CHANGELOG.md) - [Commits](https://github.com/tailwindlabs/prettier-plugin-tailwindcss/compare/v0.5.9...v0.5.10) --- updated-dependencies: - dependency-name: prettier-plugin-tailwindcss dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Bump react-router-dom from 6.21.0 to 6.21.1 Bumps [react-router-dom](https://github.com/remix-run/react-router/tree/HEAD/packages/react-router-dom) from 6.21.0 to 6.21.1. - [Release notes](https://github.com/remix-run/react-router/releases) - [Changelog](https://github.com/remix-run/react-router/blob/main/packages/react-router-dom/CHANGELOG.md) - [Commits](https://github.com/remix-run/react-router/commits/react-router-dom@6.21.1/packages/react-router-dom) --- updated-dependencies: - dependency-name: react-router-dom dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Break overflowing words in Read Contract error messages * Use 3 pending columns in Blocks Rewarded table * Bump vite-imagetools from 6.2.7 to 6.2.9 Bumps [vite-imagetools](https://github.com/JonasKruckenberg/imagetools) from 6.2.7 to 6.2.9. - [Release notes](https://github.com/JonasKruckenberg/imagetools/releases) - [Commits](https://github.com/JonasKruckenberg/imagetools/commits) --- updated-dependencies: - dependency-name: vite-imagetools dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Bump @testing-library/jest-dom from 6.1.5 to 6.2.0 Bumps [@testing-library/jest-dom](https://github.com/testing-library/jest-dom) from 6.1.5 to 6.2.0. - [Release notes](https://github.com/testing-library/jest-dom/releases) - [Changelog](https://github.com/testing-library/jest-dom/blob/main/CHANGELOG.md) - [Commits](https://github.com/testing-library/jest-dom/compare/v6.1.5...v6.2.0) --- updated-dependencies: - dependency-name: "@testing-library/jest-dom" dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * Bump postcss from 8.4.32 to 8.4.33 Bumps [postcss](https://github.com/postcss/postcss) from 8.4.32 to 8.4.33. - [Release notes](https://github.com/postcss/postcss/releases) - [Changelog](https://github.com/postcss/postcss/blob/main/CHANGELOG.md) - [Commits](https://github.com/postcss/postcss/compare/8.4.32...8.4.33) --- updated-dependencies: - dependency-name: postcss dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Bump vite from 5.0.10 to 5.0.11 Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 5.0.10 to 5.0.11. - [Release notes](https://github.com/vitejs/vite/releases) - [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md) - [Commits](https://github.com/vitejs/vite/commits/v5.0.11/packages/vite) --- updated-dependencies: - dependency-name: vite dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Make creation tx hash responsive and truncated * Bump tailwindcss from 3.4.0 to 3.4.1 Bumps [tailwindcss](https://github.com/tailwindlabs/tailwindcss) from 3.4.0 to 3.4.1. - [Release notes](https://github.com/tailwindlabs/tailwindcss/releases) - [Changelog](https://github.com/tailwindlabs/tailwindcss/blob/v3.4.1/CHANGELOG.md) - [Commits](https://github.com/tailwindlabs/tailwindcss/compare/v3.4.0...v3.4.1) --- updated-dependencies: - dependency-name: tailwindcss dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Bump prettier-plugin-tailwindcss from 0.5.10 to 0.5.11 Bumps [prettier-plugin-tailwindcss](https://github.com/tailwindlabs/prettier-plugin-tailwindcss) from 0.5.10 to 0.5.11. - [Release notes](https://github.com/tailwindlabs/prettier-plugin-tailwindcss/releases) - [Changelog](https://github.com/tailwindlabs/prettier-plugin-tailwindcss/blob/main/CHANGELOG.md) - [Commits](https://github.com/tailwindlabs/prettier-plugin-tailwindcss/compare/v0.5.10...v0.5.11) --- updated-dependencies: - dependency-name: prettier-plugin-tailwindcss dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Prevent address tab page titles from being overwritten The AddressMainPage was overwriting the page title with the address page title. * Show user notices and dev docs in decoded functions * Add function signature and docs toggle to params table * Move dev and user docs to Transaction Action section * Add HelpButton component and apply to function docs * Simplify component return * Bump @headlessui/react from 1.7.17 to 1.7.18 Bumps [@headlessui/react](https://github.com/tailwindlabs/headlessui/tree/HEAD/packages/@headlessui-react) from 1.7.17 to 1.7.18. - [Release notes](https://github.com/tailwindlabs/headlessui/releases) - [Changelog](https://github.com/tailwindlabs/headlessui/blob/main/packages/@headlessui-react/CHANGELOG.md) - [Commits](https://github.com/tailwindlabs/headlessui/commits/@headlessui/react@v1.7.18/packages/@headlessui-react) --- updated-dependencies: - dependency-name: "@headlessui/react" dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Bump react-router-dom from 6.21.1 to 6.21.2 Bumps [react-router-dom](https://github.com/remix-run/react-router/tree/HEAD/packages/react-router-dom) from 6.21.1 to 6.21.2. - [Release notes](https://github.com/remix-run/react-router/releases) - [Changelog](https://github.com/remix-run/react-router/blob/main/packages/react-router-dom/CHANGELOG.md) - [Commits](https://github.com/remix-run/react-router/commits/react-router-dom@6.21.2/packages/react-router-dom) --- updated-dependencies: - dependency-name: react-router-dom dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Bump prettier from 3.1.1 to 3.2.4 Bumps [prettier](https://github.com/prettier/prettier) from 3.1.1 to 3.2.4. - [Release notes](https://github.com/prettier/prettier/releases) - [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md) - [Commits](https://github.com/prettier/prettier/compare/3.1.1...3.2.4) --- updated-dependencies: - dependency-name: prettier dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * Prettier 3.2 now interprets tsconfig.json as jsonc * Bump @types/react from 18.2.46 to 18.2.48 (#1693) Bumps [@types/react](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react) from 18.2.46 to 18.2.48. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react) --- updated-dependencies: - dependency-name: "@types/react" dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump cypress from 13.6.2 to 13.6.3 (#1699) Bumps [cypress](https://github.com/cypress-io/cypress) from 13.6.2 to 13.6.3. - [Release notes](https://github.com/cypress-io/cypress/releases) - [Changelog](https://github.com/cypress-io/cypress/blob/develop/CHANGELOG.md) - [Commits](https://github.com/cypress-io/cypress/compare/v13.6.2...v13.6.3) --- updated-dependencies: - dependency-name: cypress dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump storybook from 7.6.7 to 7.6.9 (#1694) * Bump storybook from 7.6.7 to 7.6.9 Bumps [storybook](https://github.com/storybookjs/storybook/tree/HEAD/code/lib/cli) from 7.6.7 to 7.6.9. - [Release notes](https://github.com/storybookjs/storybook/releases) - [Changelog](https://github.com/storybookjs/storybook/blob/next/CHANGELOG.md) - [Commits](https://github.com/storybookjs/storybook/commits/v7.6.9/code/lib/cli) --- updated-dependencies: - dependency-name: storybook dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Bump other dependencies --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Willian Mitsuda * Bump storybook from 7.6.9 to 7.6.10 (#1708) * Bump storybook from 7.6.9 to 7.6.10 Bumps [storybook](https://github.com/storybookjs/storybook/tree/HEAD/code/lib/cli) from 7.6.9 to 7.6.10. - [Release notes](https://github.com/storybookjs/storybook/releases) - [Changelog](https://github.com/storybookjs/storybook/blob/next/CHANGELOG.md) - [Commits](https://github.com/storybookjs/storybook/commits/v7.6.10/code/lib/cli) --- updated-dependencies: - dependency-name: storybook dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] * Bump all sb components --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Willian Mitsuda * Bump autoprefixer from 10.4.16 to 10.4.17 (#1709) Bumps [autoprefixer](https://github.com/postcss/autoprefixer) from 10.4.16 to 10.4.17. - [Release notes](https://github.com/postcss/autoprefixer/releases) - [Changelog](https://github.com/postcss/autoprefixer/blob/main/CHANGELOG.md) - [Commits](https://github.com/postcss/autoprefixer/compare/10.4.16...10.4.17) --- updated-dependencies: - dependency-name: autoprefixer dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump vite from 5.0.11 to 5.0.12 (#1712) Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 5.0.11 to 5.0.12. - [Release notes](https://github.com/vitejs/vite/releases) - [Changelog](https://github.com/vitejs/vite/blob/v5.0.12/packages/vite/CHANGELOG.md) - [Commits](https://github.com/vitejs/vite/commits/v5.0.12/packages/vite) --- updated-dependencies: - dependency-name: vite dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump react-router-dom from 6.21.2 to 6.21.3 (#1713) Bumps [react-router-dom](https://github.com/remix-run/react-router/tree/HEAD/packages/react-router-dom) from 6.21.2 to 6.21.3. - [Release notes](https://github.com/remix-run/react-router/releases) - [Changelog](https://github.com/remix-run/react-router/blob/main/packages/react-router-dom/CHANGELOG.md) - [Commits](https://github.com/remix-run/react-router/commits/react-router-dom@6.21.3/packages/react-router-dom) --- updated-dependencies: - dependency-name: react-router-dom dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * New attempt to fix docker (#1714) * Try to split runners (#1715) * New attempt to fix docker * Split runners * Fix (#1716) * Docker fix 4 (#1717) * More fixes * Fix prettier * Show function signatures (#1681) * Move function signature above params table * Show function signature above input params table * Add blockquote around function docs and increase vertical spacing * Use keys in FunctionSignature param declarations * Bump ts-jest from 29.1.1 to 29.1.2 (#1719) Bumps [ts-jest](https://github.com/kulshekhar/ts-jest) from 29.1.1 to 29.1.2. - [Release notes](https://github.com/kulshekhar/ts-jest/releases) - [Changelog](https://github.com/kulshekhar/ts-jest/blob/main/CHANGELOG.md) - [Commits](https://github.com/kulshekhar/ts-jest/compare/v29.1.1...v29.1.2) --- updated-dependencies: - dependency-name: ts-jest dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump @testing-library/jest-dom from 6.2.0 to 6.3.0 (#1721) Bumps [@testing-library/jest-dom](https://github.com/testing-library/jest-dom) from 6.2.0 to 6.3.0. - [Release notes](https://github.com/testing-library/jest-dom/releases) - [Changelog](https://github.com/testing-library/jest-dom/blob/main/CHANGELOG.md) - [Commits](https://github.com/testing-library/jest-dom/compare/v6.2.0...v6.3.0) --- updated-dependencies: - dependency-name: "@testing-library/jest-dom" dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Add withdrawals count to epoch page (#1724) * Add withdrawals count to epoch page * Handle pre-Capella block responses properly * Show withdrawals on slot page (#1725) * Show withdrawals on slot page * Move withdrawal details row into its own component * Use TransactionAddress to show selection highlighting * Add hex-to-zil and fix API calls (#1) * Add hex-to-zil button Fix copy button to display new address Made changes according to comments * Update image name in Docker publish action (#2) * Remove publish to GHCR (#3) * Show contract bytecode in Contract tab (#8) Co-authored-by: sealer3 <125761775+sealer3@users.noreply.github.com> * Display Scilla contract source (#9) * Add ability to view DS Blocks (#13) * Changed Runtime Context to contain Zilliqa object * Reformatted code so that all Pending components are together * Added basic components for DS Blocks * Implemented polling for most recent DS Block * Added function to convert to Otterscan timestamp format * Added detailed DS Block page * Added ability to search for DS Blocks using search bar * Added DS Block List page * (fix) Make otterscan build again. * US-322: Can now decode scilla logs. (#16) * (feat) Scilla log decodes now work. * (fix) US-322: Fix package-lock.json * (fix) fix compile issues * (feat) Show raw receipts. * (feat) A bit more resilience to improperly formatted receipts. * (fix) Reverse priority of scilla and EVM log entry decodes so that we don't accidentally think any appropriately-formatted EVM log is a Scilla log (may need changing back) (feat) Now understands forwarded errors from EVM contracts that call Scilla (feat) Can now filter out empty blocks. * (fix) Remove debugging (fix) Suppress "no key" warning in decoded scilla params (fix) update package-lock.json (fix) ignore .vite directory (working dir) * (fix) Fix builds. * (fix) remove publish to github - we can't publish otterscan's images :-) * (fix) Fix use of invalid variable in AddressTransactionResults.tsx (fix) Update package-lock.json * (fix) Make otterscan compile again (fix) In-line address converter and copy icons * (fix) Better spacing for address display (fix) More API fixes * Update ethers. * (fix) the obligatory prettier run. --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: sealer3 <125761775+sealer3@users.noreply.github.com> Co-authored-by: Willian Mitsuda Co-authored-by: lucac-zilliqa <137715422+lucac-zilliqa@users.noreply.github.com> Co-authored-by: James Hinshelwood --- .github/workflows/build-and-prettier.yml | 26 + .github/workflows/docker-publish.yaml | 69 - .github/workflows/end-to-end.yaml | 112 + .gitignore | 5 + .storybook/main.ts | 3 + .storybook/preview-head.html | 2 +- .storybook/preview.tsx | 11 +- Dockerfile | 28 +- README.md | 4 +- cypress.config.ts | 40 + cypress/e2e/devnet/spec.cy.ts | 28 + cypress/e2e/devnet/verified-contracts.cy.ts | 71 + cypress/e2e/mainnet/smoketests.cy.ts | 70 + cypress/e2e/mainnet/spec.cy.ts | 10 + cypress/e2e/mainnet/verified-contracts.cy.ts | 103 + cypress/e2e/spec.cy.ts | 17 + .../fixtures/contracts/AllTypes/bytecode.txt | 1 + .../fixtures/contracts/AllTypes/metadata.json | 406 + .../contracts/AllTypes/sources/test.sol | 161 + cypress/support/commands.ts | 52 + cypress/support/devnet-config.json | 9 + cypress/support/e2e.ts | 20 + cypress/tsconfig.json | 10 + docs/ots2.md | 6 +- docs/testing.md | 48 + index.html | 3 +- package-lock.json | 16204 +++++++++------- package.json | 96 +- scripts/run-erigon-devnet-e2e-tests.sh | 9 + src/App.tsx | 9 +- src/Header.tsx | 14 +- src/Home.tsx | 152 +- src/Logo.tsx | 2 +- src/Main.tsx | 2 +- src/WarningHeader.tsx | 5 +- src/components/AddressHighlighter.tsx | 16 +- src/components/AddressSwap.tsx | 59 +- src/components/BCInfoToolTip.tsx | 7 +- src/components/BlockNotFound.tsx | 4 +- src/components/ChainInfoHeader.tsx | 6 +- src/components/ChainInfoItem.tsx | 15 +- src/components/Copy.tsx | 2 +- src/components/DSBlockLink.tsx | 6 +- src/components/DSBlockNotFound.tsx | 8 +- src/components/DisplayInteger.stories.tsx | 33 + src/components/DisplayInteger.tsx | 30 + src/components/HelpButton.stories.tsx | 23 + src/components/HelpButton.tsx | 26 + src/components/LabeledSwitch.stories.tsx | 23 + src/components/LabeledSwitch.tsx | 37 + src/components/MethodName.tsx | 13 +- src/components/TransactionLink.tsx | 4 +- src/consensus/Epoch.tsx | 2 +- src/consensus/epoch/StoredSlotItem.tsx | 11 +- src/consensus/slot/Overview.tsx | 45 +- src/consensus/slot/WithdrawalDetailsRow.tsx | 35 + src/consensus/types.ts | 10 + src/execution/AddressMainPage.tsx | 20 +- src/execution/Block.tsx | 8 +- src/execution/BlockList.tsx | 71 +- src/execution/ChainInfo.tsx | 211 +- src/execution/DSBlock.tsx | 48 +- src/execution/DSBlockList.tsx | 64 +- src/execution/Transaction.tsx | 3 + src/execution/address/AddressSubtitle.tsx | 6 +- src/execution/address/AddressTokens.tsx | 2 + .../address/AddressTransactionResults.tsx | 21 +- src/execution/address/BlockRewardedItem.tsx | 6 + src/execution/address/BlocksRewarded.tsx | 21 +- src/execution/address/Contracts.tsx | 22 +- src/execution/address/ERC20Item.tsx | 2 +- src/execution/address/TokenBalance.tsx | 4 +- .../address/contract/DecodedFragment.tsx | 13 +- .../contract/FunctionParamInput.stories.tsx | 50 + .../address/contract/FunctionParamInput.tsx | 184 + .../contract/FunctionParamsInput.stories.tsx | 56 - .../address/contract/FunctionParamsInput.tsx | 62 - .../address/contract/ReadContract.tsx | 36 +- .../address/contract/ReadFunction.tsx | 136 +- .../block/BlockTransactionResults.tsx | 5 +- src/execution/block/RecentBlocks.tsx | 33 +- src/execution/block/RecentDSBlocks.tsx | 31 +- src/execution/components/ParamDeclaration.tsx | 55 +- src/execution/transaction/Details.tsx | 37 +- .../transaction/FunctionSignature.tsx | 4 +- src/execution/transaction/LogEntry.tsx | 170 +- src/execution/transaction/Logs.tsx | 29 +- src/execution/transaction/Receipt.tsx | 26 + src/execution/transaction/TraceInput.tsx | 34 +- .../transaction/decoder/BytesDecoder.tsx | 5 +- .../decoder/DecodedLogSignature.tsx | 23 +- .../decoder/DecodedParamsTable.tsx | 7 +- .../decoder/DecodedScillaEncaps.tsx | 25 + .../decoder/DecodedScillaLogSignature.tsx | 24 +- .../decoder/DecodedScillaParamsTable.tsx | 66 +- .../transaction/decoder/FunctionSignature.tsx | 74 + .../transaction/decoder/InputDecoder.tsx | 23 +- .../transaction/decoder/Uint256Decoder.tsx | 7 +- src/ots2/contractMatchParsers.ts | 15 +- src/ots2/usePrototypeHooks.ts | 7 + src/ots2/usePrototypeTransferHooks.ts | 34 +- src/search/BlockItem.tsx | 66 +- src/search/BlockResultHeader.tsx | 25 +- src/search/DSBlockItem.tsx | 61 +- src/search/DSBlockResultHeader.tsx | 1 - src/search/RecentBlockItem.tsx | 59 +- src/search/RecentBlockResultHeader.tsx | 8 +- src/search/RecentDSBlockItem.tsx | 27 +- src/search/RecentDSNavBar.tsx | 18 +- src/search/RecentNavBar.tsx | 18 +- src/search/TransactionItem.tsx | 6 +- src/search/UndefinedPageButton.tsx | 13 +- src/search/messages.ts | 5 +- src/search/search.ts | 4 +- src/search/useEmptyBlocksToggler.ts | 19 + src/selection/SelectionHighlighter.tsx | 2 +- src/sourcify/useSourcify.ts | 7 +- src/special/london/BlockRow.tsx | 4 +- src/types.ts | 5 + src/use4Bytes.ts | 49 +- src/useErigonHooks.ts | 87 +- src/useLatestBlock.ts | 83 +- src/useProvider.ts | 8 +- src/useRuntime.ts | 10 +- src/useZilliqa.ts | 7 +- src/useZilliqaHooks.ts | 67 +- src/utils/utils.ts | 11 +- tsconfig.json | 4 +- vercel.json | 2 +- vite.config.ts | 8 +- 130 files changed, 12724 insertions(+), 7963 deletions(-) create mode 100644 .github/workflows/build-and-prettier.yml delete mode 100644 .github/workflows/docker-publish.yaml create mode 100644 .github/workflows/end-to-end.yaml create mode 100644 cypress.config.ts create mode 100644 cypress/e2e/devnet/spec.cy.ts create mode 100644 cypress/e2e/devnet/verified-contracts.cy.ts create mode 100644 cypress/e2e/mainnet/smoketests.cy.ts create mode 100644 cypress/e2e/mainnet/spec.cy.ts create mode 100644 cypress/e2e/mainnet/verified-contracts.cy.ts create mode 100644 cypress/e2e/spec.cy.ts create mode 100644 cypress/fixtures/contracts/AllTypes/bytecode.txt create mode 100644 cypress/fixtures/contracts/AllTypes/metadata.json create mode 100644 cypress/fixtures/contracts/AllTypes/sources/test.sol create mode 100644 cypress/support/commands.ts create mode 100644 cypress/support/devnet-config.json create mode 100644 cypress/support/e2e.ts create mode 100644 cypress/tsconfig.json create mode 100644 docs/testing.md create mode 100755 scripts/run-erigon-devnet-e2e-tests.sh create mode 100644 src/components/DisplayInteger.stories.tsx create mode 100644 src/components/DisplayInteger.tsx create mode 100644 src/components/HelpButton.stories.tsx create mode 100644 src/components/HelpButton.tsx create mode 100644 src/components/LabeledSwitch.stories.tsx create mode 100644 src/components/LabeledSwitch.tsx create mode 100644 src/consensus/slot/WithdrawalDetailsRow.tsx create mode 100644 src/execution/address/contract/FunctionParamInput.stories.tsx create mode 100644 src/execution/address/contract/FunctionParamInput.tsx delete mode 100644 src/execution/address/contract/FunctionParamsInput.stories.tsx delete mode 100644 src/execution/address/contract/FunctionParamsInput.tsx create mode 100644 src/execution/transaction/Receipt.tsx create mode 100644 src/execution/transaction/decoder/DecodedScillaEncaps.tsx create mode 100644 src/execution/transaction/decoder/FunctionSignature.tsx create mode 100644 src/search/useEmptyBlocksToggler.ts diff --git a/.github/workflows/build-and-prettier.yml b/.github/workflows/build-and-prettier.yml new file mode 100644 index 00000000..c2708dc1 --- /dev/null +++ b/.github/workflows/build-and-prettier.yml @@ -0,0 +1,26 @@ +name: Build and Prettier +on: + pull_request: + types: [opened, synchronize] + push: + branches: + - develop + - main + workflow_dispatch: +jobs: + check-prettier: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Install node + uses: actions/setup-node@v4 + with: + node-version-file: ".nvmrc" + cache: "npm" + - name: Install packages + run: npm ci + - name: Run prettier + run: npx prettier -c . + - name: Build Otterscan + run: npm run build diff --git a/.github/workflows/docker-publish.yaml b/.github/workflows/docker-publish.yaml deleted file mode 100644 index 1c71f328..00000000 --- a/.github/workflows/docker-publish.yaml +++ /dev/null @@ -1,69 +0,0 @@ -name: Publish Docker image - -on: - push: - branches: - - "develop" - tags: - - "*" - -jobs: - push_to_registry: - name: Push Docker image to Docker Hub - runs-on: ubuntu-latest - permissions: - contents: read - packages: write - - steps: - - name: Checkout - uses: actions/checkout@v4 - with: - submodules: recursive - - - name: Cache Docker layers - uses: actions/cache@v3 - with: - path: /tmp/.buildx-cache - key: ${{ runner.os }}-buildx-${{ github.sha }} - restore-keys: | - ${{ runner.os }}-buildx- - - - name: Docker Setup Buildx - uses: docker/setup-buildx-action@v3 - with: - driver: docker-container - driver-opts: | - image=moby/buildkit:master - - - name: Docker Login - uses: docker/login-action@v3 - with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_PASSWORD }} - - - name: Docker Metadata action - id: meta - uses: docker/metadata-action@v5 - with: - images: | - zilliqa/otterscan - - - name: Build and push Docker images - uses: docker/build-push-action@v5 - with: - context: . - push: true - platforms: linux/amd64,linux/arm64 - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} - cache-from: type=local,src=/tmp/.buildx-cache - cache-to: type=local,dest=/tmp/.buildx-cache-new - - # Temp fix - # https://github.com/docker/build-push-action/issues/252 - # https://github.com/moby/buildkit/issues/1896 - - name: Move cache - run: | - rm -rf /tmp/.buildx-cache - mv /tmp/.buildx-cache-new /tmp/.buildx-cache diff --git a/.github/workflows/end-to-end.yaml b/.github/workflows/end-to-end.yaml new file mode 100644 index 00000000..89a4eb9b --- /dev/null +++ b/.github/workflows/end-to-end.yaml @@ -0,0 +1,112 @@ +name: End-to-End Tests +on: + pull_request: + types: [opened, synchronize] + push: + branches: + - develop + - main + workflow_dispatch: +jobs: + check-secrets: + runs-on: ubuntu-latest + outputs: + e2e-erigon-url: ${{ steps.e2e-erigon-url.outputs.defined }} + e2e-cypress-record-key: ${{ steps.e2e-cypress-record-key.outputs.defined }} + steps: + - name: Check if E2E_ERIGON_URL is available + id: e2e-erigon-url + env: + E2E_ERIGON_URL: ${{ secrets.E2E_ERIGON_URL }} + if: "${{ env.E2E_ERIGON_URL != '' }}" + run: echo "defined=true" >> $GITHUB_OUTPUT + - name: Check if E2E_CYPRESS_RECORD_KEY is available + id: e2e-cypress-record-key + env: + E2E_CYPRESS_RECORD_KEY: ${{ secrets.E2E_CYPRESS_RECORD_KEY }} + if: "${{ env.E2E_CYPRESS_RECORD_KEY != '' }}" + run: echo "defined=true" >> $GITHUB_OUTPUT + + e2e-test-mainnet: + name: Run E2E tests on mainnet + runs-on: ubuntu-latest + if: ${{ needs.check-secrets.outputs.e2e-erigon-url == 'true' }} + needs: [check-secrets] + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Set up xvfb + run: | + sudo apt update + sudo apt install -y libgtk2.0-0 libgtk-3-0 libgbm-dev libnotify-dev libnss3 libxss1 libasound2 libxtst6 xauth xvfb + + - name: Run Cypress tests on mainnet + uses: cypress-io/github-action@v6 + with: + start: npm start + wait-on: "http://localhost:5173" + spec: "cypress/e2e/mainnet/**/*.cy.ts,cypress/e2e/*.cy.ts" + tag: ${{needs.check-secrets.outputs.e2e-cypress-record-key == 'true' && 'mainnet' || ''}} + record: | + ${{needs.check-secrets.outputs.e2e-cypress-record-key == 'true' && 'true' || 'false'}} + env: + VITE_ERIGON_URL: ${{secrets.E2E_ERIGON_URL}} + CYPRESS_RECORD_KEY: ${{secrets.E2E_CYPRESS_RECORD_KEY}} + - name: Upload screenshots from failing tests + uses: actions/upload-artifact@v4 + if: failure() + with: + name: Cypress Mainnet Screenshots + path: cypress/screenshots + + e2e-test-devnet: + name: Run E2E tests on a devnet + runs-on: ubuntu-latest + needs: [check-secrets] + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Set up xvfb + run: | + sudo apt update + sudo apt install -y libgtk2.0-0 libgtk-3-0 libgbm-dev libnotify-dev libnss3 libxss1 libasound2 libxtst6 xauth xvfb + + - name: Download Erigon + run: git clone --branch release/2.54 --single-branch https://github.com/ledgerwatch/erigon.git + - name: Set up Go + uses: actions/setup-go@v5 + with: + go-version-file: "erigon/go.mod" + cache-dependency-path: "erigon/go.sum" + - name: Build Erigon + run: | + cd erigon + make erigon + - name: Load devnet config + id: load-devnet-config + run: | + OTTERSCAN_CONFIG="$(cat cypress/support/devnet-config.json | sed 's/localhost/127.0.0.1/')" + OTTERSCAN_CONFIG=$(echo $OTTERSCAN_CONFIG) + echo "config=$OTTERSCAN_CONFIG" >> $GITHUB_OUTPUT + - name: Run Cypress tests on devnet + uses: cypress-io/github-action@v6 + with: + start: | + sh ./scripts/run-erigon-devnet-e2e-tests.sh + npm run start + wait-on: "http://127.0.0.1:8545, http://localhost:5173" + spec: "cypress/e2e/devnet/**/*.cy.ts,cypress/e2e/*.cy.ts" + tag: ${{needs.check-secrets.outputs.e2e-cypress-record-key == 'true' && 'devnet' || ''}} + record: | + ${{needs.check-secrets.outputs.e2e-cypress-record-key == 'true' && 'true' || 'false'}} + env: + VITE_CONFIG_JSON: ${{steps.load-devnet-config.outputs.config}} + CYPRESS_RECORD_KEY: ${{secrets.E2E_CYPRESS_RECORD_KEY}} + CYPRESS_DEVNET_ERIGON_URL: "http://127.0.0.1:8545" + CYPRESS_DEVNET_SOURCIFY_SOURCE: "http://127.0.0.1:7077" + - name: Upload screenshots from failing tests + uses: actions/upload-artifact@v4 + if: failure() + with: + name: Cypress Devnet Screenshots + path: cypress/screenshots diff --git a/.gitignore b/.gitignore index 3fcf3f97..b8f6f5e9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,6 @@ # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. +# Vite cache +.vite/ # emacs backups *~ @@ -12,6 +14,9 @@ # testing /coverage +/storybook-static +/cypress/screenshots +/cypress/videos # production /build diff --git a/.storybook/main.ts b/.storybook/main.ts index 2f153797..2ef0c9ef 100644 --- a/.storybook/main.ts +++ b/.storybook/main.ts @@ -17,6 +17,9 @@ const config: StorybookConfig = { typescript: { reactDocgen: false, }, + core: { + disableTelemetry: true, + }, }; export default config; diff --git a/.storybook/preview-head.html b/.storybook/preview-head.html index 05da1e9d..e5510401 100644 --- a/.storybook/preview-head.html +++ b/.storybook/preview-head.html @@ -1,3 +1,3 @@ \ No newline at end of file + diff --git a/.storybook/preview.tsx b/.storybook/preview.tsx index 09f1f465..457b3215 100644 --- a/.storybook/preview.tsx +++ b/.storybook/preview.tsx @@ -1,12 +1,11 @@ -import React from "react"; -import { Decorator } from "@storybook/react"; -import { INITIAL_VIEWPORTS } from "@storybook/addon-viewport"; -import { BrowserRouter as Router } from "react-router-dom"; import "@fontsource/fira-code/index.css"; -import "@fontsource/space-grotesk/index.css"; -import "@fontsource/roboto/index.css"; import "@fontsource/roboto-mono/index.css"; +import "@fontsource/roboto/index.css"; import "@fontsource/space-grotesk/files/space-grotesk-latin-400-normal.woff2"; +import "@fontsource/space-grotesk/index.css"; +import { INITIAL_VIEWPORTS } from "@storybook/addon-viewport"; +import { Decorator } from "@storybook/react"; +import { BrowserRouter as Router } from "react-router-dom"; import "../src/index.css"; export const parameters = { diff --git a/Dockerfile b/Dockerfile index 5f9297ee..f5cac181 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,10 +1,10 @@ -FROM node:20.8.1-alpine3.17 AS builder +FROM node:20.10.0-alpine3.17 AS builder WORKDIR /otterscan-build -COPY ["package.json", "package-lock.json", "/otterscan-build/"] -RUN npm ci -COPY ["run-nginx.sh", "tsconfig.json", "tsconfig.node.json", "postcss.config.js", "tailwind.config.js", "vite.config.ts", "index.html", "/otterscan-build/"] -COPY ["public", "/otterscan-build/public/"] -COPY ["src", "/otterscan-build/src/"] +COPY --link ["package.json", "package-lock.json", "/otterscan-build/"] +RUN npm ci --fetch-timeout 600000 --verbose +COPY --link ["run-nginx.sh", "tsconfig.json", "tsconfig.node.json", "postcss.config.js", "tailwind.config.js", "vite.config.ts", "index.html", "/otterscan-build/"] +COPY --link ["public", "/otterscan-build/public/"] +COPY --link ["src", "/otterscan-build/src/"] RUN npm run build # Add brotli module to official nginx image @@ -71,14 +71,14 @@ RUN set -ex \ && rm -rf /tmp/packages RUN apk update && apk add jq WORKDIR /usr/share/nginx/html/ -COPY --from=otterscan/otterscan-assets:v1.1.1 /usr/share/nginx/html/chains chains/ -COPY --from=otterscan/otterscan-assets:v1.1.1 /usr/share/nginx/html/topic0 topic0/ -COPY --from=otterscan/otterscan-assets:v1.1.1 /usr/share/nginx/html/assets assets/ -COPY --from=otterscan/otterscan-assets:v1.1.1 /usr/share/nginx/html/signatures signatures/ -COPY nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf -COPY nginx/nginx.conf /etc/nginx/nginx.conf -COPY --from=builder /otterscan-build/dist /usr/share/nginx/html/ -COPY --from=builder /otterscan-build/run-nginx.sh / +COPY --link --from=otterscan/otterscan-assets:v1.1.1 /usr/share/nginx/html/chains chains/ +COPY --link --from=otterscan/otterscan-assets:v1.1.1 /usr/share/nginx/html/topic0 topic0/ +COPY --link --from=otterscan/otterscan-assets:v1.1.1 /usr/share/nginx/html/assets assets/ +COPY --link --from=otterscan/otterscan-assets:v1.1.1 /usr/share/nginx/html/signatures signatures/ +COPY --link nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf +COPY --link nginx/nginx.conf /etc/nginx/nginx.conf +COPY --link --from=builder /otterscan-build/dist /usr/share/nginx/html/ +COPY --link --from=builder /otterscan-build/run-nginx.sh / WORKDIR / CMD ["/run-nginx.sh"] diff --git a/README.md b/README.md index 5e29cd97..fb143697 100644 --- a/README.md +++ b/README.md @@ -118,4 +118,6 @@ Follow the creator on Twitter for more updates ([@wmitsuda](https://twitter.com/ ### Donation address -If you like this project, feel free to send donations to `otterscan.eth` or use our gitcoin grant page: https://gitcoin.co/grants/3224/otterscan +If you like this project, feel free to send donations to `otterscan.eth` on any EVM chain (it's an EOA). + +We also participate regularly on Gitcoin Grants rounds. diff --git a/cypress.config.ts b/cypress.config.ts new file mode 100644 index 00000000..4417f9c0 --- /dev/null +++ b/cypress.config.ts @@ -0,0 +1,40 @@ +import { defineConfig } from "cypress"; +import fs from "fs"; + +export default defineConfig({ + e2e: { + projectId: "rypdvn", + setupNodeEvents(on, config) { + on( + "after:spec", + (spec: Cypress.Spec, results: CypressCommandLine.RunResult) => { + if (results && results.video) { + // Do we have failures for any retry attempts? + const failures = results.tests.some((test) => + test.attempts.some((attempt) => attempt.state === "failed"), + ); + if (!failures) { + // delete the video if the spec passed and no tests retried + fs.unlinkSync(results.video); + } + } + }, + ); + on("task", { + // Run cy.task('log', ) to log something to stdout + log(message) { + console.log(message); + return null; + }, + }); + }, + baseUrl: "http://localhost:5173", + // SyntaxHighlighter files may take several seconds to load in dev mode + defaultCommandTimeout: 8_000, + video: true, + env: { + DEVNET_ERIGON_URL: "http://localhost:8545", + DEVNET_SOURCIFY_SOURCE: "http://localhost:7077", + }, + }, +}); diff --git a/cypress/e2e/devnet/spec.cy.ts b/cypress/e2e/devnet/spec.cy.ts new file mode 100644 index 00000000..5e7e50ef --- /dev/null +++ b/cypress/e2e/devnet/spec.cy.ts @@ -0,0 +1,28 @@ +describe("Devnet tests", () => { + beforeEach(() => { + cy.visit("/"); + }); + it("Has a warning header with the chain ID", () => { + cy.get('[data-test="warning-header-network-name"]').contains( + "You are on ChainID: 1337", + ); + }); + it("Can navigate to a transaction's Trace tab and back", () => { + cy.sendTx({ + to: "0x67b1d87101671b127f5f8714789C7192f7ad340e", + }).then(({ txReceipt }) => { + cy.visit("/tx/" + txReceipt.hash); + // Click Trace button and make sure the trace loads + cy.get("a").contains("Trace").click(); + cy.get("span").contains(""); + cy.location("pathname").should( + "equal", + "/tx/" + txReceipt.hash + "/trace", + ); + // Go back to the Overview tab + cy.get("a").contains("Overview").click(); + cy.location("pathname").should("equal", "/tx/" + txReceipt.hash); + cy.get('[data-test="tx-hash"]').contains(txReceipt.hash); + }); + }); +}); diff --git a/cypress/e2e/devnet/verified-contracts.cy.ts b/cypress/e2e/devnet/verified-contracts.cy.ts new file mode 100644 index 00000000..2fdc87b4 --- /dev/null +++ b/cypress/e2e/devnet/verified-contracts.cy.ts @@ -0,0 +1,71 @@ +describe("Read Contract tests", () => { + it("Should add and remove elements from a dynamic array", () => { + // Deploy AllTypes contract + cy.fixture("contracts/AllTypes/bytecode.txt").then((bytecode) => { + cy.sendTx({ data: bytecode.trim() }).then(({ txReceipt }) => { + // TODO: Remove this second transaction when ots_hasCode on the contract creation block is fixed + cy.sendTx({}); + cy.interceptDirectory( + `${Cypress.env("DEVNET_SOURCIFY_SOURCE")}/contracts/full_match/1337/${ + txReceipt.contractAddress + }/`, + "contracts/AllTypes", + ); + + // Visit contract's Read Contract page + cy.visit("/address/" + txReceipt.contractAddress + "/readContract"); + cy.get('[data-test="read-function"]') + .contains("getVariableLengthStringArray") + .parent() + .as("func"); + cy.get("@func").find("input").type("one"); + cy.get("@func").find("button").contains("Add Element").click(); + cy.get("@func").find("input").eq(1).type("two"); + cy.get("@func").find("button").contains("Add Element").click(); + cy.get("@func").find("input").eq(2).type("three"); + + cy.get("@func").find("input").eq(0).should("have.value", "one"); + cy.get("@func").find("input").eq(1).should("have.value", "two"); + cy.get("@func").find("input").eq(2).should("have.value", "three"); + + // Remove the 2nd element + cy.get("@func") + .find("[data-test='remove-array-element']") + .eq(1) + .click(); + cy.get("@func").find("input").eq(0).should("have.value", "one"); + cy.get("@func").find("input").eq(1).should("have.value", "three"); + + // Add another array element + cy.get("@func").find("button").contains("Add Element").click(); + cy.get("@func").find("input").eq(2).type("new"); + + cy.get("@func").find("input").eq(0).should("have.value", "one"); + cy.get("@func").find("input").eq(1).should("have.value", "three"); + cy.get("@func").find("input").eq(2).should("have.value", "new"); + + // Remove the 1st element + cy.get("@func") + .find("[data-test='remove-array-element']") + .eq(0) + .click(); + cy.get("@func").find("input").eq(0).should("have.value", "three"); + cy.get("@func").find("input").eq(1).should("have.value", "new"); + + // Query + cy.get("@func").find("button").contains("Query").click(); + + cy.get("@func") + .contains("ret_0 [0]") + .parents("tr") + .eq(0) + .contains("three"); + cy.get("@func") + .contains("ret_0 [1]") + .parents("tr") + .eq(0) + .contains("new"); + }); + }); + }); +}); diff --git a/cypress/e2e/mainnet/smoketests.cy.ts b/cypress/e2e/mainnet/smoketests.cy.ts new file mode 100644 index 00000000..2763f980 --- /dev/null +++ b/cypress/e2e/mainnet/smoketests.cy.ts @@ -0,0 +1,70 @@ +describe("Basic navigation", () => { + it("Should load vitalik.eth address", () => { + // From the home page, go to vitalik.eth address page, expect it finds it + cy.visit("/"); + cy.get('[data-test="home-search-input"]').type(`vitalik.eth{enter}`); + + cy.get('[data-test="address"]', { timeout: 15_000 }).contains( + "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045", + ); + + // Go to last page, check if it has a full 25 entries page + cy.get('[data-test="nav-last"]').first().click(); + cy.get('[data-test="page-count"]') + .first() + .invoke("text") + .should("equal", "25"); + + // Examine the first transaction hash + cy.get('[data-test="tx-hash"]') + .first() + .invoke("text") + .should( + "equal", + "0x32e725433af17709360462be3ee194bba4994650fe697b5677339531a5db99a9", + ); + + // Go back 2 pages + cy.get('[data-test="nav-prev"]').first().click(); + cy.get('[data-test="tx-hash"]') + .first() + .invoke("text") + .should( + "equal", + "0x012616c16fc2dbffe6dfba0f450aca81624743a684e176cea208e499a1af9b62", + ); + + cy.get('[data-test="nav-prev"]').first().click(); + cy.get('[data-test="tx-hash"]') + .first() + .invoke("text") + .should( + "equal", + "0x64426b39b22e76b9679c86292d16e1ca1f68a144a9029ec49efdae1f900db8d8", + ); + + // Go forward 1 page (test forward is working) + cy.get('[data-test="nav-next"]').first().click(); + cy.get('[data-test="tx-hash"]') + .first() + .invoke("text") + .should( + "equal", + "0x012616c16fc2dbffe6dfba0f450aca81624743a684e176cea208e499a1af9b62", + ); + + // Click second tx, open tx page + cy.get('[data-test="tx-hash"]').eq(1).click(); + cy.location("pathname").should( + "equal", + "/tx/0x9b8964cd49910fd7494fb8359912b8925bf7417126a3e5a0a3f69e0166ad437e", + ); + cy.get('[data-test="tx-hash"]') + .invoke("text") + .should( + "equal", + "0x9b8964cd49910fd7494fb8359912b8925bf7417126a3e5a0a3f69e0166ad437e", + ); + cy.get('[data-test="status"]').invoke("text").should("equal", "Success"); + }); +}); diff --git a/cypress/e2e/mainnet/spec.cy.ts b/cypress/e2e/mainnet/spec.cy.ts new file mode 100644 index 00000000..02ee96fb --- /dev/null +++ b/cypress/e2e/mainnet/spec.cy.ts @@ -0,0 +1,10 @@ +describe("Direct navigation by URL", () => { + it("Loads a block page by hash", () => { + cy.visit( + "/block/0xaf53d2fe59e1c849f157be75e2b47b4f8b4d551e55ed27d98ec58eee420df3a7", + ); + cy.get('[data-test="block-height-text"]', { timeout: 10000 }).contains( + `18,600,400`, + ); + }); +}); diff --git a/cypress/e2e/mainnet/verified-contracts.cy.ts b/cypress/e2e/mainnet/verified-contracts.cy.ts new file mode 100644 index 00000000..8366e209 --- /dev/null +++ b/cypress/e2e/mainnet/verified-contracts.cy.ts @@ -0,0 +1,103 @@ +describe("Read Contract tests", () => { + it("Should get a correct response with array input", () => { + cy.visit( + "/address/0x536384FCd25b576265B6775F383D5ac408FF9dB7/readContract", + ); + cy.get('[data-test="read-function"]') + .contains("getAddressForCounterfactualWallet") + .parent() + .as("func"); + cy.get("@func") + .find("input") + .eq(0) + .type("0x0000000000000000000000000000000000000001"); + cy.get("@func") + .find("input") + .eq(1) + .type("0x0000000000000000000000000000000000000005"); + cy.get("@func").find("button").contains("Add Element").click(); + cy.get("@func") + .find("input") + .eq(2) + .type("0x0000000000000000000000000000000000000006"); + cy.get("@func").find("button").contains("Add Element").click(); + cy.get("@func") + .find("input") + .eq(3) + .type("0x0000000000000000000000000000000000000007"); + + cy.get("@func") + .find("input") + .eq(1) + .should("have.value", "0x0000000000000000000000000000000000000005"); + cy.get("@func") + .find("input") + .eq(2) + .should("have.value", "0x0000000000000000000000000000000000000006"); + cy.get("@func") + .find("input") + .eq(3) + .should("have.value", "0x0000000000000000000000000000000000000007"); + + // Remove the 2nd element + cy.get("@func").find("[data-test='remove-array-element']").eq(1).click(); + cy.get("@func") + .find("input") + .eq(1) + .should("have.value", "0x0000000000000000000000000000000000000005"); + cy.get("@func") + .find("input") + .eq(2) + .should("have.value", "0x0000000000000000000000000000000000000007"); + + // Add another array element + cy.get("@func").find("button").contains("Add Element").click(); + cy.get("@func") + .find("input") + .eq(3) + .type("0x0000000000000000000000000000000000000008"); + + cy.get("@func") + .find("input") + .eq(1) + .should("have.value", "0x0000000000000000000000000000000000000005"); + cy.get("@func") + .find("input") + .eq(2) + .should("have.value", "0x0000000000000000000000000000000000000007"); + cy.get("@func") + .find("input") + .eq(3) + .should("have.value", "0x0000000000000000000000000000000000000008"); + + // Remove the 1st element + cy.get("@func").find("[data-test='remove-array-element']").eq(0).click(); + cy.get("@func") + .find("input") + .eq(1) + .should("have.value", "0x0000000000000000000000000000000000000007"); + cy.get("@func") + .find("input") + .eq(2) + .should("have.value", "0x0000000000000000000000000000000000000008"); + + // Add other inputs + cy.get("@func") + .find("input") + .eq(3) + .type("0x0000000000000000000000000000000000000002"); + cy.get("@func") + .find("input") + .eq(4) + .type("0x0000000000000000000000000000000000000000"); + + // Query + cy.get("@func").find("button").contains("Query").click(); + + cy.get("@func") + .contains("_wallet") + .parents("tr") + .eq(0) + .contains("0x296d1362694fA673719D6F5dD6521c019ed1978C"); + }); +}); diff --git a/cypress/e2e/spec.cy.ts b/cypress/e2e/spec.cy.ts new file mode 100644 index 00000000..04d59f64 --- /dev/null +++ b/cypress/e2e/spec.cy.ts @@ -0,0 +1,17 @@ +describe("Home and navigation", () => { + beforeEach(() => { + cy.visit("/"); + }); + it("Loads the logo text", () => { + cy.get('[data-test="logotext"]').contains("Otterscan"); + }); + it("Searches by block number", () => { + const blockNumber = "10"; + cy.get('[data-test="home-search-input"]').type(`${blockNumber}{enter}`); + cy.url().should("include", `/block/${blockNumber}`); + cy.get('[data-test="block-number"]').contains(`#${blockNumber}`); + }); + it("Loads the latest block via useLatestBlockHeader and displays it on the home page", () => { + cy.get('[data-test="home-latest-block-header"]', { timeout: 10000 }); + }); +}); diff --git a/cypress/fixtures/contracts/AllTypes/bytecode.txt b/cypress/fixtures/contracts/AllTypes/bytecode.txt new file mode 100644 index 00000000..60e04b2e --- /dev/null +++ b/cypress/fixtures/contracts/AllTypes/bytecode.txt @@ -0,0 +1 @@ +0x608060405234801561001057600080fd5b50611784806100206000396000f3fe608060405234801561001057600080fd5b50600436106100ea5760003560e01c806382abdced1161008c578063a2050af811610066578063a2050af8146102d2578063a6ed563e14610303578063ae22c57d14610333578063c946bf4c14610363576100ea565b806382abdced1461024157806382d696a1146102715780639c981fcb146102a1576100ea565b80634d507192116100c85780634d5071921461017f5780636168d817146101b05780636689e498146101e0578063781c6dbe14610210576100ea565b80631e553250146100ef5780633740774b1461011f578063441abbac1461014f575b600080fd5b61010960048036038101906101049190610497565b610393565b60405161011691906104d3565b60405180910390f35b61013960048036038101906101349190610527565b61039d565b6040516101469190610563565b60405180910390f35b610169600480360381019061016491906105b4565b6103a7565b60405161017691906105f0565b60405180910390f35b61019960048036038101906101949190610670565b6103b1565b6040516101a7929190611044565b60405180910390f35b6101ca60048036038101906101c59190611068565b6103c1565b6040516101d791906110a4565b60405180910390f35b6101fa60048036038101906101f591906110bf565b6103cb565b60405161020791906110fb565b60405180910390f35b61022a6004803603810190610225919061116c565b6103d5565b6040516102389291906111f7565b60405180910390f35b61025b6004803603810190610256919061123d565b6103e5565b604051610268919061130e565b60405180910390f35b61028b60048036038101906102869190611330565b6103ee565b604051610298919061136c565b60405180910390f35b6102bb60048036038101906102b691906113dd565b6103f8565b6040516102c9929190611468565b60405180910390f35b6102ec60048036038101906102e791906114e2565b610408565b6040516102fa9291906115b6565b60405180910390f35b61031d600480360381019061031891906115da565b610418565b60405161032a9190611616565b60405180910390f35b61034d60048036038101906103489190611631565b610422565b60405161035a919061166d565b60405180910390f35b61037d600480360381019061037891906116ac565b61042c565b60405161038a9190611733565b60405180910390f35b6000819050919050565b6000819050919050565b6000819050919050565b3660008383915091509250929050565b6000819050919050565b6000819050919050565b3660008383915091509250929050565b36819050919050565b6000819050919050565b3660008383915091509250929050565b3660008383915091509250929050565b6000819050919050565b6000819050919050565b36819050919050565b600080fd5b600080fd5b60007fff0000000000000000000000000000000000000000000000000000000000000082169050919050565b6104748161043f565b811461047f57600080fd5b50565b6000813590506104918161046b565b92915050565b6000602082840312156104ad576104ac610435565b5b60006104bb84828501610482565b91505092915050565b6104cd8161043f565b82525050565b60006020820190506104e860008301846104c4565b92915050565b600060ff82169050919050565b610504816104ee565b811461050f57600080fd5b50565b600081359050610521816104fb565b92915050565b60006020828403121561053d5761053c610435565b5b600061054b84828501610512565b91505092915050565b61055d816104ee565b82525050565b60006020820190506105786000830184610554565b92915050565b6000819050919050565b6105918161057e565b811461059c57600080fd5b50565b6000813590506105ae81610588565b92915050565b6000602082840312156105ca576105c9610435565b5b60006105d88482850161059f565b91505092915050565b6105ea8161057e565b82525050565b600060208201905061060560008301846105e1565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f8401126106305761062f61060b565b5b8235905067ffffffffffffffff81111561064d5761064c610610565b5b60208301915083602082028301111561066957610668610615565b5b9250929050565b6000806020838503121561068757610686610435565b5b600083013567ffffffffffffffff8111156106a5576106a461043a565b5b6106b18582860161061a565b92509250509250929050565b600082825260208201905092915050565b6000819050919050565b60008115159050919050565b6106ed816106d8565b81146106f857600080fd5b50565b60008135905061070a816106e4565b92915050565b600061071f60208401846106fb565b905092915050565b610730816106d8565b82525050565b60006107456020840184610512565b905092915050565b610756816104ee565b82525050565b600061076b602084018461059f565b905092915050565b61077c8161057e565b82525050565b60008160000b9050919050565b61079881610782565b81146107a357600080fd5b50565b6000813590506107b58161078f565b92915050565b60006107ca60208401846107a6565b905092915050565b6107db81610782565b82525050565b6000819050919050565b6107f4816107e1565b81146107ff57600080fd5b50565b600081359050610811816107eb565b92915050565b60006108266020840184610802565b905092915050565b610837816107e1565b82525050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006108688261083d565b9050919050565b6108788161085d565b811461088357600080fd5b50565b6000813590506108958161086f565b92915050565b60006108aa6020840184610886565b905092915050565b6108bb8161085d565b82525050565b60006108d06020840184610482565b905092915050565b6108e18161043f565b82525050565b6000819050919050565b6108fa816108e7565b811461090557600080fd5b50565b600081359050610917816108f1565b92915050565b600061092c6020840184610908565b905092915050565b61093d816108e7565b82525050565b600080fd5b600080fd5b600080fd5b6000808335600160200384360303811261096f5761096e61094d565b5b83810192508235915060208301925067ffffffffffffffff82111561099757610996610943565b5b6001820236038313156109ad576109ac610948565b5b509250929050565b600082825260208201905092915050565b82818337600083830152505050565b6000601f19601f8301169050919050565b60006109f283856109b5565b93506109ff8385846109c6565b610a08836109d5565b840190509392505050565b60008083356001602003843603038112610a3057610a2f61094d565b5b83810192508235915060208301925067ffffffffffffffff821115610a5857610a57610943565b5b600182023603831315610a6e57610a6d610948565b5b509250929050565b600082825260208201905092915050565b6000610a938385610a76565b9350610aa08385846109c6565b610aa9836109d5565b840190509392505050565b60008083356001602003843603038112610ad157610ad061094d565b5b83810192508235915060208301925067ffffffffffffffff821115610af957610af8610943565b5b602082023603831315610b0f57610b0e610948565b5b509250929050565b600082825260208201905092915050565b6000819050919050565b6000610b3f848484610a87565b90509392505050565b6000602082019050919050565b6000610b618385610b17565b935083602084028501610b7384610b28565b8060005b87811015610bb9578484038952610b8e8284610a13565b610b99868284610b32565b9550610ba484610b48565b935060208b019a505050600181019050610b77565b50829750879450505050509392505050565b600082356001604003833603038112610be757610be661094d565b5b82810191505092915050565b600060029050919050565b600081905092915050565b6000819050919050565b600060029050919050565b600081905092915050565b6000819050919050565b6000602082019050919050565b6000610c4b82610c13565b610c558185610c1e565b935083602082028501610c6785610c29565b8060005b85811015610cad578484038952610c828284610a13565b610c8d868284610b32565b9550610c9884610c33565b935060208b019a505050600181019050610c6b565b50829750879550505050505092915050565b6000610ccb8383610c40565b905092915050565b600082356001604003833603038112610cef57610cee61094d565b5b82810191505092915050565b6000602082019050919050565b6000610d1382610bf3565b610d1d8185610bfe565b935083602082028501610d2f85610c09565b8060005b85811015610d73578484038952610d4a8284610cd3565b610d548582610cbf565b9450610d5f83610cfb565b925060208a01995050600181019050610d33565b50829750879550505050505092915050565b600082905092915050565b60608201610da16000830183610736565b610dae600085018261074d565b50610dbc60208301836108c1565b610dc960208501826108d8565b50610dd7604083018361089b565b610de460408501826108b2565b50505050565b60006101e08301610dfe6000840184610710565b610e0b6000860182610727565b50610e196020840184610736565b610e26602086018261074d565b50610e34604084018461075c565b610e416040860182610773565b50610e4f60608401846107bb565b610e5c60608601826107d2565b50610e6a6080840184610817565b610e77608086018261082e565b50610e8560a084018461089b565b610e9260a08601826108b2565b50610ea060c08401846108c1565b610ead60c08601826108d8565b50610ebb60e084018461091d565b610ec860e0860182610934565b50610ed7610100840184610952565b858303610100870152610eeb8382846109e6565b92505050610efd610120840184610a13565b858303610120870152610f11838284610a87565b92505050610f23610140840184610ab4565b858303610140870152610f37838284610b55565b92505050610f49610160840184610bcb565b848203610160860152610f5c8282610d08565b915050610f6d610180840184610d85565b610f7b610180860182610d90565b508091505092915050565b6000610f928383610dea565b905092915050565b6000823560016101e003833603038112610fb757610fb661094d565b5b82810191505092915050565b6000602082019050919050565b6000610fdc83856106bd565b935083602084028501610fee846106ce565b8060005b878110156110325784840389526110098284610f9a565b6110138582610f86565b945061101e83610fc3565b925060208a01995050600181019050610ff2565b50829750879450505050509392505050565b6000602082019050818103600083015261105f818486610fd0565b90509392505050565b60006020828403121561107e5761107d610435565b5b600061108c848285016106fb565b91505092915050565b61109e816106d8565b82525050565b60006020820190506110b96000830184611095565b92915050565b6000602082840312156110d5576110d4610435565b5b60006110e3848285016107a6565b91505092915050565b6110f581610782565b82525050565b600060208201905061111060008301846110ec565b92915050565b60008083601f84011261112c5761112b61060b565b5b8235905067ffffffffffffffff81111561114957611148610610565b5b60208301915083600182028301111561116557611164610615565b5b9250929050565b6000806020838503121561118357611182610435565b5b600083013567ffffffffffffffff8111156111a1576111a061043a565b5b6111ad85828601611116565b92509250509250929050565b600082825260208201905092915050565b60006111d683856111b9565b93506111e38385846109c6565b6111ec836109d5565b840190509392505050565b600060208201905081810360008301526112128184866111ca565b90509392505050565b60008190508260206002028201111561123757611236610615565b5b92915050565b60006020828403121561125357611252610435565b5b600082013567ffffffffffffffff8111156112715761127061043a565b5b61127d8482850161121b565b91505092915050565b600081905092915050565b600061129c82610bf3565b6112a68185611286565b9350836020820285016112b885610c09565b8060005b858110156112fc5784840389526112d38284610cd3565b6112dd8582610cbf565b94506112e883610cfb565b925060208a019950506001810190506112bc565b50829750879550505050505092915050565b600060208201905081810360008301526113288184611291565b905092915050565b60006020828403121561134657611345610435565b5b600061135484828501610802565b91505092915050565b611366816107e1565b82525050565b6000602082019050611381600083018461135d565b92915050565b60008083601f84011261139d5761139c61060b565b5b8235905067ffffffffffffffff8111156113ba576113b9610610565b5b6020830191508360018202830111156113d6576113d5610615565b5b9250929050565b600080602083850312156113f4576113f3610435565b5b600083013567ffffffffffffffff8111156114125761141161043a565b5b61141e85828601611387565b92509250509250929050565b600082825260208201905092915050565b6000611447838561142a565b93506114548385846109c6565b61145d836109d5565b840190509392505050565b6000602082019050818103600083015261148381848661143b565b90509392505050565b60008083601f8401126114a2576114a161060b565b5b8235905067ffffffffffffffff8111156114bf576114be610610565b5b6020830191508360208202830111156114db576114da610615565b5b9250929050565b600080602083850312156114f9576114f8610435565b5b600083013567ffffffffffffffff8111156115175761151661043a565b5b6115238582860161148c565b92509250509250929050565b600082825260208201905092915050565b600061154c838561152f565b93508360208402850161155e84610b28565b8060005b878110156115a45784840389526115798284610a13565b611584868284610b32565b955061158f84610b48565b935060208b019a505050600181019050611562565b50829750879450505050509392505050565b600060208201905081810360008301526115d1818486611540565b90509392505050565b6000602082840312156115f0576115ef610435565b5b60006115fe84828501610908565b91505092915050565b611610816108e7565b82525050565b600060208201905061162b6000830184611607565b92915050565b60006020828403121561164757611646610435565b5b600061165584828501610886565b91505092915050565b6116678161085d565b82525050565b6000602082019050611682600083018461165e565b92915050565b600080fd5b6000606082840312156116a3576116a2611688565b5b81905092915050565b6000606082840312156116c2576116c1610435565b5b60006116d08482850161168d565b91505092915050565b606082016116ea6000830183610736565b6116f7600085018261074d565b5061170560208301836108c1565b61171260208501826108d8565b50611720604083018361089b565b61172d60408501826108b2565b50505050565b600060608201905061174860008301846116d9565b9291505056fea2646970667358221220fce0a7dcb191d14c3a4e9c9ce570179e21a4078982de09aaefb6d45b10d9cd0264736f6c63430008120033 diff --git a/cypress/fixtures/contracts/AllTypes/metadata.json b/cypress/fixtures/contracts/AllTypes/metadata.json new file mode 100644 index 00000000..479b09be --- /dev/null +++ b/cypress/fixtures/contracts/AllTypes/metadata.json @@ -0,0 +1,406 @@ +{ + "compiler": { "version": "0.8.18+commit.87f61d96" }, + "language": "Solidity", + "output": { + "abi": [ + { + "inputs": [ + { "internalType": "address", "name": "val", "type": "address" } + ], + "name": "getAddress", + "outputs": [ + { "internalType": "address", "name": "", "type": "address" } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { "internalType": "bool", "name": "boolVal", "type": "bool" }, + { "internalType": "uint8", "name": "uint8Val", "type": "uint8" }, + { + "internalType": "uint256", + "name": "uint256Val", + "type": "uint256" + }, + { "internalType": "int8", "name": "int8Val", "type": "int8" }, + { + "internalType": "int256", + "name": "int256Val", + "type": "int256" + }, + { + "internalType": "address", + "name": "addressVal", + "type": "address" + }, + { + "internalType": "bytes1", + "name": "bytes1Val", + "type": "bytes1" + }, + { + "internalType": "bytes32", + "name": "bytes32Val", + "type": "bytes32" + }, + { "internalType": "bytes", "name": "bytesVal", "type": "bytes" }, + { + "internalType": "string", + "name": "stringVal", + "type": "string" + }, + { + "internalType": "string[]", + "name": "varLenStringArray", + "type": "string[]" + }, + { + "internalType": "string[2][2]", + "name": "fixedLenStringArray", + "type": "string[2][2]" + }, + { + "components": [ + { + "internalType": "uint8", + "name": "tinyUint8", + "type": "uint8" + }, + { + "internalType": "bytes1", + "name": "tinyBytes1", + "type": "bytes1" + }, + { + "internalType": "address", + "name": "tinyAddress", + "type": "address" + } + ], + "internalType": "struct TinyTuple", + "name": "tupleVal", + "type": "tuple" + } + ], + "internalType": "struct AllTypeVal[]", + "name": "val", + "type": "tuple[]" + } + ], + "name": "getAllTypeTuple", + "outputs": [ + { + "components": [ + { "internalType": "bool", "name": "boolVal", "type": "bool" }, + { "internalType": "uint8", "name": "uint8Val", "type": "uint8" }, + { + "internalType": "uint256", + "name": "uint256Val", + "type": "uint256" + }, + { "internalType": "int8", "name": "int8Val", "type": "int8" }, + { + "internalType": "int256", + "name": "int256Val", + "type": "int256" + }, + { + "internalType": "address", + "name": "addressVal", + "type": "address" + }, + { + "internalType": "bytes1", + "name": "bytes1Val", + "type": "bytes1" + }, + { + "internalType": "bytes32", + "name": "bytes32Val", + "type": "bytes32" + }, + { "internalType": "bytes", "name": "bytesVal", "type": "bytes" }, + { + "internalType": "string", + "name": "stringVal", + "type": "string" + }, + { + "internalType": "string[]", + "name": "varLenStringArray", + "type": "string[]" + }, + { + "internalType": "string[2][2]", + "name": "fixedLenStringArray", + "type": "string[2][2]" + }, + { + "components": [ + { + "internalType": "uint8", + "name": "tinyUint8", + "type": "uint8" + }, + { + "internalType": "bytes1", + "name": "tinyBytes1", + "type": "bytes1" + }, + { + "internalType": "address", + "name": "tinyAddress", + "type": "address" + } + ], + "internalType": "struct TinyTuple", + "name": "tupleVal", + "type": "tuple" + } + ], + "internalType": "struct AllTypeVal[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [{ "internalType": "bool", "name": "val", "type": "bool" }], + "name": "getBool", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [{ "internalType": "bytes", "name": "val", "type": "bytes" }], + "name": "getBytes", + "outputs": [{ "internalType": "bytes", "name": "", "type": "bytes" }], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes1", "name": "val", "type": "bytes1" } + ], + "name": "getBytes1", + "outputs": [{ "internalType": "bytes1", "name": "", "type": "bytes1" }], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes32", "name": "val", "type": "bytes32" } + ], + "name": "getBytes32", + "outputs": [ + { "internalType": "bytes32", "name": "", "type": "bytes32" } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string[2][2]", + "name": "val", + "type": "string[2][2]" + } + ], + "name": "getFixedLengthStringArray", + "outputs": [ + { "internalType": "string[2][2]", "name": "", "type": "string[2][2]" } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { "internalType": "int256", "name": "val", "type": "int256" } + ], + "name": "getInt256", + "outputs": [{ "internalType": "int256", "name": "", "type": "int256" }], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [{ "internalType": "int8", "name": "val", "type": "int8" }], + "name": "getInt8", + "outputs": [{ "internalType": "int8", "name": "", "type": "int8" }], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { "internalType": "string", "name": "val", "type": "string" } + ], + "name": "getString", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { "internalType": "uint8", "name": "tinyUint8", "type": "uint8" }, + { + "internalType": "bytes1", + "name": "tinyBytes1", + "type": "bytes1" + }, + { + "internalType": "address", + "name": "tinyAddress", + "type": "address" + } + ], + "internalType": "struct TinyTuple", + "name": "val", + "type": "tuple" + } + ], + "name": "getTinyTuple", + "outputs": [ + { + "components": [ + { "internalType": "uint8", "name": "tinyUint8", "type": "uint8" }, + { + "internalType": "bytes1", + "name": "tinyBytes1", + "type": "bytes1" + }, + { + "internalType": "address", + "name": "tinyAddress", + "type": "address" + } + ], + "internalType": "struct TinyTuple", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "val", "type": "uint256" } + ], + "name": "getUint256", + "outputs": [ + { "internalType": "uint256", "name": "", "type": "uint256" } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint8", "name": "val", "type": "uint8" }], + "name": "getUint8", + "outputs": [{ "internalType": "uint8", "name": "", "type": "uint8" }], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { "internalType": "string[]", "name": "val", "type": "string[]" } + ], + "name": "getVariableLengthStringArray", + "outputs": [ + { "internalType": "string[]", "name": "", "type": "string[]" } + ], + "stateMutability": "pure", + "type": "function" + } + ], + "devdoc": { + "details": "Store & retrieve all types", + "kind": "dev", + "methods": { + "getAddress(address)": { + "details": "Store & retrieve an address", + "params": { "val": "Value to return" } + }, + "getAllTypeTuple((bool,uint8,uint256,int8,int256,address,bytes1,bytes32,bytes,string,string[],string[2][2],(uint8,bytes1,address))[])": { + "details": "Store & retrieve a tuple with all types", + "params": { "val": "Value to return" } + }, + "getBool(bool)": { + "details": "Store & retrieve a bool", + "params": { "val": "Value to return" } + }, + "getBytes(bytes)": { + "details": "Store & retrieve a byte array", + "params": { "val": "Value to return" } + }, + "getBytes1(bytes1)": { + "details": "Store & retrieve a bytes1", + "params": { "val": "Value to return" } + }, + "getBytes32(bytes32)": { + "details": "Store & retrieve a bytes32", + "params": { "val": "Value to return" } + }, + "getFixedLengthStringArray(string[2][2])": { + "details": "Store & retrieve a fixed-length string array", + "params": { "val": "Value to return" } + }, + "getInt256(int256)": { + "details": "Store & retrieve an int256", + "params": { "val": "Value to return" } + }, + "getInt8(int8)": { + "details": "Store & retrieve an int8", + "params": { "val": "Value to return" } + }, + "getString(string)": { + "details": "Store & retrieve a string", + "params": { "val": "Value to return" } + }, + "getTinyTuple((uint8,bytes1,address))": { + "details": "Store & retrieve a tuple with fixed-length types", + "params": { "val": "Value to return" } + }, + "getUint256(uint256)": { + "details": "Store & retrieve a uint256", + "params": { "val": "Value to return" } + }, + "getUint8(uint8)": { + "details": "Store & retrieve a uint8", + "params": { "val": "Value to return" } + }, + "getVariableLengthStringArray(string[])": { + "details": "Store & retrieve a variable-length string array", + "params": { "val": "Value to return" } + } + }, + "title": "AllTypes", + "version": 1 + }, + "userdoc": { "kind": "user", "methods": {}, "version": 1 } + }, + "settings": { + "compilationTarget": { "test.sol": "AllTypes" }, + "evmVersion": "paris", + "libraries": {}, + "metadata": { "bytecodeHash": "ipfs" }, + "optimizer": { "enabled": false, "runs": 200 }, + "remappings": [] + }, + "sources": { + "test.sol": { + "keccak256": "0x6557dc50dd96646f758608c668ebe005caab5695e68064fdfd9b5795beff9189", + "license": "GPL-3.0", + "urls": [ + "bzz-raw://057d9e0fe433f0acb411609f9e974f8b6a828932a368077dc2e23a81fbebf2eb", + "dweb:/ipfs/QmTMiFNCi1yoBMZZJ9sgUNAiTCptXaeJnEGz5qN4yFNTEy" + ] + } + }, + "version": 1 +} diff --git a/cypress/fixtures/contracts/AllTypes/sources/test.sol b/cypress/fixtures/contracts/AllTypes/sources/test.sol new file mode 100644 index 00000000..aaf1cba8 --- /dev/null +++ b/cypress/fixtures/contracts/AllTypes/sources/test.sol @@ -0,0 +1,161 @@ +// SPDX-License-Identifier: GPL-3.0 + +pragma solidity >=0.8.2 <0.9.0; + +/** +* @title TinyTuple +* @dev A structure with fixed-length types +*/ +struct TinyTuple { + uint8 tinyUint8; + bytes1 tinyBytes1; + function(uint8) external tinyFunction; +} + +/** + * @title AllTypes + * @dev A structure that has all types + */ +struct AllTypeVal { + bool boolVal; + uint8 uint8Val; + uint256 uint256Val; + int8 int8Val; + int256 int256Val; + address addressVal; + bytes1 bytes1Val; + bytes32 bytes32Val; + function() external functionVal; + bytes bytesVal; + string stringVal; + string[] varLenStringArray; + string[2][2] fixedLenStringArray; + TinyTuple tupleVal; +} + +/** + * @title AllTypes + * @dev Store & retrieve all types + */ +contract AllTypes { + + /** + * @dev Store & retrieve a bool + * @param val Value to return + */ + function getBool(bool val) public pure returns (bool) { + return val; + } + + /** + * @dev Store & retrieve a uint8 + * @param val Value to return + */ + function getUint8(uint8 val) public pure returns (uint8) { + return val; + } + + /** + * @dev Store & retrieve a uint256 + * @param val Value to return + */ + function getUint256(uint256 val) public pure returns (uint256) { + return val; + } + + /** + * @dev Store & retrieve an int8 + * @param val Value to return + */ + function getInt8(int8 val) public pure returns (int8) { + return val; + } + + /** + * @dev Store & retrieve an int256 + * @param val Value to return + */ + function getInt256(int256 val) public pure returns (int256) { + return val; + } + + /** + * @dev Store & retrieve an address + * @param val Value to return + */ + function getAddress(address val) public pure returns (address) { + return val; + } + + /** + * @dev Store & retrieve a bytes1 + * @param val Value to return + */ + function getBytes1(bytes1 val) public pure returns (bytes1) { + return val; + } + + /** + * @dev Store & retrieve a bytes32 + * @param val Value to return + */ + function getBytes32(bytes32 val) public pure returns (bytes32) { + return val; + } + + /** + * @dev Store & retrieve a function + * @param val Value to return + */ + function getFunction(function() external val) public pure returns (function() external) { + return val; + } + + /** + * @dev Store & retrieve a byte array + * @param val Value to return + */ + function getBytes(bytes calldata val) public pure returns (bytes calldata) { + return val; + } + + /** + * @dev Store & retrieve a string + * @param val Value to return + */ + function getString(string calldata val) public pure returns (string calldata) { + return val; + } + + /** + * @dev Store & retrieve a variable-length string array + * @param val Value to return + */ + function getVariableLengthStringArray(string[] calldata val) public pure returns (string[] calldata) { + return val; + } + + /** + * @dev Store & retrieve a fixed-length string array + * @param val Value to return + */ + function getFixedLengthStringArray(string[2][2] calldata val) public pure returns (string[2][2] calldata) { + return val; + } + + /** + * @dev Store & retrieve a tuple with fixed-length types + * @param val Value to return + */ + function getTinyTuple(TinyTuple calldata val) public pure returns (TinyTuple calldata) { + return val; + } + + /** + * @dev Store & retrieve a tuple with all types + * @param val Value to return + */ + function getAllTypeTuple(AllTypeVal calldata val) public pure returns (AllTypeVal calldata) { + return val; + } +} diff --git a/cypress/support/commands.ts b/cypress/support/commands.ts new file mode 100644 index 00000000..2212b009 --- /dev/null +++ b/cypress/support/commands.ts @@ -0,0 +1,52 @@ +/// +import { + TransactionReceipt, + TransactionRequest, + TransactionResponse, + Wallet, + ethers, +} from "ethers"; + +Cypress.Commands.add( + "interceptDirectory", + (baseUrl: string, directory: string) => { + cy.intercept(baseUrl + "**", (req) => { + const filePath = req.url.replace(baseUrl, ""); + req.reply({ + fixture: directory + "/" + filePath, + }); + }); + }, +); + +// Send a transaction using the devnet key +Cypress.Commands.add("sendTx", (txReq) => { + return cy.wrap( + (async () => { + const provider = new ethers.JsonRpcProvider( + Cypress.env("DEVNET_ERIGON_URL"), + ); + const wallet = new ethers.Wallet( + ethers.sha256(ethers.toUtf8Bytes("erigon devnet key")), + provider, + ); + const tx = await wallet.sendTransaction(txReq); + const txReceipt = await tx.wait(); + return { tx, txReceipt, wallet }; + })(), + { timeout: 15_000 }, + ); +}); + +declare global { + namespace Cypress { + interface Chainable { + interceptDirectory(baseUrl: string, directory: string): Chainable; + sendTx(txReq: TransactionRequest): Chainable<{ + tx: TransactionResponse; + txReceipt: TransactionReceipt; + wallet: Wallet; + }>; + } + } +} diff --git a/cypress/support/devnet-config.json b/cypress/support/devnet-config.json new file mode 100644 index 00000000..704efac3 --- /dev/null +++ b/cypress/support/devnet-config.json @@ -0,0 +1,9 @@ +{ + "erigonURL": "http://localhost:8545", + "beaconAPI": "http://localhost:5052", + "assetsURLPrefix": "http://localhost:5175", + "sourcifySources": { + "central_server": "http://localhost:7077", + "ipfs": "http://localhost:7077" + } +} diff --git a/cypress/support/e2e.ts b/cypress/support/e2e.ts new file mode 100644 index 00000000..6a173d6f --- /dev/null +++ b/cypress/support/e2e.ts @@ -0,0 +1,20 @@ +// *********************************************************** +// This example support/e2e.ts is processed and +// loaded automatically before your test files. +// +// This is a great place to put global configuration and +// behavior that modifies Cypress. +// +// You can change the location of this file or turn off +// automatically serving support files with the +// 'supportFile' configuration option. +// +// You can read more here: +// https://on.cypress.io/configuration +// *********************************************************** + +// Import commands.js using ES2015 syntax: +import "./commands"; + +// Alternatively you can use CommonJS syntax: +// require('./commands') diff --git a/cypress/tsconfig.json b/cypress/tsconfig.json new file mode 100644 index 00000000..90a72dea --- /dev/null +++ b/cypress/tsconfig.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "target": "ESNext", + "lib": ["ESNext", "dom"], + "types": ["cypress", "node"], + "baseUrl": "../node_modules", + "moduleResolution": "Node", + }, + "include": ["**/*.ts"], +} diff --git a/docs/ots2.md b/docs/ots2.md index b68836c4..cb8a8e83 100644 --- a/docs/ots2.md +++ b/docs/ots2.md @@ -6,7 +6,7 @@ Be sure to have a working Otterscan/Erigon installation first, following the [in ## Clone and build Erigon + OTS2 support -Checkout the `ots2-alpha2` branch from Erigon repository: https://github.com/ledgerwatch/erigon/tree/ots2-alpha2 +Checkout the `ots2-alpha4` branch from Erigon repository: https://github.com/ledgerwatch/erigon/tree/ots2-alpha4 Build it as usual with `make` command. @@ -49,11 +49,11 @@ Add the `OTS2=true` env variable when starting the docker container. For example, if your docker start command is: ``` -docker run --rm --name otterscan -d -p 5100:80 --env ERIGON_URL="" otterscan/otterscan:v2.1.0 +docker run --rm --name otterscan -d -p 5100:80 --env ERIGON_URL="" otterscan/otterscan:v2.3.0 ``` change it to: ``` -docker run --rm --name otterscan -d -p 5100:80 --env ERIGON_URL="" --env OTS2=true otterscan/otterscan:v2.1.0 +docker run --rm --name otterscan -d -p 5100:80 --env ERIGON_URL="" --env OTS2=true otterscan/otterscan:v2.3.0 ``` diff --git a/docs/testing.md b/docs/testing.md new file mode 100644 index 00000000..94733c0e --- /dev/null +++ b/docs/testing.md @@ -0,0 +1,48 @@ +# Running tests + +## Unit tests +To run the unit tests with Jest, simply run + +```sh +npm run test +``` + +## End-to-end tests +Otterscan uses Cypress as its end-to-end testing framework. You can run the end-to-end tests locally. First, ensure you are running an Otterscan instance on `http://localhost:5173`. Then you can run one of the following commands: + +### Ethereum mainnet +```sh +npm run cy:run-mainnet +``` + +### Erigon devnet +Running the devnet tests requires a custom Otterscan configuration. You can use this command to start Otterscan with the devnet configuration: +```sh +npm run start-devnet +``` +The Otterscan instance should then be pointed to an Erigon devnet running on `http://localhost:8545`. You can start an Erigon devnet with this command: +```sh +./erigon --chain=dev --datadir=dev --http.api eth,erigon,trace,ots,ots2 --http.corsdomain "*" --http.vhosts "*" --mine --fakepow +``` + +(Note: The private key for the funded account can be found with `echo -n "erigon devnet key" | sha256sum`.) + +Run the devnet and common end-to-end tests: +```sh +npm run cy:run-devnet +``` + +## Running GitHub Actions workflows locally +Otterscan uses GitHub Actions as its CI platform and runs several jobs when pull requests are opened or commits are made to the `develop` and `main` branches. + +You can test these locally using [act](https://github.com/nektos/act) with the following command: +```sh +# Ethereum Mainnet Erigon RPC URL +E2E_ERIGON_URL= +# Cypress Cloud record key, if you have one +E2E_CYPRESS_RECORD_KEY= + +act --container-architecture linux/amd64 pull_request -s E2E_ERIGON_URL=$E2E_ERIGON_URL -s E2E_CYPRESS_RECORD_KEY=$E2E_CYPRESS_RECORD_KEY --artifact-server-path /tmp/artifacts +``` + +Screenshots of failed tests will be "uploaded" to `/tmp/artifacts`. diff --git a/index.html b/index.html index 5722f16a..49ce6481 100644 --- a/index.html +++ b/index.html @@ -1,4 +1,4 @@ - + @@ -6,6 +6,7 @@ +