diff --git a/CHANGELOG.md b/CHANGELOG.md index 811d339..49e6fec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 1.1.0 +Published by **[jarcodallo](https://github.com/jarcodallo)** on **2021/02/11** +- [#17](https://github.com/protofire/polkadot-mempool-explorer/pull/17) Update polkadot dependencies an fix node connection issue. + ## 1.0.3 Published by **[jarcodallo](https://github.com/jarcodallo)** on **2021/01/28** - [#16](https://github.com/protofire/polkadot-mempool-explorer/pull/16) UI Fixes, API Definition and CODE_OF_CONDUCT diff --git a/README.md b/README.md index f9cf9cb..386813c 100644 --- a/README.md +++ b/README.md @@ -83,12 +83,6 @@ Displays log output from custom `polkadot-westend` service. Displays log output from custom `polkadot-main` service. -## Mempool Explorer API Definition - -

- -You can read more about the API Definition [here](https://mempool.dot.protofire.io/api/v1/api-docs). - ## Contributing ### Code of Conduct diff --git a/api/README.md b/api/README.md new file mode 100644 index 0000000..bdfcb87 --- /dev/null +++ b/api/README.md @@ -0,0 +1,45 @@ +# Polkadot Mempool Explorer API + +Mempool Explorer API Definition [api-docs](https://mempool.dot.protofire.io/api/v1/api-docs). + +## Environment setup + + - Install [Node.js](https://nodejs.org/) + - Recommended method is by using [NVM](https://github.com/creationix/nvm) + - Recommended Node.js version is v12 + +## Demo + +[mempool.dot.protofire.io](https://mempool.dot.protofire.io) + +## Custom Polkadot Node + +In order to track extrinsics lifecycle. We added a new RPC method ([author_trackExtrinsic](https://github.com/protofire/polkadot-mempool-explorer/blob/develop/api/services/polkadot/custom-rpc-methods.js)) on [Substrate core](https://github.com/jarcodallo/substrate/blob/master/client/rpc-api/src/author/mod.rs). + +This basically allows someone to subscribe and track status changes in the extrinsics lifecycle, for example movements getting in or out of queues, and everything that matters for us before including those extrinsics in blocks. + + - Substrate change: [github.com/paritytech/substrate](https://github.com/jarcodallo/substrate/commits/master) + - Polkadot dependencies update: [github.com/paritytech/polkadot](https://github.com/jarcodallo/polkadot/commits/master) + - Docker image of the polkadot binary: [hub.docker.com/polkadot](https://hub.docker.com/repository/docker/jarcodallo/polkadot) + +## Get Started + +In the project directory, you can run: + +### `npm start` + +Runs the NodeJs service in the development mode.\ +Open [localhost:8081/api/v1/api-docs](http://localhost:8084/api/v1/api-docs) to view it in the browser or Postman. + +The service will reload if you make edits. + +## Mempool Explorer API Definition + +

+ + +## Endpoints + + - `/networks`: Get networks [specs](https://github.com/protofire/polkadot-mempool-explorer/blob/main/api/routes/explorerApiDocumentation.js#L32-L65). + - `/networks/:networkId/reset`: Reset the listener for a network id. [specs](https://github.com/protofire/polkadot-mempool-explorer/blob/main/api/routes/explorerApiDocumentation.js#L66-L95). + - `/transactions/:networkId`: Get transactions by network id. [specs](https://github.com/protofire/polkadot-mempool-explorer/blob/main/api/routes/explorerApiDocumentation.js#L96-L133). \ No newline at end of file diff --git a/api/constants/networks.js b/api/constants/networks.js index 601bcff..938d4a1 100644 --- a/api/constants/networks.js +++ b/api/constants/networks.js @@ -1,7 +1,7 @@ const DEFAULT_NETWORK = { id: 'polkadot', name: 'Polkadot', - url: 'wss://cc1-1.polkadot.network', + url: 'wss://rpc.polkadot.io', }; const LIVE_NETWORKS = [ @@ -9,26 +9,21 @@ const LIVE_NETWORKS = [ { id: 'kusama', name: 'Kusama', - url: 'wss://cc3-5.kusama.network', + url: 'wss://kusama-rpc.polkadot.io', }, ]; const TEST_NETWORKS = [ - { - id: 'amber', - name: 'Amber', - url: 'wss://fullnode.amber.centrifuge.io', - }, { id: 'westend2', name: 'Westend', url: 'wss://westend-rpc.polkadot.io', }, - // { - // id: 'rococo', - // name: 'Rococo', - // url: 'wss://rococo-rpc.polkadot.io', - // }, + { + id: 'rococo', + name: 'Rococo', + url: 'wss://rococo-rpc.polkadot.io', + }, // { // id: 'rococo-tick', // name: 'Rococo Tick', diff --git a/api/env.js b/api/env.js index 4604ca7..af89aef 100644 --- a/api/env.js +++ b/api/env.js @@ -21,4 +21,7 @@ module.exports = Object.assign({}, variables, { CACHE_MAX_AGE: variables.CACHE_MAX_AGE || 3600000 * 24, // Default 24 hours NETWORK_MAX_ITEMS: variables.NETWORK_MAX_ITEMS || 50, // Default 50 DATE_FORMAT: variables.DATE_FORMAT || 'MMM D, YYYY, h:mm:ss A', + WS_PROVIDER_RETRIES: variables.WS_PROVIDER_RETRIES || 5, // Default 10 times + WS_PROVIDER_RETRY_DELAY: variables.WS_PROVIDER_RETRY_DELAY || 5000, // Default 5 seconds + FETCH_PENDING_EXTRINSICS_DELAY: variables.FETCH_PENDING_EXTRINSICS_DELAY || 5000, // Default 5 seconds }); diff --git a/api/package-lock.json b/api/package-lock.json index d65113d..d704886 100644 --- a/api/package-lock.json +++ b/api/package-lock.json @@ -1,16 +1,16 @@ { "name": "api", - "version": "1.0.2", + "version": "1.0.3", "lockfileVersion": 1, "requires": true, "dependencies": { "@babel/code-frame": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", - "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz", + "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==", "dev": true, "requires": { - "@babel/highlight": "^7.10.4" + "@babel/highlight": "^7.12.13" } }, "@babel/helper-validator-identifier": { @@ -20,12 +20,12 @@ "dev": true }, "@babel/highlight": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", - "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.12.13.tgz", + "integrity": "sha512-kocDQvIbgMKlWxXe9fof3TQ+gkIPOUSEYhJjqUjvKMez3krV7vbzYCDq39Oj11UAVK7JqPVGQPlgE85dPNlQww==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.10.4", + "@babel/helper-validator-identifier": "^7.12.11", "chalk": "^2.0.0", "js-tokens": "^4.0.0" }, @@ -44,9 +44,9 @@ } }, "@babel/runtime": { - "version": "7.12.5", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz", - "integrity": "sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.13.tgz", + "integrity": "sha512-8+3UMPBrjFa/6TtKi/7sehPKqfAm4g6K+YQjyyFOLUTxzOngcRZTlAVY8sc2CORJYqdHQY8gRPHmn+qo15rCBw==", "requires": { "regenerator-runtime": "^0.13.4" } @@ -93,21 +93,21 @@ "dev": true }, "@polkadot/api": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/@polkadot/api/-/api-3.5.1.tgz", - "integrity": "sha512-prnWXjzMBZczpIhnF4dgamWAUOn5V4Fhv/D85QyEcrloiLgC5JBhXgdhDwHcESh+fkw8+gFptkuIMu3emWVaHg==", - "requires": { - "@babel/runtime": "^7.12.5", - "@polkadot/api-derive": "3.5.1", - "@polkadot/keyring": "^5.3.1", - "@polkadot/metadata": "3.5.1", - "@polkadot/rpc-core": "3.5.1", - "@polkadot/rpc-provider": "3.5.1", - "@polkadot/types": "3.5.1", - "@polkadot/types-known": "3.5.1", - "@polkadot/util": "^5.3.1", - "@polkadot/util-crypto": "^5.3.1", - "@polkadot/x-rxjs": "3.5.1", + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/@polkadot/api/-/api-3.8.1.tgz", + "integrity": "sha512-5ayXsixyEL7A/ljFBCJReYfn9KAxfTJRTymDVf4S3aOwll0WRtvb0Vhy8nQa9H9RQleQ2Bk5JL5zx4EgAy01dg==", + "requires": { + "@babel/runtime": "^7.12.13", + "@polkadot/api-derive": "3.8.1", + "@polkadot/keyring": "^5.6.1", + "@polkadot/metadata": "3.8.1", + "@polkadot/rpc-core": "3.8.1", + "@polkadot/rpc-provider": "3.8.1", + "@polkadot/types": "3.8.1", + "@polkadot/types-known": "3.8.1", + "@polkadot/util": "^5.6.1", + "@polkadot/util-crypto": "^5.6.1", + "@polkadot/x-rxjs": "^5.6.1", "bn.js": "^4.11.9", "eventemitter3": "^4.0.7" }, @@ -120,17 +120,17 @@ } }, "@polkadot/api-derive": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/@polkadot/api-derive/-/api-derive-3.5.1.tgz", - "integrity": "sha512-hZlWc05+td1SikFdKH0v9sTd5lz0s5LF+JHJNA35m07zG3MISEByxGhEbGDtBtCe5k4e8CL9JNgw4GcdGVOKiA==", - "requires": { - "@babel/runtime": "^7.12.5", - "@polkadot/api": "3.5.1", - "@polkadot/rpc-core": "3.5.1", - "@polkadot/types": "3.5.1", - "@polkadot/util": "^5.3.1", - "@polkadot/util-crypto": "^5.3.1", - "@polkadot/x-rxjs": "3.5.1", + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/@polkadot/api-derive/-/api-derive-3.8.1.tgz", + "integrity": "sha512-F9HAPNz7MtK5EPhn/2nI3Gu4xQuLDX0rnv+v5K6LZybCPxh9ei3na56PCeCkG5kruoILtSnXecTuSrPyE1EWJA==", + "requires": { + "@babel/runtime": "^7.12.13", + "@polkadot/api": "3.8.1", + "@polkadot/rpc-core": "3.8.1", + "@polkadot/types": "3.8.1", + "@polkadot/util": "^5.6.1", + "@polkadot/util-crypto": "^5.6.1", + "@polkadot/x-rxjs": "^5.6.1", "bn.js": "^4.11.9" }, "dependencies": { @@ -142,25 +142,25 @@ } }, "@polkadot/keyring": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/@polkadot/keyring/-/keyring-5.3.1.tgz", - "integrity": "sha512-wbi1kVxNoxY4hJOcqwHjk+17/aVHGkYzVjASj1QPjNbHVho+KKcjrJVRtUu9ekkblh84sWl9DbcjPwyDDr5F0w==", + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/@polkadot/keyring/-/keyring-5.6.2.tgz", + "integrity": "sha512-LqN/ziJ3Nbpn1hiaGVc5DRKDxfbdY1kjTO9W8P4XENrGQmKzr+iBucNv/8KoFgKcwqksbVAQdvoiUhBkcQLtiw==", "requires": { - "@babel/runtime": "^7.12.5", - "@polkadot/util": "5.3.1", - "@polkadot/util-crypto": "5.3.1" + "@babel/runtime": "^7.12.13", + "@polkadot/util": "5.6.2", + "@polkadot/util-crypto": "5.6.2" } }, "@polkadot/metadata": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/@polkadot/metadata/-/metadata-3.5.1.tgz", - "integrity": "sha512-pfvV3EvlWmX6zJxsMc3TQlBYFJhmds6PH/gNuxZura4JXSS5ocVPu1JuPq+f31W+D6Yc/tl3+wpVM0cVV0a39A==", - "requires": { - "@babel/runtime": "^7.12.5", - "@polkadot/types": "3.5.1", - "@polkadot/types-known": "3.5.1", - "@polkadot/util": "^5.3.1", - "@polkadot/util-crypto": "^5.3.1", + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/@polkadot/metadata/-/metadata-3.8.1.tgz", + "integrity": "sha512-bx+cg/BsjkRzuPEOdvhO62/2+mLJPGxohZL/Uuf1W4hgv/dBYvV/48wSCcpFNIeiJr40Zy2QPD5uiOXfncOtqA==", + "requires": { + "@babel/runtime": "^7.12.13", + "@polkadot/types": "3.8.1", + "@polkadot/types-known": "3.8.1", + "@polkadot/util": "^5.6.1", + "@polkadot/util-crypto": "^5.6.1", "bn.js": "^4.11.9" }, "dependencies": { @@ -172,37 +172,38 @@ } }, "@polkadot/networks": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/@polkadot/networks/-/networks-5.3.1.tgz", - "integrity": "sha512-ilSSPdm7IDKqDzbjRgY7CKwDxCW/2UsOck5TCgDwwZdyRaIsXTQsMDgMqP+jK0rxdEzHSPMvLbnW1uAs7ZWbYA==", + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/@polkadot/networks/-/networks-5.6.2.tgz", + "integrity": "sha512-DI70uSFLUmiVhn8LvoXSfMIbI2/+ikVQydD567QtIsH9uDF2VE4XtdSvykCv5Em3WKs1Wlu1/ylPukKk+2ZEhw==", "requires": { - "@babel/runtime": "^7.12.5" + "@babel/runtime": "^7.12.13" } }, "@polkadot/rpc-core": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/@polkadot/rpc-core/-/rpc-core-3.5.1.tgz", - "integrity": "sha512-iVz8hPMU2y0WR0p0fN+v9CYU1wph9sy4DM/PQjm2gAHun2cAFbK4EGOCUdUWZhE6qWvyGgXJrTja2qH/O1oDrg==", + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/@polkadot/rpc-core/-/rpc-core-3.8.1.tgz", + "integrity": "sha512-QBOZKjOMO6FM0xF4SKwPRk3rOSVM9+h7VoJa4BRdoiFjlgLfbIFl7g4mfNQVHqHjpAIR9ZeE5T6zU9bWIr3uog==", "requires": { - "@babel/runtime": "^7.12.5", - "@polkadot/metadata": "3.5.1", - "@polkadot/rpc-provider": "3.5.1", - "@polkadot/types": "3.5.1", - "@polkadot/util": "^5.3.1", - "@polkadot/x-rxjs": "3.5.1" + "@babel/runtime": "^7.12.13", + "@polkadot/metadata": "3.8.1", + "@polkadot/rpc-provider": "3.8.1", + "@polkadot/types": "3.8.1", + "@polkadot/util": "^5.6.1", + "@polkadot/x-rxjs": "^5.6.1" } }, "@polkadot/rpc-provider": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/@polkadot/rpc-provider/-/rpc-provider-3.5.1.tgz", - "integrity": "sha512-WVPTxVIFv3Lx2fNPHp8uWrUyKixiZDDFffI1nrbZbPeFqzKCmCC56wed0VMrZjmtdFnhQD4M1b4ubV6rHeoACw==", - "requires": { - "@babel/runtime": "^7.12.5", - "@polkadot/types": "3.5.1", - "@polkadot/util": "^5.3.1", - "@polkadot/util-crypto": "^5.3.1", - "@polkadot/x-fetch": "^5.3.1", - "@polkadot/x-ws": "^5.3.1", + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/@polkadot/rpc-provider/-/rpc-provider-3.8.1.tgz", + "integrity": "sha512-1U0A9OxQ2B2ABNFWaporuIaNxMrHqVbWJgpOoRSf8lbnwuHWQClRIljlxBp9TT3S7RKC3XXegQi8zpl22ZEorQ==", + "requires": { + "@babel/runtime": "^7.12.13", + "@polkadot/types": "3.8.1", + "@polkadot/util": "^5.6.1", + "@polkadot/util-crypto": "^5.6.1", + "@polkadot/x-fetch": "^5.6.1", + "@polkadot/x-global": "^5.6.1", + "@polkadot/x-ws": "^5.6.1", "bn.js": "^4.11.9", "eventemitter3": "^4.0.7" }, @@ -215,15 +216,15 @@ } }, "@polkadot/types": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/@polkadot/types/-/types-3.5.1.tgz", - "integrity": "sha512-oeENgaPNwaNGZSvjO/PN2gyDUiPv4MMoEkwhFkO0spuMsbXZ+5oGRbSkAY09uNlo2Hv2pzfXaUDrQ0j+DwSBbg==", - "requires": { - "@babel/runtime": "^7.12.5", - "@polkadot/metadata": "3.5.1", - "@polkadot/util": "^5.3.1", - "@polkadot/util-crypto": "^5.3.1", - "@polkadot/x-rxjs": "3.5.1", + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/@polkadot/types/-/types-3.8.1.tgz", + "integrity": "sha512-ONqae9KD2N/HsSfPB6ZmRh6cuUvrfmhHORNl7ciTzM4Q6MnK1r+66N5wg1wZpadkCIl8eeMzRre065aTKGrm3Q==", + "requires": { + "@babel/runtime": "^7.12.13", + "@polkadot/metadata": "3.8.1", + "@polkadot/util": "^5.6.1", + "@polkadot/util-crypto": "^5.6.1", + "@polkadot/x-rxjs": "^5.6.1", "@types/bn.js": "^4.11.6", "bn.js": "^4.11.9" }, @@ -236,13 +237,14 @@ } }, "@polkadot/types-known": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/@polkadot/types-known/-/types-known-3.5.1.tgz", - "integrity": "sha512-km0T1V+aD42A0/NyUy8nE9poEd++5uaNWp7edZg6Gq5XaTWKpHKasHaSXeEOxtrSs0kkXNL1Y8QDX5+9IUAZqA==", - "requires": { - "@babel/runtime": "^7.12.5", - "@polkadot/types": "3.5.1", - "@polkadot/util": "^5.3.1", + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/@polkadot/types-known/-/types-known-3.8.1.tgz", + "integrity": "sha512-mGQNaFzMImMwU5ahT6QEySkREy++Dt6c2VAf+CuvYKqORQWODM/95cveJdVdypi36iohW0SJc4UCXupicVey7Q==", + "requires": { + "@babel/runtime": "^7.12.13", + "@polkadot/networks": "^5.6.1", + "@polkadot/types": "3.8.1", + "@polkadot/util": "^5.6.1", "bn.js": "^4.11.9" }, "dependencies": { @@ -254,17 +256,17 @@ } }, "@polkadot/util": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/@polkadot/util/-/util-5.3.1.tgz", - "integrity": "sha512-JhXA71kGwlLPj3a7+lGuT3Kgp6Au/UEItnHXLMWdbmlLaWCPhdG5CKrkk/e4yH9VynPDZSyiSOxRgipGiNo8PA==", + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/@polkadot/util/-/util-5.6.2.tgz", + "integrity": "sha512-SgwSmLf6YgLFwLUsVYHiqeheGWRtSBwD76zX+H6rj+qb31V+idtKpa0mxODrZ06x9fRg1erJbxvffya34KuYAQ==", "requires": { - "@babel/runtime": "^7.12.5", - "@polkadot/x-textdecoder": "5.3.1", - "@polkadot/x-textencoder": "5.3.1", + "@babel/runtime": "^7.12.13", + "@polkadot/x-textdecoder": "5.6.2", + "@polkadot/x-textencoder": "5.6.2", "@types/bn.js": "^4.11.6", "bn.js": "^4.11.9", "camelcase": "^5.3.1", - "ip-regex": "^4.2.0" + "ip-regex": "^4.3.0" }, "dependencies": { "bn.js": { @@ -275,20 +277,20 @@ } }, "@polkadot/util-crypto": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/@polkadot/util-crypto/-/util-crypto-5.3.1.tgz", - "integrity": "sha512-bZRKbgyshpgTxoLDwRPAGJHmxs76N6Wv4Bl13NK+MyTUy5s66M7q7n2CJ2hSgHMDTzanwmge1JMSXpC5ujPieg==", - "requires": { - "@babel/runtime": "^7.12.5", - "@polkadot/networks": "5.3.1", - "@polkadot/util": "5.3.1", - "@polkadot/wasm-crypto": "^3.1.1", - "@polkadot/x-randomvalues": "5.3.1", + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/@polkadot/util-crypto/-/util-crypto-5.6.2.tgz", + "integrity": "sha512-cdwyPrfqYWJP2A4/jUnQIlCkMYl6saZR9jlke4PmCva0oYKdJjVCEu2g/caOoLH+wb+w29ulHzKzNRlyswSl0A==", + "requires": { + "@babel/runtime": "^7.12.13", + "@polkadot/networks": "5.6.2", + "@polkadot/util": "5.6.2", + "@polkadot/wasm-crypto": "^3.2.2", + "@polkadot/x-randomvalues": "5.6.2", "base-x": "^3.0.8", "blakejs": "^1.1.0", "bn.js": "^4.11.9", "create-hash": "^1.2.0", - "elliptic": "^6.5.3", + "elliptic": "^6.5.4", "hash.js": "^1.1.7", "js-sha3": "^0.8.0", "scryptsy": "^2.1.0", @@ -304,80 +306,95 @@ } }, "@polkadot/wasm-crypto": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@polkadot/wasm-crypto/-/wasm-crypto-3.1.1.tgz", - "integrity": "sha512-uApLRojJY9Q7Arji6w9/eOYEu8Pg8dm+zt+640QLzC4KVVCpbdMmrcFAXCZXeOIJwsKveZsNehGUCcG77ypVPg==", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@polkadot/wasm-crypto/-/wasm-crypto-3.2.2.tgz", + "integrity": "sha512-dffdBQvFHbP0WLvpCf2fJ5mEWavXj75ykuFR16WIduhTRnI7fVYqYRaiJioUHWvPR34ik/VKlATWG7WPYiF5ZQ==", "requires": { "@babel/runtime": "^7.12.5", - "@polkadot/wasm-crypto-asmjs": "^3.1.1", - "@polkadot/wasm-crypto-wasm": "^3.1.1" + "@polkadot/wasm-crypto-asmjs": "^3.2.2", + "@polkadot/wasm-crypto-wasm": "^3.2.2" } }, "@polkadot/wasm-crypto-asmjs": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@polkadot/wasm-crypto-asmjs/-/wasm-crypto-asmjs-3.1.1.tgz", - "integrity": "sha512-7Lt4B/6dwUhb5OAuSes0qMd83TpkngvEpiXTt2ccf/t2OvAXY9msfeJ9as3dI2jvjA9edD//jiejJ0BHJgpuXw==", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@polkadot/wasm-crypto-asmjs/-/wasm-crypto-asmjs-3.2.2.tgz", + "integrity": "sha512-OD6Ejzq0II+VuMLbs7nvGILO9b7PbK8F74uglDXQIaAl2YXuSEWbpE4S3RY7mRp+1Xg0igeNBhgMdRRUg5vDVg==", "requires": { "@babel/runtime": "^7.12.5" } }, "@polkadot/wasm-crypto-wasm": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@polkadot/wasm-crypto-wasm/-/wasm-crypto-wasm-3.1.1.tgz", - "integrity": "sha512-KaP1Ojf889ZeXHGPmyFTj0Qxr/jQ4yfpaGiEOCvYKXRYsDsbZKfxcb96PFil/x0yoZswWG3TX2S3hebnAzkmBg==", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@polkadot/wasm-crypto-wasm/-/wasm-crypto-wasm-3.2.2.tgz", + "integrity": "sha512-kU0m5X68NA8g7OKu0f0C+M1TmTy+hBEmGZ+7jbGBdDqkogc01sUR6qNtmPiT9g9Qsi1bhCoYVaVqtetpiD+CUw==", "requires": { "@babel/runtime": "^7.12.5" } }, "@polkadot/x-fetch": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/@polkadot/x-fetch/-/x-fetch-5.3.1.tgz", - "integrity": "sha512-MoHQrazcEEpEZHbnkBdXWI2CGcNczqcJYWzwnCPLqHamLGgJrwgCQSYdqdYASV+PHukN0/odDWbfiHLbVBvYew==", + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/@polkadot/x-fetch/-/x-fetch-5.6.2.tgz", + "integrity": "sha512-pAOaD24opprqIKfYdnRsf5aJ7XEnz1ryk2nQ67Ypv4BXQt+pih4kI9mVhZeAoK+yWpX3S6JjZkkkEYQ2lcqbZQ==", "requires": { - "@babel/runtime": "^7.12.5", + "@babel/runtime": "^7.12.13", + "@polkadot/x-global": "5.6.2", + "@types/node-fetch": "^2.5.8", + "node-fetch": "^2.6.1" + } + }, + "@polkadot/x-global": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/@polkadot/x-global/-/x-global-5.6.2.tgz", + "integrity": "sha512-oAj0gf3HtWrxMEpjQPKZ1hlTKw4qMrMXB6lCls+jCK+TfLrwcMLOsYJsqt/RJoNIXyTxnWRgCktOt5UYgWLTGQ==", + "requires": { + "@babel/runtime": "^7.12.13", "@types/node-fetch": "^2.5.8", "node-fetch": "^2.6.1" } }, "@polkadot/x-randomvalues": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/@polkadot/x-randomvalues/-/x-randomvalues-5.3.1.tgz", - "integrity": "sha512-Hf6vYUKBKFR0dMaeBJ+btb6YOCe606zrH9DYbGiKmoKrIfMth+LRw8J9ml8a0q2DOTTfnhpUV3bSdDSBpqb8hA==", + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/@polkadot/x-randomvalues/-/x-randomvalues-5.6.2.tgz", + "integrity": "sha512-+DjkwgmKFTfM8IOY1YvBI0duwuKzOeG/CWR8XuLyE3PnSnTn7eHXUGhtx6LHJPyMg9vHMs34ircYEVmhBKBvbA==", "requires": { - "@babel/runtime": "^7.12.5" + "@babel/runtime": "^7.12.13", + "@polkadot/x-global": "5.6.2" } }, "@polkadot/x-rxjs": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/@polkadot/x-rxjs/-/x-rxjs-3.5.1.tgz", - "integrity": "sha512-LW8KPhqQltzmhhC3HMvIDaQfrR7OSj7JFWVYTrN0GAuPX89pQKak6j98oUd2dWiYSZxEXwD0e6MH5yBTqsAtEw==", + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/@polkadot/x-rxjs/-/x-rxjs-5.6.2.tgz", + "integrity": "sha512-PNifEC0N8e8bxNY/aWkHnWESjvWt8zepavo3xoG/rJ4hTAHRKjtpG9Gv16RCG1QQPiaX38VKHVxeUVqcp5Grcw==", "requires": { - "@babel/runtime": "^7.12.5", + "@babel/runtime": "^7.12.13", "rxjs": "^6.6.3" } }, "@polkadot/x-textdecoder": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/@polkadot/x-textdecoder/-/x-textdecoder-5.3.1.tgz", - "integrity": "sha512-ACt0mO2b1exfWwzgl711xR6Vlciy7cM8qhaD01AnIv/DxWdHQL2dluwFv3Er5663WM9k2QTf/7WamNOt2GyYmQ==", + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/@polkadot/x-textdecoder/-/x-textdecoder-5.6.2.tgz", + "integrity": "sha512-kgZM+HwQSPVXjEJyOZulACHiPctCLsClgOrzsismm6UPPrsoweXFOlLIkK1K7VjloJFzi0uw0TCJxLtjzd24Jw==", "requires": { - "@babel/runtime": "^7.12.5" + "@babel/runtime": "^7.12.13", + "@polkadot/x-global": "5.6.2" } }, "@polkadot/x-textencoder": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/@polkadot/x-textencoder/-/x-textencoder-5.3.1.tgz", - "integrity": "sha512-I3Sc5fPicJVidk88Lsa7Y8QLWPMHsNIUu5MHrqbjNOEgq+blu8UHC/foUgUo+uWxhJsWgIO+eZXVNAmAwMep4w==", + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/@polkadot/x-textencoder/-/x-textencoder-5.6.2.tgz", + "integrity": "sha512-3ln2vwzRi0qH1zHl+MltfX9f3zuQVaYLFHSyfr7FvlJ4mXIXslCjqsgIvmGuyyY50naD2nOd1IWg1uGlNhZLJA==", "requires": { - "@babel/runtime": "^7.12.5" + "@babel/runtime": "^7.12.13", + "@polkadot/x-global": "5.6.2" } }, "@polkadot/x-ws": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/@polkadot/x-ws/-/x-ws-5.3.1.tgz", - "integrity": "sha512-7nw0xqXWHJftoLDu7kbkCj1vo3eW0NE/xiqMxo1/Dc+mi1HJALz+PU5LvOmc6kdrQU46agTH4Cz2vFwXjlFKPg==", + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/@polkadot/x-ws/-/x-ws-5.6.2.tgz", + "integrity": "sha512-HihaUsxceC6KH5PGErugKs/V5sSzGDnmOrCTQ6g8XJ8Ob2CLixyzgF0L7+SUL1PbuvIRsVOJY/jcy2ThHk4OXg==", "requires": { - "@babel/runtime": "^7.12.5", + "@babel/runtime": "^7.12.13", + "@polkadot/x-global": "5.6.2", "@types/websocket": "^1.0.1", "websocket": "^1.0.33" } @@ -389,139 +406,13 @@ "dev": true }, "@substrate/txwrapper": { - "version": "3.10.6", - "resolved": "https://registry.npmjs.org/@substrate/txwrapper/-/txwrapper-3.10.6.tgz", - "integrity": "sha512-8w2XbkJppxikOlbHQatcwHedpFWjzMg2lZv3W+tfRvFLnNRF7Nse5Yvr1wvB4G2jPZQwBYx40SDi2Y0AR5q9ew==", + "version": "3.10.9", + "resolved": "https://registry.npmjs.org/@substrate/txwrapper/-/txwrapper-3.10.9.tgz", + "integrity": "sha512-Zv3YF/ptcca0qIVwFDtgyZLgWG8aR6PT/W/91LOVg70X9QQgHoHFAyMWyKoZTCsTnq8BSJbya2cym6yGJ2rP2g==", "dev": true, "requires": { - "@polkadot/api": "3.3.1", + "@polkadot/api": "3.8.1", "memoizee": "^0.4.14" - }, - "dependencies": { - "@polkadot/api": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/@polkadot/api/-/api-3.3.1.tgz", - "integrity": "sha512-52n7ZSOBD/JNEaKqtI4+G4PCMbrrVzl/sQZhjEV+OCdx0XMwf3Zm7f2X6zukLSo0zoHrBYBKWekN+xR2GHH1Tg==", - "dev": true, - "requires": { - "@babel/runtime": "^7.12.5", - "@polkadot/api-derive": "3.3.1", - "@polkadot/keyring": "^5.2.3", - "@polkadot/metadata": "3.3.1", - "@polkadot/rpc-core": "3.3.1", - "@polkadot/rpc-provider": "3.3.1", - "@polkadot/types": "3.3.1", - "@polkadot/types-known": "3.3.1", - "@polkadot/util": "^5.2.3", - "@polkadot/util-crypto": "^5.2.3", - "@polkadot/x-rxjs": "3.3.1", - "bn.js": "^4.11.9", - "eventemitter3": "^4.0.7" - } - }, - "@polkadot/api-derive": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/@polkadot/api-derive/-/api-derive-3.3.1.tgz", - "integrity": "sha512-q31gxAitW9XKTBpGxJ2pywtQ9QddRZJzgj4mpBAIXVF+CHsOtmM+nvwHtZRE4FiaVQAhvgoWij3ARLfH5eRV2g==", - "dev": true, - "requires": { - "@babel/runtime": "^7.12.5", - "@polkadot/api": "3.3.1", - "@polkadot/rpc-core": "3.3.1", - "@polkadot/types": "3.3.1", - "@polkadot/util": "^5.2.3", - "@polkadot/util-crypto": "^5.2.3", - "@polkadot/x-rxjs": "3.3.1", - "bn.js": "^4.11.9" - } - }, - "@polkadot/metadata": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/@polkadot/metadata/-/metadata-3.3.1.tgz", - "integrity": "sha512-Ebzm+ctbp1mzol1e6C8ECG7NdLzeL4gQKxa1ilKF+wm2kiFwvzrxV21tYmvNI7I3IKMeHT0+X3pRlzUFyfXjSw==", - "dev": true, - "requires": { - "@babel/runtime": "^7.12.5", - "@polkadot/types": "3.3.1", - "@polkadot/types-known": "3.3.1", - "@polkadot/util": "^5.2.3", - "@polkadot/util-crypto": "^5.2.3", - "bn.js": "^4.11.9" - } - }, - "@polkadot/rpc-core": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/@polkadot/rpc-core/-/rpc-core-3.3.1.tgz", - "integrity": "sha512-OBQZl1PNlLTMG1vte6YXwfC7HJqqyQSGLaxS1xJUFJVdIN9txwbsrrqbhgYwWfsWdacFZ11r/rB0HfZ89zdqDg==", - "dev": true, - "requires": { - "@babel/runtime": "^7.12.5", - "@polkadot/metadata": "3.3.1", - "@polkadot/rpc-provider": "3.3.1", - "@polkadot/types": "3.3.1", - "@polkadot/util": "^5.2.3", - "@polkadot/x-rxjs": "3.3.1" - } - }, - "@polkadot/rpc-provider": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/@polkadot/rpc-provider/-/rpc-provider-3.3.1.tgz", - "integrity": "sha512-uniicLPOWGOr0mEgr3KO56ryUTcu+6Fe6vhTpklguB3J7uO2/hIaMpCPN3Yb1xUQ5buQIkp16YVr7SF3pL4PWQ==", - "dev": true, - "requires": { - "@babel/runtime": "^7.12.5", - "@polkadot/types": "3.3.1", - "@polkadot/util": "^5.2.3", - "@polkadot/util-crypto": "^5.2.3", - "@polkadot/x-fetch": "^5.2.3", - "@polkadot/x-ws": "^5.2.3", - "bn.js": "^4.11.9", - "eventemitter3": "^4.0.7" - } - }, - "@polkadot/types": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/@polkadot/types/-/types-3.3.1.tgz", - "integrity": "sha512-Qba8dqyTAZLbep1hCq9gkXmzOp28BXc6fsD7X5+9kibv3/L0ZKHbmKmoDDM4OsBX5Ar04AuxKomR77FJR1FymQ==", - "dev": true, - "requires": { - "@babel/runtime": "^7.12.5", - "@polkadot/metadata": "3.3.1", - "@polkadot/util": "^5.2.3", - "@polkadot/util-crypto": "^5.2.3", - "@polkadot/x-rxjs": "3.3.1", - "@types/bn.js": "^4.11.6", - "bn.js": "^4.11.9" - } - }, - "@polkadot/types-known": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/@polkadot/types-known/-/types-known-3.3.1.tgz", - "integrity": "sha512-foOt/NgYqerqvs7PNlfyNWYKym0CQvrDuF7SkZewW5Y1XF4Ulx60A3pXOfUNwCRHuN9PB/JI/D3g9Fth3Tr0eg==", - "dev": true, - "requires": { - "@babel/runtime": "^7.12.5", - "@polkadot/types": "3.3.1", - "@polkadot/util": "^5.2.3", - "bn.js": "^4.11.9" - } - }, - "@polkadot/x-rxjs": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/@polkadot/x-rxjs/-/x-rxjs-3.3.1.tgz", - "integrity": "sha512-nmvAikDWSkChlqFzTHR5PX2wANVz8IepN9zO4QrgO4PmX3wT/ZykehsLtTXrVsOe95iuoZY4Qyvi9fcnNw0PTQ==", - "dev": true, - "requires": { - "@babel/runtime": "^7.12.5", - "rxjs": "^6.6.3" - } - }, - "bn.js": { - "version": "4.11.9", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", - "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", - "dev": true - } } }, "@szmarczak/http-timer": { @@ -548,9 +439,9 @@ "dev": true }, "@types/node": { - "version": "14.14.21", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.21.tgz", - "integrity": "sha512-cHYfKsnwllYhjOzuC5q1VpguABBeecUp24yFluHpn/BQaVxB1CuQ1FSRZCzrPxrkIfWISXV2LbeoBthLWg0+0A==" + "version": "14.14.25", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.25.tgz", + "integrity": "sha512-EPpXLOVqDvisVxtlbvzfyqSsFeQxltFbluZNRndIb8tr9KiBnYNLzrc1N3pyKUCww2RNrfHDViqDWWE1LCJQtQ==" }, "@types/node-fetch": { "version": "2.5.8", @@ -997,9 +888,9 @@ "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" }, "chai": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", - "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.0.tgz", + "integrity": "sha512-/BFd2J30EcOwmdOgXvVsmM48l0Br0nmZPlO0uOW4XKh6kpsUumRXBgPV+IlaqFaqr9cYbeoZAM1Npx0i4A+aiA==", "dev": true, "requires": { "assertion-error": "^1.1.0", @@ -1454,17 +1345,17 @@ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" }, "elliptic": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz", - "integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==", + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", + "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", "requires": { - "bn.js": "^4.4.0", - "brorand": "^1.0.1", + "bn.js": "^4.11.9", + "brorand": "^1.1.0", "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.0" + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" }, "dependencies": { "bn.js": { @@ -1604,9 +1495,9 @@ "dev": true }, "eslint": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.18.0.tgz", - "integrity": "sha512-fbgTiE8BfUJZuBeq2Yi7J3RB3WGUQ9PNuNbmgi6jt9Iv8qrkxfy19Ds3OpL1Pm7zg3BtTVhvcUZbIRQ0wmSjAQ==", + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.19.0.tgz", + "integrity": "sha512-CGlMgJY56JZ9ZSYhJuhow61lMPPjUzWmChFya71Z/jilVos7mR/jPgaEfVGgMBY5DshbKdG8Ezb8FDCHcoMEMg==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", @@ -1788,9 +1679,9 @@ "dev": true }, "esquery": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.3.1.tgz", - "integrity": "sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", "dev": true, "requires": { "estraverse": "^5.1.0" @@ -2011,9 +1902,9 @@ "integrity": "sha512-4zPxDyhCyiN2wIAtSLI6gc82/EjqZc1onI4Mz/l0pWrAlsSfYH/2ZIcU+e3oA2wDwbzIWNKwa23F8rh6+DRWkw==" }, "flatted": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.1.0.tgz", - "integrity": "sha512-tW+UkmtNg/jv9CSofAKvgVcO7c2URjhTdW1ZTkcAritblu8tajiYy7YisnIflEwtKssCtOxpnBRoCB7iap0/TA==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.1.1.tgz", + "integrity": "sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA==", "dev": true }, "form-data": { @@ -2080,9 +1971,9 @@ "dev": true }, "get-intrinsic": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.0.2.tgz", - "integrity": "sha512-aeX0vrFm21ILl3+JpFFRNe9aUvp6VFZb2/CTbgLb8j75kOhvoNYjt9d8KA/tJG4gSo8nzEDedRl0h7vDmBYRVg==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", + "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", "dev": true, "requires": { "function-bind": "^1.1.1", @@ -2160,9 +2051,9 @@ } }, "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", + "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==", "dev": true }, "growl": { @@ -2342,9 +2233,9 @@ "dev": true }, "ip-regex": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-4.2.0.tgz", - "integrity": "sha512-n5cDDeTWWRwK1EBoWwRti+8nP4NbytBBY0pldmnIkq6Z55KNFmWofh4rl9dPZpj+U/nVq7gweR3ylrvMt4YZ5A==" + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-4.3.0.tgz", + "integrity": "sha512-B9ZWJxHHOHUhUjCPrMpLD4xEq35bUTClHM1S6CBU5ixQnkZmwipwgc96vAd7AAGM9TGHvJR+Uss+/Ak6UphK+Q==" }, "ipaddr.js": { "version": "1.9.1", @@ -2367,9 +2258,9 @@ } }, "is-callable": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.2.tgz", - "integrity": "sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz", + "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==", "dev": true }, "is-ci": { @@ -2470,11 +2361,12 @@ "dev": true }, "is-regex": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz", - "integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.2.tgz", + "integrity": "sha512-axvdhb5pdhEVThqJzYXwMlVuZwC+FF2DpcOhTS+y/8jVq4trxyPgfcwIxIKiyeuLlSQYKkmUaPQJ8ZE4yNKXDg==", "dev": true, "requires": { + "call-bind": "^1.0.2", "has-symbols": "^1.0.1" } }, @@ -3234,9 +3126,9 @@ } }, "pathval": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", - "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", "dev": true }, "picomatch": { @@ -3252,9 +3144,9 @@ "dev": true }, "pino": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/pino/-/pino-6.11.0.tgz", - "integrity": "sha512-VPqEE2sU1z6wqkTtr7DdTktayTNE/JgeuWjfXh9g/TI6X7venzv4gaoU24/jSywf6bBeDfZRHWEeO/6f8bNppA==", + "version": "6.11.1", + "resolved": "https://registry.npmjs.org/pino/-/pino-6.11.1.tgz", + "integrity": "sha512-PoDR/4jCyaP1k2zhuQ4N0NuhaMtei+C9mUHBRRJQujexl/bq3JkeL2OC23ada6Np3zeUMHbO4TGzY2D/rwZX3w==", "requires": { "fast-redact": "^3.0.0", "fast-safe-stringify": "^2.0.7", @@ -3265,9 +3157,9 @@ } }, "pino-http": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/pino-http/-/pino-http-5.3.0.tgz", - "integrity": "sha512-aV4e7L8ez2MCa1qsuuliKYX5CDJug3LjW8oht+r4H4+fcf7ZvxPOppTs7P9dNHccF8k8oqhOcU/myiP4GvzJiA==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/pino-http/-/pino-http-5.5.0.tgz", + "integrity": "sha512-ZXhWeYhUisf9oZdS54XaBTrNVzZ7p61/sw0RpwCdU1vI/qdGWvSG4QUA5qU5Y5ya47ch3kM3HTcZf/QB5SCtNw==", "requires": { "fast-url-parser": "^1.1.3", "pino": "^6.0.0", @@ -3282,9 +3174,9 @@ } }, "pino-pretty": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/pino-pretty/-/pino-pretty-4.3.0.tgz", - "integrity": "sha512-uEc9SUCCGVEs0goZvyznKXBHtI1PNjGgqHviJHxOCEFEWZN6Z/IQKv5pO9gSdm/b+WfX+/dfheWhtZUyScqjlQ==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/pino-pretty/-/pino-pretty-4.5.0.tgz", + "integrity": "sha512-TtIzAq3JrPT4cYMZcXHypAXYV+MTE7ncAPUFoaz/1enVD2Loj+hV6RZsypYo85dm7SbBolW6fcIydOF28iGjsg==", "dev": true, "requires": { "@hapi/bourne": "^2.0.0", @@ -3301,9 +3193,9 @@ } }, "pino-std-serializers": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-3.1.1.tgz", - "integrity": "sha512-Ud4+WzgEr/swOlfQdkxqKP2hlwuQlIqQ5YwYpo9MczNg2mpsKKyKgwQXW5KnP5tgH3/Cy9QRhAhLM8k1K+gfnA==" + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-3.2.0.tgz", + "integrity": "sha512-EqX4pwDPrt3MuOAAUBMU0Tk5kR/YcCM5fNPEzgCO2zJ5HfX0vbiH9HbJglnyeQsN96Kznae6MWD47pZB5avTrg==" }, "pkg-dir": { "version": "2.0.0", @@ -3731,9 +3623,9 @@ } }, "sonic-boom": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-1.3.0.tgz", - "integrity": "sha512-4nX6OYvOYr6R76xfQKi6cZpTO3YSWe/vd+QdIfoH0lBy0MnPkeAbb2rRWgmgADkXUeCKPwO1FZAKlAVWAadELw==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-1.3.2.tgz", + "integrity": "sha512-/B4tAuK2+hIlR94GhhWU1mJHWk5lt0CEuBvG0kvk1qIAzQc4iB1TieMio8DCZxY+Y7tsuzOxSUDOGmaUm3vXMg==", "requires": { "atomic-sleep": "^1.0.0", "flatstr": "^1.0.12" @@ -3900,9 +3792,9 @@ } }, "supertest": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/supertest/-/supertest-6.1.1.tgz", - "integrity": "sha512-3WDAWfqdNifCURjGUHZFv3u5nMg5tFtFRCTJOcSZXdlYZ0gqVF3UMhA7IJDP8nDXnR3gocbQ6s0bpiPnsoFeQw==", + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/supertest/-/supertest-6.1.3.tgz", + "integrity": "sha512-v2NVRyP73XDewKb65adz+yug1XMtmvij63qIWHZzSX8tp6wiq6xBLUy4SUAd2NII6wIipOmHT/FD9eicpJwdgQ==", "dev": true, "requires": { "methods": "^1.1.2", @@ -3919,9 +3811,9 @@ } }, "swagger-ui-dist": { - "version": "3.40.0", - "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-3.40.0.tgz", - "integrity": "sha512-R0eaS61/cOE6wiFOY7AtmoTBV5lZqmyosuE14G9nAudp5MNsNfCTdI9MWJLs8iF28HXdtH8EACiFFtUbQomHog==" + "version": "3.42.0", + "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-3.42.0.tgz", + "integrity": "sha512-hTNX6cX7KWtBZgk6ZQSOzsBJhqdCmD5NOIjb6dBPKSnYZidSkIXOcaPMR3+kwxLrj8bDC881bSDlNbLsHikacg==" }, "swagger-ui-express": { "version": "4.1.6", @@ -3944,9 +3836,9 @@ }, "dependencies": { "ajv": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-7.0.3.tgz", - "integrity": "sha512-R50QRlXSxqXcQP5SvKUrw8VZeypvo12i2IX0EeR5PiZ7bEKeHWgzgo264LDadUsCU42lTJVhFikTqJwNeH34gQ==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-7.1.0.tgz", + "integrity": "sha512-svS9uILze/cXbH0z2myCK2Brqprx/+JJYK5pHicT/GQiBfzzhUVAIT6MwqJg8y4xV/zoGsUeuPuwtoiKSGE15g==", "dev": true, "requires": { "fast-deep-equal": "^3.1.1", diff --git a/api/package.json b/api/package.json index d804bba..775ce58 100644 --- a/api/package.json +++ b/api/package.json @@ -1,6 +1,6 @@ { "name": "api", - "version": "1.0.3", + "version": "1.1.0", "engines": { "node": ">= 14.0.0" }, @@ -15,7 +15,7 @@ "author": "", "license": "ISC", "dependencies": { - "@polkadot/api": "^3.3.1", + "@polkadot/api": "^3.8.1", "body-parser": "^1.19.0", "compression": "^1.7.4", "express": "^4.17.1", diff --git a/api/routes/explorer.js b/api/routes/explorer.js index e42abf2..87585e8 100644 --- a/api/routes/explorer.js +++ b/api/routes/explorer.js @@ -47,7 +47,6 @@ router.post('/networks/:networkId/reset', async (req, res) => { router.get('/transactions/:networkId', async (req, res) => { try { const networkId = req.params.networkId || ''; - await PolkadotService.watchPendingExtrinsics(networkId); const extrinsics = await CacheService.getExtrinsics(networkId); const response = extrinsics.map((extrinsic) => { diff --git a/api/server.js b/api/server.js index 92942df..41a13c7 100644 --- a/api/server.js +++ b/api/server.js @@ -7,6 +7,7 @@ const pinoHttp = require('pino-http'); const { API_BASE_PATH, PORT } = require('./env'); const routes = require('./routes'); const logger = require('./logger'); +const PolkadotService = require('./services/polkadot'); const app = express(); const appLogger = pinoHttp({ logger }); @@ -19,4 +20,11 @@ app.use(API_BASE_PATH, routes); */ http.createServer(app).listen(PORT, () => { logger.info(`App listening on port http://localhost:${PORT}/`); + + // Init all watchers + PolkadotService.initWatchers().then(() => { + logger.info('All watchers started'); + }).catch((err) => { + logger.error({ err }, 'Error trying to init watchers.'); + }); }); diff --git a/api/services/polkadot/index.js b/api/services/polkadot/index.js index ee89baa..53d8c0b 100644 --- a/api/services/polkadot/index.js +++ b/api/services/polkadot/index.js @@ -2,7 +2,12 @@ * Module dependencies */ const { ApiPromise, WsProvider } = require('@polkadot/api'); -const { DEVELOPMENT } = require('../../env'); +const { + DEVELOPMENT, + WS_PROVIDER_RETRIES, + WS_PROVIDER_RETRY_DELAY, + FETCH_PENDING_EXTRINSICS_DELAY, +} = require('../../env'); const { LIVE_NETWORKS, TEST_NETWORKS, @@ -56,6 +61,15 @@ class PolkadotService { await CacheService.setTokenSymbol(networkId, tokenSymbol.toString()); } + static async initWatchers() { + const { test, live, local } = PolkadotService.getNetworks(); + const promises = [...test, ...live, ...local].map((network) => ( + PolkadotService.watchPendingExtrinsics(network.id) + )); + + return Promise.all(promises); + } + /** * Connect to Polkadot via WebSocket * @param {string} networkId @@ -65,26 +79,65 @@ class PolkadotService { // Store all connection in memory. if (!connections[networkId]) { - const provider = new WsProvider(endpoint); - let options = { provider }; - let api = await ApiPromise.create(options); + try { + const provider = new WsProvider(endpoint, false); + + provider.on('connected', () => logger.info(`Service connected to ${endpoint}`)); + provider.on('disconnected', () => { + logger.warn(`Service disconnected from ${endpoint}.`); + logger.info(`Trying to connect again in ${WS_PROVIDER_RETRY_DELAY / 1000} seconds.`); + + let retries = 1; + + // Retry to connect + const unsub = setInterval(async () => { + try { + await provider.connect(); + await PolkadotService.unSubscribeWatchers(networkId); + } catch (err) { + logger.error({ err }, 'Error trying to connect with Provider.'); + } finally { + if (provider.isConnected || retries === WS_PROVIDER_RETRIES) { + clearInterval(unsub); + return; + } + + retries = retries + 1; + } + }, WS_PROVIDER_RETRY_DELAY); + }); + provider.on('error', (err) => { + logger.error({ err }, 'Error trying to connect with Provider.'); + }); - const { methods } = await api.rpc.rpc.methods(); + // connect manually to websocket + await provider.connect(); + + let options = { provider }; + let api = await ApiPromise.create(options); + const { methods } = await api.rpc.rpc.methods(); - customMethodKeys.forEach((methodKey) => { - if (methods.includes(methodKey)) { - options = { ...options, ...customMethods[methodKey] }; + customMethodKeys.forEach((methodKey) => { + if (methods.includes(methodKey)) { + options = { ...options, ...customMethods[methodKey] }; + } + }); + + // If options contains custom RPC methods. + if (options.rpc) { + api = await ApiPromise.create(options); } - }); - // If options contains custom RPC methods. - if (options.rpc) { - api = await ApiPromise.create(options); - } + connections[networkId] = api.clone(); - connections[networkId] = api; + await PolkadotService.setTokenSymbol(networkId, api); + + return connections[networkId]; + } catch (error) { + logger.error({ err: error }, 'Error trying to create Api Provider.'); - await PolkadotService.setTokenSymbol(networkId, api); + return null; + } } return connections[networkId]; @@ -110,10 +163,8 @@ class PolkadotService { * * @param {*} networkId */ - static async hasTrackExtrinsicMethod(networkId) { - const api = await PolkadotService.connect(networkId); - - return typeof api.rpc.author.trackExtrinsic === 'function'; + static hasTrackExtrinsicMethod(networkId) { + return connections[networkId] && connections[networkId].rpc.author.trackExtrinsic === 'function'; } /** @@ -121,25 +172,30 @@ class PolkadotService { * @param {*} networkId */ static async resetWatchPendingExtrinsics(networkId) { + const hasTrackExtrinsicMethod = PolkadotService.hasTrackExtrinsicMethod(networkId); + + PolkadotService.unSubscribeWatchers(networkId); + + if (!hasTrackExtrinsicMethod) { + await PolkadotService.watchNewHeads(networkId); + } + + return PolkadotService.watchPendingExtrinsics(networkId); + } + + static unSubscribeWatchers(networkId) { const unsubExtrinsic = PolkadotService.getExtrinsicWatcher(networkId); const unsubNewHead = PolkadotService.getNewHeadWatcher(networkId); - const hasTrackExtrinsicMethod = await PolkadotService.hasTrackExtrinsicMethod(networkId); - + if (unsubExtrinsic) { // un subscribe from watchPendingExtrinsics - unsubExtrinsic(); + clearInterval(unsubExtrinsic); } if (unsubNewHead) { // un subscribe from watchNewHeads unsubNewHead(); } - - if (!hasTrackExtrinsicMethod) { - await PolkadotService.watchNewHeads(networkId); - } - - return PolkadotService.watchPendingExtrinsics(networkId); } /** @@ -149,93 +205,103 @@ class PolkadotService { static async watchPendingExtrinsics(networkId) { if (!PolkadotService.getExtrinsicWatcher(networkId)) { logger.info(`Init watcher extrinsics for network: ${networkId}`); + + try { + const api = await PolkadotService.connect(networkId); + + if (api) { + // Wait until we are ready and connected + await api.isReady; + + const tokenSymbol = await CacheService.getTokenSymbol(networkId); + const hasTrackExtrinsicMethod = PolkadotService.hasTrackExtrinsicMethod(networkId); + + if (!hasTrackExtrinsicMethod) { + await PolkadotService.watchNewHeads(networkId); + } - const api = await PolkadotService.connect(networkId); - const tokenSymbol = await CacheService.getTokenSymbol(networkId); - const hasTrackExtrinsicMethod = await PolkadotService.hasTrackExtrinsicMethod(networkId); - - if (!hasTrackExtrinsicMethod) { - await PolkadotService.watchNewHeads(networkId); - } - - const unsub = setInterval(async () => { - await api.rpc.author.pendingExtrinsics(async (extrinsics) => { - if (extrinsics.length > 0) { - const rows = []; - - logger.info(`${extrinsics.length} pending extrinsics in the pool.`); - - extrinsics.forEach((extrinsic) => { - const hash = extrinsic.hash.toString(); - const from = extrinsic.signer.toString(); - const nonce = parseInt(extrinsic.nonce.toString(), 10); - const tip = parseFloat(extrinsic.tip.toString()); - let to = null; - let value = 0; - let symbol = tokenSymbol; - let era = { isMortal: false }; - - // Start to track transaction life cycle - if (hasTrackExtrinsicMethod) { - PolkadotService.trackExtrinsic(networkId, hash, from, nonce); - } - - extrinsic.args.forEach((arg) => { - switch (arg.toRawType()) { - case 'AccountId': - to = arg.toHuman(); - break; - case 'Compact': - [value, symbol] = arg.toHuman().split(' '); - break; - default: - break; + const unsub = setInterval(async () => { + await api.rpc.author.pendingExtrinsics(async (extrinsics) => { + if (extrinsics.length > 0) { + const rows = []; + + logger.info(`${extrinsics.length} pending extrinsics in network ${networkId}.`); + + extrinsics.forEach((extrinsic) => { + const hash = extrinsic.hash.toString(); + const from = extrinsic.signer.toString(); + const nonce = parseInt(extrinsic.nonce.toString(), 10); + const tip = parseFloat(extrinsic.tip.toString()); + let to = null; + let value = 0; + let symbol = tokenSymbol; + let era = { isMortal: false }; + + // Start to track transaction life cycle + if (hasTrackExtrinsicMethod) { + PolkadotService.trackExtrinsic(networkId, hash, from, nonce); + } + + extrinsic.args.forEach((arg) => { + switch (arg.toRawType()) { + case 'AccountId': + to = arg.toHuman(); + break; + case 'Compact': + [value, symbol] = arg.toHuman().split(' '); + break; + default: + break; + } + }); + + if (extrinsic.era.isMortalEra) { + const { period, phase } = extrinsic.era.asMortalEra; + era = { + isMortal: true, + period: period.toString(), + phase: phase.toString(), + }; + } + + rows.push({ + networkId, + hash, + from, + to, + value, + era, + nonce, + tip, + tokenSymbol: symbol, + section: extrinsic.method.sectionName, + method: extrinsic.method.methodName, + transactionVersion: extrinsic.type, + specVersion: extrinsic.version, + isSigned: extrinsic.isSigned, + signature: extrinsic.signature.toString(), + createAt: Date.now(), + updateAt: Date.now(), + }); + }); + + try { + // Save extrinsics + await Promise.all(rows.map((row) => CacheService.upsertExtrinsic(row))); + } catch (err) { + logger.error({ err }, 'Error trying to store extrinsis'); } - }); - - if (extrinsic.era.isMortalEra) { - const { period, phase } = extrinsic.era.asMortalEra; - era = { - isMortal: true, - period: period.toString(), - phase: phase.toString(), - }; + } else { + logger.debug(`No pending extrinsics in the pool in network ${networkId}.`); } - - rows.push({ - networkId, - hash, - from, - to, - value, - era, - nonce, - tip, - tokenSymbol: symbol, - section: extrinsic.method.sectionName, - method: extrinsic.method.methodName, - transactionVersion: extrinsic.type, - specVersion: extrinsic.version, - isSigned: extrinsic.isSigned, - signature: extrinsic.signature.toString(), - createAt: Date.now(), - updateAt: Date.now(), - }); }); + }, FETCH_PENDING_EXTRINSICS_DELAY); - try { - // Save extrinsics - await Promise.all(rows.map((row) => CacheService.upsertExtrinsic(row))); - } catch (err) { - logger.error({ err }, 'Error trying to store extrinsis'); - } - } else { - logger.debug('No pending extrinsics in the pool.'); - } - }); - }, 2000); - - extrinsicWatchers[networkId] = unsub; + extrinsicWatchers[networkId] = unsub; + } + } catch (error) { + logger.error({ err }, 'Error on watchPendingExtrinsics.'); + } } } @@ -327,66 +393,76 @@ class PolkadotService { if (!PolkadotService.getNewHeadWatcher(networkId)) { logger.info(`Init watcher heads for network: ${networkId}`); - const api = await PolkadotService.connect(networkId); - const unsub = await api.rpc.chain.subscribeNewHeads(async (header) => { - const pendingExtrinsicHashes = await CacheService.getPendingExtrinsicHashes(networkId); - const blockHash = await api.rpc.chain.getBlockHash(header.number); - const { block } = await api.rpc.chain.getBlock(blockHash); - const blockEvents = await api.query.system.events.at(header.hash); - const rows = []; - - // map between the extrinsics and events - block.extrinsics.forEach((extrinsic, index) => { - const hash = extrinsic.hash.toString(); - - if (pendingExtrinsicHashes.includes(hash)) { - const data = { - hash, - networkId, - from: extrinsic.signer.toString(), - nonce: parseInt(extrinsic.nonce.toString(), 10), - block: { - number: header.number.toString(), - hash: blockHash.toString(), - }, - events: [], - updateAt: Date.now(), - }; - - // filter the specific events based on the phase and then the - // index of our extrinsic in the block - data.events = blockEvents - .filter(({ phase }) => phase.isApplyExtrinsic - && phase.asApplyExtrinsic.eq(index)) - .map(({ event }) => { - if (api.events.system.ExtrinsicSuccess.is(event)) { - data.success = true; - data.finalized = true; - } else if (api.events.system.ExtrinsicFailed.is(event)) { - data.success = false; - data.finalized = true; - } - - return { - method: event.section.toString(), - section: event.method.toString(), - data: event.data.toHuman(), + try { + const api = await PolkadotService.connect(networkId); + + if (api) { + // Wait until we are ready and connected + await api.isReady; + + const unsub = await api.rpc.chain.subscribeNewHeads(async (header) => { + const pendingExtrinsicHashes = await CacheService.getPendingExtrinsicHashes(networkId); + const blockHash = await api.rpc.chain.getBlockHash(header.number); + const { block } = await api.rpc.chain.getBlock(blockHash); + const blockEvents = await api.query.system.events.at(header.hash); + const rows = []; + + // map between the extrinsics and events + block.extrinsics.forEach((extrinsic, index) => { + const hash = extrinsic.hash.toString(); + + if (pendingExtrinsicHashes.includes(hash)) { + const data = { + hash, + networkId, + from: extrinsic.signer.toString(), + nonce: parseInt(extrinsic.nonce.toString(), 10), + block: { + number: header.number.toString(), + hash: blockHash.toString(), + }, + events: [], + updateAt: Date.now(), }; - }); - - rows.push(data); - } - }); - - try { - // Update extrinsics - await Promise.all(rows.map((row) => CacheService.upsertExtrinsic(row))); - } catch (err) { - logger.error({ err }, 'Error trying to update extrinsis'); + + // filter the specific events based on the phase and then the + // index of our extrinsic in the block + data.events = blockEvents + .filter(({ phase }) => phase.isApplyExtrinsic + && phase.asApplyExtrinsic.eq(index)) + .map(({ event }) => { + if (api.events.system.ExtrinsicSuccess.is(event)) { + data.success = true; + data.finalized = true; + } else if (api.events.system.ExtrinsicFailed.is(event)) { + data.success = false; + data.finalized = true; + } + + return { + method: event.section.toString(), + section: event.method.toString(), + data: event.data.toHuman(), + }; + }); + + rows.push(data); + } + }); + + try { + // Update extrinsics + await Promise.all(rows.map((row) => CacheService.upsertExtrinsic(row))); + } catch (err) { + logger.error({ err }, 'Error trying to update extrinsis'); + } + }); + + newHeadWatchers[networkId] = unsub; } - }); - - newHeadWatchers[networkId] = unsub; + } catch (error) { + logger.error({ err }, 'Error on watchNewHeads.'); + } } } } diff --git a/package.json b/package.json index 6c34e85..9c1efb2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "polkadot-mempool-explorer", - "version": "1.0.3", + "version": "1.1.0", "scripts": { "start:dev": "docker-compose up -d", "down": "docker-compose down -v --rmi=local --remove-orphans", diff --git a/web/package.json b/web/package.json index 4f3ea53..133bbb6 100644 --- a/web/package.json +++ b/web/package.json @@ -1,6 +1,6 @@ { "name": "web", - "version": "1.0.3", + "version": "1.1.0", "engines": { "node": ">= 14.0.0" }, diff --git a/web/public/favicon.ico b/web/public/favicon.ico new file mode 100644 index 0000000..ec3c167 Binary files /dev/null and b/web/public/favicon.ico differ