diff --git a/Dockerfile b/Dockerfile index e113ddb..aec42e4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -23,12 +23,74 @@ FROM alpine:3.14.0 AS topic0builder WORKDIR /topic0 COPY topic0/with_parameter_names /topic0/ -FROM nginx:1.21.1-alpine -RUN apk add jq +# Add brotli module to official nginx image +# Based on: https://github.com/nginxinc/docker-nginx/tree/master/modules +FROM nginx:1.21.3-alpine as nginxbuilder + +RUN set -ex \ + && apk update \ + && apk add linux-headers openssl-dev pcre-dev zlib-dev openssl abuild \ + musl-dev libxslt libxml2-utils make mercurial gcc unzip git \ + xz g++ coreutils \ + # allow abuild as a root user \ + && printf "#!/bin/sh\\nSETFATTR=true /usr/bin/abuild -F \"\$@\"\\n" > /usr/local/bin/abuild \ + && chmod +x /usr/local/bin/abuild \ + && hg clone -r ${NGINX_VERSION}-${PKG_RELEASE} https://hg.nginx.org/pkg-oss/ \ + && cd pkg-oss \ + && mkdir /tmp/packages \ + && for module in "brotli"; do \ + echo "Building $module for nginx-$NGINX_VERSION"; \ + if [ -d /modules/$module ]; then \ + echo "Building $module from user-supplied sources"; \ + # check if module sources file is there and not empty + if [ ! -s /modules/$module/source ]; then \ + echo "No source file for $module in modules/$module/source, exiting"; \ + exit 1; \ + fi; \ + # some modules require build dependencies + if [ -f /modules/$module/build-deps ]; then \ + echo "Installing $module build dependencies"; \ + apk update && apk add $(cat /modules/$module/build-deps | xargs); \ + fi; \ + # if a module has a build dependency that is not in a distro, provide a + # shell script to fetch/build/install those + # note that shared libraries produced as a result of this script will + # not be copied from the builder image to the main one so build static + if [ -x /modules/$module/prebuild ]; then \ + echo "Running prebuild script for $module"; \ + /modules/$module/prebuild; \ + fi; \ + /pkg-oss/build_module.sh -v $NGINX_VERSION -f -y -o /tmp/packages -n $module $(cat /modules/$module/source); \ + BUILT_MODULES="$BUILT_MODULES $(echo $module | tr '[A-Z]' '[a-z]' | tr -d '[/_\-\.\t ]')"; \ + elif make -C /pkg-oss/alpine list | grep -E "^$module\s+\d+" > /dev/null; then \ + echo "Building $module from pkg-oss sources"; \ + cd /pkg-oss/alpine; \ + make abuild-module-$module BASE_VERSION=$NGINX_VERSION NGINX_VERSION=$NGINX_VERSION; \ + apk add $(. ./abuild-module-$module/APKBUILD; echo $makedepends;); \ + make module-$module BASE_VERSION=$NGINX_VERSION NGINX_VERSION=$NGINX_VERSION; \ + find ~/packages -type f -name "*.apk" -exec mv -v {} /tmp/packages/ \;; \ + BUILT_MODULES="$BUILT_MODULES $module"; \ + else \ + echo "Don't know how to build $module module, exiting"; \ + exit 1; \ + fi; \ + done \ + && echo "BUILT_MODULES=\"$BUILT_MODULES\"" > /tmp/packages/modules.env + +FROM nginx:1.21.3-alpine +COPY --from=nginxbuilder /tmp/packages /tmp/packages +RUN set -ex \ + && . /tmp/packages/modules.env \ + && for module in $BUILT_MODULES; do \ + apk add --no-cache --allow-untrusted /tmp/packages/nginx-module-${module}-${NGINX_VERSION}*.apk; \ + done \ + && rm -rf /tmp/packages +RUN apk update && apk add jq COPY --from=topic0builder /topic0 /usr/share/nginx/html/topic0/ COPY --from=fourbytesbuilder /signatures /usr/share/nginx/html/signatures/ COPY --from=logobuilder /assets /usr/share/nginx/html/assets/ -COPY nginx.conf /etc/nginx/conf.d/default.conf +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/build /usr/share/nginx/html/ COPY --from=builder /otterscan-build/run-nginx.sh / WORKDIR / diff --git a/nginx.conf b/nginx/conf.d/default.conf similarity index 99% rename from nginx.conf rename to nginx/conf.d/default.conf index 932cfeb..b5d141b 100644 --- a/nginx.conf +++ b/nginx/conf.d/default.conf @@ -2,6 +2,8 @@ server { listen 80; server_name localhost; + gzip_static on; + #access_log /var/log/nginx/host.access.log main; location /static { @@ -115,6 +117,8 @@ server { root /usr/share/nginx/html; index index.html; try_files $uri /index.html; + + brotli_static on; } #error_page 404 /404.html; diff --git a/nginx/nginx.conf b/nginx/nginx.conf new file mode 100644 index 0000000..7364514 --- /dev/null +++ b/nginx/nginx.conf @@ -0,0 +1,32 @@ +user nginx; +worker_processes auto; + +error_log /var/log/nginx/error.log notice; +pid /var/run/nginx.pid; + +load_module modules/ngx_http_brotli_static_module.so; + +events { + worker_connections 1024; +} + + +http { + include /etc/nginx/mime.types; + default_type application/octet-stream; + + log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"'; + + access_log /var/log/nginx/access.log main; + + sendfile on; + #tcp_nopush on; + + keepalive_timeout 65; + + #gzip on; + + include /etc/nginx/conf.d/*.conf; +} diff --git a/package-lock.json b/package-lock.json index 178efba..ef51571 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,7 @@ "dependencies": { "@blackbox-vision/react-qr-reader": "^5.0.0", "@chainlink/contracts": "^0.2.2", - "@craco/craco": "^6.3.0", + "@craco/craco": "^6.4.0", "@fontsource/fira-code": "^4.5.1", "@fontsource/roboto": "^4.5.1", "@fontsource/roboto-mono": "^4.5.0", @@ -27,21 +27,22 @@ "@testing-library/user-event": "^12.1.10", "@types/jest": "^26.0.24", "@types/node": "^14.17.5", - "@types/react": "^17.0.30", + "@types/react": "^17.0.33", "@types/react-blockies": "^1.4.1", - "@types/react-dom": "^17.0.9", + "@types/react-dom": "^17.0.10", "@types/react-highlight": "^0.12.5", - "@types/react-router-dom": "^5.3.1", + "@types/react-router-dom": "^5.3.2", "@types/react-syntax-highlighter": "^13.5.2", "chart.js": "^3.5.1", - "ethers": "^5.4.7", + "ethers": "^5.5.1", "highlightjs-solidity": "^2.0.1", "query-string": "^7.0.1", "react": "^17.0.2", "react-blockies": "^1.4.1", - "react-chartjs-2": "^3.0.5", + "react-chartjs-2": "^3.3.0", "react-dom": "^17.0.2", - "react-error-boundary": "^3.1.3", + "react-error-boundary": "^3.1.4", + "react-helmet-async": "^1.1.2", "react-image": "^4.0.3", "react-router-dom": "^5.3.0", "react-scripts": "4.0.3", @@ -53,6 +54,7 @@ }, "devDependencies": { "autoprefixer": "^9.8.8", + "compress-create-react-app": "^1.1.3", "postcss": "^7.0.39", "source-map-explorer": "^2.5.2", "tailwindcss": "npm:@tailwindcss/postcss7-compat@^2.2.6" @@ -1247,10 +1249,12 @@ } }, "node_modules/@craco/craco": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/@craco/craco/-/craco-6.3.0.tgz", - "integrity": "sha512-SCnfEQxT/6NAbU/3sIWw7gQXtzjjiTp/EZFdJTd8inPURILIy0YajrC2p8qBG2KhFo5cwgOrEDyaGyAFvvuyuA==", + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/@craco/craco/-/craco-6.4.0.tgz", + "integrity": "sha512-puLp+pSL5B2tpoIPUYlWjKd0VDBPNF16BJIKEKrwg0x/9XC/4h8XPcVGNr6pd27pj8sahiH5QUdoBxB5AE9++g==", "dependencies": { + "@endemolshinegroup/cosmiconfig-typescript-loader": "^3.0.2", + "cosmiconfig": "^7.0.1", "cross-spawn": "^7.0.0", "lodash": "^4.17.15", "semver": "^7.3.2", @@ -1266,6 +1270,38 @@ "react-scripts": "^4.0.0" } }, + "node_modules/@craco/craco/node_modules/@endemolshinegroup/cosmiconfig-typescript-loader": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@endemolshinegroup/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-3.0.2.tgz", + "integrity": "sha512-QRVtqJuS1mcT56oHpVegkKBlgtWjXw/gHNWO3eL9oyB5Sc7HBoc2OLG/nYpVfT/Jejvo3NUrD0Udk7XgoyDKkA==", + "dependencies": { + "lodash.get": "^4", + "make-error": "^1", + "ts-node": "^9", + "tslib": "^2" + }, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "cosmiconfig": ">=6" + } + }, + "node_modules/@craco/craco/node_modules/cosmiconfig": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.1.tgz", + "integrity": "sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ==", + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/@craco/craco/node_modules/semver": { "version": "7.3.5", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", @@ -1324,9 +1360,9 @@ } }, "node_modules/@ethersproject/abi": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.4.1.tgz", - "integrity": "sha512-9mhbjUk76BiSluiiW4BaYyI58KSbDMMQpCLdsAR+RsT2GyATiNYxVv+pGWRrekmsIdY3I+hOqsYQSTkc8L/mcg==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.5.0.tgz", + "integrity": "sha512-loW7I4AohP5KycATvc0MgujU6JyCHPqHdeoo9z3Nr9xEiNioxa65ccdm1+fsoJhkuhdRtfcL8cfyGamz2AxZ5w==", "funding": [ { "type": "individual", @@ -1338,21 +1374,21 @@ } ], "dependencies": { - "@ethersproject/address": "^5.4.0", - "@ethersproject/bignumber": "^5.4.0", - "@ethersproject/bytes": "^5.4.0", - "@ethersproject/constants": "^5.4.0", - "@ethersproject/hash": "^5.4.0", - "@ethersproject/keccak256": "^5.4.0", - "@ethersproject/logger": "^5.4.0", - "@ethersproject/properties": "^5.4.0", - "@ethersproject/strings": "^5.4.0" + "@ethersproject/address": "^5.5.0", + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/constants": "^5.5.0", + "@ethersproject/hash": "^5.5.0", + "@ethersproject/keccak256": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/strings": "^5.5.0" } }, "node_modules/@ethersproject/abstract-provider": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.4.1.tgz", - "integrity": "sha512-3EedfKI3LVpjSKgAxoUaI+gB27frKsxzm+r21w9G60Ugk+3wVLQwhi1LsEJAKNV7WoZc8CIpNrATlL1QFABjtQ==", + "version": "5.5.1", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.5.1.tgz", + "integrity": "sha512-m+MA/ful6eKbxpr99xUYeRvLkfnlqzrF8SZ46d/xFB1A7ZVknYc/sXJG0RcufF52Qn2jeFj1hhcoQ7IXjNKUqg==", "funding": [ { "type": "individual", @@ -1364,19 +1400,19 @@ } ], "dependencies": { - "@ethersproject/bignumber": "^5.4.0", - "@ethersproject/bytes": "^5.4.0", - "@ethersproject/logger": "^5.4.0", - "@ethersproject/networks": "^5.4.0", - "@ethersproject/properties": "^5.4.0", - "@ethersproject/transactions": "^5.4.0", - "@ethersproject/web": "^5.4.0" + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/networks": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/transactions": "^5.5.0", + "@ethersproject/web": "^5.5.0" } }, "node_modules/@ethersproject/abstract-signer": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.4.1.tgz", - "integrity": "sha512-SkkFL5HVq1k4/25dM+NWP9MILgohJCgGv5xT5AcRruGz4ILpfHeBtO/y6j+Z3UN/PAjDeb4P7E51Yh8wcGNLGA==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.5.0.tgz", + "integrity": "sha512-lj//7r250MXVLKI7sVarXAbZXbv9P50lgmJQGr2/is82EwEb8r7HrxsmMqAjTsztMYy7ohrIhGMIml+Gx4D3mA==", "funding": [ { "type": "individual", @@ -1388,17 +1424,17 @@ } ], "dependencies": { - "@ethersproject/abstract-provider": "^5.4.0", - "@ethersproject/bignumber": "^5.4.0", - "@ethersproject/bytes": "^5.4.0", - "@ethersproject/logger": "^5.4.0", - "@ethersproject/properties": "^5.4.0" + "@ethersproject/abstract-provider": "^5.5.0", + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0" } }, "node_modules/@ethersproject/address": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.4.0.tgz", - "integrity": "sha512-SD0VgOEkcACEG/C6xavlU1Hy3m5DGSXW3CUHkaaEHbAPPsgi0coP5oNPsxau8eTlZOk/bpa/hKeCNoK5IzVI2Q==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.5.0.tgz", + "integrity": "sha512-l4Nj0eWlTUh6ro5IbPTgbpT4wRbdH5l8CQf7icF7sb/SI3Nhd9Y9HzhonTSTi6CefI0necIw7LJqQPopPLZyWw==", "funding": [ { "type": "individual", @@ -1410,17 +1446,17 @@ } ], "dependencies": { - "@ethersproject/bignumber": "^5.4.0", - "@ethersproject/bytes": "^5.4.0", - "@ethersproject/keccak256": "^5.4.0", - "@ethersproject/logger": "^5.4.0", - "@ethersproject/rlp": "^5.4.0" + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/keccak256": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/rlp": "^5.5.0" } }, "node_modules/@ethersproject/base64": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.4.0.tgz", - "integrity": "sha512-CjQw6E17QDSSC5jiM9YpF7N1aSCHmYGMt9bWD8PWv6YPMxjsys2/Q8xLrROKI3IWJ7sFfZ8B3flKDTM5wlWuZQ==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.5.0.tgz", + "integrity": "sha512-tdayUKhU1ljrlHzEWbStXazDpsx4eg1dBXUSI6+mHlYklOXoXF6lZvw8tnD6oVaWfnMxAgRSKROg3cVKtCcppA==", "funding": [ { "type": "individual", @@ -1432,13 +1468,13 @@ } ], "dependencies": { - "@ethersproject/bytes": "^5.4.0" + "@ethersproject/bytes": "^5.5.0" } }, "node_modules/@ethersproject/basex": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.4.0.tgz", - "integrity": "sha512-J07+QCVJ7np2bcpxydFVf/CuYo9mZ7T73Pe7KQY4c1lRlrixMeblauMxHXD0MPwFmUHZIILDNViVkykFBZylbg==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.5.0.tgz", + "integrity": "sha512-ZIodwhHpVJ0Y3hUCfUucmxKsWQA5TMnavp5j/UOuDdzZWzJlRmuOjcTMIGgHCYuZmHt36BfiSyQPSRskPxbfaQ==", "funding": [ { "type": "individual", @@ -1450,14 +1486,14 @@ } ], "dependencies": { - "@ethersproject/bytes": "^5.4.0", - "@ethersproject/properties": "^5.4.0" + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/properties": "^5.5.0" } }, "node_modules/@ethersproject/bignumber": { - "version": "5.4.2", - "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.4.2.tgz", - "integrity": "sha512-oIBDhsKy5bs7j36JlaTzFgNPaZjiNDOXsdSgSpXRucUl+UA6L/1YLlFeI3cPAoodcenzF4nxNPV13pcy7XbWjA==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.5.0.tgz", + "integrity": "sha512-6Xytlwvy6Rn3U3gKEc1vP7nR92frHkv6wtVr95LFR3jREXiCPzdWxKQ1cx4JGQBXxcguAwjA8murlYN2TSiEbg==", "funding": [ { "type": "individual", @@ -1469,15 +1505,15 @@ } ], "dependencies": { - "@ethersproject/bytes": "^5.4.0", - "@ethersproject/logger": "^5.4.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", "bn.js": "^4.11.9" } }, "node_modules/@ethersproject/bytes": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.4.0.tgz", - "integrity": "sha512-H60ceqgTHbhzOj4uRc/83SCN9d+BSUnOkrr2intevqdtEMO1JFVZ1XL84OEZV+QjV36OaZYxtnt4lGmxcGsPfA==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.5.0.tgz", + "integrity": "sha512-ABvc7BHWhZU9PNM/tANm/Qx4ostPGadAuQzWTr3doklZOhDlmcBqclrQe/ZXUIj3K8wC28oYeuRa+A37tX9kog==", "funding": [ { "type": "individual", @@ -1489,13 +1525,13 @@ } ], "dependencies": { - "@ethersproject/logger": "^5.4.0" + "@ethersproject/logger": "^5.5.0" } }, "node_modules/@ethersproject/constants": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.4.0.tgz", - "integrity": "sha512-tzjn6S7sj9+DIIeKTJLjK9WGN2Tj0P++Z8ONEIlZjyoTkBuODN+0VfhAyYksKi43l1Sx9tX2VlFfzjfmr5Wl3Q==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.5.0.tgz", + "integrity": "sha512-2MsRRVChkvMWR+GyMGY4N1sAX9Mt3J9KykCsgUFd/1mwS0UH1qw+Bv9k1UJb3X3YJYFco9H20pjSlOIfCG5HYQ==", "funding": [ { "type": "individual", @@ -1507,13 +1543,13 @@ } ], "dependencies": { - "@ethersproject/bignumber": "^5.4.0" + "@ethersproject/bignumber": "^5.5.0" } }, "node_modules/@ethersproject/contracts": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.4.1.tgz", - "integrity": "sha512-m+z2ZgPy4pyR15Je//dUaymRUZq5MtDajF6GwFbGAVmKz/RF+DNIPwF0k5qEcL3wPGVqUjFg2/krlCRVTU4T5w==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.5.0.tgz", + "integrity": "sha512-2viY7NzyvJkh+Ug17v7g3/IJC8HqZBDcOjYARZLdzRxrfGlRgmYgl6xPRKVbEzy1dWKw/iv7chDcS83pg6cLxg==", "funding": [ { "type": "individual", @@ -1525,22 +1561,22 @@ } ], "dependencies": { - "@ethersproject/abi": "^5.4.0", - "@ethersproject/abstract-provider": "^5.4.0", - "@ethersproject/abstract-signer": "^5.4.0", - "@ethersproject/address": "^5.4.0", - "@ethersproject/bignumber": "^5.4.0", - "@ethersproject/bytes": "^5.4.0", - "@ethersproject/constants": "^5.4.0", - "@ethersproject/logger": "^5.4.0", - "@ethersproject/properties": "^5.4.0", - "@ethersproject/transactions": "^5.4.0" + "@ethersproject/abi": "^5.5.0", + "@ethersproject/abstract-provider": "^5.5.0", + "@ethersproject/abstract-signer": "^5.5.0", + "@ethersproject/address": "^5.5.0", + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/constants": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/transactions": "^5.5.0" } }, "node_modules/@ethersproject/hash": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.4.0.tgz", - "integrity": "sha512-xymAM9tmikKgbktOCjW60Z5sdouiIIurkZUr9oW5NOex5uwxrbsYG09kb5bMcNjlVeJD3yPivTNzViIs1GCbqA==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.5.0.tgz", + "integrity": "sha512-dnGVpK1WtBjmnp3mUT0PlU2MpapnwWI0PibldQEq1408tQBAbZpPidkWoVVuNMOl/lISO3+4hXZWCL3YV7qzfg==", "funding": [ { "type": "individual", @@ -1552,20 +1588,20 @@ } ], "dependencies": { - "@ethersproject/abstract-signer": "^5.4.0", - "@ethersproject/address": "^5.4.0", - "@ethersproject/bignumber": "^5.4.0", - "@ethersproject/bytes": "^5.4.0", - "@ethersproject/keccak256": "^5.4.0", - "@ethersproject/logger": "^5.4.0", - "@ethersproject/properties": "^5.4.0", - "@ethersproject/strings": "^5.4.0" + "@ethersproject/abstract-signer": "^5.5.0", + "@ethersproject/address": "^5.5.0", + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/keccak256": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/strings": "^5.5.0" } }, "node_modules/@ethersproject/hdnode": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.4.0.tgz", - "integrity": "sha512-pKxdS0KAaeVGfZPp1KOiDLB0jba11tG6OP1u11QnYfb7pXn6IZx0xceqWRr6ygke8+Kw74IpOoSi7/DwANhy8Q==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.5.0.tgz", + "integrity": "sha512-mcSOo9zeUg1L0CoJH7zmxwUG5ggQHU1UrRf8jyTYy6HxdZV+r0PBoL1bxr+JHIPXRzS6u/UW4mEn43y0tmyF8Q==", "funding": [ { "type": "individual", @@ -1577,24 +1613,24 @@ } ], "dependencies": { - "@ethersproject/abstract-signer": "^5.4.0", - "@ethersproject/basex": "^5.4.0", - "@ethersproject/bignumber": "^5.4.0", - "@ethersproject/bytes": "^5.4.0", - "@ethersproject/logger": "^5.4.0", - "@ethersproject/pbkdf2": "^5.4.0", - "@ethersproject/properties": "^5.4.0", - "@ethersproject/sha2": "^5.4.0", - "@ethersproject/signing-key": "^5.4.0", - "@ethersproject/strings": "^5.4.0", - "@ethersproject/transactions": "^5.4.0", - "@ethersproject/wordlists": "^5.4.0" + "@ethersproject/abstract-signer": "^5.5.0", + "@ethersproject/basex": "^5.5.0", + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/pbkdf2": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/sha2": "^5.5.0", + "@ethersproject/signing-key": "^5.5.0", + "@ethersproject/strings": "^5.5.0", + "@ethersproject/transactions": "^5.5.0", + "@ethersproject/wordlists": "^5.5.0" } }, "node_modules/@ethersproject/json-wallets": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.4.0.tgz", - "integrity": "sha512-igWcu3fx4aiczrzEHwG1xJZo9l1cFfQOWzTqwRw/xcvxTk58q4f9M7cjh51EKphMHvrJtcezJ1gf1q1AUOfEQQ==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.5.0.tgz", + "integrity": "sha512-9lA21XQnCdcS72xlBn1jfQdj2A1VUxZzOzi9UkNdnokNKke/9Ya2xA9aIK1SC3PQyBDLt4C+dfps7ULpkvKikQ==", "funding": [ { "type": "individual", @@ -1606,25 +1642,25 @@ } ], "dependencies": { - "@ethersproject/abstract-signer": "^5.4.0", - "@ethersproject/address": "^5.4.0", - "@ethersproject/bytes": "^5.4.0", - "@ethersproject/hdnode": "^5.4.0", - "@ethersproject/keccak256": "^5.4.0", - "@ethersproject/logger": "^5.4.0", - "@ethersproject/pbkdf2": "^5.4.0", - "@ethersproject/properties": "^5.4.0", - "@ethersproject/random": "^5.4.0", - "@ethersproject/strings": "^5.4.0", - "@ethersproject/transactions": "^5.4.0", + "@ethersproject/abstract-signer": "^5.5.0", + "@ethersproject/address": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/hdnode": "^5.5.0", + "@ethersproject/keccak256": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/pbkdf2": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/random": "^5.5.0", + "@ethersproject/strings": "^5.5.0", + "@ethersproject/transactions": "^5.5.0", "aes-js": "3.0.0", "scrypt-js": "3.0.1" } }, "node_modules/@ethersproject/keccak256": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.4.0.tgz", - "integrity": "sha512-FBI1plWet+dPUvAzPAeHzRKiPpETQzqSUWR1wXJGHVWi4i8bOSrpC3NwpkPjgeXG7MnugVc1B42VbfnQikyC/A==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.5.0.tgz", + "integrity": "sha512-5VoFCTjo2rYbBe1l2f4mccaRFN/4VQEYFwwn04aJV2h7qf4ZvI2wFxUE1XOX+snbwCLRzIeikOqtAoPwMza9kg==", "funding": [ { "type": "individual", @@ -1636,14 +1672,14 @@ } ], "dependencies": { - "@ethersproject/bytes": "^5.4.0", - "js-sha3": "0.5.7" + "@ethersproject/bytes": "^5.5.0", + "js-sha3": "0.8.0" } }, "node_modules/@ethersproject/logger": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.4.1.tgz", - "integrity": "sha512-DZ+bRinnYLPw1yAC64oRl0QyVZj43QeHIhVKfD/+YwSz4wsv1pfwb5SOFjz+r710YEWzU6LrhuSjpSO+6PeE4A==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.5.0.tgz", + "integrity": "sha512-rIY/6WPm7T8n3qS2vuHTUBPdXHl+rGxWxW5okDfo9J4Z0+gRRZT0msvUdIJkE4/HS29GUMziwGaaKO2bWONBrg==", "funding": [ { "type": "individual", @@ -1656,9 +1692,9 @@ ] }, "node_modules/@ethersproject/networks": { - "version": "5.4.2", - "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.4.2.tgz", - "integrity": "sha512-eekOhvJyBnuibfJnhtK46b8HimBc5+4gqpvd1/H9LEl7Q7/qhsIhM81dI9Fcnjpk3jB1aTy6bj0hz3cifhNeYw==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.5.0.tgz", + "integrity": "sha512-KWfP3xOnJeF89Uf/FCJdV1a2aDJe5XTN2N52p4fcQ34QhDqQFkgQKZ39VGtiqUgHcLI8DfT0l9azC3KFTunqtA==", "funding": [ { "type": "individual", @@ -1670,13 +1706,13 @@ } ], "dependencies": { - "@ethersproject/logger": "^5.4.0" + "@ethersproject/logger": "^5.5.0" } }, "node_modules/@ethersproject/pbkdf2": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.4.0.tgz", - "integrity": "sha512-x94aIv6tiA04g6BnazZSLoRXqyusawRyZWlUhKip2jvoLpzJuLb//KtMM6PEovE47pMbW+Qe1uw+68ameJjB7g==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.5.0.tgz", + "integrity": "sha512-SaDvQFvXPnz1QGpzr6/HToLifftSXGoXrbpZ6BvoZhmx4bNLHrxDe8MZisuecyOziP1aVEwzC2Hasj+86TgWVg==", "funding": [ { "type": "individual", @@ -1688,14 +1724,14 @@ } ], "dependencies": { - "@ethersproject/bytes": "^5.4.0", - "@ethersproject/sha2": "^5.4.0" + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/sha2": "^5.5.0" } }, "node_modules/@ethersproject/properties": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.4.1.tgz", - "integrity": "sha512-cyCGlF8wWlIZyizsj2PpbJ9I7rIlUAfnHYwy/T90pdkSn/NFTa5YWZx2wTJBe9V7dD65dcrrEMisCRUJiq6n3w==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.5.0.tgz", + "integrity": "sha512-l3zRQg3JkD8EL3CPjNK5g7kMx4qSwiR60/uk5IVjd3oq1MZR5qUg40CNOoEJoX5wc3DyY5bt9EbMk86C7x0DNA==", "funding": [ { "type": "individual", @@ -1707,13 +1743,13 @@ } ], "dependencies": { - "@ethersproject/logger": "^5.4.0" + "@ethersproject/logger": "^5.5.0" } }, "node_modules/@ethersproject/providers": { - "version": "5.4.5", - "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.4.5.tgz", - "integrity": "sha512-1GkrvkiAw3Fj28cwi1Sqm8ED1RtERtpdXmRfwIBGmqBSN5MoeRUHuwHPppMtbPayPgpFcvD7/Gdc9doO5fGYgw==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.5.0.tgz", + "integrity": "sha512-xqMbDnS/FPy+J/9mBLKddzyLLAQFjrVff5g00efqxPzcAwXiR+SiCGVy6eJ5iAIirBOATjx7QLhDNPGV+AEQsw==", "funding": [ { "type": "individual", @@ -1725,23 +1761,23 @@ } ], "dependencies": { - "@ethersproject/abstract-provider": "^5.4.0", - "@ethersproject/abstract-signer": "^5.4.0", - "@ethersproject/address": "^5.4.0", - "@ethersproject/basex": "^5.4.0", - "@ethersproject/bignumber": "^5.4.0", - "@ethersproject/bytes": "^5.4.0", - "@ethersproject/constants": "^5.4.0", - "@ethersproject/hash": "^5.4.0", - "@ethersproject/logger": "^5.4.0", - "@ethersproject/networks": "^5.4.0", - "@ethersproject/properties": "^5.4.0", - "@ethersproject/random": "^5.4.0", - "@ethersproject/rlp": "^5.4.0", - "@ethersproject/sha2": "^5.4.0", - "@ethersproject/strings": "^5.4.0", - "@ethersproject/transactions": "^5.4.0", - "@ethersproject/web": "^5.4.0", + "@ethersproject/abstract-provider": "^5.5.0", + "@ethersproject/abstract-signer": "^5.5.0", + "@ethersproject/address": "^5.5.0", + "@ethersproject/basex": "^5.5.0", + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/constants": "^5.5.0", + "@ethersproject/hash": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/networks": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/random": "^5.5.0", + "@ethersproject/rlp": "^5.5.0", + "@ethersproject/sha2": "^5.5.0", + "@ethersproject/strings": "^5.5.0", + "@ethersproject/transactions": "^5.5.0", + "@ethersproject/web": "^5.5.0", "bech32": "1.1.4", "ws": "7.4.6" } @@ -1767,9 +1803,9 @@ } }, "node_modules/@ethersproject/random": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.4.0.tgz", - "integrity": "sha512-pnpWNQlf0VAZDEOVp1rsYQosmv2o0ITS/PecNw+mS2/btF8eYdspkN0vIXrCMtkX09EAh9bdk8GoXmFXM1eAKw==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.5.0.tgz", + "integrity": "sha512-egGYZwZ/YIFKMHcoBUo8t3a8Hb/TKYX8BCBoLjudVCZh892welR3jOxgOmb48xznc9bTcMm7Tpwc1gHC1PFNFQ==", "funding": [ { "type": "individual", @@ -1781,14 +1817,14 @@ } ], "dependencies": { - "@ethersproject/bytes": "^5.4.0", - "@ethersproject/logger": "^5.4.0" + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0" } }, "node_modules/@ethersproject/rlp": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.4.0.tgz", - "integrity": "sha512-0I7MZKfi+T5+G8atId9QaQKHRvvasM/kqLyAH4XxBCBchAooH2EX5rL9kYZWwcm3awYV+XC7VF6nLhfeQFKVPg==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.5.0.tgz", + "integrity": "sha512-hLv8XaQ8PTI9g2RHoQGf/WSxBfTB/NudRacbzdxmst5VHAqd1sMibWG7SENzT5Dj3yZ3kJYx+WiRYEcQTAkcYA==", "funding": [ { "type": "individual", @@ -1800,14 +1836,14 @@ } ], "dependencies": { - "@ethersproject/bytes": "^5.4.0", - "@ethersproject/logger": "^5.4.0" + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0" } }, "node_modules/@ethersproject/sha2": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.4.0.tgz", - "integrity": "sha512-siheo36r1WD7Cy+bDdE1BJ8y0bDtqXCOxRMzPa4bV1TGt/eTUUt03BHoJNB6reWJD8A30E/pdJ8WFkq+/uz4Gg==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.5.0.tgz", + "integrity": "sha512-B5UBoglbCiHamRVPLA110J+2uqsifpZaTmid2/7W5rbtYVz6gus6/hSDieIU/6gaKIDcOj12WnOdiymEUHIAOA==", "funding": [ { "type": "individual", @@ -1819,15 +1855,15 @@ } ], "dependencies": { - "@ethersproject/bytes": "^5.4.0", - "@ethersproject/logger": "^5.4.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", "hash.js": "1.1.7" } }, "node_modules/@ethersproject/signing-key": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.4.0.tgz", - "integrity": "sha512-q8POUeywx6AKg2/jX9qBYZIAmKSB4ubGXdQ88l40hmATj29JnG5pp331nAWwwxPn2Qao4JpWHNZsQN+bPiSW9A==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.5.0.tgz", + "integrity": "sha512-5VmseH7qjtNmDdZBswavhotYbWB0bOwKIlOTSlX14rKn5c11QmJwGt4GHeo7NrL/Ycl7uo9AHvEqs5xZgFBTng==", "funding": [ { "type": "individual", @@ -1839,18 +1875,18 @@ } ], "dependencies": { - "@ethersproject/bytes": "^5.4.0", - "@ethersproject/logger": "^5.4.0", - "@ethersproject/properties": "^5.4.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0", "bn.js": "^4.11.9", "elliptic": "6.5.4", "hash.js": "1.1.7" } }, "node_modules/@ethersproject/solidity": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.4.0.tgz", - "integrity": "sha512-XFQTZ7wFSHOhHcV1DpcWj7VXECEiSrBuv7JErJvB9Uo+KfCdc3QtUZV+Vjh/AAaYgezUEKbCtE6Khjm44seevQ==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.5.0.tgz", + "integrity": "sha512-9NgZs9LhGMj6aCtHXhtmFQ4AN4sth5HuFXVvAQtzmm0jpSCNOTGtrHZJAeYTh7MBjRR8brylWZxBZR9zDStXbw==", "funding": [ { "type": "individual", @@ -1862,17 +1898,18 @@ } ], "dependencies": { - "@ethersproject/bignumber": "^5.4.0", - "@ethersproject/bytes": "^5.4.0", - "@ethersproject/keccak256": "^5.4.0", - "@ethersproject/sha2": "^5.4.0", - "@ethersproject/strings": "^5.4.0" + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/keccak256": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/sha2": "^5.5.0", + "@ethersproject/strings": "^5.5.0" } }, "node_modules/@ethersproject/strings": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.4.0.tgz", - "integrity": "sha512-k/9DkH5UGDhv7aReXLluFG5ExurwtIpUfnDNhQA29w896Dw3i4uDTz01Quaptbks1Uj9kI8wo9tmW73wcIEaWA==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.5.0.tgz", + "integrity": "sha512-9fy3TtF5LrX/wTrBaT8FGE6TDJyVjOvXynXJz5MT5azq+E6D92zuKNx7i29sWW2FjVOaWjAsiZ1ZWznuduTIIQ==", "funding": [ { "type": "individual", @@ -1884,15 +1921,15 @@ } ], "dependencies": { - "@ethersproject/bytes": "^5.4.0", - "@ethersproject/constants": "^5.4.0", - "@ethersproject/logger": "^5.4.0" + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/constants": "^5.5.0", + "@ethersproject/logger": "^5.5.0" } }, "node_modules/@ethersproject/transactions": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.4.0.tgz", - "integrity": "sha512-s3EjZZt7xa4BkLknJZ98QGoIza94rVjaEed0rzZ/jB9WrIuu/1+tjvYCWzVrystXtDswy7TPBeIepyXwSYa4WQ==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.5.0.tgz", + "integrity": "sha512-9RZYSKX26KfzEd/1eqvv8pLauCKzDTub0Ko4LfIgaERvRuwyaNV78mJs7cpIgZaDl6RJui4o49lHwwCM0526zA==", "funding": [ { "type": "individual", @@ -1904,21 +1941,21 @@ } ], "dependencies": { - "@ethersproject/address": "^5.4.0", - "@ethersproject/bignumber": "^5.4.0", - "@ethersproject/bytes": "^5.4.0", - "@ethersproject/constants": "^5.4.0", - "@ethersproject/keccak256": "^5.4.0", - "@ethersproject/logger": "^5.4.0", - "@ethersproject/properties": "^5.4.0", - "@ethersproject/rlp": "^5.4.0", - "@ethersproject/signing-key": "^5.4.0" + "@ethersproject/address": "^5.5.0", + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/constants": "^5.5.0", + "@ethersproject/keccak256": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/rlp": "^5.5.0", + "@ethersproject/signing-key": "^5.5.0" } }, "node_modules/@ethersproject/units": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.4.0.tgz", - "integrity": "sha512-Z88krX40KCp+JqPCP5oPv5p750g+uU6gopDYRTBGcDvOASh6qhiEYCRatuM/suC4S2XW9Zz90QI35MfSrTIaFg==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.5.0.tgz", + "integrity": "sha512-7+DpjiZk4v6wrikj+TCyWWa9dXLNU73tSTa7n0TSJDxkYbV3Yf1eRh9ToMLlZtuctNYu9RDNNy2USq3AdqSbag==", "funding": [ { "type": "individual", @@ -1930,15 +1967,15 @@ } ], "dependencies": { - "@ethersproject/bignumber": "^5.4.0", - "@ethersproject/constants": "^5.4.0", - "@ethersproject/logger": "^5.4.0" + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/constants": "^5.5.0", + "@ethersproject/logger": "^5.5.0" } }, "node_modules/@ethersproject/wallet": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.4.0.tgz", - "integrity": "sha512-wU29majLjM6AjCjpat21mPPviG+EpK7wY1+jzKD0fg3ui5fgedf2zEu1RDgpfIMsfn8fJHJuzM4zXZ2+hSHaSQ==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.5.0.tgz", + "integrity": "sha512-Mlu13hIctSYaZmUOo7r2PhNSd8eaMPVXe1wxrz4w4FCE4tDYBywDH+bAR1Xz2ADyXGwqYMwstzTrtUVIsKDO0Q==", "funding": [ { "type": "individual", @@ -1950,27 +1987,27 @@ } ], "dependencies": { - "@ethersproject/abstract-provider": "^5.4.0", - "@ethersproject/abstract-signer": "^5.4.0", - "@ethersproject/address": "^5.4.0", - "@ethersproject/bignumber": "^5.4.0", - "@ethersproject/bytes": "^5.4.0", - "@ethersproject/hash": "^5.4.0", - "@ethersproject/hdnode": "^5.4.0", - "@ethersproject/json-wallets": "^5.4.0", - "@ethersproject/keccak256": "^5.4.0", - "@ethersproject/logger": "^5.4.0", - "@ethersproject/properties": "^5.4.0", - "@ethersproject/random": "^5.4.0", - "@ethersproject/signing-key": "^5.4.0", - "@ethersproject/transactions": "^5.4.0", - "@ethersproject/wordlists": "^5.4.0" + "@ethersproject/abstract-provider": "^5.5.0", + "@ethersproject/abstract-signer": "^5.5.0", + "@ethersproject/address": "^5.5.0", + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/hash": "^5.5.0", + "@ethersproject/hdnode": "^5.5.0", + "@ethersproject/json-wallets": "^5.5.0", + "@ethersproject/keccak256": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/random": "^5.5.0", + "@ethersproject/signing-key": "^5.5.0", + "@ethersproject/transactions": "^5.5.0", + "@ethersproject/wordlists": "^5.5.0" } }, "node_modules/@ethersproject/web": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.4.0.tgz", - "integrity": "sha512-1bUusGmcoRLYgMn6c1BLk1tOKUIFuTg8j+6N8lYlbMpDesnle+i3pGSagGNvwjaiLo4Y5gBibwctpPRmjrh4Og==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.5.0.tgz", + "integrity": "sha512-BEgY0eL5oH4mAo37TNYVrFeHsIXLRxggCRG/ksRIxI2X5uj5IsjGmcNiRN/VirQOlBxcUhCgHhaDLG4m6XAVoA==", "funding": [ { "type": "individual", @@ -1982,17 +2019,17 @@ } ], "dependencies": { - "@ethersproject/base64": "^5.4.0", - "@ethersproject/bytes": "^5.4.0", - "@ethersproject/logger": "^5.4.0", - "@ethersproject/properties": "^5.4.0", - "@ethersproject/strings": "^5.4.0" + "@ethersproject/base64": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/strings": "^5.5.0" } }, "node_modules/@ethersproject/wordlists": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.4.0.tgz", - "integrity": "sha512-FemEkf6a+EBKEPxlzeVgUaVSodU7G0Na89jqKjmWMlDB0tomoU8RlEMgUvXyqtrg8N4cwpLh8nyRnm1Nay1isA==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.5.0.tgz", + "integrity": "sha512-bL0UTReWDiaQJJYOC9sh/XcRu/9i2jMrzf8VLRmPKx58ckSlOJiohODkECCO50dtLZHcGU6MLXQ4OOrgBwP77Q==", "funding": [ { "type": "individual", @@ -2004,11 +2041,11 @@ } ], "dependencies": { - "@ethersproject/bytes": "^5.4.0", - "@ethersproject/hash": "^5.4.0", - "@ethersproject/logger": "^5.4.0", - "@ethersproject/properties": "^5.4.0", - "@ethersproject/strings": "^5.4.0" + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/hash": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/strings": "^5.5.0" } }, "node_modules/@fontsource/fira-code": { @@ -3090,9 +3127,9 @@ "license": "MIT" }, "node_modules/@types/react": { - "version": "17.0.30", - "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.30.tgz", - "integrity": "sha512-3Dt/A8gd3TCXi2aRe84y7cK1K8G+N9CZRDG8kDGguOKa0kf/ZkSwTmVIDPsm/KbQOVMaDJXwhBtuOXxqwdpWVg==", + "version": "17.0.33", + "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.33.tgz", + "integrity": "sha512-pLWntxXpDPaU+RTAuSGWGSEL2FRTNyRQOjSWDke/rxRg14ncsZvx8AKWMWZqvc1UOaJIAoObdZhAWvRaHFi5rw==", "dependencies": { "@types/prop-types": "*", "@types/scheduler": "*", @@ -3108,9 +3145,9 @@ } }, "node_modules/@types/react-dom": { - "version": "17.0.9", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.9.tgz", - "integrity": "sha512-wIvGxLfgpVDSAMH5utdL9Ngm5Owu0VsGmldro3ORLXV8CShrL8awVj06NuEXFQ5xyaYfdca7Sgbk/50Ri1GdPg==", + "version": "17.0.10", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.10.tgz", + "integrity": "sha512-8oz3NAUId2z/zQdFI09IMhQPNgIbiP8Lslhv39DIDamr846/0spjZK0vnrMak0iB8EKb9QFTTIdg2Wj2zH5a3g==", "dependencies": { "@types/react": "*" } @@ -3133,9 +3170,9 @@ } }, "node_modules/@types/react-router-dom": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/@types/react-router-dom/-/react-router-dom-5.3.1.tgz", - "integrity": "sha512-UvyRy73318QI83haXlaMwmklHHzV9hjl3u71MmM6wYNu0hOVk9NLTa0vGukf8zXUqnwz4O06ig876YSPpeK28A==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/@types/react-router-dom/-/react-router-dom-5.3.2.tgz", + "integrity": "sha512-ELEYRUie2czuJzaZ5+ziIp9Hhw+juEw8b7C11YNA4QdLCVbQ3qLi2l4aq8XnlqM7V31LZX8dxUuFUCrzHm6sqQ==", "dependencies": { "@types/history": "*", "@types/react": "*", @@ -3910,6 +3947,15 @@ "node": ">=0.10.0" } }, + "node_modules/app-root-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/app-root-path/-/app-root-path-3.0.0.tgz", + "integrity": "sha512-qMcx+Gy2UZynHjOHOIXPNvpf+9cjvk3cWrBBK7zg4gH9+clobJRb9NGzcT7mQTcV/6Gm/1WelUtqxVXnNlrwcw==", + "dev": true, + "engines": { + "node": ">= 6.0.0" + } + }, "node_modules/aproba": { "version": "1.2.0", "license": "ISC" @@ -5969,6 +6015,19 @@ "arity-n": "^1.0.4" } }, + "node_modules/compress-create-react-app": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/compress-create-react-app/-/compress-create-react-app-1.1.3.tgz", + "integrity": "sha512-3HCWi9q7TqxBvklmJY/Pm96Fs8wqEXxduW3LGlK0PUYuezZwKkjB454GjyGhjKmxKpl91Q9b2+ZjXeKdNOIhlA==", + "dev": true, + "dependencies": { + "app-root-path": "^3.0.0" + }, + "bin": { + "compress-cra": "index.js", + "compress-create-react-app": "index.js" + } + }, "node_modules/compressible": { "version": "2.0.18", "license": "MIT", @@ -6228,6 +6287,11 @@ "sha.js": "^2.4.8" } }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==" + }, "node_modules/cross-spawn": { "version": "7.0.3", "license": "MIT", @@ -6960,6 +7024,14 @@ "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", "dev": true }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "engines": { + "node": ">=0.3.1" + } + }, "node_modules/diff-sequences": { "version": "26.6.2", "license": "MIT", @@ -8125,9 +8197,9 @@ } }, "node_modules/ethers": { - "version": "5.4.7", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.4.7.tgz", - "integrity": "sha512-iZc5p2nqfWK1sj8RabwsPM28cr37Bpq7ehTQ5rWExBr2Y09Sn1lDKZOED26n+TsZMye7Y6mIgQ/1cwpSD8XZew==", + "version": "5.5.1", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.5.1.tgz", + "integrity": "sha512-RodEvUFZI+EmFcE6bwkuJqpCYHazdzeR1nMzg+YWQSmQEsNtfl1KHGfp/FWZYl48bI/g7cgBeP2IlPthjiVngw==", "funding": [ { "type": "individual", @@ -8139,36 +8211,36 @@ } ], "dependencies": { - "@ethersproject/abi": "5.4.1", - "@ethersproject/abstract-provider": "5.4.1", - "@ethersproject/abstract-signer": "5.4.1", - "@ethersproject/address": "5.4.0", - "@ethersproject/base64": "5.4.0", - "@ethersproject/basex": "5.4.0", - "@ethersproject/bignumber": "5.4.2", - "@ethersproject/bytes": "5.4.0", - "@ethersproject/constants": "5.4.0", - "@ethersproject/contracts": "5.4.1", - "@ethersproject/hash": "5.4.0", - "@ethersproject/hdnode": "5.4.0", - "@ethersproject/json-wallets": "5.4.0", - "@ethersproject/keccak256": "5.4.0", - "@ethersproject/logger": "5.4.1", - "@ethersproject/networks": "5.4.2", - "@ethersproject/pbkdf2": "5.4.0", - "@ethersproject/properties": "5.4.1", - "@ethersproject/providers": "5.4.5", - "@ethersproject/random": "5.4.0", - "@ethersproject/rlp": "5.4.0", - "@ethersproject/sha2": "5.4.0", - "@ethersproject/signing-key": "5.4.0", - "@ethersproject/solidity": "5.4.0", - "@ethersproject/strings": "5.4.0", - "@ethersproject/transactions": "5.4.0", - "@ethersproject/units": "5.4.0", - "@ethersproject/wallet": "5.4.0", - "@ethersproject/web": "5.4.0", - "@ethersproject/wordlists": "5.4.0" + "@ethersproject/abi": "5.5.0", + "@ethersproject/abstract-provider": "5.5.1", + "@ethersproject/abstract-signer": "5.5.0", + "@ethersproject/address": "5.5.0", + "@ethersproject/base64": "5.5.0", + "@ethersproject/basex": "5.5.0", + "@ethersproject/bignumber": "5.5.0", + "@ethersproject/bytes": "5.5.0", + "@ethersproject/constants": "5.5.0", + "@ethersproject/contracts": "5.5.0", + "@ethersproject/hash": "5.5.0", + "@ethersproject/hdnode": "5.5.0", + "@ethersproject/json-wallets": "5.5.0", + "@ethersproject/keccak256": "5.5.0", + "@ethersproject/logger": "5.5.0", + "@ethersproject/networks": "5.5.0", + "@ethersproject/pbkdf2": "5.5.0", + "@ethersproject/properties": "5.5.0", + "@ethersproject/providers": "5.5.0", + "@ethersproject/random": "5.5.0", + "@ethersproject/rlp": "5.5.0", + "@ethersproject/sha2": "5.5.0", + "@ethersproject/signing-key": "5.5.0", + "@ethersproject/solidity": "5.5.0", + "@ethersproject/strings": "5.5.0", + "@ethersproject/transactions": "5.5.0", + "@ethersproject/units": "5.5.0", + "@ethersproject/wallet": "5.5.0", + "@ethersproject/web": "5.5.0", + "@ethersproject/wordlists": "5.5.0" } }, "node_modules/eventemitter3": { @@ -9805,6 +9877,14 @@ "node": ">= 0.4" } }, + "node_modules/invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "dependencies": { + "loose-envify": "^1.0.0" + } + }, "node_modules/ip": { "version": "1.1.5", "license": "MIT" @@ -11014,9 +11094,9 @@ } }, "node_modules/js-sha3": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz", - "integrity": "sha1-DU/9gALVMzqrr0oj7tL2N0yfKOc=" + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", + "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==" }, "node_modules/js-tokens": { "version": "4.0.0", @@ -11364,6 +11444,11 @@ "version": "3.0.0", "license": "MIT" }, + "node_modules/lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=" + }, "node_modules/lodash.memoize": { "version": "4.1.2", "license": "MIT" @@ -11488,6 +11573,11 @@ "semver": "bin/semver.js" } }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" + }, "node_modules/makeerror": { "version": "1.0.11", "license": "BSD-3-Clause", @@ -14386,12 +14476,9 @@ } }, "node_modules/react-chartjs-2": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/react-chartjs-2/-/react-chartjs-2-3.0.5.tgz", - "integrity": "sha512-fYr4E82agaZi9IFMe5GtOZ6WE/HWdxy/KywLNOzXsqgPkD2oo1IlrQLKMLUki/2UXko3p95TR2L8Q2rEss/opQ==", - "dependencies": { - "lodash": "^4.17.19" - }, + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/react-chartjs-2/-/react-chartjs-2-3.3.0.tgz", + "integrity": "sha512-4Mt0SR2aiUbWi/4762odRBYSnbNKSs4HWc0o3IW43py5bMfmfpeZU95w6mbvtuLZH/M3GsPJMU8DvDc+5U9blQ==", "peerDependencies": { "chart.js": "^3.5.0", "react": "^16.8.0 || ^17.0.0" @@ -14534,9 +14621,9 @@ } }, "node_modules/react-error-boundary": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/react-error-boundary/-/react-error-boundary-3.1.3.tgz", - "integrity": "sha512-A+F9HHy9fvt9t8SNDlonq01prnU8AmkjvGKV4kk8seB9kU3xMEO8J/PQlLVmoOIDODl5U2kufSBs4vrWIqhsAA==", + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/react-error-boundary/-/react-error-boundary-3.1.4.tgz", + "integrity": "sha512-uM9uPzZJTF6wRQORmSrvOIgt4lJ9MC1sNgEOj2XGsDTRE4kmpWxg7ENK9EWNKJRMAOY9z0MuF4yIfl6gp4sotA==", "dependencies": { "@babel/runtime": "^7.12.5" }, @@ -14552,6 +14639,27 @@ "version": "6.0.9", "license": "MIT" }, + "node_modules/react-fast-compare": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.0.tgz", + "integrity": "sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA==" + }, + "node_modules/react-helmet-async": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/react-helmet-async/-/react-helmet-async-1.1.2.tgz", + "integrity": "sha512-LTTzDDkyIleT/JJ6T/uqx7Y8qi1EuPPSiJawQY/nHHz0h7SPDT6HxP1YDDQx/fzcVxCqpWEEMS3QdrSrNkJYhg==", + "dependencies": { + "@babel/runtime": "^7.12.5", + "invariant": "^2.2.4", + "prop-types": "^15.7.2", + "react-fast-compare": "^3.2.0", + "shallowequal": "^1.1.0" + }, + "peerDependencies": { + "react": "^16.6.0 || ^17.0.0", + "react-dom": "^16.6.0 || ^17.0.0" + } + }, "node_modules/react-image": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/react-image/-/react-image-4.0.3.tgz", @@ -16256,6 +16364,11 @@ "sha.js": "bin.js" } }, + "node_modules/shallowequal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", + "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==" + }, "node_modules/shebang-command": { "version": "2.0.0", "license": "MIT", @@ -18049,6 +18162,36 @@ "node": ">=8.0.0" } }, + "node_modules/ts-node": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-9.1.1.tgz", + "integrity": "sha512-hPlt7ZACERQGf03M253ytLY3dHbGNGrAq9qIHWUY9XHYl1z7wYngSr3OQ5xmui8o2AaxsONxIzjafLUiWBo1Fg==", + "dependencies": { + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "source-map-support": "^0.5.17", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "typescript": ">=2.7" + } + }, + "node_modules/ts-node/node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" + }, "node_modules/ts-pnp": { "version": "1.2.0", "license": "MIT", @@ -19645,6 +19788,14 @@ "node": ">=6" } }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "engines": { + "node": ">=6" + } + }, "node_modules/yocto-queue": { "version": "0.1.0", "license": "MIT", @@ -20486,16 +20637,41 @@ } }, "@craco/craco": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/@craco/craco/-/craco-6.3.0.tgz", - "integrity": "sha512-SCnfEQxT/6NAbU/3sIWw7gQXtzjjiTp/EZFdJTd8inPURILIy0YajrC2p8qBG2KhFo5cwgOrEDyaGyAFvvuyuA==", + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/@craco/craco/-/craco-6.4.0.tgz", + "integrity": "sha512-puLp+pSL5B2tpoIPUYlWjKd0VDBPNF16BJIKEKrwg0x/9XC/4h8XPcVGNr6pd27pj8sahiH5QUdoBxB5AE9++g==", "requires": { + "@endemolshinegroup/cosmiconfig-typescript-loader": "^3.0.2", + "cosmiconfig": "^7.0.1", "cross-spawn": "^7.0.0", "lodash": "^4.17.15", "semver": "^7.3.2", "webpack-merge": "^4.2.2" }, "dependencies": { + "@endemolshinegroup/cosmiconfig-typescript-loader": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@endemolshinegroup/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-3.0.2.tgz", + "integrity": "sha512-QRVtqJuS1mcT56oHpVegkKBlgtWjXw/gHNWO3eL9oyB5Sc7HBoc2OLG/nYpVfT/Jejvo3NUrD0Udk7XgoyDKkA==", + "requires": { + "lodash.get": "^4", + "make-error": "^1", + "ts-node": "^9", + "tslib": "^2" + } + }, + "cosmiconfig": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.1.tgz", + "integrity": "sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ==", + "requires": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + } + }, "semver": { "version": "7.3.5", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", @@ -20536,234 +20712,234 @@ } }, "@ethersproject/abi": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.4.1.tgz", - "integrity": "sha512-9mhbjUk76BiSluiiW4BaYyI58KSbDMMQpCLdsAR+RsT2GyATiNYxVv+pGWRrekmsIdY3I+hOqsYQSTkc8L/mcg==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.5.0.tgz", + "integrity": "sha512-loW7I4AohP5KycATvc0MgujU6JyCHPqHdeoo9z3Nr9xEiNioxa65ccdm1+fsoJhkuhdRtfcL8cfyGamz2AxZ5w==", "requires": { - "@ethersproject/address": "^5.4.0", - "@ethersproject/bignumber": "^5.4.0", - "@ethersproject/bytes": "^5.4.0", - "@ethersproject/constants": "^5.4.0", - "@ethersproject/hash": "^5.4.0", - "@ethersproject/keccak256": "^5.4.0", - "@ethersproject/logger": "^5.4.0", - "@ethersproject/properties": "^5.4.0", - "@ethersproject/strings": "^5.4.0" + "@ethersproject/address": "^5.5.0", + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/constants": "^5.5.0", + "@ethersproject/hash": "^5.5.0", + "@ethersproject/keccak256": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/strings": "^5.5.0" } }, "@ethersproject/abstract-provider": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.4.1.tgz", - "integrity": "sha512-3EedfKI3LVpjSKgAxoUaI+gB27frKsxzm+r21w9G60Ugk+3wVLQwhi1LsEJAKNV7WoZc8CIpNrATlL1QFABjtQ==", + "version": "5.5.1", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.5.1.tgz", + "integrity": "sha512-m+MA/ful6eKbxpr99xUYeRvLkfnlqzrF8SZ46d/xFB1A7ZVknYc/sXJG0RcufF52Qn2jeFj1hhcoQ7IXjNKUqg==", "requires": { - "@ethersproject/bignumber": "^5.4.0", - "@ethersproject/bytes": "^5.4.0", - "@ethersproject/logger": "^5.4.0", - "@ethersproject/networks": "^5.4.0", - "@ethersproject/properties": "^5.4.0", - "@ethersproject/transactions": "^5.4.0", - "@ethersproject/web": "^5.4.0" + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/networks": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/transactions": "^5.5.0", + "@ethersproject/web": "^5.5.0" } }, "@ethersproject/abstract-signer": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.4.1.tgz", - "integrity": "sha512-SkkFL5HVq1k4/25dM+NWP9MILgohJCgGv5xT5AcRruGz4ILpfHeBtO/y6j+Z3UN/PAjDeb4P7E51Yh8wcGNLGA==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.5.0.tgz", + "integrity": "sha512-lj//7r250MXVLKI7sVarXAbZXbv9P50lgmJQGr2/is82EwEb8r7HrxsmMqAjTsztMYy7ohrIhGMIml+Gx4D3mA==", "requires": { - "@ethersproject/abstract-provider": "^5.4.0", - "@ethersproject/bignumber": "^5.4.0", - "@ethersproject/bytes": "^5.4.0", - "@ethersproject/logger": "^5.4.0", - "@ethersproject/properties": "^5.4.0" + "@ethersproject/abstract-provider": "^5.5.0", + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0" } }, "@ethersproject/address": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.4.0.tgz", - "integrity": "sha512-SD0VgOEkcACEG/C6xavlU1Hy3m5DGSXW3CUHkaaEHbAPPsgi0coP5oNPsxau8eTlZOk/bpa/hKeCNoK5IzVI2Q==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.5.0.tgz", + "integrity": "sha512-l4Nj0eWlTUh6ro5IbPTgbpT4wRbdH5l8CQf7icF7sb/SI3Nhd9Y9HzhonTSTi6CefI0necIw7LJqQPopPLZyWw==", "requires": { - "@ethersproject/bignumber": "^5.4.0", - "@ethersproject/bytes": "^5.4.0", - "@ethersproject/keccak256": "^5.4.0", - "@ethersproject/logger": "^5.4.0", - "@ethersproject/rlp": "^5.4.0" + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/keccak256": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/rlp": "^5.5.0" } }, "@ethersproject/base64": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.4.0.tgz", - "integrity": "sha512-CjQw6E17QDSSC5jiM9YpF7N1aSCHmYGMt9bWD8PWv6YPMxjsys2/Q8xLrROKI3IWJ7sFfZ8B3flKDTM5wlWuZQ==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.5.0.tgz", + "integrity": "sha512-tdayUKhU1ljrlHzEWbStXazDpsx4eg1dBXUSI6+mHlYklOXoXF6lZvw8tnD6oVaWfnMxAgRSKROg3cVKtCcppA==", "requires": { - "@ethersproject/bytes": "^5.4.0" + "@ethersproject/bytes": "^5.5.0" } }, "@ethersproject/basex": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.4.0.tgz", - "integrity": "sha512-J07+QCVJ7np2bcpxydFVf/CuYo9mZ7T73Pe7KQY4c1lRlrixMeblauMxHXD0MPwFmUHZIILDNViVkykFBZylbg==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.5.0.tgz", + "integrity": "sha512-ZIodwhHpVJ0Y3hUCfUucmxKsWQA5TMnavp5j/UOuDdzZWzJlRmuOjcTMIGgHCYuZmHt36BfiSyQPSRskPxbfaQ==", "requires": { - "@ethersproject/bytes": "^5.4.0", - "@ethersproject/properties": "^5.4.0" + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/properties": "^5.5.0" } }, "@ethersproject/bignumber": { - "version": "5.4.2", - "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.4.2.tgz", - "integrity": "sha512-oIBDhsKy5bs7j36JlaTzFgNPaZjiNDOXsdSgSpXRucUl+UA6L/1YLlFeI3cPAoodcenzF4nxNPV13pcy7XbWjA==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.5.0.tgz", + "integrity": "sha512-6Xytlwvy6Rn3U3gKEc1vP7nR92frHkv6wtVr95LFR3jREXiCPzdWxKQ1cx4JGQBXxcguAwjA8murlYN2TSiEbg==", "requires": { - "@ethersproject/bytes": "^5.4.0", - "@ethersproject/logger": "^5.4.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", "bn.js": "^4.11.9" } }, "@ethersproject/bytes": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.4.0.tgz", - "integrity": "sha512-H60ceqgTHbhzOj4uRc/83SCN9d+BSUnOkrr2intevqdtEMO1JFVZ1XL84OEZV+QjV36OaZYxtnt4lGmxcGsPfA==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.5.0.tgz", + "integrity": "sha512-ABvc7BHWhZU9PNM/tANm/Qx4ostPGadAuQzWTr3doklZOhDlmcBqclrQe/ZXUIj3K8wC28oYeuRa+A37tX9kog==", "requires": { - "@ethersproject/logger": "^5.4.0" + "@ethersproject/logger": "^5.5.0" } }, "@ethersproject/constants": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.4.0.tgz", - "integrity": "sha512-tzjn6S7sj9+DIIeKTJLjK9WGN2Tj0P++Z8ONEIlZjyoTkBuODN+0VfhAyYksKi43l1Sx9tX2VlFfzjfmr5Wl3Q==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.5.0.tgz", + "integrity": "sha512-2MsRRVChkvMWR+GyMGY4N1sAX9Mt3J9KykCsgUFd/1mwS0UH1qw+Bv9k1UJb3X3YJYFco9H20pjSlOIfCG5HYQ==", "requires": { - "@ethersproject/bignumber": "^5.4.0" + "@ethersproject/bignumber": "^5.5.0" } }, "@ethersproject/contracts": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.4.1.tgz", - "integrity": "sha512-m+z2ZgPy4pyR15Je//dUaymRUZq5MtDajF6GwFbGAVmKz/RF+DNIPwF0k5qEcL3wPGVqUjFg2/krlCRVTU4T5w==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.5.0.tgz", + "integrity": "sha512-2viY7NzyvJkh+Ug17v7g3/IJC8HqZBDcOjYARZLdzRxrfGlRgmYgl6xPRKVbEzy1dWKw/iv7chDcS83pg6cLxg==", "requires": { - "@ethersproject/abi": "^5.4.0", - "@ethersproject/abstract-provider": "^5.4.0", - "@ethersproject/abstract-signer": "^5.4.0", - "@ethersproject/address": "^5.4.0", - "@ethersproject/bignumber": "^5.4.0", - "@ethersproject/bytes": "^5.4.0", - "@ethersproject/constants": "^5.4.0", - "@ethersproject/logger": "^5.4.0", - "@ethersproject/properties": "^5.4.0", - "@ethersproject/transactions": "^5.4.0" + "@ethersproject/abi": "^5.5.0", + "@ethersproject/abstract-provider": "^5.5.0", + "@ethersproject/abstract-signer": "^5.5.0", + "@ethersproject/address": "^5.5.0", + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/constants": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/transactions": "^5.5.0" } }, "@ethersproject/hash": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.4.0.tgz", - "integrity": "sha512-xymAM9tmikKgbktOCjW60Z5sdouiIIurkZUr9oW5NOex5uwxrbsYG09kb5bMcNjlVeJD3yPivTNzViIs1GCbqA==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.5.0.tgz", + "integrity": "sha512-dnGVpK1WtBjmnp3mUT0PlU2MpapnwWI0PibldQEq1408tQBAbZpPidkWoVVuNMOl/lISO3+4hXZWCL3YV7qzfg==", "requires": { - "@ethersproject/abstract-signer": "^5.4.0", - "@ethersproject/address": "^5.4.0", - "@ethersproject/bignumber": "^5.4.0", - "@ethersproject/bytes": "^5.4.0", - "@ethersproject/keccak256": "^5.4.0", - "@ethersproject/logger": "^5.4.0", - "@ethersproject/properties": "^5.4.0", - "@ethersproject/strings": "^5.4.0" + "@ethersproject/abstract-signer": "^5.5.0", + "@ethersproject/address": "^5.5.0", + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/keccak256": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/strings": "^5.5.0" } }, "@ethersproject/hdnode": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.4.0.tgz", - "integrity": "sha512-pKxdS0KAaeVGfZPp1KOiDLB0jba11tG6OP1u11QnYfb7pXn6IZx0xceqWRr6ygke8+Kw74IpOoSi7/DwANhy8Q==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.5.0.tgz", + "integrity": "sha512-mcSOo9zeUg1L0CoJH7zmxwUG5ggQHU1UrRf8jyTYy6HxdZV+r0PBoL1bxr+JHIPXRzS6u/UW4mEn43y0tmyF8Q==", "requires": { - "@ethersproject/abstract-signer": "^5.4.0", - "@ethersproject/basex": "^5.4.0", - "@ethersproject/bignumber": "^5.4.0", - "@ethersproject/bytes": "^5.4.0", - "@ethersproject/logger": "^5.4.0", - "@ethersproject/pbkdf2": "^5.4.0", - "@ethersproject/properties": "^5.4.0", - "@ethersproject/sha2": "^5.4.0", - "@ethersproject/signing-key": "^5.4.0", - "@ethersproject/strings": "^5.4.0", - "@ethersproject/transactions": "^5.4.0", - "@ethersproject/wordlists": "^5.4.0" + "@ethersproject/abstract-signer": "^5.5.0", + "@ethersproject/basex": "^5.5.0", + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/pbkdf2": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/sha2": "^5.5.0", + "@ethersproject/signing-key": "^5.5.0", + "@ethersproject/strings": "^5.5.0", + "@ethersproject/transactions": "^5.5.0", + "@ethersproject/wordlists": "^5.5.0" } }, "@ethersproject/json-wallets": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.4.0.tgz", - "integrity": "sha512-igWcu3fx4aiczrzEHwG1xJZo9l1cFfQOWzTqwRw/xcvxTk58q4f9M7cjh51EKphMHvrJtcezJ1gf1q1AUOfEQQ==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.5.0.tgz", + "integrity": "sha512-9lA21XQnCdcS72xlBn1jfQdj2A1VUxZzOzi9UkNdnokNKke/9Ya2xA9aIK1SC3PQyBDLt4C+dfps7ULpkvKikQ==", "requires": { - "@ethersproject/abstract-signer": "^5.4.0", - "@ethersproject/address": "^5.4.0", - "@ethersproject/bytes": "^5.4.0", - "@ethersproject/hdnode": "^5.4.0", - "@ethersproject/keccak256": "^5.4.0", - "@ethersproject/logger": "^5.4.0", - "@ethersproject/pbkdf2": "^5.4.0", - "@ethersproject/properties": "^5.4.0", - "@ethersproject/random": "^5.4.0", - "@ethersproject/strings": "^5.4.0", - "@ethersproject/transactions": "^5.4.0", + "@ethersproject/abstract-signer": "^5.5.0", + "@ethersproject/address": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/hdnode": "^5.5.0", + "@ethersproject/keccak256": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/pbkdf2": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/random": "^5.5.0", + "@ethersproject/strings": "^5.5.0", + "@ethersproject/transactions": "^5.5.0", "aes-js": "3.0.0", "scrypt-js": "3.0.1" } }, "@ethersproject/keccak256": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.4.0.tgz", - "integrity": "sha512-FBI1plWet+dPUvAzPAeHzRKiPpETQzqSUWR1wXJGHVWi4i8bOSrpC3NwpkPjgeXG7MnugVc1B42VbfnQikyC/A==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.5.0.tgz", + "integrity": "sha512-5VoFCTjo2rYbBe1l2f4mccaRFN/4VQEYFwwn04aJV2h7qf4ZvI2wFxUE1XOX+snbwCLRzIeikOqtAoPwMza9kg==", "requires": { - "@ethersproject/bytes": "^5.4.0", - "js-sha3": "0.5.7" + "@ethersproject/bytes": "^5.5.0", + "js-sha3": "0.8.0" } }, "@ethersproject/logger": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.4.1.tgz", - "integrity": "sha512-DZ+bRinnYLPw1yAC64oRl0QyVZj43QeHIhVKfD/+YwSz4wsv1pfwb5SOFjz+r710YEWzU6LrhuSjpSO+6PeE4A==" + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.5.0.tgz", + "integrity": "sha512-rIY/6WPm7T8n3qS2vuHTUBPdXHl+rGxWxW5okDfo9J4Z0+gRRZT0msvUdIJkE4/HS29GUMziwGaaKO2bWONBrg==" }, "@ethersproject/networks": { - "version": "5.4.2", - "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.4.2.tgz", - "integrity": "sha512-eekOhvJyBnuibfJnhtK46b8HimBc5+4gqpvd1/H9LEl7Q7/qhsIhM81dI9Fcnjpk3jB1aTy6bj0hz3cifhNeYw==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.5.0.tgz", + "integrity": "sha512-KWfP3xOnJeF89Uf/FCJdV1a2aDJe5XTN2N52p4fcQ34QhDqQFkgQKZ39VGtiqUgHcLI8DfT0l9azC3KFTunqtA==", "requires": { - "@ethersproject/logger": "^5.4.0" + "@ethersproject/logger": "^5.5.0" } }, "@ethersproject/pbkdf2": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.4.0.tgz", - "integrity": "sha512-x94aIv6tiA04g6BnazZSLoRXqyusawRyZWlUhKip2jvoLpzJuLb//KtMM6PEovE47pMbW+Qe1uw+68ameJjB7g==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.5.0.tgz", + "integrity": "sha512-SaDvQFvXPnz1QGpzr6/HToLifftSXGoXrbpZ6BvoZhmx4bNLHrxDe8MZisuecyOziP1aVEwzC2Hasj+86TgWVg==", "requires": { - "@ethersproject/bytes": "^5.4.0", - "@ethersproject/sha2": "^5.4.0" + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/sha2": "^5.5.0" } }, "@ethersproject/properties": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.4.1.tgz", - "integrity": "sha512-cyCGlF8wWlIZyizsj2PpbJ9I7rIlUAfnHYwy/T90pdkSn/NFTa5YWZx2wTJBe9V7dD65dcrrEMisCRUJiq6n3w==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.5.0.tgz", + "integrity": "sha512-l3zRQg3JkD8EL3CPjNK5g7kMx4qSwiR60/uk5IVjd3oq1MZR5qUg40CNOoEJoX5wc3DyY5bt9EbMk86C7x0DNA==", "requires": { - "@ethersproject/logger": "^5.4.0" + "@ethersproject/logger": "^5.5.0" } }, "@ethersproject/providers": { - "version": "5.4.5", - "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.4.5.tgz", - "integrity": "sha512-1GkrvkiAw3Fj28cwi1Sqm8ED1RtERtpdXmRfwIBGmqBSN5MoeRUHuwHPppMtbPayPgpFcvD7/Gdc9doO5fGYgw==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.5.0.tgz", + "integrity": "sha512-xqMbDnS/FPy+J/9mBLKddzyLLAQFjrVff5g00efqxPzcAwXiR+SiCGVy6eJ5iAIirBOATjx7QLhDNPGV+AEQsw==", "requires": { - "@ethersproject/abstract-provider": "^5.4.0", - "@ethersproject/abstract-signer": "^5.4.0", - "@ethersproject/address": "^5.4.0", - "@ethersproject/basex": "^5.4.0", - "@ethersproject/bignumber": "^5.4.0", - "@ethersproject/bytes": "^5.4.0", - "@ethersproject/constants": "^5.4.0", - "@ethersproject/hash": "^5.4.0", - "@ethersproject/logger": "^5.4.0", - "@ethersproject/networks": "^5.4.0", - "@ethersproject/properties": "^5.4.0", - "@ethersproject/random": "^5.4.0", - "@ethersproject/rlp": "^5.4.0", - "@ethersproject/sha2": "^5.4.0", - "@ethersproject/strings": "^5.4.0", - "@ethersproject/transactions": "^5.4.0", - "@ethersproject/web": "^5.4.0", + "@ethersproject/abstract-provider": "^5.5.0", + "@ethersproject/abstract-signer": "^5.5.0", + "@ethersproject/address": "^5.5.0", + "@ethersproject/basex": "^5.5.0", + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/constants": "^5.5.0", + "@ethersproject/hash": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/networks": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/random": "^5.5.0", + "@ethersproject/rlp": "^5.5.0", + "@ethersproject/sha2": "^5.5.0", + "@ethersproject/strings": "^5.5.0", + "@ethersproject/transactions": "^5.5.0", + "@ethersproject/web": "^5.5.0", "bech32": "1.1.4", "ws": "7.4.6" }, @@ -20777,138 +20953,139 @@ } }, "@ethersproject/random": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.4.0.tgz", - "integrity": "sha512-pnpWNQlf0VAZDEOVp1rsYQosmv2o0ITS/PecNw+mS2/btF8eYdspkN0vIXrCMtkX09EAh9bdk8GoXmFXM1eAKw==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.5.0.tgz", + "integrity": "sha512-egGYZwZ/YIFKMHcoBUo8t3a8Hb/TKYX8BCBoLjudVCZh892welR3jOxgOmb48xznc9bTcMm7Tpwc1gHC1PFNFQ==", "requires": { - "@ethersproject/bytes": "^5.4.0", - "@ethersproject/logger": "^5.4.0" + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0" } }, "@ethersproject/rlp": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.4.0.tgz", - "integrity": "sha512-0I7MZKfi+T5+G8atId9QaQKHRvvasM/kqLyAH4XxBCBchAooH2EX5rL9kYZWwcm3awYV+XC7VF6nLhfeQFKVPg==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.5.0.tgz", + "integrity": "sha512-hLv8XaQ8PTI9g2RHoQGf/WSxBfTB/NudRacbzdxmst5VHAqd1sMibWG7SENzT5Dj3yZ3kJYx+WiRYEcQTAkcYA==", "requires": { - "@ethersproject/bytes": "^5.4.0", - "@ethersproject/logger": "^5.4.0" + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0" } }, "@ethersproject/sha2": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.4.0.tgz", - "integrity": "sha512-siheo36r1WD7Cy+bDdE1BJ8y0bDtqXCOxRMzPa4bV1TGt/eTUUt03BHoJNB6reWJD8A30E/pdJ8WFkq+/uz4Gg==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.5.0.tgz", + "integrity": "sha512-B5UBoglbCiHamRVPLA110J+2uqsifpZaTmid2/7W5rbtYVz6gus6/hSDieIU/6gaKIDcOj12WnOdiymEUHIAOA==", "requires": { - "@ethersproject/bytes": "^5.4.0", - "@ethersproject/logger": "^5.4.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", "hash.js": "1.1.7" } }, "@ethersproject/signing-key": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.4.0.tgz", - "integrity": "sha512-q8POUeywx6AKg2/jX9qBYZIAmKSB4ubGXdQ88l40hmATj29JnG5pp331nAWwwxPn2Qao4JpWHNZsQN+bPiSW9A==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.5.0.tgz", + "integrity": "sha512-5VmseH7qjtNmDdZBswavhotYbWB0bOwKIlOTSlX14rKn5c11QmJwGt4GHeo7NrL/Ycl7uo9AHvEqs5xZgFBTng==", "requires": { - "@ethersproject/bytes": "^5.4.0", - "@ethersproject/logger": "^5.4.0", - "@ethersproject/properties": "^5.4.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0", "bn.js": "^4.11.9", "elliptic": "6.5.4", "hash.js": "1.1.7" } }, "@ethersproject/solidity": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.4.0.tgz", - "integrity": "sha512-XFQTZ7wFSHOhHcV1DpcWj7VXECEiSrBuv7JErJvB9Uo+KfCdc3QtUZV+Vjh/AAaYgezUEKbCtE6Khjm44seevQ==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.5.0.tgz", + "integrity": "sha512-9NgZs9LhGMj6aCtHXhtmFQ4AN4sth5HuFXVvAQtzmm0jpSCNOTGtrHZJAeYTh7MBjRR8brylWZxBZR9zDStXbw==", "requires": { - "@ethersproject/bignumber": "^5.4.0", - "@ethersproject/bytes": "^5.4.0", - "@ethersproject/keccak256": "^5.4.0", - "@ethersproject/sha2": "^5.4.0", - "@ethersproject/strings": "^5.4.0" + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/keccak256": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/sha2": "^5.5.0", + "@ethersproject/strings": "^5.5.0" } }, "@ethersproject/strings": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.4.0.tgz", - "integrity": "sha512-k/9DkH5UGDhv7aReXLluFG5ExurwtIpUfnDNhQA29w896Dw3i4uDTz01Quaptbks1Uj9kI8wo9tmW73wcIEaWA==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.5.0.tgz", + "integrity": "sha512-9fy3TtF5LrX/wTrBaT8FGE6TDJyVjOvXynXJz5MT5azq+E6D92zuKNx7i29sWW2FjVOaWjAsiZ1ZWznuduTIIQ==", "requires": { - "@ethersproject/bytes": "^5.4.0", - "@ethersproject/constants": "^5.4.0", - "@ethersproject/logger": "^5.4.0" + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/constants": "^5.5.0", + "@ethersproject/logger": "^5.5.0" } }, "@ethersproject/transactions": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.4.0.tgz", - "integrity": "sha512-s3EjZZt7xa4BkLknJZ98QGoIza94rVjaEed0rzZ/jB9WrIuu/1+tjvYCWzVrystXtDswy7TPBeIepyXwSYa4WQ==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.5.0.tgz", + "integrity": "sha512-9RZYSKX26KfzEd/1eqvv8pLauCKzDTub0Ko4LfIgaERvRuwyaNV78mJs7cpIgZaDl6RJui4o49lHwwCM0526zA==", "requires": { - "@ethersproject/address": "^5.4.0", - "@ethersproject/bignumber": "^5.4.0", - "@ethersproject/bytes": "^5.4.0", - "@ethersproject/constants": "^5.4.0", - "@ethersproject/keccak256": "^5.4.0", - "@ethersproject/logger": "^5.4.0", - "@ethersproject/properties": "^5.4.0", - "@ethersproject/rlp": "^5.4.0", - "@ethersproject/signing-key": "^5.4.0" + "@ethersproject/address": "^5.5.0", + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/constants": "^5.5.0", + "@ethersproject/keccak256": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/rlp": "^5.5.0", + "@ethersproject/signing-key": "^5.5.0" } }, "@ethersproject/units": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.4.0.tgz", - "integrity": "sha512-Z88krX40KCp+JqPCP5oPv5p750g+uU6gopDYRTBGcDvOASh6qhiEYCRatuM/suC4S2XW9Zz90QI35MfSrTIaFg==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.5.0.tgz", + "integrity": "sha512-7+DpjiZk4v6wrikj+TCyWWa9dXLNU73tSTa7n0TSJDxkYbV3Yf1eRh9ToMLlZtuctNYu9RDNNy2USq3AdqSbag==", "requires": { - "@ethersproject/bignumber": "^5.4.0", - "@ethersproject/constants": "^5.4.0", - "@ethersproject/logger": "^5.4.0" + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/constants": "^5.5.0", + "@ethersproject/logger": "^5.5.0" } }, "@ethersproject/wallet": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.4.0.tgz", - "integrity": "sha512-wU29majLjM6AjCjpat21mPPviG+EpK7wY1+jzKD0fg3ui5fgedf2zEu1RDgpfIMsfn8fJHJuzM4zXZ2+hSHaSQ==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.5.0.tgz", + "integrity": "sha512-Mlu13hIctSYaZmUOo7r2PhNSd8eaMPVXe1wxrz4w4FCE4tDYBywDH+bAR1Xz2ADyXGwqYMwstzTrtUVIsKDO0Q==", "requires": { - "@ethersproject/abstract-provider": "^5.4.0", - "@ethersproject/abstract-signer": "^5.4.0", - "@ethersproject/address": "^5.4.0", - "@ethersproject/bignumber": "^5.4.0", - "@ethersproject/bytes": "^5.4.0", - "@ethersproject/hash": "^5.4.0", - "@ethersproject/hdnode": "^5.4.0", - "@ethersproject/json-wallets": "^5.4.0", - "@ethersproject/keccak256": "^5.4.0", - "@ethersproject/logger": "^5.4.0", - "@ethersproject/properties": "^5.4.0", - "@ethersproject/random": "^5.4.0", - "@ethersproject/signing-key": "^5.4.0", - "@ethersproject/transactions": "^5.4.0", - "@ethersproject/wordlists": "^5.4.0" + "@ethersproject/abstract-provider": "^5.5.0", + "@ethersproject/abstract-signer": "^5.5.0", + "@ethersproject/address": "^5.5.0", + "@ethersproject/bignumber": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/hash": "^5.5.0", + "@ethersproject/hdnode": "^5.5.0", + "@ethersproject/json-wallets": "^5.5.0", + "@ethersproject/keccak256": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/random": "^5.5.0", + "@ethersproject/signing-key": "^5.5.0", + "@ethersproject/transactions": "^5.5.0", + "@ethersproject/wordlists": "^5.5.0" } }, "@ethersproject/web": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.4.0.tgz", - "integrity": "sha512-1bUusGmcoRLYgMn6c1BLk1tOKUIFuTg8j+6N8lYlbMpDesnle+i3pGSagGNvwjaiLo4Y5gBibwctpPRmjrh4Og==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.5.0.tgz", + "integrity": "sha512-BEgY0eL5oH4mAo37TNYVrFeHsIXLRxggCRG/ksRIxI2X5uj5IsjGmcNiRN/VirQOlBxcUhCgHhaDLG4m6XAVoA==", "requires": { - "@ethersproject/base64": "^5.4.0", - "@ethersproject/bytes": "^5.4.0", - "@ethersproject/logger": "^5.4.0", - "@ethersproject/properties": "^5.4.0", - "@ethersproject/strings": "^5.4.0" + "@ethersproject/base64": "^5.5.0", + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/strings": "^5.5.0" } }, "@ethersproject/wordlists": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.4.0.tgz", - "integrity": "sha512-FemEkf6a+EBKEPxlzeVgUaVSodU7G0Na89jqKjmWMlDB0tomoU8RlEMgUvXyqtrg8N4cwpLh8nyRnm1Nay1isA==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.5.0.tgz", + "integrity": "sha512-bL0UTReWDiaQJJYOC9sh/XcRu/9i2jMrzf8VLRmPKx58ckSlOJiohODkECCO50dtLZHcGU6MLXQ4OOrgBwP77Q==", "requires": { - "@ethersproject/bytes": "^5.4.0", - "@ethersproject/hash": "^5.4.0", - "@ethersproject/logger": "^5.4.0", - "@ethersproject/properties": "^5.4.0", - "@ethersproject/strings": "^5.4.0" + "@ethersproject/bytes": "^5.5.0", + "@ethersproject/hash": "^5.5.0", + "@ethersproject/logger": "^5.5.0", + "@ethersproject/properties": "^5.5.0", + "@ethersproject/strings": "^5.5.0" } }, "@fontsource/fira-code": { @@ -21619,9 +21796,9 @@ "version": "1.5.4" }, "@types/react": { - "version": "17.0.30", - "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.30.tgz", - "integrity": "sha512-3Dt/A8gd3TCXi2aRe84y7cK1K8G+N9CZRDG8kDGguOKa0kf/ZkSwTmVIDPsm/KbQOVMaDJXwhBtuOXxqwdpWVg==", + "version": "17.0.33", + "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.33.tgz", + "integrity": "sha512-pLWntxXpDPaU+RTAuSGWGSEL2FRTNyRQOjSWDke/rxRg14ncsZvx8AKWMWZqvc1UOaJIAoObdZhAWvRaHFi5rw==", "requires": { "@types/prop-types": "*", "@types/scheduler": "*", @@ -21637,9 +21814,9 @@ } }, "@types/react-dom": { - "version": "17.0.9", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.9.tgz", - "integrity": "sha512-wIvGxLfgpVDSAMH5utdL9Ngm5Owu0VsGmldro3ORLXV8CShrL8awVj06NuEXFQ5xyaYfdca7Sgbk/50Ri1GdPg==", + "version": "17.0.10", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.10.tgz", + "integrity": "sha512-8oz3NAUId2z/zQdFI09IMhQPNgIbiP8Lslhv39DIDamr846/0spjZK0vnrMak0iB8EKb9QFTTIdg2Wj2zH5a3g==", "requires": { "@types/react": "*" } @@ -21662,9 +21839,9 @@ } }, "@types/react-router-dom": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/@types/react-router-dom/-/react-router-dom-5.3.1.tgz", - "integrity": "sha512-UvyRy73318QI83haXlaMwmklHHzV9hjl3u71MmM6wYNu0hOVk9NLTa0vGukf8zXUqnwz4O06ig876YSPpeK28A==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/@types/react-router-dom/-/react-router-dom-5.3.2.tgz", + "integrity": "sha512-ELEYRUie2czuJzaZ5+ziIp9Hhw+juEw8b7C11YNA4QdLCVbQ3qLi2l4aq8XnlqM7V31LZX8dxUuFUCrzHm6sqQ==", "requires": { "@types/history": "*", "@types/react": "*", @@ -22192,6 +22369,12 @@ } } }, + "app-root-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/app-root-path/-/app-root-path-3.0.0.tgz", + "integrity": "sha512-qMcx+Gy2UZynHjOHOIXPNvpf+9cjvk3cWrBBK7zg4gH9+clobJRb9NGzcT7mQTcV/6Gm/1WelUtqxVXnNlrwcw==", + "dev": true + }, "aproba": { "version": "1.2.0" }, @@ -23645,6 +23828,15 @@ "arity-n": "^1.0.4" } }, + "compress-create-react-app": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/compress-create-react-app/-/compress-create-react-app-1.1.3.tgz", + "integrity": "sha512-3HCWi9q7TqxBvklmJY/Pm96Fs8wqEXxduW3LGlK0PUYuezZwKkjB454GjyGhjKmxKpl91Q9b2+ZjXeKdNOIhlA==", + "dev": true, + "requires": { + "app-root-path": "^3.0.0" + } + }, "compressible": { "version": "2.0.18", "requires": { @@ -23826,6 +24018,11 @@ "sha.js": "^2.4.8" } }, + "create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==" + }, "cross-spawn": { "version": "7.0.3", "requires": { @@ -24305,6 +24502,11 @@ "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", "dev": true }, + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==" + }, "diff-sequences": { "version": "26.6.2" }, @@ -25043,40 +25245,40 @@ "version": "1.8.1" }, "ethers": { - "version": "5.4.7", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.4.7.tgz", - "integrity": "sha512-iZc5p2nqfWK1sj8RabwsPM28cr37Bpq7ehTQ5rWExBr2Y09Sn1lDKZOED26n+TsZMye7Y6mIgQ/1cwpSD8XZew==", + "version": "5.5.1", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.5.1.tgz", + "integrity": "sha512-RodEvUFZI+EmFcE6bwkuJqpCYHazdzeR1nMzg+YWQSmQEsNtfl1KHGfp/FWZYl48bI/g7cgBeP2IlPthjiVngw==", "requires": { - "@ethersproject/abi": "5.4.1", - "@ethersproject/abstract-provider": "5.4.1", - "@ethersproject/abstract-signer": "5.4.1", - "@ethersproject/address": "5.4.0", - "@ethersproject/base64": "5.4.0", - "@ethersproject/basex": "5.4.0", - "@ethersproject/bignumber": "5.4.2", - "@ethersproject/bytes": "5.4.0", - "@ethersproject/constants": "5.4.0", - "@ethersproject/contracts": "5.4.1", - "@ethersproject/hash": "5.4.0", - "@ethersproject/hdnode": "5.4.0", - "@ethersproject/json-wallets": "5.4.0", - "@ethersproject/keccak256": "5.4.0", - "@ethersproject/logger": "5.4.1", - "@ethersproject/networks": "5.4.2", - "@ethersproject/pbkdf2": "5.4.0", - "@ethersproject/properties": "5.4.1", - "@ethersproject/providers": "5.4.5", - "@ethersproject/random": "5.4.0", - "@ethersproject/rlp": "5.4.0", - "@ethersproject/sha2": "5.4.0", - "@ethersproject/signing-key": "5.4.0", - "@ethersproject/solidity": "5.4.0", - "@ethersproject/strings": "5.4.0", - "@ethersproject/transactions": "5.4.0", - "@ethersproject/units": "5.4.0", - "@ethersproject/wallet": "5.4.0", - "@ethersproject/web": "5.4.0", - "@ethersproject/wordlists": "5.4.0" + "@ethersproject/abi": "5.5.0", + "@ethersproject/abstract-provider": "5.5.1", + "@ethersproject/abstract-signer": "5.5.0", + "@ethersproject/address": "5.5.0", + "@ethersproject/base64": "5.5.0", + "@ethersproject/basex": "5.5.0", + "@ethersproject/bignumber": "5.5.0", + "@ethersproject/bytes": "5.5.0", + "@ethersproject/constants": "5.5.0", + "@ethersproject/contracts": "5.5.0", + "@ethersproject/hash": "5.5.0", + "@ethersproject/hdnode": "5.5.0", + "@ethersproject/json-wallets": "5.5.0", + "@ethersproject/keccak256": "5.5.0", + "@ethersproject/logger": "5.5.0", + "@ethersproject/networks": "5.5.0", + "@ethersproject/pbkdf2": "5.5.0", + "@ethersproject/properties": "5.5.0", + "@ethersproject/providers": "5.5.0", + "@ethersproject/random": "5.5.0", + "@ethersproject/rlp": "5.5.0", + "@ethersproject/sha2": "5.5.0", + "@ethersproject/signing-key": "5.5.0", + "@ethersproject/solidity": "5.5.0", + "@ethersproject/strings": "5.5.0", + "@ethersproject/transactions": "5.5.0", + "@ethersproject/units": "5.5.0", + "@ethersproject/wallet": "5.5.0", + "@ethersproject/web": "5.5.0", + "@ethersproject/wordlists": "5.5.0" } }, "eventemitter3": { @@ -26189,6 +26391,14 @@ "side-channel": "^1.0.4" } }, + "invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "requires": { + "loose-envify": "^1.0.0" + } + }, "ip": { "version": "1.1.5" }, @@ -26965,9 +27175,9 @@ } }, "js-sha3": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz", - "integrity": "sha1-DU/9gALVMzqrr0oj7tL2N0yfKOc=" + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", + "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==" }, "js-tokens": { "version": "4.0.0" @@ -27191,6 +27401,11 @@ "lodash._reinterpolate": { "version": "3.0.0" }, + "lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=" + }, "lodash.memoize": { "version": "4.1.2" }, @@ -27275,6 +27490,11 @@ } } }, + "make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" + }, "makeerror": { "version": "1.0.11", "requires": { @@ -29224,12 +29444,10 @@ } }, "react-chartjs-2": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/react-chartjs-2/-/react-chartjs-2-3.0.5.tgz", - "integrity": "sha512-fYr4E82agaZi9IFMe5GtOZ6WE/HWdxy/KywLNOzXsqgPkD2oo1IlrQLKMLUki/2UXko3p95TR2L8Q2rEss/opQ==", - "requires": { - "lodash": "^4.17.19" - } + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/react-chartjs-2/-/react-chartjs-2-3.3.0.tgz", + "integrity": "sha512-4Mt0SR2aiUbWi/4762odRBYSnbNKSs4HWc0o3IW43py5bMfmfpeZU95w6mbvtuLZH/M3GsPJMU8DvDc+5U9blQ==", + "requires": {} }, "react-dev-utils": { "version": "11.0.4", @@ -29325,9 +29543,9 @@ } }, "react-error-boundary": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/react-error-boundary/-/react-error-boundary-3.1.3.tgz", - "integrity": "sha512-A+F9HHy9fvt9t8SNDlonq01prnU8AmkjvGKV4kk8seB9kU3xMEO8J/PQlLVmoOIDODl5U2kufSBs4vrWIqhsAA==", + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/react-error-boundary/-/react-error-boundary-3.1.4.tgz", + "integrity": "sha512-uM9uPzZJTF6wRQORmSrvOIgt4lJ9MC1sNgEOj2XGsDTRE4kmpWxg7ENK9EWNKJRMAOY9z0MuF4yIfl6gp4sotA==", "requires": { "@babel/runtime": "^7.12.5" } @@ -29335,6 +29553,23 @@ "react-error-overlay": { "version": "6.0.9" }, + "react-fast-compare": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.0.tgz", + "integrity": "sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA==" + }, + "react-helmet-async": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/react-helmet-async/-/react-helmet-async-1.1.2.tgz", + "integrity": "sha512-LTTzDDkyIleT/JJ6T/uqx7Y8qi1EuPPSiJawQY/nHHz0h7SPDT6HxP1YDDQx/fzcVxCqpWEEMS3QdrSrNkJYhg==", + "requires": { + "@babel/runtime": "^7.12.5", + "invariant": "^2.2.4", + "prop-types": "^15.7.2", + "react-fast-compare": "^3.2.0", + "shallowequal": "^1.1.0" + } + }, "react-image": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/react-image/-/react-image-4.0.3.tgz", @@ -30513,6 +30748,11 @@ "safe-buffer": "^5.0.1" } }, + "shallowequal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", + "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==" + }, "shebang-command": { "version": "2.0.0", "requires": { @@ -31774,6 +32014,26 @@ "resolved": "https://registry.npmjs.org/ts-custom-error/-/ts-custom-error-3.2.0.tgz", "integrity": "sha512-cBvC2QjtvJ9JfWLvstVnI45Y46Y5dMxIaG1TDMGAD/R87hpvqFL+7LhvUDhnRCfOnx/xitollFWWvUKKKhbN0A==" }, + "ts-node": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-9.1.1.tgz", + "integrity": "sha512-hPlt7ZACERQGf03M253ytLY3dHbGNGrAq9qIHWUY9XHYl1z7wYngSr3OQ5xmui8o2AaxsONxIzjafLUiWBo1Fg==", + "requires": { + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "source-map-support": "^0.5.17", + "yn": "3.1.1" + }, + "dependencies": { + "arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" + } + } + }, "ts-pnp": { "version": "1.2.0" }, @@ -32876,6 +33136,11 @@ "decamelize": "^1.2.0" } }, + "yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==" + }, "yocto-queue": { "version": "0.1.0" } diff --git a/package.json b/package.json index 3b0c375..d301e67 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "dependencies": { "@blackbox-vision/react-qr-reader": "^5.0.0", "@chainlink/contracts": "^0.2.2", - "@craco/craco": "^6.3.0", + "@craco/craco": "^6.4.0", "@fontsource/fira-code": "^4.5.1", "@fontsource/roboto": "^4.5.1", "@fontsource/roboto-mono": "^4.5.0", @@ -22,21 +22,22 @@ "@testing-library/user-event": "^12.1.10", "@types/jest": "^26.0.24", "@types/node": "^14.17.5", - "@types/react": "^17.0.30", + "@types/react": "^17.0.33", "@types/react-blockies": "^1.4.1", - "@types/react-dom": "^17.0.9", + "@types/react-dom": "^17.0.10", "@types/react-highlight": "^0.12.5", - "@types/react-router-dom": "^5.3.1", + "@types/react-router-dom": "^5.3.2", "@types/react-syntax-highlighter": "^13.5.2", "chart.js": "^3.5.1", - "ethers": "^5.4.7", + "ethers": "^5.5.1", "highlightjs-solidity": "^2.0.1", "query-string": "^7.0.1", "react": "^17.0.2", "react-blockies": "^1.4.1", - "react-chartjs-2": "^3.0.5", + "react-chartjs-2": "^3.3.0", "react-dom": "^17.0.2", - "react-error-boundary": "^3.1.3", + "react-error-boundary": "^3.1.4", + "react-helmet-async": "^1.1.2", "react-image": "^4.0.3", "react-router-dom": "^5.3.0", "react-scripts": "4.0.3", @@ -48,12 +49,12 @@ }, "scripts": { "start": "craco start", - "build": "craco build", + "build": "craco build && compress-cra", "test": "craco test", "eject": "react-scripts eject", "source-map-explorer": "source-map-explorer build/static/js/*.js", - "assets-start": "docker run --rm -p 3001:80 --name otterscan-assets -d -v$(pwd)/4bytes/signatures:/usr/share/nginx/html/signatures/ -v$(pwd)/trustwallet/blockchains/ethereum/assets:/usr/share/nginx/html/assets -v$(pwd)/topic0/with_parameter_names:/usr/share/nginx/html/topic0/ -v$(pwd)/nginx.conf:/etc/nginx/conf.d/default.conf nginx:1.21.1-alpine", - "assets-start-with-param-names": "docker run --rm -p 3001:80 --name otterscan-assets -d -v$(pwd)/4bytes/with_parameter_names:/usr/share/nginx/html/signatures/ -v$(pwd)/trustwallet/blockchains/ethereum/assets:/usr/share/nginx/html/assets -v$(pwd)/topic0/with_parameter_names:/usr/share/nginx/html/topic0/ -v$(pwd)/nginx.conf:/etc/nginx/conf.d/default.conf nginx:1.21.1-alpine", + "assets-start": "docker run --rm -p 3001:80 --name otterscan-assets -d -v$(pwd)/4bytes/signatures:/usr/share/nginx/html/signatures/ -v$(pwd)/trustwallet/blockchains/ethereum/assets:/usr/share/nginx/html/assets -v$(pwd)/topic0/with_parameter_names:/usr/share/nginx/html/topic0/ -v$(pwd)/nginx/nginx.conf:/etc/nginx/nginx.conf -v$(pwd)/nginx/conf.d/default.conf:/etc/nginx/conf.d/default.conf nginx:1.21.1-alpine", + "assets-start-with-param-names": "docker run --rm -p 3001:80 --name otterscan-assets -d -v$(pwd)/4bytes/with_parameter_names:/usr/share/nginx/html/signatures/ -v$(pwd)/trustwallet/blockchains/ethereum/assets:/usr/share/nginx/html/assets -v$(pwd)/topic0/with_parameter_names:/usr/share/nginx/html/topic0/ -v$(pwd)/nginx/nginx.conf:/etc/nginx/nginx.conf -v$(pwd)/nginx/conf.d/default.conf:/etc/nginx/conf.d/default.conf nginx:1.21.1-alpine", "assets-stop": "docker stop otterscan-assets", "docker-build": "DOCKER_BUILDKIT=1 docker build -t otterscan -f Dockerfile .", "docker-start": "docker run --rm -p 5000:80 --name otterscan -d otterscan", @@ -79,6 +80,7 @@ }, "devDependencies": { "autoprefixer": "^9.8.8", + "compress-create-react-app": "^1.1.3", "postcss": "^7.0.39", "source-map-explorer": "^2.5.2", "tailwindcss": "npm:@tailwindcss/postcss7-compat@^2.2.6" diff --git a/src/AddressTransactions.tsx b/src/AddressTransactions.tsx index 6baead0..19d41bb 100644 --- a/src/AddressTransactions.tsx +++ b/src/AddressTransactions.tsx @@ -26,12 +26,13 @@ import PendingResults from "./search/PendingResults"; import TransactionItem from "./search/TransactionItem"; import { SearchController } from "./search/search"; import { RuntimeContext } from "./useRuntime"; -import { useENSCache } from "./useReverseCache"; +import { pageCollector, useResolvedAddresses } from "./useResolvedAddresses"; import { useFeeToggler } from "./search/useFeeToggler"; import { SelectionContext, useSelection } from "./useSelection"; import { useMultipleETHUSDOracle } from "./usePriceOracle"; import { useAppConfigContext } from "./useAppConfig"; import { useSourcify } from "./useSourcify"; +import SourcifyLogo from "./sourcify.svg"; type BlockParams = { addressOrName: string; @@ -164,7 +165,8 @@ const AddressTransactions: React.FC = () => { }, [provider, checksummedAddress, params.direction, hash, controller]); const page = useMemo(() => controller?.getPage(), [controller]); - const reverseCache = useENSCache(provider, page); + const addrCollector = useMemo(() => pageCollector(page), [page]); + const resolvedAddresses = useResolvedAddresses(provider, addrCollector); const blockTags: BlockTag[] = useMemo(() => { if (!page) { @@ -240,7 +242,7 @@ const AddressTransactions: React.FC = () => { ) : ( Sourcify logo { feeDisplay={feeDisplay} feeDisplayToggler={feeDisplayToggler} /> - {controller ? ( + {page ? ( - {controller.getPage().map((tx) => ( + {page.map((tx) => ( import("./Block")); -const BlockTransactions = React.lazy(() => import("./BlockTransactions")); -const AddressTransactions = React.lazy(() => import("./AddressTransactions")); -const Transaction = React.lazy(() => import("./Transaction")); +const Block = React.lazy( + () => import(/* webpackChunkName: "block", webpackPrefetch: true */ "./Block") +); +const BlockTransactions = React.lazy( + () => + import( + /* webpackChunkName: "blocktxs", webpackPrefetch: true */ "./BlockTransactions" + ) +); +const AddressTransactions = React.lazy( + () => + import( + /* webpackChunkName: "address", webpackPrefetch: true */ "./AddressTransactions" + ) +); +const Transaction = React.lazy( + () => + import(/* webpackChunkName: "tx", webpackPrefetch: true */ "./Transaction") +); +const London = React.lazy( + () => + import( + /* webpackChunkName: "london", webpackPrefetch: true */ "./special/london/London" + ) +); const App = () => { const runtime = useRuntime(); @@ -30,7 +50,7 @@ const App = () => { }, [sourcifySource, setSourcifySource]); return ( - LOADING}> + {runtime.connStatus !== ConnectionStatus.CONNECTED ? ( { -
- - <Route path="/block/:blockNumberOrHash" exact> - <Block /> - </Route> - <Route path="/block/:blockNumber/txs" exact> - <BlockTransactions /> - </Route> - <Route path="/tx/:txhash"> - <Transaction /> - </Route> - <Route path="/address/:addressOrName/:direction?"> - <AddressTransactions /> - </Route> - </div> + <Title /> + <Route path="/block/:blockNumberOrHash" exact> + <Block /> + </Route> + <Route path="/block/:blockNumber/txs" exact> + <BlockTransactions /> + </Route> + <Route path="/tx/:txhash"> + <Transaction /> + </Route> + <Route path="/address/:addressOrName/:direction?"> + <AddressTransactions /> + </Route> </AppConfigContext.Provider> </Route> </Switch> diff --git a/src/Block.tsx b/src/Block.tsx index b63e942..df16643 100644 --- a/src/Block.tsx +++ b/src/Block.tsx @@ -166,7 +166,7 @@ const Block: React.FC = () => { <USDValue value={blockETHUSDPrice} /> </InfoRow> <InfoRow title="Difficult"> - {block.difficulty ? commify(block.difficulty) : "?"} + {commify(block._difficulty.toString())} </InfoRow> <InfoRow title="Total Difficult"> {commify(block.totalDifficulty.toString())} diff --git a/src/Home.tsx b/src/Home.tsx index 650c86c..103639a 100644 --- a/src/Home.tsx +++ b/src/Home.tsx @@ -5,12 +5,13 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { faBurn } from "@fortawesome/free-solid-svg-icons/faBurn"; import { faQrcode } from "@fortawesome/free-solid-svg-icons/faQrcode"; import Logo from "./Logo"; -import CameraScanner from "./search/CameraScanner"; import Timestamp from "./components/Timestamp"; import { RuntimeContext } from "./useRuntime"; import { useLatestBlock } from "./useLatestBlock"; import { blockURL } from "./url"; +const CameraScanner = React.lazy(() => import("./search/CameraScanner")); + const Home: React.FC = () => { const { provider } = useContext(RuntimeContext); const [search, setSearch] = useState<string>(); @@ -37,9 +38,11 @@ const Home: React.FC = () => { document.title = "Home | Otterscan"; return ( - <div className="m-auto"> + <div className="mx-auto flex flex-col flex-grow pb-5"> {isScanning && <CameraScanner turnOffScan={() => setScanning(false)} />} - <Logo /> + <div className="m-5 mb-10 flex items-end flex-grow max-h-64"> + <Logo /> + </div> <form className="flex flex-col" onSubmit={handleSubmit} @@ -70,7 +73,9 @@ const Home: React.FC = () => { > Search </button> - <div className="mx-auto mt-5 mb-5 text-lg text-link-blue hover:text-link-blue-hover font-bold"> + </form> + <div className="mx-auto h-32"> + <div className="text-lg text-link-blue hover:text-link-blue-hover font-bold"> <NavLink to="/special/london"> <div className="flex space-x-2 items-baseline text-orange-500 hover:text-orange-700 hover:underline"> <span> @@ -85,14 +90,14 @@ const Home: React.FC = () => { </div> {latestBlock && ( <NavLink - className="mx-auto flex flex-col items-center space-y-1 mt-5 text-sm text-gray-500 hover:text-link-blue" + className="flex flex-col items-center space-y-1 mt-5 text-sm text-gray-500 hover:text-link-blue" to={blockURL(latestBlock.number)} > <div>Latest block: {commify(latestBlock.number)}</div> <Timestamp value={latestBlock.timestamp} /> </NavLink> )} - </form> + </div> </div> ); }; diff --git a/src/Logo.tsx b/src/Logo.tsx index 905ee2c..3671e42 100644 --- a/src/Logo.tsx +++ b/src/Logo.tsx @@ -1,10 +1,11 @@ import React from "react"; +import Otter from "./otter.jpg"; const Logo: React.FC = () => ( - <div className="mx-auto mb-16 text-6xl text-link-blue font-title font-bold cursor-default flex items-center space-x-4"> + <div className="mx-auto text-6xl text-link-blue font-title font-bold cursor-default flex items-center space-x-4"> <img className="rounded-full" - src="/otter.jpg" + src={Otter} width={96} height={96} alt="An otter scanning" diff --git a/src/SourcifyMenu.tsx b/src/SourcifyMenu.tsx index 36f43a5..7c614f0 100644 --- a/src/SourcifyMenu.tsx +++ b/src/SourcifyMenu.tsx @@ -30,14 +30,6 @@ const SourcifyMenu: React.FC = () => { > Sourcify Servers </SourcifyMenuItem> - <SourcifyMenuItem - checked={sourcifySource === SourcifySource.CUSTOM_SNAPSHOT_SERVER} - onClick={() => - setSourcifySource(SourcifySource.CUSTOM_SNAPSHOT_SERVER) - } - > - Local Snapshot - </SourcifyMenuItem> </Menu.Items> </div> </Menu> diff --git a/src/StandardFrame.tsx b/src/StandardFrame.tsx index 65fc076..10b5fe8 100644 --- a/src/StandardFrame.tsx +++ b/src/StandardFrame.tsx @@ -1,7 +1,7 @@ import React from "react"; const StandardFrame: React.FC = ({ children }) => ( - <div className="bg-gray-100 px-9 pt-3 pb-12">{children}</div> + <div className="flex-grow bg-gray-100 px-9 pt-3 pb-12">{children}</div> ); export default StandardFrame; diff --git a/src/Title.tsx b/src/Title.tsx index e4c5f47..e1e9b8e 100644 --- a/src/Title.tsx +++ b/src/Title.tsx @@ -4,9 +4,11 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { faQrcode } from "@fortawesome/free-solid-svg-icons/faQrcode"; import useKeyboardShortcut from "use-keyboard-shortcut"; import PriceBox from "./PriceBox"; -import CameraScanner from "./search/CameraScanner"; import SourcifyMenu from "./SourcifyMenu"; import { RuntimeContext } from "./useRuntime"; +import Otter from "./otter.jpg"; + +const CameraScanner = React.lazy(() => import("./search/CameraScanner")); const Title: React.FC = () => { const { provider } = useContext(RuntimeContext); @@ -43,7 +45,7 @@ const Title: React.FC = () => { <div className="text-2xl text-link-blue font-title font-bold flex items-center space-x-2"> <img className="rounded-full" - src="/otter.jpg" + src={Otter} width={32} height={32} alt="An otter scanning" diff --git a/src/TokenTransferItem.tsx b/src/TokenTransferItem.tsx index 083f7f0..03fa198 100644 --- a/src/TokenTransferItem.tsx +++ b/src/TokenTransferItem.tsx @@ -11,11 +11,13 @@ import { TokenTransfer, TransactionData, } from "./types"; +import { ResolvedAddresses } from "./api/address-resolver"; type TokenTransferItemProps = { t: TokenTransfer; txData: TransactionData; tokenMeta?: TokenMeta | undefined; + resolvedAddresses: ResolvedAddresses | undefined; }; // TODO: handle partial @@ -23,6 +25,7 @@ const TokenTransferItem: React.FC<TokenTransferItemProps> = ({ t, txData, tokenMeta, + resolvedAddresses, }) => ( <div className="flex items-baseline space-x-2 px-2 py-1 truncate hover:bg-gray-100"> <span className="text-gray-500"> @@ -64,10 +67,7 @@ const TokenTransferItem: React.FC<TokenTransferItemProps> = ({ <AddressHighlighter address={t.token}> <DecoratedAddressLink address={t.token} - text={ - tokenMeta ? `${tokenMeta.name} (${tokenMeta.symbol})` : undefined - } - tokenMeta={tokenMeta} + resolvedAddresses={resolvedAddresses} /> </AddressHighlighter> </div> diff --git a/src/Transaction.tsx b/src/Transaction.tsx index 0edd994..7107b32 100644 --- a/src/Transaction.tsx +++ b/src/Transaction.tsx @@ -5,14 +5,30 @@ import StandardFrame from "./StandardFrame"; import StandardSubtitle from "./StandardSubtitle"; import ContentFrame from "./ContentFrame"; import NavTab from "./components/NavTab"; -import Details from "./transaction/Details"; -import Logs from "./transaction/Logs"; import { RuntimeContext } from "./useRuntime"; import { SelectionContext, useSelection } from "./useSelection"; import { useInternalOperations, useTxData } from "./useErigonHooks"; import { useETHUSDOracle } from "./usePriceOracle"; import { useAppConfigContext } from "./useAppConfig"; import { useSourcify, useTransactionDescription } from "./useSourcify"; +import { + transactionDataCollector, + useResolvedAddresses, +} from "./useResolvedAddresses"; + +const Details = React.lazy( + () => + import( + /* webpackChunkName: "txdetails", webpackPrefetch: true */ + "./transaction/Details" + ) +); +const Logs = React.lazy( + () => + import( + /* webpackChunkName: "txlogs", webpackPrefetch: true */ "./transaction/Logs" + ) +); type TransactionParams = { txhash: string; @@ -24,6 +40,11 @@ const Transaction: React.FC = () => { const { txhash } = params; const txData = useTxData(provider, txhash); + const addrCollector = useMemo( + () => transactionDataCollector(txData), + [txData] + ); + const resolvedAddresses = useResolvedAddresses(provider, addrCollector); const internalOps = useInternalOperations(provider, txData); const sendsEthToMiner = useMemo(() => { @@ -77,22 +98,29 @@ const Transaction: React.FC = () => { )} </Tab.List> </Tab.Group> - <Switch> - <Route path="/tx/:txhash/" exact> - <Details - txData={txData} - txDesc={txDesc} - userDoc={metadata?.output.userdoc} - devDoc={metadata?.output.devdoc} - internalOps={internalOps} - sendsEthToMiner={sendsEthToMiner} - ethUSDPrice={blockETHUSDPrice} - /> - </Route> - <Route path="/tx/:txhash/logs/" exact> - <Logs txData={txData} metadata={metadata} /> - </Route> - </Switch> + <React.Suspense fallback={null}> + <Switch> + <Route path="/tx/:txhash/" exact> + <Details + txData={txData} + txDesc={txDesc} + userDoc={metadata?.output.userdoc} + devDoc={metadata?.output.devdoc} + internalOps={internalOps} + sendsEthToMiner={sendsEthToMiner} + ethUSDPrice={blockETHUSDPrice} + resolvedAddresses={resolvedAddresses} + /> + </Route> + <Route path="/tx/:txhash/logs/" exact> + <Logs + txData={txData} + metadata={metadata} + resolvedAddresses={resolvedAddresses} + /> + </Route> + </Switch> + </React.Suspense> </SelectionContext.Provider> )} </StandardFrame> diff --git a/src/address/ABI.tsx b/src/address/ABI.tsx deleted file mode 100644 index 7190f4e..0000000 --- a/src/address/ABI.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import React from "react"; -import { Light as SyntaxHighlighter } from "react-syntax-highlighter"; -import hljs from "highlight.js"; -import docco from "react-syntax-highlighter/dist/esm/styles/hljs/docco"; - -import hljsDefineSolidity from "highlightjs-solidity"; -hljsDefineSolidity(hljs); - -type ABIProps = { - abi: any[]; -}; - -const ABI: React.FC<ABIProps> = ({ abi }) => ( - <SyntaxHighlighter - className="w-full h-60 border font-code text-base" - language="json" - style={docco} - showLineNumbers - > - {JSON.stringify(abi, null, " ") ?? ""} - </SyntaxHighlighter> -); - -export default React.memo(ABI); diff --git a/src/address/Contract.tsx b/src/address/Contract.tsx index 7ddfe56..5432f51 100644 --- a/src/address/Contract.tsx +++ b/src/address/Contract.tsx @@ -1,12 +1,7 @@ import React from "react"; -import { Light as SyntaxHighlighter } from "react-syntax-highlighter"; -import hljs from "highlight.js"; -import docco from "react-syntax-highlighter/dist/esm/styles/hljs/docco"; +import { SyntaxHighlighter, docco } from "../highlight-init"; import { useContract } from "../useSourcify"; - -import hljsDefineSolidity from "highlightjs-solidity"; import { useAppConfigContext } from "../useAppConfig"; -hljsDefineSolidity(hljs); type ContractProps = { checksummedAddress: string; diff --git a/src/address/ContractABI.tsx b/src/address/ContractABI.tsx new file mode 100644 index 0000000..edd713c --- /dev/null +++ b/src/address/ContractABI.tsx @@ -0,0 +1,35 @@ +import React from "react"; +import { Tab } from "@headlessui/react"; +import ModeTab from "../components/ModeTab"; +import Copy from "../components/Copy"; +import DecodedABI from "./DecodedABI"; +import RawABI from "./RawABI"; + +type ContractABIProps = { + abi: any[]; +}; + +const ContractABI: React.FC<ContractABIProps> = ({ abi }) => ( + <div className="mb-3"> + <Tab.Group> + <Tab.List className="flex items-baseline space-x-1 mb-1"> + <div className="flex items-baseline space-x-2 text-sm pr-2 py-1"> + <span>ABI</span> + <Copy value={JSON.stringify(abi)} /> + </div> + <ModeTab>Decoded</ModeTab> + <ModeTab>Raw</ModeTab> + </Tab.List> + <Tab.Panels> + <Tab.Panel> + <DecodedABI abi={abi} /> + </Tab.Panel> + <Tab.Panel> + <RawABI abi={abi} /> + </Tab.Panel> + </Tab.Panels> + </Tab.Group> + </div> +); + +export default React.memo(ContractABI); diff --git a/src/address/Contracts.tsx b/src/address/Contracts.tsx index 0745d73..dbaaf83 100644 --- a/src/address/Contracts.tsx +++ b/src/address/Contracts.tsx @@ -5,13 +5,12 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { faChevronDown } from "@fortawesome/free-solid-svg-icons/faChevronDown"; import ContentFrame from "../ContentFrame"; import InfoRow from "../components/InfoRow"; -import Copy from "../components/Copy"; -import ABI from "./ABI"; import Contract from "./Contract"; import { RuntimeContext } from "../useRuntime"; import { Metadata } from "../useSourcify"; import ExternalLink from "../components/ExternalLink"; import { openInRemixURL } from "../url"; +import ContractABI from "./ContractABI"; type ContractsProps = { checksummedAddress: string; @@ -70,13 +69,7 @@ const Contracts: React.FC<ContractsProps> = ({ {rawMetadata !== undefined && rawMetadata !== null && ( <> {rawMetadata.output.abi && ( - <div className="mb-3"> - <div className="flex space-x-2 text-sm border-l border-r border-t rounded-t px-2 py-1"> - <span>ABI</span> - <Copy value={JSON.stringify(rawMetadata.output.abi)} /> - </div> - <ABI abi={rawMetadata.output.abi} /> - </div> + <ContractABI abi={rawMetadata.output.abi} /> )} <div> <Menu> diff --git a/src/address/DecodedABI.tsx b/src/address/DecodedABI.tsx new file mode 100644 index 0000000..83faabc --- /dev/null +++ b/src/address/DecodedABI.tsx @@ -0,0 +1,20 @@ +import { Interface } from "@ethersproject/abi"; +import React from "react"; +import DecodedFragment from "./DecodedFragment"; + +type DecodedABIProps = { + abi: any[]; +}; + +const DecodedABI: React.FC<DecodedABIProps> = ({ abi }) => { + const intf = new Interface(abi); + return ( + <div className="border overflow-x-auto"> + {intf.fragments.map((f, i) => ( + <DecodedFragment key={i} intf={intf} fragment={f} /> + ))} + </div> + ); +}; + +export default React.memo(DecodedABI); diff --git a/src/address/DecodedFragment.tsx b/src/address/DecodedFragment.tsx new file mode 100644 index 0000000..ac06a16 --- /dev/null +++ b/src/address/DecodedFragment.tsx @@ -0,0 +1,78 @@ +import React from "react"; +import { + ConstructorFragment, + EventFragment, + Fragment, + FunctionFragment, + Interface, +} from "@ethersproject/abi"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { faCaretRight } from "@fortawesome/free-solid-svg-icons/faCaretRight"; + +type DecodedFragmentProps = { + intf: Interface; + fragment: Fragment; +}; + +const DecodedFragment: React.FC<DecodedFragmentProps> = ({ + intf, + fragment, +}) => { + let fragmentType: "constructor" | "event" | "function" | undefined; + let sig: string | undefined; + let letter: string | undefined; + let letterBg: string | undefined; + let hashBg: string | undefined; + + if (FunctionFragment.isFunctionFragment(fragment)) { + fragmentType = "function"; + sig = intf.getSighash(fragment); + letter = "F"; + letterBg = "bg-purple-500"; + hashBg = "bg-purple-50"; + } else if (EventFragment.isEventFragment(fragment)) { + fragmentType = "event"; + sig = intf.getEventTopic(fragment); + letter = "E"; + letterBg = "bg-green-300"; + hashBg = "bg-green-50"; + } else if (ConstructorFragment.isConstructorFragment(fragment)) { + fragmentType = "constructor"; + letter = "C"; + letterBg = "bg-blue-500"; + } + + return ( + <div className="flex flex-wrap items-baseline space-x-2 px-2 py-1 hover:bg-gray-100"> + <span className="text-gray-500"> + <FontAwesomeIcon icon={faCaretRight} size="1x" /> + </span> + {letter && ( + <span + className={`flex-shrink-0 text-xs font-code border border-gray-300 rounded-full w-5 h-5 self-center flex items-center justify-center text-white font-bold ${letterBg}`} + > + {letter} + </span> + )} + <span className="text-sm font-code whitespace-nowrap"> + {fragment.format("full")} + </span> + {sig && ( + <span + className={`text-xs border rounded-xl px-2 pt-1 font-code text-gray-600 ${hashBg}`} + title={ + fragmentType === "function" + ? "Method Selector" + : fragmentType === "event" + ? "Topic Hash" + : "" + } + > + {sig} + </span> + )} + </div> + ); +}; + +export default React.memo(DecodedFragment); diff --git a/src/address/RawABI.tsx b/src/address/RawABI.tsx new file mode 100644 index 0000000..bc07e81 --- /dev/null +++ b/src/address/RawABI.tsx @@ -0,0 +1,19 @@ +import React from "react"; +import { SyntaxHighlighter, docco } from "../highlight-init"; + +type RawABIProps = { + abi: any[]; +}; + +const RawABI: React.FC<RawABIProps> = ({ abi }) => ( + <SyntaxHighlighter + className="w-full h-60 border font-code text-base" + language="json" + style={docco} + showLineNumbers + > + {JSON.stringify(abi, null, " ") ?? ""} + </SyntaxHighlighter> +); + +export default React.memo(RawABI); diff --git a/src/api/address-resolver/CompositeAddressResolver.ts b/src/api/address-resolver/CompositeAddressResolver.ts new file mode 100644 index 0000000..55a7318 --- /dev/null +++ b/src/api/address-resolver/CompositeAddressResolver.ts @@ -0,0 +1,28 @@ +import { BaseProvider } from "@ethersproject/providers"; +import { IAddressResolver } from "./address-resolver"; + +export type SelectedResolvedName<T> = [IAddressResolver<T>, T] | null; + +export class CompositeAddressResolver<T = any> + implements IAddressResolver<SelectedResolvedName<T>> +{ + private resolvers: IAddressResolver<T>[] = []; + + addResolver(resolver: IAddressResolver<T>) { + this.resolvers.push(resolver); + } + + async resolveAddress( + provider: BaseProvider, + address: string + ): Promise<SelectedResolvedName<T> | undefined> { + for (const r of this.resolvers) { + const resolvedAddress = await r.resolveAddress(provider, address); + if (resolvedAddress !== undefined) { + return [r, resolvedAddress]; + } + } + + return null; + } +} diff --git a/src/api/address-resolver/ENSAddressResolver.ts b/src/api/address-resolver/ENSAddressResolver.ts new file mode 100644 index 0000000..820a51f --- /dev/null +++ b/src/api/address-resolver/ENSAddressResolver.ts @@ -0,0 +1,15 @@ +import { BaseProvider } from "@ethersproject/providers"; +import { IAddressResolver } from "./address-resolver"; + +export class ENSAddressResolver implements IAddressResolver<string> { + async resolveAddress( + provider: BaseProvider, + address: string + ): Promise<string | undefined> { + const name = await provider.lookupAddress(address); + if (name === null) { + return undefined; + } + return name; + } +} diff --git a/src/api/address-resolver/ERCTokenResolver.ts b/src/api/address-resolver/ERCTokenResolver.ts new file mode 100644 index 0000000..02625dc --- /dev/null +++ b/src/api/address-resolver/ERCTokenResolver.ts @@ -0,0 +1,30 @@ +import { BaseProvider } from "@ethersproject/providers"; +import { Contract } from "@ethersproject/contracts"; +import { IAddressResolver } from "./address-resolver"; +import erc20 from "../../erc20.json"; +import { TokenMeta } from "../../types"; + +export class ERCTokenResolver implements IAddressResolver<TokenMeta> { + async resolveAddress( + provider: BaseProvider, + address: string + ): Promise<TokenMeta | undefined> { + const erc20Contract = new Contract(address, erc20, provider); + try { + const [name, symbol, decimals] = await Promise.all([ + erc20Contract.name(), + erc20Contract.symbol(), + erc20Contract.decimals(), + ]); + return { + name, + symbol, + decimals, + }; + } catch (err) { + // Ignore on purpose; this indicates the probe failed and the address + // is not a token + } + return undefined; + } +} diff --git a/src/api/address-resolver/address-resolver.ts b/src/api/address-resolver/address-resolver.ts new file mode 100644 index 0000000..12d289e --- /dev/null +++ b/src/api/address-resolver/address-resolver.ts @@ -0,0 +1,16 @@ +import React from "react"; +import { BaseProvider } from "@ethersproject/providers"; + +export interface IAddressResolver<T> { + resolveAddress( + provider: BaseProvider, + address: string + ): Promise<T | undefined>; +} + +export type ResolvedAddressRenderer<T> = ( + address: string, + resolvedAddress: T, + linkable: boolean, + dontOverrideColors: boolean +) => React.ReactElement; diff --git a/src/api/address-resolver/index.ts b/src/api/address-resolver/index.ts new file mode 100644 index 0000000..dc72a9f --- /dev/null +++ b/src/api/address-resolver/index.ts @@ -0,0 +1,57 @@ +import { BaseProvider } from "@ethersproject/providers"; +import { ensRenderer } from "../../components/ENSName"; +import { tokenRenderer } from "../../components/TokenName"; +import { IAddressResolver, ResolvedAddressRenderer } from "./address-resolver"; +import { + CompositeAddressResolver, + SelectedResolvedName, +} from "./CompositeAddressResolver"; +import { ENSAddressResolver } from "./ENSAddressResolver"; +import { ERCTokenResolver } from "./ERCTokenResolver"; + +export type ResolvedAddresses = Record<string, SelectedResolvedName<any>>; + +// Create and configure the main resolver +export const ensResolver = new ENSAddressResolver(); +export const ercTokenResolver = new ERCTokenResolver(); + +const _mainResolver = new CompositeAddressResolver(); +_mainResolver.addResolver(ensResolver); +_mainResolver.addResolver(ercTokenResolver); + +export const mainResolver: IAddressResolver<SelectedResolvedName<any>> = + _mainResolver; + +export const resolverRendererRegistry = new Map< + IAddressResolver<any>, + ResolvedAddressRenderer<any> +>(); +resolverRendererRegistry.set(ensResolver, ensRenderer); +resolverRendererRegistry.set(ercTokenResolver, tokenRenderer); + +// TODO: implement progressive resolving +export const batchPopulate = async ( + provider: BaseProvider, + addresses: string[], + currentMap: ResolvedAddresses | undefined +): Promise<ResolvedAddresses> => { + const solvers: Promise<SelectedResolvedName<any> | undefined>[] = []; + const unresolvedAddresses = addresses.filter( + (a) => currentMap?.[a] === undefined + ); + for (const a of unresolvedAddresses) { + solvers.push(mainResolver.resolveAddress(provider, a)); + } + + const resultMap: ResolvedAddresses = currentMap ? { ...currentMap } : {}; + const results = await Promise.all(solvers); + for (let i = 0; i < results.length; i++) { + const r = results[i]; + if (r === undefined) { + continue; + } + resultMap[unresolvedAddresses[i]] = r; + } + + return resultMap; +}; diff --git a/src/block/BlockTransactionResults.tsx b/src/block/BlockTransactionResults.tsx index b911013..f9cfc27 100644 --- a/src/block/BlockTransactionResults.tsx +++ b/src/block/BlockTransactionResults.tsx @@ -8,7 +8,7 @@ import TransactionItem from "../search/TransactionItem"; import { useFeeToggler } from "../search/useFeeToggler"; import { RuntimeContext } from "../useRuntime"; import { SelectionContext, useSelection } from "../useSelection"; -import { useENSCache } from "../useReverseCache"; +import { pageCollector, useResolvedAddresses } from "../useResolvedAddresses"; import { ProcessedTransaction } from "../types"; import { PAGE_SIZE } from "../params"; import { useMultipleETHUSDOracle } from "../usePriceOracle"; @@ -29,7 +29,8 @@ const BlockTransactionResults: React.FC<BlockTransactionResultsProps> = ({ const selectionCtx = useSelection(); const [feeDisplay, feeDisplayToggler] = useFeeToggler(); const { provider } = useContext(RuntimeContext); - const reverseCache = useENSCache(provider, page); + const addrCollector = useMemo(() => pageCollector(page), [page]); + const resolvedAddresses = useResolvedAddresses(provider, addrCollector); const blockTags = useMemo(() => [blockTag], [blockTag]); const priceMap = useMultipleETHUSDOracle(provider, blockTags); @@ -59,7 +60,7 @@ const BlockTransactionResults: React.FC<BlockTransactionResultsProps> = ({ <TransactionItem key={tx.hash} tx={tx} - ensCache={reverseCache} + resolvedAddresses={resolvedAddresses} feeDisplay={feeDisplay} priceMap={priceMap} /> diff --git a/src/components/Address.tsx b/src/components/Address.tsx deleted file mode 100644 index d7694e5..0000000 --- a/src/components/Address.tsx +++ /dev/null @@ -1,13 +0,0 @@ -import React from "react"; - -type AddressProps = { - address: string; -}; - -const Address: React.FC<AddressProps> = ({ address }) => ( - <span className="font-address text-gray-400 truncate" title={address}> - <span className="truncate">{address}</span> - </span> -); - -export default React.memo(Address); diff --git a/src/components/AddressHighlighter.tsx b/src/components/AddressHighlighter.tsx index 1b7df0d..e8078d6 100644 --- a/src/components/AddressHighlighter.tsx +++ b/src/components/AddressHighlighter.tsx @@ -1,4 +1,4 @@ -import React from "react"; +import React, { useMemo } from "react"; import { useSelectionContext } from "../useSelection"; type AddressHighlighterProps = React.PropsWithChildren<{ @@ -10,12 +10,15 @@ const AddressHighlighter: React.FC<AddressHighlighterProps> = ({ children, }) => { const [selection, setSelection] = useSelectionContext(); - const select = () => { - setSelection({ type: "address", content: address }); - }; - const deselect = () => { - setSelection(null); - }; + const [select, deselect] = useMemo(() => { + const _select = () => { + setSelection({ type: "address", content: address }); + }; + const _deselect = () => { + setSelection(null); + }; + return [_select, _deselect]; + }, [setSelection, address]); return ( <div diff --git a/src/components/AddressLink.tsx b/src/components/AddressLink.tsx deleted file mode 100644 index a8fd5c3..0000000 --- a/src/components/AddressLink.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import React from "react"; -import { NavLink } from "react-router-dom"; - -type AddressLinkProps = { - address: string; - text?: string; - dontOverrideColors?: boolean; -}; - -const AddressLink: React.FC<AddressLinkProps> = ({ - address, - text, - dontOverrideColors, -}) => ( - <NavLink - className={`${ - dontOverrideColors ? "" : "text-link-blue hover:text-link-blue-hover" - } font-address truncate`} - to={`/address/${address}`} - > - <span className="truncate" title={text ?? address}> - {text ?? address} - </span> - </NavLink> -); - -export default React.memo(AddressLink); diff --git a/src/components/AddressOrENSName.tsx b/src/components/AddressOrENSName.tsx index 9cb2f9e..62ee289 100644 --- a/src/components/AddressOrENSName.tsx +++ b/src/components/AddressOrENSName.tsx @@ -1,51 +1,49 @@ import React from "react"; -import Address from "./Address"; -import AddressLink from "./AddressLink"; -import ENSName from "./ENSName"; -import ENSNameLink from "./ENSNameLink"; +import { + ResolvedAddresses, + resolverRendererRegistry, +} from "../api/address-resolver"; +import PlainAddress from "./PlainAddress"; type AddressOrENSNameProps = { address: string; - ensName?: string; selectedAddress?: string; - text?: string; dontOverrideColors?: boolean; + resolvedAddresses?: ResolvedAddresses | undefined; }; const AddressOrENSName: React.FC<AddressOrENSNameProps> = ({ address, - ensName, selectedAddress, - text, dontOverrideColors, -}) => ( - <> - {address === selectedAddress ? ( - <> - {ensName ? ( - <ENSName name={ensName} address={address} /> - ) : ( - <Address address={address} /> - )} - </> - ) : ( - <> - {ensName ? ( - <ENSNameLink - name={ensName} - address={address} - dontOverrideColors={dontOverrideColors} - /> - ) : ( - <AddressLink - address={address} - text={text} - dontOverrideColors={dontOverrideColors} - /> - )} - </> - )} - </> -); + resolvedAddresses, +}) => { + const resolvedAddress = resolvedAddresses?.[address]; + const linkable = address !== selectedAddress; -export default React.memo(AddressOrENSName); + if (!resolvedAddress) { + return ( + <PlainAddress + address={address} + linkable={linkable} + dontOverrideColors={dontOverrideColors} + /> + ); + } + + const [resolver, resolvedName] = resolvedAddress; + const renderer = resolverRendererRegistry.get(resolver); + if (renderer === undefined) { + return ( + <PlainAddress + address={address} + linkable={linkable} + dontOverrideColors={dontOverrideColors} + /> + ); + } + + return renderer(address, resolvedName, linkable, !!dontOverrideColors); +}; + +export default AddressOrENSName; diff --git a/src/components/DecoratedAddressLink.tsx b/src/components/DecoratedAddressLink.tsx index 0b38fab..cadc77f 100644 --- a/src/components/DecoratedAddressLink.tsx +++ b/src/components/DecoratedAddressLink.tsx @@ -5,36 +5,32 @@ import { faBomb } from "@fortawesome/free-solid-svg-icons/faBomb"; import { faMoneyBillAlt } from "@fortawesome/free-solid-svg-icons/faMoneyBillAlt"; import { faBurn } from "@fortawesome/free-solid-svg-icons/faBurn"; import { faCoins } from "@fortawesome/free-solid-svg-icons/faCoins"; -import TokenLogo from "./TokenLogo"; import AddressOrENSName from "./AddressOrENSName"; -import { AddressContext, TokenMeta, ZERO_ADDRESS } from "../types"; +import { AddressContext, ZERO_ADDRESS } from "../types"; +import { ResolvedAddresses } from "../api/address-resolver"; type DecoratedAddressLinkProps = { address: string; - ensName?: string; selectedAddress?: string; - text?: string; addressCtx?: AddressContext; creation?: boolean; miner?: boolean; selfDestruct?: boolean; txFrom?: boolean; txTo?: boolean; - tokenMeta?: TokenMeta; + resolvedAddresses?: ResolvedAddresses | undefined; }; -const DecoratedAddresssLink: React.FC<DecoratedAddressLinkProps> = ({ +const DecoratedAddressLink: React.FC<DecoratedAddressLinkProps> = ({ address, - ensName, selectedAddress, - text, addressCtx, creation, miner, selfDestruct, txFrom, txTo, - tokenMeta, + resolvedAddresses, }) => { const mint = addressCtx === AddressContext.FROM && address === ZERO_ADDRESS; const burn = addressCtx === AddressContext.TO && address === ZERO_ADDRESS; @@ -74,20 +70,14 @@ const DecoratedAddresssLink: React.FC<DecoratedAddressLinkProps> = ({ <FontAwesomeIcon icon={faCoins} size="1x" /> </span> )} - {tokenMeta && ( - <div className="self-center"> - <TokenLogo address={address} name={tokenMeta.name} /> - </div> - )} <AddressOrENSName address={address} - ensName={ensName} selectedAddress={selectedAddress} - text={text} dontOverrideColors={mint || burn} + resolvedAddresses={resolvedAddresses} /> </div> ); }; -export default React.memo(DecoratedAddresssLink); +export default React.memo(DecoratedAddressLink); diff --git a/src/components/ENSName.tsx b/src/components/ENSName.tsx index 7bc8032..f12f416 100644 --- a/src/components/ENSName.tsx +++ b/src/components/ENSName.tsx @@ -1,25 +1,75 @@ import React from "react"; +import { NavLink } from "react-router-dom"; +import { ResolvedAddressRenderer } from "../api/address-resolver/address-resolver"; import ENSLogo from "./ensLogo.svg"; type ENSNameProps = { name: string; address: string; + linkable: boolean; + dontOverrideColors?: boolean; }; -const ENSName: React.FC<ENSNameProps> = ({ name, address }) => ( - <div - className="flex items-baseline space-x-1 font-sans text-gray-700 truncate" - title={`${name}: ${address}`} - > +const ENSName: React.FC<ENSNameProps> = ({ + name, + address, + linkable, + dontOverrideColors, +}) => { + if (linkable) { + return ( + <NavLink + className={`flex items-baseline space-x-1 font-sans ${ + dontOverrideColors ? "" : "text-link-blue hover:text-link-blue-hover" + } truncate`} + to={`/address/${name}`} + title={`${name}: ${address}`} + > + <Content linkable={true} name={name} /> + </NavLink> + ); + } + + return ( + <div + className="flex items-baseline space-x-1 font-sans text-gray-700 truncate" + title={`${name}: ${address}`} + > + <Content linkable={false} name={name} /> + </div> + ); +}; + +type ContentProps = { + linkable: boolean; + name: string; +}; + +const Content: React.FC<ContentProps> = ({ linkable, name }) => ( + <> <img - className="self-center filter grayscale" + className={`self-center ${linkable ? "" : "filter grayscale"}`} src={ENSLogo} alt="ENS Logo" width={12} height={12} /> <span className="truncate">{name}</span> - </div> + </> ); -export default React.memo(ENSName); +export const ensRenderer: ResolvedAddressRenderer<string> = ( + address, + resolvedAddress, + linkable, + dontOverrideColors +) => ( + <ENSName + address={address} + name={resolvedAddress} + linkable={linkable} + dontOverrideColors={dontOverrideColors} + /> +); + +export default ENSName; diff --git a/src/components/ENSNameLink.tsx b/src/components/ENSNameLink.tsx deleted file mode 100644 index c1da646..0000000 --- a/src/components/ENSNameLink.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import React from "react"; -import { NavLink } from "react-router-dom"; -import ENSLogo from "./ensLogo.svg"; - -type ENSNameLinkProps = { - name: string; - address: string; - dontOverrideColors?: boolean; -}; - -const ENSNameLink: React.FC<ENSNameLinkProps> = ({ - name, - address, - dontOverrideColors, -}) => ( - <NavLink - className={`flex items-baseline space-x-1 font-sans ${ - dontOverrideColors ? "" : "text-link-blue hover:text-link-blue-hover" - } truncate`} - to={`/address/${name}`} - title={`${name}: ${address}`} - > - <img - className="self-center" - src={ENSLogo} - alt="ENS Logo" - width={12} - height={12} - /> - <span className="truncate">{name}</span> - </NavLink> -); - -export default React.memo(ENSNameLink); diff --git a/src/components/InternalTransactionOperation.tsx b/src/components/InternalTransactionOperation.tsx index 095162f..7de3bb2 100644 --- a/src/components/InternalTransactionOperation.tsx +++ b/src/components/InternalTransactionOperation.tsx @@ -3,17 +3,23 @@ import InternalTransfer from "./InternalTransfer"; import InternalSelfDestruct from "./InternalSelfDestruct"; import InternalCreate from "./InternalCreate"; import { TransactionData, InternalOperation, OperationType } from "../types"; +import { ResolvedAddresses } from "../api/address-resolver"; type InternalTransactionOperationProps = { txData: TransactionData; internalOp: InternalOperation; + resolvedAddresses: ResolvedAddresses | undefined; }; const InternalTransactionOperation: React.FC<InternalTransactionOperationProps> = - ({ txData, internalOp }) => ( + ({ txData, internalOp, resolvedAddresses }) => ( <> {internalOp.type === OperationType.TRANSFER && ( - <InternalTransfer txData={txData} internalOp={internalOp} /> + <InternalTransfer + txData={txData} + internalOp={internalOp} + resolvedAddresses={resolvedAddresses} + /> )} {internalOp.type === OperationType.SELF_DESTRUCT && ( <InternalSelfDestruct txData={txData} internalOp={internalOp} /> diff --git a/src/components/InternalTransfer.tsx b/src/components/InternalTransfer.tsx index dc53d05..2958452 100644 --- a/src/components/InternalTransfer.tsx +++ b/src/components/InternalTransfer.tsx @@ -5,15 +5,18 @@ import { faAngleRight } from "@fortawesome/free-solid-svg-icons/faAngleRight"; import AddressHighlighter from "./AddressHighlighter"; import DecoratedAddressLink from "./DecoratedAddressLink"; import { TransactionData, InternalOperation } from "../types"; +import { ResolvedAddresses } from "../api/address-resolver"; type InternalTransferProps = { txData: TransactionData; internalOp: InternalOperation; + resolvedAddresses: ResolvedAddresses | undefined; }; const InternalTransfer: React.FC<InternalTransferProps> = ({ txData, internalOp, + resolvedAddresses, }) => { const fromMiner = txData.confirmedData?.miner !== undefined && diff --git a/src/components/PlainAddress.tsx b/src/components/PlainAddress.tsx new file mode 100644 index 0000000..fbc37ca --- /dev/null +++ b/src/components/PlainAddress.tsx @@ -0,0 +1,36 @@ +import React from "react"; +import { NavLink } from "react-router-dom"; + +type PlainAddressProps = { + address: string; + linkable: boolean; + dontOverrideColors: boolean | undefined; +}; + +const PlainAddress: React.FC<PlainAddressProps> = ({ + address, + linkable, + dontOverrideColors, +}) => { + if (linkable) { + return ( + <NavLink + className={`${ + dontOverrideColors ? "" : "text-link-blue hover:text-link-blue-hover" + } font-address truncate`} + to={`/address/${address}`} + title={address} + > + {address} + </NavLink> + ); + } + + return ( + <span className="font-address text-gray-400 truncate" title={address}> + {address} + </span> + ); +}; + +export default PlainAddress; diff --git a/src/components/TokenLogo.tsx b/src/components/TokenLogo.tsx index c6f5b8b..8568a0b 100644 --- a/src/components/TokenLogo.tsx +++ b/src/components/TokenLogo.tsx @@ -9,7 +9,7 @@ type TokenLogoProps = { }; const TokenLogo: React.FC<TokenLogoProps> = (props) => ( - <Suspense fallback={<></>}> + <Suspense fallback={null}> <InternalTokenLogo {...props} /> </Suspense> ); diff --git a/src/components/TokenName.tsx b/src/components/TokenName.tsx new file mode 100644 index 0000000..5c3e91b --- /dev/null +++ b/src/components/TokenName.tsx @@ -0,0 +1,91 @@ +import React from "react"; +import { NavLink } from "react-router-dom"; +import TokenLogo from "./TokenLogo"; +import { ResolvedAddressRenderer } from "../api/address-resolver/address-resolver"; +import { TokenMeta } from "../types"; + +type TokenNameProps = { + address: string; + name: string; + symbol: string; + linkable: boolean; + dontOverrideColors?: boolean; +}; + +const TokenName: React.FC<TokenNameProps> = ({ + address, + name, + symbol, + linkable, + dontOverrideColors, +}) => { + if (linkable) { + return ( + <NavLink + className={`flex items-baseline space-x-1 font-sans ${ + dontOverrideColors ? "" : "text-link-blue hover:text-link-blue-hover" + } truncate`} + to={`/address/${address}`} + title={`${name} (${symbol}): ${address}`} + > + <Content + address={address} + linkable={true} + name={name} + symbol={symbol} + /> + </NavLink> + ); + } + + return ( + <div + className="flex items-baseline space-x-1 font-sans text-gray-700 truncate" + title={`${name} (${symbol}): ${address}`} + > + <Content address={address} linkable={false} name={name} symbol={symbol} /> + </div> + ); +}; + +type ContentProps = { + address: string; + name: string; + symbol: string; + linkable: boolean; +}; + +const Content: React.FC<ContentProps> = ({ + address, + name, + symbol, + linkable, +}) => ( + <> + <div + className={`self-center w-5 h-5 ${linkable ? "" : "filter grayscale"}`} + > + <TokenLogo address={address} name={name} /> + </div> + <span className="truncate"> + {name} ({symbol}) + </span> + </> +); + +export const tokenRenderer: ResolvedAddressRenderer<TokenMeta> = ( + address, + tokenMeta, + linkable, + dontOverrideColors +) => ( + <TokenName + address={address} + name={tokenMeta.name} + symbol={tokenMeta.symbol} + linkable={linkable} + dontOverrideColors={dontOverrideColors} + /> +); + +export default TokenName; diff --git a/src/highlight-init.ts b/src/highlight-init.ts new file mode 100644 index 0000000..f8318eb --- /dev/null +++ b/src/highlight-init.ts @@ -0,0 +1,14 @@ +import { Light as SyntaxHighlighter } from "react-syntax-highlighter"; + +// @ts-ignore +import hljs from "highlight.js/lib/core"; + +// @ts-ignore +import json from "highlight.js/lib/languages/json"; +import docco from "react-syntax-highlighter/dist/esm/styles/hljs/docco"; + +import hljsDefineSolidity from "highlightjs-solidity"; +hljsDefineSolidity(hljs); +hljs.registerLanguage("json", json); + +export { SyntaxHighlighter, docco }; diff --git a/src/index.tsx b/src/index.tsx index a1b9d79..11695da 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,15 +1,28 @@ import React from "react"; import ReactDOM from "react-dom"; +import { HelmetProvider, Helmet } from "react-helmet-async"; import "@fontsource/space-grotesk/index.css"; import "@fontsource/roboto/index.css"; import "@fontsource/roboto-mono/index.css"; +import spaceGrotesk from "@fontsource/space-grotesk/files/space-grotesk-latin-400-normal.woff2"; import "./index.css"; import App from "./App"; import reportWebVitals from "./reportWebVitals"; ReactDOM.render( <React.StrictMode> - <App /> + <HelmetProvider> + <Helmet> + <link + rel="preload" + href={spaceGrotesk} + as="font" + type="font/woff2" + crossOrigin="true" + /> + </Helmet> + <App /> + </HelmetProvider> </React.StrictMode>, document.getElementById("root") ); diff --git a/public/otter.jpg b/src/otter.jpg similarity index 100% rename from public/otter.jpg rename to src/otter.jpg diff --git a/src/react-app-env.d.ts b/src/react-app-env.d.ts index 625fe40..dc08ce3 100644 --- a/src/react-app-env.d.ts +++ b/src/react-app-env.d.ts @@ -1,3 +1,5 @@ /// <reference types="react-scripts" /> declare module "use-keyboard-shortcut"; declare module "highlightjs-solidity"; +declare module "*.woff"; +declare module "*.woff2"; diff --git a/src/search/TransactionItem.tsx b/src/search/TransactionItem.tsx index 76e58e7..2e6132d 100644 --- a/src/search/TransactionItem.tsx +++ b/src/search/TransactionItem.tsx @@ -14,14 +14,15 @@ import TransactionDirection, { Flags, } from "../components/TransactionDirection"; import TransactionValue from "../components/TransactionValue"; -import { ENSReverseCache, ProcessedTransaction } from "../types"; +import { ProcessedTransaction } from "../types"; import { FeeDisplay } from "./useFeeToggler"; import { formatValue } from "../components/formatter"; import ETH2USDValue from "../components/ETH2USDValue"; +import { ResolvedAddresses } from "../api/address-resolver"; type TransactionItemProps = { tx: ProcessedTransaction; - ensCache?: ENSReverseCache; + resolvedAddresses?: ResolvedAddresses; selectedAddress?: string; feeDisplay: FeeDisplay; priceMap: Record<BlockTag, BigNumber>; @@ -29,7 +30,7 @@ type TransactionItemProps = { const TransactionItem: React.FC<TransactionItemProps> = ({ tx, - ensCache, + resolvedAddresses, selectedAddress, feeDisplay, priceMap, @@ -50,12 +51,6 @@ const TransactionItem: React.FC<TransactionItemProps> = ({ } } - const ensFrom = ensCache && tx.from && ensCache[tx.from]; - const ensTo = ensCache && tx.to && ensCache[tx.to]; - const ensCreated = - ensCache && - tx.createdContractAddress && - ensCache[tx.createdContractAddress]; const flash = tx.gasPrice.isZero() && tx.internalMinerInteraction; return ( @@ -87,9 +82,9 @@ const TransactionItem: React.FC<TransactionItemProps> = ({ <AddressHighlighter address={tx.from}> <DecoratedAddressLink address={tx.from} - ensName={ensFrom} selectedAddress={selectedAddress} miner={tx.miner === tx.from} + resolvedAddresses={resolvedAddresses} /> </AddressHighlighter> )} @@ -107,18 +102,18 @@ const TransactionItem: React.FC<TransactionItemProps> = ({ <AddressHighlighter address={tx.to}> <DecoratedAddressLink address={tx.to} - ensName={ensTo} selectedAddress={selectedAddress} miner={tx.miner === tx.to} + resolvedAddresses={resolvedAddresses} /> </AddressHighlighter> ) : ( <AddressHighlighter address={tx.createdContractAddress!}> <DecoratedAddressLink address={tx.createdContractAddress!} - ensName={ensCreated} selectedAddress={selectedAddress} creation + resolvedAddresses={resolvedAddresses} /> </AddressHighlighter> )} @@ -144,4 +139,4 @@ const TransactionItem: React.FC<TransactionItemProps> = ({ ); }; -export default React.memo(TransactionItem); +export default TransactionItem; diff --git a/public/sourcify.svg b/src/sourcify.svg similarity index 100% rename from public/sourcify.svg rename to src/sourcify.svg diff --git a/src/special/london/Blocks.tsx b/src/special/london/Blocks.tsx index 64fcba8..d100717 100644 --- a/src/special/london/Blocks.tsx +++ b/src/special/london/Blocks.tsx @@ -103,7 +103,7 @@ const Blocks: React.FC<BlocksProps> = ({ latestBlock, targetBlockNumber }) => { ); return ( - <div className="w-full mb-auto"> + <div className="w-full flex-grow"> <div className="px-9 pt-3 pb-12 divide-y-2"> <div className="relative"> <div className="flex justify-center items-baseline space-x-2 px-3 pb-2 text-lg text-orange-500 "> diff --git a/src/special/london/London.tsx b/src/special/london/London.tsx index 0663796..aba0684 100644 --- a/src/special/london/London.tsx +++ b/src/special/london/London.tsx @@ -9,7 +9,7 @@ const London: React.FC = () => { const { provider } = useContext(RuntimeContext); const block = useLatestBlock(provider); if (!provider || !block) { - return <></>; + return <div className="flex-grow"></div>; } // Display countdown diff --git a/src/special/london/chart.ts b/src/special/london/chart.ts index 8c57fdf..cb64508 100644 --- a/src/special/london/chart.ts +++ b/src/special/london/chart.ts @@ -2,7 +2,7 @@ import { commify } from "@ethersproject/units"; import { ChartData, ChartOptions } from "chart.js"; import { ExtendedBlock } from "../../useErigonHooks"; -export const burntFeesChartOptions: ChartOptions = { +export const burntFeesChartOptions: ChartOptions<"line"> = { animation: false, plugins: { legend: { @@ -45,7 +45,9 @@ export const burntFeesChartOptions: ChartOptions = { }, }; -export const burntFeesChartData = (blocks: ExtendedBlock[]): ChartData => ({ +export const burntFeesChartData = ( + blocks: ExtendedBlock[] +): ChartData<"line"> => ({ labels: blocks.map((b) => b.number.toString()).reverse(), datasets: [ { @@ -68,7 +70,7 @@ export const burntFeesChartData = (blocks: ExtendedBlock[]): ChartData => ({ ], }); -export const gasChartOptions: ChartOptions = { +export const gasChartOptions: ChartOptions<"line"> = { animation: false, interaction: { mode: "index", @@ -112,7 +114,7 @@ export const gasChartOptions: ChartOptions = { }, }; -export const gasChartData = (blocks: ExtendedBlock[]): ChartData => ({ +export const gasChartData = (blocks: ExtendedBlock[]): ChartData<"line"> => ({ labels: blocks.map((b) => b.number.toString()).reverse(), datasets: [ { @@ -148,7 +150,7 @@ export const gasChartData = (blocks: ExtendedBlock[]): ChartData => ({ borderColor: "#B91C1CF0", tension: 0.2, pointStyle: "crossRot", - radius: 5, + pointRadius: 5, }, { label: "Base fee (wei)", diff --git a/src/transaction/Details.tsx b/src/transaction/Details.tsx index 4746cc5..9c9e29d 100644 --- a/src/transaction/Details.tsx +++ b/src/transaction/Details.tsx @@ -38,6 +38,7 @@ import ModeTab from "../components/ModeTab"; import DecodedParamsTable from "./decoder/DecodedParamsTable"; import { rawInputTo4Bytes, use4Bytes } from "../use4Bytes"; import { DevDoc, UserDoc } from "../useSourcify"; +import { ResolvedAddresses } from "../api/address-resolver"; type DetailsProps = { txData: TransactionData; @@ -47,6 +48,7 @@ type DetailsProps = { internalOps?: InternalOperation[]; sendsEthToMiner: boolean; ethUSDPrice: BigNumber | undefined; + resolvedAddresses: ResolvedAddresses | undefined; }; const Details: React.FC<DetailsProps> = ({ @@ -57,6 +59,7 @@ const Details: React.FC<DetailsProps> = ({ internalOps, sendsEthToMiner, ethUSDPrice, + resolvedAddresses, }) => { const hasEIP1559 = txData.confirmedData?.blockBaseFeePerGas !== undefined && @@ -154,6 +157,7 @@ const Details: React.FC<DetailsProps> = ({ address={txData.from} miner={txData.from === txData.confirmedData?.miner} txFrom + resolvedAddresses={resolvedAddresses} /> </AddressHighlighter> <Copy value={txData.from} /> @@ -171,6 +175,7 @@ const Details: React.FC<DetailsProps> = ({ address={txData.to} miner={txData.to === txData.confirmedData?.miner} txTo + resolvedAddresses={resolvedAddresses} /> </AddressHighlighter> <Copy value={txData.to} /> @@ -188,6 +193,7 @@ const Details: React.FC<DetailsProps> = ({ address={txData.confirmedData.createdContractAddress!} creation txTo + resolvedAddresses={resolvedAddresses} /> </AddressHighlighter> <Copy value={txData.confirmedData.createdContractAddress!} /> @@ -200,6 +206,7 @@ const Details: React.FC<DetailsProps> = ({ key={i} txData={txData} internalOp={op} + resolvedAddresses={resolvedAddresses} /> ))} </div> @@ -219,6 +226,7 @@ const Details: React.FC<DetailsProps> = ({ t={t} txData={txData} tokenMeta={txData.tokenMetas[t.token]} + resolvedAddresses={resolvedAddresses} /> ))} </div> diff --git a/src/transaction/LogEntry.tsx b/src/transaction/LogEntry.tsx index 23ab883..2993e16 100644 --- a/src/transaction/LogEntry.tsx +++ b/src/transaction/LogEntry.tsx @@ -10,14 +10,21 @@ import DecodedParamsTable from "./decoder/DecodedParamsTable"; import DecodedLogSignature from "./decoder/DecodedLogSignature"; import { TransactionData } from "../types"; import { useTopic0 } from "../useTopic0"; +import { ResolvedAddresses } from "../api/address-resolver"; type LogEntryProps = { txData: TransactionData; log: Log; logDesc: LogDescription | null | undefined; + resolvedAddresses: ResolvedAddresses | undefined; }; -const LogEntry: React.FC<LogEntryProps> = ({ txData, log, logDesc }) => { +const LogEntry: React.FC<LogEntryProps> = ({ + txData, + log, + logDesc, + resolvedAddresses, +}) => { const rawTopic0 = log.topics[0]; const topic0 = useTopic0(rawTopic0); @@ -62,6 +69,7 @@ const LogEntry: React.FC<LogEntryProps> = ({ txData, log, logDesc }) => { miner={log.address === txData.confirmedData?.miner} txFrom={log.address === txData.from} txTo={log.address === txData.to} + resolvedAddresses={resolvedAddresses} /> </AddressHighlighter> <Copy value={log.address} /> diff --git a/src/transaction/Logs.tsx b/src/transaction/Logs.tsx index 45fe491..1fd4207 100644 --- a/src/transaction/Logs.tsx +++ b/src/transaction/Logs.tsx @@ -5,13 +5,15 @@ import LogEntry from "./LogEntry"; import { TransactionData } from "../types"; import { useAppConfigContext } from "../useAppConfig"; import { Metadata, useMultipleMetadata } from "../useSourcify"; +import { ResolvedAddresses } from "../api/address-resolver"; type LogsProps = { txData: TransactionData; metadata: Metadata | null | undefined; + resolvedAddresses: ResolvedAddresses | undefined; }; -const Logs: React.FC<LogsProps> = ({ txData, metadata }) => { +const Logs: React.FC<LogsProps> = ({ txData, metadata, resolvedAddresses }) => { const baseMetadatas = useMemo((): Record<string, Metadata | null> => { if (!txData.to || metadata === undefined) { return {}; @@ -70,6 +72,7 @@ const Logs: React.FC<LogsProps> = ({ txData, metadata }) => { txData={txData} log={l} logDesc={logDescs?.[i]} + resolvedAddresses={resolvedAddresses} /> ))} </> diff --git a/src/types.ts b/src/types.ts index 5904b31..12763bb 100644 --- a/src/types.ts +++ b/src/types.ts @@ -32,10 +32,6 @@ export type TransactionChunk = { lastPage: boolean; }; -export type ENSReverseCache = { - [address: string]: string; -}; - export type TransactionData = { transactionHash: string; from: string; diff --git a/src/url.ts b/src/url.ts index a229fd1..4639738 100644 --- a/src/url.ts +++ b/src/url.ts @@ -23,16 +23,12 @@ export enum SourcifySource { // Centralized Sourcify servers CENTRAL_SERVER, - - // Snapshot server - CUSTOM_SNAPSHOT_SERVER, } const sourcifyIPNS = "k51qzi5uqu5dll0ocge71eudqnrgnogmbr37gsgl12uubsinphjoknl6bbi41p"; const defaultIpfsGatewayPrefix = `https://ipfs.io/ipns/${sourcifyIPNS}`; const sourcifyHttpRepoPrefix = `https://repo.sourcify.dev`; -const snapshotPrefix = "http://localhost:3006"; const resolveSourcifySource = (source: SourcifySource) => { if (source === SourcifySource.IPFS_IPNS) { @@ -41,7 +37,8 @@ const resolveSourcifySource = (source: SourcifySource) => { if (source === SourcifySource.CENTRAL_SERVER) { return sourcifyHttpRepoPrefix; } - return snapshotPrefix; + + throw new Error(`Unknown Sourcify intergration source code: ${source}`); }; export const sourcifyMetadata = ( diff --git a/src/useResolvedAddresses.ts b/src/useResolvedAddresses.ts new file mode 100644 index 0000000..1936da0 --- /dev/null +++ b/src/useResolvedAddresses.ts @@ -0,0 +1,92 @@ +import { useState, useEffect, useRef } from "react"; +import { JsonRpcProvider } from "@ethersproject/providers"; +import { ProcessedTransaction, TransactionData } from "./types"; +import { batchPopulate, ResolvedAddresses } from "./api/address-resolver"; + +export type AddressCollector = () => string[]; + +export const pageCollector = + (page: ProcessedTransaction[] | undefined): AddressCollector => + () => { + if (!page) { + return []; + } + + const uniqueAddresses = new Set<string>(); + for (const tx of page) { + if (tx.from) { + uniqueAddresses.add(tx.from); + } + if (tx.to) { + uniqueAddresses.add(tx.to); + } + } + + return Array.from(uniqueAddresses); + }; + +export const transactionDataCollector = + (txData: TransactionData | null | undefined): AddressCollector => + () => { + if (!txData) { + return []; + } + + const uniqueAddresses = new Set<string>(); + + // Standard fields + uniqueAddresses.add(txData.from); + if (txData.to) { + uniqueAddresses.add(txData.to); + } + if (txData.confirmedData?.createdContractAddress) { + uniqueAddresses.add(txData.confirmedData?.createdContractAddress); + } + + // Dig token transfers + for (const t of txData.tokenTransfers) { + uniqueAddresses.add(t.from); + uniqueAddresses.add(t.to); + uniqueAddresses.add(t.token); + } + + // Dig log addresses + if (txData.confirmedData) { + for (const l of txData.confirmedData.logs) { + uniqueAddresses.add(l.address); + // TODO: find a way to dig over decoded address log attributes + } + } + + return Array.from(uniqueAddresses); + }; + +export const useResolvedAddresses = ( + provider: JsonRpcProvider | undefined, + addrCollector: AddressCollector +) => { + const [names, setNames] = useState<ResolvedAddresses>(); + const ref = useRef<ResolvedAddresses | undefined>(); + useEffect(() => { + ref.current = names; + }); + + useEffect( + () => { + if (!provider) { + return; + } + + const populate = async () => { + const _addresses = addrCollector(); + const _names = await batchPopulate(provider, _addresses, ref.current); + setNames(_names); + }; + populate(); + }, + // DON'T put names variables in dependency array; this is intentional; useRef + [provider, addrCollector] + ); + + return names; +}; diff --git a/src/useReverseCache.ts b/src/useReverseCache.ts deleted file mode 100644 index 86c6472..0000000 --- a/src/useReverseCache.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { useState, useEffect } from "react"; -import { JsonRpcProvider } from "@ethersproject/providers"; -import { ENSReverseCache, ProcessedTransaction } from "./types"; - -export const useENSCache = ( - provider?: JsonRpcProvider, - page?: ProcessedTransaction[] -) => { - const [reverseCache, setReverseCache] = useState<ENSReverseCache>(); - - useEffect(() => { - if (!provider || !page) { - return; - } - - const addrSet = new Set<string>(); - for (const tx of page) { - if (tx.from) { - addrSet.add(tx.from); - } - if (tx.to) { - addrSet.add(tx.to); - } - } - const addresses = Array.from(addrSet); - - const reverseResolve = async () => { - const solvers: Promise<string>[] = []; - for (const a of addresses) { - solvers.push(provider.lookupAddress(a)); - } - - const results = await Promise.all(solvers); - const cache: ENSReverseCache = {}; - for (let i = 0; i < results.length; i++) { - if (results[i] === null) { - continue; - } - cache[addresses[i]] = results[i]; - } - setReverseCache(cache); - }; - reverseResolve(); - }, [provider, page]); - - return reverseCache; -}; diff --git a/src/useSelection.ts b/src/useSelection.ts index b34dc81..03a2a92 100644 --- a/src/useSelection.ts +++ b/src/useSelection.ts @@ -1,23 +1,29 @@ -import React, { useState, useContext } from "react"; +import { + Dispatch, + SetStateAction, + createContext, + useState, + useContext, +} from "react"; export type Selection = { type: "address" | "value"; content: string; }; +type OptionalSelection = Selection | null; + export const useSelection = (): [ - Selection | null, - React.Dispatch<React.SetStateAction<Selection | null>> + OptionalSelection, + Dispatch<SetStateAction<OptionalSelection>> ] => { - const [selection, setSelection] = useState<Selection | null>(null); - return [selection, setSelection]; + return useState<OptionalSelection>(null); }; -export const SelectionContext = React.createContext< - ReturnType<typeof useSelection> ->(null!); +export const SelectionContext = createContext<ReturnType<typeof useSelection>>( + null! +); export const useSelectionContext = () => { - const ctx = useContext(SelectionContext); - return ctx; + return useContext(SelectionContext); }; diff --git a/topic0 b/topic0 index 52559d5..5026a20 160000 --- a/topic0 +++ b/topic0 @@ -1 +1 @@ -Subproject commit 52559d5690d491f8191a2d3fdb3c037516adc68f +Subproject commit 5026a20b712c1cad66878821c38e1f070e4a3799