Logging and Caching
This commit is contained in:
parent
3c1f70df9a
commit
c2534570cc
|
@ -26,12 +26,14 @@ module.exports = {
|
|||
"0x0000000000000000000000000000000000000000": {
|
||||
"name": "Ethereum",
|
||||
"symbol": "ETH",
|
||||
"minAcceptedRate": 1
|
||||
"minAcceptedRate": 1,
|
||||
"refreshPricePeriod": 60000
|
||||
},
|
||||
"%STTAddress%": {
|
||||
"name": "Status Test Token",
|
||||
"symbol": "SNT",
|
||||
"minAcceptedRate": 0.0001500,
|
||||
"refreshPricePeriod": 60000,
|
||||
"pricePlugin": "../plugins/token-utils.js"
|
||||
}
|
||||
},
|
||||
|
|
|
@ -26,14 +26,15 @@ module.exports = {
|
|||
"0x0000000000000000000000000000000000000000": {
|
||||
"name": "Ethereum",
|
||||
"symbol": "ETH",
|
||||
"minAcceptedRate": 1
|
||||
|
||||
"minAcceptedRate": 1,
|
||||
"refreshPricePeriod": 60000
|
||||
},
|
||||
"0x121a430A73Fc13e2D6d4a9dc3E943de647c30f8f": {
|
||||
"name": "Status Gas Relayer Test Token",
|
||||
"symbol": "SNT",
|
||||
"minAcceptedRate": 0.0001500,
|
||||
"pricePlugin": "../plugins/token-utils.js"
|
||||
"pricePlugin": "../plugins/token-utils.js",
|
||||
"refreshPricePeriod": 60000
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
@ -191,7 +191,6 @@
|
|||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
|
||||
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"color-convert": "1.9.3"
|
||||
}
|
||||
|
@ -259,6 +258,14 @@
|
|||
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
|
||||
"integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU="
|
||||
},
|
||||
"async": {
|
||||
"version": "2.6.1",
|
||||
"resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz",
|
||||
"integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==",
|
||||
"requires": {
|
||||
"lodash": "4.17.10"
|
||||
}
|
||||
},
|
||||
"async-limiter": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz",
|
||||
|
@ -884,7 +891,6 @@
|
|||
"version": "2.4.1",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
|
||||
"integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-styles": "3.2.1",
|
||||
"escape-string-regexp": "1.0.5",
|
||||
|
@ -897,6 +903,11 @@
|
|||
"integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=",
|
||||
"dev": true
|
||||
},
|
||||
"ci-info": {
|
||||
"version": "1.5.1",
|
||||
"resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.5.1.tgz",
|
||||
"integrity": "sha512-fKFIKXaYiL1exImwJ0AhR/6jxFPSKQBk2ayV5NiNoruUs2+rxC2kNw0EG+1Z9dugZRdCrppskQ8DN2cyaUM1Hw=="
|
||||
},
|
||||
"cipher-base": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz",
|
||||
|
@ -932,11 +943,19 @@
|
|||
"resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
|
||||
"integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ="
|
||||
},
|
||||
"color": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/color/-/color-3.0.0.tgz",
|
||||
"integrity": "sha512-jCpd5+s0s0t7p3pHQKpnJ0TpQKKdleP71LWcA0aqiljpiuAkOSUFN/dyH8ZwF0hRmFlrIuRhufds1QyEP9EB+w==",
|
||||
"requires": {
|
||||
"color-convert": "1.9.3",
|
||||
"color-string": "1.5.3"
|
||||
}
|
||||
},
|
||||
"color-convert": {
|
||||
"version": "1.9.3",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
|
||||
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"color-name": "1.1.3"
|
||||
}
|
||||
|
@ -944,8 +963,35 @@
|
|||
"color-name": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
|
||||
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
|
||||
"dev": true
|
||||
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
|
||||
},
|
||||
"color-string": {
|
||||
"version": "1.5.3",
|
||||
"resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.3.tgz",
|
||||
"integrity": "sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw==",
|
||||
"requires": {
|
||||
"color-name": "1.1.3",
|
||||
"simple-swizzle": "0.2.2"
|
||||
}
|
||||
},
|
||||
"colornames": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/colornames/-/colornames-1.1.1.tgz",
|
||||
"integrity": "sha1-+IiQMGhcfE/54qVZ9Qd+t2qBb5Y="
|
||||
},
|
||||
"colors": {
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmjs.org/colors/-/colors-1.3.2.tgz",
|
||||
"integrity": "sha512-rhP0JSBGYvpcNQj4s5AdShMeE5ahMop96cTeDl/v9qQQm2fYClE2QXZRi8wLzc+GmXSxdIqqbOIAhyObEXDbfQ=="
|
||||
},
|
||||
"colorspace": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.1.tgz",
|
||||
"integrity": "sha512-pI3btWyiuz7Ken0BWh9Elzsmv2bM9AhA7psXib4anUXy/orfZ/E0MbQwhSOG/9L8hLlalqrU0UhOuqxW1YjmVw==",
|
||||
"requires": {
|
||||
"color": "3.0.0",
|
||||
"text-hex": "1.0.0"
|
||||
}
|
||||
},
|
||||
"combined-stream": {
|
||||
"version": "1.0.6",
|
||||
|
@ -980,6 +1026,17 @@
|
|||
"typedarray": "0.0.6"
|
||||
}
|
||||
},
|
||||
"consola": {
|
||||
"version": "1.4.3",
|
||||
"resolved": "https://registry.npmjs.org/consola/-/consola-1.4.3.tgz",
|
||||
"integrity": "sha512-PIbVeO9JVVeJ9eY2n8PrkL+hXBGnmaD5x4yJxp2K9nWR7zgtAzRn7rmWxu/d0Iyyr92v8s5AM0qax6xQZ5rSeQ==",
|
||||
"requires": {
|
||||
"chalk": "2.4.1",
|
||||
"figures": "2.0.0",
|
||||
"lodash": "4.17.10",
|
||||
"std-env": "1.3.1"
|
||||
}
|
||||
},
|
||||
"contains-path": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz",
|
||||
|
@ -1254,6 +1311,16 @@
|
|||
"resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
|
||||
"integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
|
||||
},
|
||||
"diagnostics": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/diagnostics/-/diagnostics-1.1.1.tgz",
|
||||
"integrity": "sha512-8wn1PmdunLJ9Tqbx+Fx/ZEuHfJf4NKSN2ZBj7SJC/OWRWha843+WsTjqMe1B5E3p28jqBlp+mJ2fPVxPyNgYKQ==",
|
||||
"requires": {
|
||||
"colorspace": "1.1.1",
|
||||
"enabled": "1.0.2",
|
||||
"kuler": "1.0.0"
|
||||
}
|
||||
},
|
||||
"diffie-hellman": {
|
||||
"version": "5.0.3",
|
||||
"resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz",
|
||||
|
@ -1312,6 +1379,14 @@
|
|||
"minimalistic-crypto-utils": "1.0.1"
|
||||
}
|
||||
},
|
||||
"enabled": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/enabled/-/enabled-1.0.2.tgz",
|
||||
"integrity": "sha1-ll9lE9LC0cX0ZStkouM5ZGf8L5M=",
|
||||
"requires": {
|
||||
"env-variable": "0.0.4"
|
||||
}
|
||||
},
|
||||
"encodeurl": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
|
||||
|
@ -1325,6 +1400,11 @@
|
|||
"once": "1.4.0"
|
||||
}
|
||||
},
|
||||
"env-variable": {
|
||||
"version": "0.0.4",
|
||||
"resolved": "https://registry.npmjs.org/env-variable/-/env-variable-0.0.4.tgz",
|
||||
"integrity": "sha512-+jpGxSWG4vr6gVxUHOc4p+ilPnql7NzZxOZBxNldsKGjCF+97df3CbuX7XMaDa5oAVkKQj4rKp38rYdC4VcpDg=="
|
||||
},
|
||||
"error-ex": {
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
|
||||
|
@ -1342,8 +1422,7 @@
|
|||
"escape-string-regexp": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
|
||||
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
|
||||
"dev": true
|
||||
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
|
||||
},
|
||||
"eslint": {
|
||||
"version": "4.19.1",
|
||||
|
@ -1789,6 +1868,11 @@
|
|||
"integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
|
||||
"dev": true
|
||||
},
|
||||
"fast-safe-stringify": {
|
||||
"version": "2.0.6",
|
||||
"resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.0.6.tgz",
|
||||
"integrity": "sha512-q8BZ89jjc+mz08rSxROs8VsrBBcn1SIw1kq9NjolL509tkABRk9io01RAjSaEv1Xb2uFLt8VtRiZbGp5H8iDtg=="
|
||||
},
|
||||
"fd-slicer": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz",
|
||||
|
@ -1797,11 +1881,15 @@
|
|||
"pend": "1.2.0"
|
||||
}
|
||||
},
|
||||
"fecha": {
|
||||
"version": "2.3.3",
|
||||
"resolved": "https://registry.npmjs.org/fecha/-/fecha-2.3.3.tgz",
|
||||
"integrity": "sha512-lUGBnIamTAwk4znq5BcqsDaxSmZ9nDVJaij6NvRt/Tg4R69gERA+otPKbS86ROw9nxVMw2/mp1fnaiWqbs6Sdg=="
|
||||
},
|
||||
"figures": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz",
|
||||
"integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"escape-string-regexp": "1.0.5"
|
||||
}
|
||||
|
@ -2097,8 +2185,7 @@
|
|||
"has-flag": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
|
||||
"integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
|
||||
"dev": true
|
||||
"integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0="
|
||||
},
|
||||
"has-symbol-support-x": {
|
||||
"version": "1.4.2",
|
||||
|
@ -2290,6 +2377,14 @@
|
|||
"resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz",
|
||||
"integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA=="
|
||||
},
|
||||
"is-ci": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.2.1.tgz",
|
||||
"integrity": "sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg==",
|
||||
"requires": {
|
||||
"ci-info": "1.5.1"
|
||||
}
|
||||
},
|
||||
"is-fullwidth-code-point": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
|
||||
|
@ -2484,6 +2579,14 @@
|
|||
"sha3": "1.2.2"
|
||||
}
|
||||
},
|
||||
"kuler": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/kuler/-/kuler-1.0.0.tgz",
|
||||
"integrity": "sha512-oyy6pu/yWRjiVfCoJebNUKFL061sNtrs9ejKTbirIwY3oiHmENVCSkHhxDV85Dkm7JYR/czMCBeoM87WilTdSg==",
|
||||
"requires": {
|
||||
"colornames": "1.1.1"
|
||||
}
|
||||
},
|
||||
"levn": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
|
||||
|
@ -2527,8 +2630,26 @@
|
|||
"lodash": {
|
||||
"version": "4.17.10",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz",
|
||||
"integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==",
|
||||
"dev": true
|
||||
"integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg=="
|
||||
},
|
||||
"logform": {
|
||||
"version": "1.9.1",
|
||||
"resolved": "https://registry.npmjs.org/logform/-/logform-1.9.1.tgz",
|
||||
"integrity": "sha512-ZHrZE8VSf7K3xKxJiQ1aoTBp2yK+cEbFcgarsjzI3nt3nE/3O0heNSppoOQMUJVMZo/xiVwCxiXIabaZApsKNQ==",
|
||||
"requires": {
|
||||
"colors": "1.3.2",
|
||||
"fast-safe-stringify": "2.0.6",
|
||||
"fecha": "2.3.3",
|
||||
"ms": "2.1.1",
|
||||
"triple-beam": "1.3.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"ms": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
|
||||
"integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"loose-envify": {
|
||||
"version": "1.4.0",
|
||||
|
@ -2583,6 +2704,11 @@
|
|||
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
|
||||
"integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g="
|
||||
},
|
||||
"memory-cache": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/memory-cache/-/memory-cache-0.2.0.tgz",
|
||||
"integrity": "sha1-eJCwHVLADI68nVM+H46xfjA0hxo="
|
||||
},
|
||||
"merge-descriptors": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
|
||||
|
@ -2792,6 +2918,11 @@
|
|||
"wrappy": "1.0.2"
|
||||
}
|
||||
},
|
||||
"one-time": {
|
||||
"version": "0.0.4",
|
||||
"resolved": "https://registry.npmjs.org/one-time/-/one-time-0.0.4.tgz",
|
||||
"integrity": "sha1-+M33eISCb+Tf+T46nMN7HkSAdC4="
|
||||
},
|
||||
"onetime": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz",
|
||||
|
@ -3433,6 +3564,21 @@
|
|||
"simple-concat": "1.0.0"
|
||||
}
|
||||
},
|
||||
"simple-swizzle": {
|
||||
"version": "0.2.2",
|
||||
"resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz",
|
||||
"integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=",
|
||||
"requires": {
|
||||
"is-arrayish": "0.3.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"is-arrayish": {
|
||||
"version": "0.3.2",
|
||||
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz",
|
||||
"integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"slice-ansi": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz",
|
||||
|
@ -3510,11 +3656,24 @@
|
|||
"tweetnacl": "0.14.5"
|
||||
}
|
||||
},
|
||||
"stack-trace": {
|
||||
"version": "0.0.10",
|
||||
"resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz",
|
||||
"integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA="
|
||||
},
|
||||
"statuses": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
|
||||
"integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow="
|
||||
},
|
||||
"std-env": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/std-env/-/std-env-1.3.1.tgz",
|
||||
"integrity": "sha512-KI2F2pPJpd3lHjng+QLezu0eq+QDtXcv1um016mhOPAJFHKL+09ykK5PUBWta2pZDC8BVV0VPya08A15bUXSLQ==",
|
||||
"requires": {
|
||||
"is-ci": "1.2.1"
|
||||
}
|
||||
},
|
||||
"strict-uri-encode": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz",
|
||||
|
@ -3596,7 +3755,6 @@
|
|||
"version": "5.5.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
|
||||
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"has-flag": "3.0.0"
|
||||
}
|
||||
|
@ -3678,6 +3836,11 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"text-hex": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz",
|
||||
"integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg=="
|
||||
},
|
||||
"text-table": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
|
||||
|
@ -3750,6 +3913,11 @@
|
|||
"integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=",
|
||||
"dev": true
|
||||
},
|
||||
"triple-beam": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.3.0.tgz",
|
||||
"integrity": "sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw=="
|
||||
},
|
||||
"tunnel-agent": {
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
|
||||
|
@ -4191,6 +4359,31 @@
|
|||
"isexe": "2.0.0"
|
||||
}
|
||||
},
|
||||
"winston": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/winston/-/winston-3.1.0.tgz",
|
||||
"integrity": "sha512-FsQfEE+8YIEeuZEYhHDk5cILo1HOcWkGwvoidLrDgPog0r4bser1lEIOco2dN9zpDJ1M88hfDgZvxe5z4xNcwg==",
|
||||
"requires": {
|
||||
"async": "2.6.1",
|
||||
"diagnostics": "1.1.1",
|
||||
"is-stream": "1.1.0",
|
||||
"logform": "1.9.1",
|
||||
"one-time": "0.0.4",
|
||||
"readable-stream": "2.3.6",
|
||||
"stack-trace": "0.0.10",
|
||||
"triple-beam": "1.3.0",
|
||||
"winston-transport": "4.2.0"
|
||||
}
|
||||
},
|
||||
"winston-transport": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.2.0.tgz",
|
||||
"integrity": "sha512-0R1bvFqxSlK/ZKTH86nymOuKv/cT1PQBMuDdA7k7f0S9fM44dNH6bXnuxwXPrN8lefJgtZq08BKdyZ0DZIy/rg==",
|
||||
"requires": {
|
||||
"readable-stream": "2.3.6",
|
||||
"triple-beam": "1.3.0"
|
||||
}
|
||||
},
|
||||
"wordwrap": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
|
||||
|
|
|
@ -22,9 +22,12 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"axios": "^0.18.0",
|
||||
"consola": "^1.4.3",
|
||||
"daemonize2": "^0.4.2",
|
||||
"ganache-cli": "^6.1.0",
|
||||
"jsum": "^0.1.4",
|
||||
"web3": "^1.0.0-beta.33"
|
||||
"memory-cache": "^0.2.0",
|
||||
"web3": "^1.0.0-beta.33",
|
||||
"winston": "^3.1.0"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,11 +8,12 @@ class ContractSettings {
|
|||
* @param {object} web3 - Web3 object already configured
|
||||
* @param {object} eventEmitter - Event Emitter
|
||||
*/
|
||||
constructor(config, web3, eventEmitter){
|
||||
constructor(config, web3, eventEmitter, logger){
|
||||
this.tokens = config.tokens;
|
||||
this.topics = [];
|
||||
this.contracts = config.contracts;
|
||||
this.config = config;
|
||||
this.logger = logger;
|
||||
|
||||
this.web3 = web3;
|
||||
this.events = eventEmitter;
|
||||
|
@ -107,8 +108,8 @@ class ContractSettings {
|
|||
this.pendingToLoad--;
|
||||
if(this.pendingToLoad == 0) this.events.emit("setup:complete", this);
|
||||
} catch(err) {
|
||||
console.error("Invalid contract for " + topicName);
|
||||
console.error(err);
|
||||
this.logger.error("Invalid contract for " + topicName);
|
||||
this.logger.error(err);
|
||||
process.exit();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,11 +9,13 @@ class MessageProcessor {
|
|||
* @param {object} web3 - Web3 object already configured
|
||||
* @param {object} events - Event emitter
|
||||
*/
|
||||
constructor(config, settings, web3, events){
|
||||
constructor(config, settings, web3, events, logger, cache){
|
||||
this.config = config;
|
||||
this.settings = settings;
|
||||
this.web3 = web3;
|
||||
this.events = events;
|
||||
this.logger = logger;
|
||||
this.cache = cache;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -23,7 +25,7 @@ class MessageProcessor {
|
|||
* @returns {object} State of validation
|
||||
*/
|
||||
async _validateInput(contract, input){
|
||||
console.info("Processing '%s' request to contract: %s", input.action, input.contract);
|
||||
this.logger.info("Processing '" + input.action + "' request to contract: " + input.contract);
|
||||
|
||||
if(contract == undefined){
|
||||
return {success: false, message: 'Unknown contract'};
|
||||
|
@ -71,9 +73,9 @@ class MessageProcessor {
|
|||
if(strategy || contract.strategy){
|
||||
let validationResult;
|
||||
if(strategy){
|
||||
validationResult = await strategy.execute(input, reply);
|
||||
validationResult = await strategy.execute(input, this.cache);
|
||||
} else {
|
||||
validationResult = await contract.strategy.execute(input, reply);
|
||||
validationResult = await contract.strategy.execute(input, this.cache);
|
||||
}
|
||||
|
||||
if(!validationResult.success){
|
||||
|
@ -114,7 +116,7 @@ class MessageProcessor {
|
|||
|
||||
if(nodeBalance < p.gas){
|
||||
reply("Relayer unavailable");
|
||||
console.error("Relayer doesn't have enough gas to process trx: %s, required %s", nodeBalance, p.gas);
|
||||
this.logger.error("Relayer doesn't have enough gas to process trx: " + nodeBalance + ", required " + p.gas);
|
||||
this.events.emit('exit');
|
||||
} else {
|
||||
try {
|
||||
|
@ -129,7 +131,7 @@ class MessageProcessor {
|
|||
} catch(err){
|
||||
reply("Couldn't mine transaction: " + err.message);
|
||||
// TODO log this?
|
||||
console.error(err);
|
||||
this.logger.error(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,9 +4,24 @@ const config = require('../config/config.js');
|
|||
const ContractSettings = require('./contract-settings');
|
||||
const MessageProcessor = require('./message-processor');
|
||||
const JSum = require('jsum');
|
||||
const logger = require('consola');
|
||||
const winston = require('winston');
|
||||
var cache = require('memory-cache');
|
||||
|
||||
// Setting up logging
|
||||
const wLogger = winston.createLogger({
|
||||
level: 'info',
|
||||
format: winston.format.simple(),
|
||||
transports: [
|
||||
new winston.transports.Console(),
|
||||
new winston.transports.File({filename: 'gas-relayer.log'})
|
||||
]
|
||||
});
|
||||
logger.clear().add(new logger.WinstonReporter(wLogger));
|
||||
|
||||
|
||||
console.info("Starting...");
|
||||
// Service Init
|
||||
logger.info("Starting...");
|
||||
const events = new EventEmitter();
|
||||
|
||||
// Web3 Connection
|
||||
|
@ -17,14 +32,14 @@ const web3 = new Web3(wsProvider);
|
|||
web3.eth.net.isListening()
|
||||
.then(() => events.emit('web3:connected', connectionURL))
|
||||
.catch(error => {
|
||||
console.error(error);
|
||||
logger.error(error);
|
||||
process.exit();
|
||||
});
|
||||
|
||||
|
||||
events.on('web3:connected', connURL => {
|
||||
console.info("Connected to '%s'", connURL);
|
||||
let settings = new ContractSettings(config, web3, events);
|
||||
logger.info("Connected to '" + connURL + "'");
|
||||
let settings = new ContractSettings(config, web3, events, logger);
|
||||
settings.process();
|
||||
});
|
||||
|
||||
|
@ -37,9 +52,9 @@ const shhOptions = {
|
|||
const verifyBalance = async (exitSubs) => {
|
||||
const nodeBalance = await web3.eth.getBalance(config.node.blockchain.account);
|
||||
if(web3.utils.toBN(nodeBalance).lte(web3.utils.toBN(100000))){ // TODO: tune minimum amount required for transactions
|
||||
console.log("Not enough balance available for processing transactions");
|
||||
console.log("> Account: %s", config.node.blockchain.account);
|
||||
console.log("> Balance: %s", nodeBalance);
|
||||
logger.info("Not enough balance available for processing transactions");
|
||||
logger.info("> Account: " + config.node.blockchain.account);
|
||||
logger.info("> Balance: " + nodeBalance);
|
||||
|
||||
if(exitSubs){
|
||||
web3.shh.clearSubscriptions();
|
||||
|
@ -51,7 +66,7 @@ const verifyBalance = async (exitSubs) => {
|
|||
|
||||
events.on('exit', () => {
|
||||
web3.shh.clearSubscriptions();
|
||||
console.log("Closing service...");
|
||||
logger.info("Closing service...");
|
||||
process.exit(0);
|
||||
});
|
||||
|
||||
|
@ -67,11 +82,11 @@ events.on('setup:complete', async (settings) => {
|
|||
// Listening to whisper
|
||||
// Individual subscriptions due to https://github.com/ethereum/web3.js/issues/1361
|
||||
// once this is fixed, we'll be able to use an array of topics and a single subs for symkey and a single subs for privKey
|
||||
console.info(`Sym Key: ${config.node.whisper.symKey}`);
|
||||
console.info(`Relayer Public Key: ${pubKey}`);
|
||||
console.info("Topics Available:");
|
||||
logger.info(`Sym Key: ${config.node.whisper.symKey}`);
|
||||
logger.info(`Relayer Public Key: ${pubKey}`);
|
||||
logger.info("Topics Available:");
|
||||
for(let contract in settings.contracts) {
|
||||
console.info("- %s: %s [%s]", settings.getContractByTopic(contract).name, contract, Object.keys(settings.getContractByTopic(contract).allowedFunctions).join(', '));
|
||||
logger.info("- " + settings.getContractByTopic(contract).name + ": " + contract + " [" + (Object.keys(settings.getContractByTopic(contract).allowedFunctions).join(', ')) + "]");
|
||||
shhOptions.topics = [contract];
|
||||
|
||||
// Listen to public channel - Used for reporting availability
|
||||
|
@ -126,7 +141,7 @@ const extractInput = (message) => {
|
|||
obj.gasPrice = parsedObj.gasPrice;
|
||||
}
|
||||
} catch(err){
|
||||
console.error("Couldn't parse " + message);
|
||||
logger.error("Couldn't parse " + message);
|
||||
}
|
||||
|
||||
return obj;
|
||||
|
@ -136,28 +151,29 @@ const extractInput = (message) => {
|
|||
let messagesCheckSum = {};
|
||||
|
||||
events.on('server:listen', (shhOptions, settings) => {
|
||||
let processor = new MessageProcessor(config, settings, web3, events);
|
||||
let processor = new MessageProcessor(config, settings, web3, events, logger, cache);
|
||||
web3.shh.subscribe('messages', shhOptions, async (error, message) => {
|
||||
if(error){
|
||||
console.error(error);
|
||||
logger.error(error);
|
||||
return;
|
||||
}
|
||||
|
||||
verifyBalance(true);
|
||||
|
||||
const input = extractInput(message);
|
||||
const inputCheckSum = JSum.digest(input, 'SHA256', 'hex');
|
||||
const inputCheckSum = JSum.digest({input}, 'SHA256', 'hex');
|
||||
|
||||
const reply = replyFunction(message, inputCheckSum);
|
||||
|
||||
// TODO: Probably it makes sense to have some small db to store checksums
|
||||
if(messagesCheckSum[inputCheckSum] && messagesCheckSum[inputCheckSum] + 3600000 > (new Date().getTime())){
|
||||
if(cache.get(inputCheckSum)){
|
||||
reply("Duplicated message received");
|
||||
} else {
|
||||
let validationResult;
|
||||
switch(input.action){
|
||||
case 'transaction':
|
||||
messagesCheckSum[inputCheckSum] = (new Date().getTime());
|
||||
|
||||
cache.put(inputCheckSum, (new Date().getTime()), 86400000);
|
||||
|
||||
processor.processTransaction(settings.getContractByTopic(message.topic),
|
||||
input,
|
||||
reply);
|
||||
|
@ -181,26 +197,14 @@ events.on('server:listen', (shhOptions, settings) => {
|
|||
});
|
||||
});
|
||||
|
||||
// Cleaning old message checksums
|
||||
const deleteOldChecksums = () => {
|
||||
for (var key in messagesCheckSum) {
|
||||
if (messagesCheckSum.hasOwnProperty(key)) {
|
||||
if(messagesCheckSum[key] + 86400000 < (new Date().getTime())){
|
||||
delete messagesCheckSum[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
setInterval(deleteOldChecksums, 3600000);
|
||||
|
||||
// Daemon helper functions
|
||||
|
||||
process.on("uncaughtException", function(err) {
|
||||
// TODO
|
||||
console.error(err);
|
||||
logger.error(err);
|
||||
});
|
||||
|
||||
process.once("SIGTERM", function() {
|
||||
console.log("Stopping...");
|
||||
logger.info("Stopping...");
|
||||
});
|
||||
|
|
|
@ -11,14 +11,27 @@ class AvailabilityStrategy extends Strategy {
|
|||
* @param {object} input - Object obtained from an 'availability' request. It expects an object with this structure `{contract, address, action, gasToken, gasPrice}`
|
||||
* @returns {object} Status of validation, and minimum price
|
||||
*/
|
||||
async execute(input){
|
||||
async execute(input, cache){
|
||||
// Verifying if token is allowed
|
||||
const token = this.settings.getToken(input.gasToken);
|
||||
if(token == undefined) return {success: false, message: "Token not allowed"};
|
||||
|
||||
|
||||
// Get Price
|
||||
const tokenRate = await token.pricePlugin.getRate();
|
||||
let tokenRate = cache.get(input.gasToken);
|
||||
if(tokenRate === null){
|
||||
try {
|
||||
tokenRate = await token.pricePlugin.getRate();
|
||||
cache.put(input.gasToken, tokenRate, token.refreshPricePeriod);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
return {
|
||||
success: false,
|
||||
message: "Token price unavailable"
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
const minRate = token.minAcceptedRate;
|
||||
|
||||
if(tokenRate >= minRate){ // TODO: verify this
|
||||
|
|
|
@ -90,7 +90,7 @@ class BaseStrategy {
|
|||
}
|
||||
|
||||
/*
|
||||
async execute(message, reply){
|
||||
async execute(input){
|
||||
return {
|
||||
success: true,
|
||||
message: "Valid transaction"
|
||||
|
|
|
@ -32,7 +32,7 @@ class IdentityStrategy extends Strategy {
|
|||
* @param {object} input - Object obtained from an 'transaction' request. It expects an object with this structure `{contract, address, action, functionName, functionParameters, payload}`
|
||||
* @returns {object} Status of validation and estimated gas
|
||||
*/
|
||||
async execute(input){
|
||||
async execute(input, cache){
|
||||
if(this.contract.isIdentity){
|
||||
let validInstance = await this._validateInstance(input);
|
||||
if(!validInstance){
|
||||
|
@ -87,7 +87,20 @@ class IdentityStrategy extends Strategy {
|
|||
}
|
||||
|
||||
// Get Price
|
||||
const tokenRate = await token.pricePlugin.getRate();
|
||||
let tokenRate = cache.get(input.gasToken);
|
||||
if(tokenRate === null){
|
||||
try {
|
||||
tokenRate = await token.pricePlugin.getRate();
|
||||
cache.put(input.gasToken, tokenRate, token.refreshPricePeriod);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
return {
|
||||
success: false,
|
||||
message: "Token price unavailable"
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
const minRate = token.minAcceptedRate;
|
||||
|
||||
if(tokenRate < minRate){ // TODO: verify this. Maybe we want to accept a minRate instead of just simply not processing the trx
|
||||
|
|
|
@ -14,7 +14,7 @@ class SNTStrategy extends Strategy {
|
|||
* @param {object} input - Object obtained from an 'transaction' request. It expects an object with this structure `{contract, address, action, functionName, functionParameters, payload}`
|
||||
* @returns {object} Status of validation and estimated gas
|
||||
*/
|
||||
async execute(input){
|
||||
async execute(input, cache){
|
||||
const params = this._obtainParametersFunc(input);
|
||||
|
||||
// Verifying if token is allowed
|
||||
|
@ -30,7 +30,20 @@ class SNTStrategy extends Strategy {
|
|||
});
|
||||
|
||||
// Get Price
|
||||
const tokenRate = await token.pricePlugin.getRate();
|
||||
let tokenRate = cache.get(input.gasToken);
|
||||
if(tokenRate === null){
|
||||
try {
|
||||
tokenRate = await token.pricePlugin.getRate();
|
||||
cache.put(input.gasToken, tokenRate, token.refreshPricePeriod);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
return {
|
||||
success: false,
|
||||
message: "Token price unavailable"
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
const minRate = token.minAcceptedRate;
|
||||
|
||||
if(tokenRate < minRate){ // TODO: verify this. Maybe we want to accept a minRate instead of just simply not processing the trx
|
||||
|
|
Loading…
Reference in New Issue