Merge branch 'release/v2022.02.03-otterscan'
This commit is contained in:
commit
fd9778443d
|
@ -4,3 +4,4 @@ updates:
|
|||
directory: "/"
|
||||
schedule:
|
||||
interval: "daily"
|
||||
open-pull-requests-limit: 20
|
||||
|
|
|
@ -74,9 +74,11 @@ All methods are prefixed with the `ots_` namespace in order to make it clear it
|
|||
| `ots_getTransactionError` | Extract the transaction raw error output. | In order to get the error message or custom error from a failed transaction, you need to get its error output and decoded it. This info is not exposed through standard APIs. |
|
||||
| `ots_traceTransaction` | Extract all variations of calls, contract creation and self-destructs and returns a call tree. | This is an optimized version of tracing; regular tracing returns lots of data, and custom tracing using a JS tracer could be slow. |
|
||||
| `ots_getBlockDetails` | Tailor-made and expanded version of `eth_getBlock*` for block details page in Otterscan. | The standard `eth_getBlock*` is quite verbose and it doesn't bring all info we need. We explicitly remove the transaction list (unnecessary for that page and also this call doesn't scale well), log blooms and other unnecessary fields. We add issuance and block fees info and return all of this in just one call. |
|
||||
| `ots_getBlockDetailsByHash` | Same as `ots_getBlockDetails`, but it accepts a block hash as parameter. | |
|
||||
| `ots_getBlockTransactions` | Get paginated transactions for a certain block. Also remove some verbose fields like logs. | As block size increases, getting all transactions from a block at once doesn't scale, so the first point here is to add pagination support. The second point is that receipts may have big, unnecessary information, like logs. So we cap all of them to save network bandwidth. |
|
||||
| `ots_searchTransactionsBefore` and `ots_searchTransactionsAfter` | Gets paginated inbound/outbound transaction calls for a certain address. | There is no native support for any kind of transaction search in the standard JSON-RPC API. We don't want to introduce an additional indexer middleware in Otterscan, so we implemented in-node search. |
|
||||
| `ots_getTransactionBySenderAndNonce` | Gets the transaction hash for a certain sender address, given its nonce. | There is no native support for this search in the standard JSON-RPC API. Otterscan needs it to allow user navigation between nonces from the same sender address. |
|
||||
| `ots_getContractCreator` | Gets the transaction hash and the address who created a contract. | No way to get this info from the standard JSON-RPC API. |
|
||||
|
||||
## Method details
|
||||
|
||||
|
@ -335,3 +337,40 @@ Response:
|
|||
"result": "0x021304206b2517c3f8f2df07014a55b79aac2ae097488fa807cc88eccd851a50"
|
||||
}
|
||||
```
|
||||
|
||||
### `ots_getContractCreator`
|
||||
|
||||
Given an ETH contract address, returns the tx hash and the direct address who created the contract.
|
||||
|
||||
If the address is an EOA or a destroyed contract, it returns `null`.
|
||||
|
||||
Parameters:
|
||||
|
||||
1. `address` - The ETH address that may contain a contract.
|
||||
|
||||
Returns:
|
||||
|
||||
- `object` containing the following attributes, or `null` if the address does not contain a contract.
|
||||
- `hash` - The tx hash of the transaction who created the contract.
|
||||
- `creator` - The address who directly created the contract. Note that for simple transactions that directly deploy a contract this corresponds to the EOA in the `from` field of the transaction. For deployer contracts, i.e., the contract is created as a result of a method call, this corresponds to the address of the contract who created it.
|
||||
|
||||
Example: get who created the Uniswap V3 Router contract.
|
||||
|
||||
Request:
|
||||
|
||||
```
|
||||
$ curl -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0", "id": 1, "method":"ots_getContractCreator","params":["0xE592427A0AEce92De3Edee1F18E0157C05861564"]}' http://127.0.0.1:8545
|
||||
```
|
||||
|
||||
Response:
|
||||
|
||||
```
|
||||
{
|
||||
"jsonrpc": "2.0",
|
||||
"id": 1,
|
||||
"result": {
|
||||
"hash": "0xe881c43cd88063e84a1d0283f41ee5348239b259c0d17a7e2e4552da3f4b2bc7",
|
||||
"creator": "0x6c9fc64a53c1b71fb3f9af64d1ae3a4931a5f4e9"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
|
|
@ -10,31 +10,31 @@
|
|||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@blackbox-vision/react-qr-reader": "^5.0.0",
|
||||
"@chainlink/contracts": "^0.2.2",
|
||||
"@chainlink/contracts": "^0.4.0",
|
||||
"@craco/craco": "^6.4.3",
|
||||
"@fontsource/fira-code": "^4.5.2",
|
||||
"@fontsource/roboto": "^4.5.1",
|
||||
"@fontsource/roboto-mono": "^4.5.0",
|
||||
"@fontsource/space-grotesk": "^4.5.0",
|
||||
"@fontsource/fira-code": "^4.5.5",
|
||||
"@fontsource/roboto": "^4.5.3",
|
||||
"@fontsource/roboto-mono": "^4.5.3",
|
||||
"@fontsource/space-grotesk": "^4.5.3",
|
||||
"@fortawesome/fontawesome-svg-core": "^1.2.36",
|
||||
"@fortawesome/free-brands-svg-icons": "^5.15.4",
|
||||
"@fortawesome/free-regular-svg-icons": "^5.15.4",
|
||||
"@fortawesome/free-solid-svg-icons": "^5.15.4",
|
||||
"@fortawesome/react-fontawesome": "^0.1.16",
|
||||
"@headlessui/react": "^1.4.2",
|
||||
"@testing-library/jest-dom": "^5.16.1",
|
||||
"@fortawesome/react-fontawesome": "^0.1.17",
|
||||
"@headlessui/react": "^1.4.3",
|
||||
"@testing-library/jest-dom": "^5.16.2",
|
||||
"@testing-library/react": "^11.1.0",
|
||||
"@testing-library/user-event": "^12.1.10",
|
||||
"@types/jest": "^26.0.24",
|
||||
"@types/node": "^16.11.14",
|
||||
"@types/react": "^17.0.38",
|
||||
"@types/react": "^17.0.39",
|
||||
"@types/react-blockies": "^1.4.1",
|
||||
"@types/react-dom": "^17.0.11",
|
||||
"@types/react-highlight": "^0.12.5",
|
||||
"@types/react-syntax-highlighter": "^13.5.2",
|
||||
"chart.js": "^3.7.0",
|
||||
"ethers": "^5.5.2",
|
||||
"highlightjs-solidity": "^2.0.3",
|
||||
"chart.js": "^3.7.1",
|
||||
"ethers": "^5.5.4",
|
||||
"highlightjs-solidity": "^2.0.4",
|
||||
"react": "^17.0.2",
|
||||
"react-blockies": "^1.4.1",
|
||||
"react-chartjs-2": "^4.0.0",
|
||||
|
@ -46,9 +46,9 @@
|
|||
"react-scripts": "4.0.3",
|
||||
"react-syntax-highlighter": "^15.4.5",
|
||||
"serve": "^13.0.2",
|
||||
"swr": "^1.1.2",
|
||||
"typescript": "^4.5.4",
|
||||
"use-keyboard-shortcut": "^1.1.2",
|
||||
"swr": "^1.2.1",
|
||||
"typescript": "^4.5.5",
|
||||
"use-keyboard-shortcut": "^1.1.3",
|
||||
"web-vitals": "^1.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
@ -1229,9 +1229,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@chainlink/contracts": {
|
||||
"version": "0.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@chainlink/contracts/-/contracts-0.2.2.tgz",
|
||||
"integrity": "sha512-wxXPbt7O3aZaUSG34ufFASC5amRSL6eeYCqsa+2gpqbB8Hk7B7FydEDCI5dqvAC444TlFskPHcVbizCZkRHPpw=="
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@chainlink/contracts/-/contracts-0.4.0.tgz",
|
||||
"integrity": "sha512-yZGeCBd7d+qxfw9r/JxtPzsW2kCc6MorPRZ/tDKnaJI98H99j5P2Fosfehmcwk6wVZlz+0Bp4kS1y480nw3Zow=="
|
||||
},
|
||||
"node_modules/@cnakazawa/watch": {
|
||||
"version": "1.0.4",
|
||||
|
@ -1775,9 +1775,9 @@
|
|||
]
|
||||
},
|
||||
"node_modules/@ethersproject/networks": {
|
||||
"version": "5.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.5.1.tgz",
|
||||
"integrity": "sha512-tYRDM4zZtSUcKnD4UMuAlj7SeXH/k5WC4SP2u1Pn57++JdXHkRu2zwNkgNogZoxHzhm9Q6qqurDBVptHOsW49Q==",
|
||||
"version": "5.5.2",
|
||||
"resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.5.2.tgz",
|
||||
"integrity": "sha512-NEqPxbGBfy6O3x4ZTISb90SjEDkWYDUbEeIFhJly0F7sZjoQMnj5KYzMSkMkLKZ+1fGpx00EDpHQCy6PrDupkQ==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
|
@ -1830,9 +1830,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@ethersproject/providers": {
|
||||
"version": "5.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.5.1.tgz",
|
||||
"integrity": "sha512-2zdD5sltACDWhjUE12Kucg2PcgM6V2q9JMyVvObtVGnzJu+QSmibbP+BHQyLWZUBfLApx2942+7DC5D+n4wBQQ==",
|
||||
"version": "5.5.3",
|
||||
"resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.5.3.tgz",
|
||||
"integrity": "sha512-ZHXxXXXWHuwCQKrgdpIkbzMNJMvs+9YWemanwp1fA7XZEv7QlilseysPvQe0D7Q7DlkJX/w/bGA1MdgK2TbGvA==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
|
@ -1886,9 +1886,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@ethersproject/random": {
|
||||
"version": "5.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.5.0.tgz",
|
||||
"integrity": "sha512-egGYZwZ/YIFKMHcoBUo8t3a8Hb/TKYX8BCBoLjudVCZh892welR3jOxgOmb48xznc9bTcMm7Tpwc1gHC1PFNFQ==",
|
||||
"version": "5.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.5.1.tgz",
|
||||
"integrity": "sha512-YaU2dQ7DuhL5Au7KbcQLHxcRHfgyNgvFV4sQOo0HrtW3Zkrc9ctWNz8wXQ4uCSfSDsqX2vcjhroxU5RQRV0nqA==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
|
@ -2132,24 +2132,24 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@fontsource/fira-code": {
|
||||
"version": "4.5.2",
|
||||
"resolved": "https://registry.npmjs.org/@fontsource/fira-code/-/fira-code-4.5.2.tgz",
|
||||
"integrity": "sha512-wNUvcqmm1dZYTbJlkbFZL9Huu7p+Hwaa4CLNTPql3CG90Rh9dSi43wNg5AnVHxjAhWQOGlCpSrEswnnHu1CkxA=="
|
||||
"version": "4.5.5",
|
||||
"resolved": "https://registry.npmjs.org/@fontsource/fira-code/-/fira-code-4.5.5.tgz",
|
||||
"integrity": "sha512-bwsPmA5HW11SR0oIkgqSJYI3A8KP8aQLRCCH/EnR9gLHRuTFi1iG7GQ3wDTKy/AhECQJAKjXZ+mkVKlMxUaYCQ=="
|
||||
},
|
||||
"node_modules/@fontsource/roboto": {
|
||||
"version": "4.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@fontsource/roboto/-/roboto-4.5.1.tgz",
|
||||
"integrity": "sha512-3mhfL+eNPG/woMNqwD/OHaW5qMpeGEBsDwzmhFmjB1yUV+M+M9P0NhP/AyHvnGz3DrqkvZ7CPzNMa+UkVLeELg=="
|
||||
"version": "4.5.3",
|
||||
"resolved": "https://registry.npmjs.org/@fontsource/roboto/-/roboto-4.5.3.tgz",
|
||||
"integrity": "sha512-NUvBTj332dFRdiVkLlavXbDGoD2zyyeGYmMyrXOnctg/3e4pq95+rJgNfUP+k4v8UBk2L1aomGw9dDjbRdAmTg=="
|
||||
},
|
||||
"node_modules/@fontsource/roboto-mono": {
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@fontsource/roboto-mono/-/roboto-mono-4.5.0.tgz",
|
||||
"integrity": "sha512-/6Gm6fJjBHZiFNyvzIKGJkVuyifoc1aoTel+pkzdhxNh7yNhFyokCoChdbbqZEpGKpqs5uld74G5TJthUVFyjw=="
|
||||
"version": "4.5.3",
|
||||
"resolved": "https://registry.npmjs.org/@fontsource/roboto-mono/-/roboto-mono-4.5.3.tgz",
|
||||
"integrity": "sha512-ELuIIUBo1kq2hFmOXjWv9o2VbM22Pct2F0T+D8f5T0MxDKIqkh0m1JMs9bbTzMjc+wVvyJ6LU5EiNkO26kLlKA=="
|
||||
},
|
||||
"node_modules/@fontsource/space-grotesk": {
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@fontsource/space-grotesk/-/space-grotesk-4.5.0.tgz",
|
||||
"integrity": "sha512-Kdnq5m31DsJ8l/VCpZGz4QpIxLLvNVh4MyVGY0PmDh7aY9aM5rmO2NF49dJ0749gLPgMW6Moc/xjgW95G0MbMg=="
|
||||
"version": "4.5.3",
|
||||
"resolved": "https://registry.npmjs.org/@fontsource/space-grotesk/-/space-grotesk-4.5.3.tgz",
|
||||
"integrity": "sha512-uhCiGA3DXiT7BLCcbKzSDlgUp6Pct50+WObzLJvee8qnA2ezH/cfWlIU3+3ydc1poxQuR6+jJN2Cd8XjpOB9lg=="
|
||||
},
|
||||
"node_modules/@fortawesome/fontawesome-common-types": {
|
||||
"version": "0.2.36",
|
||||
|
@ -2209,11 +2209,11 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@fortawesome/react-fontawesome": {
|
||||
"version": "0.1.16",
|
||||
"resolved": "https://registry.npmjs.org/@fortawesome/react-fontawesome/-/react-fontawesome-0.1.16.tgz",
|
||||
"integrity": "sha512-aLmzDwC9rEOAJv2UJdMns89VZR5Ry4IHu5dQQh24Z/lWKEm44lfQr1UNalZlkUaQN8d155tNh+CS7ntntj1VMA==",
|
||||
"version": "0.1.17",
|
||||
"resolved": "https://registry.npmjs.org/@fortawesome/react-fontawesome/-/react-fontawesome-0.1.17.tgz",
|
||||
"integrity": "sha512-dX43Z5IvMaW7fwzU8farosYjKNGfRb2HB/DgjVBHeJZ/NSnuuaujPPx0YOdcAq+n3mqn70tyCde2HM1mqbhiuw==",
|
||||
"dependencies": {
|
||||
"prop-types": "^15.7.2"
|
||||
"prop-types": "^15.8.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@fortawesome/fontawesome-svg-core": "~1 || >=1.3.0-beta1",
|
||||
|
@ -2250,9 +2250,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@headlessui/react": {
|
||||
"version": "1.4.2",
|
||||
"resolved": "https://registry.npmjs.org/@headlessui/react/-/react-1.4.2.tgz",
|
||||
"integrity": "sha512-N8tv7kLhg9qGKBkVdtg572BvKvWhmiudmeEpOCyNwzOsZHCXBtl8AazGikIfUS+vBoub20Fse3BjawXDVPPdug==",
|
||||
"version": "1.4.3",
|
||||
"resolved": "https://registry.npmjs.org/@headlessui/react/-/react-1.4.3.tgz",
|
||||
"integrity": "sha512-n2IQkaaw0aAAlQS5MEXsM4uRK+w18CrM72EqnGRl/UBOQeQajad8oiKXR9Nk15jOzTFQjpxzrZMf1NxHidFBiw==",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
|
@ -2970,9 +2970,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@testing-library/jest-dom": {
|
||||
"version": "5.16.1",
|
||||
"resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.16.1.tgz",
|
||||
"integrity": "sha512-ajUJdfDIuTCadB79ukO+0l8O+QwN0LiSxDaYUTI4LndbbUsGi6rWU1SCexXzBA2NSjlVB9/vbkasQIL3tmPBjw==",
|
||||
"version": "5.16.2",
|
||||
"resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.16.2.tgz",
|
||||
"integrity": "sha512-6ewxs1MXWwsBFZXIk4nKKskWANelkdUehchEOokHsN8X7c2eKXGw+77aRV63UU8f/DTSVUPLaGxdrj4lN7D/ug==",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.9.2",
|
||||
"@types/testing-library__jest-dom": "^5.9.1",
|
||||
|
@ -3233,9 +3233,9 @@
|
|||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/react": {
|
||||
"version": "17.0.38",
|
||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.38.tgz",
|
||||
"integrity": "sha512-SI92X1IA+FMnP3qM5m4QReluXzhcmovhZnLNm3pyeQlooi02qI7sLiepEYqT678uNiyc25XfCqxREFpy3W7YhQ==",
|
||||
"version": "17.0.39",
|
||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.39.tgz",
|
||||
"integrity": "sha512-UVavlfAxDd/AgAacMa60Azl7ygyQNRwC/DsHZmKgNvPmRR5p70AJ5Q9EAmL2NWOJmeV+vVUI4IAP7GZrN8h8Ug==",
|
||||
"dependencies": {
|
||||
"@types/prop-types": "*",
|
||||
"@types/scheduler": "*",
|
||||
|
@ -5689,9 +5689,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/chart.js": {
|
||||
"version": "3.7.0",
|
||||
"resolved": "https://registry.npmjs.org/chart.js/-/chart.js-3.7.0.tgz",
|
||||
"integrity": "sha512-31gVuqqKp3lDIFmzpKIrBeum4OpZsQjSIAqlOpgjosHDJZlULtvwLEZKtEhIAZc7JMPaHlYMys40Qy9Mf+1AAg=="
|
||||
"version": "3.7.1",
|
||||
"resolved": "https://registry.npmjs.org/chart.js/-/chart.js-3.7.1.tgz",
|
||||
"integrity": "sha512-8knRegQLFnPQAheZV8MjxIXc5gQEfDFD897BJgv/klO/vtIyFFmgMXrNfgrXpbTr/XbTturxRgxIXx/Y+ASJBA=="
|
||||
},
|
||||
"node_modules/check-types": {
|
||||
"version": "11.1.2",
|
||||
|
@ -8201,9 +8201,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/ethers": {
|
||||
"version": "5.5.2",
|
||||
"resolved": "https://registry.npmjs.org/ethers/-/ethers-5.5.2.tgz",
|
||||
"integrity": "sha512-EF5W+6Wwcu6BqVwpgmyR5U2+L4c1FQzlM/02dkZOugN3KF0cG9bzHZP+TDJglmPm2/IzCEJDT7KBxzayk7SAHw==",
|
||||
"version": "5.5.4",
|
||||
"resolved": "https://registry.npmjs.org/ethers/-/ethers-5.5.4.tgz",
|
||||
"integrity": "sha512-N9IAXsF8iKhgHIC6pquzRgPBJEzc9auw3JoRkaKe+y4Wl/LFBtDDunNe7YmdomontECAcC5APaAgWZBiu1kirw==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
|
@ -8230,11 +8230,11 @@
|
|||
"@ethersproject/json-wallets": "5.5.0",
|
||||
"@ethersproject/keccak256": "5.5.0",
|
||||
"@ethersproject/logger": "5.5.0",
|
||||
"@ethersproject/networks": "5.5.1",
|
||||
"@ethersproject/networks": "5.5.2",
|
||||
"@ethersproject/pbkdf2": "5.5.0",
|
||||
"@ethersproject/properties": "5.5.0",
|
||||
"@ethersproject/providers": "5.5.1",
|
||||
"@ethersproject/random": "5.5.0",
|
||||
"@ethersproject/providers": "5.5.3",
|
||||
"@ethersproject/random": "5.5.1",
|
||||
"@ethersproject/rlp": "5.5.0",
|
||||
"@ethersproject/sha2": "5.5.0",
|
||||
"@ethersproject/signing-key": "5.5.0",
|
||||
|
@ -8755,14 +8755,15 @@
|
|||
}
|
||||
},
|
||||
"node_modules/follow-redirects": {
|
||||
"version": "1.13.2",
|
||||
"version": "1.14.8",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.8.tgz",
|
||||
"integrity": "sha512-1x0S9UVJHsQprFcEC/qnNzBLcIxsjAV905f/UkQxbclCsoTWlacCNOpQa/anodLl2uaEKFhfWOvM2Qg77+15zA==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
"url": "https://github.com/sponsors/RubenVerborgh"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=4.0"
|
||||
},
|
||||
|
@ -9362,9 +9363,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/highlightjs-solidity": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/highlightjs-solidity/-/highlightjs-solidity-2.0.3.tgz",
|
||||
"integrity": "sha512-tjFm5dtIE61VQBzjlZmkCtY5fLs3CaEABbVuUNyXeW+UuOCsxMg3MsPFy0kCelHP74hPpkoqDejLrbnV1axAIw=="
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/highlightjs-solidity/-/highlightjs-solidity-2.0.4.tgz",
|
||||
"integrity": "sha512-jsmfDXrjjxt4LxWfzp27j4CX6qYk6B8uK8sxzEDyGts8Ut1IuVlFCysAu6n5RrgHnuEKA+SCIcGPweO7qlPhCg=="
|
||||
},
|
||||
"node_modules/history": {
|
||||
"version": "5.2.0",
|
||||
|
@ -11151,8 +11152,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/jsdom/node_modules/ws": {
|
||||
"version": "7.4.3",
|
||||
"license": "MIT",
|
||||
"version": "7.5.6",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-7.5.6.tgz",
|
||||
"integrity": "sha512-6GLgCqo2cy2A2rjCNFlxQS6ZljG/coZfZXclldI8FB/1G3CCI36Zd8xy2HrFVACi8tfk5XrgLQEk+P0Tnz9UcA==",
|
||||
"engines": {
|
||||
"node": ">=8.3.0"
|
||||
},
|
||||
|
@ -11934,9 +11936,9 @@
|
|||
"optional": true
|
||||
},
|
||||
"node_modules/nanoid": {
|
||||
"version": "3.1.23",
|
||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.23.tgz",
|
||||
"integrity": "sha512-FiB0kzdP0FFVGDKlRLEQ1BgDzU87dy5NnzjeW9YZNt+/c3+q82EQDUwniSAUxp/F0gFNI1ZhKU1FqYsMuqZVnw==",
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.2.0.tgz",
|
||||
"integrity": "sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA==",
|
||||
"bin": {
|
||||
"nanoid": "bin/nanoid.cjs"
|
||||
},
|
||||
|
@ -14109,12 +14111,13 @@
|
|||
}
|
||||
},
|
||||
"node_modules/prop-types": {
|
||||
"version": "15.7.2",
|
||||
"license": "MIT",
|
||||
"version": "15.8.1",
|
||||
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
|
||||
"integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==",
|
||||
"dependencies": {
|
||||
"loose-envify": "^1.4.0",
|
||||
"object-assign": "^4.1.1",
|
||||
"react-is": "^16.8.1"
|
||||
"react-is": "^16.13.1"
|
||||
}
|
||||
},
|
||||
"node_modules/prop-types/node_modules/react-is": {
|
||||
|
@ -17207,9 +17210,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/swr": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/swr/-/swr-1.1.2.tgz",
|
||||
"integrity": "sha512-UsM0eo5T+kRPyWFZtWRx2XR5qzohs/LS4lDC0GCyLpCYFmsfTk28UCVDbOE9+KtoXY4FnwHYiF+ZYEU3hnJ1lQ==",
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/swr/-/swr-1.2.1.tgz",
|
||||
"integrity": "sha512-1cuWXqJqXcFwbgONGCY4PHZ8v05009JdHsC3CIC6u7d00kgbMswNr1sHnnhseOBxtzVqcCNpOHEgVDciRer45w==",
|
||||
"peerDependencies": {
|
||||
"react": "^16.11.0 || ^17.0.0 || ^18.0.0"
|
||||
}
|
||||
|
@ -18130,9 +18133,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/typescript": {
|
||||
"version": "4.5.4",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.4.tgz",
|
||||
"integrity": "sha512-VgYs2A2QIRuGphtzFV7aQJduJ2gyfTljngLzjpfW9FoYZF6xuw1W0vW9ghCKLfcWrCFxK81CSGRAvS1pn4fIUg==",
|
||||
"version": "4.5.5",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.5.tgz",
|
||||
"integrity": "sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA==",
|
||||
"bin": {
|
||||
"tsc": "bin/tsc",
|
||||
"tsserver": "bin/tsserver"
|
||||
|
@ -18354,8 +18357,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/url-parse": {
|
||||
"version": "1.5.1",
|
||||
"license": "MIT",
|
||||
"version": "1.5.7",
|
||||
"resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.7.tgz",
|
||||
"integrity": "sha512-HxWkieX+STA38EDk7CE9MEryFeHCKzgagxlGvsdS7WBImq9Mk+PGwiT56w82WI3aicwJA8REp42Cxo98c8FZMA==",
|
||||
"dependencies": {
|
||||
"querystringify": "^2.1.1",
|
||||
"requires-port": "^1.0.0"
|
||||
|
@ -18373,12 +18377,12 @@
|
|||
}
|
||||
},
|
||||
"node_modules/use-keyboard-shortcut": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/use-keyboard-shortcut/-/use-keyboard-shortcut-1.1.2.tgz",
|
||||
"integrity": "sha512-VrAu1avPLuFHShGo1RiPtCZ6htwsnLRlZc/w4+jmK99HCvIGG5WThz1KsoGgP8KCxP5c8a+pDjtnCgBg+3bXzA==",
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/use-keyboard-shortcut/-/use-keyboard-shortcut-1.1.3.tgz",
|
||||
"integrity": "sha512-3xGUkPMu0WEYAAoIkt39F6MVNqw37mb+IMVUmqLVYT7mLlB9WWp+qGWzZ4WhmbfKtM1/lIP8BiZkXSE8wwfXzQ==",
|
||||
"peerDependencies": {
|
||||
"react": "^16.8.0",
|
||||
"react-dom": "^16.8.0"
|
||||
"react": ">=16.8",
|
||||
"react-dom": ">=16.8"
|
||||
}
|
||||
},
|
||||
"node_modules/util": {
|
||||
|
@ -19173,8 +19177,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/webpack/node_modules/ssri": {
|
||||
"version": "6.0.1",
|
||||
"license": "ISC",
|
||||
"version": "6.0.2",
|
||||
"resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.2.tgz",
|
||||
"integrity": "sha512-cepbSq/neFK7xB6A50KHN0xHDotYzq58wWCa5LeWqnPrHG8GzfEjO/4O8kpmcGW+oaxkvhEJCWgbgNk4/ZV93Q==",
|
||||
"dependencies": {
|
||||
"figgy-pudding": "^3.5.1"
|
||||
}
|
||||
|
@ -19502,8 +19507,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/ws": {
|
||||
"version": "6.2.1",
|
||||
"license": "MIT",
|
||||
"version": "6.2.2",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz",
|
||||
"integrity": "sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==",
|
||||
"dependencies": {
|
||||
"async-limiter": "~1.0.0"
|
||||
}
|
||||
|
@ -20407,9 +20413,9 @@
|
|||
}
|
||||
},
|
||||
"@chainlink/contracts": {
|
||||
"version": "0.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@chainlink/contracts/-/contracts-0.2.2.tgz",
|
||||
"integrity": "sha512-wxXPbt7O3aZaUSG34ufFASC5amRSL6eeYCqsa+2gpqbB8Hk7B7FydEDCI5dqvAC444TlFskPHcVbizCZkRHPpw=="
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@chainlink/contracts/-/contracts-0.4.0.tgz",
|
||||
"integrity": "sha512-yZGeCBd7d+qxfw9r/JxtPzsW2kCc6MorPRZ/tDKnaJI98H99j5P2Fosfehmcwk6wVZlz+0Bp4kS1y480nw3Zow=="
|
||||
},
|
||||
"@cnakazawa/watch": {
|
||||
"version": "1.0.4",
|
||||
|
@ -20721,9 +20727,9 @@
|
|||
"integrity": "sha512-rIY/6WPm7T8n3qS2vuHTUBPdXHl+rGxWxW5okDfo9J4Z0+gRRZT0msvUdIJkE4/HS29GUMziwGaaKO2bWONBrg=="
|
||||
},
|
||||
"@ethersproject/networks": {
|
||||
"version": "5.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.5.1.tgz",
|
||||
"integrity": "sha512-tYRDM4zZtSUcKnD4UMuAlj7SeXH/k5WC4SP2u1Pn57++JdXHkRu2zwNkgNogZoxHzhm9Q6qqurDBVptHOsW49Q==",
|
||||
"version": "5.5.2",
|
||||
"resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.5.2.tgz",
|
||||
"integrity": "sha512-NEqPxbGBfy6O3x4ZTISb90SjEDkWYDUbEeIFhJly0F7sZjoQMnj5KYzMSkMkLKZ+1fGpx00EDpHQCy6PrDupkQ==",
|
||||
"requires": {
|
||||
"@ethersproject/logger": "^5.5.0"
|
||||
}
|
||||
|
@ -20746,9 +20752,9 @@
|
|||
}
|
||||
},
|
||||
"@ethersproject/providers": {
|
||||
"version": "5.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.5.1.tgz",
|
||||
"integrity": "sha512-2zdD5sltACDWhjUE12Kucg2PcgM6V2q9JMyVvObtVGnzJu+QSmibbP+BHQyLWZUBfLApx2942+7DC5D+n4wBQQ==",
|
||||
"version": "5.5.3",
|
||||
"resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.5.3.tgz",
|
||||
"integrity": "sha512-ZHXxXXXWHuwCQKrgdpIkbzMNJMvs+9YWemanwp1fA7XZEv7QlilseysPvQe0D7Q7DlkJX/w/bGA1MdgK2TbGvA==",
|
||||
"requires": {
|
||||
"@ethersproject/abstract-provider": "^5.5.0",
|
||||
"@ethersproject/abstract-signer": "^5.5.0",
|
||||
|
@ -20780,9 +20786,9 @@
|
|||
}
|
||||
},
|
||||
"@ethersproject/random": {
|
||||
"version": "5.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.5.0.tgz",
|
||||
"integrity": "sha512-egGYZwZ/YIFKMHcoBUo8t3a8Hb/TKYX8BCBoLjudVCZh892welR3jOxgOmb48xznc9bTcMm7Tpwc1gHC1PFNFQ==",
|
||||
"version": "5.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.5.1.tgz",
|
||||
"integrity": "sha512-YaU2dQ7DuhL5Au7KbcQLHxcRHfgyNgvFV4sQOo0HrtW3Zkrc9ctWNz8wXQ4uCSfSDsqX2vcjhroxU5RQRV0nqA==",
|
||||
"requires": {
|
||||
"@ethersproject/bytes": "^5.5.0",
|
||||
"@ethersproject/logger": "^5.5.0"
|
||||
|
@ -20916,24 +20922,24 @@
|
|||
}
|
||||
},
|
||||
"@fontsource/fira-code": {
|
||||
"version": "4.5.2",
|
||||
"resolved": "https://registry.npmjs.org/@fontsource/fira-code/-/fira-code-4.5.2.tgz",
|
||||
"integrity": "sha512-wNUvcqmm1dZYTbJlkbFZL9Huu7p+Hwaa4CLNTPql3CG90Rh9dSi43wNg5AnVHxjAhWQOGlCpSrEswnnHu1CkxA=="
|
||||
"version": "4.5.5",
|
||||
"resolved": "https://registry.npmjs.org/@fontsource/fira-code/-/fira-code-4.5.5.tgz",
|
||||
"integrity": "sha512-bwsPmA5HW11SR0oIkgqSJYI3A8KP8aQLRCCH/EnR9gLHRuTFi1iG7GQ3wDTKy/AhECQJAKjXZ+mkVKlMxUaYCQ=="
|
||||
},
|
||||
"@fontsource/roboto": {
|
||||
"version": "4.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@fontsource/roboto/-/roboto-4.5.1.tgz",
|
||||
"integrity": "sha512-3mhfL+eNPG/woMNqwD/OHaW5qMpeGEBsDwzmhFmjB1yUV+M+M9P0NhP/AyHvnGz3DrqkvZ7CPzNMa+UkVLeELg=="
|
||||
"version": "4.5.3",
|
||||
"resolved": "https://registry.npmjs.org/@fontsource/roboto/-/roboto-4.5.3.tgz",
|
||||
"integrity": "sha512-NUvBTj332dFRdiVkLlavXbDGoD2zyyeGYmMyrXOnctg/3e4pq95+rJgNfUP+k4v8UBk2L1aomGw9dDjbRdAmTg=="
|
||||
},
|
||||
"@fontsource/roboto-mono": {
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@fontsource/roboto-mono/-/roboto-mono-4.5.0.tgz",
|
||||
"integrity": "sha512-/6Gm6fJjBHZiFNyvzIKGJkVuyifoc1aoTel+pkzdhxNh7yNhFyokCoChdbbqZEpGKpqs5uld74G5TJthUVFyjw=="
|
||||
"version": "4.5.3",
|
||||
"resolved": "https://registry.npmjs.org/@fontsource/roboto-mono/-/roboto-mono-4.5.3.tgz",
|
||||
"integrity": "sha512-ELuIIUBo1kq2hFmOXjWv9o2VbM22Pct2F0T+D8f5T0MxDKIqkh0m1JMs9bbTzMjc+wVvyJ6LU5EiNkO26kLlKA=="
|
||||
},
|
||||
"@fontsource/space-grotesk": {
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@fontsource/space-grotesk/-/space-grotesk-4.5.0.tgz",
|
||||
"integrity": "sha512-Kdnq5m31DsJ8l/VCpZGz4QpIxLLvNVh4MyVGY0PmDh7aY9aM5rmO2NF49dJ0749gLPgMW6Moc/xjgW95G0MbMg=="
|
||||
"version": "4.5.3",
|
||||
"resolved": "https://registry.npmjs.org/@fontsource/space-grotesk/-/space-grotesk-4.5.3.tgz",
|
||||
"integrity": "sha512-uhCiGA3DXiT7BLCcbKzSDlgUp6Pct50+WObzLJvee8qnA2ezH/cfWlIU3+3ydc1poxQuR6+jJN2Cd8XjpOB9lg=="
|
||||
},
|
||||
"@fortawesome/fontawesome-common-types": {
|
||||
"version": "0.2.36",
|
||||
|
@ -20973,11 +20979,11 @@
|
|||
}
|
||||
},
|
||||
"@fortawesome/react-fontawesome": {
|
||||
"version": "0.1.16",
|
||||
"resolved": "https://registry.npmjs.org/@fortawesome/react-fontawesome/-/react-fontawesome-0.1.16.tgz",
|
||||
"integrity": "sha512-aLmzDwC9rEOAJv2UJdMns89VZR5Ry4IHu5dQQh24Z/lWKEm44lfQr1UNalZlkUaQN8d155tNh+CS7ntntj1VMA==",
|
||||
"version": "0.1.17",
|
||||
"resolved": "https://registry.npmjs.org/@fortawesome/react-fontawesome/-/react-fontawesome-0.1.17.tgz",
|
||||
"integrity": "sha512-dX43Z5IvMaW7fwzU8farosYjKNGfRb2HB/DgjVBHeJZ/NSnuuaujPPx0YOdcAq+n3mqn70tyCde2HM1mqbhiuw==",
|
||||
"requires": {
|
||||
"prop-types": "^15.7.2"
|
||||
"prop-types": "^15.8.1"
|
||||
}
|
||||
},
|
||||
"@hapi/address": {
|
||||
|
@ -21005,9 +21011,9 @@
|
|||
}
|
||||
},
|
||||
"@headlessui/react": {
|
||||
"version": "1.4.2",
|
||||
"resolved": "https://registry.npmjs.org/@headlessui/react/-/react-1.4.2.tgz",
|
||||
"integrity": "sha512-N8tv7kLhg9qGKBkVdtg572BvKvWhmiudmeEpOCyNwzOsZHCXBtl8AazGikIfUS+vBoub20Fse3BjawXDVPPdug==",
|
||||
"version": "1.4.3",
|
||||
"resolved": "https://registry.npmjs.org/@headlessui/react/-/react-1.4.3.tgz",
|
||||
"integrity": "sha512-n2IQkaaw0aAAlQS5MEXsM4uRK+w18CrM72EqnGRl/UBOQeQajad8oiKXR9Nk15jOzTFQjpxzrZMf1NxHidFBiw==",
|
||||
"requires": {}
|
||||
},
|
||||
"@istanbuljs/load-nyc-config": {
|
||||
|
@ -21436,9 +21442,9 @@
|
|||
}
|
||||
},
|
||||
"@testing-library/jest-dom": {
|
||||
"version": "5.16.1",
|
||||
"resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.16.1.tgz",
|
||||
"integrity": "sha512-ajUJdfDIuTCadB79ukO+0l8O+QwN0LiSxDaYUTI4LndbbUsGi6rWU1SCexXzBA2NSjlVB9/vbkasQIL3tmPBjw==",
|
||||
"version": "5.16.2",
|
||||
"resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.16.2.tgz",
|
||||
"integrity": "sha512-6ewxs1MXWwsBFZXIk4nKKskWANelkdUehchEOokHsN8X7c2eKXGw+77aRV63UU8f/DTSVUPLaGxdrj4lN7D/ug==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.9.2",
|
||||
"@types/testing-library__jest-dom": "^5.9.1",
|
||||
|
@ -21643,9 +21649,9 @@
|
|||
"version": "1.5.4"
|
||||
},
|
||||
"@types/react": {
|
||||
"version": "17.0.38",
|
||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.38.tgz",
|
||||
"integrity": "sha512-SI92X1IA+FMnP3qM5m4QReluXzhcmovhZnLNm3pyeQlooi02qI7sLiepEYqT678uNiyc25XfCqxREFpy3W7YhQ==",
|
||||
"version": "17.0.39",
|
||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.39.tgz",
|
||||
"integrity": "sha512-UVavlfAxDd/AgAacMa60Azl7ygyQNRwC/DsHZmKgNvPmRR5p70AJ5Q9EAmL2NWOJmeV+vVUI4IAP7GZrN8h8Ug==",
|
||||
"requires": {
|
||||
"@types/prop-types": "*",
|
||||
"@types/scheduler": "*",
|
||||
|
@ -23348,9 +23354,9 @@
|
|||
"integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg=="
|
||||
},
|
||||
"chart.js": {
|
||||
"version": "3.7.0",
|
||||
"resolved": "https://registry.npmjs.org/chart.js/-/chart.js-3.7.0.tgz",
|
||||
"integrity": "sha512-31gVuqqKp3lDIFmzpKIrBeum4OpZsQjSIAqlOpgjosHDJZlULtvwLEZKtEhIAZc7JMPaHlYMys40Qy9Mf+1AAg=="
|
||||
"version": "3.7.1",
|
||||
"resolved": "https://registry.npmjs.org/chart.js/-/chart.js-3.7.1.tgz",
|
||||
"integrity": "sha512-8knRegQLFnPQAheZV8MjxIXc5gQEfDFD897BJgv/klO/vtIyFFmgMXrNfgrXpbTr/XbTturxRgxIXx/Y+ASJBA=="
|
||||
},
|
||||
"check-types": {
|
||||
"version": "11.1.2"
|
||||
|
@ -25004,9 +25010,9 @@
|
|||
"version": "1.8.1"
|
||||
},
|
||||
"ethers": {
|
||||
"version": "5.5.2",
|
||||
"resolved": "https://registry.npmjs.org/ethers/-/ethers-5.5.2.tgz",
|
||||
"integrity": "sha512-EF5W+6Wwcu6BqVwpgmyR5U2+L4c1FQzlM/02dkZOugN3KF0cG9bzHZP+TDJglmPm2/IzCEJDT7KBxzayk7SAHw==",
|
||||
"version": "5.5.4",
|
||||
"resolved": "https://registry.npmjs.org/ethers/-/ethers-5.5.4.tgz",
|
||||
"integrity": "sha512-N9IAXsF8iKhgHIC6pquzRgPBJEzc9auw3JoRkaKe+y4Wl/LFBtDDunNe7YmdomontECAcC5APaAgWZBiu1kirw==",
|
||||
"requires": {
|
||||
"@ethersproject/abi": "5.5.0",
|
||||
"@ethersproject/abstract-provider": "5.5.1",
|
||||
|
@ -25023,11 +25029,11 @@
|
|||
"@ethersproject/json-wallets": "5.5.0",
|
||||
"@ethersproject/keccak256": "5.5.0",
|
||||
"@ethersproject/logger": "5.5.0",
|
||||
"@ethersproject/networks": "5.5.1",
|
||||
"@ethersproject/networks": "5.5.2",
|
||||
"@ethersproject/pbkdf2": "5.5.0",
|
||||
"@ethersproject/properties": "5.5.0",
|
||||
"@ethersproject/providers": "5.5.1",
|
||||
"@ethersproject/random": "5.5.0",
|
||||
"@ethersproject/providers": "5.5.3",
|
||||
"@ethersproject/random": "5.5.1",
|
||||
"@ethersproject/rlp": "5.5.0",
|
||||
"@ethersproject/sha2": "5.5.0",
|
||||
"@ethersproject/signing-key": "5.5.0",
|
||||
|
@ -25419,7 +25425,9 @@
|
|||
}
|
||||
},
|
||||
"follow-redirects": {
|
||||
"version": "1.13.2"
|
||||
"version": "1.14.8",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.8.tgz",
|
||||
"integrity": "sha512-1x0S9UVJHsQprFcEC/qnNzBLcIxsjAV905f/UkQxbclCsoTWlacCNOpQa/anodLl2uaEKFhfWOvM2Qg77+15zA=="
|
||||
},
|
||||
"for-in": {
|
||||
"version": "1.0.2"
|
||||
|
@ -25797,9 +25805,9 @@
|
|||
"integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A=="
|
||||
},
|
||||
"highlightjs-solidity": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/highlightjs-solidity/-/highlightjs-solidity-2.0.3.tgz",
|
||||
"integrity": "sha512-tjFm5dtIE61VQBzjlZmkCtY5fLs3CaEABbVuUNyXeW+UuOCsxMg3MsPFy0kCelHP74hPpkoqDejLrbnV1axAIw=="
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/highlightjs-solidity/-/highlightjs-solidity-2.0.4.tgz",
|
||||
"integrity": "sha512-jsmfDXrjjxt4LxWfzp27j4CX6qYk6B8uK8sxzEDyGts8Ut1IuVlFCysAu6n5RrgHnuEKA+SCIcGPweO7qlPhCg=="
|
||||
},
|
||||
"history": {
|
||||
"version": "5.2.0",
|
||||
|
@ -26966,7 +26974,9 @@
|
|||
}
|
||||
},
|
||||
"ws": {
|
||||
"version": "7.4.3",
|
||||
"version": "7.5.6",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-7.5.6.tgz",
|
||||
"integrity": "sha512-6GLgCqo2cy2A2rjCNFlxQS6ZljG/coZfZXclldI8FB/1G3CCI36Zd8xy2HrFVACi8tfk5XrgLQEk+P0Tnz9UcA==",
|
||||
"requires": {}
|
||||
}
|
||||
}
|
||||
|
@ -27468,9 +27478,9 @@
|
|||
"optional": true
|
||||
},
|
||||
"nanoid": {
|
||||
"version": "3.1.23",
|
||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.23.tgz",
|
||||
"integrity": "sha512-FiB0kzdP0FFVGDKlRLEQ1BgDzU87dy5NnzjeW9YZNt+/c3+q82EQDUwniSAUxp/F0gFNI1ZhKU1FqYsMuqZVnw=="
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.2.0.tgz",
|
||||
"integrity": "sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA=="
|
||||
},
|
||||
"nanomatch": {
|
||||
"version": "1.2.13",
|
||||
|
@ -28936,11 +28946,13 @@
|
|||
}
|
||||
},
|
||||
"prop-types": {
|
||||
"version": "15.7.2",
|
||||
"version": "15.8.1",
|
||||
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
|
||||
"integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==",
|
||||
"requires": {
|
||||
"loose-envify": "^1.4.0",
|
||||
"object-assign": "^4.1.1",
|
||||
"react-is": "^16.8.1"
|
||||
"react-is": "^16.13.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"react-is": {
|
||||
|
@ -31079,9 +31091,9 @@
|
|||
}
|
||||
},
|
||||
"swr": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/swr/-/swr-1.1.2.tgz",
|
||||
"integrity": "sha512-UsM0eo5T+kRPyWFZtWRx2XR5qzohs/LS4lDC0GCyLpCYFmsfTk28UCVDbOE9+KtoXY4FnwHYiF+ZYEU3hnJ1lQ==",
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/swr/-/swr-1.2.1.tgz",
|
||||
"integrity": "sha512-1cuWXqJqXcFwbgONGCY4PHZ8v05009JdHsC3CIC6u7d00kgbMswNr1sHnnhseOBxtzVqcCNpOHEgVDciRer45w==",
|
||||
"requires": {}
|
||||
},
|
||||
"symbol-tree": {
|
||||
|
@ -31712,9 +31724,9 @@
|
|||
}
|
||||
},
|
||||
"typescript": {
|
||||
"version": "4.5.4",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.4.tgz",
|
||||
"integrity": "sha512-VgYs2A2QIRuGphtzFV7aQJduJ2gyfTljngLzjpfW9FoYZF6xuw1W0vW9ghCKLfcWrCFxK81CSGRAvS1pn4fIUg=="
|
||||
"version": "4.5.5",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.5.tgz",
|
||||
"integrity": "sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA=="
|
||||
},
|
||||
"unicode-canonical-property-names-ecmascript": {
|
||||
"version": "1.0.4"
|
||||
|
@ -31854,7 +31866,9 @@
|
|||
}
|
||||
},
|
||||
"url-parse": {
|
||||
"version": "1.5.1",
|
||||
"version": "1.5.7",
|
||||
"resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.7.tgz",
|
||||
"integrity": "sha512-HxWkieX+STA38EDk7CE9MEryFeHCKzgagxlGvsdS7WBImq9Mk+PGwiT56w82WI3aicwJA8REp42Cxo98c8FZMA==",
|
||||
"requires": {
|
||||
"querystringify": "^2.1.1",
|
||||
"requires-port": "^1.0.0"
|
||||
|
@ -31864,9 +31878,9 @@
|
|||
"version": "3.1.1"
|
||||
},
|
||||
"use-keyboard-shortcut": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/use-keyboard-shortcut/-/use-keyboard-shortcut-1.1.2.tgz",
|
||||
"integrity": "sha512-VrAu1avPLuFHShGo1RiPtCZ6htwsnLRlZc/w4+jmK99HCvIGG5WThz1KsoGgP8KCxP5c8a+pDjtnCgBg+3bXzA==",
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/use-keyboard-shortcut/-/use-keyboard-shortcut-1.1.3.tgz",
|
||||
"integrity": "sha512-3xGUkPMu0WEYAAoIkt39F6MVNqw37mb+IMVUmqLVYT7mLlB9WWp+qGWzZ4WhmbfKtM1/lIP8BiZkXSE8wwfXzQ==",
|
||||
"requires": {}
|
||||
},
|
||||
"util": {
|
||||
|
@ -32174,7 +32188,9 @@
|
|||
}
|
||||
},
|
||||
"ssri": {
|
||||
"version": "6.0.1",
|
||||
"version": "6.0.2",
|
||||
"resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.2.tgz",
|
||||
"integrity": "sha512-cepbSq/neFK7xB6A50KHN0xHDotYzq58wWCa5LeWqnPrHG8GzfEjO/4O8kpmcGW+oaxkvhEJCWgbgNk4/ZV93Q==",
|
||||
"requires": {
|
||||
"figgy-pudding": "^3.5.1"
|
||||
}
|
||||
|
@ -32662,7 +32678,9 @@
|
|||
}
|
||||
},
|
||||
"ws": {
|
||||
"version": "6.2.1",
|
||||
"version": "6.2.2",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz",
|
||||
"integrity": "sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==",
|
||||
"requires": {
|
||||
"async-limiter": "~1.0.0"
|
||||
}
|
||||
|
|
30
package.json
30
package.json
|
@ -5,31 +5,31 @@
|
|||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@blackbox-vision/react-qr-reader": "^5.0.0",
|
||||
"@chainlink/contracts": "^0.2.2",
|
||||
"@chainlink/contracts": "^0.4.0",
|
||||
"@craco/craco": "^6.4.3",
|
||||
"@fontsource/fira-code": "^4.5.2",
|
||||
"@fontsource/roboto": "^4.5.1",
|
||||
"@fontsource/roboto-mono": "^4.5.0",
|
||||
"@fontsource/space-grotesk": "^4.5.0",
|
||||
"@fontsource/fira-code": "^4.5.5",
|
||||
"@fontsource/roboto": "^4.5.3",
|
||||
"@fontsource/roboto-mono": "^4.5.3",
|
||||
"@fontsource/space-grotesk": "^4.5.3",
|
||||
"@fortawesome/fontawesome-svg-core": "^1.2.36",
|
||||
"@fortawesome/free-brands-svg-icons": "^5.15.4",
|
||||
"@fortawesome/free-regular-svg-icons": "^5.15.4",
|
||||
"@fortawesome/free-solid-svg-icons": "^5.15.4",
|
||||
"@fortawesome/react-fontawesome": "^0.1.16",
|
||||
"@headlessui/react": "^1.4.2",
|
||||
"@testing-library/jest-dom": "^5.16.1",
|
||||
"@fortawesome/react-fontawesome": "^0.1.17",
|
||||
"@headlessui/react": "^1.4.3",
|
||||
"@testing-library/jest-dom": "^5.16.2",
|
||||
"@testing-library/react": "^11.1.0",
|
||||
"@testing-library/user-event": "^12.1.10",
|
||||
"@types/jest": "^26.0.24",
|
||||
"@types/node": "^16.11.14",
|
||||
"@types/react": "^17.0.38",
|
||||
"@types/react": "^17.0.39",
|
||||
"@types/react-blockies": "^1.4.1",
|
||||
"@types/react-dom": "^17.0.11",
|
||||
"@types/react-highlight": "^0.12.5",
|
||||
"@types/react-syntax-highlighter": "^13.5.2",
|
||||
"chart.js": "^3.7.0",
|
||||
"ethers": "^5.5.2",
|
||||
"highlightjs-solidity": "^2.0.3",
|
||||
"chart.js": "^3.7.1",
|
||||
"ethers": "^5.5.4",
|
||||
"highlightjs-solidity": "^2.0.4",
|
||||
"react": "^17.0.2",
|
||||
"react-blockies": "^1.4.1",
|
||||
"react-chartjs-2": "^4.0.0",
|
||||
|
@ -41,9 +41,9 @@
|
|||
"react-scripts": "4.0.3",
|
||||
"react-syntax-highlighter": "^15.4.5",
|
||||
"serve": "^13.0.2",
|
||||
"swr": "^1.1.2",
|
||||
"typescript": "^4.5.4",
|
||||
"use-keyboard-shortcut": "^1.1.2",
|
||||
"swr": "^1.2.1",
|
||||
"typescript": "^4.5.5",
|
||||
"use-keyboard-shortcut": "^1.1.3",
|
||||
"web-vitals": "^1.0.1"
|
||||
},
|
||||
"scripts": {
|
||||
|
|
|
@ -100,7 +100,10 @@ const Address: React.FC = () => {
|
|||
return (
|
||||
<StandardFrame>
|
||||
{error ? (
|
||||
<AddressOrENSNameNotFound addressOrENSName={addressOrName} />
|
||||
<AddressOrENSNameNotFound
|
||||
addressOrENSName={addressOrName}
|
||||
supportsENS={provider?.network.ensAddress !== undefined}
|
||||
/>
|
||||
) : (
|
||||
checksummedAddress && (
|
||||
<>
|
||||
|
|
|
@ -25,6 +25,7 @@ import { useLatestBlockNumber } from "./useLatestBlock";
|
|||
import { blockTxsURL } from "./url";
|
||||
import { useBlockData } from "./useErigonHooks";
|
||||
import { useETHUSDOracle } from "./usePriceOracle";
|
||||
import BlockNotFound from "./components/BlockNotFound";
|
||||
|
||||
const Block: React.FC = () => {
|
||||
const { provider } = useContext(RuntimeContext);
|
||||
|
@ -35,10 +36,10 @@ const Block: React.FC = () => {
|
|||
|
||||
const block = useBlockData(provider, blockNumberOrHash);
|
||||
useEffect(() => {
|
||||
if (block) {
|
||||
document.title = `Block #${block.number} | Otterscan`;
|
||||
if (block !== undefined) {
|
||||
document.title = `Block #${blockNumberOrHash} | Otterscan`;
|
||||
}
|
||||
}, [block]);
|
||||
}, [blockNumberOrHash, block]);
|
||||
|
||||
const extraStr = useMemo(() => {
|
||||
try {
|
||||
|
@ -71,6 +72,9 @@ const Block: React.FC = () => {
|
|||
)}
|
||||
</div>
|
||||
</StandardSubtitle>
|
||||
{block === null && (
|
||||
<BlockNotFound blockNumberOrHash={blockNumberOrHash} />
|
||||
)}
|
||||
{block && (
|
||||
<ContentFrame>
|
||||
<InfoRow title="Block Height">
|
||||
|
|
|
@ -44,7 +44,9 @@ const Header: React.FC = () => {
|
|||
className="w-full border-t border-b border-l rounded-l focus:outline-none px-2 py-1 text-sm"
|
||||
type="text"
|
||||
size={60}
|
||||
placeholder='Type "/" to search by address / txn hash / block number / ENS name'
|
||||
placeholder={`Type "/" to search by address / txn hash / block number${
|
||||
provider?.network.ensAddress ? " / ENS name" : ""
|
||||
}`}
|
||||
onChange={handleChange}
|
||||
ref={searchRef}
|
||||
/>
|
||||
|
|
28
src/Home.tsx
28
src/Home.tsx
|
@ -39,7 +39,9 @@ const Home: React.FC = () => {
|
|||
className="w-full border-l border-t border-b rounded-l focus:outline-none px-2 py-1"
|
||||
type="text"
|
||||
size={50}
|
||||
placeholder="Search by address / txn hash / block number / ENS name"
|
||||
placeholder={`Search by address / txn hash / block number${
|
||||
provider?.network.ensAddress ? " / ENS name" : ""
|
||||
}`}
|
||||
onChange={handleChange}
|
||||
ref={searchRef}
|
||||
autoFocus
|
||||
|
@ -62,17 +64,19 @@ const Home: React.FC = () => {
|
|||
</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>
|
||||
<FontAwesomeIcon icon={faBurn} />
|
||||
</span>
|
||||
<span>Check out the special dashboard for EIP-1559</span>
|
||||
<span>
|
||||
<FontAwesomeIcon icon={faBurn} />
|
||||
</span>
|
||||
</div>
|
||||
</NavLink>
|
||||
{provider?.network.chainId !== 11155111 && (
|
||||
<NavLink to="/special/london">
|
||||
<div className="flex space-x-2 items-baseline text-orange-500 hover:text-orange-700 hover:underline">
|
||||
<span>
|
||||
<FontAwesomeIcon icon={faBurn} />
|
||||
</span>
|
||||
<span>Check out the special dashboard for EIP-1559</span>
|
||||
<span>
|
||||
<FontAwesomeIcon icon={faBurn} />
|
||||
</span>
|
||||
</div>
|
||||
</NavLink>
|
||||
)}
|
||||
</div>
|
||||
{latestBlock && (
|
||||
<NavLink
|
||||
|
|
|
@ -10,6 +10,7 @@ import { useLatestBlock } from "./useLatestBlock";
|
|||
|
||||
const ETH_FEED_DECIMALS = 8;
|
||||
|
||||
// TODO: reduce duplication with useETHUSDOracle
|
||||
const PriceBox: React.FC = () => {
|
||||
const { provider } = useContext(RuntimeContext);
|
||||
const latestBlock = useLatestBlock(provider);
|
||||
|
|
|
@ -17,6 +17,8 @@ const WarningHeader: React.FC = () => {
|
|||
chainMsg = "Görli Testnet";
|
||||
} else if (chainId === 42) {
|
||||
chainMsg = "Kovan Testnet";
|
||||
} else if (chainId === 11155111) {
|
||||
chainMsg = "Sepolia Testnet";
|
||||
}
|
||||
return (
|
||||
<div className="w-full bg-orange-400 text-white text-center font-bold px-2 py-1">
|
||||
|
|
|
@ -1,6 +1,12 @@
|
|||
import React, { useContext, useEffect, useMemo, useState } from "react";
|
||||
import { BlockTag } from "@ethersproject/providers";
|
||||
import ContentFrame from "../ContentFrame";
|
||||
import InfoRow from "../components/InfoRow";
|
||||
import TransactionValue from "../components/TransactionValue";
|
||||
import ETH2USDValue from "../components/ETH2USDValue";
|
||||
import TransactionAddress from "../components/TransactionAddress";
|
||||
import Copy from "../components/Copy";
|
||||
import TransactionLink from "../components/TransactionLink";
|
||||
import PendingResults from "../search/PendingResults";
|
||||
import ResultHeader from "../search/ResultHeader";
|
||||
import { SearchController } from "../search/search";
|
||||
|
@ -11,8 +17,9 @@ import { SelectionContext, useSelection } from "../useSelection";
|
|||
import { useMultipleETHUSDOracle } from "../usePriceOracle";
|
||||
import { RuntimeContext } from "../useRuntime";
|
||||
import { useParams, useSearchParams } from "react-router-dom";
|
||||
import { ChecksummedAddress } from "../types";
|
||||
import { ChecksummedAddress, ProcessedTransaction } from "../types";
|
||||
import { useContractsMetadata } from "../hooks";
|
||||
import { useAddressBalance, useContractCreator } from "../useErigonHooks";
|
||||
|
||||
type AddressTransactionResultsProps = {
|
||||
address: ChecksummedAddress;
|
||||
|
@ -95,9 +102,12 @@ const AddressTransactionResults: React.FC<AddressTransactionResultsProps> = ({
|
|||
// TODO: dedup blockTags
|
||||
const blockTags: BlockTag[] = useMemo(() => {
|
||||
if (!page) {
|
||||
return [];
|
||||
return ["latest"];
|
||||
}
|
||||
return page.map((t) => t.blockNumber);
|
||||
|
||||
const blockTags: BlockTag[] = page.map((t) => t.blockNumber);
|
||||
blockTags.push("latest");
|
||||
return blockTags;
|
||||
}, [page]);
|
||||
const priceMap = useMultipleETHUSDOracle(provider, blockTags);
|
||||
|
||||
|
@ -117,65 +127,91 @@ const AddressTransactionResults: React.FC<AddressTransactionResultsProps> = ({
|
|||
return _addresses;
|
||||
}, [address, page]);
|
||||
const metadatas = useContractsMetadata(addresses, provider);
|
||||
const balance = useAddressBalance(provider, address);
|
||||
const creator = useContractCreator(provider, address);
|
||||
|
||||
return (
|
||||
<ContentFrame tabs>
|
||||
<div className="flex justify-between items-baseline py-3">
|
||||
<div className="text-sm text-gray-500">
|
||||
{page === undefined ? (
|
||||
<>Waiting for search results...</>
|
||||
) : (
|
||||
<>{page.length} transactions on this page</>
|
||||
)}
|
||||
</div>
|
||||
<UndefinedPageControl
|
||||
address={address}
|
||||
isFirst={controller?.isFirst}
|
||||
isLast={controller?.isLast}
|
||||
prevHash={page?.[0]?.hash ?? ""}
|
||||
nextHash={page?.[page.length - 1]?.hash ?? ""}
|
||||
disabled={controller === undefined}
|
||||
/>
|
||||
</div>
|
||||
<ResultHeader
|
||||
feeDisplay={feeDisplay}
|
||||
feeDisplayToggler={feeDisplayToggler}
|
||||
/>
|
||||
{page ? (
|
||||
<SelectionContext.Provider value={selectionCtx}>
|
||||
{page.map((tx) => (
|
||||
<TransactionItem
|
||||
key={tx.hash}
|
||||
tx={tx}
|
||||
selectedAddress={address}
|
||||
feeDisplay={feeDisplay}
|
||||
priceMap={priceMap}
|
||||
metadatas={metadatas}
|
||||
/>
|
||||
))}
|
||||
<div className="flex justify-between items-baseline py-3">
|
||||
<div className="text-sm text-gray-500">
|
||||
{page === undefined ? (
|
||||
<>Waiting for search results...</>
|
||||
) : (
|
||||
<>{page.length} transactions on this page</>
|
||||
<SelectionContext.Provider value={selectionCtx}>
|
||||
{balance && (
|
||||
<InfoRow title="Balance">
|
||||
<div className="space-x-2">
|
||||
<TransactionValue value={balance} />
|
||||
{!balance.isZero() && priceMap["latest"] !== undefined && (
|
||||
<span className="px-2 border-green-200 border rounded-lg bg-green-100 text-green-600">
|
||||
<ETH2USDValue
|
||||
ethAmount={balance}
|
||||
eth2USDValue={priceMap["latest"]}
|
||||
/>
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
<UndefinedPageControl
|
||||
address={address}
|
||||
isFirst={controller?.isFirst}
|
||||
isLast={controller?.isLast}
|
||||
prevHash={page?.[0]?.hash ?? ""}
|
||||
nextHash={page?.[page.length - 1]?.hash ?? ""}
|
||||
disabled={controller === undefined}
|
||||
/>
|
||||
</div>
|
||||
</SelectionContext.Provider>
|
||||
) : (
|
||||
<PendingResults />
|
||||
)}
|
||||
</InfoRow>
|
||||
)}
|
||||
{creator && (
|
||||
<InfoRow title="Contract creator">
|
||||
<div className="flex divide-x-2 divide-dotted divide-gray-300">
|
||||
<div className="flex items-baseline space-x-2 -ml-1 mr-3">
|
||||
<TransactionAddress address={creator.creator} />
|
||||
<Copy value={creator.creator} />
|
||||
</div>
|
||||
<div className="flex items-baseline pl-3">
|
||||
<TransactionLink txHash={creator.hash} />
|
||||
</div>
|
||||
</div>
|
||||
</InfoRow>
|
||||
)}
|
||||
<NavBar address={address} page={page} controller={controller} />
|
||||
<ResultHeader
|
||||
feeDisplay={feeDisplay}
|
||||
feeDisplayToggler={feeDisplayToggler}
|
||||
/>
|
||||
{page ? (
|
||||
<>
|
||||
{page.map((tx) => (
|
||||
<TransactionItem
|
||||
key={tx.hash}
|
||||
tx={tx}
|
||||
selectedAddress={address}
|
||||
feeDisplay={feeDisplay}
|
||||
priceMap={priceMap}
|
||||
metadatas={metadatas}
|
||||
/>
|
||||
))}
|
||||
<NavBar address={address} page={page} controller={controller} />
|
||||
</>
|
||||
) : (
|
||||
<PendingResults />
|
||||
)}
|
||||
</SelectionContext.Provider>
|
||||
</ContentFrame>
|
||||
);
|
||||
};
|
||||
|
||||
type NavBarProps = {
|
||||
address: ChecksummedAddress;
|
||||
page: ProcessedTransaction[] | undefined;
|
||||
controller: SearchController | undefined;
|
||||
};
|
||||
|
||||
const NavBar: React.FC<NavBarProps> = ({ address, page, controller }) => (
|
||||
<div className="flex justify-between items-baseline py-3">
|
||||
<div className="text-sm text-gray-500">
|
||||
{page === undefined ? (
|
||||
<>Waiting for search results...</>
|
||||
) : (
|
||||
<>{page.length} transactions on this page</>
|
||||
)}
|
||||
</div>
|
||||
<UndefinedPageControl
|
||||
address={address}
|
||||
isFirst={controller?.isFirst}
|
||||
isLast={controller?.isLast}
|
||||
prevHash={page?.[0]?.hash ?? ""}
|
||||
nextHash={page?.[page.length - 1]?.hash ?? ""}
|
||||
disabled={controller === undefined}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
||||
export default AddressTransactionResults;
|
||||
|
|
|
@ -17,9 +17,14 @@ export class CompositeAddressResolver<T = any>
|
|||
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];
|
||||
try {
|
||||
const resolvedAddress = await r.resolveAddress(provider, address);
|
||||
if (resolvedAddress !== undefined) {
|
||||
return [r, resolvedAddress];
|
||||
}
|
||||
} catch (err) {
|
||||
console.warn(`Error while trying to resolve addr ${address}`);
|
||||
console.warn(err);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -19,23 +19,38 @@ import { HardcodedAddressResolver } from "./HardcodedAddressResolver";
|
|||
export type ResolvedAddresses = Record<string, SelectedResolvedName<any>>;
|
||||
|
||||
// Create and configure the main resolver
|
||||
export const ensResolver = new ENSAddressResolver();
|
||||
export const uniswapV1Resolver = new UniswapV1Resolver();
|
||||
export const uniswapV2Resolver = new UniswapV2Resolver();
|
||||
export const uniswapV3Resolver = new UniswapV3Resolver();
|
||||
export const ercTokenResolver = new ERCTokenResolver();
|
||||
export const hardcodedResolver = new HardcodedAddressResolver();
|
||||
const ensResolver = new ENSAddressResolver();
|
||||
const uniswapV1Resolver = new UniswapV1Resolver();
|
||||
const uniswapV2Resolver = new UniswapV2Resolver();
|
||||
const uniswapV3Resolver = new UniswapV3Resolver();
|
||||
const ercTokenResolver = new ERCTokenResolver();
|
||||
const hardcodedResolver = new HardcodedAddressResolver();
|
||||
|
||||
const _mainResolver = new CompositeAddressResolver();
|
||||
_mainResolver.addResolver(ensResolver);
|
||||
_mainResolver.addResolver(uniswapV3Resolver);
|
||||
_mainResolver.addResolver(uniswapV2Resolver);
|
||||
_mainResolver.addResolver(uniswapV1Resolver);
|
||||
_mainResolver.addResolver(ercTokenResolver);
|
||||
_mainResolver.addResolver(hardcodedResolver);
|
||||
const _mainnetResolver = new CompositeAddressResolver();
|
||||
_mainnetResolver.addResolver(ensResolver);
|
||||
_mainnetResolver.addResolver(uniswapV3Resolver);
|
||||
_mainnetResolver.addResolver(uniswapV2Resolver);
|
||||
_mainnetResolver.addResolver(uniswapV1Resolver);
|
||||
_mainnetResolver.addResolver(ercTokenResolver);
|
||||
_mainnetResolver.addResolver(hardcodedResolver);
|
||||
|
||||
export const mainResolver: IAddressResolver<SelectedResolvedName<any>> =
|
||||
_mainResolver;
|
||||
const _defaultResolver = new CompositeAddressResolver();
|
||||
_defaultResolver.addResolver(hardcodedResolver);
|
||||
|
||||
const resolvers: Record<number, IAddressResolver<SelectedResolvedName<any>>> = {
|
||||
1: _mainnetResolver,
|
||||
0: _defaultResolver,
|
||||
};
|
||||
|
||||
export const getResolver = (
|
||||
chainId: number
|
||||
): IAddressResolver<SelectedResolvedName<any>> => {
|
||||
const resolver = resolvers[chainId];
|
||||
if (resolver === undefined) {
|
||||
return resolver[0]; // default MAGIC NUMBER
|
||||
}
|
||||
return resolver;
|
||||
};
|
||||
|
||||
export const resolverRendererRegistry = new Map<
|
||||
IAddressResolver<any>,
|
||||
|
|
|
@ -4,16 +4,19 @@ import ContentFrame from "../ContentFrame";
|
|||
|
||||
type AddressOrENSNameNotFoundProps = {
|
||||
addressOrENSName: string;
|
||||
supportsENS: boolean;
|
||||
};
|
||||
|
||||
const AddressOrENSNameNotFound: React.FC<AddressOrENSNameNotFoundProps> = ({
|
||||
addressOrENSName,
|
||||
supportsENS,
|
||||
}) => (
|
||||
<>
|
||||
<StandardSubtitle>Transaction Details</StandardSubtitle>
|
||||
<ContentFrame>
|
||||
<div className="py-4 text-sm">
|
||||
"{addressOrENSName}" is not an ETH address or ENS name.
|
||||
"{addressOrENSName}" is not an ETH address
|
||||
{supportsENS && " or ENS name"}.
|
||||
</div>
|
||||
</ContentFrame>
|
||||
</>
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
import React from "react";
|
||||
import ContentFrame from "../ContentFrame";
|
||||
|
||||
type BlockNotFoundProps = {
|
||||
blockNumberOrHash: string;
|
||||
};
|
||||
|
||||
const BlockNotFound: React.FC<BlockNotFoundProps> = ({ blockNumberOrHash }) => (
|
||||
<ContentFrame>
|
||||
<div className="py-4 text-sm">Block "{blockNumberOrHash}" not found.</div>
|
||||
</ContentFrame>
|
||||
);
|
||||
|
||||
export default React.memo(BlockNotFound);
|
|
@ -22,7 +22,7 @@ const Copy: React.FC<CopyProps> = ({ value, rounded }) => {
|
|||
|
||||
return (
|
||||
<button
|
||||
className={`text-gray-500 focus:outline-none ${
|
||||
className={`self-center flex flex-no-wrap justify-center items-center space-x-1 text-gray-500 focus:outline-none ${
|
||||
rounded
|
||||
? "transition-colors transition-shadows bg-gray-200 hover:bg-gray-500 hover:text-gray-200 hover:shadow w-7 h-7 rounded-full text-xs"
|
||||
: "text-sm"
|
||||
|
@ -34,10 +34,10 @@ const Copy: React.FC<CopyProps> = ({ value, rounded }) => {
|
|||
rounded ? (
|
||||
<FontAwesomeIcon icon={faCheck} size="1x" />
|
||||
) : (
|
||||
<div className="space-x-1">
|
||||
<>
|
||||
<FontAwesomeIcon icon={faCheckCircle} size="1x" />
|
||||
{!rounded && <span>Copied</span>}
|
||||
</div>
|
||||
<span className="self-baseline">Copied</span>
|
||||
</>
|
||||
)
|
||||
) : (
|
||||
<FontAwesomeIcon icon={faCopy} size="1x" />
|
||||
|
|
|
@ -7,6 +7,13 @@ type ETH2USDValueProps = {
|
|||
eth2USDValue: BigNumber;
|
||||
};
|
||||
|
||||
/**
|
||||
* Basic display of ETH -> USD values WITHOUT box decoration, only
|
||||
* text formatting.
|
||||
*
|
||||
* USD amounts are displayed commified with 2 decimals places and $ prefix,
|
||||
* i.e., "$1,000.00".
|
||||
*/
|
||||
const ETH2USDValue: React.FC<ETH2USDValueProps> = ({
|
||||
ethAmount,
|
||||
eth2USDValue,
|
||||
|
|
|
@ -7,6 +7,7 @@ type FormatterBalanceProps = {
|
|||
decimals?: number;
|
||||
};
|
||||
|
||||
// TODO: remove duplication with TransactionValue component
|
||||
const FormattedBalance: React.FC<FormatterBalanceProps> = ({
|
||||
value,
|
||||
decimals = 18,
|
||||
|
|
|
@ -6,22 +6,34 @@ type TransactionValueProps = {
|
|||
value: BigNumber;
|
||||
decimals?: number;
|
||||
hideUnit?: boolean;
|
||||
unitName?: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* Standard component for displaying balances. It:
|
||||
*
|
||||
* - Commify non-decimal parts, i.e., 1,000,000.00
|
||||
* - Light gray absolute zero values
|
||||
* - Cut out decimal part is it is 0 to reduce UI clutter, i.e., show
|
||||
* 123 instead of 123.00
|
||||
*
|
||||
* TODO: remove duplication with FormattedBalance
|
||||
*/
|
||||
const TransactionValue: React.FC<TransactionValueProps> = ({
|
||||
value,
|
||||
decimals = 18,
|
||||
hideUnit,
|
||||
unitName = "ETH",
|
||||
}) => {
|
||||
const formattedValue = formatValue(value, decimals);
|
||||
|
||||
return (
|
||||
<span
|
||||
className={`text-sm ${value.isZero() ? "text-gray-400" : ""}`}
|
||||
title={`${formattedValue} Ether`}
|
||||
title={`${formattedValue} ${unitName}`}
|
||||
>
|
||||
<span className={`font-balance`}>{formattedValue}</span>
|
||||
{!hideUnit && " Ether"}
|
||||
{!hideUnit && ` ${unitName}`}
|
||||
</span>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
export const MIN_API_LEVEL = 6;
|
||||
export const MIN_API_LEVEL = 8;
|
||||
|
||||
export const PAGE_SIZE = 25;
|
||||
|
|
|
@ -75,6 +75,9 @@ const Blocks: React.FC<BlocksProps> = ({ latestBlock, targetBlockNumber }) => {
|
|||
if (_blocks.length > 0 && blockNumber === _blocks[0].number) {
|
||||
return _blocks;
|
||||
}
|
||||
if (extBlock === null) {
|
||||
return _blocks;
|
||||
}
|
||||
|
||||
// Leave the last block because of transition animation
|
||||
const newBlocks = [extBlock, ..._blocks].slice(
|
||||
|
|
|
@ -36,19 +36,24 @@ export interface ExtendedBlock extends Block {
|
|||
export const readBlock = async (
|
||||
provider: JsonRpcProvider,
|
||||
blockNumberOrHash: string
|
||||
) => {
|
||||
): Promise<ExtendedBlock | null> => {
|
||||
let blockPromise: Promise<any>;
|
||||
if (isHexString(blockNumberOrHash, 32)) {
|
||||
// TODO: fix
|
||||
blockPromise = provider.send("eth_getBlockByHash", [
|
||||
blockPromise = provider.send("ots_getBlockDetailsByHash", [
|
||||
blockNumberOrHash,
|
||||
false,
|
||||
]);
|
||||
} else {
|
||||
blockPromise = provider.send("ots_getBlockDetails", [blockNumberOrHash]);
|
||||
const blockNumber = parseInt(blockNumberOrHash);
|
||||
if (isNaN(blockNumber) || blockNumber < 0) {
|
||||
return null;
|
||||
}
|
||||
blockPromise = provider.send("ots_getBlockDetails", [blockNumber]);
|
||||
}
|
||||
|
||||
const _rawBlock = await blockPromise;
|
||||
if (_rawBlock === null) {
|
||||
return null;
|
||||
}
|
||||
const _block = provider.formatter.block(_rawBlock.block);
|
||||
const _rawIssuance = _rawBlock.issuance;
|
||||
|
||||
|
@ -162,11 +167,11 @@ export const useBlockTransactions = (
|
|||
export const useBlockData = (
|
||||
provider: JsonRpcProvider | undefined,
|
||||
blockNumberOrHash: string
|
||||
) => {
|
||||
const [block, setBlock] = useState<ExtendedBlock>();
|
||||
): ExtendedBlock | null | undefined => {
|
||||
const [block, setBlock] = useState<ExtendedBlock | null | undefined>();
|
||||
useEffect(() => {
|
||||
if (!provider) {
|
||||
return;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const _readBlock = async () => {
|
||||
|
@ -201,7 +206,7 @@ export const useTxData = (
|
|||
return;
|
||||
}
|
||||
|
||||
let _block: ExtendedBlock | undefined;
|
||||
let _block: ExtendedBlock | null | undefined;
|
||||
if (_response.blockNumber) {
|
||||
_block = await readBlock(provider, _response.blockNumber.toString());
|
||||
}
|
||||
|
@ -600,3 +605,77 @@ export const useTransactionBySenderAndNonce = (
|
|||
}
|
||||
return data;
|
||||
};
|
||||
|
||||
type ContractCreatorKey = {
|
||||
type: "cc";
|
||||
network: number;
|
||||
address: ChecksummedAddress;
|
||||
};
|
||||
|
||||
type ContractCreator = {
|
||||
hash: string;
|
||||
creator: ChecksummedAddress;
|
||||
};
|
||||
|
||||
export const useContractCreator = (
|
||||
provider: JsonRpcProvider | undefined,
|
||||
address: ChecksummedAddress | undefined
|
||||
): ContractCreator | null | undefined => {
|
||||
const { data, error } = useSWR<
|
||||
ContractCreator | null | undefined,
|
||||
any,
|
||||
ContractCreatorKey | null
|
||||
>(
|
||||
provider && address
|
||||
? {
|
||||
type: "cc",
|
||||
network: provider.network.chainId,
|
||||
address,
|
||||
}
|
||||
: null,
|
||||
getContractCreatorFetcher(provider!)
|
||||
);
|
||||
|
||||
if (error) {
|
||||
return undefined;
|
||||
}
|
||||
return data as ContractCreator;
|
||||
};
|
||||
|
||||
const getContractCreatorFetcher =
|
||||
(provider: JsonRpcProvider) =>
|
||||
async ({
|
||||
network,
|
||||
address,
|
||||
}: ContractCreatorKey): Promise<ContractCreator | null | undefined> => {
|
||||
const result = (await provider.send("ots_getContractCreator", [
|
||||
address,
|
||||
])) as ContractCreator;
|
||||
|
||||
// Empty or success
|
||||
if (result) {
|
||||
result.creator = provider.formatter.address(result.creator);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
export const useAddressBalance = (
|
||||
provider: JsonRpcProvider | undefined,
|
||||
address: ChecksummedAddress | undefined
|
||||
): BigNumber | null | undefined => {
|
||||
const [balance, setBalance] = useState<BigNumber | undefined>();
|
||||
|
||||
useEffect(() => {
|
||||
if (!provider || !address) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const readBalance = async () => {
|
||||
const _balance = await provider.getBalance(address);
|
||||
setBalance(_balance);
|
||||
};
|
||||
readBalance();
|
||||
}, [provider, address]);
|
||||
|
||||
return balance;
|
||||
};
|
||||
|
|
|
@ -2,7 +2,7 @@ import { useState, useEffect, useContext } from "react";
|
|||
import { BaseProvider } from "@ethersproject/providers";
|
||||
import { getAddress, isAddress } from "@ethersproject/address";
|
||||
import useSWRImmutable from "swr/immutable";
|
||||
import { mainResolver } from "./api/address-resolver";
|
||||
import { getResolver } from "./api/address-resolver";
|
||||
import { SelectedResolvedName } from "./api/address-resolver/CompositeAddressResolver";
|
||||
import { RuntimeContext } from "./useRuntime";
|
||||
import { ChecksummedAddress } from "./types";
|
||||
|
@ -48,19 +48,25 @@ export const useAddressOrENS = (
|
|||
if (!provider) {
|
||||
return;
|
||||
}
|
||||
const resolveName = async () => {
|
||||
const resolvedAddress = await provider.resolveName(addressOrName);
|
||||
if (resolvedAddress !== null) {
|
||||
setENS(true);
|
||||
setError(false);
|
||||
setChecksummedAddress(resolvedAddress);
|
||||
} else {
|
||||
setENS(false);
|
||||
setError(true);
|
||||
setChecksummedAddress(undefined);
|
||||
}
|
||||
};
|
||||
resolveName();
|
||||
if (provider.network.ensAddress) {
|
||||
const resolveName = async () => {
|
||||
const resolvedAddress = await provider.resolveName(addressOrName);
|
||||
if (resolvedAddress !== null) {
|
||||
setENS(true);
|
||||
setError(false);
|
||||
setChecksummedAddress(resolvedAddress);
|
||||
} else {
|
||||
setENS(false);
|
||||
setError(true);
|
||||
setChecksummedAddress(undefined);
|
||||
}
|
||||
};
|
||||
resolveName();
|
||||
} else {
|
||||
setENS(false);
|
||||
setError(true);
|
||||
setChecksummedAddress(undefined);
|
||||
}
|
||||
}, [provider, addressOrName, urlFixer]);
|
||||
|
||||
return [checksummedAddress, isENS, error];
|
||||
|
@ -76,7 +82,8 @@ export const useResolvedAddress = (
|
|||
if (!provider) {
|
||||
return undefined;
|
||||
}
|
||||
return mainResolver.resolveAddress(provider, address);
|
||||
const resolver = getResolver(provider.network.chainId);
|
||||
return resolver.resolveAddress(provider, address);
|
||||
};
|
||||
|
||||
const { data, error } = useSWRImmutable(address, fetcher);
|
||||
|
|
Loading…
Reference in New Issue